From a2fc2c55433e4405d507ba6c26cbcc56a56983ae Mon Sep 17 00:00:00 2001 From: cdhigh Date: Tue, 2 Apr 2024 21:55:37 -0300 Subject: [PATCH] porting to python3 --- application/back_end/db_models.py | 3 +- application/lib/calibre/web/feeds/news.py | 147 ++++++++++++++++-- .../lib/calibre/web/feeds/recipes/__init__.py | 19 +-- application/lib/smtp_mail.py | 2 +- application/static/base.js | 10 +- application/templates/base.html | 2 +- .../tr_TR/LC_MESSAGES/messages.mo | Bin 23378 -> 23402 bytes .../tr_TR/LC_MESSAGES/messages.po | 147 +++++++++--------- .../translations/zh/LC_MESSAGES/messages.mo | Bin 21977 -> 22013 bytes .../translations/zh/LC_MESSAGES/messages.po | 135 ++++++++-------- application/view/adv.py | 2 +- application/view/login.py | 11 +- application/view/logs.py | 1 + application/work/worker.py | 9 +- docs/Chinese/2.config.md | 2 +- docs/English/2.config.md | 2 +- messages.pot | 130 ++++++++-------- tools/update_req.py | 7 +- 18 files changed, 385 insertions(+), 244 deletions(-) diff --git a/application/back_end/db_models.py b/application/back_end/db_models.py index fe2e2b70..a383925c 100644 --- a/application/back_end/db_models.py +++ b/application/back_end/db_models.py @@ -220,7 +220,8 @@ class SharedRssCategory(MyBaseModel): class LastDelivered(MyBaseModel): user = CharField() - bookname = CharField() + bookname = CharField(default='') + url = CharField(default='') num = IntegerField(default=0) record = CharField(default='') datetime = DateTimeField(default=datetime.datetime.utcnow) diff --git a/application/lib/calibre/web/feeds/news.py b/application/lib/calibre/web/feeds/news.py index fbaf4cda..4eaf4530 100644 --- a/application/lib/calibre/web/feeds/news.py +++ b/application/lib/calibre/web/feeds/news.py @@ -8,14 +8,9 @@ __docformat__ = "restructuredtext en" -import io -import os -import re -import sys -import time -import traceback +import io, os, re, sys, time, datetime, traceback from collections import defaultdict, namedtuple -from urllib.parse import urlparse, urlsplit, quote +from urllib.parse import urlparse, urlsplit, quote, urljoin from urllib.error import HTTPError, URLError from calibre import __appname__, as_unicode, force_unicode, iswindows, preferred_encoding, strftime from calibre.ebooks.BeautifulSoup import BeautifulSoup, CData, NavigableString, Tag @@ -39,6 +34,7 @@ from urlopener import UrlOpener from requests_file import LocalFileAdapter from filesystem_dict import FsDictStub +from application.back_end.db_models import LastDelivered MASTHEAD_SIZE = (600, 60) DEFAULT_MASTHEAD_IMAGE = 'mastheadImage.gif' @@ -925,6 +921,7 @@ def __init__(self, options, log, output_dir, fs, feed_index_start=0): self.title = str(self.title, 'utf-8', 'replace') self.options = options + self.user = self.options.user self.debug = options.verbose > 1 self.output_dir = output_dir self.fs = fs @@ -1045,7 +1042,7 @@ def _postprocess_html(self, soup, first_fetch, job_info): del img['srcset'] #如果需要,去掉正文中的超链接(使用斜体下划线标识),以避免误触 - remove_hyperlinks = self.options.user.remove_hyperlinks + remove_hyperlinks = self.user.remove_hyperlinks if remove_hyperlinks in ('text', 'all'): for a_ in soup.find_all('a'): a_.name = 'i' @@ -1099,18 +1096,17 @@ def append_share_links(self, soup, url): if not soup: return - user = self.options.user - shareLinks = user.share_links + shareLinks = self.user.share_links aTags = [] for type_ in ['Evernote', 'Wiz', 'Pocket', 'Instapaper']: if shareLinks.get(type_, {}).get('enable'): - ashare = soup.new_tag('a', href=self.make_share_link(type_, user, url, soup)) + ashare = soup.new_tag('a', href=self.make_share_link(type_, self.user, url, soup)) ashare.string = _('Save to {}').format(type_) aTags.append(ashare) for type_ in ['Weibo', 'Facebook', 'X', 'Tumblr']: if shareLinks.get(type_): - ashare = soup.new_tag('a', href=self.make_share_link(type_, user, url, soup)) + ashare = soup.new_tag('a', href=self.make_share_link(type_, self.user, url, soup)) ashare.string = _('Share on {}').format(type_) aTags.append(ashare) @@ -1284,8 +1280,8 @@ def _fetch_article(self, job_info, preloaded=None): if preloaded is not None: fetcher.preloaded_urls[url] = preloaded - #res为对应url的一个html文件名 - res = fetcher.start_fetch(url) + res = fetcher.start_fetch(url) #res为对应url的一个html文件名 + path = fetcher.downloaded_paths failures = fetcher.failed_links if not res or not self.fs.exists(res): @@ -2053,6 +2049,129 @@ def parse_feeds(self): return [feed] +#保存的url为网页url,给定一个规则,从网页url里面提取链接,每个链接一篇文章 +#一般用于新闻类的网页,即使新闻网站不提供RSS,也可以每天去获取新闻 +#这个类建议搭配KindleEar chrome插件使用,插件可以自动生成抓取脚本 +class WebPageUrlNewsRecipe(BasicNewsRecipe): + max_articles_per_feed = 30 + + #为一个二维列表,可以保存多个标签规则,每个规则都很灵活,只要是BeautifulSoup的合法规则即可(字典或CSS选择器字符串) + #每个顶层元素为一个html标签的查找规则列表,从父节点到子节点,依次往下一直到最后一个元素为止 + #最后一个元素必须为链接,或其子节点有链接,则此链接为文章最终链接,链接的文本为文章标题 + #比如:url_extract_rules = [[{'name': 'div', 'attrs': {'class': 'art', 'data': True}}, {'name': 'a'}],] + #或:url_extract_rules = [['div.art[data]', 'a'],] + url_extract_rules = [] + + #格式和 url_extract_rules 一致,在文章的网页中提取文章正文,为空则使用自动提取 + content_extract_rules = [] + + #返回一个Feed实例列表 + def parse_feeds(self): + main_urls = self.get_feeds() + if not main_urls: + self.log.warning(f'There are no urls in "{self.title}"') + return [] + + feeds = [] + id_counter = 0 + added = set(); + for obj in main_urls: + main_title, main_url = (self.title, obj) if isinstance(obj, str) else obj + feed = Feed() + feed.title = main_title + feed.description = '' + feed.image_url = None + feed.oldest_article = self.oldest_article + feed.articles = [] + now = time.gmtime() + + for title, url in self.extract_urls(main_title, main_url): + if len(feed) >= self.max_articles_per_feed: + break + if url in added: #避免重复添加 + continue + + added.add(url) + lastTime = LastDelivered.get_or_none(user=self.user.name, url=url) + delta = (datetime.datetime.utcnow() - lastTime.datetime) if lastTime else None + #这里oldest_article和其他的recipe不一样,这个参数表示在这个区间内不会重复推送 + if ((not lastTime) or (not self.oldest_article) or + (delta.days * 24 * 3600 + delta.seconds > 24 * 3600 * self.oldest_article)): + id_counter += 1 + feed.articles.append(Article(f'internal id#{id_counter}', title, url, 'KindleEar', '', now, '')) + + if lastTime: + lastTime.datetime = datetime.datetime.utcnow() + lastTime.save() + else: + LastDelivered.create(user=self.user.name, url=url) + else: + self.log.debug(f'Skipping article {title}({url}) as it is too old.') + + feed.id_counter = id_counter + if len(feed) > 0: + feeds.append(feed) + + return feeds + + #在一个soup对象中查找所有满足条件的tag + def _soup_find_all(self, tag, rule): + return tag.find_all(**rule) if isinstance(rule, dict) else tag.select(rule) + + #从一个网页中根据指定的规则,提取文章链接 + def extract_urls(self, main_title, main_url): + resp = self.browser.open(main_url, timeout=self.timeout) + if resp.status_code != 200: + self.log.warning(f'Failed to fetch {main_url}: {UrlOpener.CodeMap(resp.status_code)}') + return [] + + soup = BeautifulSoup(resp.text, 'lxml') + + articles = [] + for rule in self.url_extract_rules: + resultTags = self._soup_find_all(soup, rule[0]) + for flt in rule[1:]: + resultTags = [self._soup_find_all(tag, flt) for tag in resultTags] + resultTags = [tag for sublist in resultTags for tag in sublist] #二级列表展开为一级列表 + + for item in resultTags: + #如果最终tag不是链接,则在子节点中查找 + item = item.find_all('a') if item.name.lower() != 'a' else [item] + for tag in item: + title = ' '.join(tag.stripped_strings) or main_title + url = tag.attrs.get('href', None) + if not url.startswith('http'): + url = urljoin(main_url, url) + if title and url: + articles.append((title, url)) + + self.log.debug(f'Found {len(articles)} articles in {self.title}\n') + self.log.debug(str(articles)) + return articles + + #提取文章内容,这个函数在文章被下载解码为unicode后,转换为DOM树前被调用 + def preprocess_raw_html(self, raw_html, url): + if self.auto_cleanup or not self.content_extract_rules: #由readability自动提取 + return raw_html + + soup = BeautifulSoup(raw_html, 'lxml') + oldBody = soup.find('body') + if not oldBody: + return raw_html + + newBody = soup.new_tag('body') + for rule in self.content_extract_rules: + resultTags = self._soup_find_all(soup, rule[0]) + for flt in rule[1:]: + resultTags = [self._soup_find_all(tag, flt) for tag in resultTags] + resultTags = [tag for sublist in resultTags for tag in sublist] #二级列表展开为一级列表 + + newBody.extend(resultTags) + + oldBody.replace_with(newBody) + return str(soup) + + class CalibrePeriodical(BasicNewsRecipe): #: Set this to the slug for the calibre periodical diff --git a/application/lib/calibre/web/feeds/recipes/__init__.py b/application/lib/calibre/web/feeds/recipes/__init__.py index d3e5c02f..e0ffaba3 100644 --- a/application/lib/calibre/web/feeds/recipes/__init__.py +++ b/application/lib/calibre/web/feeds/recipes/__init__.py @@ -7,13 +7,13 @@ ''' import re, time, io from calibre.web.feeds.news import (BasicNewsRecipe, CustomIndexRecipe, - AutomaticNewsRecipe, UrlNewsRecipe, CalibrePeriodical) + AutomaticNewsRecipe, UrlNewsRecipe, CalibrePeriodical, WebPageUrlNewsRecipe) from calibre.ebooks.BeautifulSoup import BeautifulSoup from calibre.utils.config import JSONConfig from polyglot.builtins import itervalues, codepoint_to_chr basic_recipes = (BasicNewsRecipe, AutomaticNewsRecipe, UrlNewsRecipe, CustomIndexRecipe, - CalibrePeriodical) + CalibrePeriodical, WebPageUrlNewsRecipe) custom_recipes = JSONConfig('custom_recipes/index.json') @@ -42,11 +42,13 @@ def compile_recipe(src): src = io.StringIO(src, newline=None).getvalue() namespace = { - 'BasicNewsRecipe':BasicNewsRecipe, - 'AutomaticNewsRecipe':AutomaticNewsRecipe, - 'UrlNewsRecipe':UrlNewsRecipe, - 'time':time, 're':re, - 'BeautifulSoup':BeautifulSoup, + 'BasicNewsRecipe': BasicNewsRecipe, + 'AutomaticNewsRecipe': AutomaticNewsRecipe, + 'UrlNewsRecipe': UrlNewsRecipe, + 'WebPageUrlNewsRecipe': WebPageUrlNewsRecipe, + 'time': time, + 're': re, + 'BeautifulSoup': BeautifulSoup, 'unicode': str, 'unichr': codepoint_to_chr, 'xrange': range, @@ -55,8 +57,7 @@ def compile_recipe(src): ua = namespace.get('calibre_most_common_ua') for x in itervalues(namespace): - if (isinstance(x, type) and issubclass(x, BasicNewsRecipe) and x not - in basic_recipes): + if (isinstance(x, type) and issubclass(x, BasicNewsRecipe) and x not in basic_recipes): x.calibre_most_common_ua = ua return x diff --git a/application/lib/smtp_mail.py b/application/lib/smtp_mail.py index 6caafe88..e682cebb 100644 --- a/application/lib/smtp_mail.py +++ b/application/lib/smtp_mail.py @@ -13,7 +13,7 @@ def smtp_send_mail(sender, to, subject, body, host, username, password, port=Non if ':' in host: host, port = host.split(':', 2) port = int(port) - else: + elif not port: port = 587 #587-TLS, 465-SSL, 25-Nocrpt to = to if isinstance(to, list) else [to] diff --git a/application/static/base.js b/application/static/base.js index d5640c70..40c54b60 100644 --- a/application/static/base.js +++ b/application/static/base.js @@ -672,9 +672,11 @@ function OpenUploadRecipeDialog() { modal.close(); //更新本地数据 delete data.status; + let language = data.language; my_uploaded_recipes.unshift(data); PopulateLibrary(''); - ShowSimpleModalDialog('

{0}

{1}

'.format(i18n.congratulations, i18n.recipeUploadedTips)); + ShowSimpleModalDialog('

{0}

{1}

'.format(i18n.congratulations, + i18n.recipeUploadedTips.format(LanguageName(language)))); } else if (data.status == i18n.loginRequired) { window.location.href = '/login'; } else { @@ -718,16 +720,14 @@ function DeleteUploadRecipe(id, title) { //在页面下发插入bookmarklet function insertBookmarkletGmailThis(subscribeUrl, mailPrefix) { - var parser = $('', { - href: subscribeUrl - }); + var parser = $('', {href: subscribeUrl}); var host = parser.prop('hostname'); var length = host.length; var addr = ''; if ((length > 12) && host.substr(length - 12, 12) == '.appspot.com') { addr = '{0}read@{1}.appspotmail.com'.format(mailPrefix, host.substr(0, length - 12)); } else { - return; + addr = '{0}read@{1}'.format(mailPrefix, host); } var parent = $('#bookmarklet_content'); diff --git a/application/templates/base.html b/application/templates/base.html index dab87994..d42f3785 100644 --- a/application/templates/base.html +++ b/application/templates/base.html @@ -51,7 +51,7 @@ chooseRecipeFile: '{{_("Choose a recipe file to upload")|safe}}', congratulations: '{{_("Congratulations")|safe}}', thanks: '{{_("Thanks")|safe}}', - recipeUploadedTips: '{{_("Your recipe has been uploaded, and it can be found in the Library section. If you dont see it, please make sure to switch to the correct language.")|safe}}', + recipeUploadedTips: '{{_("Your recipe has been uploaded, and it can be found in the Library section. If you dont see it, please make sure to switch to the correct language ({0}).")|safe}}', recipeDeleted: '{{_("Your recipe have been deleted.")|safe}}', kindleifySelection: '{{_("Kindleify Selection")|safe}}', verify: '{{_("Verify")|safe}}', diff --git a/application/translations/tr_TR/LC_MESSAGES/messages.mo b/application/translations/tr_TR/LC_MESSAGES/messages.mo index 9eaf0e04448b17786340de86e1b2941517783ee4..bff340fd8b4ac0f98d5b2973fbddd780882e391e 100644 GIT binary patch delta 3591 zcmXxl3rv<(9LMoPAc~-J@dZJv*DE(cKmjj+x4c3o2AbqX-boD&3>RvzsWZ)VDbrzU z4HxRjTf@9fG>uj=!Am)(%dni5N@;1)!nE(N=d?LL=RD7O&-tJK|D1=5hrI3_@;b1x zjpwv6rnI*)!I&Or%riJ1yW@Q9ie;FHpJ5XIWZy@`8`F(`29Cq27>)<$a8YtaY4Mt`hFKfHpi@CLTU+ZcckF$ld9j0wdMdf}G6F$Nabdd)AFxr}o8b1_$aRm0oEOg^C zRAwu1EFQ!le1ghUkcWJ>qY;bR@c`70GO!J1Vld{|{%q7j3s3yjJ zfmc|oPytli_a{&ps7E&9F^x{c+(Om%7gS^qaJ`o?&8P`hr8*hffXcvT)bs7OzuWfr zqcVBS_D@>tte5Qj>;Lts|4kYp{NO$+0H6NGL||LgPI{syj7Kfl*FMj%{ZZJN=MzvV zFGK}cf|_S3_P}!Njy0%pKcFw`o7*%p@ji01Oxgfr2I3ry!Aexh&g0YgBkGK3kS1z} zdhbFvMq)aSMr~-7^*s!xzY!H+C3>`@Jv8KD)HOM6y^OlwO{gDq806gRP}CVnLG3IT zdtoVRd<81-T2uz_q2~V!m1*xZCy=l->aPbeJkY((z(~wREw~h;aV5HOA8JSE(1n+< z1Kvd)!WL8}TCsgy(=cmy)cZc@#sR33=B1N=9kzTP==4sv7Fpj$?d*Nj#D`JW?TqbT zMeVE!mAPhAW&$#t>llmL$OzPjE(<&13e@kmd1$DHyHFGFNA2iyoQ3C60j3T%rV$6B zYTtQ?lZhzQMDeI`15npE9kX#3PQfFn+Pj7tGYz9K0zGSKD8ikn0QRCLJb{|<3@UZ? zs6a2HO3-M%X`kOkjeCH~>hKB#%><`jH=m&;Z6#- zqcU+EHNja_39h07Y(fRpjH=}m)Ht8#oLdr%;q((w8yt(?n2pLrE(Wo_DWIW+OYMMF zs2{wG+R+BXCMh(tZy=DMB`LD zU@dBaZKy-F%l40>0{aTPVFT(c{D#WJW7Gn^Bl(747`ibBRf;!|Z=5-c&!f*M^6x`q z0u3!V3Duv5zBn6oe+#iSE<)ANgDTA??1GgThNsbuSFJ7Bm427e&hrdZ>hnt-wQ$f_{>Eb`Y>j!S57#u?FF|eOEsVx8+pj?_d=YzKBWgaM zOlLiR4-M_03u<5tMq(Yum!kq&hiz~Z>Rx|{p?DNE?|JNr*RVHw zXE~p8PXZ0?csy#N9P1SHqdx<6CJIr36{7;#im_OM%xUUT8wuxRO~6Q0txHiEUWfWF zRHClsLFCVh$28E0;(^~dWB3DTl2C_gE~emWjK`Cx+Wm^UKIR2uhCn#-&*br+0<5xL zMAi6jRG@+5oztI&D%C<9r2D^yhEnz=>JVMWT6~25cq-coupSlIpQu`fu+4th9~1F4 z>qn?VcL8*LG8Q&JK#5{@i!)se>Lv$paxs)z@snm2ZH_yjKPkR zox?O3-=v?5C3p^3;K)2@M|G$jUqc0U3)|rz_PO`V&ieq=^>roC(4lgpGLVki@dWE+ zRLx&OrF2$xcT;atA(@OQ)kR5nps>tv$%Rs@9k}T-BF7ZmPVJ2 iNp5c2FD@a;otQc>F|~SZ%AtsA-|Q;C|KA_T+wm{{jIDJ5 delta 3565 zcmXZec~I6x9LMoRJU~(|L5_?ELA*dtO;J1^H3U@f!n~-Mv^*lstkCR<@ksvw9W1TU z)JVlq8wHg}LnkJKoYBeDBptIs^F*7<#%w}+fBfw~zIOMw&+d1>-~IjYc8%AMHC_i+ z`gjf)W0uAn6NG&ejClr!Vhqm0Xe_~G{2Wv8ynXJ|&zSD?<8eIZVmNNaD6B;nHlaU0 zw9kDL*^7QmqVbpkG;;00YV@XGjcu_8{qQLIVgt6rGuRO?;8WO)f%rRyqF0hJZ7>Yy zVu3}E-F)xJv2Je2q&*PaZl8V;?V~OVGz1)e+p`&0#v}WF#s2$7A!#pv>A1P zZK!#b)@s~GzYaCeGmmiHG>WhnR$&}o#0BV;W=xizV>#BM?nq95rxf#0rCErbaVaYB zwbpV}0GsXeU8oEkMh@aJ4Nk+HM%DH_DzZyh=4H$k)B;7%IvFZPW#B#3_$u39Z~L22 znXIt=N^7;X&OUE^(x?8XXaw_vCR6||7=eGHPSRi+$%JcC_ ziBRjz##nqGV{j*G-uKv^{mmH~IoO1}StfQ6i{V74<4Z2>qn?N@XTQ6WEmJo zzYsNlEh_MRs7zfzt^X@3(|1sTJRVH_H4rq!d2i#eC;bf6hO@CZEDIZZlf8plcpK_C%;ENb2*R3?AJe7ukPz~#7|l1;-D`mZCG-D4_f>}KExRLzPa}|XRhs4aG?rpl+=DKxw_e3)`fbNJ<8i3eXQJ-L^fBaLC#`1c@~_Bi z7|?>JQ43tL6Rx5HdWc-)Cx65{fIHjyl4Ya%1*n6}!QQyc_IIK-K7z5>fLgBwwclSJ z8ahGS9A{z>_M{($9WfLAa3Z$D0_)4D=krhjEI}V!juE&T^*^D{Pyy6p4?KbKcn71< z6E@a4@j%o-5mb$v zQGx!0y8W?vPN`<1{{EOnG?cP0P?x9?PvSN7!~GMS0FR<>`!!T8y*OqX#$htfu$H1O z-Eq_{Z^k$rG|4H+i>UqHMnAp(NBx3jza}F6IJ_H zF$fo7Ag;7-M5TN;s+9G(1{=_$ROU@_YBU#h2TD*ItVP{{k5O+$1!|*RsFLl+F4%;c ze;2j!f2jGLIlkrxp&KJnB`QD#x;mfyQx@|H16t@7Dm9NV0K=y`uS*{crk{)&AB~}y zkJ|V(R3_d<9bgS=o%N{sdr>F<8vXGb)ciA3$-f$x8K}csc4Fo8#&8I;5Bp%7Y0hOz zz+(C%@hz;w<(M|zIZ-w0#3xXJoyJah*^b|_-bcN@tw}U=seEQQ8R&ufK%`qoplUt_ zmD2GC!$ZqL+s#;(w0zdVWAUH*Y\n" "Language: tr_TR\n" @@ -337,12 +337,13 @@ msgid "White list" msgstr "Beyaz liste" #: application/templates/adv_whitelist.html:15 +#, python-format msgid "" "Emails sent to %(name)sxxx@%(mailHost)s will be transferred to your " "kindle email." msgstr "" -"%(name)sxxx@%(mailHost)s adresine gönderilen emailler admin " -"hesabına bağlı Kindle'a gönderilecek." +"%(name)sxxx@%(mailHost)s adresine gönderilen emailler admin hesabına " +"bağlı Kindle'a gönderilecek." #: application/templates/adv_whitelist.html:27 msgid "Please input mail address" @@ -487,10 +488,10 @@ msgstr "Teşekkürler" msgid "" "Your recipe has been uploaded, and it can be found in the Library " "section. If you dont see it, please make sure to switch to the correct " -"language." +"language ({0})." msgstr "" "Tarifiniz yüklendi ve Kütüphane bölümünde bulunabilir. Görmüyorsanız, " -"lütfen doğru dile geçtiğinizden emin olun." +"lütfen doğru dile geçtiğinizden emin olun ({0})." #: application/templates/base.html:55 msgid "Your recipe have been deleted." @@ -504,7 +505,7 @@ msgstr "Kindle'laştırma Seçimi" msgid "Verified" msgstr "Doğrulanmış" -#: application/templates/base.html:59 application/view/login.py:78 +#: application/templates/base.html:59 application/view/login.py:81 #: application/view/share.py:154 msgid "The username does not exist or password is wrong." msgstr "Kullanıcı adı mevcut değil veya şifre yanlış." @@ -608,7 +609,7 @@ msgstr "Kullanıcı adı veya şifre boş." #: application/templates/base.html:84 application/view/admin.py:86 #: application/view/admin.py:165 application/view/admin.py:205 -#: application/view/login.py:219 application/view/login.py:279 +#: application/view/login.py:222 application/view/login.py:282 msgid "The two new passwords are dismatch." msgstr "İki yeni şifre uyuşmuyor." @@ -620,7 +621,7 @@ msgstr "Şifre başarıyla değiştirildi." msgid "Account added successfully." msgstr "Hesap başarıyla eklendi." -#: application/templates/base.html:87 application/view/login.py:129 +#: application/templates/base.html:87 application/view/login.py:132 msgid "login required" msgstr "Giriş yapılması gerekiyor" @@ -660,10 +661,13 @@ msgstr "Emb" #: application/templates/base.html:95 msgid "" -"The test email has been successfully sent to [{0}]. Please check your " -"inbox or spam folder to confirm its delivery. Depending on your email " -"server, there may be a slight delay." -msgstr "Test e-postası başarıyla [{0}] adresine gönderildi. Teslimatını onaylamak için gelen kutunuzu veya spam klasörünüzü kontrol edin. E-posta sunucunuza bağlı olarak hafif bir gecikme olabilir." +"The test email has been successfully sent to the following addresses. " +"Please check your inbox or spam folder to confirm its delivery. Depending" +" on your email server, there may be a slight delay." +msgstr "" +"Test e-postası başarıyla adresine gönderildi. Teslimatını onaylamak" +" için gelen kutunuzu veya spam klasörünüzü kontrol edin. E-posta " +"sunucunuza bağlı olarak hafif bir gecikme olabilir." #: application/templates/base.html:117 application/templates/home.html:12 msgid "Logout" @@ -845,14 +849,17 @@ msgid "" "With the open-source %(kindleear)s application, you can set up your own " "server to deliver daily news feeds to your e-reader and effortlessly " "share the service with friends." -msgstr "Açık kaynaklı %(kindleear)s uygulaması ile kendi sunucunuzu kurarak günlük haber akışlarınızı e-okuyucunuza teslim edebilir ve hizmeti dostlarınızla kolayca paylaşabilirsiniz." +msgstr "" +"Açık kaynaklı %(kindleear)s uygulaması ile kendi sunucunuzu kurarak " +"günlük haber akışlarınızı e-okuyucunuza teslim edebilir ve hizmeti " +"dostlarınızla kolayca paylaşabilirsiniz." #: application/templates/library.html:50 application/templates/my.html:62 msgid "Search" msgstr "Ara" -#: application/templates/login.html:34 application/view/login.py:196 -#: application/view/login.py:203 +#: application/templates/login.html:34 application/view/login.py:199 +#: application/view/login.py:206 msgid "" "The website does not allow registration. You can ask the owner for an " "account." @@ -1105,7 +1112,7 @@ msgstr "" msgid "Personal Document Settings" msgstr "Ayarları kaydet" -#: application/templates/setting.html:239 application/view/setting.py:130 +#: application/templates/setting.html:239 application/view/setting.py:134 msgid "" "You have not yet set up your email address. Please go to the 'Admin' page" " to add your email address firstly." @@ -1125,7 +1132,7 @@ msgstr "Davetiye kodu" msgid "User account" msgstr "Kullanıcı hesabı" -#: application/view/admin.py:51 application/view/adv.py:353 +#: application/view/admin.py:51 application/view/adv.py:350 #: application/view/setting.py:96 application/view/subscribe.py:241 msgid "Settings Saved!" msgstr "Ayarlar Kaydedildi!" @@ -1141,23 +1148,23 @@ msgid "You do not have sufficient privileges." msgstr "Yeterli yetkiniz yok." #: application/view/admin.py:82 application/view/admin.py:152 -#: application/view/login.py:215 application/view/login.py:244 +#: application/view/login.py:218 application/view/login.py:247 #: application/view/setting.py:61 application/view/setting.py:63 #: application/view/setting.py:65 application/view/share.py:36 msgid "Some parameters are missing or wrong." msgstr "Bazı parametreler eksik veya yanlış." #: application/view/admin.py:84 application/view/login.py:40 -#: application/view/login.py:221 +#: application/view/login.py:224 msgid "The username includes unsafe chars." msgstr "Kullanıcı adı güvensiz karakterler içeriyor." -#: application/view/admin.py:88 application/view/login.py:223 +#: application/view/admin.py:88 application/view/login.py:226 msgid "Already exist the username." msgstr "Kullanıcı adı zaten var." #: application/view/admin.py:93 application/view/admin.py:171 -#: application/view/admin.py:198 application/view/login.py:270 +#: application/view/admin.py:198 application/view/login.py:273 msgid "The password includes non-ascii chars." msgstr "Şifre ascii olmayan karakterler içeriyor." @@ -1240,19 +1247,19 @@ msgstr "tumblr" msgid "Open in browser" msgstr "Tarayıcıda aç" -#: application/view/adv.py:355 +#: application/view/adv.py:352 msgid "The format is invalid." msgstr "Format geçersiz." -#: application/view/adv.py:388 +#: application/view/adv.py:385 msgid "Authorization Error!
{}" msgstr "Yetkilendirme Hatası!
{}" -#: application/view/adv.py:411 +#: application/view/adv.py:408 msgid "Success authorized by Pocket!" msgstr "Pocket tarafından yetkilendirilen başarı!" -#: application/view/adv.py:417 +#: application/view/adv.py:414 msgid "" "Failed to request authorization of Pocket!
See details " "below:

{}" @@ -1260,17 +1267,17 @@ msgstr "" "Pocket yetkilendirme isteği başarısız oldu!
Aşağıdaki ayrıntılara " "bakın:

{}" -#: application/view/adv.py:427 +#: application/view/adv.py:424 msgid "Request type [{}] unsupported" msgstr "İstek türü [{}] desteklenmiyor" -#: application/view/adv.py:442 +#: application/view/adv.py:439 msgid "The Instapaper service encountered an error. Please try again later." msgstr "" "Instapaper servisi bir hata ile karşılaştı. Lütfen daha sonra tekrar " "deneyin." -#: application/view/deliver.py:67 application/view/login.py:166 +#: application/view/deliver.py:67 application/view/login.py:169 #: application/view/share.py:40 msgid "The username does not exist or the email is empty." msgstr "Kullanıcı adı mevcut değil veya e-posta boş." @@ -1290,11 +1297,11 @@ msgstr "{}, durumundan veri alınamıyor: {}" #: application/view/library.py:51 application/view/subscribe.py:195 #: application/view/subscribe.py:221 application/view/subscribe.py:272 #: application/view/subscribe.py:301 application/view/subscribe.py:421 -#: application/view/subscribe.py:450 application/view/subscribe.py:458 +#: application/view/subscribe.py:449 application/view/subscribe.py:456 msgid "The recipe does not exist." msgstr "Tarif mevcut değil." -#: application/view/login.py:26 +#: application/view/login.py:26 application/view/login.py:78 msgid "Please use {}/{} to login at first time." msgstr "İlk giriş için kullanıcı adı:'{}' ve şifre: '{}'" @@ -1306,65 +1313,65 @@ msgstr "Kullanıcı adı boş." msgid "The len of username reached the limit of 25 chars." msgstr "Kullanıcı adının uzunluğu 25 karakter sınırına ulaştı." -#: application/view/login.py:79 +#: application/view/login.py:82 msgid "Forgot password?" msgstr "Forgot password?" -#: application/view/login.py:145 application/view/login.py:281 +#: application/view/login.py:148 application/view/login.py:284 msgid "The token is wrong or expired." msgstr "Belirteç yanlış veya süresi dolmuş." -#: application/view/login.py:148 +#: application/view/login.py:151 msgid "Please input the correct username and email to reset password." msgstr "" "Şifreyi sıfırlamak için lütfen doğru kullanıcı adı ve e-posta adresini " "girin." -#: application/view/login.py:150 +#: application/view/login.py:153 msgid "The email of account '{name}' is {email}." msgstr "'{name}' hesabının e-postası {email}." -#: application/view/login.py:171 +#: application/view/login.py:174 msgid "Reset password success, Please close this page and login again." msgstr "" "Şifre sıfırlama başarılı, Lütfen bu sayfayı kapatın ve yeniden giriş " "yapın." -#: application/view/login.py:174 +#: application/view/login.py:177 msgid "The email you input is not associated with this account." msgstr "Girdiğiniz e-posta bu hesapla ilişkilendirilmemiştir." -#: application/view/login.py:185 +#: application/view/login.py:188 msgid "The link to reset your password has been sent to your email." msgstr "Şifrenizi sıfırlamak için gerekli bağlantı e-postanıza gönderilmiştir." -#: application/view/login.py:186 +#: application/view/login.py:189 msgid "Please check your email inbox within 24 hours." msgstr "Lütfen e-posta gelen kutunuzu 24 saat içinde kontrol edin." -#: application/view/login.py:217 +#: application/view/login.py:220 msgid "The invitation code is invalid." msgstr "Davetiye kodu geçersiz." -#: application/view/login.py:225 +#: application/view/login.py:228 msgid "" "Failed to create an account. Please contact the administrator for " "assistance." msgstr "Bir hesap oluşturulamadı. Yardım için lütfen yöneticiyle iletişime geçin." -#: application/view/login.py:235 +#: application/view/login.py:238 msgid "Successfully created account." msgstr "Hesap başarıyla oluşturuldu." -#: application/view/login.py:246 +#: application/view/login.py:249 msgid "Reset KindleEar password" msgstr "KindleEar şifrenizi sıfırlama" -#: application/view/login.py:247 +#: application/view/login.py:250 msgid "This is an automated email. Please do not reply to it." msgstr "Bu otomatik bir e-postadır. Lütfen yanıt vermeyin." -#: application/view/login.py:248 +#: application/view/login.py:251 msgid "You can click the following link to reset your KindleEar password." msgstr "" "KindleEar şifrenizi sıfırlamak için aşağıdaki bağlantıya " @@ -1378,107 +1385,107 @@ msgstr "Kindle E-mail adresi gerekli!" msgid "Title is requied!" msgstr "Başlık zorunlu!" -#: application/view/setting.py:153 +#: application/view/setting.py:157 msgid "Chinese" msgstr "Çince" -#: application/view/setting.py:154 +#: application/view/setting.py:158 msgid "English" msgstr "İngilizce" -#: application/view/setting.py:155 +#: application/view/setting.py:159 msgid "French" msgstr "Fransızca" -#: application/view/setting.py:156 +#: application/view/setting.py:160 msgid "Spanish" msgstr "İspanyolca" -#: application/view/setting.py:157 +#: application/view/setting.py:161 msgid "Portuguese" msgstr "Portekizce" -#: application/view/setting.py:158 +#: application/view/setting.py:162 msgid "German" msgstr "Almanca" -#: application/view/setting.py:159 +#: application/view/setting.py:163 msgid "Italian" msgstr "İtalyanca" -#: application/view/setting.py:160 +#: application/view/setting.py:164 msgid "Japanese" msgstr "Japonca" -#: application/view/setting.py:161 +#: application/view/setting.py:165 msgid "Russian" msgstr "Rusça" -#: application/view/setting.py:162 +#: application/view/setting.py:166 msgid "Turkish" msgstr "Türkçe" -#: application/view/setting.py:163 +#: application/view/setting.py:167 msgid "Korean" msgstr "Koreli" -#: application/view/setting.py:164 +#: application/view/setting.py:168 msgid "Arabic" msgstr "Arapça" -#: application/view/setting.py:165 +#: application/view/setting.py:169 msgid "Czech" msgstr "Çek" -#: application/view/setting.py:166 +#: application/view/setting.py:170 msgid "Dutch" msgstr "Flemenkçe" -#: application/view/setting.py:167 +#: application/view/setting.py:171 msgid "Greek" msgstr "Yunan" -#: application/view/setting.py:168 +#: application/view/setting.py:172 msgid "Hindi" msgstr "Hintçe" -#: application/view/setting.py:169 +#: application/view/setting.py:173 msgid "Malaysian" msgstr "Malezyalı" -#: application/view/setting.py:170 +#: application/view/setting.py:174 msgid "Bengali" msgstr "Bengal" -#: application/view/setting.py:171 +#: application/view/setting.py:175 msgid "Persian" msgstr "Farsça" -#: application/view/setting.py:172 +#: application/view/setting.py:176 msgid "Urdu" msgstr "Urduca" -#: application/view/setting.py:173 +#: application/view/setting.py:177 msgid "Swahili" msgstr "Svahili" -#: application/view/setting.py:174 +#: application/view/setting.py:178 msgid "Vietnamese" msgstr "Vietnam" -#: application/view/setting.py:175 +#: application/view/setting.py:179 msgid "Punjabi" msgstr "Pencap" -#: application/view/setting.py:176 +#: application/view/setting.py:180 msgid "Javanese" msgstr "Cava" -#: application/view/setting.py:177 +#: application/view/setting.py:181 msgid "Tagalog" msgstr "Tagalog" -#: application/view/setting.py:178 +#: application/view/setting.py:182 msgid "Hausa" msgstr "Hausa" diff --git a/application/translations/zh/LC_MESSAGES/messages.mo b/application/translations/zh/LC_MESSAGES/messages.mo index a231ad6f63018d71baad77c90a94124bfff3257b..c50eebe2352a9f786cfe0ca59484545176428058 100644 GIT binary patch delta 3600 zcmXxmdra3=7{~ELD57Y<4+RucR5TP!P{F*RsHlLN*I8K>6TBparG}RFGiuIzDmAs~ zlETfrp^}$sp(SnVyz6vkc?BJzo3|{TW$#blr@vn3Ip1@h^PKZNUw)k59Psz%fbAa# z`+suIy_e{m4|{iXt_2RqHduhIuo#nZ7k0)Q_Pp71&b1~^!(o_%O>sN6#KRbizhfwd zbn>3ZU;=SUC+BymG;*wCH3kw_VjVn)A$Sz)<9V!$*RTQBU_-o*;TVwQTqH)|Q`iBg zVn=L@Yp@A!L*=bZ@_P?X(4mCYr~+|aIuozX)R@4S| zpvHY`R^k@ogK;Y{4)>$-RAUh9ySp^>6+FZQOzQ4jTYLre85N->e2Mzp$}B#GI{Hf%*O(7b z^8$N#^V*n6W^XeK{YpHRMkwZ@F5?Wd2(^Rds2%M^J_NVV`fsD|Omt5^HB2}2QR7yj z<{dPTqt-i%I@xPIIe&FLphE=&_VSK00yQxab=kV0CXBTHJk-2=bGG%*N1e!0>tAJ- znmbUhwgNToOfSw~3tgl`R@=av=0l93Kd84ip*3pZM6X6^)<9hP@;RNid|oCfiTpHpe8?kq^+Homr!bYC(F`-yfw`yx3Q-e2uz0b#5>?0=R3T-kh4-Q6A3}a{-LI%|Ap`iS#a5`# zax4zR1?bm8=V)l5i>SEP;=2|JgRlfu;6~JC+liWY(!7Yu zUptWVSK}W#bd=$PyaijKcG4DuFbz2bmtpZDd%nWrO{fKSpe|j7#lM(0tp7eLU)W%8 zd{jIQ6%c0~-B1+|K?FI^6ZBOuJFz4qclX zzf5i>w!t!d22Z0Fx`Vo&jrg;n-^(;qf%&MsbFz6^`c6KfBLz31CR|2M2p{4N?1M@? z68SI2O+yt_ihb}qY=w`^=0lxZL7awK@C3%UkD+)L8{&1;0{1L_WY6o3@Ct}Rjf+8ErQgNV2&ZEZHo%uq335>t zPqnxJdlJ8kDrhHa=f{v=G>;0RRS@u&^vp-+FT3#_Ba1}w3- z7?p4x`fw|%p#7+Xm8j<@%`3Q#_zr5^`cdB9D8&xMRj9&4M^gkQ-~iTli)bvv#m2v%G`D?mX3Ad;x^_(J9Gl#&M{>9F i?9|7R4XeK2P_=h)_1f*#>*kdY9a>ZG|G}wazWNu@sHva; delta 3566 zcmXZedra0<9LMoPC<1~CB0gj&isA*l0AUI$<^}H;3^uL2l{H1j=wcb=eql|eNDbS_ zOex){uEAvvWwSnpE{qgtx>vg{8`aS14=XsucyMoT|3aWWK z)T?pM6{k2Cjmd+Z>xpA95$9uXEWuRViD}qu?V&@Q>qDG^GjSHi;dbnW2QdN9VP|Z! z_OPL>MVvU)d2Tp`Syr(YgNbXg9e#-&u^z+lB(}#!49A}^0$VT&|H4=d8s^+X7{KM& z17mO8`0++D^wqOAN#I6|3F=$|SGZEE)D28Afl+u9byD{|3Xv4zI9KhsKWaxQ7>Xk?8pm0jk6LH}D&gm_3l^a!EI}o-6}5p% zRKIGo7IzbWjq2wWknT7Ng*X8BViI1!6&UoWb5qog<#-TvN2X=?A4LJ`qbb5pSd2=% z)GS9Ou+`eDP$#e-*@)*(`UUp`>a%S|Wp)uugPi-t+Lt}%@2CiMQmarWvD)IdEiOgv ze3Qi=nw4giweP_&)_40U=*W*+htt@NxCx{2n$_P$^$Q;1+r^AW-H}14g~y{3n}+>y z4)S1JG4{pJQ1hI@5Y~4WDCiYj!DI}KbgmyxKs}=Z)PQ$T&#l7ZL-^oTSlnn{Mvc2} zamP%5e8B8yrlF^avnh1O>8Q*2v{``K!79{_K0zLWtG4=cs5|4b*gXt1^HBXf)VLb+ z0BXG>sFVFZi}P2-Wh#`wbqwHtsDUw~{L9t@H6RmJKLa%`&s=Qvg{Tu*Y4x62W^O@! zv{k5nhevV#ny`TidB!^aXkNh{)Zao42p{b)9Aox2hoHu1nd49!nqu)h)I5t&&-D$| zeD8S_bn7cnJKSd0;8fz{sMpYGjB}r2G-{!Js1vBS_!Mfwv)C2SqwdsA|Y=7sA za3b+5*b}|O6g1IARK|ax7HCB+d>=J&@L0b-5*5doJ;xg0*H=`D= zLN2@KPEgoG#cfm~m5=+Ea5w5M96~MFgi7#dRKJ_31@BmU5Z_{|?}(3J0CnUUsD8QT zT+|&{h!J}KD=BD!HK-kzp$2R+D^L?}M-AMCO5__<|3+(XM$OY=^*1d3+q{FCr`>qp zD2!%(*OS7-n5qh#j!Ix5YQXarzhoAp5-C9?Qh{2y8Z~||@=NQ!MfLj!Gcas||17g{ zCUFsZTIeVRE!2RDn=HOy@$aYwZlNY@wYU>ENec#0s0G6&`3Xg02yqg!X*by77p?s@i_1|9Y(ZVRDvOVqXRZDcYQ9#hzwc2{ z0uht_33{P2PC@Npn$_o{20mjhv-Tp3i_H?$QLjhMyB#&pUhISQ*cUIO`gy@q{2j-k zP9Pq&lfh;tYT-$!oz1kk05!o2$i;T+to}RHnt>x$agK-6Ec$;j`M=jKyL zq@n`ju^zS1dDM@{zo?(jB)(0QU><7XC8$^PDrR6gs{bie|29;={?q+=Gm-x^ZZ0aJ zGR)Td-$9`_6)k4F8P2^+oP=7i78CFo>XQD7O7Je~C zI)R{Bz6to?{by5%qhStef)%Leu>m#F3Dl*$g8C?~Vg%kW+su&J{%744)gF%;KM1>H zjsd{fpf>H&_Y3T{9msqj3n-dN-P~U@mLJQNf?c}7B4}y7h1d$HJ^vk zxDl1m4%B>AsP?)!eEupNr{W82vW{z>(B*J$Ee^s4ROYvF0Y>Ke-v=vjJ@H=DiDc&c z|AOaXN8+XC%NR=hrdf(QvGQRQl+iZxbJR`_m`BVL)_%G!E_Op~`=?$Xwt9Zuk(6zr mn-^!ahNlls%ScE|%}h`VP?c=} diff --git a/application/translations/zh/LC_MESSAGES/messages.po b/application/translations/zh/LC_MESSAGES/messages.po index 4397d91f..4ceb78d9 100644 --- a/application/translations/zh/LC_MESSAGES/messages.po +++ b/application/translations/zh/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: KindleEar v3.0.0\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-25 21:13-0300\n" +"POT-Creation-Date: 2024-04-02 17:17-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh\n" @@ -335,6 +335,7 @@ msgid "White list" msgstr "邮件白名单" #: application/templates/adv_whitelist.html:15 +#, python-format msgid "" "Emails sent to %(name)sxxx@%(mailHost)s will be transferred to your " "kindle email." @@ -481,8 +482,8 @@ msgstr "谢谢" msgid "" "Your recipe has been uploaded, and it can be found in the Library " "section. If you dont see it, please make sure to switch to the correct " -"language." -msgstr "您的Recipe已经上传,可以在本页面的 \"新闻源\" 区段找到。如果没有,请确认您已经切换到正确的语种。" +"language ({0})." +msgstr "您的Recipe已经上传,可以在本页面的 \"新闻源\" 区段找到。如果没有,请确认您已经切换到正确的语种 ({0})。" #: application/templates/base.html:55 msgid "Your recipe have been deleted." @@ -496,7 +497,7 @@ msgstr "选择内容发送到Kindle" msgid "Verified" msgstr "已校验" -#: application/templates/base.html:59 application/view/login.py:78 +#: application/templates/base.html:59 application/view/login.py:81 #: application/view/share.py:154 msgid "The username does not exist or password is wrong." msgstr "用户名不存在或密码错误。" @@ -600,7 +601,7 @@ msgstr "用户名或密码为空。" #: application/templates/base.html:84 application/view/admin.py:86 #: application/view/admin.py:165 application/view/admin.py:205 -#: application/view/login.py:219 application/view/login.py:279 +#: application/view/login.py:222 application/view/login.py:282 msgid "The two new passwords are dismatch." msgstr "两个密码不匹配。" @@ -612,7 +613,7 @@ msgstr "修改密码成功。" msgid "Account added successfully." msgstr "添加账号成功。" -#: application/templates/base.html:87 application/view/login.py:129 +#: application/templates/base.html:87 application/view/login.py:132 msgid "login required" msgstr "需要登录" @@ -650,10 +651,10 @@ msgstr "Emb" #: application/templates/base.html:95 msgid "" -"The test email has been successfully sent to [{0}]. Please check your " -"inbox or spam folder to confirm its delivery. Depending on your email " -"server, there may be a slight delay." -msgstr "测试邮件已经成功发送到 [{0}], 请打开收件箱或垃圾箱确认是否到达,根据服务器不同,可能稍有延迟。" +"The test email has been successfully sent to the following addresses. " +"Please check your inbox or spam folder to confirm its delivery. Depending" +" on your email server, there may be a slight delay." +msgstr "测试邮件已经成功发送到以下地址, 请打开收件箱或垃圾箱确认是否到达,根据服务器不同,可能稍有延迟。" #: application/templates/base.html:117 application/templates/home.html:12 msgid "Logout" @@ -837,8 +838,8 @@ msgstr "使用开源 %(kindleear)s 应用,您可以部署您自己的网站, msgid "Search" msgstr "搜索" -#: application/templates/login.html:34 application/view/login.py:196 -#: application/view/login.py:203 +#: application/templates/login.html:34 application/view/login.py:199 +#: application/view/login.py:206 msgid "" "The website does not allow registration. You can ask the owner for an " "account." @@ -1086,7 +1087,7 @@ msgstr "" msgid "Personal Document Settings" msgstr "个人文档设置" -#: application/templates/setting.html:239 application/view/setting.py:130 +#: application/templates/setting.html:239 application/view/setting.py:134 msgid "" "You have not yet set up your email address. Please go to the 'Admin' page" " to add your email address firstly." @@ -1104,7 +1105,7 @@ msgstr "邀请码" msgid "User account" msgstr "账号" -#: application/view/admin.py:51 application/view/adv.py:353 +#: application/view/admin.py:51 application/view/adv.py:350 #: application/view/setting.py:96 application/view/subscribe.py:241 msgid "Settings Saved!" msgstr "恭喜,保存成功!" @@ -1120,23 +1121,23 @@ msgid "You do not have sufficient privileges." msgstr "您没有足够的权限。" #: application/view/admin.py:82 application/view/admin.py:152 -#: application/view/login.py:215 application/view/login.py:244 +#: application/view/login.py:218 application/view/login.py:247 #: application/view/setting.py:61 application/view/setting.py:63 #: application/view/setting.py:65 application/view/share.py:36 msgid "Some parameters are missing or wrong." msgstr "一些参数为空或错误。" #: application/view/admin.py:84 application/view/login.py:40 -#: application/view/login.py:221 +#: application/view/login.py:224 msgid "The username includes unsafe chars." msgstr "用户名包含不安全字符。" -#: application/view/admin.py:88 application/view/login.py:223 +#: application/view/admin.py:88 application/view/login.py:226 msgid "Already exist the username." msgstr "此账号已经存在。" #: application/view/admin.py:93 application/view/admin.py:171 -#: application/view/admin.py:198 application/view/login.py:270 +#: application/view/admin.py:198 application/view/login.py:273 msgid "The password includes non-ascii chars." msgstr "密码包含非ASCII字符。" @@ -1219,33 +1220,33 @@ msgstr "tumblr" msgid "Open in browser" msgstr "在浏览器打开" -#: application/view/adv.py:355 +#: application/view/adv.py:352 msgid "The format is invalid." msgstr "格式非法。" -#: application/view/adv.py:388 +#: application/view/adv.py:385 msgid "Authorization Error!
{}" msgstr "申请授权过程失败!
{}" -#: application/view/adv.py:411 +#: application/view/adv.py:408 msgid "Success authorized by Pocket!" msgstr "已经成功获得Pocket的授权!" -#: application/view/adv.py:417 +#: application/view/adv.py:414 msgid "" "Failed to request authorization of Pocket!
See details " "below:

{}" msgstr "申请Pocket授权失败!
错误信息参考如下:

{}" -#: application/view/adv.py:427 +#: application/view/adv.py:424 msgid "Request type [{}] unsupported" msgstr "不支持你请求的命令类型 [{}]" -#: application/view/adv.py:442 +#: application/view/adv.py:439 msgid "The Instapaper service encountered an error. Please try again later." msgstr "Instapaper服务器异常,请稍候再试。" -#: application/view/deliver.py:67 application/view/login.py:166 +#: application/view/deliver.py:67 application/view/login.py:169 #: application/view/share.py:40 msgid "The username does not exist or the email is empty." msgstr "用户名不存在或email为空。" @@ -1265,11 +1266,11 @@ msgstr "无法从 {} 获取数据,状态: {}" #: application/view/library.py:51 application/view/subscribe.py:195 #: application/view/subscribe.py:221 application/view/subscribe.py:272 #: application/view/subscribe.py:301 application/view/subscribe.py:421 -#: application/view/subscribe.py:450 application/view/subscribe.py:458 +#: application/view/subscribe.py:449 application/view/subscribe.py:456 msgid "The recipe does not exist." msgstr "此Recipe不存在。" -#: application/view/login.py:26 +#: application/view/login.py:26 application/view/login.py:78 msgid "Please use {}/{} to login at first time." msgstr "初次登录请使用用户名'{}'/密码'{}'。" @@ -1281,61 +1282,61 @@ msgstr "账号名为空。" msgid "The len of username reached the limit of 25 chars." msgstr "用户名超过25字符。" -#: application/view/login.py:79 +#: application/view/login.py:82 msgid "Forgot password?" msgstr "忘记密码?" -#: application/view/login.py:145 application/view/login.py:281 +#: application/view/login.py:148 application/view/login.py:284 msgid "The token is wrong or expired." msgstr "Token码错误或已经逾期。" -#: application/view/login.py:148 +#: application/view/login.py:151 msgid "Please input the correct username and email to reset password." msgstr "请输入正确的用户名和Email来重置密码。" -#: application/view/login.py:150 +#: application/view/login.py:153 msgid "The email of account '{name}' is {email}." msgstr "账号 '{name}' 的Email为 {email}" -#: application/view/login.py:171 +#: application/view/login.py:174 msgid "Reset password success, Please close this page and login again." msgstr "修改密码成功,请关闭此页面重新登录。" -#: application/view/login.py:174 +#: application/view/login.py:177 msgid "The email you input is not associated with this account." msgstr "您输入的email不正确。" -#: application/view/login.py:185 +#: application/view/login.py:188 msgid "The link to reset your password has been sent to your email." msgstr "重置密码的邮件已经被发送至你的email。" -#: application/view/login.py:186 +#: application/view/login.py:189 msgid "Please check your email inbox within 24 hours." msgstr "请在24小时内检查你的email收件箱。" -#: application/view/login.py:217 +#: application/view/login.py:220 msgid "The invitation code is invalid." msgstr "邀请码无效。" -#: application/view/login.py:225 +#: application/view/login.py:228 msgid "" "Failed to create an account. Please contact the administrator for " "assistance." msgstr "创建账号失败,请联系管理员请求协助。" -#: application/view/login.py:235 +#: application/view/login.py:238 msgid "Successfully created account." msgstr "成功创建账号。" -#: application/view/login.py:246 +#: application/view/login.py:249 msgid "Reset KindleEar password" msgstr "重置KindleEar密码" -#: application/view/login.py:247 +#: application/view/login.py:250 msgid "This is an automated email. Please do not reply to it." msgstr "这个是自动发送的邮件,请勿直接回复。" -#: application/view/login.py:248 +#: application/view/login.py:251 msgid "You can click the following link to reset your KindleEar password." msgstr "你可以点击下面的链接来重置你的KindleEar密码。" @@ -1347,107 +1348,107 @@ msgstr "Kindle E-mail必须填写!" msgid "Title is requied!" msgstr "书籍标题不能为空!" -#: application/view/setting.py:153 +#: application/view/setting.py:157 msgid "Chinese" msgstr "中文" -#: application/view/setting.py:154 +#: application/view/setting.py:158 msgid "English" msgstr "英语" -#: application/view/setting.py:155 +#: application/view/setting.py:159 msgid "French" msgstr "法语" -#: application/view/setting.py:156 +#: application/view/setting.py:160 msgid "Spanish" msgstr "西班牙语" -#: application/view/setting.py:157 +#: application/view/setting.py:161 msgid "Portuguese" msgstr "葡萄牙语" -#: application/view/setting.py:158 +#: application/view/setting.py:162 msgid "German" msgstr "德语" -#: application/view/setting.py:159 +#: application/view/setting.py:163 msgid "Italian" msgstr "意大利语" -#: application/view/setting.py:160 +#: application/view/setting.py:164 msgid "Japanese" msgstr "日语" -#: application/view/setting.py:161 +#: application/view/setting.py:165 msgid "Russian" msgstr "俄语" -#: application/view/setting.py:162 +#: application/view/setting.py:166 msgid "Turkish" msgstr "土耳其语" -#: application/view/setting.py:163 +#: application/view/setting.py:167 msgid "Korean" msgstr "韩语" -#: application/view/setting.py:164 +#: application/view/setting.py:168 msgid "Arabic" msgstr "阿拉伯语" -#: application/view/setting.py:165 +#: application/view/setting.py:169 msgid "Czech" msgstr "捷克语" -#: application/view/setting.py:166 +#: application/view/setting.py:170 msgid "Dutch" msgstr "荷兰语" -#: application/view/setting.py:167 +#: application/view/setting.py:171 msgid "Greek" msgstr "希腊语" -#: application/view/setting.py:168 +#: application/view/setting.py:172 msgid "Hindi" msgstr "印地语" -#: application/view/setting.py:169 +#: application/view/setting.py:173 msgid "Malaysian" msgstr "马来西亚语" -#: application/view/setting.py:170 +#: application/view/setting.py:174 msgid "Bengali" msgstr "孟加拉语" -#: application/view/setting.py:171 +#: application/view/setting.py:175 msgid "Persian" msgstr "波斯语" -#: application/view/setting.py:172 +#: application/view/setting.py:176 msgid "Urdu" msgstr "乌尔都语" -#: application/view/setting.py:173 +#: application/view/setting.py:177 msgid "Swahili" msgstr "斯瓦希里语" -#: application/view/setting.py:174 +#: application/view/setting.py:178 msgid "Vietnamese" msgstr "越南语" -#: application/view/setting.py:175 +#: application/view/setting.py:179 msgid "Punjabi" msgstr "旁遮普语" -#: application/view/setting.py:176 +#: application/view/setting.py:180 msgid "Javanese" msgstr "爪哇语" -#: application/view/setting.py:177 +#: application/view/setting.py:181 msgid "Tagalog" msgstr "他加禄语" -#: application/view/setting.py:178 +#: application/view/setting.py:182 msgid "Hausa" msgstr "豪萨语" diff --git a/application/view/adv.py b/application/view/adv.py index 18d1dc6c..374d908c 100644 --- a/application/view/adv.py +++ b/application/view/adv.py @@ -148,7 +148,7 @@ def AdvImportPost(): return adv_render_template('adv_import.html', 'import', user=user, tips=str(e)) for o in walkOpmlOutline(rssList): - title, url, isfulltext = xml_unescape(o.text), xml_unescape(o.xmlUrl), o.isFulltext #isFulltext为非标准属性 + title, url, isfulltext = xml_unescape(o.text), unquote(xml_unescape(o.xmlUrl)), o.isFulltext #isFulltext为非标准属性 if isfulltext: isfulltext = str_to_bool(isfulltext) else: diff --git a/application/view/login.py b/application/view/login.py index 7e25f1b2..cfa00b39 100644 --- a/application/view/login.py +++ b/application/view/login.py @@ -43,7 +43,7 @@ def LoginPost(): return render_template('login.html', tips=tips) adminName = app.config['ADMIN_NAME'] - CreateAccountIfNotExist(adminName) #确认管理员账号是否存在 + isFirstTime = CreateAccountIfNotExist(adminName) #确认管理员账号是否存在 u = KeUser.get_or_none(KeUser.name == name) if u: @@ -74,9 +74,12 @@ def LoginPost(): default_log.info(f"Login event: {name}") return redirect(url) else: #账号或密码错 - time.sleep(5) #防止暴力破解 - tips = (_("The username does not exist or password is wrong.") + - f'
' + _('Forgot password?') + '') + if isFirstTime: + tips = (_("Please use {}/{} to login at first time.").format(adminName, adminName)) + else: + time.sleep(5) #防止暴力破解 + tips = (_("The username does not exist or password is wrong.") + + f'
' + _('Forgot password?') + '') session.pop('login', None) session.pop('userName', None) diff --git a/application/view/logs.py b/application/view/logs.py index a7af2cb7..b3402826 100644 --- a/application/view/logs.py +++ b/application/view/logs.py @@ -42,6 +42,7 @@ def RemoveLogs(): #清理30天之前的推送记录 time30 = datetime.datetime.utcnow() - datetime.timedelta(days=30) cnt = DeliverLog.delete().where(DeliverLog.datetime < time30).execute() + cnt += LastDelivered.delete().where(LastDelivered.datetime < time30).execute() return "{} lines delivery log removed.".format(cnt) #查询推送记录,按时间倒排 diff --git a/application/work/worker.py b/application/work/worker.py index 890f78b1..c7e7afa1 100644 --- a/application/work/worker.py +++ b/application/work/worker.py @@ -60,6 +60,8 @@ def WorkerImpl(userName: str, recipeId: list=None, log=None): log.warning(ret) return ret + startTime = time.time() + #编译recipe srcDict = GetAllRecipeSrc(user, recipeId) #返回一个字典,键名为title,元素为 [BookedRecipe, Recipe, src] recipes = defaultdict(list) #用于保存编译好的recipe代码对象 @@ -106,7 +108,12 @@ def WorkerImpl(userName: str, recipeId: list=None, log=None): else: save_delivery_log(user, title, 0, status='nonews') - ret = '\n'.join(ret) if ret else "There are no new feeds available." + elaspTime = time.time() - startTime + if ret: + ret = '\n'.join(ret) + ret += f'\nTime: {elaspTime} seconds.' + else: + ret = "There are no new feeds available." log.warning(ret) return ret diff --git a/docs/Chinese/2.config.md b/docs/Chinese/2.config.md index aed9f29d..e12fabd2 100644 --- a/docs/Chinese/2.config.md +++ b/docs/Chinese/2.config.md @@ -25,7 +25,7 @@ sort: 2 ## 数据库选择 数据库用于保存应用的配置数据和订阅数据。 -得益于SQL数据库ORM库 [peewee](https://pypi.org/project/peewee/) 和作者因KindleEar需要而创建的NoSQL数据库ODM库 [weedata](https://pypi.org/project/weedata/),KindleEar支持很多数据库类型,包括:datastore, sqlite, mysql, postgresql, cockroachdb, mongodb, redis, pickle, 基本兼容了市面上的主流数据库,更适合全平台部署,平台支持什么数据库就可以使用什么数据库。 +得益于SQL数据库ORM库 [peewee](https://pypi.org/project/peewee/) 和作者因KindleEar需要而创建的NoSQL数据库ODM库 [weedata](https://github.com/cdhigh/weedata),KindleEar支持很多数据库类型,包括:datastore, sqlite, mysql, postgresql, cockroachdb, mongodb, redis, pickle, 基本兼容了市面上的主流数据库,更适合全平台部署,平台支持什么数据库就可以使用什么数据库。 如果目标平台同时支持SQL/NoSQL,则建议NoSQL,其最大的优点是万一以后升级需要修改数据库结构,则NoSQL不会影响原有数据,而SQL会删掉原数据。 本应用的数据量不大,确切的来说,很小很小,一般就几十行数据,选择什么数据库都不会对资源消耗和性能造成什么影响,即使最简单的就用一个文本文件当做数据库使用可能都会比其他正规的数据库要快。 diff --git a/docs/English/2.config.md b/docs/English/2.config.md index 98da58b7..ac16c4bb 100644 --- a/docs/English/2.config.md +++ b/docs/English/2.config.md @@ -25,7 +25,7 @@ This section describes several simple configuration items, with more detailed de ## Database Selection The database is used to store application configuration data and subscription data. -Thanks to the SQL database ORM library [peewee](https://pypi.org/project/peewee/) and the NoSQL database ODM library [weedata](https://pypi.org/project/weedata/) created by the author for KindleEar, KindleEar supports many types of databases, including: datastore, sqlite, mysql, postgresql, cockroachdb, mongodb, redis, pickle. +Thanks to the SQL database ORM library [peewee](https://pypi.org/project/peewee/) and the NoSQL database ODM library [weedata](https://github.com/cdhigh/weedata) created by the author for KindleEar, KindleEar supports many types of databases, including: datastore, sqlite, mysql, postgresql, cockroachdb, mongodb, redis, pickle. It basically covers the mainstream databases on the market and is more suitable for cross-platform deployment. You can use whatever database the platform supports. If the target platform supports both SQL and NoSQL, it is advisable to use NoSQL. Its major advantage is that in case of future upgrades requiring modifications to the database structure, NoSQL will not affect the existing data, whereas SQL would delete the original data. The amount of data in this application is very small, to be precise, very, very small, usually just a few dozen lines of data. Choosing any database will not have any impact on resource consumption and performance. Even using a simple text file as a database may be faster than other formal databases. diff --git a/messages.pot b/messages.pot index c98da5ea..ae5363d0 100644 --- a/messages.pot +++ b/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-25 21:13-0300\n" +"POT-Creation-Date: 2024-04-02 17:17-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -481,7 +481,7 @@ msgstr "" msgid "" "Your recipe has been uploaded, and it can be found in the Library " "section. If you dont see it, please make sure to switch to the correct " -"language." +"language ({0})." msgstr "" #: application/templates/base.html:55 @@ -496,7 +496,7 @@ msgstr "" msgid "Verified" msgstr "" -#: application/templates/base.html:59 application/view/login.py:78 +#: application/templates/base.html:59 application/view/login.py:81 #: application/view/share.py:154 msgid "The username does not exist or password is wrong." msgstr "" @@ -600,7 +600,7 @@ msgstr "" #: application/templates/base.html:84 application/view/admin.py:86 #: application/view/admin.py:165 application/view/admin.py:205 -#: application/view/login.py:219 application/view/login.py:279 +#: application/view/login.py:222 application/view/login.py:282 msgid "The two new passwords are dismatch." msgstr "" @@ -612,7 +612,7 @@ msgstr "" msgid "Account added successfully." msgstr "" -#: application/templates/base.html:87 application/view/login.py:129 +#: application/templates/base.html:87 application/view/login.py:132 msgid "login required" msgstr "" @@ -650,9 +650,9 @@ msgstr "" #: application/templates/base.html:95 msgid "" -"The test email has been successfully sent to [{0}]. Please check your " -"inbox or spam folder to confirm its delivery. Depending on your email " -"server, there may be a slight delay." +"The test email has been successfully sent to the following addresses. " +"Please check your inbox or spam folder to confirm its delivery. Depending" +" on your email server, there may be a slight delay." msgstr "" #: application/templates/base.html:117 application/templates/home.html:12 @@ -837,8 +837,8 @@ msgstr "" msgid "Search" msgstr "" -#: application/templates/login.html:34 application/view/login.py:196 -#: application/view/login.py:203 +#: application/templates/login.html:34 application/view/login.py:199 +#: application/view/login.py:206 msgid "" "The website does not allow registration. You can ask the owner for an " "account." @@ -1084,7 +1084,7 @@ msgstr "" msgid "Personal Document Settings" msgstr "" -#: application/templates/setting.html:239 application/view/setting.py:130 +#: application/templates/setting.html:239 application/view/setting.py:134 msgid "" "You have not yet set up your email address. Please go to the 'Admin' page" " to add your email address firstly." @@ -1102,7 +1102,7 @@ msgstr "" msgid "User account" msgstr "" -#: application/view/admin.py:51 application/view/adv.py:353 +#: application/view/admin.py:51 application/view/adv.py:350 #: application/view/setting.py:96 application/view/subscribe.py:241 msgid "Settings Saved!" msgstr "" @@ -1118,23 +1118,23 @@ msgid "You do not have sufficient privileges." msgstr "" #: application/view/admin.py:82 application/view/admin.py:152 -#: application/view/login.py:215 application/view/login.py:244 +#: application/view/login.py:218 application/view/login.py:247 #: application/view/setting.py:61 application/view/setting.py:63 #: application/view/setting.py:65 application/view/share.py:36 msgid "Some parameters are missing or wrong." msgstr "" #: application/view/admin.py:84 application/view/login.py:40 -#: application/view/login.py:221 +#: application/view/login.py:224 msgid "The username includes unsafe chars." msgstr "" -#: application/view/admin.py:88 application/view/login.py:223 +#: application/view/admin.py:88 application/view/login.py:226 msgid "Already exist the username." msgstr "" #: application/view/admin.py:93 application/view/admin.py:171 -#: application/view/admin.py:198 application/view/login.py:270 +#: application/view/admin.py:198 application/view/login.py:273 msgid "The password includes non-ascii chars." msgstr "" @@ -1217,33 +1217,33 @@ msgstr "" msgid "Open in browser" msgstr "" -#: application/view/adv.py:355 +#: application/view/adv.py:352 msgid "The format is invalid." msgstr "" -#: application/view/adv.py:388 +#: application/view/adv.py:385 msgid "Authorization Error!
{}" msgstr "" -#: application/view/adv.py:411 +#: application/view/adv.py:408 msgid "Success authorized by Pocket!" msgstr "" -#: application/view/adv.py:417 +#: application/view/adv.py:414 msgid "" "Failed to request authorization of Pocket!
See details " "below:

{}" msgstr "" -#: application/view/adv.py:427 +#: application/view/adv.py:424 msgid "Request type [{}] unsupported" msgstr "" -#: application/view/adv.py:442 +#: application/view/adv.py:439 msgid "The Instapaper service encountered an error. Please try again later." msgstr "" -#: application/view/deliver.py:67 application/view/login.py:166 +#: application/view/deliver.py:67 application/view/login.py:169 #: application/view/share.py:40 msgid "The username does not exist or the email is empty." msgstr "" @@ -1263,11 +1263,11 @@ msgstr "" #: application/view/library.py:51 application/view/subscribe.py:195 #: application/view/subscribe.py:221 application/view/subscribe.py:272 #: application/view/subscribe.py:301 application/view/subscribe.py:421 -#: application/view/subscribe.py:450 application/view/subscribe.py:458 +#: application/view/subscribe.py:449 application/view/subscribe.py:456 msgid "The recipe does not exist." msgstr "" -#: application/view/login.py:26 +#: application/view/login.py:26 application/view/login.py:78 msgid "Please use {}/{} to login at first time." msgstr "" @@ -1279,61 +1279,61 @@ msgstr "" msgid "The len of username reached the limit of 25 chars." msgstr "" -#: application/view/login.py:79 +#: application/view/login.py:82 msgid "Forgot password?" msgstr "" -#: application/view/login.py:145 application/view/login.py:281 +#: application/view/login.py:148 application/view/login.py:284 msgid "The token is wrong or expired." msgstr "" -#: application/view/login.py:148 +#: application/view/login.py:151 msgid "Please input the correct username and email to reset password." msgstr "" -#: application/view/login.py:150 +#: application/view/login.py:153 msgid "The email of account '{name}' is {email}." msgstr "" -#: application/view/login.py:171 +#: application/view/login.py:174 msgid "Reset password success, Please close this page and login again." msgstr "" -#: application/view/login.py:174 +#: application/view/login.py:177 msgid "The email you input is not associated with this account." msgstr "" -#: application/view/login.py:185 +#: application/view/login.py:188 msgid "The link to reset your password has been sent to your email." msgstr "" -#: application/view/login.py:186 +#: application/view/login.py:189 msgid "Please check your email inbox within 24 hours." msgstr "" -#: application/view/login.py:217 +#: application/view/login.py:220 msgid "The invitation code is invalid." msgstr "" -#: application/view/login.py:225 +#: application/view/login.py:228 msgid "" "Failed to create an account. Please contact the administrator for " "assistance." msgstr "" -#: application/view/login.py:235 +#: application/view/login.py:238 msgid "Successfully created account." msgstr "" -#: application/view/login.py:246 +#: application/view/login.py:249 msgid "Reset KindleEar password" msgstr "" -#: application/view/login.py:247 +#: application/view/login.py:250 msgid "This is an automated email. Please do not reply to it." msgstr "" -#: application/view/login.py:248 +#: application/view/login.py:251 msgid "You can click the following link to reset your KindleEar password." msgstr "" @@ -1345,107 +1345,107 @@ msgstr "" msgid "Title is requied!" msgstr "" -#: application/view/setting.py:153 +#: application/view/setting.py:157 msgid "Chinese" msgstr "" -#: application/view/setting.py:154 +#: application/view/setting.py:158 msgid "English" msgstr "" -#: application/view/setting.py:155 +#: application/view/setting.py:159 msgid "French" msgstr "" -#: application/view/setting.py:156 +#: application/view/setting.py:160 msgid "Spanish" msgstr "" -#: application/view/setting.py:157 +#: application/view/setting.py:161 msgid "Portuguese" msgstr "" -#: application/view/setting.py:158 +#: application/view/setting.py:162 msgid "German" msgstr "" -#: application/view/setting.py:159 +#: application/view/setting.py:163 msgid "Italian" msgstr "" -#: application/view/setting.py:160 +#: application/view/setting.py:164 msgid "Japanese" msgstr "" -#: application/view/setting.py:161 +#: application/view/setting.py:165 msgid "Russian" msgstr "" -#: application/view/setting.py:162 +#: application/view/setting.py:166 msgid "Turkish" msgstr "" -#: application/view/setting.py:163 +#: application/view/setting.py:167 msgid "Korean" msgstr "" -#: application/view/setting.py:164 +#: application/view/setting.py:168 msgid "Arabic" msgstr "" -#: application/view/setting.py:165 +#: application/view/setting.py:169 msgid "Czech" msgstr "" -#: application/view/setting.py:166 +#: application/view/setting.py:170 msgid "Dutch" msgstr "" -#: application/view/setting.py:167 +#: application/view/setting.py:171 msgid "Greek" msgstr "" -#: application/view/setting.py:168 +#: application/view/setting.py:172 msgid "Hindi" msgstr "" -#: application/view/setting.py:169 +#: application/view/setting.py:173 msgid "Malaysian" msgstr "" -#: application/view/setting.py:170 +#: application/view/setting.py:174 msgid "Bengali" msgstr "" -#: application/view/setting.py:171 +#: application/view/setting.py:175 msgid "Persian" msgstr "" -#: application/view/setting.py:172 +#: application/view/setting.py:176 msgid "Urdu" msgstr "" -#: application/view/setting.py:173 +#: application/view/setting.py:177 msgid "Swahili" msgstr "" -#: application/view/setting.py:174 +#: application/view/setting.py:178 msgid "Vietnamese" msgstr "" -#: application/view/setting.py:175 +#: application/view/setting.py:179 msgid "Punjabi" msgstr "" -#: application/view/setting.py:176 +#: application/view/setting.py:180 msgid "Javanese" msgstr "" -#: application/view/setting.py:177 +#: application/view/setting.py:181 msgid "Tagalog" msgstr "" -#: application/view/setting.py:178 +#: application/view/setting.py:182 msgid "Hausa" msgstr "" diff --git a/tools/update_req.py b/tools/update_req.py index b5208bbb..789d3d86 100644 --- a/tools/update_req.py +++ b/tools/update_req.py @@ -99,15 +99,16 @@ def dockered_config_py(cfgFile): continue match = re.match(pattern, line) - if match: - name = match.group(1) - value = default_cfg.get(name, match.group(2)) + name = match.group(1) if match else None + value = default_cfg.get(name, None) + if name is not None and value is not None: ret.append(f'{name} = "{value}"') else: ret.append(line) with open(cfgFile, 'w', encoding='utf-8') as f: f.write('\n'.join(ret)) + print(f'Finished update {cfgFile}') if __name__ == '__main__': thisDir = os.path.abspath(os.path.dirname(__file__))