<commit_before>// Copyright 2014 Endless Mobile, Inc.
const ByteArray = imports.byteArray;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;

GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE;

/**
 * Class: ContentObjectModel
 * This is the base class for all content objects in the knowledge app.
 */
const ContentObjectModel = new Lang.Class({
    Name: 'ContentObjectModel',
    GTypeName: 'EknContentObjectModel',
    Extends: GObject.Object,
    Properties: {
        /**
         * Property: ekn-id
         * A string with the ID of the content object. This is an internal ID assigned by EKN.
         */
        'ekn-id': GObject.ParamSpec.string('ekn-id', 'Object\'s ID', 'The ID of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: ekn-version
         *
         * The version of the on-disk data format for this bundle. This value
         * is incremented whenever we have a major change in this format, and
         * is used to support backwards compatible changes.
         *
         * Defaults to 1
         */
        'ekn-version': GObject.ParamSpec.int('ekn-version', 'EKN Version',
            'The version of the knowledge app.',
             GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
             0, GLib.MAXINT32, 1),
        /**
         * Property: title
         * A string with the title of the content object. Defaults to an empty string.
         */
        'title': GObject.ParamSpec.string('title', 'Title', 'The title of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: original-title
         * A string with the original title of the content object. Defaults to an empty string.
         */
        'original-title': GObject.ParamSpec.string('original-title', 'Original Title', 'The original title (wikipedia title) of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),

        /**
         * Property: original-uri
         * URI where the original version of this content can be downloaded
         *
         * This property is distinct from <source-uri>, which represents the URI
         * where the article was downloaded from during database build.
         *
         * Note that this property may not be present in client databases, since
         * it was added in 0.2.
         * However, on an <ArticleObjectModel> with <source> equal to
         * "wikipedia", "wikihow", "wikisource", or "wikibooks", it will be
         * set to the value of <source-uri> if it is not present in the
         * database, for backwards compatibility reasons.
         *
         * Since:
         *   0.2
         */
        'original-uri': GObject.ParamSpec.string('original-uri', 'Original URI',
            'URI where the original version of this content can be downloaded',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),

        /**
         * Property: thumbnail-id
         * The ekn id of a ImageObjectModel representing the thumbnail image. Must be set to type GObject, since
         * ImageObjectModel subclasses this class and so we cannot reference it here.
         */
        'thumbnail-id': GObject.ParamSpec.string('thumbnail-id', 'Thumbnail ID', 'EKN ID of the thumbnail image',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: language
         * The language for this content object. Defaults to an empty string.
         */
        'language': GObject.ParamSpec.string('language', 'Language', 'Language of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: copyright-holder
         * The copyright holder for this content object. Defaults to an empty string.
         */
        'copyright-holder': GObject.ParamSpec.string('copyright-holder', 'Copyright Holder', 'The copyright holder of the object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: source-uri
         * URI where this content was downloaded from during database build
         *
         * TODO Should we check to always have a value for <source-uri>?
         * Don't use this property for user-visible things.
         * It is only used internally.
         */
        'source-uri': GObject.ParamSpec.string('source-uri', 'Source URL',
            'URI where this content was downloaded from during database build',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),

        /**
         * Property: source-name
         * Human-readable name of the source of this article
         *
         * A string containing the name of this article's source.
         * For example, "Wikipedia" or "Huffington Post" or "Cosimo's Blog".
         *
         * Note that this property may not be present in client databases, since
         * it was added in 0.2.
         * However, it will be present in all Reader app databases.
         * Also, on an <ArticleObjectModel> with <source> equal to "wikipedia",
         * "wikihow", "wikisource", or "wikibooks", it will be set to the
         * appropriate value even if it is not present in the database, for
         * backwards compatibility reasons.
         *
         * Since:
         *   0.2
         */
        'source-name': GObject.ParamSpec.string('source-name', 'Source name',
            'Human-readable name of the source of this article',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),

        /**
         * Property: content-uri
         * (DEPRECATED) A string with the URI to the file content for this
         * object.
         *
         * No longer used in ekn bundles. Content is now stored in a shard file
         * which is indexed by ekn-id, and is accessed by get_content_stream()
         */
        'content-uri': GObject.ParamSpec.string('content-uri', 'Object Content URL',
            'URI of the source content file',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: content-type
         * The source content's mimetype
         */
        'content-type': GObject.ParamSpec.string('content-type', 'Object Content Type',
            'Mimetype of the source content',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: synopsis
         * The synopsis for this content object. Defaults to an empty string.
         */
        'synopsis': GObject.ParamSpec.string('synopsis', 'Synopsis', 'Synopsis of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: last-modified-date
         * The date of last modification for this content object. It treats dates
         * according to the ISO8601 standard.
         */
        'last-modified-date': GObject.ParamSpec.string('last-modified-date', 'Last Modified Date', 'Last Modified Date of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: license
         * The license for this content object. Defaults to an empty string.
         */
        'license': GObject.ParamSpec.string('license', 'License', 'License of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: redirects-to
         * The EKN ID of the ContentObject to which this model should redirect.
         */
        'redirects-to': GObject.ParamSpec.string('redirects-to', 'Redirects To',
            'EKN ID of the object to which this model should redirect',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
    },

    _init: function (params) {
        this._resources = [];
        this.parent(params);
    },

    get title () {
        return this._title;
    },

    get_resources: function () {
        return this._resources;
    },

    get_tags: function () {
        return this._tags;
    },

    get_content_stream: function () {
        if (this.ekn_version >= 2) {
            // FIXME: We need to do this import here in the method to avoid a
            // circular dependency of imports
            let engine = imports.search.engine.Engine.get_default();
            let [stream, content_type] = engine.get_content_by_id(this.ekn_id);
            return stream;
        } else {
            if (this.content_type === 'text/html') {
                let bytes = ByteArray.fromString(this.html).toGBytes();
                let stream = Gio.MemoryInputStream.new_from_bytes(bytes);
                return stream;
            } else {
                let file = Gio.File.new_for_uri(this.content_uri);
                let stream = file.read(null);
                return stream;
            }
        }
    },

    set title (v) {
        // TODO: Remove this line once we have reliable content
        // For now we need to programmatically capitalize titles
        v = v.charAt(0).toUpperCase() + v.slice(1);
        this._title = v;
    },

    set_resources: function (v) {
        this._resources = v;
    },

    set_tags: function (v) {
        this._tags = v;
    }
});

/**
 * Constructor: new_from_json_ld
 * Creates an ContentObjectModel from a Knowledge Engine ContentObject
 * JSON-LD document
 */
ContentObjectModel.new_from_json_ld = function (json_ld_data, media_path, ekn_version) {
    let props = ContentObjectModel._props_from_json_ld(json_ld_data, media_path, ekn_version);
    let contentObjectModel = new ContentObjectModel(props);
    ContentObjectModel._setup_from_json_ld(contentObjectModel, json_ld_data, media_path, ekn_version);

    return contentObjectModel;
};

ContentObjectModel._setup_from_json_ld = function (model, json_ld_data, media_path, ekn_version) {
    if (json_ld_data.hasOwnProperty('resources')) {
        model.set_resources(json_ld_data.resources);
    }
};

ContentObjectModel._props_from_json_ld = function (json_ld_data, media_path, ekn_version) {
    let props = {};

    if (typeof ekn_version === 'number')<commit_msg>contentObjectModel: actually assign tags property<commit_after>// Copyright 2014 Endless Mobile, Inc.
const ByteArray = imports.byteArray;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;

GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE;

/**
 * Class: ContentObjectModel
 * This is the base class for all content objects in the knowledge app.
 */
const ContentObjectModel = new Lang.Class({
    Name: 'ContentObjectModel',
    GTypeName: 'EknContentObjectModel',
    Extends: GObject.Object,
    Properties: {
        /**
         * Property: ekn-id
         * A string with the ID of the content object. This is an internal ID assigned by EKN.
         */
        'ekn-id': GObject.ParamSpec.string('ekn-id', 'Object\'s ID', 'The ID of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: ekn-version
         *
         * The version of the on-disk data format for this bundle. This value
         * is incremented whenever we have a major change in this format, and
         * is used to support backwards compatible changes.
         *
         * Defaults to 1
         */
        'ekn-version': GObject.ParamSpec.int('ekn-version', 'EKN Version',
            'The version of the knowledge app.',
             GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
             0, GLib.MAXINT32, 1),
        /**
         * Property: title
         * A string with the title of the content object. Defaults to an empty string.
         */
        'title': GObject.ParamSpec.string('title', 'Title', 'The title of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: original-title
         * A string with the original title of the content object. Defaults to an empty string.
         */
        'original-title': GObject.ParamSpec.string('original-title', 'Original Title', 'The original title (wikipedia title) of a document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),

        /**
         * Property: original-uri
         * URI where the original version of this content can be downloaded
         *
         * This property is distinct from <source-uri>, which represents the URI
         * where the article was downloaded from during database build.
         *
         * Note that this property may not be present in client databases, since
         * it was added in 0.2.
         * However, on an <ArticleObjectModel> with <source> equal to
         * "wikipedia", "wikihow", "wikisource", or "wikibooks", it will be
         * set to the value of <source-uri> if it is not present in the
         * database, for backwards compatibility reasons.
         *
         * Since:
         *   0.2
         */
        'original-uri': GObject.ParamSpec.string('original-uri', 'Original URI',
            'URI where the original version of this content can be downloaded',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),

        /**
         * Property: thumbnail-id
         * The ekn id of a ImageObjectModel representing the thumbnail image. Must be set to type GObject, since
         * ImageObjectModel subclasses this class and so we cannot reference it here.
         */
        'thumbnail-id': GObject.ParamSpec.string('thumbnail-id', 'Thumbnail ID', 'EKN ID of the thumbnail image',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: language
         * The language for this content object. Defaults to an empty string.
         */
        'language': GObject.ParamSpec.string('language', 'Language', 'Language of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: copyright-holder
         * The copyright holder for this content object. Defaults to an empty string.
         */
        'copyright-holder': GObject.ParamSpec.string('copyright-holder', 'Copyright Holder', 'The copyright holder of the object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: source-uri
         * URI where this content was downloaded from during database build
         *
         * TODO Should we check to always have a value for <source-uri>?
         * Don't use this property for user-visible things.
         * It is only used internally.
         */
        'source-uri': GObject.ParamSpec.string('source-uri', 'Source URL',
            'URI where this content was downloaded from during database build',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),

        /**
         * Property: source-name
         * Human-readable name of the source of this article
         *
         * A string containing the name of this article's source.
         * For example, "Wikipedia" or "Huffington Post" or "Cosimo's Blog".
         *
         * Note that this property may not be present in client databases, since
         * it was added in 0.2.
         * However, it will be present in all Reader app databases.
         * Also, on an <ArticleObjectModel> with <source> equal to "wikipedia",
         * "wikihow", "wikisource", or "wikibooks", it will be set to the
         * appropriate value even if it is not present in the database, for
         * backwards compatibility reasons.
         *
         * Since:
         *   0.2
         */
        'source-name': GObject.ParamSpec.string('source-name', 'Source name',
            'Human-readable name of the source of this article',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),

        /**
         * Property: content-uri
         * (DEPRECATED) A string with the URI to the file content for this
         * object.
         *
         * No longer used in ekn bundles. Content is now stored in a shard file
         * which is indexed by ekn-id, and is accessed by get_content_stream()
         */
        'content-uri': GObject.ParamSpec.string('content-uri', 'Object Content URL',
            'URI of the source content file',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: content-type
         * The source content's mimetype
         */
        'content-type': GObject.ParamSpec.string('content-type', 'Object Content Type',
            'Mimetype of the source content',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
            ''),
        /**
         * Property: synopsis
         * The synopsis for this content object. Defaults to an empty string.
         */
        'synopsis': GObject.ParamSpec.string('synopsis', 'Synopsis', 'Synopsis of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: last-modified-date
         * The date of last modification for this content object. It treats dates
         * according to the ISO8601 standard.
         */
        'last-modified-date': GObject.ParamSpec.string('last-modified-date', 'Last Modified Date', 'Last Modified Date of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: license
         * The license for this content object. Defaults to an empty string.
         */
        'license': GObject.ParamSpec.string('license', 'License', 'License of the document or media object',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
        /**
         * Property: redirects-to
         * The EKN ID of the ContentObject to which this model should redirect.
         */
        'redirects-to': GObject.ParamSpec.string('redirects-to', 'Redirects To',
            'EKN ID of the object to which this model should redirect',
            GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, ''),
    },

    _init: function (params) {
        this._resources = [];
        this.parent(params);
    },

    get title () {
        return this._title;
    },

    get_resources: function () {
        return this._resources;
    },

    get_tags: function () {
        return this._tags;
    },

    get_content_stream: function () {
        if (this.ekn_version >= 2) {
            // FIXME: We need to do this import here in the method to avoid a
            // circular dependency of imports
            let engine = imports.search.engine.Engine.get_default();
            let [stream, content_type] = engine.get_content_by_id(this.ekn_id);
            return stream;
        } else {
            if (this.content_type === 'text/html') {
                let bytes = ByteArray.fromString(this.html).toGBytes();
                let stream = Gio.MemoryInputStream.new_from_bytes(bytes);
                return stream;
            } else {
                let file = Gio.File.new_for_uri(this.content_uri);
                let stream = file.read(null);
                return stream;
            }
        }
    },

    set title (v) {
        // TODO: Remove this line once we have reliable content
        // For now we need to programmatically capitalize titles
        v = v.charAt(0).toUpperCase() + v.slice(1);
        this._title = v;
    },

    set_resources: function (v) {
        this._resources = v;
    },

    set_tags: function (v) {
        this._tags = v;
    }
});

/**
 * Constructor: new_from_json_ld
 * Creates an ContentObjectModel from a Knowledge Engine ContentObject
 * JSON-LD document
 */
ContentObjectModel.new_from_json_ld = function (json_ld_data, media_path, ekn_version) {
    let props = ContentObjectModel._props_from_json_ld(json_ld_data, media_path, ekn_version);
    let contentObjectModel = new ContentObjectModel(props);
    ContentObjectModel._setup_from_json_ld(contentObjectModel, json_ld_data, media_path, ekn_version);

    return contentObjectModel;
};

ContentObjectModel._setup_from_json_ld = function (model, json_ld_data, media_path, ekn_version) {
    if (json_ld_data.hasOwnProperty('resources')) {
        model.set_resources(json_ld_data.resources);
    }

    if (json_ld_data.hasOwnProperty('tags')) {
        model.set_resources(json_ld_data.tags);
    }
};

ContentObjectModel._props_from_json_ld = function (json_ld_data, media_path, ekn_version) {
    let props = {};

    if (typeof ekn_version === 'number')
{'fraction_non_alphanumeric': 0.09727681078046041, 'fraction_numerical': 0.0022459292532285235, 'mean_word_length': 2.267043717517579, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2739354', 'n_tokens_mistral': 5810, 'n_tokens_neox': 5709, 'n_words': 1790}