support drag and drop
This commit is contained in:
parent
2cbcc9e7dd
commit
25c24d6f20
4 changed files with 121 additions and 2 deletions
|
@ -8,11 +8,23 @@ import os
|
|||
from urllib.request import quote
|
||||
import zipfile
|
||||
|
||||
from .models import Item
|
||||
import ox
|
||||
|
||||
from .models import Item, File
|
||||
from user.models import List
|
||||
from .scan import add_file
|
||||
import db
|
||||
import settings
|
||||
import tornado.web
|
||||
import tornado.gen
|
||||
import tornado.concurrent
|
||||
|
||||
from oxtornado import json_dumps, json_response
|
||||
|
||||
from media import get_id
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('item.handlers')
|
||||
|
||||
class OMLHandler(tornado.web.RequestHandler):
|
||||
|
||||
|
@ -126,3 +138,60 @@ class ReaderHandler(OMLHandler):
|
|||
item.update_sort()
|
||||
item.save()
|
||||
return serve_static(self, os.path.join(settings.static_path, html), 'text/html')
|
||||
|
||||
class UploadHandler(tornado.web.RequestHandler):
|
||||
|
||||
def initialize(self, context=None):
|
||||
self._context = context
|
||||
|
||||
def get(self):
|
||||
self.write('use POST')
|
||||
|
||||
@tornado.web.asynchronous
|
||||
@tornado.gen.coroutine
|
||||
def post(self):
|
||||
if 'origin' in self.request.headers and self.request.host not in self.request.headers['origin']:
|
||||
logger.debug('reject cross site attempt to access api %s', self.request)
|
||||
self.set_status(403)
|
||||
self.write('')
|
||||
return
|
||||
def save_files(context, request, callback):
|
||||
listname = request.arguments.get('list', None)
|
||||
if listname:
|
||||
listname = listname[0]
|
||||
if isinstance(listname, bytes):
|
||||
listname = listname.decode('utf-8')
|
||||
with context():
|
||||
prefs = settings.preferences
|
||||
ids = []
|
||||
for upload in request.files.get('files', []):
|
||||
filename = upload.filename
|
||||
id = get_id(data=upload.body)
|
||||
ids.append(id)
|
||||
file = File.get(id)
|
||||
if not file:
|
||||
prefix_books = os.path.join(os.path.expanduser(prefs['libraryPath']), 'Books/')
|
||||
prefix_imported = os.path.join(prefix_books, 'Imported/')
|
||||
ox.makedirs(prefix_imported)
|
||||
import_name = os.path.join(prefix_imported, filename)
|
||||
n = 1
|
||||
while os.path.exists(import_name):
|
||||
n += 1
|
||||
name, extension = filename.rsplit('.', 1)
|
||||
import_name = os.path.join(prefix_imported, '%s [%d].%s' % (name, n, extension))
|
||||
with open(import_name, 'wb') as fd:
|
||||
fd.write(upload.body)
|
||||
file = add_file(id, import_name, prefix_books)
|
||||
if listname and ids:
|
||||
l = List.get(settings.USER_ID, listname)
|
||||
if l:
|
||||
l.add_items(ids)
|
||||
response = json_response({'ids': ids})
|
||||
callback(response)
|
||||
|
||||
response = yield tornado.gen.Task(save_files, self._context, self.request)
|
||||
if not 'status' in response:
|
||||
response = json_response(response)
|
||||
response = json_dumps(response)
|
||||
self.set_header('Content-Type', 'application/json')
|
||||
self.write(response)
|
||||
|
|
|
@ -13,7 +13,7 @@ from tornado.web import StaticFileHandler, Application
|
|||
|
||||
from cache import Cache
|
||||
from item.handlers import EpubHandler, ReaderHandler, FileHandler
|
||||
from item.handlers import OMLHandler
|
||||
from item.handlers import OMLHandler, UploadHandler
|
||||
from item.icons import IconHandler
|
||||
import db
|
||||
import node.server
|
||||
|
@ -74,6 +74,7 @@ def run():
|
|||
'attachment': True
|
||||
}),
|
||||
(r'/(.*)/(cover|preview)(\d*).jpg', IconHandler),
|
||||
(r'/api/upload/', UploadHandler, dict(context=db.session)),
|
||||
(r'/api/', oxtornado.ApiHandler, dict(context=db.session)),
|
||||
(r'/ws', websocket.Handler),
|
||||
(r"(.*)", MainHandler),
|
||||
|
|
|
@ -93,6 +93,25 @@
|
|||
Ox.$window.on({
|
||||
resize: oml.resizeWindow
|
||||
});
|
||||
Ox.$document.on({
|
||||
dragenter: function(event) {
|
||||
event.preventDefault();
|
||||
},
|
||||
dragover: function(event) {
|
||||
event.preventDefault();
|
||||
},
|
||||
drop: function(event) {
|
||||
if (event.originalEvent.dataTransfer.files) {
|
||||
event.preventDefault();
|
||||
oml.upload(event.originalEvent.dataTransfer.files, function(response) {
|
||||
setTimeout(function() {
|
||||
oml.UI.set({listSelection: response.data.ids});
|
||||
oml.reloadList();
|
||||
}, 50);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
oml.$ui.appPanel = oml.ui.appPanel().appendTo(Ox.$body);
|
||||
oml.$ui.loadingIcon.updateElement(Ox.Request.requests());
|
||||
Ox.Request.bindEvent({
|
||||
|
|
|
@ -999,3 +999,33 @@ oml.updateDebugMenu = function() {
|
|||
});
|
||||
oml.user.ui.showDebugMenu ? menu.show() : menu.hide();
|
||||
};
|
||||
|
||||
oml.supportedExtensions = ['pdf', 'epub', 'cbr', 'cbz'];
|
||||
oml.upload = function(files, callback) {
|
||||
var request = new XMLHttpRequest(),
|
||||
url = '/api/upload/';
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == 4) {
|
||||
if (request.status == 200) {
|
||||
callback(JSON.parse(request.responseText), null);
|
||||
} else {
|
||||
callback(null, {
|
||||
code: request.status,
|
||||
text: request.statusText
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
var formData = new FormData();
|
||||
for (var i=0; i < files.length; i++) {
|
||||
var extension = Ox.last(files[i].name.split('.'));
|
||||
if (Ox.contains(oml.supportedExtensions, extension)) {
|
||||
formData.append('files', files[i]);
|
||||
}
|
||||
}
|
||||
if (oml.user.ui._list[0] == ':' && oml.user.ui._list.length > 1) {
|
||||
formData.append('list', oml.user.ui._list.slice(1));
|
||||
}
|
||||
request.open('post', url, true);
|
||||
request.send(formData);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue