--gid gid Искать по id жанра
-l, --lang lang Искать по языку
--lid lid Искать по id языка
+ --filters Использовать фильтры из файла конфигурации
-P, --path path Путь к директории с архивами библиотеки
--download-to [path] Путь к директории для сохранения книг
-F, --format format Формат имени сохраняемого файла
Опция полезна в ситуации работы с несколькими базами данных (глобальная
опция `-D`).
+Опция `--filters` включает использование фильтров из файла конфигурации.
+Фильтры записываются следующим образом::
+
+ [filters]
+ lang = en ru
+ deleted = 0
+
+Фильтр `lang` перечисляет список языков, которыми будет ограничен поиск.
+Фильтр `deleted` — это флаг 0/1; 0 означает, что удалённые книги не
+будут найдены.
+
Опция `--download-to` задаёт путь к директории для сохранения книг.
По умолчанию скрипт сохраняет книги в текущую директорию.
Если опция используется без указания аргумента `path` скрипт использует
--gid gid Search by genre’s id
-l, --lang lang Search by language
--lid lid Search by language’s id
+ --filters Use filters from config
-P, --path path Path to the directory with the library
archives
--download-to [path] Download directory
The option is useful for multiple databases (global option `-D`).
+Option `--filters` turns on using filters from config. Currently there
+are two kind of filters: filters on languages and filter on flag
+`deleted`. They are defined in the config file the following way::
+
+ [filters]
+ lang = en ru
+ deleted = 0
+
+`lang` filters is a list of language codes separated by a space.
+`deleted` is a 0/1 flag; 0 hides deleted books from search.
+
Option `--download-to` provides the path to the download directory.
By default the script downloads books to the current directory.
If the option is used without `path` argument the path is extracted from
News
====
-Version 0.1.4 (2018-05-??)
+Version 0.1.4 (2018-06-??)
--------------------------
* Search by book's title.
+* Use filters from config.
+
Version 0.1.3 (2018-05-25)
--------------------------
+try:
+ from configparser import NoSectionError, NoOptionError
+except ImportError: # Python 2
+ from ConfigParser import NoSectionError, NoOptionError
-from sqlobject.sqlbuilder import AND, func
+from sqlobject.sqlbuilder import AND, OR, func
+from .config import get_config
from .db import Author, Book, Extension, Genre, Language
__all__ = [
def search_books(search_type, case_sensitive, values, join_expressions=None,
- orderBy=None):
- return _search(Book, search_type, case_sensitive, values,
- join_expressions=join_expressions, orderBy=orderBy)
+ orderBy=None, use_filters=False):
+ if use_filters:
+ config = get_config()
+ try:
+ lang_filter = config.get('filters', 'lang')
+ except (NoSectionError, NoOptionError):
+ lang_filter = None
+ try:
+ deleted_filter = config.getint('filters', 'deleted')
+ except (NoSectionError, NoOptionError):
+ deleted_filter = None
+ if lang_filter:
+ if join_expressions is None:
+ join_expressions = []
+ lang_conditions = []
+ for lang in lang_filter.split():
+ lvalues = {'name': lang}
+ conditions = mk_search_conditions(
+ Language, search_type, case_sensitive, lvalues)
+ lang_conditions.append(conditions)
+ join_expressions.append(Book.j.language)
+ join_expressions.append(OR(*lang_conditions))
+ conditions = mk_search_conditions(
+ Book, search_type, case_sensitive, values,
+ join_expressions=join_expressions)
+ if use_filters and not deleted_filter:
+ conditions.append(Book.q.deleted == False) # noqa: E712
+ return Book.select(AND(*conditions), orderBy=orderBy)
def search_extensions(search_type, case_sensitive, values, orderBy=None):
@route('/')
@cheetah_view('index.tmpl')
def index():
- return {}
+ return {
+ 'get_config': get_config,
+ }
@route('/search_authors', method='GET')
@route('/books-by-author/<id:int>/', method='GET')
@cheetah_view('books_by_author.tmpl')
def books_by_author(id):
- return {
- 'author': Author.get(id),
- 'books': Book.select(
- Book.j.authors & (Author.q.id == id),
- orderBy=['series', 'ser_no', 'title'],
- )
- }
+ use_filters = get_config().getint('filters', 'use_in_books_list')
+ if use_filters:
+ join_expressions = []
+ join_expressions.append(Book.j.authors)
+ join_expressions.append(Author.q.id == id)
+ books = search_books('full', None, {}, join_expressions,
+ orderBy=('series', 'ser_no', 'title'),
+ use_filters=use_filters)
+ return {
+ 'author': Author.get(id),
+ 'books': books,
+ }
+ else:
+ return {
+ 'author': Author.get(id),
+ 'books': Book.select(
+ Book.j.authors & (Author.q.id == id),
+ orderBy=['series', 'ser_no', 'title'],
+ )
+ }
@route('/static/<filename:path>')
@route('/search_books/', method='GET')
@cheetah_view('search_books.tmpl')
def search_books_get():
- return {}
+ return {
+ 'get_config': get_config,
+ }
@route('/search_books/', method='POST')
case_sensitive = request.forms.get('case_sensitive')
if case_sensitive is None:
case_sensitive = _guess_case_sensitivity(value)
+ use_filters = request.forms.get('use_filters')
books = search_books(search_type, case_sensitive, {'title': value}, None,
- orderBy=('title',))
+ orderBy=('title',), use_filters=use_filters)
books_by_authors = {}
for book in books:
author = book.authors[0].fullname
currentTime=time.time
__CHEETAH_version__ = '3.1.0'
__CHEETAH_versionTuple__ = (3, 1, 0, 'final', 1)
-__CHEETAH_genTime__ = 1527354048.844765
-__CHEETAH_genTimestamp__ = 'Sat May 26 20:00:48 2018'
+__CHEETAH_genTime__ = 1528138831.71884
+__CHEETAH_genTimestamp__ = 'Mon Jun 4 22:00:31 2018'
__CHEETAH_src__ = 'search_books_form.tmpl'
-__CHEETAH_srcLastModified__ = 'Sat May 26 20:00:32 2018'
+__CHEETAH_srcLastModified__ = 'Mon Jun 4 22:00:29 2018'
__CHEETAH_docstring__ = 'Autogenerated by Cheetah: The Python-Powered Template Engine'
if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple:
return _dummyTrans and trans.response().getvalue() or ""
+ def use_filters_check(self, **KWS):
+
+
+
+ ## CHEETAH: generated from #def $use_filters_check at line 13, col 1.
+ trans = KWS.get("trans")
+ if (not trans and not self._CHEETAH__isBuffering and not callable(self.transaction)):
+ trans = self.transaction # is None unless self.awake() was called
+ if not trans:
+ trans = DummyTransaction()
+ _dummyTrans = True
+ else: _dummyTrans = False
+ write = trans.response().write
+ SL = self._CHEETAH__searchList
+ _filter = self._CHEETAH__currentFilter
+
+ ########################################
+ ## START - generated method body
+
+ if VFFSL(SL,"getVar",False)('use_filters', VFN(VFFSL(SL,"get_config",False)(),"getint",False)('filters', 'use_in_search_forms')): # generated from line 14, col 1
+ write(u'''checked''')
+
+ ########################################
+ ## END - generated method body
+
+ return _dummyTrans and trans.response().getvalue() or ""
+
+
def respond(self, trans=None):
<input name="search_books" value="''')
_v = VFFSL(SL,"html_escape",False)(VFFSL(SL,"getVar",False)('search_books',
''))
- if _v is not None: write(_filter(_v, rawExpr=u"$html_escape($getVar('search_books',\n ''))")) # from line 15, col 37.
+ if _v is not None: write(_filter(_v, rawExpr=u"$html_escape($getVar('search_books',\n ''))")) # from line 20, col 37.
write(u'''" type="text" style="width: 100%">
<br>
<input name="search_type" value="start" ''')
- _v = VFFSL(SL,"search_type_checked",False)('start') # u"$search_type_checked('start')" on line 18, col 43
- if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('start')")) # from line 18, col 43.
+ _v = VFFSL(SL,"search_type_checked",False)('start') # u"$search_type_checked('start')" on line 23, col 43
+ if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('start')")) # from line 23, col 43.
write(u''' type="radio">
\u041f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0430 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435
<input name="search_type" value="substring" ''')
- _v = VFFSL(SL,"search_type_checked",False)('substring') # u"$search_type_checked('substring')" on line 20, col 47
- if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('substring')")) # from line 20, col 47.
+ _v = VFFSL(SL,"search_type_checked",False)('substring') # u"$search_type_checked('substring')" on line 25, col 47
+ if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('substring')")) # from line 25, col 47.
write(u''' type="radio">
\u041f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0430
<input name="search_type" value="full" ''')
- _v = VFFSL(SL,"search_type_checked",False)('full') # u"$search_type_checked('full')" on line 22, col 42
- if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('full')")) # from line 22, col 42.
+ _v = VFFSL(SL,"search_type_checked",False)('full') # u"$search_type_checked('full')" on line 27, col 42
+ if _v is not None: write(_filter(_v, rawExpr=u"$search_type_checked('full')")) # from line 27, col 42.
write(u''' type="radio">
\u0422\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435
<br>
<input name="case_sensitive" type="checkbox" ''')
- _v = VFFSL(SL,"case_sensitive_checked",True) # u'$case_sensitive_checked' on line 25, col 48
- if _v is not None: write(_filter(_v, rawExpr=u'$case_sensitive_checked')) # from line 25, col 48.
+ _v = VFFSL(SL,"case_sensitive_checked",True) # u'$case_sensitive_checked' on line 30, col 48
+ if _v is not None: write(_filter(_v, rawExpr=u'$case_sensitive_checked')) # from line 30, col 48.
write(u'''>
\u0420\u0430\u0437\u043b\u0438\u0447\u0430\u0442\u044c \u043f\u0440\u043e\u043f\u0438\u0441\u043d\u044b\u0435/\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0435
+ <input name="use_filters" type="checkbox" ''')
+ _v = VFFSL(SL,"use_filters_check",True) # u'$use_filters_check' on line 32, col 45
+ if _v is not None: write(_filter(_v, rawExpr=u'$use_filters_check')) # from line 32, col 45.
+ write(u'''>
+ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u044b
</div>
<div style="width: 100%; text-align: center">
<input name="submit" type="submit">
checked#slurp
#end if
#end def
+#def $use_filters_check
+#if $getVar('use_filters', $get_config().getint('filters', 'use_in_search_forms'))
+checked#slurp
+#end if
+#end def
<form action="/search_books/" method="POST">
<div style="width: 100%">
<input name="search_books" value="$html_escape($getVar('search_books',
<br>
<input name="case_sensitive" type="checkbox" $case_sensitive_checked>
Различать прописные/строчные
+ <input name="use_filters" type="checkbox" $use_filters_check>
+ Использовать фильтры
</div>
<div style="width: 100%; text-align: center">
<input name="submit" type="submit">
[library]
path = /var/lib/LRE_Flibusta
+[filters]
+# Space-separated list of language codes
+lang = ru en
+
+# Show/hide deleted books; 0 - hide, 1 - show
+deleted = 1
+
+# Default value to use filters in search forms
+use_in_search_forms = 1
+
+# Use filters in lists of books
+use_in_books_list = 1
+
[download]
# Download formats:
# %a - author (one of)
Language, search_type, case_sensitive, lvalues)
join_expressions.extend(conditions)
books = search_books(search_type, case_sensitive, values, join_expressions,
- orderBy=('series', 'ser_no', 'title'))
+ orderBy=('series', 'ser_no', 'title'),
+ use_filters=args.filters)
if args.count:
print_count(books.count())
return
parser.add_argument('--gid', type=int, help='search by genre\'s id')
parser.add_argument('-l', '--lang', help='search by language')
parser.add_argument('--lid', type=int, help='search by language\'s id')
+ parser.add_argument('--filters', action='store_true',
+ help='use filters from config')
parser.add_argument('-P', '--path', help='path to the library archives')
parser.add_argument('--download-to', nargs='?',
const=None, default=os.path.curdir,