예제 #1
0
 def extract_montage(self, m, elements):
     """Extract the montage corresponding to annotation list
     """
     ann = elements[0]
     if len(elements) == 1:
         basename = ann.id + "-" + helper.title2id(
             self.controller.get_title(ann)) + ".webm"
     else:
         atypes = set(a.type for a in elements)
         if len(atypes) == 1:
             # Single type - use its title for basename
             basename = helper.title2id(ann.type) + '.webm'
         else:
             basename = 'montage.webm'
     self.controller.gui.render_montage_dialog(elements, basename=basename)
     return True
예제 #2
0
 def render(self, *p):
     """Render the current montage.
     """
     self.controller.gui.render_montage_dialog([ w.annotation for w in self.contents ],
                                               basename = helper.title2id(self.view_name) + ".ogv",
                                               title = _("Extracting %s") % self.view_name,
                                               label = _("Exporting montage %(title)s\nto %%(filename)s") % { 'title': self.view_name })
     return True
예제 #3
0
 def render(self, *p):
     """Render the current montage.
     """
     self.controller.gui.render_montage_dialog(
         [w.annotation for w in self.contents],
         basename=helper.title2id(self.view_name) + ".ogv",
         title=_("Extracting %s") % self.view_name,
         label=_("Exporting montage %(title)s\nto %%(filename)s") %
         {'title': self.view_name})
     return True
예제 #4
0
파일: popup.py 프로젝트: pchampin/advene
 def extract_fragment(self, m, ann):
     """Extract the fragment corresponding to an annotation.
     """
     title = self.controller.get_title(ann)
     begin = helper.format_time(ann.fragment.begin)
     end = helper.format_time(ann.fragment.end)
     self.controller.gui.render_montage_dialog([ ann ],
                                               basename = ann.id + "-" + helper.title2id(title) + ".ogv",
                                               title = _("Extracting %s") % title,
                                               label = _("Exporting annotation %(title)s\nfrom %(begin)s to %(end)s\nto %%(filename)s") % locals())
     return True
예제 #5
0
 def new_from_title(self, title):
     """Generate a new (title, identifier) from a given title.
     """
     root = helper.title2id(title)
     index = 1
     i = "%s%d" % (root, index)
     while i in self.existing:
         index += 1
         i = "%s%d" % (root, index)
     if index != 1:
         title = "%s%d" % (title, index)
     return title, i
예제 #6
0
 def new_from_title(self, title):
     """Generate a new (title, identifier) from a given title.
     """
     root=helper.title2id(title)
     index=1
     i="%s%d" % (root, index)
     while i in self.existing:
         index += 1
         i="%s%d" % (root, index)
     if index != 1:
         title="%s%d" % (title, index)
     return title, i
예제 #7
0
    def save_query(self, *p):
        """Saves the query in the package.
        """
        l = self.eq.invalid_items()
        if l:
            self.log(
                _("Invalid query.\nThe following fields have an invalid value:\n%s"
                  ) % ", ".join(l))
            return True
        # Update the query
        self.eq.update_value()

        if hasattr(self.eq, 'container'):
            default_id = self.eq.container.id
            default_title = self.eq.container.title
        else:
            default_id = helper.title2id(self._label)
            default_title = self._label

        t, i = dialog.get_title_id(
            title=_("Saving the query..."),
            text=_("Give a title and identifier for saving the query"),
            element_title=default_title,
            element_id=default_id)
        if i is None:
            return True

        q = helper.get_id(self.controller.package.queries, i)
        # Overwriting an existing query
        if q:
            create = False
            self.controller.notify('EditSessionStart',
                                   element=q,
                                   immediate=True)
        else:
            create = True
            # Create the query
            q = self.controller.package.createQuery(ident=i)
            q.author = config.data.userid
            q.date = helper.get_timestamp()
            self.controller.package.queries.append(q)

        q.title = t
        q.content.mimetype = 'application/x-advene-simplequery'

        # Store the query itself in the _interactive query
        q.content.data = self.eq.model.xml_repr()
        if create:
            self.controller.notify('QueryCreate', query=q)
        else:
            self.controller.notify('QueryEditEnd', query=q)
            self.controller.notify('EditSessionEnd', element=q)
        return q
예제 #8
0
    def save_query(self, *p):
        """Saves the query in the package.
        """
        l=self.eq.invalid_items()
        if l:
            self.log(_("Invalid query.\nThe following fields have an invalid value:\n%s")
                     % ", ".join(l))
            return True
        # Update the query
        self.eq.update_value()

        if hasattr(self.eq, 'container'):
            default_id=self.eq.container.id
            default_title=self.eq.container.title
        else:
            default_id=helper.title2id(self._label)
            default_title=self._label


        t, i = dialog.get_title_id(title=_("Saving the query..."),
                                   text=_("Give a title and identifier for saving the query"),
                                   element_title=default_title,
                                   element_id=default_id)
        if i is None:
            return True

        q=helper.get_id(self.controller.package.queries, i)
        # Overwriting an existing query
        if q:
            create=False
            self.controller.notify('EditSessionStart', element=q, immediate=True)
        else:
            create=True
            # Create the query
            q=self.controller.package.createQuery(ident=i)
            q.author=config.data.userid
            q.date=helper.get_timestamp()
            self.controller.package.queries.append(q)

        q.title=t
        q.content.mimetype='application/x-advene-simplequery'

        # Store the query itself in the _interactive query
        q.content.data = self.eq.model.xml_repr()
        if create:
            self.controller.notify('QueryCreate', query=q)
        else:
            self.controller.notify('QueryEditEnd', query=q)
            self.controller.notify('EditSessionEnd', element=q)
        return q
예제 #9
0
    def save_query(self, *p):
        """Saves the query in the package.
        """
        if hasattr(self.query, 'container'):
            default_id = self.query.container.id
            default_title = self.query.container.title
        else:
            default_id = helper.title2id(self._label)
            default_title = self._label

        t, i = dialog.get_title_id(
            title=_("Saving the query..."),
            text=_("Give a title and identifier for saving the query"),
            element_title=default_title,
            element_id=default_id)
        if i is None:
            return True

        q = helper.get_id(self.controller.package.queries, i)
        # Overwriting an existing query
        if q:
            create = False
        else:
            create = True
            # Create the query
            q = self.controller.package.createQuery(ident=i)
            q.author = config.data.userid
            q.date = helper.get_timestamp()
            self.controller.package.queries.append(q)

        q.title = t
        if isinstance(self.query, SimpleQuery):
            q.content.mimetype = 'application/x-advene-simplequery'
        elif isinstance(self.query, Quicksearch):
            q.content.mimetype = 'application/x-advene-quicksearch'
        q.content.data = self.query.xml_repr()
        if create:
            self.controller.notify('QueryCreate', query=q)
        else:
            self.controller.notify('QueryEditEnd', query=q)
        return q
예제 #10
0
    def save_query(self, *p):
        """Saves the query in the package.
        """
        if hasattr(self.query, 'container'):
            default_id=self.query.container.id
            default_title=self.query.container.title
        else:
            default_id=helper.title2id(self._label)
            default_title=self._label

        t, i = dialog.get_title_id(title=_("Saving the query..."),
                                   text=_("Give a title and identifier for saving the query"),
                                   element_title=default_title,
                                   element_id=default_id)
        if i is None:
            return True

        q=helper.get_id(self.controller.package.queries, i)
        # Overwriting an existing query
        if q:
            create=False
        else:
            create=True
            # Create the query
            q=self.controller.package.createQuery(ident=i)
            q.author=config.data.userid
            q.date=helper.get_timestamp()
            self.controller.package.queries.append(q)

        q.title=t
        if isinstance(self.query, SimpleQuery):
            q.content.mimetype='application/x-advene-simplequery'
        elif isinstance(self.query, Quicksearch):
            q.content.mimetype='application/x-advene-quicksearch'
        q.content.data = self.query.xml_repr()
        if create:
            self.controller.notify('QueryCreate', query=q)
        else:
            self.controller.notify('QueryEditEnd', query=q)
        return q
예제 #11
0
    def iterator(self, rows):
        progress=0.02
        incr = 1.0 / self.row_count
        # Column cache: store (in_time, content) for each column
        column_cache = {}
        # Row cache: for coalesced types, store
        # (in_time, content) indexed by DCP type
        row_cache = {}
        for row in rows:
            row_cache.clear()
            self.progress(progress, _("Converting #%(num)d / %(count)d") % { 'num': rows.line_num,
                                                                             'count': self.row_count})
            progress += incr
            t = self.str2time(row[1])
            for (label, tc, value) in zip(self.labels[2::2], row[2::2], row[3::2]):
                label = str(label, 'mac_roman')

                if tc == 'IN':
                    # Store into column_cache
                    column_cache[label]=( t, str(value, 'mac_roman') )
                elif tc == 'OUT':
                    (begin, content) = column_cache.get(label, (0, 'OUT without IN'))
                    if label in type_mapping:
                        # Coalesced type
                        row_cache[label] = (begin, content)
                        continue
                    at = self.label2type.get(label)
                    if at is None:
                        at = self.label2type[label] = self.create_annotation_type(self.schema, helper.title2id(label), title=label)
                    yield {
                        'begin': begin,
                        'end': t,
                        'content': content,
                        'type': at,
                        }
            # Process row_cache
            output = {}
            for dcp_type, data in row_cache.items():
                label, attr = type_mapping[dcp_type]
                begin, content = data
                at = self.label2type.get(label)
                if at is None:
                    at = self.label2type[label] = self.create_annotation_type(self.schema, helper.title2id(label), title=label, mimetype='application/x-advene-structured')
                    at.setMetaData(config.data.namespace, 'representation', 'here/content/parsed/num')
                info = output.setdefault(at, { 'begin': begin, 'content': [] })
                #if info[begin] != begin:
                #    # FIXME: consistency check on begin time. What to do here???
                info['content'].append('%s=%s' % (attr, content.replace('\n', ' -- ')))
            for at, info in output.items():
                yield {
                    'begin': info['begin'],
                    'end': t,
                    'content': "\n".join(info['content']),
                    'type': at,
                    }
        self.progress(1.0)
예제 #12
0
 def update_id(entry):
     id_entry.set_text(helper.title2id(unicode(entry.get_text())))
     return True
예제 #13
0
    def convert_transcription_cb(self, button=None):
        if not self.controller.gui:
            self.message(_("Cannot convert the data: no associated package"))
            return True

        d = Gtk.Dialog(title=_("Converting transcription"),
                       parent=self.controller.gui.gui.win,
                       flags=Gtk.DialogFlags.DESTROY_WITH_PARENT,
                       buttons=( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                 Gtk.STOCK_OK, Gtk.ResponseType.OK,
                                 ))
        l=Gtk.Label(label=_("Choose the annotation-type where to create annotations.\n"))
        l.set_line_wrap(True)
        l.show()
        d.vbox.pack_start(l, False, True, 0)

        # Anticipated declaration of some widgets, which need to be
        # updated in the handle_new_type_selection callback.
        new_type_dialog=Gtk.VBox()
        delete_existing_toggle=Gtk.CheckButton(_("Delete existing annotations in this type"))
        delete_existing_toggle.set_active(False)

        ats=list(self.controller.package.annotationTypes)
        newat=helper.TitledElement(value=None,
                                   title=_("Create a new annotation type"))
        ats.append(newat)

        def handle_new_type_selection(combo):
            el=combo.get_current_element()
            if el == newat:
                new_type_dialog.show()
                delete_existing_toggle.set_sensitive(False)
            else:
                new_type_dialog.hide()
                delete_existing_toggle.set_sensitive(True)
            return True

        type_selection=dialog.list_selector_widget(members=[ (a, self.controller.get_title(a), self.controller.get_element_color(a)) for a in ats],
                                                   callback=handle_new_type_selection,
                                                   preselect=self.controller.package.get_element_by_id(self.options['annotation-type-id']))

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Select type") + " "), False, False, 0)
        hb.pack_start(type_selection, False, True, 0)
        d.vbox.pack_start(hb, False, True, 0)

        l=Gtk.Label(label=_("You want to create a new type. Please specify its schema and title."))
        l.set_line_wrap(True)
        l.show()
        new_type_dialog.pack_start(l, False, True, 0)

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Title") + " "), False, False, 0)
        new_title=Gtk.Entry()
        hb.pack_start(new_title, True, True, 0)
        new_type_dialog.pack_start(hb, False, True, 0)

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Containing schema") + " "), False, False, 0)
        schemas=list(self.controller.package.schemas)
        schema_selection=dialog.list_selector_widget(members=[ (s, self.controller.get_title(s)) for s in schemas])
        hb.pack_start(schema_selection, False, True, 0)
        new_type_dialog.pack_start(hb, False, True, 0)

        new_type_dialog.show_all()
        new_type_dialog.set_no_show_all(True)
        new_type_dialog.hide()

        d.vbox.pack_start(new_type_dialog, True, True, 0)

        l=Gtk.Label()
        l.set_markup("<b>" + _("Export options") + "</b>")
        d.vbox.pack_start(l, False, True, 0)

        d.vbox.pack_start(delete_existing_toggle, False, True, 0)

        empty_contents_toggle=Gtk.CheckButton(_("Generate annotations for empty contents"))
        empty_contents_toggle.set_active(self.options['empty-annotations'])
        d.vbox.pack_start(empty_contents_toggle, False, True, 0)

        d.connect('key-press-event', dialog.dialog_keypressed_cb)

        d.show_all()
        dialog.center_on_mouse(d)

        finished=None
        while not finished:
            res=d.run()
            if res == Gtk.ResponseType.OK:
                at=type_selection.get_current_element()
                if at == newat:
                    new_type_title=new_title.get_text()
                    if new_type_title == '':
                        # Empty title. Generate one.
                        id_=self.controller.package._idgenerator.get_id(AnnotationType)
                        new_type_title=id_
                    else:
                        id_=helper.title2id(new_type_title)
                        # Check that the id is available
                        if self.controller.package._idgenerator.exists(id_):
                            dialog.message_dialog(
                                _("The %s identifier already exists. Choose another one.") % id_,
                                icon=Gtk.MessageType.WARNING)
                            at=None
                            continue
                    # Creating a new type
                    s=schema_selection.get_current_element()
                    at=s.createAnnotationType(ident=id_)
                    at.author=config.data.userid
                    at.date=helper.get_timestamp()
                    at.title=new_type_title
                    at.mimetype='text/plain'
                    at.setMetaData(config.data.namespace, 'color', next(s.rootPackage._color_palette))
                    at.setMetaData(config.data.namespace, 'item_color', 'here/tag_color')
                    s.annotationTypes.append(at)
                    self.controller.notify('AnnotationTypeCreate', annotationtype=at)

                if delete_existing_toggle.get_active():
                    # Remove all annotations of at type
                    batch_id=object()
                    for a in at.annotations:
                        self.controller.delete_element(a, batch=batch_id)

                self.options['empty-annotations']=empty_contents_toggle.get_active()
                finished=True
            else:
                at=None
                finished=True
        d.destroy()

        if at is not None:
            self.options['annotation-type-id'] = at.id
            ti=TranscriptionImporter(package=self.controller.package,
                                     controller=self.controller,
                                     defaulttype=at,
                                     transcription_edit=self)
            ti.process_file('transcription')

            self.controller.package._modified=True
            self.controller.notify("PackageActivate", package=ti.package)
            self.message(_('Notes converted'))
            self.log(ti.statistics_formatted())
            # Feedback
            dialog.message_dialog(
                _("Conversion completed.\n%s annotations generated.") % ti.statistics['annotation'])

        return True
예제 #14
0
파일: hpi.py 프로젝트: oaubert/advene
    def iterator(self):
        """I iterate over the created annotations.
        """
        logger.warn("Importing using %s model", self.model)
        self.source_type = self.controller.package.get_element_by_id(self.source_type_id)
        minconf = self.confidence

        self.progress(.1, "Sending request to server")
        if self.split_types:
            # Dict indexed by entity type name
            new_atypes = {}
        else:
            new_atype = self.ensure_new_type(
                "concept_%s" % self.source_type_id,
                title = _("Concepts for %s" % (self.source_type_id)))
            new_atype.mimetype = 'application/json'
            new_atype.setMetaData(config.data.namespace, "representation",
                                  'here/content/parsed/label')
        if self.create_relations:
            schema = self.create_schema('s_concept')
            rtype_id = 'concept_relation'
            rtype = self.package.get_element_by_id(rtype_id)
            if not rtype:
                # Create a relation type if it does not exist.
                rtype = schema.createRelationType(ident=rtype_id)
                rtype.author = config.data.get_userid()
                rtype.date = self.timestamp
                rtype.title = "Related concept"
                rtype.mimetype='text/plain'
                rtype.setHackedMemberTypes( ('*', '*') )
                schema.relationTypes.append(rtype)
                self.update_statistics('relation-type')
            if not hasattr(rtype, 'getHackedMemberTypes'):
                logger.error("%s is not a valid relation type" % rtype_id)

        image_scale = self.available_models.get(self.model, {}).get('image_size')
        if image_scale:
            logger.warn("Scaling images to (%d, %d) as requested by %s", image_scale, image_scale, self.model)

        def get_scaled_image(t):
            """Return the image at the appropriate scale for the selected model.
            """
            original = bytes(self.controller.package.imagecache.get(t))
            if image_scale:
                im = Image.open(BytesIO(original))
                im = im.resize((image_scale, image_scale))
                buf = BytesIO()
                im.save(buf, 'PNG')
                scaled = buf.getvalue()
                buf.close()
            else:
                scaled = original
            return scaled

        # Use a requests.session to use a KeepAlive connection to the server
        session = requests.session()
        headers = {"Content-Type": "application/json", "Accept": "application/json"}
        response = session.post(self.url, headers=headers, json={
            "model": self.model,
            'media_uri': self.package.uri,
            'media_filename': self.controller.get_default_media(),
            'minimum_confidence': minconf,
            'annotations': [
                { 'annotationid': a.id,
                  'begin': a.fragment.begin,
                  'end': a.fragment.end,
                  'frames': [
                      {
                          'screenshot': base64.encodebytes(get_scaled_image(t)).decode('ascii'),
                          'timecode': t
                      } for t in (a.fragment.begin,
                                  int((a.fragment.begin + a.fragment.end) / 2),
                                  a.fragment.end)
                  ]
                }
                for a in self.source_type.annotations
            ]
        })

        output = response.json()
        if output.get('status') != 200:
            # Not OK result. Display error message.
            msg = _("Server error: %s") % output.get('message', _("Server transmission error."))
            logger.error(msg)
            self.output_message = msg
            return
        # FIXME: maybe check consistency with media_filename/media_uri?
        concepts = output.get('data', {}).get('concepts', [])
        progress = .2
        step = .8 / (len(concepts) or 1)
        self.progress(.2, _("Parsing %d results") % len(concepts))
        logger.warn(_("Parsing %d results (level %f)") % (len(concepts), self.confidence))
        for item in concepts:
            # Should not happen, since we pass the parameter to the server
            if item["confidence"] < minconf:
                continue
            a = self.package.get_element_by_id(item['annotationid'])
            if self.detected_position:
                begin = item['timecode']
            else:
                begin = a.fragment.begin
            end = a.fragment.end
            label = item.get('label')
            label_id = helper.title2id(label)
            if label and self.split_types:
                new_atype = new_atypes.get(label_id)
                if new_atype is None:
                   # Not defined yet. Create a new one.
                   new_atype = self.ensure_new_type(label_id, title = _("%s concept" % label))
                   new_atype.mimetype = 'application/json'
                   new_atype.setMetaData(config.data.namespace, "representation",
                                         'here/content/parsed/label')
                   new_atypes[label_id] = new_atype
            an = yield {
                'type': new_atype,
                'begin': begin,
                'end': end,
                'content': json.dumps(item),
            }
            if an is not None and self.create_relations:
                r = self.package.createRelation(
                    ident='_'.join( ('r', a.id, an.id) ),
                    type=rtype,
                    author=config.data.get_userid(),
                    date=self.timestamp,
                    members=(a, an))
                r.title = "Relation between %s and %s" % (a.id, an.id)
                self.package.relations.append(r)
                self.update_statistics('relation')
            self.progress(progress)
            progress += step
예제 #15
0
    def convert_transcription_cb(self, button=None):
        if not self.controller.gui:
            self.message(_("Cannot convert the data: no associated package"))
            return True

        d = Gtk.Dialog(title=_("Converting transcription"),
                       parent=self.controller.gui.gui.win,
                       flags=Gtk.DialogFlags.DESTROY_WITH_PARENT,
                       buttons=( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                 Gtk.STOCK_OK, Gtk.ResponseType.OK,
                                 ))
        l=Gtk.Label(label=_("Choose the annotation-type where to create annotations.\n"))
        l.set_line_wrap(True)
        l.show()
        d.vbox.pack_start(l, False, True, 0)

        # Anticipated declaration of some widgets, which need to be
        # updated in the handle_new_type_selection callback.
        new_type_dialog=Gtk.VBox()
        delete_existing_toggle=Gtk.CheckButton(_("Delete existing annotations in this type"))
        delete_existing_toggle.set_active(False)

        ats=list(self.controller.package.annotationTypes)
        newat=helper.TitledElement(value=None,
                                   title=_("Create a new annotation type"))
        ats.append(newat)

        def handle_new_type_selection(combo):
            el=combo.get_current_element()
            if el == newat:
                new_type_dialog.show()
                delete_existing_toggle.set_sensitive(False)
            else:
                new_type_dialog.hide()
                delete_existing_toggle.set_sensitive(True)
            return True

        type_selection=dialog.list_selector_widget(members=[ (a, self.controller.get_title(a), self.controller.get_element_color(a)) for a in ats],
                                                   callback=handle_new_type_selection,
                                                   preselect=self.controller.package.get_element_by_id(self.options['annotation-type-id']))

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Select type") + " "), False, False, 0)
        hb.pack_start(type_selection, False, True, 0)
        d.vbox.pack_start(hb, False, True, 0)

        l=Gtk.Label(label=_("You want to create a new type. Please specify its schema and title."))
        l.set_line_wrap(True)
        l.show()
        new_type_dialog.pack_start(l, False, True, 0)

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Title") + " "), False, False, 0)
        new_title=Gtk.Entry()
        hb.pack_start(new_title, True, True, 0)
        new_type_dialog.pack_start(hb, False, True, 0)

        hb=Gtk.HBox()
        hb.pack_start(Gtk.Label(_("Containing schema") + " "), False, False, 0)
        schemas=list(self.controller.package.schemas)
        schema_selection=dialog.list_selector_widget(members=[ (s, self.controller.get_title(s)) for s in schemas])
        hb.pack_start(schema_selection, False, True, 0)
        new_type_dialog.pack_start(hb, False, True, 0)

        new_type_dialog.show_all()
        new_type_dialog.set_no_show_all(True)
        new_type_dialog.hide()

        d.vbox.pack_start(new_type_dialog, True, True, 0)

        l=Gtk.Label()
        l.set_markup("<b>" + _("Export options") + "</b>")
        d.vbox.pack_start(l, False, True, 0)

        d.vbox.pack_start(delete_existing_toggle, False, True, 0)

        empty_contents_toggle=Gtk.CheckButton(_("Generate annotations for empty contents"))
        empty_contents_toggle.set_active(self.options['empty-annotations'])
        d.vbox.pack_start(empty_contents_toggle, False, True, 0)

        d.connect('key-press-event', dialog.dialog_keypressed_cb)

        d.show_all()
        dialog.center_on_mouse(d)

        finished=None
        while not finished:
            res=d.run()
            if res == Gtk.ResponseType.OK:
                at=type_selection.get_current_element()
                if at == newat:
                    new_type_title=new_title.get_text()
                    if new_type_title == '':
                        # Empty title. Generate one.
                        id_=self.controller.package._idgenerator.get_id(AnnotationType)
                        new_type_title=id_
                    else:
                        id_=helper.title2id(new_type_title)
                        # Check that the id is available
                        if self.controller.package._idgenerator.exists(id_):
                            dialog.message_dialog(
                                _("The %s identifier already exists. Choose another one.") % id_,
                                icon=Gtk.MessageType.WARNING)
                            at=None
                            continue
                    # Creating a new type
                    s=schema_selection.get_current_element()
                    at=s.createAnnotationType(ident=id_)
                    at.author=config.data.userid
                    at.date=helper.get_timestamp()
                    at.title=new_type_title
                    at.mimetype='text/plain'
                    at.setMetaData(config.data.namespace, 'color', next(s.rootPackage._color_palette))
                    at.setMetaData(config.data.namespace, 'item_color', 'here/tag_color')
                    s.annotationTypes.append(at)
                    self.controller.notify('AnnotationTypeCreate', annotationtype=at)

                if delete_existing_toggle.get_active():
                    # Remove all annotations of at type
                    batch_id=object()
                    for a in at.annotations:
                        self.controller.delete_element(a, batch=batch_id)

                self.options['empty-annotations']=empty_contents_toggle.get_active()
                finished=True
            else:
                at=None
                finished=True
        d.destroy()

        if at is not None:
            self.options['annotation-type-id'] = at.id
            ti=TranscriptionImporter(package=self.controller.package,
                                     controller=self.controller,
                                     defaulttype=at,
                                     transcription_edit=self)
            ti.process_file('transcription')

            self.controller.package._modified=True
            self.controller.notify("PackageActivate", package=ti.package)
            self.message(_('Notes converted'))
            self.log(ti.statistics_formatted())
            # Feedback
            dialog.message_dialog(
                _("Conversion completed.\n%s annotations generated.") % ti.statistics['annotation'])

        return True
예제 #16
0
파일: dialog.py 프로젝트: oaubert/advene
 def update_id(entry):
     id_entry.set_text(helper.title2id(entry.get_text()))
     return True
예제 #17
0
    def iterator(self):
        """I iterate over the created annotations.
        """
        logger.warning("Importing using %s model", self.model)
        self.source_type = self.controller.package.get_element_by_id(self.source_type_id)
        minconf = self.confidence

        self.progress(.1, "Sending request to server")
        if self.split_types:
            # Dict indexed by entity type name
            new_atypes = {}
        else:
            new_atype = self.ensure_new_type("concept_%s" % self.source_type_id,
                                             title = _("Concepts for %s" % (self.source_type_id)),
                                             mimetype = 'application/json')
            new_atype.setMetaData(config.data.namespace, "representation",
                                  'here/content/parsed/label')
        if self.create_relations:
            schema = self.create_schema('s_concept')
            rtype_id = 'concept_relation'
            rtype = self.package.get_element_by_id(rtype_id)
            if not rtype:
                # Create a relation type if it does not exist.
                rtype = schema.createRelationType(ident=rtype_id)
                rtype.author = config.data.get_userid()
                rtype.date = self.timestamp
                rtype.title = "Related concept"
                rtype.mimetype='text/plain'
                rtype.setHackedMemberTypes( ('*', '*') )
                schema.relationTypes.append(rtype)
                self.update_statistics('relation-type')
            if not hasattr(rtype, 'getHackedMemberTypes'):
                logger.error("%s is not a valid relation type", rtype_id)

        image_scale = self.available_models.get(self.model, {}).get('image_size')
        if image_scale:
            logger.warning("Scaling images to (%d, %d) as requested by %s", image_scale, image_scale, self.model)

        def get_scaled_image(t):
            """Return the image at the appropriate scale for the selected model.
            """
            original = bytes(self.controller.package.imagecache.get(t))
            if image_scale:
                im = Image.open(BytesIO(original))
                im = im.resize((image_scale, image_scale))
                buf = BytesIO()
                im.save(buf, 'PNG')
                scaled = buf.getvalue()
                buf.close()
            else:
                scaled = original
            return scaled

        # Use a requests.session to use a KeepAlive connection to the server
        session = requests.session()
        headers = {"Content-Type": "application/json", "Accept": "application/json"}
        response = session.post(self.url, headers=headers, json={
            "model": self.model,
            'media_uri': self.package.uri,
            'media_filename': self.controller.get_default_media(),
            'minimum_confidence': minconf,
            'annotations': [
                { 'annotationid': a.id,
                  'begin': a.fragment.begin,
                  'end': a.fragment.end,
                  'frames': [
                      {
                          'screenshot': base64.encodebytes(get_scaled_image(t)).decode('ascii'),
                          'timecode': t
                      } for t in (a.fragment.begin,
                                  int((a.fragment.begin + a.fragment.end) / 2),
                                  a.fragment.end)
                  ]
                }
                for a in self.source_type.annotations
            ]
        })

        output = response.json()
        if output.get('status') != 200:
            # Not OK result. Display error message.
            msg = _("Server error: %s") % output.get('message', _("Server transmission error."))
            logger.error(msg)
            self.output_message = msg
            return
        # FIXME: maybe check consistency with media_filename/media_uri?
        concepts = output.get('data', {}).get('concepts', [])
        progress = .2
        step = .8 / (len(concepts) or 1)
        self.progress(.2, _("Parsing %d results") % len(concepts))
        logger.warning(_("Parsing %(count)d results (level %(confidence)f)") % { "count": len(concepts),
                                                                                 "confidence": self.confidence })
        for item in concepts:
            # Should not happen, since we pass the parameter to the server
            if item["confidence"] < minconf:
                continue
            a = self.package.get_element_by_id(item['annotationid'])
            if self.detected_position:
                begin = item['timecode']
            else:
                begin = a.fragment.begin
            end = a.fragment.end
            label = item.get('label')
            label_id = helper.title2id(label)
            if label and self.split_types:
                new_atype = new_atypes.get(label_id)
                if new_atype is None:
                    # Not defined yet. Create a new one.
                    new_atype = self.ensure_new_type(label_id,
                                                     title = _("%s concept" % label),
                                                     mimetype = 'application/json')
                    new_atype.setMetaData(config.data.namespace, "representation",
                                          'here/content/parsed/label')
                    new_atypes[label_id] = new_atype
            an = yield {
                'type': new_atype,
                'begin': begin,
                'end': end,
                'content': json.dumps(item),
            }
            if an is not None and self.create_relations:
                r = self.package.createRelation(
                    ident='_'.join( ('r', a.id, an.id) ),
                    type=rtype,
                    author=config.data.get_userid(),
                    date=self.timestamp,
                    members=(a, an))
                r.title = "Relation between %s and %s" % (a.id, an.id)
                self.package.relations.append(r)
                self.update_statistics('relation')
            self.progress(progress)
            progress += step