mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Content server: Handle books with # in their title/authors correctly. Fixes #7354 (Having problems with calibre server)
This commit is contained in:
parent
39e102e3f8
commit
20e015ed74
@ -5,10 +5,37 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import subprocess, tempfile, os, time
|
||||
import subprocess, tempfile, os, time, sys
|
||||
|
||||
from setup import Command
|
||||
|
||||
try:
|
||||
from pyinotify import WatchManager, ThreadedNotifier, EventsCodes, ProcessEvent
|
||||
except:
|
||||
wm = None
|
||||
else:
|
||||
wm = WatchManager()
|
||||
flags = EventsCodes.ALL_FLAGS
|
||||
mask = flags['IN_MODIFY']
|
||||
|
||||
class ProcessEvents(ProcessEvent):
|
||||
|
||||
def __init__(self, command):
|
||||
ProcessEvent.__init__(self)
|
||||
self.command = command
|
||||
|
||||
def process_default(self, event):
|
||||
name = getattr(event,
|
||||
'name', None)
|
||||
if name and os.path.splitext(name)[1].startswith('.py'):
|
||||
print
|
||||
print name, 'changed'
|
||||
self.command.kill_server()
|
||||
self.command.launch_server()
|
||||
print self.command.prompt,
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
class Server(Command):
|
||||
|
||||
description = 'Run the calibre server in development mode conveniently'
|
||||
@ -20,35 +47,51 @@ class Server(Command):
|
||||
'-I', 'src', 'src/monocle.js'],
|
||||
stdout=open('resources/content_server/read/monocle.js', 'wb'))
|
||||
|
||||
def launch_server(self, log):
|
||||
def launch_server(self):
|
||||
print 'Starting server...\n'
|
||||
self.rebuild_monocole()
|
||||
p = subprocess.Popen(['calibre-server', '--develop'],
|
||||
stderr=subprocess.STDOUT, stdout=log)
|
||||
stderr=subprocess.STDOUT, stdout=self.server_log)
|
||||
time.sleep(0.2)
|
||||
if p.poll() is not None:
|
||||
print 'Starting server failed'
|
||||
raise SystemExit(1)
|
||||
return p
|
||||
|
||||
def kill_server(self):
|
||||
while self.server_proc.poll() is None:
|
||||
self.server_proc.terminate()
|
||||
time.sleep(0.1)
|
||||
self.server_proc.kill()
|
||||
|
||||
def watch(self):
|
||||
if wm is not None:
|
||||
self.notifier = ThreadedNotifier(wm, ProcessEvents(self))
|
||||
self.notifier.start()
|
||||
self.wdd = wm.add_watch(os.path.abspath('src'), mask, rec=True)
|
||||
|
||||
def run(self, opts):
|
||||
tdir = tempfile.gettempdir()
|
||||
logf = os.path.join(tdir, 'calibre-server.log')
|
||||
log = open(logf, 'ab')
|
||||
self.server_log = open(logf, 'ab')
|
||||
self.prompt = 'Press Enter to kill/restart server. Ctrl+C to quit: '
|
||||
print 'Server log available at:', logf
|
||||
print
|
||||
self.server_proc = None
|
||||
self.watch()
|
||||
|
||||
while True:
|
||||
print 'Starting server...'
|
||||
p = self.launch_server(log)
|
||||
self.server_proc = self.launch_server()
|
||||
try:
|
||||
raw_input('Press Enter to kill/restart server. Ctrl+C to quit: ')
|
||||
raw_input(self.prompt)
|
||||
except:
|
||||
if p.poll() is None:
|
||||
p.kill()
|
||||
if self.server_proc.poll() is None:
|
||||
self.server_proc.kill()
|
||||
break
|
||||
else:
|
||||
while p.poll() is None:
|
||||
p.terminate()
|
||||
time.sleep(0.1)
|
||||
p.kill()
|
||||
self.kill_server()
|
||||
print
|
||||
|
||||
if hasattr(self, 'notifier'):
|
||||
self.notifier.stop()
|
||||
|
||||
|
@ -566,7 +566,8 @@ class BrowseServer(object):
|
||||
if not val:
|
||||
val = ''
|
||||
args[key] = xml(val, True)
|
||||
fname = ascii_filename(args['title']) + ' - ' + ascii_filename(args['authors'])
|
||||
fname = quote(ascii_filename(args['title']) + ' - ' +
|
||||
ascii_filename(args['authors']))
|
||||
return args, fmt, fmts, fname
|
||||
|
||||
@Endpoint(mimetype='application/json; charset=utf-8')
|
||||
|
@ -70,10 +70,10 @@ class ContentServer(object):
|
||||
id = id.rpartition('_')[-1].partition('.')[0]
|
||||
match = re.search(r'\d+', id)
|
||||
if not match:
|
||||
raise cherrypy.HTTPError(400, 'id:%s not an integer'%id)
|
||||
raise cherrypy.HTTPError(404, 'id:%s not an integer'%id)
|
||||
id = int(match.group())
|
||||
if not self.db.has_id(id):
|
||||
raise cherrypy.HTTPError(400, 'id:%d does not exist in database'%id)
|
||||
raise cherrypy.HTTPError(404, 'id:%d does not exist in database'%id)
|
||||
if what == 'thumb' or what.startswith('thumb_'):
|
||||
try:
|
||||
width, height = map(int, what.split('_')[1:])
|
||||
|
@ -7,6 +7,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import re, os
|
||||
import __builtin__
|
||||
from urllib import quote
|
||||
|
||||
import cherrypy
|
||||
from lxml import html
|
||||
@ -115,8 +116,8 @@ def build_index(books, num, search, sort, order, start, total, url_base, CKEYS,
|
||||
|
||||
data = TD()
|
||||
for fmt in book['formats'].split(','):
|
||||
a = ascii_filename(book['authors'])
|
||||
t = ascii_filename(book['title'])
|
||||
a = quote(ascii_filename(book['authors']))
|
||||
t = quote(ascii_filename(book['title']))
|
||||
s = SPAN(
|
||||
A(
|
||||
fmt.lower(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user