Ejemplo n.º 1
0
    def get(self, request):
        root = JSONAPIRoot()

        namespace = request.GET.get("namespace")
        key = request.GET.get("key")
        if not key or not namespace:
            raise Http404

        identifier = "%s/%s" % (namespace, key)

        obj = JSONAPIObject("setting", identifier)
        obj["namespace"] = namespace
        obj["key"] = key
        if request.GET.get("default"):
            obj["value"] = self.service.config.get_default_config(
                namespace, key)
        else:
            obj["value"] = self.service.config.get_user_config(
                request.user, namespace, key)

        root.append(obj)

        schema = self.service.config.get_config_schema(namespace, key)
        if schema:
            schema_obj = JSONAPIObject("schema", identifier)
            schema_obj["namespace"] = namespace
            schema_obj["key"] = key

            json_schema = JSONSchema()
            schema = schema()
            schema_obj["schema"] = json_schema.dump(schema)
            obj.add_relationship("schema", schema_obj)

        return Response(root.serialize(request))
Ejemplo n.º 2
0
    def get_config_view(self, request):
        root = JSONAPIRoot()
        logger.debug(
            f"Plugin {self.service!r}/{self.service.name} with full sections config {self.service.config['sections']!r}"
        )
        for section in self.service.config["sections"]:
            logger.debug(
                f"Making config view {section['name']} with settings {section!r}"
            )

            links = {
                "self":
                request.build_absolute_uri(
                    f"/{self.service.name}/{section['name']}")
            }
            obj = JSONAPIObject("folder",
                                f"{self.service.name}/{section['name']}",
                                links=links)
            obj["name"] = section["name"]
            if section.get("display_name"):
                obj["display_name"] = section["display_name"]

            search_filter_obj = self.get_search_filter(obj["name"], section)
            if search_filter_obj:
                obj.add_relationship("metadata_searchfilter",
                                     search_filter_obj,
                                     local=True)

            root.append(obj)

        return root.serialize(request)
Ejemplo n.º 3
0
    def get(self, request, metadata_handler, identifier):
        logger.debug(
            f"Fetching metadata using {metadata_handler} with identifier {identifier}"
        )
        for plugin in self.service._related_plugins:
            if (plugin.name == metadata_handler
                    and plugin.plugin_type == "metadatahandler"):
                break
        else:
            logger.warning(f"Did not find metadata_handler {metadata_handler}")
            raise Http404

        metadata = plugin.get_metadata(request, identifier)
        if not metadata:
            raise Http404

        root = JSONAPIRoot()

        identifier = f"{plugin.plugin_name}:{identifier}"
        obj_type = plugin.get_jsonapi_type()
        obj = JSONAPIObject(obj_type, identifier)
        obj.update(metadata)
        root.append(obj)

        return Response(root.serialize(request))
Ejemplo n.º 4
0
    def stream(self, request, config, listingitem):
        item = listingitem.get_original_item()

        streamresult = create_stream(item, request)

        # UserActionLog.objects.log_plugin(self.service, request.user, 'Stream started by %s' % (request.user, ),
        #                                  'Stream for %s started by %s' % (item.path, request.user))
        with Log.objects.start_chain(self.service,
                                     "USER.STREAM_START",
                                     user=request.user) as log:
            log.log(0, f"Trying to stream {item.path}")

            viewstate = ViewState(request.user, request.GET.get("viewstate"))
            root = JSONAPIRoot()

            for history_plugin in config.get("histories", []):
                logger.debug(f"Logging history to {history_plugin.name}")
                history_plugin.log_history(config, listingitem, viewstate)

            viewstate_obj = JSONAPIObject("viewstate", viewstate.id)
            viewstate_obj.update(viewstate)
            root.append(viewstate_obj)

            player_service = self.service.config.get("player_service")
            player_id = self.request.GET.get("target")
            if player_id and player_service:
                payload = streamresult.serialize(request)
                player_service.play(payload, viewstate, player_id)

            root.append(streamresult.to_jsonapi(request))

            return Response(root.serialize(request))
