<s> """<STR_LIT>""" <EOL> """<STR_LIT>""" <EOL> from datetime import date <EOL> import tornado . escape <EOL> import tornado . ioloop <EOL> import tornado . web <EOL> import urllib <EOL> from urllib2 import quote <EOL> from sqlalchemy import desc <EOL> from sqlalchemy . orm import joinedload , subqueryload , aliased <EOL> from sqlalchemy . sql . expression import func , select <EOL> import json <EOL> import pprint <EOL> import mimetypes <EOL> from PIL import Image <EOL> from PIL import WebPImagePlugin <EOL> import StringIO <EOL> import gzip <EOL> import dateutil . parser <EOL> import logging <EOL> import logging . handlers <EOL> import imghdr <EOL> import random <EOL> import signal <EOL> import sys <EOL> import socket <EOL> import webbrowser <EOL> import time <EOL> from libs . comictaggerlib . comicarchive import * <EOL> import csversion <EOL> import utils <EOL> from database import * <EOL> from monitor import Monitor <EOL> from config import ComicStreamerConfig <EOL> from comicstreamerlib . folders import AppFolders <EOL> from options import Options <EOL> from bonjour import BonjourThread <EOL> from bookmarker import Bookmarker <EOL> def my_test_webp ( h , f ) : <EOL> if h . startswith ( b'<STR_LIT>' ) and h [ <NUM_LIT:8> : <NUM_LIT:12> ] == b'<STR_LIT>' : <EOL> return '<STR_LIT>' <EOL> imghdr . tests . append ( my_test_webp ) <EOL> def fix_username ( username ) : <EOL> return username + "<STR_LIT>" <EOL> def custom_get_current_user ( handler ) : <EOL> user = handler . get_secure_cookie ( "<STR_LIT:user>" ) <EOL> if user : <EOL> user = fix_username ( user ) <EOL> return user <EOL> class BaseHandler ( tornado . web . RequestHandler ) : <EOL> def get_current_user ( self ) : <EOL> return custom_get_current_user ( self ) <EOL> class GenericAPIHandler ( BaseHandler ) : <EOL> def validateAPIKey ( self ) : <EOL> if self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> api_key = self . get_argument ( u"<STR_LIT>" , default = "<STR_LIT>" ) <EOL> if api_key == self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> return True <EOL> else : <EOL> raise tornado . web . HTTPError ( <NUM_LIT> ) <EOL> return False <EOL> class JSONResultAPIHandler ( GenericAPIHandler ) : <EOL> def setContentType ( self ) : <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> def processPagingArgs ( self , query ) : <EOL> per_page = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> offset = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> total_results = None <EOL> if per_page is not None : <EOL> total_results = query . distinct ( ) . count ( ) <EOL> try : <EOL> max = <NUM_LIT:0> <EOL> max = int ( per_page ) <EOL> if total_results > max : <EOL> query = query . limit ( max ) <EOL> except : <EOL> pass <EOL> if offset is not None : <EOL> try : <EOL> off = <NUM_LIT:0> <EOL> off = int ( offset ) <EOL> query = query . offset ( off ) <EOL> except : <EOL> pass <EOL> return query , total_results <EOL> def processComicQueryArgs ( self , query ) : <EOL> def hasValue ( obj ) : <EOL> return obj is not None and obj != "<STR_LIT>" <EOL> keyphrase_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> series_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> path_filter = self . get_argument ( u"<STR_LIT:path>" , default = None ) <EOL> folder_filter = self . get_argument ( u"<STR_LIT>" , default = "<STR_LIT>" ) <EOL> title_filter = self . get_argument ( u"<STR_LIT:title>" , default = None ) <EOL> start_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> end_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> added_since = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> modified_since = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> lastread_since = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> order = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> character = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> team = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> location = self . get_argument ( u"<STR_LIT:location>" , default = None ) <EOL> storyarc = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> volume = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> publisher = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> credit_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> tag = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> genre = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> if folder_filter != "<STR_LIT>" : <EOL> folder_filter = os . path . normcase ( os . path . normpath ( folder_filter ) ) <EOL> print folder_filter <EOL> person = None <EOL> role = None <EOL> if hasValue ( credit_filter ) : <EOL> credit_info = credit_filter . split ( "<STR_LIT::>" ) <EOL> if len ( credit_info [ <NUM_LIT:0> ] ) != <NUM_LIT:0> : <EOL> person = credit_info [ <NUM_LIT:0> ] <EOL> if len ( credit_info ) > <NUM_LIT:1> : <EOL> role = credit_info [ <NUM_LIT:1> ] <EOL> if hasValue ( person ) : <EOL> query = query . join ( Credit ) . filter ( Person . name . ilike ( person . replace ( "<STR_LIT:*>" , "<STR_LIT:%>" ) ) ) . filter ( Credit . person_id == Person . id ) <EOL> if role is not None : <EOL> query = query . filter ( Credit . role_id == Role . id ) . filter ( Role . name . ilike ( role . replace ( "<STR_LIT:*>" , "<STR_LIT:%>" ) ) ) <EOL> if hasValue ( keyphrase_filter ) : <EOL> keyphrase_filter = unicode ( keyphrase_filter ) . replace ( "<STR_LIT:*>" , "<STR_LIT:%>" ) <EOL> keyphrase_filter = "<STR_LIT:%>" + keyphrase_filter + "<STR_LIT:%>" <EOL> query = query . filter ( Comic . series . ilike ( keyphrase_filter ) <EOL> | Comic . title . ilike ( keyphrase_filter ) <EOL> | Comic . publisher . ilike ( keyphrase_filter ) <EOL> | Comic . path . ilike ( keyphrase_filter ) <EOL> | Comic . comments . ilike ( keyphrase_filter ) <EOL> | Comic . persons_raw . any ( Person . name . ilike ( keyphrase_filter ) ) <EOL> ) <EOL> def addQueryOnScalar ( query , obj_prop , filt ) : <EOL> if hasValue ( filt ) : <EOL> filt = unicode ( filt ) . replace ( "<STR_LIT:*>" , "<STR_LIT:%>" ) <EOL> return query . filter ( obj_prop . ilike ( filt ) ) <EOL> else : <EOL> return query <EOL> def addQueryOnList ( query , obj_list , list_prop , filt ) : <EOL> if hasValue ( filt ) : <EOL> filt = unicode ( filt ) . replace ( "<STR_LIT:*>" , "<STR_LIT:%>" ) <EOL> return query . filter ( obj_list . any ( list_prop . ilike ( filt ) ) ) <EOL> else : <EOL> return query <EOL> query = addQueryOnScalar ( query , Comic . series , series_filter ) <EOL> query = addQueryOnScalar ( query , Comic . title , title_filter ) <EOL> query = addQueryOnScalar ( query , Comic . path , path_filter ) <EOL> query = addQueryOnScalar ( query , Comic . folder , folder_filter ) <EOL> query = addQueryOnScalar ( query , Comic . publisher , publisher ) <EOL> query = addQueryOnList ( query , Comic . characters_raw , Character . name , character ) <EOL> query = addQueryOnList ( query , Comic . generictags_raw , GenericTag . name , tag ) <EOL> query = addQueryOnList ( query , Comic . teams_raw , Team . name , team ) <EOL> query = addQueryOnList ( query , Comic . locations_raw , Location . name , location ) <EOL> query = addQueryOnList ( query , Comic . storyarcs_raw , StoryArc . name , storyarc ) <EOL> query = addQueryOnList ( query , Comic . genres_raw , Genre . name , genre ) <EOL> if hasValue ( volume ) : <EOL> try : <EOL> vol = <NUM_LIT:0> <EOL> vol = int ( volume ) <EOL> query = query . filter ( Comic . volume == vol ) <EOL> except : <EOL> pass <EOL> if hasValue ( start_filter ) : <EOL> try : <EOL> dt = dateutil . parser . parse ( start_filter ) <EOL> query = query . filter ( Comic . date >= dt ) <EOL> except : <EOL> pass <EOL> if hasValue ( end_filter ) : <EOL> try : <EOL> dt = dateutil . parser . parse ( end_filter ) <EOL> query = query . filter ( Comic . date <= dt ) <EOL> except : <EOL> pass <EOL> if hasValue ( modified_since ) : <EOL> try : <EOL> dt = dateutil . parser . parse ( modified_since ) <EOL> resultset = resultset . filter ( Comic . mod_ts >= dt ) <EOL> except : <EOL> pass <EOL> if hasValue ( added_since ) : <EOL> try : <EOL> dt = dateutil . parser . parse ( added_since ) <EOL> query = query . filter ( Comic . added_ts >= dt ) <EOL> except : <EOL> pass <EOL> if hasValue ( lastread_since ) : <EOL> try : <EOL> dt = dateutil . parser . parse ( lastread_since ) <EOL> query = query . filter ( Comic . lastread_ts >= dt , Comic . lastread_ts != "<STR_LIT>" ) <EOL> except : <EOL> pass <EOL> order_key = None <EOL> if not hasValue ( order ) : <EOL> order = "<STR_LIT:id>" <EOL> if hasValue ( order ) : <EOL> if order [ <NUM_LIT:0> ] == "<STR_LIT:->" : <EOL> order_desc = True <EOL> order = order [ <NUM_LIT:1> : ] <EOL> else : <EOL> order_desc = False <EOL> if order == "<STR_LIT:id>" : <EOL> order_key = Comic . id <EOL> if order == "<STR_LIT>" : <EOL> order_key = Comic . series <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . mod_ts <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . added_ts <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . lastread_ts <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . volume <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . issue_num <EOL> elif order == "<STR_LIT:date>" : <EOL> order_key = Comic . date <EOL> elif order == "<STR_LIT>" : <EOL> order_key = Comic . publisher <EOL> elif order == "<STR_LIT:title>" : <EOL> order_key = Comic . title <EOL> elif order == "<STR_LIT:path>" : <EOL> order_key = Comic . path <EOL> if order_key is not None : <EOL> if order_desc : <EOL> order_key = order_key . desc ( ) <EOL> query = query . order_by ( order_key ) <EOL> return query <EOL> class ZippableAPIHandler ( JSONResultAPIHandler ) : <EOL> def writeResults ( self , json_data ) : <EOL> self . setContentType ( ) <EOL> if self . get_argument ( u"<STR_LIT>" , default = None ) is not None : <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> zbuf = StringIO . StringIO ( ) <EOL> zfile = gzip . GzipFile ( mode = '<STR_LIT:wb>' , fileobj = zbuf , compresslevel = <NUM_LIT:9> ) <EOL> zfile . write ( json . dumps ( json_data ) ) <EOL> zfile . close ( ) <EOL> self . write ( zbuf . getvalue ( ) ) <EOL> else : <EOL> self . write ( json_data ) <EOL> class CommandAPIHandler ( GenericAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> cmd = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> if cmd == "<STR_LIT>" : <EOL> logging . info ( "<STR_LIT>" ) <EOL> self . application . restart ( ) <EOL> elif cmd == "<STR_LIT>" : <EOL> logging . info ( "<STR_LIT>" ) <EOL> self . application . rebuild ( ) <EOL> elif cmd == "<STR_LIT>" : <EOL> logging . info ( "<STR_LIT>" ) <EOL> self . application . shutdown ( ) <EOL> class ImageAPIHandler ( GenericAPIHandler ) : <EOL> def setContentType ( self , image_data ) : <EOL> imtype = imghdr . what ( StringIO . StringIO ( image_data ) ) <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" . format ( imtype ) ) <EOL> def getImageData ( self , comic_id , pagenum ) : <EOL> session = self . application . dm . Session ( ) <EOL> obj = session . query ( Comic ) . filter ( Comic . id == int ( comic_id ) ) . first ( ) <EOL> image_data = None <EOL> default_img_file = AppFolders . imagePath ( "<STR_LIT>" ) <EOL> if obj is not None : <EOL> if int ( pagenum ) < obj . page_count : <EOL> ca = self . application . getComicArchive ( obj . path ) <EOL> image_data = ca . getPage ( int ( pagenum ) ) <EOL> if image_data is None : <EOL> with open ( default_img_file , '<STR_LIT:rb>' ) as fd : <EOL> image_data = fd . read ( ) <EOL> return image_data <EOL> def resizeImage ( self , max , image_data ) : <EOL> imtype = imghdr . what ( StringIO . StringIO ( image_data ) ) <EOL> if imtype == "<STR_LIT>" : <EOL> with open ( AppFolders . imagePath ( "<STR_LIT>" ) , '<STR_LIT:rb>' ) as fd : <EOL> image_data = fd . read ( ) <EOL> im = Image . open ( StringIO . StringIO ( image_data ) ) <EOL> w , h = im . size <EOL> if max < h : <EOL> im . thumbnail ( ( w , max ) , Image . ANTIALIAS ) <EOL> output = StringIO . StringIO ( ) <EOL> im . save ( output , format = "<STR_LIT>" ) <EOL> return output . getvalue ( ) <EOL> else : <EOL> return image_data <EOL> class VersionAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> response = { '<STR_LIT:version>' : self . application . version , <EOL> '<STR_LIT>' : date . today ( ) . isoformat ( ) } <EOL> self . setContentType ( ) <EOL> self . write ( response ) <EOL> class DBInfoAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> obj = session . query ( DatabaseInfo ) . first ( ) <EOL> response = { '<STR_LIT:id>' : obj . uuid , <EOL> '<STR_LIT>' : obj . last_updated . isoformat ( ) , <EOL> '<STR_LIT>' : obj . created . isoformat ( ) , <EOL> '<STR_LIT>' : session . query ( Comic ) . count ( ) <EOL> } <EOL> self . setContentType ( ) <EOL> self . write ( response ) <EOL> class ScanStatusAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> status = self . application . monitor . status <EOL> detail = self . application . monitor . statusdetail <EOL> last_complete = self . application . monitor . scancomplete_ts <EOL> response = { '<STR_LIT:status>' : status , <EOL> '<STR_LIT>' : detail , <EOL> '<STR_LIT>' : last_complete , <EOL> '<STR_LIT>' : int ( time . mktime ( datetime . utcnow ( ) . timetuple ( ) ) * <NUM_LIT:1000> ) , <EOL> } <EOL> self . setContentType ( ) <EOL> self . write ( response ) <EOL> class ComicListAPIHandler ( ZippableAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> query = session . query ( Comic ) <EOL> query = self . processComicQueryArgs ( query ) <EOL> query , total_results = self . processPagingArgs ( query ) <EOL> logging . debug ( "<STR_LIT>" ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> resultset = query . all ( ) <EOL> logging . debug ( "<STR_LIT>" ) <EOL> logging . debug ( "<STR_LIT>" ) <EOL> json_data = resultSetToJson ( resultset , "<STR_LIT>" , total_results ) <EOL> logging . debug ( "<STR_LIT>" ) <EOL> self . writeResults ( json_data ) <EOL> class DeletedAPIHandler ( ZippableAPIHandler ) : <EOL> def get ( self ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> resultset = session . query ( DeletedComic ) <EOL> since_filter = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> if since_filter is not None : <EOL> try : <EOL> dt = dateutil . parser . parse ( since_filter ) <EOL> resultset = resultset . filter ( DeletedComic . ts >= dt ) <EOL> except : <EOL> pass <EOL> json_data = resultSetToJson ( resultset , "<STR_LIT>" ) <EOL> self . writeResults ( json_data ) <EOL> class ComicListBrowserHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> entity_src = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> if entity_src is not None : <EOL> src = entity_src <EOL> else : <EOL> default_src = "<STR_LIT>" <EOL> arg_string = "<STR_LIT>" <EOL> src = default_src + arg_string <EOL> self . render ( "<STR_LIT>" , <EOL> src = src , <EOL> api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> ) <EOL> class FoldersBrowserHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self , args ) : <EOL> if args is None : <EOL> args = "<STR_LIT:/>" <EOL> args = utils . collapseRepeats ( args , "<STR_LIT:/>" ) <EOL> self . render ( "<STR_LIT>" , <EOL> args = args , <EOL> api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> class EntitiesBrowserHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self , args ) : <EOL> if args is None : <EOL> args = "<STR_LIT>" <EOL> arg_string = args <EOL> self . render ( "<STR_LIT>" , <EOL> args = arg_string , <EOL> api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> class ComicAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self , id ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> result = session . query ( Comic ) . filter ( Comic . id == int ( id ) ) . all ( ) <EOL> self . setContentType ( ) <EOL> self . write ( resultSetToJson ( result , "<STR_LIT>" ) ) <EOL> class ComicBookmarkAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self , comic_id , pagenum ) : <EOL> self . validateAPIKey ( ) <EOL> self . application . bookmarker . setBookmark ( comic_id , pagenum ) <EOL> self . setContentType ( ) <EOL> response = { '<STR_LIT:status>' : <NUM_LIT:0> } <EOL> self . write ( response ) <EOL> class ComicPageAPIHandler ( ImageAPIHandler ) : <EOL> def get ( self , comic_id , pagenum ) : <EOL> self . validateAPIKey ( ) <EOL> image_data = self . getImageData ( comic_id , pagenum ) <EOL> max_height = self . get_argument ( u"<STR_LIT>" , default = None ) <EOL> if max_height is not None : <EOL> try : <EOL> max_h = int ( max_height ) <EOL> image_data = self . resizeImage ( max_h , image_data ) <EOL> except Exception as e : <EOL> logging . error ( e ) <EOL> pass <EOL> self . setContentType ( image_data ) <EOL> self . write ( image_data ) <EOL> class ThumbnailAPIHandler ( ImageAPIHandler ) : <EOL> def get ( self , comic_id ) : <EOL> self . validateAPIKey ( ) <EOL> image_data = self . getImageData ( comic_id , <NUM_LIT:0> ) <EOL> thumbail_data = self . resizeImage ( <NUM_LIT:200> , image_data ) <EOL> self . setContentType ( image_data ) <EOL> self . write ( thumbail_data ) <EOL> class FileAPIHandler ( GenericAPIHandler ) : <EOL> def get ( self , comic_id ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> obj = session . query ( Comic ) . filter ( Comic . id == int ( comic_id ) ) . first ( ) <EOL> if obj is not None : <EOL> ca = self . application . getComicArchive ( obj . path ) <EOL> if ca . isZip ( ) : <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> else : <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> self . add_header ( "<STR_LIT>" , "<STR_LIT>" + os . path . basename ( obj . path ) ) <EOL> with open ( obj . path , '<STR_LIT:rb>' ) as fd : <EOL> file_data = fd . read ( ) <EOL> self . write ( file_data ) <EOL> class FolderAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self , args ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> if args is not None : <EOL> args = urllib . unquote ( args ) <EOL> arglist = args . split ( '<STR_LIT:/>' ) <EOL> arglist = filter ( None , arglist ) <EOL> argcount = len ( arglist ) <EOL> else : <EOL> arglist = list ( ) <EOL> argcount = <NUM_LIT:0> <EOL> folder_list = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> response = { <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT:count>' : <NUM_LIT:0> <EOL> } <EOL> } <EOL> if argcount == <NUM_LIT:0> : <EOL> for idx , val in enumerate ( folder_list ) : <EOL> item = { <EOL> '<STR_LIT:name>' : val , <EOL> '<STR_LIT>' : "<STR_LIT>" + str ( idx ) <EOL> } <EOL> response [ '<STR_LIT>' ] . append ( item ) <EOL> else : <EOL> try : <EOL> folder_idx = int ( arglist [ <NUM_LIT:0> ] ) <EOL> if folder_idx >= len ( folder_list ) : <EOL> raise Exception <EOL> path = os . path . join ( folder_list [ folder_idx ] , * arglist [ <NUM_LIT:1> : ] ) <EOL> if not os . path . exists ( path ) : <EOL> print "<STR_LIT>" , path , type ( path ) <EOL> raise Exception <EOL> response [ '<STR_LIT>' ] = path <EOL> for o in os . listdir ( path ) : <EOL> if os . path . isdir ( os . path . join ( path , o ) ) : <EOL> sub_path = u"<STR_LIT>" + args + u"<STR_LIT:/>" + o <EOL> sub_path = urllib . quote ( sub_path . encode ( "<STR_LIT:utf-8>" ) ) <EOL> item = { <EOL> '<STR_LIT:name>' : o , <EOL> '<STR_LIT>' : sub_path <EOL> } <EOL> response [ '<STR_LIT>' ] . append ( item ) <EOL> response [ '<STR_LIT>' ] [ '<STR_LIT:count>' ] = session . query ( Comic ) . filter ( Comic . folder == path ) . count ( ) <EOL> comic_path = u"<STR_LIT>" + urllib . quote ( u"<STR_LIT>" . format ( path ) . encode ( '<STR_LIT:utf-8>' ) ) <EOL> response [ '<STR_LIT>' ] [ '<STR_LIT>' ] = comic_path <EOL> except FloatingPointError as e : <EOL> print e <EOL> raise tornado . web . HTTPError ( <NUM_LIT> , "<STR_LIT>" ) <EOL> self . setContentType ( ) <EOL> self . write ( response ) <EOL> class EntityAPIHandler ( JSONResultAPIHandler ) : <EOL> def get ( self , args ) : <EOL> self . validateAPIKey ( ) <EOL> session = self . application . dm . Session ( ) <EOL> if args is None : <EOL> args = "<STR_LIT>" <EOL> arglist = args . split ( '<STR_LIT:/>' ) <EOL> arglist = filter ( None , arglist ) <EOL> argcount = len ( arglist ) <EOL> entities = { <EOL> '<STR_LIT>' : Character . name , <EOL> '<STR_LIT>' : Person . name , <EOL> '<STR_LIT>' : Comic . publisher , <EOL> '<STR_LIT>' : Role . name , <EOL> '<STR_LIT>' : Comic . series , <EOL> '<STR_LIT>' : Comic . volume , <EOL> '<STR_LIT>' : Team . name , <EOL> '<STR_LIT>' : StoryArc . name , <EOL> '<STR_LIT>' : Genre . name , <EOL> '<STR_LIT>' : Location . name , <EOL> '<STR_LIT>' : GenericTag . name , <EOL> '<STR_LIT>' : Comic <EOL> } <EOL> for e in arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] : <EOL> if e not in entities : <EOL> raise tornado . web . HTTPError ( <NUM_LIT> , "<STR_LIT>" . format ( e ) ) <EOL> if len ( arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] ) != len ( set ( arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] ) ) : <EOL> raise tornado . web . HTTPError ( <NUM_LIT> , "<STR_LIT>" ) <EOL> if '<STR_LIT>' in arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] and arglist [ - <NUM_LIT:1> ] != "<STR_LIT>" : <EOL> raise tornado . web . HTTPError ( <NUM_LIT> , "<STR_LIT>" ) <EOL> resp = "<STR_LIT>" <EOL> if argcount % <NUM_LIT:2> == <NUM_LIT:0> : <EOL> name_list = [ key for key in entities ] <EOL> for e in arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] : <EOL> try : <EOL> name_list . remove ( e ) <EOL> except : <EOL> pass <EOL> dict_list = [ ] <EOL> for e in name_list : <EOL> tmp_arg_list = list ( ) <EOL> tmp_arg_list . extend ( arglist ) <EOL> tmp_arg_list . append ( e ) <EOL> query = self . buildQuery ( session , entities , tmp_arg_list ) <EOL> e_dict = dict ( ) <EOL> e_dict [ '<STR_LIT:name>' ] = e <EOL> e_dict [ '<STR_LIT:count>' ] = query . distinct ( ) . count ( ) <EOL> dict_list . append ( e_dict ) <EOL> resp = { "<STR_LIT>" : dict_list } <EOL> self . setContentType ( ) <EOL> self . write ( resp ) <EOL> return <EOL> else : <EOL> entity = arglist [ - <NUM_LIT:1> ] <EOL> query = self . buildQuery ( session , entities , arglist ) <EOL> if entity == "<STR_LIT>" : <EOL> query = self . processComicQueryArgs ( query ) <EOL> query , total_results = self . processPagingArgs ( query ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . options ( subqueryload ( '<STR_LIT>' ) ) <EOL> query = query . all ( ) <EOL> resp = resultSetToJson ( query , "<STR_LIT>" , total_results ) <EOL> else : <EOL> resp = { entity : sorted ( list ( set ( [ i [ <NUM_LIT:0> ] for i in query . all ( ) ] ) ) ) } <EOL> self . application . dm . engine . echo = False <EOL> self . setContentType ( ) <EOL> self . write ( resp ) <EOL> def buildQuery ( self , session , entities , arglist ) : <EOL> """<STR_LIT>""" <EOL> entity = arglist [ - <NUM_LIT:1> ] <EOL> querylist = [ ] <EOL> querybase = session . query ( entities [ entity ] ) <EOL> if len ( arglist ) != <NUM_LIT:1> : <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( Credit ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( Credit ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_characters_table ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_teams_table ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_storyarcs_table ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_genres_table ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_locations_table ) . join ( Comic ) <EOL> if entity == '<STR_LIT>' : <EOL> querybase = querybase . join ( comics_generictags_table ) . join ( Comic ) <EOL> for e , v in zip ( arglist [ <NUM_LIT:0> : : <NUM_LIT:2> ] , arglist [ <NUM_LIT:1> : : <NUM_LIT:2> ] ) : <EOL> query = querybase <EOL> if e == '<STR_LIT>' : <EOL> if entity != '<STR_LIT>' : <EOL> query = query . join ( Credit ) <EOL> query = query . join ( Role ) <EOL> if e == '<STR_LIT>' : <EOL> if entity != '<STR_LIT>' : <EOL> query = query . join ( Credit ) <EOL> query = query . join ( Person ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_characters_table ) . join ( Character ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_teams_table ) . join ( Team ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_storyarcs_table ) . join ( StoryArc ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_genres_table ) . join ( Genre ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_locations_table ) . join ( Location ) <EOL> if e == '<STR_LIT>' : <EOL> query = query . join ( comics_generictags_table ) . join ( GenericTag ) <EOL> query = query . filter ( entities [ e ] == v ) <EOL> querylist . append ( query ) <EOL> if len ( querylist ) == <NUM_LIT:0> : <EOL> finalquery = querybase <EOL> else : <EOL> finalquery = querylist [ <NUM_LIT:0> ] . intersect ( * querylist [ <NUM_LIT:1> : ] ) <EOL> return finalquery <EOL> class ReaderHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self , comic_id ) : <EOL> session = self . application . dm . Session ( ) <EOL> obj = session . query ( Comic ) . filter ( Comic . id == int ( comic_id ) ) . first ( ) <EOL> page_data = None <EOL> if obj is not None : <EOL> title = os . path . basename ( obj . path ) <EOL> if obj . series is not None and obj . issue is not None : <EOL> title = obj . series + u"<STR_LIT>" + obj . issue <EOL> if obj . title is not None : <EOL> title += u"<STR_LIT>" + obj . title <EOL> if obj . lastread_page is None : <EOL> target_page = <NUM_LIT:0> <EOL> else : <EOL> target_page = obj . lastread_page <EOL> self . render ( "<STR_LIT>" , <EOL> title = title , <EOL> id = comic_id , <EOL> count = obj . page_count , <EOL> page = target_page , <EOL> api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> def make_list ( self , id , count ) : <EOL> text = u"<STR_LIT>" <EOL> for i in range ( count ) : <EOL> text += u"<STR_LIT>" + str ( i ) + u"<STR_LIT>" <EOL> return text <EOL> class UnknownHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> self . write ( "<STR_LIT>" ) <EOL> class MainHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> session = self . application . dm . Session ( ) <EOL> stats = dict ( ) <EOL> stats [ '<STR_LIT>' ] = session . query ( Comic ) . count ( ) <EOL> dt = session . query ( DatabaseInfo ) . first ( ) . last_updated <EOL> stats [ '<STR_LIT>' ] = utils . utc_to_local ( dt ) . strftime ( "<STR_LIT>" ) <EOL> dt = session . query ( DatabaseInfo ) . first ( ) . created <EOL> stats [ '<STR_LIT>' ] = utils . utc_to_local ( dt ) . strftime ( "<STR_LIT>" ) <EOL> stats [ '<STR_LIT>' ] = len ( set ( session . query ( Comic . series ) ) ) <EOL> stats [ '<STR_LIT>' ] = session . query ( Person ) . count ( ) <EOL> recently_added_comics = session . query ( Comic ) . order_by ( Comic . added_ts . desc ( ) ) . limit ( <NUM_LIT:10> ) <EOL> recently_read_comics = session . query ( Comic ) . filter ( Comic . lastread_ts != "<STR_LIT>" ) . order_by ( Comic . lastread_ts . desc ( ) ) . limit ( <NUM_LIT:10> ) <EOL> roles_query = session . query ( Role . name ) <EOL> roles_list = [ i [ <NUM_LIT:0> ] for i in list ( roles_query ) ] <EOL> random_comic = session . query ( Comic ) . order_by ( func . random ( ) ) . first ( ) <EOL> if random_comic is None : <EOL> random_comic = type ( '<STR_LIT>' , ( object , ) , <EOL> { '<STR_LIT:id>' : <NUM_LIT:0> , '<STR_LIT>' : '<STR_LIT>' , '<STR_LIT>' : <NUM_LIT:0> } ) ( ) <EOL> self . render ( "<STR_LIT>" , stats = stats , <EOL> random_comic = random_comic , <EOL> recently_added = list ( recently_added_comics ) , <EOL> recently_read = list ( recently_read_comics ) , <EOL> roles = roles_list , <EOL> server_time = int ( time . mktime ( datetime . utcnow ( ) . timetuple ( ) ) * <NUM_LIT:1000> ) , <EOL> api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> ) <EOL> class GenericPageHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self , page ) : <EOL> self . render ( page + "<STR_LIT>" ) <EOL> class AboutPageHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> self . render ( "<STR_LIT>" , version = self . application . version ) <EOL> class ControlPageHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> self . render ( "<STR_LIT>" , api_key = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> class LogPageHandler ( BaseHandler ) : <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> log_file = os . path . join ( AppFolders . logs ( ) , "<STR_LIT>" ) <EOL> logtxt = "<STR_LIT>" <EOL> for line in reversed ( open ( log_file ) . readlines ( ) ) : <EOL> logtxt += line . rstrip ( ) + '<STR_LIT:\n>' <EOL> self . render ( "<STR_LIT>" , <EOL> logtxt = logtxt ) <EOL> class ConfigPageHandler ( BaseHandler ) : <EOL> fakepass = "<STR_LIT>" <EOL> def is_port_available ( self , port ) : <EOL> host = '<STR_LIT:127.0.0.1>' <EOL> s = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> try : <EOL> s . connect ( ( host , port ) ) <EOL> s . shutdown ( <NUM_LIT:2> ) <EOL> return False <EOL> except Exception as e : <EOL> print e <EOL> return True <EOL> def render_config ( self , formdata , success = "<STR_LIT>" , failure = "<STR_LIT>" ) : <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" if formdata [ '<STR_LIT>' ] else "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" if formdata [ '<STR_LIT>' ] else "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" if formdata [ '<STR_LIT>' ] else "<STR_LIT>" <EOL> if ( self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) : <EOL> formdata [ '<STR_LIT:password>' ] = ConfigPageHandler . fakepass <EOL> formdata [ '<STR_LIT>' ] = ConfigPageHandler . fakepass <EOL> else : <EOL> formdata [ '<STR_LIT:password>' ] = "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" <EOL> self . render ( "<STR_LIT>" , <EOL> formdata = formdata , <EOL> success = success , <EOL> failure = failure ) <EOL> @ tornado . web . authenticated <EOL> def get ( self ) : <EOL> formdata = dict ( ) <EOL> formdata [ '<STR_LIT:port>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:port>' ] <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT:\n>" . join ( self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> formdata [ '<STR_LIT>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> formdata [ '<STR_LIT:username>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] <EOL> formdata [ '<STR_LIT:password>' ] = "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> formdata [ '<STR_LIT>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> formdata [ '<STR_LIT>' ] = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> self . render_config ( formdata ) <EOL> @ tornado . web . authenticated <EOL> def post ( self ) : <EOL> formdata = dict ( ) <EOL> formdata [ '<STR_LIT:port>' ] = self . get_argument ( u"<STR_LIT:port>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT>' ] = self . get_argument ( u"<STR_LIT>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT>' ] = ( len ( self . get_arguments ( "<STR_LIT>" ) ) != <NUM_LIT:0> ) <EOL> formdata [ '<STR_LIT:username>' ] = self . get_argument ( u"<STR_LIT:username>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT:password>' ] = self . get_argument ( u"<STR_LIT:password>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT>' ] = self . get_argument ( u"<STR_LIT>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT>' ] = ( len ( self . get_arguments ( "<STR_LIT>" ) ) != <NUM_LIT:0> ) <EOL> formdata [ '<STR_LIT>' ] = self . get_argument ( u"<STR_LIT>" , default = "<STR_LIT>" ) <EOL> formdata [ '<STR_LIT>' ] = ( len ( self . get_arguments ( "<STR_LIT>" ) ) != <NUM_LIT:0> ) <EOL> failure_str = "<STR_LIT>" <EOL> success_str = "<STR_LIT>" <EOL> failure_strs = list ( ) <EOL> validated = False <EOL> old_folder_list = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> new_folder_list = [ os . path . normcase ( os . path . abspath ( os . path . normpath ( unicode ( a ) ) ) ) for a in formdata [ '<STR_LIT>' ] . splitlines ( ) ] <EOL> try : <EOL> for i , f in enumerate ( new_folder_list ) : <EOL> if not ( os . path . exists ( f ) and os . path . isdir ( f ) ) : <EOL> failure_strs . append ( u"<STR_LIT>" . format ( f ) ) <EOL> break <EOL> for j , f1 in enumerate ( new_folder_list ) : <EOL> if i != j : <EOL> if f1 == f : <EOL> failure_strs . append ( u"<STR_LIT>" ) <EOL> raise Exception <EOL> if f1 . startswith ( f + os . path . sep ) : <EOL> failure_strs . append ( u"<STR_LIT>" ) <EOL> raise Exception <EOL> except Exception : <EOL> pass <EOL> port_failed = False <EOL> old_port = self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:port>' ] <EOL> if not formdata [ '<STR_LIT:port>' ] . isdigit ( ) : <EOL> port_failed = True <EOL> failure_strs . append ( u"<STR_LIT>" . format ( formdata [ '<STR_LIT:port>' ] ) ) <EOL> if not port_failed : <EOL> new_port = int ( formdata [ '<STR_LIT:port>' ] ) <EOL> if new_port > <NUM_LIT> or new_port < <NUM_LIT> : <EOL> failure_strs . append ( u"<STR_LIT>" . format ( new_port ) ) <EOL> port_failed = True <EOL> if not port_failed : <EOL> if new_port != old_port and not self . is_port_available ( new_port ) : <EOL> failure_strs . append ( u"<STR_LIT>" . format ( new_port ) ) <EOL> port_failed = True <EOL> if formdata [ '<STR_LIT>' ] and ( formdata [ '<STR_LIT:username>' ] == "<STR_LIT>" or formdata [ '<STR_LIT:password>' ] == "<STR_LIT>" ) : <EOL> failure_strs . append ( u"<STR_LIT>" ) <EOL> if formdata [ '<STR_LIT:password>' ] != formdata [ '<STR_LIT>' ] : <EOL> failure_strs . append ( u"<STR_LIT>" ) <EOL> if formdata [ '<STR_LIT>' ] and formdata [ '<STR_LIT>' ] == "<STR_LIT>" : <EOL> failure_strs . append ( u"<STR_LIT>" ) <EOL> if len ( failure_strs ) == <NUM_LIT:0> : <EOL> validated = True <EOL> if validated : <EOL> password_changed = True <EOL> if formdata [ '<STR_LIT>' ] : <EOL> if formdata [ '<STR_LIT:password>' ] == ConfigPageHandler . fakepass : <EOL> password_changed = False <EOL> elif utils . getDigest ( formdata [ '<STR_LIT:password>' ] ) == self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> password_changed = False <EOL> else : <EOL> password_changed = False <EOL> if ( new_port != old_port or <EOL> new_folder_list != old_folder_list or <EOL> formdata [ '<STR_LIT:username>' ] != self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] or <EOL> password_changed or <EOL> formdata [ '<STR_LIT>' ] != self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] or <EOL> formdata [ '<STR_LIT>' ] != self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] or <EOL> formdata [ '<STR_LIT>' ] != self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> ) : <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = new_folder_list <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:port>' ] = new_port <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = formdata [ '<STR_LIT>' ] <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] = formdata [ '<STR_LIT:username>' ] <EOL> if formdata [ '<STR_LIT:password>' ] != ConfigPageHandler . fakepass : <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = utils . getDigest ( formdata [ '<STR_LIT:password>' ] ) <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = formdata [ '<STR_LIT>' ] <EOL> if self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = formdata [ '<STR_LIT>' ] <EOL> else : <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] = formdata [ '<STR_LIT>' ] <EOL> success_str = "<STR_LIT>" <EOL> self . application . config . write ( ) <EOL> else : <EOL> failure_str = "<STR_LIT>" . join ( failure_strs ) <EOL> formdata [ '<STR_LIT:password>' ] = "<STR_LIT>" <EOL> formdata [ '<STR_LIT>' ] = "<STR_LIT>" <EOL> self . render_config ( formdata , success = success_str , failure = failure_str ) <EOL> class LoginHandler ( BaseHandler ) : <EOL> def get ( self ) : <EOL> if len ( self . get_arguments ( "<STR_LIT>" ) ) != <NUM_LIT:0> : <EOL> next = self . get_argument ( "<STR_LIT>" ) <EOL> else : <EOL> next = "<STR_LIT:/>" <EOL> if ( self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] == utils . getDigest ( "<STR_LIT>" ) and <EOL> self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] == "<STR_LIT>" <EOL> ) : <EOL> self . set_secure_cookie ( "<STR_LIT:user>" , fix_username ( self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] ) ) <EOL> self . redirect ( next ) <EOL> else : <EOL> self . render ( '<STR_LIT>' , next = next ) <EOL> def post ( self ) : <EOL> next = self . get_argument ( "<STR_LIT>" ) <EOL> if len ( self . get_arguments ( "<STR_LIT:password>" ) ) != <NUM_LIT:0> : <EOL> if ( utils . getDigest ( self . get_argument ( "<STR_LIT:password>" ) ) == self . application . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] and <EOL> self . get_argument ( "<STR_LIT:username>" ) == self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] ) : <EOL> self . set_secure_cookie ( "<STR_LIT:user>" , fix_username ( self . application . config [ '<STR_LIT>' ] [ '<STR_LIT:username>' ] ) ) <EOL> self . redirect ( next ) <EOL> class APIServer ( tornado . web . Application ) : <EOL> def __init__ ( self , config , opts ) : <EOL> utils . fix_output_encoding ( ) <EOL> self . config = config <EOL> self . opts = opts <EOL> self . port = self . config [ '<STR_LIT>' ] [ '<STR_LIT:port>' ] <EOL> self . comicArchiveList = [ ] <EOL> self . dm = DataManager ( ) <EOL> if opts . reset or opts . reset_and_run : <EOL> logging . info ( "<STR_LIT>" ) <EOL> self . dm . delete ( ) <EOL> if opts . reset : <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> try : <EOL> self . dm . create ( ) <EOL> except SchemaVersionException as e : <EOL> msg = "<STR_LIT>" <EOL> logging . error ( msg ) <EOL> utils . alert ( "<STR_LIT>" , msg ) <EOL> sys . exit ( - <NUM_LIT:1> ) <EOL> try : <EOL> self . listen ( self . port , no_keep_alive = True ) <EOL> except Exception as e : <EOL> logging . error ( e ) <EOL> msg = "<STR_LIT>" . format ( self . port ) <EOL> logging . error ( msg ) <EOL> utils . alert ( "<STR_LIT>" , msg ) <EOL> sys . exit ( - <NUM_LIT:1> ) <EOL> logging . info ( "<STR_LIT>" . format ( self . port ) ) <EOL> self . version = csversion . version <EOL> handlers = [ <EOL> ( r"<STR_LIT:/>" , MainHandler ) , <EOL> ( r"<STR_LIT>" , GenericPageHandler ) , <EOL> ( r"<STR_LIT>" , AboutPageHandler ) , <EOL> ( r"<STR_LIT>" , ControlPageHandler ) , <EOL> ( r"<STR_LIT>" , ConfigPageHandler ) , <EOL> ( r"<STR_LIT>" , LogPageHandler ) , <EOL> ( r"<STR_LIT>" , ComicListBrowserHandler ) , <EOL> ( r"<STR_LIT>" , FoldersBrowserHandler ) , <EOL> ( r"<STR_LIT>" , EntitiesBrowserHandler ) , <EOL> ( r"<STR_LIT>" , ReaderHandler ) , <EOL> ( r"<STR_LIT>" , LoginHandler ) , <EOL> ( r"<STR_LIT>" , DBInfoAPIHandler ) , <EOL> ( r"<STR_LIT>" , VersionAPIHandler ) , <EOL> ( r"<STR_LIT>" , DeletedAPIHandler ) , <EOL> ( r"<STR_LIT>" , ComicAPIHandler ) , <EOL> ( r"<STR_LIT>" , ComicListAPIHandler ) , <EOL> ( r"<STR_LIT>" , ComicBookmarkAPIHandler ) , <EOL> ( r"<STR_LIT>" , ComicPageAPIHandler ) , <EOL> ( r"<STR_LIT>" , ThumbnailAPIHandler ) , <EOL> ( r"<STR_LIT>" , FileAPIHandler ) , <EOL> ( r"<STR_LIT>" , EntityAPIHandler ) , <EOL> ( r"<STR_LIT>" , FolderAPIHandler ) , <EOL> ( r"<STR_LIT>" , CommandAPIHandler ) , <EOL> ( r"<STR_LIT>" , ScanStatusAPIHandler ) , <EOL> ( r'<STR_LIT>' , UnknownHandler ) , <EOL> ] <EOL> settings = dict ( <EOL> template_path = os . path . join ( AppFolders . appBase ( ) , "<STR_LIT>" ) , <EOL> static_path = os . path . join ( AppFolders . appBase ( ) , "<STR_LIT>" ) , <EOL> debug = True , <EOL> login_url = "<STR_LIT>" , <EOL> cookie_secret = self . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] , <EOL> xsrf_cookies = True , <EOL> ) <EOL> tornado . web . Application . __init__ ( self , handlers , ** settings ) <EOL> if not opts . no_monitor : <EOL> logging . debug ( "<STR_LIT>" ) <EOL> for l in self . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> logging . debug ( u"<STR_LIT>" . format ( repr ( l ) ) ) <EOL> self . monitor = Monitor ( self . dm , self . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> self . monitor . start ( ) <EOL> self . monitor . scan ( ) <EOL> self . bookmarker = Bookmarker ( self . dm ) <EOL> self . bookmarker . start ( ) <EOL> if opts . launch_browser and self . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> if ( ( platform . system ( ) == "<STR_LIT>" and os . environ . has_key ( '<STR_LIT>' ) ) or <EOL> ( platform . system ( ) == "<STR_LIT>" and not os . environ . has_key ( '<STR_LIT>' ) ) or <EOL> platform . system ( ) == "<STR_LIT>" ) : <EOL> webbrowser . open ( "<STR_LIT>" . format ( self . port ) , new = <NUM_LIT:0> ) <EOL> def rebuild ( self ) : <EOL> sys . argv . insert ( <NUM_LIT:1> , "<STR_LIT>" ) <EOL> self . restart ( ) <EOL> def restart ( self ) : <EOL> self . shutdown ( ) <EOL> executable = sys . executable <EOL> new_argv = [ "<STR_LIT>" ] <EOL> if self . opts . quiet : <EOL> new_argv . append ( "<STR_LIT>" ) <EOL> if self . opts . debug : <EOL> new_argv . append ( "<STR_LIT>" ) <EOL> if "<STR_LIT>" in sys . argv : <EOL> new_argv . append ( "<STR_LIT>" ) <EOL> if getattr ( sys , '<STR_LIT>' , None ) : <EOL> new_argv . insert ( <NUM_LIT:0> , os . path . basename ( executable ) ) <EOL> os . execv ( executable , new_argv ) <EOL> else : <EOL> new_argv . insert ( <NUM_LIT:0> , os . path . basename ( sys . argv [ <NUM_LIT:0> ] ) ) <EOL> os . execl ( executable , executable , * new_argv ) <EOL> def shutdown ( self ) : <EOL> MAX_WAIT_SECONDS_BEFORE_SHUTDOWN = <NUM_LIT:3> <EOL> logging . info ( '<STR_LIT>' ) <EOL> self . monitor . stop ( ) <EOL> self . bookmarker . stop ( ) <EOL> logging . info ( '<STR_LIT>' , MAX_WAIT_SECONDS_BEFORE_SHUTDOWN ) <EOL> io_loop = tornado . ioloop . IOLoop . instance ( ) <EOL> deadline = time . time ( ) + MAX_WAIT_SECONDS_BEFORE_SHUTDOWN <EOL> def stop_loop ( ) : <EOL> now = time . time ( ) <EOL> if now < deadline and ( io_loop . _callbacks or io_loop . _timeouts ) : <EOL> io_loop . add_timeout ( now + <NUM_LIT:1> , stop_loop ) <EOL> else : <EOL> io_loop . stop ( ) <EOL> logging . info ( '<STR_LIT>' ) <EOL> stop_loop ( ) <EOL> def log_request ( self , handler ) : <EOL> if handler . get_status ( ) < <NUM_LIT> : <EOL> log_method = logging . debug <EOL> elif handler . get_status ( ) < <NUM_LIT> : <EOL> log_method = logging . debug <EOL> elif handler . get_status ( ) < <NUM_LIT> : <EOL> log_method = logging . warning <EOL> else : <EOL> log_method = logging . error <EOL> request_time = <NUM_LIT> * handler . request . request_time ( ) <EOL> log_method ( "<STR_LIT>" , handler . get_status ( ) , <EOL> handler . _request_summary ( ) , request_time ) <EOL> def run ( self ) : <EOL> tornado . ioloop . IOLoop . instance ( ) . start ( ) <EOL> def runInThread ( self ) : <EOL> import threading <EOL> t = threading . Thread ( target = self . run ) <EOL> t . start ( ) <EOL> def getComicArchive ( self , path ) : <EOL> for ca in self . comicArchiveList : <EOL> if ca . path == path : <EOL> self . comicArchiveList . remove ( ca ) <EOL> self . comicArchiveList . append ( ca ) <EOL> return ca <EOL> else : <EOL> ca = ComicArchive ( path , default_image_path = AppFolders . imagePath ( "<STR_LIT>" ) ) <EOL> self . comicArchiveList . append ( ca ) <EOL> if len ( self . comicArchiveList ) > <NUM_LIT:10> : <EOL> self . comicArchiveList . pop ( <NUM_LIT:0> ) <EOL> return ca </s>
