This commit is contained in:
j 2016-01-14 14:29:11 +05:30
parent 82d11e412f
commit d54f524953
4 changed files with 109 additions and 7 deletions

View File

@ -153,7 +153,6 @@ def remove(data):
id id
} }
''' '''
logger.debug('remove files %s', data)
if 'ids' in data and data['ids']: if 'ids' in data and data['ids']:
for i in models.Item.query.filter(models.Item.id.in_(data['ids'])): for i in models.Item.query.filter(models.Item.id.in_(data['ids'])):
i.remove_file() i.remove_file()
@ -229,7 +228,6 @@ def findMetadata(data):
response = { response = {
'items': [] 'items': []
} }
logger.debug('findMetadata %s', data)
key = ','.join(sorted(data)) key = ','.join(sorted(data))
if key == 'isbn': if key == 'isbn':
r = meta.lookup(key, data[key]) r = meta.lookup(key, data[key])
@ -267,7 +265,6 @@ def getMetadata(data):
} }
key can be one of the supported identifiers: isbn10, isbn13, oclc, olid,... key can be one of the supported identifiers: isbn10, isbn13, oclc, olid,...
''' '''
logger.debug('getMetadata %s', data)
if 'includeEdits' in data: if 'includeEdits' in data:
include_edits = data.pop('includeEdits') include_edits = data.pop('includeEdits')
else: else:
@ -340,6 +337,24 @@ def scan(data):
return {} return {}
actions.register(scan, cache=False) actions.register(scan, cache=False)
def export(data):
'''
takes {
path absolute path to import
list listename (add new items to this list)
mode add|replace
}
'''
import user.models
l = user.models.List.get(':' + data['list'])
if l:
data['list'] = ':' + data['list']
state.tasks.queue('export', data)
response = {'status': 'ok'}
else:
response = {'status': 'invalid list'}
return response
actions.register(export, cache=False)
def _import(data): def _import(data):
''' '''
@ -349,7 +364,6 @@ def _import(data):
mode copy|move mode copy|move
} }
''' '''
logger.debug('api.import %s', data)
state.tasks.queue('import', data) state.tasks.queue('import', data)
return {} return {}
actions.register(_import, 'import', cache=False) actions.register(_import, 'import', cache=False)

View File

@ -6,7 +6,6 @@ from queue import Queue
from threading import Thread from threading import Thread
from websocket import trigger_event from websocket import trigger_event
import state
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -23,6 +22,7 @@ class Tasks(Thread):
def run(self): def run(self):
import item.scan import item.scan
from user.models import List
while self.connected: while self.connected:
m = self.q.get() m = self.q.get()
if m: if m:
@ -32,6 +32,8 @@ class Tasks(Thread):
trigger_event('pong', data) trigger_event('pong', data)
elif action == 'import': elif action == 'import':
item.scan.run_import(data) item.scan.run_import(data)
elif action == 'export':
List.export(data)
elif action == 'scan': elif action == 'scan':
item.scan.run_scan() item.scan.run_scan()
else: else:

View File

@ -3,7 +3,10 @@
from datetime import datetime from datetime import datetime
import json import json
import hashlib import hashlib
import os
import shutil
import ox
import sqlalchemy as sa import sqlalchemy as sa
from changelog import Changelog from changelog import Changelog
@ -13,6 +16,8 @@ import json_pickler
import settings import settings
import state import state
import utils import utils
import media
from websocket import trigger_event
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -323,6 +328,87 @@ class List(db.Model):
state.db.session.add(self) state.db.session.add(self)
state.db.session.commit() state.db.session.commit()
def create_symlinks(self):
pass
@classmethod
def export(cls, data):
with db.session():
self = cls.get(data['list'])
if not self:
return
mode = data.get('mode')
prefix = data.get('path')
if mode not in ('add', 'replace'):
logger.debug('invalid mode %s', mode)
return
if not prefix or prefix == '/':
logger.debug('invalid export path %s', prefix)
trigger_event('activity', {
'activity': 'export',
'path': prefix,
'progress': [0, 0],
'status': {'code': 404, 'text': 'invalid export path'}
})
return
root = prefix
while not os.path.exists(root) and root != '/':
root = os.path.dirname(root)
if not os.access(root, os.W_OK):
logger.debug('can not write to %s', root)
trigger_event('activity', {
'activity': 'export',
'path': prefix,
'progress': [0, 0],
'path': prefix,
'status': {'code': 404, 'text': 'permission denied'}
})
return
if os.path.exists(prefix):
existing_files = set(
os.path.join(root, f) for root, _, files in os.walk(prefix) for f in files
)
else:
existing_files = set()
new_files = set()
count = self.get_items().count()
n = 1
for i in self.get_items():
if i.files.all():
f = i.files.all()[0]
source = f.fullpath()
target = os.path.join(prefix, f.path)
if mode == 'add':
p = 1
parts = target.rsplit('.', 1)
while os.path.exists(target) and media.get_id(target) != f.sha1:
target = '.'.join([parts[0], f.sha1[:p], parts[1]])
p += 1
ox.makedirs(os.path.dirname(target))
if os.path.exists(target):
if mode == 'replace' and media.get_id(target) != f.sha1:
os.unlink(target)
shutil.copy2(source, target)
else:
shutil.copy2(source, target)
new_files.add(target)
trigger_event('activity', {
'activity': 'export',
'path': prefix,
'progress': [n, count]
})
n += 1
if mode == 'replace':
for f in list(existing_files - new_files):
os.unlink(f)
utils.remove_empty_folders(prefix)
trigger_event('activity', {
'activity': 'export',
'progress': [count, count],
'path': prefix,
'status': {'code': 200, 'text': ''},
})
class Metadata(db.Model): class Metadata(db.Model):
__tablename__ = 'user_metadata' __tablename__ = 'user_metadata'

View File

@ -331,7 +331,7 @@ oml.ui.importExportDialog = function() {
); );
$innerPanel.replaceElement(0, $innerPanel.replaceElement(0,
renderActivity({ renderActivity({
activity: 'import', activity: selected,
path: data.path, path: data.path,
progress: [0, 0] progress: [0, 0]
}) })
@ -341,7 +341,7 @@ oml.ui.importExportDialog = function() {
if (result) { if (result) {
data.list = result.data.id data.list = result.data.id
} }
oml.api.import({ oml.api[selected]({
list: data.list, list: data.list,
mode: data.mode, mode: data.mode,
path: data.path, path: data.path,