[SCM] advene/master: New upstream version 3.1
oaubert-guest at users.alioth.debian.org
oaubert-guest at users.alioth.debian.org
Thu Oct 12 20:45:52 UTC 2017
The following commit has been merged in the master branch:
commit d93ebe7a5ce216214db5d8e1c4e175acb0130e46
Author: Olivier Aubert <contact at olivieraubert.net>
Date: Sun Jun 18 23:25:25 2017 +0200
New upstream version 3.1
diff --git a/CHANGES.txt b/CHANGES.txt
index 105589b..a9c5e61 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,13 @@
+advene (3.1) unstable; urgency=medium
+
+ * Bug fixes.
+
+ * Timeline : improve zoom level setting
+
+ * OWL importer: adapt to new definition structure
+
+ -- Olivier Aubert <contact at olivieraubert.net> Sun, 18 Jun 2017 23:21:19 +0200
+
advene (3.0) unstable; urgency=medium
* Upgrade libs to Gtk3 / Gstreamer 1.0
diff --git a/lib/advene/core/config.py b/lib/advene/core/config.py
index 6cfa0a0..bab0f41 100644
--- a/lib/advene/core/config.py
+++ b/lib/advene/core/config.py
@@ -492,7 +492,7 @@ class Config(object):
"""Check if the settings directory is present, and create it if necessary.
"""
if not os.path.isdir(self.path['settings']):
- os.mkdir(self.path['settings'])
+ os.makedirs(self.path['settings'])
self.first_run=True
else:
self.first_run=False
@@ -773,7 +773,7 @@ class Config(object):
dp=os.path.dirname(preffile)
if not os.path.isdir(dp):
try:
- os.mkdir(dp)
+ os.makedirs(dp)
except OSError, e:
logger.error("Error: %s", str(e))
return False
diff --git a/lib/advene/core/version.py b/lib/advene/core/version.py
index 4a01a09..b7e8ebe 100644
--- a/lib/advene/core/version.py
+++ b/lib/advene/core/version.py
@@ -19,6 +19,6 @@
"""Versioning information.
"""
-version='3.0'
-date='20170601'
+version='3.1'
+date='20170618'
major,minor=[ long(s) for s in version.split('.') ]
diff --git a/lib/advene/gui/edit/transcribe.py b/lib/advene/gui/edit/transcribe.py
index e62989f..267b5d9 100644
--- a/lib/advene/gui/edit/transcribe.py
+++ b/lib/advene/gui/edit/transcribe.py
@@ -85,7 +85,6 @@ class TranscriptionEdit(AdhocView):
self.contextual_actions = (
(_("Save view"), self.save_view),
(_("Save default options"), self.save_default_options),
- (_("Export as static view"), lambda v, t: self.export_as_static_view()),
)
self.controller=controller
diff --git a/lib/advene/gui/plugins/kinect.py b/lib/advene/gui/plugins/kinect.py
index a8c8782..9fad853 100644
--- a/lib/advene/gui/plugins/kinect.py
+++ b/lib/advene/gui/plugins/kinect.py
@@ -44,8 +44,7 @@ class KinectController(AdhocView):
def __init__(self, controller=None, uri=None, parameters=None):
super(KinectController, self).__init__(controller=controller)
self.close_on_package_load = False
- self.contextual_actions = [
- ]
+ self.contextual_actions = []
self.controller = controller
self.registered_rules = []
diff --git a/lib/advene/gui/plugins/shotvalidation.py b/lib/advene/gui/plugins/shotvalidation.py
index ef06e60..adf2b04 100644
--- a/lib/advene/gui/plugins/shotvalidation.py
+++ b/lib/advene/gui/plugins/shotvalidation.py
@@ -37,8 +37,7 @@ class ShotValidation(AdhocView):
def __init__(self, controller=None, parameters=None, annotationtype=None):
super(ShotValidation, self).__init__(controller=controller)
self.close_on_package_load = True
- self.contextual_actions = (
- )
+ self.contextual_actions = ()
self.controller=controller
self._annotationtype=None
diff --git a/lib/advene/gui/plugins/videoplayer.py b/lib/advene/gui/plugins/videoplayer.py
index c26c49d..782edad 100644
--- a/lib/advene/gui/plugins/videoplayer.py
+++ b/lib/advene/gui/plugins/videoplayer.py
@@ -119,7 +119,7 @@ class VideoPlayer(AdhocView):
arguments = [ ('offset', self.offset) ]
return self.options, arguments
- def select_file(self, button=None, *p):
+ def select_file(self, *p):
mp=[ d for d in config.data.path['moviepath'].split(os.path.pathsep) if d != '_' ]
if mp:
default=mp[0]
diff --git a/lib/advene/gui/views/browser.py b/lib/advene/gui/views/browser.py
index e59c906..6b67f44 100755
--- a/lib/advene/gui/views/browser.py
+++ b/lib/advene/gui/views/browser.py
@@ -297,7 +297,7 @@ class Browser(AdhocView):
self.current_value=element
def display_result(self, *p):
- """Display the results as annotations in a timeline.
+ """Display the results as annotations in a table
"""
if not hasattr(self.current_value, '__iter__'):
self.log(_("Result is not a list"))
diff --git a/lib/advene/gui/views/checker.py b/lib/advene/gui/views/checker.py
index bcdb800..60444d2 100644
--- a/lib/advene/gui/views/checker.py
+++ b/lib/advene/gui/views/checker.py
@@ -41,8 +41,7 @@ class CheckerView(AdhocView):
def __init__ (self, controller=None, parameters=None):
super(CheckerView, self).__init__(controller=controller)
self.close_on_package_load = False
- self.contextual_actions = (
- )
+ self.contextual_actions = ()
self.controller=controller
self.options = {
}
diff --git a/lib/advene/gui/views/editionhistory.py b/lib/advene/gui/views/editionhistory.py
index 0a3d54b..b6dbdeb 100644
--- a/lib/advene/gui/views/editionhistory.py
+++ b/lib/advene/gui/views/editionhistory.py
@@ -43,7 +43,7 @@ class EditionHistory(AdhocView):
def __init__ (self, controller=None, **kw):
super(EditionHistory, self).__init__(controller=controller)
self.close_on_package_load = False
- self.contextual_actions = ( )
+ self.contextual_actions = ()
self.options={}
diff --git a/lib/advene/gui/views/finder.py b/lib/advene/gui/views/finder.py
index e144a79..4375f04 100644
--- a/lib/advene/gui/views/finder.py
+++ b/lib/advene/gui/views/finder.py
@@ -102,15 +102,15 @@ class DetailedTreeModel(object):
def __init__(self, controller=None, package=None):
self.childrencache = {}
self.virtual={}
- self.virtual['root'] = VirtualNode(_("Package"), package)
- self.virtual['views']=VirtualNode(_("List of views"), package, viewableType='view-list')
- self.virtual['static']=VirtualNode(_("Static views"), package, viewableType='view-list')
- self.virtual['dynamic']=VirtualNode(_("Dynamic views"), package, viewableType='view-list')
- self.virtual['admin']=VirtualNode(_("Admin views"), package, viewableType='view-list')
- self.virtual['adhoc']=VirtualNode(_("Adhoc views"), package)
+ self.virtual['root'] = VirtualNode(_("Package"), package)
+ self.virtual['views'] = VirtualNode(_("List of views"), package, viewableType='view-list')
+ self.virtual['static'] = VirtualNode(_("Static views"), package, viewableType='view-list')
+ self.virtual['dynamic'] = VirtualNode(_("Dynamic views"), package, viewableType='view-list')
+ self.virtual['admin'] = VirtualNode(_("Admin views"), package, viewableType='view-list')
+ self.virtual['adhoc'] = VirtualNode(_("Adhoc views"), package)
def nodeParent (self, node):
- #print "nodeparent %s" % node
+ logger.warn("nodeparent %s", node)
if isinstance (node, Annotation):
parent = node.type
elif isinstance (node, Relation):
@@ -146,7 +146,7 @@ class DetailedTreeModel(object):
return parent
def nodeChildren (self, node):
- #print "nodechildren %s" % node
+ logger.warn("nodechildren %s %s", type(node), node)
children = []
if isinstance (node, Annotation):
children = []
@@ -171,7 +171,7 @@ class DetailedTreeModel(object):
children = []
elif isinstance (node, Package):
if not node in self.childrencache:
- self.childrencache[node] = [node.schemas, self.virtual['views'], node.queries, node.resources ]
+ self.childrencache[node] = [node.schemas, self.virtual['views'], node.queries, node.resources or _("No resources") ]
children = self.childrencache[node]
elif isinstance (node, AbstractBundle):
children = node
@@ -377,7 +377,7 @@ class ModelColumn(FinderColumn):
store, it = selection.get_selected()
if it is not None:
att = model.get_value (it, self.COLUMN_ELEMENT)
- if att and self.callback:
+ if att is not None and self.callback:
self.callback(self, att)
return True
return False
@@ -540,8 +540,11 @@ class ViewColumn(FinderColumn):
t=helper.get_view_type(self.element)
if t == 'static':
c=self.controller.build_context()
- url=c.evaluateValue('here/view/%s/absolute_url' % self.element.id)
- self.controller.open_url(url)
+ try:
+ url=c.evaluateValue('here/view/%s/absolute_url' % self.element.id)
+ self.controller.open_url(url)
+ except:
+ logger.warn("Cannot open static view: error when trying to get its url", exc_info=True)
elif t == 'dynamic':
self.controller.activate_stbv(self.element)
elif t == 'adhoc':
@@ -877,6 +880,7 @@ class Finder(AdhocView):
return True
def clicked_callback(self, columnbrowser, node):
+ logger.debug("clicked_callback %s %s %s", columnbrowser, node, columnbrowser.next)
if columnbrowser is None:
# We selected the rootcolumn. Delete the next ones
cb=self.rootcolumn.next
@@ -903,8 +907,8 @@ class Finder(AdhocView):
if cb is not None:
cb.close()
# Check if the column is still appropriate for the node
- clazz=CLASS2COLUMN.get(type(node), ModelColumn)
- if not isinstance(columnbrowser.next, clazz):
+ clazz=CLASS2COLUMN.get(type(node), None)
+ if clazz is None or not isinstance(columnbrowser.next, clazz):
# The column is not appropriate for the new node.
# Close it and reopen it.
columnbrowser.next.close()
diff --git a/lib/advene/gui/views/html.py b/lib/advene/gui/views/html.py
index 9b3144e..821b6d2 100644
--- a/lib/advene/gui/views/html.py
+++ b/lib/advene/gui/views/html.py
@@ -192,7 +192,7 @@ class HTMLView(AdhocView):
def utbv_menu(*p):
if self.controller and self.controller.gui:
m=self.controller.gui.build_utbv_menu(action=self.open_url)
- m.popup(None, None, None, 0, Gtk.get_current_event_time())
+ m.popup_at_pointer()
return True
tb=Gtk.Toolbar()
diff --git a/lib/advene/gui/views/interactivequery.py b/lib/advene/gui/views/interactivequery.py
index 4183646..34a0366 100644
--- a/lib/advene/gui/views/interactivequery.py
+++ b/lib/advene/gui/views/interactivequery.py
@@ -23,6 +23,7 @@ Display the query results in a view (timeline, tree, etc).
from gettext import gettext as _
import pprint
+from gi.repository import Gdk
from gi.repository import Gtk
from gi.repository import Pango
diff --git a/lib/advene/gui/views/table.py b/lib/advene/gui/views/table.py
index fa9cb1d..8242640 100644
--- a/lib/advene/gui/views/table.py
+++ b/lib/advene/gui/views/table.py
@@ -273,7 +273,7 @@ class AnnotationTable(AdhocView):
if not it:
return
a = self.model.get_value (it, COLUMN_ELEMENT)
- new_content = helper.title2content(text,
+ new_content = helper.title2content(text.decode('utf-8'),
a.content,
a.type.getMetaData(config.data.namespace, "representation"))
if new_content is None:
@@ -556,8 +556,7 @@ class GenericTable(AdhocView):
def __init__(self, controller=None, parameters=None, elements=None, source=None):
super(GenericTable, self).__init__(controller=controller)
self.close_on_package_load = False
- self.contextual_actions = (
- )
+ self.contextual_actions = ()
self.controller=controller
self.elements=elements
self.source = source
diff --git a/lib/advene/gui/views/timeline.py b/lib/advene/gui/views/timeline.py
index a1f3e22..fb37f39 100755
--- a/lib/advene/gui/views/timeline.py
+++ b/lib/advene/gui/views/timeline.py
@@ -139,8 +139,8 @@ class TimeLine(AdhocView):
(_("Refresh"), self.refresh),
(_("Save view"), self.save_view),
(_("Save default options"), self.save_default_options),
- (_("Limit display to current area"), lambda i, b: self.limit_display()),
- (_("Display whole movie"), lambda i, b: self.unlimit_display()),
+ (_("Limit display to current area"), self.limit_display),
+ (_("Display whole movie"), self.unlimit_display),
)
self.options = {
'highlight': False,
@@ -162,7 +162,7 @@ class TimeLine(AdhocView):
# Default position in ms.
default_position=None
default_zoom=1.0
- pane_position=opt.get('pane-position', None)
+ inspector_width = opt.get('inspector-width', None)
for n, v in arg:
if n == 'annotation-type':
at=helper.get_id(self.controller.package.annotationTypes,
@@ -264,7 +264,7 @@ class TimeLine(AdhocView):
# The same value in relative form
self.fraction_adj = Gtk.Adjustment.new(value=1.0,
lower=0.01,
- upper=1.0,
+ upper=10.0,
step_increment=.01,
page_increment=.1,
page_size=.1)
@@ -344,46 +344,66 @@ class TimeLine(AdhocView):
# Set default parameters (zoom) and refresh the legend widget
# on the first expose signal
- def set_default_parameters(widget, event, zoom, pos, pane):
- self.update_adjustment ()
- self.adjustment.set_value(u2p(self.minimum, absolute=True))
- self.fraction_adj.set_value(zoom)
- if pos >= self.minimum and pos <= self.maximum:
- self.adjustment.set_value(u2p(pos, absolute=True))
+ def set_default_parameters(widget, event, default_zoom, pos, inspector_width):
+ logger.debug("set_default_parameters default zoom: %f pos: %d inspector_width: %d", default_zoom or 0, pos or 0, inspector_width or 0)
+
# Set annotation inspector width, so that it does not auto-resize
- if pane is None:
- pane = self.widget.get_window().get_width() - 160
- self.inspector_pane.set_position(pane)
+ if inspector_width is None:
+ inspector_width = 160
+ self.set_inspector_size(inspector_width)
+
# Check if display is limited
if self.minimum > 0 and self.maximum < self.controller.package.cached_duration:
self.limit_navtools.show()
+
+ self.update_adjustment ()
+ if pos >= self.minimum and pos <= self.maximum:
+ self.adjustment.set_value(u2p(pos, absolute=True))
+ else:
+ self.adjustment.set_value(u2p(self.minimum, absolute=True))
+
if self.expose_signal:
self.widget.disconnect(self.expose_signal)
self.expose_signal = None
self.update_model(from_init=True)
+ logger.debug("set zoom value default zoom: %f width: %d", default_zoom, self.layout.get_clip().width)
+ self.fraction_adj.set_value(default_zoom)
return False
# Convert values, that could be strings
if default_position is not None:
default_position=long(float(default_position))
- if pane_position is not None:
- pane_position=long(float(pane_position))
+ if inspector_width is not None:
+ inspector_width = long(float(inspector_width))
- self.expose_signal=self.widget.connect('draw', set_default_parameters,
- default_zoom, default_position, pane_position)
+ self.expose_signal=self.widget.connect_after('draw', set_default_parameters,
+ default_zoom, default_position, inspector_width)
def get_save_arguments(self):
arguments = []
if self.annotationtypes_selection:
- arguments.append([ ('annotation-type', at.id) for at in self.annotationtypes_selection ])
+ arguments.extend([ ('annotation-type', at.id) for at in self.annotationtypes_selection ])
if self.list:
- arguments.append([ ('element', el.id) for el in self.list ])
+ arguments.extend([ ('element', el.id) for el in self.list ])
arguments.append( ('minimum', self.minimum ) )
arguments.append( ('maximum', self.maximum ) )
arguments.append( ('position', self.pixel2unit(self.adjustment.get_value(), absolute=True) ) )
arguments.append( ('zoom', self.fraction_adj.get_value()) )
- self.options['pane-position']=self.inspector_pane.get_position()
+ self.options['inspector-width'] = self.get_inspector_size()
return self.options, arguments
+ def get_inspector_size(self):
+ return self.inspector_pane.get_clip().width - self.inspector_pane.get_position()
+
+ def set_inspector_size(self, inspector_width):
+ width = self.inspector_pane.get_clip().width
+ if inspector_width > width - 100:
+ logger.debug("Too large inspector. Use a default value")
+ if width > 300:
+ inspector_width = 160
+ else:
+ inspector_width = 0
+ self.inspector_pane.set_position(width - inspector_width)
+
def draw_background(self, layout, context):
"""Draw annotation type separating lines
"""
@@ -420,12 +440,15 @@ class TimeLine(AdhocView):
for b1, b2, r in to_draw:
if b1 is None or b2 is None:
continue
+ x_offset = self.layout.get_hadjustment().get_value()
+ y_offset = self.layout.get_vadjustment().get_value()
+
r1 = b1.get_allocation()
r2 = b2.get_allocation()
- x_start = r1.x + 3 * r1.width / 4
- y_start = r1.y + r1.height / 4
- x_end=r2.x + r2.width / 4
- y_end=r2.y + 3 * r2.height / 4
+ x_start = (r1.x + 3 * r1.width / 4) - x_offset
+ y_start = (r1.y + r1.height / 4) - y_offset
+ x_end=(r2.x + r2.width / 4) - x_offset
+ y_end=(r2.y + 3 * r2.height / 4) - y_offset
context.set_source_rgb(0, 0, 0)
context.set_line_width(1)
context.move_to(x_start, y_start)
@@ -561,7 +584,7 @@ class TimeLine(AdhocView):
if self.maximum != oldmax and self.layout.get_window() is not None:
# Reset to display whole timeline
- self.scale.set_value( (self.maximum - self.minimum) / float(self.layout.get_window().get_height()) )
+ self.scale.set_value( (self.maximum - self.minimum) / float(self.layout.get_clip().width or 100) )
def update_model(self, package=None, partial_update=False, from_init=False):
"""Update the whole model.
@@ -608,8 +631,6 @@ class TimeLine(AdhocView):
def finalize_callback():
self.update_legend_widget(self.legend)
self.legend.show_all()
- if self.layout.get_window() is not None:
- self.fraction_event(widget=None, forced_window_width=self.layout.get_window().get_width())
self.update_lock.release()
self.populate(finalize_callback)
@@ -1952,11 +1973,15 @@ class TimeLine(AdhocView):
count = 10
length = len(l)
- #print '----------------------------------------- populate', length
- #import traceback; traceback.print_stack()
if l:
- old_position = self.inspector_pane.get_position()
- self.inspector_pane.set_position(2)
+ old_inspector_width = self.get_inspector_size()
+
+ def update_layout_size():
+ self.layout.set_size (u2p (self.maximum - self.minimum),
+ max(self.layer_position.values() or (0,))
+ + self.button_height + config.data.preferences['timeline']['interline-height'])
+ self.scale_layout.set_size(u2p (self.maximum - self.minimum), 40)
+
def create_annotations(annotations, length):
i = counter[0]
if i < length:
@@ -1974,15 +1999,8 @@ class TimeLine(AdhocView):
self.quickview.set_text(_("Displaying done."))
self.locked_inspector = False
self.controller.gui.set_busy_cursor(False)
- if old_position:
- self.inspector_pane.set_position(old_position)
- else:
- # old_position was = 0, because its value was
- # obtained before the widget was realized. There
- # is a good chance that the value is now
- # available.
- if self.widget.get_window():
- self.inspector_pane.set_position(max((0, self.widget.get_window().get_width() - 160)))
+ self.set_inspector_size(old_inspector_width or 20)
+ update_layout_size()
if callback:
callback()
return False
@@ -1997,14 +2015,9 @@ class TimeLine(AdhocView):
self.controller.gui.set_busy_cursor(True)
GObject.idle_add(create_annotations, l, length)
elif callback:
+ update_layout_size()
callback()
- self.layout.set_size (u2p (self.maximum - self.minimum),
- max(self.layer_position.values() or (0,))
- + self.button_height + config.data.preferences['timeline']['interline-height'])
-
- self.scale_layout.set_size(u2p (self.maximum - self.minimum), 40)
-
def draw_current_mark (self):
u2p = self.unit2pixel
@@ -2647,12 +2660,10 @@ class TimeLine(AdhocView):
def layout_resize_event(self, widget=None, event=None, *p):
"""Recompute fraction_adj value when the layout size changes
"""
- parent = self.layout.get_window()
- if not parent:
+ if not self.layout.get_window():
return False
if self.maximum != self.minimum:
- fraction=self.scale.get_value() * float(parent.get_width()) / (self.maximum - self.minimum)
- #print "Layout resize, reset fraction_adj to ", fraction, w
+ fraction=self.scale.get_value() * float(self.layout.get_clip().width) / (self.maximum - self.minimum)
self.fraction_adj.set_value(fraction)
self.zoom_combobox.get_child().set_text('%d%%' % long(100 * fraction))
return False
@@ -2661,7 +2672,7 @@ class TimeLine(AdhocView):
# Deactivate autoscroll...
self.set_autoscroll_mode(0)
- self.scale.set_value(1.3 * (end - begin) / self.layout.get_window().get_width())
+ self.scale.set_value(1.3 * (end - begin) / self.layout.get_clip().width or 100)
# Center on annotation
self.center_on_position( (begin + end) / 2 )
@@ -2700,20 +2711,20 @@ class TimeLine(AdhocView):
fraction is > 0 and <= 1.
"""
- parent = self.layout.get_window()
- if not parent:
+ if not self.layout.get_window():
return True
- w = parent.get_width()
- if forced_window_width != 0:
+ if forced_window_width > 0:
w = forced_window_width
-
- if w < 10:
+ else:
+ w = self.layout.get_clip().width
+ if w < 50:
return True
if self.minimum == self.maximum:
return True
fraction = self.fraction_adj.get_value()
+ logger.debug("fraction_event %f width %d forced %d", fraction, w, forced_window_width)
v = (self.maximum - self.minimum) / float(w) * fraction
# New width in pixel
@@ -2721,9 +2732,7 @@ class TimeLine(AdhocView):
self.log(_("Cannot zoom more"))
return True
- # Is it worth redrawing the whole timeline ?
- if abs(v - self.scale.get_value()) / float(self.scale.get_value()) > 0.01:
- self.scale.set_value(v)
+ self.scale.set_value(v)
self.zoom_combobox.get_child().set_text('%d%%' % long(100 * fraction))
return True
@@ -3408,10 +3417,6 @@ class TimeLine(AdhocView):
# Relation display toggle
def handle_toggle(b, option):
self.options[option]=b.get_active()
- if option == 'display-all-relations':
- region = self.layout.get_window().get_clip_region()
- if region:
- self.layout.get_window().invalidate_region(region, True)
return True
self.display_relations_toggle=Gtk.ToggleToolButton(stock_id=Gtk.STOCK_REDO)
diff --git a/lib/advene/gui/views/viewbook.py b/lib/advene/gui/views/viewbook.py
index ba38029..10e794c 100644
--- a/lib/advene/gui/views/viewbook.py
+++ b/lib/advene/gui/views/viewbook.py
@@ -113,6 +113,10 @@ class ViewBook(AdhocView):
self.controller.gui.viewbook[d].add_view(v, name=v._label)
return True
+ def handle_contextual_action(menuitem, action):
+ action()
+ return True
+
def popup_menu(button, event, view):
if event.button == 3:
menu = Gtk.Menu()
@@ -143,7 +147,7 @@ class ViewBook(AdhocView):
try:
for label, action in view.contextual_actions:
item = Gtk.MenuItem(label, use_underline=False)
- item.connect('activate', lambda w: action())
+ item.connect('activate', handle_contextual_action, action)
menu.append(item)
except AttributeError:
pass
diff --git a/lib/advene/model/viewable.py b/lib/advene/model/viewable.py
index cad4c38..40076d8 100644
--- a/lib/advene/model/viewable.py
+++ b/lib/advene/model/viewable.py
@@ -155,7 +155,10 @@ class Viewable(object):
context.setLocal('view', view)
context.interpret(view_source, mimetype, result)
context.popLocals ()
- s=TypedUnicode(result.getvalue())
+ v = result.getvalue()
+ if isinstance(v, str):
+ v = v.decode('utf-8')
+ s=TypedUnicode(v)
s.contenttype=view.getContent().getMimetype()
return s
diff --git a/lib/advene/plugins/owl_import.py b/lib/advene/plugins/owl_import.py
index 3245de3..3659b93 100644
--- a/lib/advene/plugins/owl_import.py
+++ b/lib/advene/plugins/owl_import.py
@@ -27,12 +27,12 @@ import os
import advene.core.config as config
from advene.util.importer import GenericImporter
try:
- import ontospy
+ import rdflib
except ImportError:
- ontospy = None
+ rdflib = None
def register(controller=None):
- if ontospy is not None:
+ if rdflib is not None:
controller.register_importer(OWLImporter)
return True
@@ -51,38 +51,73 @@ class OWLImporter(GenericImporter):
can_handle=staticmethod(can_handle)
def process_file(self, filename, dest=None):
- model = ontospy.Ontospy(filename)
+ graph = rdflib.Graph()
+ graph.parse(filename)
p, at = self.init_package(filename=dest)
p.setMetaData(config.data.namespace_prefix['dc'],
'description',
_("Converted from %s") % filename)
- self.convert(self.iterator(model))
+ self.convert(self.iterator(graph))
self.progress(1.0)
return self.package
- def iterator(self, model):
+ def iterator(self, graph):
"""Iterate through the loaded OWL.
-
- Assumptions:
- - there is a toplevel element (AnnotationConcept) in the model toplayer
- - the first level of children defines schemas
- - the leaf elements for each schema define annotation types
"""
+ AO = rdflib.Namespace('http://ada.filmontology.org/ontology/')
+ AR = rdflib.Namespace('http://ada.filmontology.org/resource/')
+ PREFIX = """PREFIX owl: <http://www.w3.org/2002/07/owl#>
+ PREFIX ar: <http://ada.filmontology.org/resource/>
+ PREFIX ao: <http://ada.filmontology.org/ontology/>
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ """
+ def get_label(graph, subject, default=""):
+ """Return a label for the object.
+
+ Using preferably @en labels
+ """
+ labels = graph.preferredLabel(s, lang='en')
+ if labels:
+ # We have at least 1 @en label. Return it.
+ return labels[0][1]
+ else:
+ # No defined label. Use default
+ return default
+
+ def get_comment(graph, subject, default=""):
+ """Return the comment at en for the object.
+ """
+ results = list(graph.query(PREFIX + 'SELECT ?comment WHERE { <%s> rdfs:comment ?comment . FILTER langMatches( lang(?comment), "en" ) }' % unicode(subject)))
+ if results:
+ return unicode(results[0][0])
+ else:
+ return default
+
progress=0.01
self.progress(progress, "Starting conversion")
- root = model.toplayer[0]
- schemas = root.children()
- incr=0.98/len(schemas)
+ RDF = rdflib.RDF
+ schemas = list(graph.subjects(RDF.type, AO.AnnotationLevel))
+ incr=0.98 / len(schemas)
for s in schemas:
progress += incr
# Create the schema
- schema = self.create_schema(s.qname.strip(':'), title=s.bestLabel(), description=s.bestDescription())
+ # FIXME: there is no label neither description at the moment.
+ schema_id = s.rpartition('/')[-1]
+ title = get_label(graph, s, schema_id)
+ description = get_comment(graph, s)
+ schema = self.create_schema(schema_id, title=title, description=description)
if not self.progress(progress, "Creating schema %s" % schema.title):
break
- for c in s.descendants():
- if not c.children():
- # We consider only leaf nodes
- self.create_annotation_type(schema, c.qname.strip(':'), title=c.bestLabel(), description=c.bestDescription())
+ for atnode in graph.objects(s, AO.term('hasAnnotationType')):
+ at_id = atnode.rpartition('/')[-1]
+ label = get_label(graph, atnode, at_id)
+ description = get_comment(graph, atnode)
+ at = self.create_annotation_type(schema, at_id, title=label, description=description)
+ values = [ unicode(t[0])
+ for t in graph.query(PREFIX + "SELECT ?label WHERE { <%s> ao:hasPredefinedValue ?x . ?x rdfs:label ?label . }" % unicode(atnode)) ]
+ if values:
+ at.setMetaData(config.data.namespace, "completions", ",".join(values))
self.progress(1.0)
# Hack: we have an empty iterator (no annotations here), but
# if the yield instruction is not present in the method code,
@@ -93,8 +128,8 @@ class OWLImporter(GenericImporter):
if __name__ == "__main__":
import sys
- if ontospy is None:
- print("Cannot import required ontospy module")
+ if rdflib is None:
+ print("Cannot import required rdflib module")
sys.exit(1)
if len(sys.argv) < 3:
print "Should provide a file name and a package name"
diff --git a/lib/advene/util/helper.py b/lib/advene/util/helper.py
index f045a02..76dc14e 100755
--- a/lib/advene/util/helper.py
+++ b/lib/advene/util/helper.py
@@ -844,9 +844,11 @@ def title2content(new_title, original_content, representation):
then we can convert the short representation back to the
appropriate content.
+ new_title is expected to be unicode.
+
@return the new content or None if the content could not be updated.
"""
- new_title = unicode(new_title, 'utf-8')
+ assert(isinstance(new_title, unicode))
r = None
if representation is None or empty_representation.match(representation):
r = new_title
--
advene packaging
More information about the pkg-multimedia-commits
mailing list