Compare commits
5 Commits
6f8acb90d9
...
a45445d114
Author | SHA1 | Date |
---|---|---|
j | a45445d114 | |
j | fa9482de48 | |
j | 41d90e1736 | |
j | b4b66f9bd5 | |
j | 8169d8e720 |
|
@ -36,14 +36,14 @@ def add_record(action, *args, **kwargs):
|
||||||
revision = next_revision()
|
revision = next_revision()
|
||||||
|
|
||||||
data = [revision, timestamp, [action] + list(args)]
|
data = [revision, timestamp, [action] + list(args)]
|
||||||
data = json.dumps(data, ensure_ascii=False)
|
data = json.dumps(data, ensure_ascii=False).encode('utf-8')
|
||||||
|
|
||||||
path = changelog_path()
|
path = changelog_path()
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
mode = 'a'
|
mode = 'ab'
|
||||||
state.changelog_size = os.path.getsize(path)
|
state.changelog_size = os.path.getsize(path)
|
||||||
else:
|
else:
|
||||||
mode = 'w'
|
mode = 'wb'
|
||||||
state.changelog_size = 0
|
state.changelog_size = 0
|
||||||
makefolder(path)
|
makefolder(path)
|
||||||
with open(path, mode) as fd:
|
with open(path, mode) as fd:
|
||||||
|
|
|
@ -311,13 +311,20 @@ class Item(db.Model):
|
||||||
|
|
||||||
def delete(self, commit=True):
|
def delete(self, commit=True):
|
||||||
Sort.query.filter_by(item_id=self.id).delete()
|
Sort.query.filter_by(item_id=self.id).delete()
|
||||||
|
Find.query.filter_by(item_id=self.id).delete()
|
||||||
if state.downloads and self.id in state.downloads.transfers:
|
if state.downloads and self.id in state.downloads.transfers:
|
||||||
del state.downloads.transfers[self.id]
|
del state.downloads.transfers[self.id]
|
||||||
state.db.session.delete(self)
|
state.db.session.delete(self)
|
||||||
icons.clear('cover:%s' % self.id)
|
|
||||||
icons.clear('preview:%s' % self.id)
|
|
||||||
if commit:
|
if commit:
|
||||||
state.db.session.commit()
|
state.db.session.commit()
|
||||||
|
icons.clear('cover:%s' % self.id)
|
||||||
|
icons.clear('preview:%s' % self.id)
|
||||||
|
|
||||||
|
def remove_annotations(self):
|
||||||
|
from annotation.models import Annotation
|
||||||
|
for a in Annotation.query.filter_by(item_id=self.id, user_id=state.user()):
|
||||||
|
a.add_record('removeannotation')
|
||||||
|
a.delete()
|
||||||
|
|
||||||
meta_keys = (
|
meta_keys = (
|
||||||
'author',
|
'author',
|
||||||
|
@ -562,6 +569,7 @@ class Item(db.Model):
|
||||||
state.db.session.add(self)
|
state.db.session.add(self)
|
||||||
|
|
||||||
def remove_file(self):
|
def remove_file(self):
|
||||||
|
folders = set()
|
||||||
for f in self.files.all():
|
for f in self.files.all():
|
||||||
path = f.fullpath()
|
path = f.fullpath()
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
@ -569,10 +577,12 @@ class Item(db.Model):
|
||||||
try:
|
try:
|
||||||
os.chmod(path, mode)
|
os.chmod(path, mode)
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
remove_empty_folders(os.path.dirname(path))
|
folders.add(os.path.dirname(path))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
state.db.session.delete(f)
|
state.db.session.delete(f)
|
||||||
|
for folder in folders:
|
||||||
|
remove_empty_folders(folder)
|
||||||
user = state.user()
|
user = state.user()
|
||||||
if user in self.users:
|
if user in self.users:
|
||||||
self.users.remove(user)
|
self.users.remove(user)
|
||||||
|
@ -589,6 +599,7 @@ class Item(db.Model):
|
||||||
if self.id in state.downloads.transfers:
|
if self.id in state.downloads.transfers:
|
||||||
del state.downloads.transfers[self.id]
|
del state.downloads.transfers[self.id]
|
||||||
add_record('removeitem', self.id)
|
add_record('removeitem', self.id)
|
||||||
|
self.remove_annotations()
|
||||||
|
|
||||||
class Sort(db.Model):
|
class Sort(db.Model):
|
||||||
__tablename__ = 'sort'
|
__tablename__ = 'sort'
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import codecs
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
@ -52,7 +53,7 @@ class Peer(object):
|
||||||
def apply_log(self):
|
def apply_log(self):
|
||||||
changes = []
|
changes = []
|
||||||
if os.path.exists(self._logpath):
|
if os.path.exists(self._logpath):
|
||||||
with open(self._logpath) as fd:
|
with codecs.open(self._logpath, 'r', encoding='utf-8') as fd:
|
||||||
for line in fd:
|
for line in fd:
|
||||||
if line:
|
if line:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -70,6 +70,8 @@ class Node(Thread):
|
||||||
else:
|
else:
|
||||||
if not self._q.qsize():
|
if not self._q.qsize():
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
else:
|
||||||
|
time.sleep(0.1)
|
||||||
self.queue(action[0], *action[1])
|
self.queue(action[0], *action[1])
|
||||||
else:
|
else:
|
||||||
logger.debug('unknown action %s', action)
|
logger.debug('unknown action %s', action)
|
||||||
|
@ -83,7 +85,8 @@ class Node(Thread):
|
||||||
self._q.put('ping')
|
self._q.put('ping')
|
||||||
|
|
||||||
def queue(self, action, *args):
|
def queue(self, action, *args):
|
||||||
logger.debug('queue node action %s->%s%s', self.user_id, action, args)
|
if DEBUG_NODES:
|
||||||
|
logger.debug('queue node action %s->%s%s', self.user_id, action, args)
|
||||||
self._q.put([action, args])
|
self._q.put([action, args])
|
||||||
|
|
||||||
def _call(self, action, *args):
|
def _call(self, action, *args):
|
||||||
|
|
|
@ -45,7 +45,7 @@ AvoidDiskWrites 1
|
||||||
Log notice stdout
|
Log notice stdout
|
||||||
SocksPort 9830
|
SocksPort 9830
|
||||||
ControlPort 9831
|
ControlPort 9831
|
||||||
CookieAuthentication 1
|
#CookieAuthentication 1
|
||||||
'''.strip())
|
'''.strip())
|
||||||
tor_data = os.path.join(settings.data_path, 'TorData')
|
tor_data = os.path.join(settings.data_path, 'TorData')
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -103,6 +103,7 @@ DirReqStatistics 0
|
||||||
for line in self.p.stdout:
|
for line in self.p.stdout:
|
||||||
self._status.append(line)
|
self._status.append(line)
|
||||||
logger.debug(line)
|
logger.debug(line)
|
||||||
|
self.p.communicate()
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
self.p = None
|
self.p = None
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
oml.ui.annotationPanel = function() {
|
oml.ui.annotationPanel = function(options, self) {
|
||||||
|
self = self || {};
|
||||||
var ui = oml.user.ui;
|
var ui = oml.user.ui;
|
||||||
|
|
||||||
var ui = oml.user.ui;
|
var ui = oml.user.ui;
|
||||||
|
@ -29,14 +30,15 @@ oml.ui.annotationPanel = function() {
|
||||||
click: function() {
|
click: function() {
|
||||||
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
||||||
$annotation.length && $annotation.delete()
|
$annotation.length && $annotation.delete()
|
||||||
$deleteQuote.options({disabled: true})
|
that.updateSelection()
|
||||||
}
|
}
|
||||||
}).appendTo($bar);
|
}).appendTo($bar);
|
||||||
|
|
||||||
var $menuButton = Ox.MenuButton({
|
var $menuButton = Ox.MenuButton({
|
||||||
items: [
|
items: [
|
||||||
{id: 'addAnnotation', title: 'Add Annotation', disabled: true},
|
{id: 'addAnnotation', title: 'Add Annotation', disabled: true, keyboard: 'return'},
|
||||||
{id: 'removeAnnotation', title: 'Remove Annotation', disabled: true},
|
{id: 'removeAnnotation', title: 'Remove Annotation', disabled: true, keyboard: 'delete'},
|
||||||
|
{id: 'removeAnnotations', title: 'Remove All Annotation', disabled: true},
|
||||||
{},
|
{},
|
||||||
{id: 'show', title: Ox._('Show Annotations'), disabled: true},
|
{id: 'show', title: Ox._('Show Annotations'), disabled: true},
|
||||||
{group: 'showAnnotationUsers', min: 1, max: 1, items: [
|
{group: 'showAnnotationUsers', min: 1, max: 1, items: [
|
||||||
|
@ -82,6 +84,14 @@ oml.ui.annotationPanel = function() {
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
oml.ui.exportAnnotationsDialog(result.data).open()
|
oml.ui.exportAnnotationsDialog(result.data).open()
|
||||||
})
|
})
|
||||||
|
} else if (id =='addAnnotation') {
|
||||||
|
oml.$ui.viewer.postMessage('addAnnotation', {})
|
||||||
|
} else if (id =='removeAnnotation') {
|
||||||
|
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
||||||
|
$annotation.length && $annotation.delete()
|
||||||
|
that.updateSelection()
|
||||||
|
} else if (id =='removeAnnotations') {
|
||||||
|
oml.ui.removeAnnotationsDialog().open()
|
||||||
} else {
|
} else {
|
||||||
console.log('click', id, data)
|
console.log('click', id, data)
|
||||||
}
|
}
|
||||||
|
@ -113,16 +123,18 @@ oml.ui.annotationPanel = function() {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
orientation: 'vertical'
|
orientation: 'vertical'
|
||||||
|
}, self).update({
|
||||||
|
hasAnnotations: function() {
|
||||||
|
$menuButton[self.options.hasAnnotations ? 'enableItem' : 'disableItem']('removeAnnotations')
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
that.updateSelection = function(selection) {
|
that.updateSelection = function(selection) {
|
||||||
$addQuote.options({
|
|
||||||
disabled: !selection
|
|
||||||
})
|
|
||||||
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
var $annotation = oml.$ui.annotationFolder.find('.OMLAnnotation.selected')
|
||||||
$deleteQuote.options({
|
$addQuote.options({disabled: !selection})
|
||||||
disabled: !$annotation.length
|
$deleteQuote.options({disabled: !$annotation.length})
|
||||||
})
|
$menuButton[selection ? 'enableItem' : 'disableItem']('addAnnotation')
|
||||||
|
$menuButton[$annotation.length ? 'enableItem' : 'disableItem']('removeAnnotation')
|
||||||
}
|
}
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
oml.ui.removeAnnotationsDialog = function() {
|
||||||
|
|
||||||
|
var ui = oml.user.ui,
|
||||||
|
|
||||||
|
annotations = oml.$ui.viewer.getAnnotations().filter(function(a) {
|
||||||
|
return a.user == oml.user.id
|
||||||
|
}),
|
||||||
|
annotationsName = Ox._(annotations.length == 1 ? 'Annotation' : 'Annotations'),
|
||||||
|
theseAnnotationsName = annotations.length == 1
|
||||||
|
? Ox._('this annotation')
|
||||||
|
: Ox._('these {0} annotations', [Ox.formatNumber(annotations.length)]),
|
||||||
|
|
||||||
|
that = oml.ui.confirmDialog({
|
||||||
|
buttons: [
|
||||||
|
Ox.Button({
|
||||||
|
style: 'squared',
|
||||||
|
title: Ox._('No, Keep {0}', [annotationsName])
|
||||||
|
}),
|
||||||
|
Ox.Button({
|
||||||
|
style: 'squared',
|
||||||
|
title: Ox._('Yes, Delete {0}', [annotationsName])
|
||||||
|
})
|
||||||
|
],
|
||||||
|
content: Ox._(
|
||||||
|
'Are you sure that you want to permanently delete {0}?',
|
||||||
|
[theseAnnotationsName]
|
||||||
|
),
|
||||||
|
title: Ox._('Delete {0}', [annotationsName])
|
||||||
|
}, function() {
|
||||||
|
Ox.serialForEach(annotations, function(a, index, annotations, next) {
|
||||||
|
oml.api.removeAnnotation({
|
||||||
|
item: ui.item,
|
||||||
|
annotation: a.id
|
||||||
|
}, function(result) {
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
}, function() {
|
||||||
|
Ox.Request.clearCache();
|
||||||
|
oml.$ui.viewer.renderAnnotations(true);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return that;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -111,6 +111,7 @@ oml.ui.viewer = function() {
|
||||||
if (save !== false) {
|
if (save !== false) {
|
||||||
oml.api.addAnnotation(a)
|
oml.api.addAnnotation(a)
|
||||||
}
|
}
|
||||||
|
data.user = a.user || oml.user.id
|
||||||
data.notes = data.notes || [];
|
data.notes = data.notes || [];
|
||||||
annotations.push(data);
|
annotations.push(data);
|
||||||
}
|
}
|
||||||
|
@ -157,9 +158,13 @@ oml.ui.viewer = function() {
|
||||||
oml.$ui.annotationFolder.append($annotation);
|
oml.$ui.annotationFolder.append($annotation);
|
||||||
$annotation.annotate();
|
$annotation.annotate();
|
||||||
oml.$ui.annotationPanel.updateSelection(false)
|
oml.$ui.annotationPanel.updateSelection(false)
|
||||||
|
oml.$ui.annotationPanel.options({hasAnnotations: true})
|
||||||
} else if (event == 'removeAnnotation') {
|
} else if (event == 'removeAnnotation') {
|
||||||
oml.$ui.annotationFolder.find('#a-' + data.id).remove()
|
oml.$ui.annotationFolder.find('#a-' + data.id).remove()
|
||||||
data.id && removeAnnotation(data.id)
|
data.id && removeAnnotation(data.id)
|
||||||
|
oml.$ui.annotationPanel.options({hasAnnotations: annotations.filter(function(a) {
|
||||||
|
return a.user == oml.user.id
|
||||||
|
}).length > 0})
|
||||||
} else if (event == 'selectAnnotation') {
|
} else if (event == 'selectAnnotation') {
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id)
|
var $annotation = oml.$ui.annotationFolder.find('#a-' + data.id)
|
||||||
|
@ -196,7 +201,7 @@ oml.ui.viewer = function() {
|
||||||
that.getAnnotations = function() {
|
that.getAnnotations = function() {
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
that.renderAnnotations = function() {
|
that.renderAnnotations = function(load=false) {
|
||||||
var sortKey = ui.sortAnnotations
|
var sortKey = ui.sortAnnotations
|
||||||
if (sortKey == 'date') {
|
if (sortKey == 'date') {
|
||||||
sortKey = 'created'
|
sortKey = 'created'
|
||||||
|
@ -207,9 +212,15 @@ oml.ui.viewer = function() {
|
||||||
if (sortKey == 'quote') {
|
if (sortKey == 'quote') {
|
||||||
sortKey = 'text'
|
sortKey = 'text'
|
||||||
}
|
}
|
||||||
|
if (load) {
|
||||||
|
loadAnnotations(function() {
|
||||||
|
that.renderAnnotations()
|
||||||
|
})
|
||||||
|
}
|
||||||
annotations = Ox.sortBy(annotations, sortKey)
|
annotations = Ox.sortBy(annotations, sortKey)
|
||||||
oml.$ui.annotationFolder.empty();
|
oml.$ui.annotationFolder.empty();
|
||||||
var visibleAnnotations = [];
|
var visibleAnnotations = [];
|
||||||
|
var hasAnnotations = false;
|
||||||
annotations.forEach(function(data) {
|
annotations.forEach(function(data) {
|
||||||
//that.postMessage('removeAnnotation', {id: data.id})
|
//that.postMessage('removeAnnotation', {id: data.id})
|
||||||
if (ui.showAnnotationUsers == 'all' || data.user == oml.user.id) {
|
if (ui.showAnnotationUsers == 'all' || data.user == oml.user.id) {
|
||||||
|
@ -217,7 +228,11 @@ oml.ui.viewer = function() {
|
||||||
oml.$ui.annotationFolder.append($annotation);
|
oml.$ui.annotationFolder.append($annotation);
|
||||||
visibleAnnotations.push(data)
|
visibleAnnotations.push(data)
|
||||||
}
|
}
|
||||||
|
if (data.user == oml.user.id) {
|
||||||
|
hasAnnotations = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
oml.$ui.annotationPanel.options({hasAnnotations: hasAnnotations})
|
||||||
// fixme: trigger loaded event from reader instead?
|
// fixme: trigger loaded event from reader instead?
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
that.postMessage('addAnnotations', {
|
that.postMessage('addAnnotations', {
|
||||||
|
@ -225,6 +240,7 @@ oml.ui.viewer = function() {
|
||||||
replace: true
|
replace: true
|
||||||
})
|
})
|
||||||
}, 500)
|
}, 500)
|
||||||
|
|
||||||
}
|
}
|
||||||
return that.updateElement();
|
return that.updateElement();
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
"preferencesPanel.js",
|
"preferencesPanel.js",
|
||||||
"previewButton.js",
|
"previewButton.js",
|
||||||
"previewDialog.js",
|
"previewDialog.js",
|
||||||
|
"removeAnnotations.js",
|
||||||
"resetUIDialog.js",
|
"resetUIDialog.js",
|
||||||
"rightPanel.js",
|
"rightPanel.js",
|
||||||
"sectionButtons.js",
|
"sectionButtons.js",
|
||||||
|
|
Loading…
Reference in New Issue