Ejemplo n.º 5
0
    def get_config_view(self, request):
        root = JSONAPIRoot()
        for section in self.service.config["sections"]:
            logger.debug(
                f"Making config view {section['name']} with settings {section!r}"
            )

            links = {
                "self":
                request.build_absolute_uri(
                    f"/{self.service.name}/{section['name']}")
            }
            obj = JSONAPIObject("folder",
                                f"{self.service.name}/{section['name']}",
                                links=links)
            obj["name"] = section["name"]
            if section.get("display_name"):
                obj["display_name"] = section["display_name"]

            first_level_config = sorted(section["levels"],
                                        key=lambda x: x["depth"])[0]
            filter_info_obj = self.get_level_filter_info(
                obj["name"], first_level_config)
            obj.add_relationship("metadata_filterinfo",
                                 filter_info_obj,
                                 local=True)

            root.append(obj)

        return root.serialize(request)
Ejemplo n.º 6
0
 def to_jsonapi(self, request):
     obj = JSONAPIObject(
         f"stream_{self.playhandler}",
         self.name,
         links={"stream": request.build_absolute_uri(self.url)},
     )
     return obj
Ejemplo n.º 7
0
    def get_search_filter(self, name, level_config):
        obj = JSONAPIObject("metadata_searchfilter", name)

        filters = self.service.get_filters(level_config)

        if filters:
            obj["filter"] = filters.serialize()

        return obj
Ejemplo n.º 8
0
    def get_tag_info(self, level_config):
        """
        Create tag to be added as relation to reply. Makes it possible to tag metadata.
        """
        tags = []
        for tag in level_config.get("tags", []):
            obj = JSONAPIObject("metadata_tag", tag.name)
            obj["plugin_name"] = tag.plugin_name

            tags.append(obj)

        return tags
Ejemplo n.º 9
0
    def get_level_filter_info(self, name, level_config):
        """
        Create filterinfo to be added as relation to reply. Makes it possible to create
        a rich search interface.
        """
        obj = JSONAPIObject("metadata_filterinfo", name)

        metadata_handlers = level_config.get("metadata_handlers", [])
        obj["metadata_handlers"] = [
            f"metadata_{mh.plugin_name}" for mh in metadata_handlers
        ]

        filter_ = self.create_filter(metadata_handlers)
        obj["filter"] = self.serialize_filter(filter_,
                                              has_indexer=bool(
                                                  level_config.get("indexer")))

        content_type = level_config.get("content_type")
        if content_type:
            obj["content_type"] = content_type

        return obj
Ejemplo n.º 10
0
    def populate_metadata_jsonapi(self, request, root):
        if self.metadata_embed_method == "skip":
            return

        logger.info("Populating JSONAPI root with metadata")

        obj_type = self.get_jsonapi_type()

        items = {
            obj._original_object.id: obj
            for obj in (root.data + list(root.included.values()))
            if obj._original_object and hasattr(obj._original_object, "id")
        }

        relations = self.get_relations(request.user, items.keys())

        jsonapi_obj_mapping = {}  # maps listitem to metadata jsonapi objects
        logger.info(
            f"Seems like we should embed the serialized metadata {self.name}")

        has_prefetch_related_denormalized = self.has_prefetch_related_denormalized(
        )
        metadatas = [(has_prefetch_related_denormalized
                      and PrefetchProxy(m, self.prefetch_related) or m)
                     for m in set(v for vs in relations.values() for v in vs)]

        try:
            self.model._meta.get_field("last_update_status")
            has_update_status = True
        except FieldDoesNotExist:
            has_update_status = False
        # else:
        #     metadatas = metadatas.filter(last_update_status__in=['success', 'do-not-fetch'])

        usable_metadata = []
        empty_metadata = []
        for metadata in metadatas:
            if not has_update_status or metadata.last_update_status == "success":
                usable_metadata.append(metadata)
                logger.trace(
                    f"Serializing a populated metadata entry for {metadata.identifier} / {metadata!r}"
                )
            else:
                empty_metadata.append(metadata)
                logger.trace(
                    f"Serializing an unpopulated metadata entry for {metadata.identifier} / {metadata!r} / {getattr(metadata, 'last_update_status', 'no-status')}"
                )

        all_serialized = self.serializer(
            usable_metadata,
            context={
                "request": request,
                "config": self.config
            },
            many=True,
        ).data + [{
            "id": metadata.identifier,
            "populated": False
        } for metadata in empty_metadata]

        for metadata, serialized in zip(usable_metadata + empty_metadata,
                                        all_serialized):
            identifier = f"{self.plugin_name}:{metadata.identifier}"

            if self.metadata_embed_method in ["include", "relate"]:
                metadata.__config__ = self.config
                obj = JSONAPIObject(obj_type, identifier, metadata)
                obj.update(serialized)
            elif self.metadata_embed_method == "embed":
                obj = {"metadata:%s" % self.plugin_name: serialized}
            else:
                raise UnknownEmbedMethodException(
                    f"Unknown embed method: {self.metadata_embed_method!r}")

            jsonapi_obj_mapping[identifier] = obj
            logger.trace(f"Created metadata object {identifier} with metadata")

        for listingitem_id, metadatas in relations.items():
            for metadata in metadatas:
                identifier = "%s:%s" % (self.plugin_name, metadata.identifier)
                if self.metadata_embed_method == "embed":
                    m = jsonapi_obj_mapping.get(identifier, {})
                    items[listingitem_id].update(m)
                elif self.metadata_embed_method in ["include", "relate"]:
                    if identifier not in jsonapi_obj_mapping:
                        metadata.__config__ = self.config
                        obj = JSONAPIObject(obj_type,
                                            identifier,
                                            metadata,
                                            populated=False)
                        jsonapi_obj_mapping[identifier] = obj
                        logger.trace(
                            f"Created metadata object {identifier} without metadata"
                        )

                    local = self.metadata_embed_method == "relate"
                    logger.trace(
                        f"Added relationship between listingitem_id:{listingitem_id} metadata_identifier:{identifier}"
                    )
                    items[listingitem_id].add_relationship(
                        obj_type, jsonapi_obj_mapping[identifier], local=local)
                else:
                    raise UnknownEmbedMethodException(
                        f"Unknown embed method: {self.metadata_embed_method!r}"
                    )
Ejemplo n.º 11
0
    def serialize_listing(self, request, config, listing_item_root,
                          listingitems, links, meta):
        """
        Serializes listingitems related to root.
        """
        root = JSONAPIRoot()
        root.links.update(links)
        root.meta.update(meta)

        root.meta["content_type"] = config["level"].get("content_type", "")

        tag_info_objs = self.get_tag_info(config["level"])
        commands_obj = self.get_jsonapi_commands()

        def add_commands(obj, commands):
            for command_obj in commands:
                if command_obj._original_object.metadata.get("usable",
                                                             "all") in [
                                                                 "all",
                                                                 obj.type,
                                                             ]:
                    obj.add_relationship("metadata_commands", command_obj)

        if listing_item_root:
            parent = JSONAPIObject(
                listing_item_root.item_type,
                listing_item_root.get_full_path(),
                listing_item_root,
            )
            parent.update(listing_item_root.attributes)

            root.meta["parent"] = {"type": parent.type, "id": parent.id}

            root.add_included(parent)

            if config["parent_level_config"]:
                for metadata_handler in config["parent_level_config"][
                        "metadata_handlers"]:
                    logger.debug(
                        f"Finding metadata from metadata handler {metadata_handler.name} for parent"
                    )
                    metadata_handler.populate_metadata_jsonapi(request, root)
                    logger.debug(
                        f"Finished metadata from metadata handler {metadata_handler.name}"
                    )

            add_commands(parent, commands_obj)

            self.add_additional_parent_relationships(parent, request, config,
                                                     listing_item_root)

            for tag_info_obj in tag_info_objs:
                parent.add_relationship("metadata_tag", tag_info_obj)
        else:
            parent = None

        if config["edge_type"] == "folder":
            next_level_config = config["levels"][config["current_level"] + 1]
            tag_info_objs = self.get_tag_info(next_level_config)
        else:
            tag_info_objs = None

        for listingitem in listingitems:
            obj = JSONAPIObject(listingitem.item_type,
                                listingitem.get_full_path(), listingitem)
            attributes = listingitem.attributes

            obj.update(attributes)
            obj["datetime"] = listingitem.datetime
            root.append(obj)

            if parent:
                obj.add_relationship("parent", parent)
            add_commands(obj, commands_obj)

            if tag_info_objs:
                for tag_info_obj in tag_info_objs:
                    obj.add_relationship("metadata_tag", tag_info_obj)

        for metadata_handler in config["level"]["metadata_handlers"]:
            logger.debug(
                f"Finding metadata from metadata handler {metadata_handler.name}"
            )
            start_time = time.time()
            metadata_handler.populate_metadata_jsonapi(request, root)
            logger.debug(
                f"Finished metadata from metadata handler {metadata_handler.name} it took {time.time() - start_time}"
            )

        if "parent" not in root.meta and root.data:
            obj = root.data[0]
            root.meta["parent"] = {"type": obj.type, "id": obj.id}

        return root.serialize(request)