mirror of
https://github.com/JimmXinu/FanFicFare.git
synced 2025-12-06 08:52:55 +01:00
Improve error handling/reporting, make redownloads appear at top of recent list.
This commit is contained in:
parent
94063d478c
commit
a3f75cb3eb
3 changed files with 89 additions and 57 deletions
|
|
@ -22,7 +22,7 @@ class DownloadMeta(db.Model):
|
||||||
title = db.StringProperty()
|
title = db.StringProperty()
|
||||||
author = db.StringProperty()
|
author = db.StringProperty()
|
||||||
format = db.StringProperty()
|
format = db.StringProperty()
|
||||||
failure = db.StringProperty()
|
failure = db.TextProperty()
|
||||||
completed = db.BooleanProperty(default=False)
|
completed = db.BooleanProperty(default=False)
|
||||||
date = db.DateTimeProperty(auto_now_add=True)
|
date = db.DateTimeProperty(auto_now_add=True)
|
||||||
version = db.StringProperty()
|
version = db.StringProperty()
|
||||||
|
|
|
||||||
142
main.py
142
main.py
|
|
@ -25,6 +25,7 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import zlib
|
import zlib
|
||||||
import urllib
|
import urllib
|
||||||
|
import datetime
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
@ -132,49 +133,60 @@ class FileServer(webapp.RequestHandler):
|
||||||
if fileId == None or len(fileId) < 3:
|
if fileId == None or len(fileId) < 3:
|
||||||
self.redirect('/')
|
self.redirect('/')
|
||||||
return
|
return
|
||||||
|
|
||||||
key = db.Key(fileId)
|
|
||||||
fanfic = db.get(key)
|
|
||||||
|
|
||||||
# check for completed & failure.
|
try:
|
||||||
|
key = db.Key(fileId)
|
||||||
name = fanfic.name.encode('utf-8')
|
fanfic = db.get(key)
|
||||||
|
|
||||||
#name = urllib.quote(name)
|
|
||||||
|
|
||||||
logging.info("Serving file: %s" % name)
|
|
||||||
|
|
||||||
if name.endswith('.epub'):
|
# check for completed & failure.
|
||||||
self.response.headers['Content-Type'] = 'application/epub+zip'
|
|
||||||
elif name.endswith('.html'):
|
name = fanfic.name.encode('utf-8')
|
||||||
self.response.headers['Content-Type'] = 'text/html'
|
|
||||||
elif name.endswith('.txt'):
|
logging.info("Serving file: %s" % name)
|
||||||
self.response.headers['Content-Type'] = 'text/plain'
|
|
||||||
elif name.endswith('.zip'):
|
if name.endswith('.epub'):
|
||||||
self.response.headers['Content-Type'] = 'application/zip'
|
self.response.headers['Content-Type'] = 'application/epub+zip'
|
||||||
else:
|
elif name.endswith('.html'):
|
||||||
self.response.headers['Content-Type'] = 'application/octet-stream'
|
self.response.headers['Content-Type'] = 'text/html'
|
||||||
|
elif name.endswith('.txt'):
|
||||||
|
self.response.headers['Content-Type'] = 'text/plain'
|
||||||
|
elif name.endswith('.zip'):
|
||||||
|
self.response.headers['Content-Type'] = 'application/zip'
|
||||||
|
else:
|
||||||
|
self.response.headers['Content-Type'] = 'application/octet-stream'
|
||||||
|
|
||||||
self.response.headers['Content-disposition'] = 'attachment; filename="%s"' % name
|
self.response.headers['Content-disposition'] = 'attachment; filename="%s"' % name
|
||||||
|
|
||||||
data = DownloadData.all().filter("download =", fanfic).order("index")
|
data = DownloadData.all().filter("download =", fanfic).order("index")
|
||||||
# epubs are all already compressed.
|
# epubs are all already compressed.
|
||||||
# Each chunk is compress individually to avoid having
|
# Each chunk is compress individually to avoid having
|
||||||
# to hold the whole in memory just for the
|
# to hold the whole in memory just for the
|
||||||
# compress/uncompress
|
# compress/uncompress
|
||||||
if fanfic.format != 'epub':
|
if fanfic.format != 'epub':
|
||||||
def dc(data):
|
def dc(data):
|
||||||
try:
|
try:
|
||||||
return zlib.decompress(data)
|
return zlib.decompress(data)
|
||||||
# if error, assume it's a chunk from before we started compessing.
|
# if error, assume it's a chunk from before we started compessing.
|
||||||
except zlib.error:
|
except zlib.error:
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
def dc(data):
|
||||||
return data
|
return data
|
||||||
else:
|
|
||||||
def dc(data):
|
|
||||||
return data
|
|
||||||
|
|
||||||
for datum in data:
|
for datum in data:
|
||||||
self.response.out.write(dc(datum.blob))
|
self.response.out.write(dc(datum.blob))
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
fic = DownloadMeta()
|
||||||
|
fic.failure = unicode(e)
|
||||||
|
|
||||||
|
template_values = dict(fic = fic,
|
||||||
|
#nickname = user.nickname(),
|
||||||
|
#escaped_url = escaped_url
|
||||||
|
)
|
||||||
|
path = os.path.join(os.path.dirname(__file__), 'status.html')
|
||||||
|
self.response.out.write(template.render(path, template_values))
|
||||||
|
|
||||||
|
|
||||||
class FileStatusServer(webapp.RequestHandler):
|
class FileStatusServer(webapp.RequestHandler):
|
||||||
def get(self):
|
def get(self):
|
||||||
|
|
@ -187,19 +199,29 @@ class FileStatusServer(webapp.RequestHandler):
|
||||||
|
|
||||||
if fileId == None or len(fileId) < 3:
|
if fileId == None or len(fileId) < 3:
|
||||||
self.redirect('/')
|
self.redirect('/')
|
||||||
|
|
||||||
key = db.Key(fileId)
|
|
||||||
fic = db.get(key)
|
|
||||||
|
|
||||||
logging.info("Status url: %s" % fic.url)
|
escaped_url=False
|
||||||
if fic.completed and fic.format=='epub':
|
|
||||||
escaped_url = urlEscape(self.request.host_url+"/file/"+fic.name+"."+fic.format+"?id="+fileId+"&fake=file."+fic.format)
|
try:
|
||||||
else:
|
key = db.Key(fileId)
|
||||||
escaped_url=False
|
fic = db.get(key)
|
||||||
|
|
||||||
|
if fic:
|
||||||
|
logging.info("Status url: %s" % fic.url)
|
||||||
|
if fic.completed and fic.format=='epub':
|
||||||
|
escaped_url = urlEscape(self.request.host_url+"/file/"+fic.name+"."+fic.format+"?id="+fileId+"&fake=file."+fic.format)
|
||||||
|
else:
|
||||||
|
fic = DownloadMeta()
|
||||||
|
fic.failure = "Download not found"
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
fic = DownloadMeta()
|
||||||
|
fic.failure = unicode(e)
|
||||||
|
|
||||||
template_values = dict(fic = fic,
|
template_values = dict(fic = fic,
|
||||||
nickname = user.nickname(),
|
nickname = user.nickname(),
|
||||||
escaped_url = escaped_url
|
escaped_url = escaped_url
|
||||||
)
|
)
|
||||||
path = os.path.join(os.path.dirname(__file__), 'status.html')
|
path = os.path.join(os.path.dirname(__file__), 'status.html')
|
||||||
self.response.out.write(template.render(path, template_values))
|
self.response.out.write(template.render(path, template_values))
|
||||||
|
|
||||||
|
|
@ -249,9 +271,14 @@ class FanfictionDownloader(UserConfigServer):
|
||||||
if not user:
|
if not user:
|
||||||
self.redirect(users.create_login_url(self.request.uri))
|
self.redirect(users.create_login_url(self.request.uri))
|
||||||
return
|
return
|
||||||
|
|
||||||
format = self.request.get('format')
|
format = self.request.get('format')
|
||||||
url = self.request.get('url')
|
url = self.request.get('url')
|
||||||
|
|
||||||
|
if not url or url.strip() == "":
|
||||||
|
self.redirect('/')
|
||||||
|
return
|
||||||
|
|
||||||
logging.info("Queuing Download: %s" % url)
|
logging.info("Queuing Download: %s" % url)
|
||||||
login = self.request.get('login')
|
login = self.request.get('login')
|
||||||
password = self.request.get('password')
|
password = self.request.get('password')
|
||||||
|
|
@ -265,6 +292,7 @@ class FanfictionDownloader(UserConfigServer):
|
||||||
download = q[0]
|
download = q[0]
|
||||||
download.completed=False
|
download.completed=False
|
||||||
download.failure=None
|
download.failure=None
|
||||||
|
download.date=datetime.datetime.now()
|
||||||
for c in download.data_chunks:
|
for c in download.data_chunks:
|
||||||
c.delete()
|
c.delete()
|
||||||
|
|
||||||
|
|
@ -308,9 +336,9 @@ class FanfictionDownloader(UserConfigServer):
|
||||||
logging.info("enqueued download key: " + str(download.key()))
|
logging.info("enqueued download key: " + str(download.key()))
|
||||||
|
|
||||||
except (exceptions.FailedToLogin,exceptions.AdultCheckRequired), e:
|
except (exceptions.FailedToLogin,exceptions.AdultCheckRequired), e:
|
||||||
download.failure = str(e)
|
download.failure = unicode(e)
|
||||||
download.put()
|
download.put()
|
||||||
logging.info(str(e))
|
logging.info(unicode(e))
|
||||||
is_login= ( isinstance(e, exceptions.FailedToLogin) )
|
is_login= ( isinstance(e, exceptions.FailedToLogin) )
|
||||||
template_values = dict(nickname = user.nickname(),
|
template_values = dict(nickname = user.nickname(),
|
||||||
url = url,
|
url = url,
|
||||||
|
|
@ -328,13 +356,13 @@ class FanfictionDownloader(UserConfigServer):
|
||||||
self.response.out.write(template.render(path, template_values))
|
self.response.out.write(template.render(path, template_values))
|
||||||
return
|
return
|
||||||
except (exceptions.InvalidStoryURL,exceptions.UnknownSite,exceptions.StoryDoesNotExist), e:
|
except (exceptions.InvalidStoryURL,exceptions.UnknownSite,exceptions.StoryDoesNotExist), e:
|
||||||
logging.warn(str(e))
|
logging.warn(unicode(e))
|
||||||
download.failure = str(e)
|
download.failure = unicode(e)
|
||||||
download.put()
|
download.put()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logging.error("Failure Queuing Download: url:%s" % url)
|
logging.error("Failure Queuing Download: url:%s" % url)
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
download.failure = str(e)
|
download.failure = unicode(e)
|
||||||
download.put()
|
download.put()
|
||||||
|
|
||||||
self.redirect('/status?id='+str(download.key()))
|
self.redirect('/status?id='+str(download.key()))
|
||||||
|
|
@ -373,6 +401,8 @@ class FanfictionDownloaderTask(UserConfigServer):
|
||||||
download = DownloadMeta()
|
download = DownloadMeta()
|
||||||
else:
|
else:
|
||||||
download = q[0]
|
download = q[0]
|
||||||
|
download.failure=None
|
||||||
|
download.date=datetime.datetime.now()
|
||||||
download.completed=False
|
download.completed=False
|
||||||
for c in download.data_chunks:
|
for c in download.data_chunks:
|
||||||
c.delete()
|
c.delete()
|
||||||
|
|
@ -389,7 +419,7 @@ class FanfictionDownloaderTask(UserConfigServer):
|
||||||
adapter = adapters.getAdapter(config,url)
|
adapter = adapters.getAdapter(config,url)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
download.failure = str(e)
|
download.failure = unicode(e)
|
||||||
download.put()
|
download.put()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -405,7 +435,7 @@ class FanfictionDownloaderTask(UserConfigServer):
|
||||||
writer = writers.getWriter(format,config,adapter)
|
writer = writers.getWriter(format,config,adapter)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
download.failure = str(e)
|
download.failure = unicode(e)
|
||||||
download.put()
|
download.put()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='urlbox'>
|
<div id='urlbox'>
|
||||||
|
{% if fic.url %}
|
||||||
<div id='greeting'>
|
<div id='greeting'>
|
||||||
<p><a href='{{ fic.url }}'>{{ fic.url }}</a></p>
|
<p><a href='{{ fic.url }}'>{{ fic.url }}</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
{% if fic.completed %}
|
{% if fic.completed %}
|
||||||
<p>Your fic has finished processing and you can download it now:</p>
|
<p>Your fic has finished processing and you can download it now:</p>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue