and more...
This commit is contained in:
parent
10d2f35b7b
commit
0c18dad1b5
20 changed files with 293 additions and 146 deletions
2
ctl
2
ctl
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
HOST="127.0.0.1:9842"
|
HOST="[::1]:9842"
|
||||||
NAME="openmedialibrary"
|
NAME="openmedialibrary"
|
||||||
PID="/tmp/$NAME.pid"
|
PID="/tmp/$NAME.pid"
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ class Changelog(db.Model):
|
||||||
l.add_items(ids)
|
l.add_items(ids)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_removelistitem(self, user, timestamp, name, ids):
|
def action_removelistitems(self, user, timestamp, name, ids):
|
||||||
from user.models import List
|
from user.models import List
|
||||||
l = List.get(user.id, name)
|
l = List.get(user.id, name)
|
||||||
if l:
|
if l:
|
||||||
|
@ -205,7 +205,7 @@ class Changelog(db.Model):
|
||||||
user.save()
|
user.save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_adduser(self, user, timestamp, peerid, username):
|
def action_addpeer(self, user, timestamp, peerid, username):
|
||||||
from user.models import User
|
from user.models import User
|
||||||
if not 'users' in user.info:
|
if not 'users' in user.info:
|
||||||
user.info['users'] = {}
|
user.info['users'] = {}
|
||||||
|
@ -215,7 +215,7 @@ class Changelog(db.Model):
|
||||||
#fixme, add username to user?
|
#fixme, add username to user?
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def action_removeuser(self, user, timestamp, peerid):
|
def action_removepeer(self, user, timestamp, peerid):
|
||||||
if 'users' in user.info and peerid in user.info['users']:
|
if 'users' in user.info and peerid in user.info['users']:
|
||||||
del user.info['users'][peerid]
|
del user.info['users'][peerid]
|
||||||
user.save()
|
user.save()
|
||||||
|
|
|
@ -172,11 +172,7 @@ def download(request):
|
||||||
data = json.loads(request.form['data']) if 'data' in request.form else {}
|
data = json.loads(request.form['data']) if 'data' in request.form else {}
|
||||||
item = models.Item.get(data['id'])
|
item = models.Item.get(data['id'])
|
||||||
if item:
|
if item:
|
||||||
item.transferprogress = 0
|
item.queue_download()
|
||||||
item.transferadded = datetime.now()
|
|
||||||
p = models.User.get(settings.USER_ID)
|
|
||||||
if p not in item.users:
|
|
||||||
item.users.append(p)
|
|
||||||
item.update()
|
item.update()
|
||||||
response = {'status': 'queued'}
|
response = {'status': 'queued'}
|
||||||
return response
|
return response
|
||||||
|
@ -190,9 +186,11 @@ def cancelDownload(request):
|
||||||
if item:
|
if item:
|
||||||
item.transferprogress = None
|
item.transferprogress = None
|
||||||
item.transferadded = None
|
item.transferadded = None
|
||||||
p = models.User.get(settings.USER_ID)
|
p = state.user()
|
||||||
if p in item.users:
|
if p in item.users:
|
||||||
item.users.remove(p)
|
item.users.remove(p)
|
||||||
|
for l in item.lists.filter_by(user_id=settings.USER_ID):
|
||||||
|
l.remove(item)
|
||||||
item.update()
|
item.update()
|
||||||
response = {'status': 'cancelled'}
|
response = {'status': 'cancelled'}
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -22,6 +22,7 @@ from person import get_sort_name
|
||||||
import media
|
import media
|
||||||
from meta import scraper
|
from meta import scraper
|
||||||
|
|
||||||
|
import state
|
||||||
import utils
|
import utils
|
||||||
|
|
||||||
from oxflask.db import MutableDict
|
from oxflask.db import MutableDict
|
||||||
|
@ -204,8 +205,8 @@ class Item(db.Model):
|
||||||
if key.get('find') or key.get('filter'):
|
if key.get('find') or key.get('filter'):
|
||||||
value = self.json().get(key['id'], None)
|
value = self.json().get(key['id'], None)
|
||||||
if key.get('filterMap') and value:
|
if key.get('filterMap') and value:
|
||||||
value = re.compile(key.get('filterMap')).findall(value)[0]
|
value = re.compile(key.get('filterMap')).findall(value)
|
||||||
print key['id'], value
|
if value: value = value[0]
|
||||||
if value:
|
if value:
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
Find.query.filter_by(item_id=self.id, key=key['id']).delete()
|
Find.query.filter_by(item_id=self.id, key=key['id']).delete()
|
||||||
|
@ -326,9 +327,20 @@ class Item(db.Model):
|
||||||
print 'FIX UPDATE', mainid
|
print 'FIX UPDATE', mainid
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def queue_download(self):
|
||||||
|
u = state.user()
|
||||||
|
if not u in self.users:
|
||||||
|
self.transferprogress = 0
|
||||||
|
self.transferadded = datetime.now()
|
||||||
|
self.users.append(u)
|
||||||
|
|
||||||
def save_file(self, content):
|
def save_file(self, content):
|
||||||
p = User.get(settings.USER_ID)
|
u = state.user()
|
||||||
f = File.get(self.id)
|
f = File.get(self.id)
|
||||||
|
content_id = media.get_id(data=content)
|
||||||
|
if content_id != self.id:
|
||||||
|
print 'INVALID CONTENT', self.id, 'vs', content_id
|
||||||
|
return False
|
||||||
if not f:
|
if not f:
|
||||||
path = 'Downloads/%s.%s' % (self.id, self.info['extension'])
|
path = 'Downloads/%s.%s' % (self.id, self.info['extension'])
|
||||||
f = File.get_or_create(self.id, self.info, path=path)
|
f = File.get_or_create(self.id, self.info, path=path)
|
||||||
|
@ -337,11 +349,11 @@ class Item(db.Model):
|
||||||
ox.makedirs(os.path.dirname(path))
|
ox.makedirs(os.path.dirname(path))
|
||||||
with open(path, 'wb') as fd:
|
with open(path, 'wb') as fd:
|
||||||
fd.write(content)
|
fd.write(content)
|
||||||
if p not in self.users:
|
if u not in self.users:
|
||||||
self.users.append(p)
|
self.users.append(u)
|
||||||
self.transferprogress = 1
|
self.transferprogress = 1
|
||||||
self.added = datetime.now()
|
self.added = datetime.now()
|
||||||
Changelog.record(p, 'additem', self.id, self.info)
|
Changelog.record(u, 'additem', self.id, self.info)
|
||||||
self.update()
|
self.update()
|
||||||
trigger_event('transfer', {
|
trigger_event('transfer', {
|
||||||
'id': self.id, 'progress': 1
|
'id': self.id, 'progress': 1
|
||||||
|
|
|
@ -27,7 +27,7 @@ class LocalNodes(Thread):
|
||||||
|
|
||||||
_BROADCAST = "ff02::1"
|
_BROADCAST = "ff02::1"
|
||||||
_PORT = 9851
|
_PORT = 9851
|
||||||
TTL = 2
|
TTL = 1
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
self._app = app
|
self._app = app
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
from __future__ import division
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
import os
|
||||||
|
|
||||||
|
import ox
|
||||||
|
|
||||||
import pdf
|
import pdf
|
||||||
import epub
|
import epub
|
||||||
import txt
|
import txt
|
||||||
import os
|
|
||||||
import base64
|
|
||||||
import ox
|
|
||||||
|
|
||||||
def get_id(f):
|
def get_id(f=None, data=None):
|
||||||
return base64.b32encode(ox.sha1sum(f).decode('hex'))
|
if data:
|
||||||
|
return base64.b32encode(hashlib.sha1(data).digest())
|
||||||
|
else:
|
||||||
|
return base64.b32encode(ox.sha1sum(f).decode('hex'))
|
||||||
|
|
||||||
|
|
||||||
def metadata(f):
|
def metadata(f):
|
||||||
ext = f.split('.')[-1]
|
ext = f.split('.')[-1]
|
||||||
|
|
|
@ -79,9 +79,18 @@ def api_rejectPeering(app, user_id, message):
|
||||||
def api_removePeering(app, user_id, message):
|
def api_removePeering(app, user_id, message):
|
||||||
user = User.get(user_id)
|
user = User.get(user_id)
|
||||||
if user:
|
if user:
|
||||||
user.peered = False
|
|
||||||
user.info['message'] = message
|
user.info['message'] = message
|
||||||
user.save()
|
user.update_peering(False)
|
||||||
trigger_event('peering', {'id': user.id, 'peered': user.peered})
|
trigger_event('peering', user.json())
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def api_cancelPeering(app, user_id, message):
|
||||||
|
user = User.get(user_id)
|
||||||
|
if user:
|
||||||
|
user.info['message'] = message
|
||||||
|
user.update_peering(False)
|
||||||
|
trigger_event('peering', user.json())
|
||||||
|
user.peered = False
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
10
oml/nodes.py
10
oml/nodes.py
|
@ -169,12 +169,22 @@ class Node(object):
|
||||||
r = self.request('rejectPeering', message)
|
r = self.request('rejectPeering', message)
|
||||||
p = self.user
|
p = self.user
|
||||||
p.update_peering(False)
|
p.update_peering(False)
|
||||||
|
self.go_online()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def removePeering(self, message):
|
def removePeering(self, message):
|
||||||
|
print 'remove peering!!!', self.user
|
||||||
r = self.request('removePeering', message)
|
r = self.request('removePeering', message)
|
||||||
p = self.user
|
p = self.user
|
||||||
p.update_peering(False)
|
p.update_peering(False)
|
||||||
|
self.go_online()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def cancelPeering(self, message):
|
||||||
|
r = self.request('cancelPeering', message)
|
||||||
|
p = self.user
|
||||||
|
p.update_peering(False)
|
||||||
|
self.go_online()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def download(self, item):
|
def download(self, item):
|
||||||
|
|
|
@ -210,3 +210,12 @@ def removePeering(request):
|
||||||
state.nodes.queue(p.id, 'removePeering', data.get('message', ''))
|
state.nodes.queue(p.id, 'removePeering', data.get('message', ''))
|
||||||
return {}
|
return {}
|
||||||
actions.register(removePeering, cache=False)
|
actions.register(removePeering, cache=False)
|
||||||
|
|
||||||
|
@returns_json
|
||||||
|
def cancelPeering(request):
|
||||||
|
data = json.loads(request.form['data']) if 'data' in request.form else {}
|
||||||
|
p = models.User.get_or_create(data['id'])
|
||||||
|
state.nodes.queue('add', p.id)
|
||||||
|
state.nodes.queue(p.id, 'cancelPeering', data.get('message', ''))
|
||||||
|
return {}
|
||||||
|
actions.register(cancelPeering, cache=False)
|
||||||
|
|
|
@ -72,9 +72,11 @@ class User(db.Model):
|
||||||
self.info['username'] = username
|
self.info['username'] = username
|
||||||
|
|
||||||
self.set_nickname(self.info.get('username', 'anonymous'))
|
self.set_nickname(self.info.get('username', 'anonymous'))
|
||||||
|
Changelog.record(state.user(), 'addpeer', self.id, self.nickname)
|
||||||
else:
|
else:
|
||||||
self.peered = False
|
self.peered = False
|
||||||
self.nickname = None
|
self.nickname = None
|
||||||
|
self.save()
|
||||||
for i in self.items:
|
for i in self.items:
|
||||||
i.users.remove(self)
|
i.users.remove(self)
|
||||||
if not i.users:
|
if not i.users:
|
||||||
|
@ -82,6 +84,8 @@ class User(db.Model):
|
||||||
db.session.delete(i)
|
db.session.delete(i)
|
||||||
else:
|
else:
|
||||||
i.update_lists()
|
i.update_lists()
|
||||||
|
Changelog.query.filter_by(user_id=self.id).delete()
|
||||||
|
Changelog.record(state.user(), 'removepeer', self.id)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def set_nickname(self, nickname):
|
def set_nickname(self, nickname):
|
||||||
|
@ -159,6 +163,7 @@ class List(db.Model):
|
||||||
for item_id in items:
|
for item_id in items:
|
||||||
i = Item.get(item_id)
|
i = Item.get(item_id)
|
||||||
self.items.append(i)
|
self.items.append(i)
|
||||||
|
i.queue_download()
|
||||||
i.update()
|
i.update()
|
||||||
db.session.add(self)
|
db.session.add(self)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
|
@ -7,7 +7,7 @@ oml.ui.backButton = function() {
|
||||||
that = Ox.Button({
|
that = Ox.Button({
|
||||||
style: 'squared',
|
style: 'squared',
|
||||||
title: 'arrowLeft',
|
title: 'arrowLeft',
|
||||||
tooltip: Ox._('Back to Books'),
|
tooltip: Ox._('Back to Books {0}', [Ox.UI.symbols.control + 'W']),
|
||||||
type: 'image'
|
type: 'image'
|
||||||
})
|
})
|
||||||
.css({
|
.css({
|
||||||
|
|
38
static/js/deleteListDialog.js
Normal file
38
static/js/deleteListDialog.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
oml.ui.deleteListDialog = function() {
|
||||||
|
|
||||||
|
var ui = oml.user.ui,
|
||||||
|
|
||||||
|
that = oml.ui.confirmDialog({
|
||||||
|
buttons: [
|
||||||
|
Ox.Button({
|
||||||
|
title: Ox._('No, Keep List')
|
||||||
|
}),
|
||||||
|
Ox.Button({
|
||||||
|
title: Ox._('Yes, Delete List')
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: Ox._('Are you sure you want to delete this list?'),
|
||||||
|
title: Ox._('Delete List')
|
||||||
|
}, function() {
|
||||||
|
oml.api.removeList({
|
||||||
|
id: ui._list
|
||||||
|
}, function() {
|
||||||
|
oml.UI.set({
|
||||||
|
find: {
|
||||||
|
conditions: [{
|
||||||
|
key: 'list',
|
||||||
|
operator: '==',
|
||||||
|
value: ':'
|
||||||
|
}],
|
||||||
|
operator: '&'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
oml.updateLists();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
|
@ -37,11 +37,11 @@ oml.ui.findElement = function() {
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
change: function(data) {
|
change: function(data) {
|
||||||
if (data.value == 'advanced') {
|
if (data.value == 'advanced') {
|
||||||
|
oml.$ui.mainMenu.checkItem('findMenu_find_' + previousFindKey);
|
||||||
that.updateElement();
|
that.updateElement();
|
||||||
//oml.$ui.mainMenu.checkItem('findMenu_find_' + previousFindKey);
|
|
||||||
oml.$ui.filterDialog = oml.ui.filterDialog().open();
|
oml.$ui.filterDialog = oml.ui.filterDialog().open();
|
||||||
} else {
|
} else {
|
||||||
//oml.$ui.mainMenu.checkItem('findMenu_find_' + data.value);
|
oml.$ui.mainMenu.checkItem('findMenu_find_' + data.value);
|
||||||
oml.$ui.findInput.options({
|
oml.$ui.findInput.options({
|
||||||
autocomplete: getAutocomplete(),
|
autocomplete: getAutocomplete(),
|
||||||
placeholder: ''
|
placeholder: ''
|
||||||
|
|
|
@ -77,7 +77,7 @@ oml.ui.folders = function() {
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
extras: [
|
extras: [
|
||||||
oml.ui.statusIcon(
|
oml.ui.statusIcon(
|
||||||
!oml.user.online ? 'unknown'
|
!oml.user.online && index ? 'unknown'
|
||||||
: user.online ? 'connected'
|
: user.online ? 'connected'
|
||||||
: 'disconnected'
|
: 'disconnected'
|
||||||
),
|
),
|
||||||
|
@ -179,14 +179,14 @@ oml.ui.folders = function() {
|
||||||
oml.$ui.folderList[index] = oml.ui.folderList({
|
oml.$ui.folderList[index] = oml.ui.folderList({
|
||||||
draggable: !!index,
|
draggable: !!index,
|
||||||
items: items,
|
items: items,
|
||||||
sortable: true
|
sortable: !index
|
||||||
})
|
})
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
add: function() {
|
add: function() {
|
||||||
!index && oml.addList();
|
!index && oml.addList();
|
||||||
},
|
},
|
||||||
'delete': function() {
|
'delete': function() {
|
||||||
!index && oml.deleteList();
|
!index && oml.ui.deleteListDialog().open();
|
||||||
},
|
},
|
||||||
key_control_d: function() {
|
key_control_d: function() {
|
||||||
oml.addList(ui._list);
|
oml.addList(ui._list);
|
||||||
|
@ -224,11 +224,6 @@ oml.ui.folders = function() {
|
||||||
oml.UI.set({find: getFind(libraryId)});
|
oml.UI.set({find: getFind(libraryId)});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.bindEvent(function(data, event) {
|
|
||||||
if (!index) {
|
|
||||||
Ox.print('LIST EVENT', event, data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.css({height: items.length * 16 + 'px'})
|
.css({height: items.length * 16 + 'px'})
|
||||||
.appendTo($content)
|
.appendTo($content)
|
||||||
);
|
);
|
||||||
|
|
|
@ -20,9 +20,6 @@ oml.ui.gridView = function() {
|
||||||
? (data.author || '') : data[sortKey]
|
? (data.author || '') : data[sortKey]
|
||||||
);
|
);
|
||||||
size = size || 128;
|
size = size || 128;
|
||||||
Ox.print('WTF', '-webkit-linear-gradient(top, ' + color.slice(2).map(function(rgba) {
|
|
||||||
return 'rgba(' + rgba.join(', ') + ')';
|
|
||||||
}).join(', ') + ')');
|
|
||||||
return {
|
return {
|
||||||
extra: ui.showFileInfo ? $('<div>')
|
extra: ui.showFileInfo ? $('<div>')
|
||||||
.css({
|
.css({
|
||||||
|
|
|
@ -395,52 +395,56 @@ oml.ui.infoView = function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ox.Button({
|
if (data.mediastate == 'available') {
|
||||||
title: Ox._('Identify Book...'),
|
|
||||||
width: 128
|
|
||||||
})
|
|
||||||
.css({marginTop: '16px'})
|
|
||||||
.bindEvent({
|
|
||||||
click: function() {
|
|
||||||
identify(data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.appendTo($data);
|
|
||||||
|
|
||||||
[
|
Ox.Button({
|
||||||
'isbn10', 'isbn13', 'lccn', 'olid', 'oclc', 'mainid'
|
title: Ox._('Identify Book...'),
|
||||||
].forEach(function(id, index) {
|
width: 128
|
||||||
|
|
||||||
var title = Ox.getObjectById(oml.config.itemKeys, id).title,
|
|
||||||
placeholder = id == 'mainid' ? 'none' : 'unknown';
|
|
||||||
|
|
||||||
$('<div>')
|
|
||||||
.css({
|
|
||||||
marginTop: (index == 0 ? 10 : 6) + 'px',
|
|
||||||
fontWeight: 'bold'
|
|
||||||
})
|
|
||||||
.text(title)
|
|
||||||
.appendTo($data);
|
|
||||||
|
|
||||||
Ox.EditableContent({
|
|
||||||
editable: true,
|
|
||||||
format: function(value) {
|
|
||||||
return id == 'mainid'
|
|
||||||
? Ox.getObjectById(oml.config.itemKeys, value).title
|
|
||||||
: value;
|
|
||||||
},
|
|
||||||
placeholder: placeholder,
|
|
||||||
tooltip: Ox._('Doubleclick to edit'),
|
|
||||||
value: data[id] || ''
|
|
||||||
})
|
})
|
||||||
|
.css({marginTop: '16px'})
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
submit: function(data) {
|
click: function() {
|
||||||
editMetadata(id, data.value);
|
identify(data);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.appendTo($data);
|
.appendTo($data);
|
||||||
|
|
||||||
});
|
[
|
||||||
|
'isbn10', 'isbn13', 'lccn', 'olid', 'oclc', 'mainid'
|
||||||
|
].forEach(function(id, index) {
|
||||||
|
|
||||||
|
var title = Ox.getObjectById(oml.config.itemKeys, id).title,
|
||||||
|
placeholder = id == 'mainid' ? 'none' : 'unknown';
|
||||||
|
|
||||||
|
$('<div>')
|
||||||
|
.css({
|
||||||
|
marginTop: (index == 0 ? 10 : 6) + 'px',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
})
|
||||||
|
.text(title)
|
||||||
|
.appendTo($data);
|
||||||
|
|
||||||
|
Ox.EditableContent({
|
||||||
|
editable: true,
|
||||||
|
format: function(value) {
|
||||||
|
return id == 'mainid'
|
||||||
|
? Ox.getObjectById(oml.config.itemKeys, value).title
|
||||||
|
: value;
|
||||||
|
},
|
||||||
|
placeholder: placeholder,
|
||||||
|
tooltip: Ox._('Doubleclick to edit'),
|
||||||
|
value: data[id] || ''
|
||||||
|
})
|
||||||
|
.bindEvent({
|
||||||
|
submit: function(data) {
|
||||||
|
editMetadata(id, data.value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.appendTo($data);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$('<div>').css({height: '16px'}).appendTo($data);
|
$('<div>').css({height: '16px'}).appendTo($data);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,9 @@ oml.ui.listDialog = function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
oml.api.getLists(function(result) {
|
oml.api.getLists(function(result) {
|
||||||
var lists = result.data.lists[oml.user.id],
|
var lists = result.data.lists.filter(function(list) {
|
||||||
|
return list.user == oml.user.preferences.username;
|
||||||
|
}),
|
||||||
listData = Ox.getObjectById(lists, list),
|
listData = Ox.getObjectById(lists, list),
|
||||||
listNames = lists.map(function(list) {
|
listNames = lists.map(function(list) {
|
||||||
return list.name;
|
return list.name;
|
||||||
|
|
|
@ -4,6 +4,7 @@ oml.ui.mainMenu = function() {
|
||||||
|
|
||||||
var ui = oml.user.ui,
|
var ui = oml.user.ui,
|
||||||
findState = oml.getFindState(ui.find),
|
findState = oml.getFindState(ui.find),
|
||||||
|
fromMenu = false,
|
||||||
appItems = Ox.getObjectById(oml.config.pages, 'app').parts,
|
appItems = Ox.getObjectById(oml.config.pages, 'app').parts,
|
||||||
|
|
||||||
that = Ox.MainMenu({
|
that = Ox.MainMenu({
|
||||||
|
@ -227,7 +228,7 @@ oml.ui.mainMenu = function() {
|
||||||
title: Ox._('Find'),
|
title: Ox._('Find'),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
id: 'finditems',
|
id: 'find',
|
||||||
title: Ox._('Find'),
|
title: Ox._('Find'),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
|
@ -236,10 +237,12 @@ oml.ui.mainMenu = function() {
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 1,
|
max: 1,
|
||||||
items: oml.config.findKeys.map(function(key) {
|
items: oml.config.findKeys.map(function(key) {
|
||||||
|
var checked = key.id == findState.key;
|
||||||
return {
|
return {
|
||||||
id: key.id,
|
id: key.id,
|
||||||
checked: key.id == findState.key,
|
title: Ox._(key.title),
|
||||||
title: Ox._(key.title)
|
checked: checked,
|
||||||
|
keyboard: checked ? 'control f' : ''
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -332,6 +335,30 @@ oml.ui.mainMenu = function() {
|
||||||
oml.UI.set({page: 'preferences'});
|
oml.UI.set({page: 'preferences'});
|
||||||
} else if (id == 'users') {
|
} else if (id == 'users') {
|
||||||
oml.UI.set({page: 'users'});
|
oml.UI.set({page: 'users'});
|
||||||
|
} else if (id == 'alllibraries') {
|
||||||
|
if (!ui._list) {
|
||||||
|
oml.UI.set({item: ''});
|
||||||
|
} else {
|
||||||
|
oml.UI.set({find: {
|
||||||
|
conditions: [],
|
||||||
|
operator: '&'
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
} else if (id == 'thislibrary') {
|
||||||
|
if (Ox.endsWith(ui._list, ':')) {
|
||||||
|
oml.UI.set({item: ''});
|
||||||
|
} else {
|
||||||
|
oml.UI.set({find: {
|
||||||
|
conditions: [{
|
||||||
|
key: 'list',
|
||||||
|
operator: '==',
|
||||||
|
value: ui._list.split(':')[0] + ':'
|
||||||
|
}],
|
||||||
|
operator: '&'
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
} else if (id == 'thislist') {
|
||||||
|
oml.UI.set({item: ''});
|
||||||
} else if (Ox.contains([
|
} else if (Ox.contains([
|
||||||
'newlist', 'newlistfromselection',
|
'newlist', 'newlistfromselection',
|
||||||
'newsmartlist', 'newsmartlistfromresults'
|
'newsmartlist', 'newsmartlistfromresults'
|
||||||
|
@ -342,7 +369,29 @@ oml.ui.mainMenu = function() {
|
||||||
} else if (id == 'editlist') {
|
} else if (id == 'editlist') {
|
||||||
oml.ui.listDialog.open();
|
oml.ui.listDialog.open();
|
||||||
} else if (id == 'deletelist') {
|
} else if (id == 'deletelist') {
|
||||||
oml.ui.deleteListDialog.open();
|
oml.ui.deleteListDialog().open();
|
||||||
|
} else if (id == 'selectall') {
|
||||||
|
oml.$ui.list.selectAll();
|
||||||
|
} else if (id == 'selectnone') {
|
||||||
|
oml.UI.set({listSelection: []});
|
||||||
|
} else if (id == 'invertselection') {
|
||||||
|
oml.$ui.list.invertSelection();
|
||||||
|
} else if (data.id == 'clearclipboard') {
|
||||||
|
oml.clipboard.clear();
|
||||||
|
} else if (data.id == 'delete') {
|
||||||
|
oml.doHistory('delete', ui.listSelection, ui._list, function() {
|
||||||
|
oml.UI.set({listSelection: []});
|
||||||
|
oml.reloadList();
|
||||||
|
});
|
||||||
|
} else if (data.id == 'undo') {
|
||||||
|
fromMenu = true;
|
||||||
|
oml.undoHistory();
|
||||||
|
} else if (data.id == 'redo') {
|
||||||
|
fromMenu = true;
|
||||||
|
oml.redoHistory();
|
||||||
|
} else if (id == 'clearhistory') {
|
||||||
|
fromMenu = true;
|
||||||
|
oml.history.clear();
|
||||||
} else if (id == 'showsidebar') {
|
} else if (id == 'showsidebar') {
|
||||||
oml.UI.set({showSidebar: !ui.showSidebar});
|
oml.UI.set({showSidebar: !ui.showSidebar});
|
||||||
} else if (id == 'showinfo') {
|
} else if (id == 'showinfo') {
|
||||||
|
@ -353,6 +402,13 @@ oml.ui.mainMenu = function() {
|
||||||
oml.UI.set({showBrowser: !ui.showBrowser});
|
oml.UI.set({showBrowser: !ui.showBrowser});
|
||||||
} else if (id == 'transfers') {
|
} else if (id == 'transfers') {
|
||||||
oml.UI.set({page: 'transfers'});
|
oml.UI.set({page: 'transfers'});
|
||||||
|
} else if (id == 'debugmode') {
|
||||||
|
if (oml.localStorage('enableDebugMode')) {
|
||||||
|
oml.localStorage['delete']('enableDebugMode');
|
||||||
|
} else {
|
||||||
|
oml.localStorage('enableDebugMode', true);
|
||||||
|
}
|
||||||
|
window.location.reload();
|
||||||
} else {
|
} else {
|
||||||
Ox.print('MAIN MENU DOES NOT YET HANDLE', id);
|
Ox.print('MAIN MENU DOES NOT YET HANDLE', id);
|
||||||
}
|
}
|
||||||
|
@ -408,6 +464,12 @@ oml.ui.mainMenu = function() {
|
||||||
oml_listselection: function(data) {
|
oml_listselection: function(data) {
|
||||||
that.replaceMenu('editMenu', getEditMenu());
|
that.replaceMenu('editMenu', getEditMenu());
|
||||||
},
|
},
|
||||||
|
oml_listsort: function(data) {
|
||||||
|
that.checkItem('sortMenu_sortitems_' + data.value[0].key);
|
||||||
|
that.checkItem('sortMenu_orderitems_' + (
|
||||||
|
data.value[0].operator == '+' ? 'ascending' : 'descending')
|
||||||
|
);
|
||||||
|
},
|
||||||
oml_showbrowser: function(data) {
|
oml_showbrowser: function(data) {
|
||||||
that.setItemTitle('showbrowser', Ox._((data.value ? 'Hide' : 'Show') + ' Browser'));
|
that.setItemTitle('showbrowser', Ox._((data.value ? 'Hide' : 'Show') + ' Browser'));
|
||||||
},
|
},
|
||||||
|
@ -429,7 +491,7 @@ oml.ui.mainMenu = function() {
|
||||||
selectionItems = ui.listSelection.length,
|
selectionItems = ui.listSelection.length,
|
||||||
selectionItemName = (
|
selectionItemName = (
|
||||||
selectionItems > 1 ? Ox.formatNumber(selectionItems) + ' ' : ''
|
selectionItems > 1 ? Ox.formatNumber(selectionItems) + ' ' : ''
|
||||||
) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'),
|
) + Ox._(selectionItems == 1 ? 'Book' : 'Books'),
|
||||||
clipboardItems = oml.clipboard.items(),
|
clipboardItems = oml.clipboard.items(),
|
||||||
clipboardType = oml.clipboard.type(),
|
clipboardType = oml.clipboard.type(),
|
||||||
clipboardItemName = !clipboardItems ? ''
|
clipboardItemName = !clipboardItems ? ''
|
||||||
|
@ -437,11 +499,12 @@ oml.ui.mainMenu = function() {
|
||||||
clipboardItems > 1 ? Ox.formatNumber(clipboardItems) + ' ' : ''
|
clipboardItems > 1 ? Ox.formatNumber(clipboardItems) + ' ' : ''
|
||||||
) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'),
|
) + Ox._(clipboardItems == 1 ? 'Book' : 'Books'),
|
||||||
canSelect = !ui.item,
|
canSelect = !ui.item,
|
||||||
|
canDownload = listData.user != username && selectionItems,
|
||||||
canCopy = canSelect && selectionItems,
|
canCopy = canSelect && selectionItems,
|
||||||
canCut = canCopy && listData.editable,
|
canCut = canCopy && listData.editable,
|
||||||
canPaste = listData.editable && clipboardItems,
|
canPaste = listData.editable && clipboardItems,
|
||||||
canAdd = canCopy && clipboardItems && clipboardItemType == ui.section,
|
canAdd = canCopy && clipboardItems && clipboardItemType == ui.section,
|
||||||
canDownload = listData.user != username && selectionItems,
|
canDelete = listData.user == username && selectionItems,
|
||||||
historyItems = oml.history.items(),
|
historyItems = oml.history.items(),
|
||||||
undoText = oml.history.undoText(),
|
undoText = oml.history.undoText(),
|
||||||
redoText = oml.history.redoText();
|
redoText = oml.history.redoText();
|
||||||
|
@ -458,13 +521,6 @@ oml.ui.mainMenu = function() {
|
||||||
title: Ox._('Export Books...')
|
title: Ox._('Export Books...')
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{
|
|
||||||
id: 'download',
|
|
||||||
title: Ox._('Download {0}', [selectionItemName]),
|
|
||||||
disabled: !canDownload,
|
|
||||||
keyboard: 'control d'
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
{
|
{
|
||||||
id: 'selectall',
|
id: 'selectall',
|
||||||
title: Ox._('Select All'),
|
title: Ox._('Select All'),
|
||||||
|
@ -484,6 +540,12 @@ oml.ui.mainMenu = function() {
|
||||||
keyboard: 'alt control a'
|
keyboard: 'alt control a'
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
|
{
|
||||||
|
id: 'download',
|
||||||
|
title: Ox._('Download {0}', [selectionItemName]),
|
||||||
|
disabled: !canDownload,
|
||||||
|
keyboard: 'control d'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'cut',
|
id: 'cut',
|
||||||
title: Ox._('Cut {0}', [selectionItemName]),
|
title: Ox._('Cut {0}', [selectionItemName]),
|
||||||
|
@ -526,6 +588,12 @@ oml.ui.mainMenu = function() {
|
||||||
disabled: !canCut,
|
disabled: !canCut,
|
||||||
keyboard: 'delete'
|
keyboard: 'delete'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'deletefromlibrary',
|
||||||
|
title: Ox._('Delete {0} from Library...', [selectionItemName]),
|
||||||
|
disabled: !canDelete,
|
||||||
|
keyboard: 'shift delete'
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
id: 'undo',
|
id: 'undo',
|
||||||
|
@ -548,6 +616,10 @@ oml.ui.mainMenu = function() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFindMenu() {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
function getListMenu() {
|
function getListMenu() {
|
||||||
var isLibraries = !ui._list,
|
var isLibraries = !ui._list,
|
||||||
isLibrary = Ox.endsWith(ui._list, ':'),
|
isLibrary = Ox.endsWith(ui._list, ':'),
|
||||||
|
@ -556,50 +628,52 @@ oml.ui.mainMenu = function() {
|
||||||
return {
|
return {
|
||||||
id: 'listMenu',
|
id: 'listMenu',
|
||||||
title: Ox._('List'),
|
title: Ox._('List'),
|
||||||
items: [
|
items: [].concat(!isLibraries || ui.item ? [
|
||||||
{
|
{
|
||||||
id: 'libraries',
|
id: 'alllibraries',
|
||||||
title: Ox._('All Libraries'),
|
title: Ox._('All Libraries'),
|
||||||
keyboard: 'shift control w'
|
keyboard: 'shift control w'
|
||||||
},
|
}
|
||||||
|
] : []).concat(isList || (isLibrary && ui.item) ? [
|
||||||
{
|
{
|
||||||
id: 'library',
|
id: 'thislibrary',
|
||||||
title: Ox._('This Library'),
|
title: Ox._('This Library'),
|
||||||
disabled: isLibraries,
|
|
||||||
keyboard: isLibrary ? 'control w' : ''
|
keyboard: isLibrary ? 'control w' : ''
|
||||||
},
|
}
|
||||||
|
] : []).concat(isList && ui.item ? [
|
||||||
{
|
{
|
||||||
id: 'list',
|
id: 'thislist',
|
||||||
title: Ox._('This List'),
|
title: Ox._('This List'),
|
||||||
disabled: isLibrary,
|
keyboard: isList ? 'control w' : ''
|
||||||
keyboard: isLibrary ? '' : 'control w'
|
}
|
||||||
},
|
] : []).concat(!isLibraries || ui.item ? [
|
||||||
{},
|
{},
|
||||||
|
] : []).concat([
|
||||||
{
|
{
|
||||||
id: 'newlist',
|
id: 'newlist',
|
||||||
title: Ox._('New List'),
|
title: Ox._('New List...'),
|
||||||
keyboard: 'control n'
|
keyboard: 'control n'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'newlistfromselection',
|
id: 'newlistfromselection',
|
||||||
title: Ox._('New List from Selection'),
|
title: Ox._('New List from Selection...'),
|
||||||
keyboard: 'shift control n',
|
keyboard: 'shift control n',
|
||||||
disabled: !ui.listSelection.length
|
disabled: !ui.listSelection.length
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'newsmartlist',
|
id: 'newsmartlist',
|
||||||
title: Ox._('New Smart List'),
|
title: Ox._('New Smart List...'),
|
||||||
keyboard: 'alt control n'
|
keyboard: 'alt control n'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'newsmartlistfromresults',
|
id: 'newsmartlistfromresults',
|
||||||
title: Ox._('New Smart List from Results'),
|
title: Ox._('New Smart List from Results...'),
|
||||||
keyboard: 'shift alt control n'
|
keyboard: 'shift alt control n'
|
||||||
},
|
},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
id: 'duplicatelist',
|
id: 'duplicatelist',
|
||||||
title: Ox._('Duplicate List'),
|
title: Ox._('Duplicate List...'),
|
||||||
disabled: !isList
|
disabled: !isList
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -614,13 +688,20 @@ oml.ui.mainMenu = function() {
|
||||||
keyboard: 'delete',
|
keyboard: 'delete',
|
||||||
disabled: !isOwnList
|
disabled: !isOwnList
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
that.update = function() {
|
that.update = function(menu) {
|
||||||
return that.updateMenu('listMenu', getListMenu())
|
(
|
||||||
.updateMenu('editMenu', getEditMenu());
|
menu ? Ox.makeArray(menu) : ['listMenu', 'editMenu']
|
||||||
|
).forEach(function(menu) {
|
||||||
|
that.updateMenu(
|
||||||
|
menu,
|
||||||
|
menu == 'listMenu' ? getListMenu() : getEditMenu()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
|
@ -2,10 +2,13 @@ oml.addList = function() {
|
||||||
// addList(isSmart, isFrom) or addList(list) [=dupicate]
|
// addList(isSmart, isFrom) or addList(list) [=dupicate]
|
||||||
var args = arguments,
|
var args = arguments,
|
||||||
isDuplicate = args.length == 1,
|
isDuplicate = args.length == 1,
|
||||||
isSmart, isFrom, list, listData, data;
|
isSmart, isFrom, list, listData, data,
|
||||||
|
username = oml.user.preferences.username;
|
||||||
oml.api.getLists(function(result) {
|
oml.api.getLists(function(result) {
|
||||||
var lists = result.data.lists,
|
var lists = result.data.lists,
|
||||||
listNames = lists[oml.user.id].map(function(list) {
|
listNames = lists.filter(function(list) {
|
||||||
|
return list.user = username;
|
||||||
|
}).map(function(list) {
|
||||||
return list.name;
|
return list.name;
|
||||||
}),
|
}),
|
||||||
query;
|
query;
|
||||||
|
@ -104,38 +107,6 @@ oml.clearFilters = function() {
|
||||||
oml.UI.set({find: find});
|
oml.UI.set({find: find});
|
||||||
};
|
};
|
||||||
|
|
||||||
oml.deleteList = function() {
|
|
||||||
var ui = oml.user.ui;
|
|
||||||
oml.ui.confirmDialog({
|
|
||||||
buttons: [
|
|
||||||
Ox.Button({
|
|
||||||
title: Ox._('No, Keep List')
|
|
||||||
}),
|
|
||||||
Ox.Button({
|
|
||||||
title: Ox._('Yes, Delete List')
|
|
||||||
})
|
|
||||||
],
|
|
||||||
content: Ox._('Are you sure you want to delete this list?'),
|
|
||||||
title: Ox._('Delete List')
|
|
||||||
}, function() {
|
|
||||||
oml.api.removeList({
|
|
||||||
id: ui._list
|
|
||||||
}, function() {
|
|
||||||
oml.UI.set({
|
|
||||||
find: {
|
|
||||||
conditions: [{
|
|
||||||
key: 'list',
|
|
||||||
operator: '==',
|
|
||||||
value: ':'
|
|
||||||
}],
|
|
||||||
operator: '&'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
oml.updateLists();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
oml.doHistory = function(action, items, targets, callback) {
|
oml.doHistory = function(action, items, targets, callback) {
|
||||||
|
@ -415,9 +386,11 @@ oml.enableDragAndDrop = function($list, canMove) {
|
||||||
operator: '&'
|
operator: '&'
|
||||||
}
|
}
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
|
/* FIXME
|
||||||
oml.$ui.folderList[drag.target.folder].value(
|
oml.$ui.folderList[drag.target.folder].value(
|
||||||
drag.target.id, 'items', result.data.items
|
drag.target.id, 'items', result.data.items
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
cleanup(250);
|
cleanup(250);
|
||||||
});
|
});
|
||||||
drag.action == 'move' && oml.reloadList();
|
drag.action == 'move' && oml.reloadList();
|
||||||
|
@ -885,7 +858,9 @@ oml.updateLists = function(callback) {
|
||||||
// FIXME: can this go somewhere else?
|
// FIXME: can this go somewhere else?
|
||||||
Ox.Request.clearCache('getLists');
|
Ox.Request.clearCache('getLists');
|
||||||
oml.api.getLists(function(result) {
|
oml.api.getLists(function(result) {
|
||||||
var items = result.data.lists[oml.user.id];
|
var items = result.data.lists.filter(function(list) {
|
||||||
|
return list.user == oml.user.preferences.username;
|
||||||
|
});
|
||||||
oml.$ui.folderList[0].options({
|
oml.$ui.folderList[0].options({
|
||||||
items: items
|
items: items
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
"columnView.js",
|
"columnView.js",
|
||||||
"confirmDialog.js",
|
"confirmDialog.js",
|
||||||
"connectionButton.js",
|
"connectionButton.js",
|
||||||
|
"deleteListDialog.js",
|
||||||
"errorDialog.js",
|
"errorDialog.js",
|
||||||
"filter.js",
|
"filter.js",
|
||||||
"filtersInnerPanel.js",
|
"filtersInnerPanel.js",
|
||||||
|
|
Loading…
Reference in a new issue