export
This commit is contained in:
parent
82d11e412f
commit
d54f524953
4 changed files with 109 additions and 7 deletions
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue