From b446a389796d3e6922ce93f089e25324765a8c62 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sun, 8 Apr 2018 03:28:21 +0300 Subject: [PATCH] Feat(web): Download one book --- m_librarian/download.py | 15 +-- m_librarian/web/app.py | 14 +++ m_librarian/web/views/download.py | 172 ++++++++++++++++++++++++++++ m_librarian/web/views/download.tmpl | 8 ++ sample/m_librarian.conf | 3 + scripts/ml-search.py | 3 +- 6 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 m_librarian/web/views/download.py create mode 100644 m_librarian/web/views/download.tmpl diff --git a/m_librarian/download.py b/m_librarian/download.py index 3041201..e10e9fe 100755 --- a/m_librarian/download.py +++ b/m_librarian/download.py @@ -64,12 +64,12 @@ def _compile_format(): _library_path = None -def download(book, path=None, a_format=None): - if path is None: +def download(book, dest_path=None, lib_path=None, a_format=None): + if lib_path is None: global _library_path if _library_path is None: _library_path = get_config().get('library', 'path') - path = _library_path + lib_path = _library_path global format, compile_format, compiled_format if a_format: @@ -92,19 +92,20 @@ def download(book, path=None, a_format=None): if '%(extension)s' not in compiled_format: compiled_format += '.%(extension)s' filename = compiled_format % bdict + full_path = os.path.join(dest_path, filename) try: - os.makedirs(os.path.dirname(filename)) + os.makedirs(os.path.dirname(full_path)) except OSError: pass # Already exists - zf = ZipFile(os.path.join(path, book.archive), 'r') + zf = ZipFile(os.path.join(lib_path, book.archive), 'r') infile = zf.open('%s.%s' % (book.file, book.extension.name)) - outfile = open(filename, 'wb') + outfile = open(full_path, 'wb') copyfileobj(infile, outfile) outfile.close() infile.close() zf.close() dt = mktime(book.date.timetuple()) - os.utime(filename, (dt, dt)) + os.utime(full_path, (dt, dt)) def test(): diff --git a/m_librarian/web/app.py b/m_librarian/web/app.py index 686dafe..7032825 100644 --- a/m_librarian/web/app.py +++ b/m_librarian/web/app.py @@ -1,9 +1,13 @@ +# -*- coding: utf-8 -*- + import os from sqlobject.sqlbuilder import CONCAT from bottle import cheetah_view, redirect, request, route, static_file +from m_librarian.config import get_config from m_librarian.db import Author, Book +from m_librarian.download import download from m_librarian.search import search_authors @@ -81,3 +85,13 @@ def send_static(filename): 'static' ) ) + + +@route('/download//', method='GET') +@cheetah_view('download.tmpl') +def download_book(id): + book = Book.get(id) + download(book, get_config().get('download', 'path')) + return { + 'message': u'Книга сохранена', + } diff --git a/m_librarian/web/views/download.py b/m_librarian/web/views/download.py new file mode 100644 index 0000000..ef05ca4 --- /dev/null +++ b/m_librarian/web/views/download.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + + + +################################################## +## DEPENDENCIES +import sys +import os +import os.path +try: + import builtins as builtin +except ImportError: + import __builtin__ as builtin +from os.path import getmtime, exists +import time +import types +from Cheetah.Version import MinCompatibleVersion as RequiredCheetahVersion +from Cheetah.Version import MinCompatibleVersionTuple as RequiredCheetahVersionTuple +from Cheetah.Template import Template +from Cheetah.DummyTransaction import * +from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList +from Cheetah.CacheRegion import CacheRegion +import Cheetah.Filters as Filters +import Cheetah.ErrorCatchers as ErrorCatchers +from Cheetah.compat import unicode +from views.layout import layout + +################################################## +## MODULE CONSTANTS +VFFSL=valueFromFrameOrSearchList +VFSL=valueFromSearchList +VFN=valueForName +currentTime=time.time +__CHEETAH_version__ = '3.1.0' +__CHEETAH_versionTuple__ = (3, 1, 0, 'final', 1) +__CHEETAH_genTime__ = 1523146500.915016 +__CHEETAH_genTimestamp__ = 'Sun Apr 8 03:15:00 2018' +__CHEETAH_src__ = 'download.tmpl' +__CHEETAH_srcLastModified__ = 'Sun Apr 8 03:14:43 2018' +__CHEETAH_docstring__ = 'Autogenerated by Cheetah: The Python-Powered Template Engine' + +if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple: + raise AssertionError( + 'This template was compiled with Cheetah version' + ' %s. Templates compiled before version %s must be recompiled.'%( + __CHEETAH_version__, RequiredCheetahVersion)) + +################################################## +## CLASSES + +class download(layout): + + ################################################## + ## CHEETAH GENERATED METHODS + + + def __init__(self, *args, **KWs): + + super(download, self).__init__(*args, **KWs) + if not self._CHEETAH__instanceInitialized: + cheetahKWArgs = {} + allowedKWs = 'searchList namespaces filter filtersLib errorCatcher'.split() + for k,v in KWs.items(): + if k in allowedKWs: cheetahKWArgs[k] = v + self._initCheetahInstance(**cheetahKWArgs) + + + def body(self, **KWS): + + + + ## CHEETAH: generated from #def body at line 4, 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 + + write(u'''

''') + _v = VFFSL(SL,"title",True) # u'$title' on line 5, col 5 + if _v is not None: write(_filter(_v, rawExpr=u'$title')) # from line 5, col 5. + write(u'''

+ +

''') + _v = VFFSL(SL,"message",True) # u'$message' on line 7, col 4 + if _v is not None: write(_filter(_v, rawExpr=u'$message')) # from line 7, col 4. + write(u'''

+''') + + ######################################## + ## END - generated method body + + return _dummyTrans and trans.response().getvalue() or "" + + + def writeBody(self, **KWS): + + + + ## CHEETAH: main method generated for this template + 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 + + + ######################################## + ## END - generated method body + + return _dummyTrans and trans.response().getvalue() or "" + + ################################################## + ## CHEETAH GENERATED ATTRIBUTES + + + _CHEETAH__instanceInitialized = False + + _CHEETAH_version = __CHEETAH_version__ + + _CHEETAH_versionTuple = __CHEETAH_versionTuple__ + + _CHEETAH_genTime = __CHEETAH_genTime__ + + _CHEETAH_genTimestamp = __CHEETAH_genTimestamp__ + + _CHEETAH_src = __CHEETAH_src__ + + _CHEETAH_srcLastModified = __CHEETAH_srcLastModified__ + + title = 'Загрузка' + + _mainCheetahMethod_for_download = 'writeBody' + +## END CLASS DEFINITION + +if not hasattr(download, '_initCheetahAttributes'): + templateAPIClass = getattr(download, + '_CHEETAH_templateClass', + Template) + templateAPIClass._addCheetahPlumbingCodeToClass(download) + + +# CHEETAH was developed by Tavis Rudd and Mike Orr +# with code, advice and input from many other volunteers. +# For more information visit http://cheetahtemplate.org/ + +################################################## +## if run from command line: +if __name__ == '__main__': + from Cheetah.TemplateCmdLineIface import CmdLineIface + CmdLineIface(templateObj=download()).run() + + diff --git a/m_librarian/web/views/download.tmpl b/m_librarian/web/views/download.tmpl new file mode 100644 index 0000000..cf7e5bf --- /dev/null +++ b/m_librarian/web/views/download.tmpl @@ -0,0 +1,8 @@ +#encoding utf-8 +#extends views.layout +#attr $title = 'Загрузка' +#def body +

$title

+ +

$message

+#end def diff --git a/sample/m_librarian.conf b/sample/m_librarian.conf index 2ed0f8a..5b8bee9 100644 --- a/sample/m_librarian.conf +++ b/sample/m_librarian.conf @@ -26,3 +26,6 @@ path = /var/lib/LRE_Flibusta # Examples: # format = %f (this is the default) # format = %a/%s/%n %t + +# Directory to download books to +path = /tmp diff --git a/scripts/ml-search.py b/scripts/ml-search.py index fe8dc48..5ee84cc 100755 --- a/scripts/ml-search.py +++ b/scripts/ml-search.py @@ -2,6 +2,7 @@ from __future__ import print_function import argparse +import os import sys from sqlobject.sqlbuilder import CONCAT @@ -199,7 +200,7 @@ def _search_books(case_sensitive, search_type, args): print(" ", encode(_("Deleted")), ":", encode(_(str(book.deleted)))) if args.get or args.get_many: - download(book, args.path, args.format) + download(book, os.path.curdir, args.path, args.format) count += 1 print_count(count) -- 2.39.2