Skip to content

Commit

Permalink
can always deliver_now custom rss
Browse files Browse the repository at this point in the history
  • Loading branch information
cdhigh committed Jul 6, 2024
1 parent 9b0d352 commit de8a3f0
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 102 deletions.
77 changes: 47 additions & 30 deletions application/static/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,11 @@ function SelectCategory(obj, category) {
function DoSearchInShared() {
var input = $('#search_text');
var txt = input.val();
if (txt == "#download") { //下载所有的共享RSS
DownAllRssToFile();
if ((txt == "#download") || (txt == "#downxml") || (txt == "#downjson")) { //下载所有的共享RSS
var fileType = (txt == "#downjson") ? "json" : "xml";
DownAllRssToFile(fileType);
input.val("");
DoSearchInShared();
return;
}

Expand Down Expand Up @@ -401,39 +403,54 @@ function ReportInvalid(title, feedurl, dbId) {


//将内容全部下载到本地一个xml文件内
function DownAllRssToFile() {
//fileType: 保存的文件格式,xml/json
function DownAllRssToFile(fileType) {
if (!g_SharedRss) {
return;
}
var title, url, ftext, cat, rssd, fmtdate, nowdate, lang;
var elementA = document.createElement('a');
var aTxt = new Array();
aTxt.push("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
aTxt.push("<opml version=\"2.0\">");
aTxt.push("<head>");
aTxt.push(" <title>KindleEar.opml</title>");
aTxt.push(" <dateCreated>" + new Date() + "</dateCreated>");
aTxt.push(" <dateModified>" + new Date() + "</dateModified>");
aTxt.push(" <ownerName>KindleEar</ownerName>");
aTxt.push("</head>");
aTxt.push("<body>");
for (var i = 0; i < g_SharedRss.length; i++) {
title = escapeXml(g_SharedRss[i].t);
url = escapeXml(g_SharedRss[i].u);
cat = escapeXml(g_SharedRss[i].c);
lang = g_SharedRss[i].l || '';
ftext = (g_SharedRss[i].f == "false") ? "no" : "yes";
aTxt.push(' <outline type="rss" text="{0}" title="{0}" xmlUrl="{1}" isFulltext="{2}" category="{3}" language="{4}" />'
.format(title, url, ftext, cat, lang));
fileType = fileType || 'xml';
var content, mimeType;
var title, url, ftext, cat, lang;
const now = new Date();
if (fileType == 'xml') {
var aTxt = new Array();
aTxt.push("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
aTxt.push("<opml version=\"2.0\">");
aTxt.push("<head>");
aTxt.push(" <title>KindleEar.opml</title>");
aTxt.push(" <dateCreated>" + now + "</dateCreated>");
aTxt.push(" <dateModified>" + now + "</dateModified>");
aTxt.push(" <ownerName>KindleEar</ownerName>");
aTxt.push("</head>");
aTxt.push("<body>");
for (var i = 0; i < g_SharedRss.length; i++) {
title = escapeXml(g_SharedRss[i].t);
url = escapeXml(g_SharedRss[i].u);
cat = escapeXml(g_SharedRss[i].c);
lang = g_SharedRss[i].l || '';
ftext = (g_SharedRss[i].f == "false") ? "no" : "yes";
aTxt.push(' <outline type="rss" text="{0}" title="{0}" xmlUrl="{1}" isFulltext="{2}" category="{3}" language="{4}" />'
.format(title, url, ftext, cat, lang));
}
aTxt.push("</body>");
aTxt.push("</opml>\n");
content = aTxt.join("\n");
mimeType = "application/xml";
} else {
var jsonData = g_SharedRss.map(function(item) {
return {t: item.t, u: item.u, c: item.c, l: item.l || '', f: item.f};
});
content = JSON.stringify(jsonData, null, 2);
mimeType = "application/json";
}
aTxt.push("</body>");
aTxt.push("</opml>\n");

nowdate = new Date();
fmtdate = "KindleEar_library_" + nowdate.getFullYear() + "_" + ((nowdate.getMonth() + 1)) + "_" + nowdate.getDate() + ".xml";

elementA.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(aTxt.join("\n")));
elementA.setAttribute("download", fmtdate);
var elementA = document.createElement('a');
const year = now.getFullYear();
const month = now.getMonth() + 1;
const date = now.getDate();
const fmtDate = "KindleEar_" + year + "_" + month + "_" + date + "." + fileType;
elementA.setAttribute("href", "data:" + mimeType + ";charset=utf-8," + encodeURIComponent(content));
elementA.setAttribute("download", fmtDate);
elementA.style.display = 'none';
document.body.appendChild(elementA);
elementA.click();
Expand Down
17 changes: 12 additions & 5 deletions application/templates/adv_delivernow.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,30 @@
{% if recipes|length == 0 -%}
<div class="box">{{ _("There are no recipes subscribed") }}</div>
{% endif -%}
{% set userName = session.get('userName', '') -%}
{% for item in recipes -%}
<label for="{{item.recipe_id}}" class="pure-checkbox box">
<input id="{{item.recipe_id}}" type="checkbox" class="deliver_now_rss_id" checked="1" onclick="UpdateDeliverLink('{{userName}}','{{deliveryKey}}');" />
<input id="{{item.recipe_id}}" type="checkbox" class="deliver_now_rss_id" checked="1" onclick="UpdateDeliverLink('{{user.name}}','{{deliveryKey}}');" />
<span>{{item.title}}</span>{% if item.separated %}<sup>{{_('Sep')}}</sup>{%endif%}
</label>
{% endfor -%}
{% if recipes|length > 0 -%}
<div class="cornerControls" style="padding:.5em 0;text-align:center;">
<a onclick="SelectDeliverAll();UpdateDeliverLink('{{userName}}','{{deliveryKey}}');return false;" href="#" class="actionButton">{{_("Select all")}}</a>
<a onclick="SelectDeliverNone();UpdateDeliverLink('{{userName}}','{{deliveryKey}}');return false;" href="#" class="actionButton">{{_("Select none")}}</a>
<a onclick="SelectDeliverAll();UpdateDeliverLink('{{user.name}}','{{deliveryKey}}');return false;" href="#" class="actionButton">{{_("Select all")}}</a>
<a onclick="SelectDeliverNone();UpdateDeliverLink('{{user.name}}','{{deliveryKey}}');return false;" href="#" class="actionButton">{{_("Select none")}}</a>
</div>
{% endif -%}
</div>
<div style="text-align:center;">
<a href="/deliver?u={{userName}}&key={{deliveryKey}}" value="{{ _('Deliver') }}" id="deliverNowButton" class="pure-button pure-button-primary pure-input-rounded">{{ _('Deliver') }}</a>
<a href="/deliver?u={{user.name}}&key={{deliveryKey}}" value="{{ _('Deliver') }}" id="deliverNowButton" class="pure-button pure-button-primary pure-input-rounded">{{ _('Deliver') }}</a>
</div>
</fieldset>
</div>
{% endblock -%}
{% block js -%}
<script type="text/javascript">
$(document).ready(function() {
SelectDeliverAll();
UpdateDeliverLink('{{user.name}}', '{{deliveryKey}}');
});
</script>
{% endblock -%}
4 changes: 2 additions & 2 deletions application/templates/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
</div>
<div class="pure-control-group">
<label><em class="required">*</em> {{_("Kindle E-mail")}}</label>
<input type="email" name="kindle_email" value="{{user.cfg('kindle_email')}}" placeholder="{{_('Seperated by comma')}}" class="pure-u-1 pure-u-sm-1-2" required multiple />
<input type="email" name="kindle_email" value="{{user.cfg('kindle_email')}}" placeholder="{{_('Seperated by comma')}}" class="pure-u-1 pure-u-sm-1-2" multiple />
</div>
{% if g.allowReader -%}
<div class="pure-control-group">
Expand Down Expand Up @@ -142,7 +142,7 @@
<legend>{{_("Custom RSS")}}</legend>
<div class="pure-control-group">
<label><em class="required">*</em> {{_("Title")}}</label>
<input type="text" name="rss_title" value="{{ user.book_cfg('title') }}" required class="pure-u-1 pure-u-sm-1-2" />
<input type="text" name="rss_title" value="{{ user.book_cfg('title') }}" class="pure-u-1 pure-u-sm-1-2" />
</div>
<div class="pure-control-group">
<label class="tooltip" data-msg="{{_('Sets the lookup dictionary')}}">{{_("Language")}}</label>
Expand Down
6 changes: 6 additions & 0 deletions application/view/adv.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ def adv_render_template(tpl, advCurr, **kwargs):
@login_required()
def AdvDeliverNow(user: KeUser):
recipes = user.get_booked_recipe()
if user.cfg('enable_send') != 'all': #添加自定义RSS
rss = [BookedRecipe(recipe_id=r.recipe_id, separated=r.custom.get('separated', False),
user=user.name, title=r.title, description=r.description)
for r in user.all_custom_rss()]
recipes = rss + recipes

deliveryKey = app.config['DELIVERY_KEY']
return adv_render_template('adv_delivernow.html', 'deliverNow', user=user, recipes=recipes,
deliveryKey=deliveryKey)
Expand Down
25 changes: 18 additions & 7 deletions application/view/deliver.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,31 @@ def MultiUserDelivery():
#idList: recipe id列表,id格式:custom:xx,upload:xx,builtin:xx,为空则推送指定账号下所有订阅
def SingleUserDelivery(userName: str, idList: list=None):
user = KeUser.get_or_none(KeUser.name == userName)
if not user or not user.cfg('kindle_email'):
if not user or ('email' in user.cfg('delivery_mode') and not user.cfg('kindle_email')):
return render_template('autoback.html', tips=_('The username does not exist or the email is empty.'))

sent = []
#这里不判断特定账号是否已经订阅了指定的书籍,只要提供就推送
if idList:
recipesToPush = list(filter(bool, map(user.get_booked_recipe, idList)))
toPush = []
for id_ in idList:
recipeType, dbId = Recipe.type_and_id(id_)
bked = user.get_booked_recipe(id_)
#如果没有启用自定义RSS推送
r = Recipe.get_by_id_or_none(dbId) if (not bked and (recipeType == 'custom')) else None
if r:
toPush.append({'id_': r.recipe_id, 'separated': r.custom.get('separated', False),
'title': r.title})
elif bked:
toPush.append({'id_': bked.recipe_id, 'separated': bked.separated, 'title': bked.title})
else: #推送特定账号所有订阅的书籍
recipesToPush = user.get_booked_recipe()
toPush = [{'id_': r.recipe_id, 'separated': r.separated, 'title': r.title}
for r in user.get_booked_recipe()]

sent = []
bkQueue = defaultdict(list)
for bkRecipe in recipesToPush: #BookedRecipe实例
queueOneBook(bkQueue, user, bkRecipe.recipe_id, bkRecipe.separated, reason='manual')
sent.append(f'<i>{bkRecipe.title}</i>')
for bked in toPush:
queueOneBook(bkQueue, user, bked['id_'], bked['separated'], reason='manual')
sent.append(f'<i>{bked["title"]}</i>')
flushQueueToPush(bkQueue, reason='manual')

if sent:
Expand Down
77 changes: 33 additions & 44 deletions application/view/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,59 +37,48 @@ def Settings(user: KeUser):
@login_required()
def SettingsPost(user: KeUser):
form = request.form
keMail = form.get('kindle_email', '').strip(';, ')
myTitle = form.get('rss_title')

send_mail_service = BuildSmSrvDict(user, form)
if not keMail:
tips = _("Kindle E-mail is requied!")
elif not myTitle:
tips = _("Title is requied!")
elif not send_mail_service:
tips = _("Some parameters are missing or wrong.")
else:
base_config = user.base_config
book_config = user.book_config

enable_send = form.get('enable_send')
base_config['enable_send'] = enable_send if enable_send in ('all', 'recipes') else ''
base_config['kindle_email'] = keMail
base_config['delivery_mode'] = form.get('delivery_mode', 'email') if app.config['EBOOK_SAVE_DIR'] else 'email'
base_config['webshelf_days'] = str_to_int(form.get('webshelf_days', '7'))
base_config['timezone'] = float(form.get('timezone', '0'))
user.send_time = int(form.get('send_time', '0'))
book_config['type'] = form.get('book_type', 'epub')
book_config['device'] = form.get('device_type', 'kindle')
book_config['title_fmt'] = form.get('title_fmt', '')
allDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
user.send_days = [weekday for weekday, day in enumerate(allDays) if str_to_bool(form.get(day, ''))]
book_config['mode'] = form.get('book_mode', '')
book_config['rm_links'] = form.get('remove_hyperlinks', '')
book_config['author_fmt'] = form.get('author_format', '') #修正Kindle 5.9.x固件的bug【将作者显示为日期】
book_config['title'] = myTitle
book_config['language'] = form.get("book_language", "en")
book_config['oldest_article'] = int(form.get('oldest', 7))
book_config['time_fmt'] = form.get('time_fmt', '')
user.base_config = base_config
user.book_config = book_config
user.send_mail_service = send_mail_service
user.save()
tips = _("Settings Saved!")

#根据自定义RSS的使能设置,将自定义RSS添加进订阅列表或从订阅列表移除
UpdateBookedCustomRss(user)
base_config = user.base_config
book_config = user.book_config

enable_send = form.get('enable_send')
base_config['enable_send'] = enable_send if enable_send in ('all', 'recipes') else ''
base_config['kindle_email'] = form.get('kindle_email', '').strip(';, ')
base_config['delivery_mode'] = form.get('delivery_mode', 'email') if app.config['EBOOK_SAVE_DIR'] else 'email'
base_config['webshelf_days'] = str_to_int(form.get('webshelf_days', '7'))
base_config['timezone'] = float(form.get('timezone', '0'))
user.send_time = int(form.get('send_time', '0'))
book_config['type'] = form.get('book_type', 'epub')
book_config['device'] = form.get('device_type', 'kindle')
book_config['title_fmt'] = form.get('title_fmt', '')
allDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
user.send_days = [weekday for weekday, day in enumerate(allDays) if str_to_bool(form.get(day, ''))]
book_config['mode'] = form.get('book_mode', '')
book_config['rm_links'] = form.get('remove_hyperlinks', '')
book_config['author_fmt'] = form.get('author_format', '') #修正Kindle 5.9.x固件的bug【将作者显示为日期】
book_config['title'] = form.get('rss_title') or 'KindleEar'
book_config['language'] = form.get("book_language", "en")
book_config['oldest_article'] = int(form.get('oldest', 7))
book_config['time_fmt'] = form.get('time_fmt', '')
user.base_config = base_config
user.book_config = book_config
user.send_mail_service = BuildSmSrvDict(user, form)
user.save()
tips = _("Settings Saved!")

#根据自定义RSS的使能设置,将自定义RSS添加进订阅列表或从订阅列表移除
UpdateBookedCustomRss(user)

sm_services = avaliable_sm_services()
return render_template('settings.html', tab='set', user=user, tips=tips, langMap=LangMap(),
sm_services=sm_services, all_timezones=all_timezones, output_profiles=output_profiles)

#构建发送邮件服务配置字典,返回空字典表示出错
#form: request.form 实例
def BuildSmSrvDict(user: KeUser, form):
def BuildSmSrvDict(user: KeUser, form) -> dict:
srv = user.send_mail_service.copy()
srvType = form.get('sm_service', '')
#service==admin 说明和管理员的设置一致
if user.name == os.getenv('ADMIN_NAME') or srv.get('service') != 'admin':
srvType = form.get('sm_service', '')
srv['service'] = srvType
srv['apikey'] = form.get('sm_apikey', '')
srv['secret_key'] = form.get('sm_secret_key', '')
Expand All @@ -98,7 +87,7 @@ def BuildSmSrvDict(user: KeUser, form):
srv['username'] = form.get('sm_username', '')
srv['password'] = user.encrypt(form.get('sm_password', ''))
srv['save_path'] = form.get('sm_save_path', '')
validations = {
validations = { #根据选择的发送邮件服务类型进行简单校验
'sendgrid': lambda srv: srv['apikey'],
'mailjet': lambda srv: srv['apikey'] and srv['secret_key'],
'smtp': lambda srv: all((srv['host'], srv['port'], srv['password'])), #部分smtp不需要账号名
Expand Down
36 changes: 22 additions & 14 deletions application/work/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,33 @@ def WorkerImpl(userName: str, recipeId: Union[list,str,None]=None, reason='cron'
#在已订阅的Recipe或自定义RSS列表创建Recipe源码列表
#返回一个字典,键名为title,元素为 [BookedRecipe, Recipe, src]
def GetAllRecipeSrc(user, idList):
bkeds = []
for id_ in idList:
recipeType, dbId = Recipe.type_and_id(id_)
bked = BookedRecipe.get_or_none(BookedRecipe.recipe_id == id_)
#针对没有启用自定义RSS推送的情况,创建一个临时BookedRecipe对象但不保存到数据库
recipe = Recipe.get_by_id_or_none(dbId) if (not bked and (recipeType == 'custom')) else None
if recipe:
bked = BookedRecipe(recipe_id=id_, separated=recipe.custom.get('separated', False),
user=user.name, title=recipe.title, description=recipe.description)
bkeds.append({'recipeId': id_, 'recipeType': recipeType, 'dbId': dbId, 'bked': bked,
'recipe': recipe})

srcDict = {}
for bked in filter(bool, [BookedRecipe.get_or_none(BookedRecipe.recipe_id == id_) for id_ in idList]):
recipeId = bked.recipe_id
recipeType, dbId = Recipe.type_and_id(recipeId)
if recipeType == 'builtin':
bnInfo = GetBuiltinRecipeInfo(recipeId)
src = GetBuiltinRecipeSource(recipeId)
for item in bkeds:
recipe = item['recipe']
if item['recipeType'] == 'builtin':
bnInfo = GetBuiltinRecipeInfo(item['recipeId'])
src = GetBuiltinRecipeSource(item['recipeId'])
if bnInfo and src:
srcDict[bnInfo.get('title', '')] = [bked, bnInfo, src]
continue

recipe = Recipe.get_by_id_or_none(dbId)
if recipe:
srcDict[bnInfo.get('title', '')] = [item['bked'], bnInfo, src]
elif recipe:
title = recipe.title
if recipeType == 'upload': #上传的Recipe
srcDict[title] = [bked, recipe, recipe.src]
if item['recipeType'] == 'upload': #上传的Recipe
srcDict[title] = [item['bked'], recipe, recipe.src]
else: #自定义RSS
src = GenerateRecipeSource(title, [(title, recipe.url)], user, isfulltext=recipe.isfulltext)
srcDict[title] = [bked, recipe, src]
srcDict[title] = [item['bked'], recipe, src]
return srcDict

#返回可用的mp3cat执行文件路径
Expand Down

0 comments on commit de8a3f0

Please sign in to comment.