<commit_before>/*
 * Copyright (C) 2008 <NAME> <<EMAIL>>.
 * Copyright (C) 2008 Nokia Corporation.
 * Copyright (C) 2012,2013 Intel Corporation.
 * Copyright (C) 2015 <NAME>
 *
 * Author: <NAME> <<EMAIL>>
 *         <NAME> <<EMAIL>>
 *         <NAME> <<EMAIL>>
 *
 * This file is part of Rygel.
 *
 * Rygel is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Rygel is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

using GUPnP;
using Gst;
using Gst.PbUtils;

/**
 * Represents MediaExport item.
 */
namespace Rygel.MediaExport.ItemFactory {
    internal errordomain ItemFactoryError {
        DESERIALIZATION,
        MISMATCH
    }

    private const string INVALID_CHARS = "()[]<>{}!@#$^&*+=|\\/\"'?~";
    private const string CONVERT_CHARS = "\t_\\.";
    private const string BLOCK_PATTERN = "%s[^%s]*%s";
    private const string[] BLOCKS = { "()", "{}", "[]", "<>" };
    private const string[] BLACKLIST = {
        "720p", "1080p", "x264", "ws", "proper", "real.repack", "repack",
        "hdtv", "pdtv", "notv", "dsr", "DVDRip", "divx", "xvid"
    };

    private const string[] VIDEO_SUFFIXES = {
        "webm", "mkv", "flv", "ogv", "ogg", "avi", "mov", "wmv", "mp4",
        "m4v", "mpeg", "mpg", "iso"
    };

    private static Regex char_remove_regex;
    private static Regex char_convert_regex;
    private static Regex space_compress_regex;
    private static Regex[] block_regexes;
    private static Regex[] blacklist_regexes;
    private static Regex[] video_suffix_regexes;

    private static bool check_variant_type (Variant v,
                                            string typestring) throws Error {
        if (!v.is_of_type (new VariantType (typestring))) {
            var msg = "Variant type mismatch, expected %s, got %s";
            throw new ItemFactoryError.DESERIALIZATION (msg,
                                                        v.get_type_string (),
                                                        typestring);
        }

        return true;
    }

    private static MediaFileItem? create_playlist_item (File file,
                                                        MediaContainer parent,
                                                        string fallback_title) {
        try {
            uint8[] contents;

            if (!file.load_contents (null, out contents, null)) {
                return null;
            }

            /* Do some heuristic check if this file looks like XML */
            var i = 0;
            while (((char) contents[i]).isspace () && i < contents.length) {
                i++;
            }

            if (contents[i] != '<') {
                return null;
            }

            var didl_s = new MediaCollection.from_string ((string) contents);
            var author = didl_s.author;
            var title = didl_s.title;

            if (author == null &&
                title == null &&
                didl_s.get_items () == null) {
                return null;
            }

            if (title == null) {
                title = fallback_title;
            }

            var item = new PlaylistItem (MediaCache.get_id (file),
                                         parent,
                                         title);

            if (author != null) {
                item.creator = author;
            }

            item.dlna_profile = "DIDL_S";

            return item;
        } catch (Error e) {
            return null;
        }
    }

    static MediaObject? create_from_variant (MediaContainer parent,
                                             File           file,
                                             Variant?       v)
                                             throws Error {

        if (v == null) {
            return null;
        }

        ItemFactory.check_variant_type (v,"(smvmvmvmvmvmv)");

        Variant? upnp_class,
                 file_info,
                 dlna_profile,
                 info,
                 video_info,
                 audio_info,
                 meta_data;

        var it = v.iterator ();

        var id = MediaCache.get_id (file);

        upnp_class = it.next_value ();

        file_info = it.next_value ().get_maybe ();
        if (file_info != null) {
            file_info = file_info.get_variant ();
        }

        dlna_profile = it.next_value ().get_maybe ();
        if (dlna_profile != null) {
            dlna_profile = dlna_profile.get_variant ();
        }

        info = it.next_value ().get_maybe ();
        if (info != null) {
            info = info.get_variant ();
        }

        audio_info = it.next_value ().get_maybe ();
        if (audio_info != null) {
            audio_info = audio_info.get_variant ();
        }

        video_info = it.next_value ().get_maybe ();
        if (video_info != null) {
            video_info = video_info.get_variant ();
        }

        meta_data = it.next_value ().get_maybe ();
        if (meta_data != null) {
            meta_data = meta_data.get_variant ();
        }

        MediaFileItem item = null;
        MediaObject object = null;
        switch (upnp_class.get_string ()) {
            case Rygel.PhotoItem.UPNP_CLASS:
                item = new PhotoItem (id, parent, "");
                break;
            case Rygel.VideoItem.UPNP_CLASS:
                item = new VideoItem (id, parent, "");
                break;
            case Rygel.MusicItem.UPNP_CLASS:
                item = new MusicItem (id, parent, "");
                break;
            case Rygel.PlaylistItem.UPNP_CLASS:
                item = ItemFactory.create_playlist_item (file, parent, "");
                break;
            case DVDContainer.UPNP_CLASS:
                var container = new DVDContainer ("dvd:" + id, parent, "", file.get_path ());
                object = container;

                if (file_info != null) {
                    apply_file_info (object, file_info);
                    object.title = strip_invalid_entities (object.title);
                }

                // If the DVD has a single track, just export that as a plain<commit_msg>media-export: Prevent criticals if playlist creation failed<commit_after>/*
 * Copyright (C) 2008 <NAME> <<EMAIL>>.
 * Copyright (C) 2008 Nokia Corporation.
 * Copyright (C) 2012,2013 Intel Corporation.
 * Copyright (C) 2015 <NAME>
 *
 * Author: <NAME> <<EMAIL>>
 *         <NAME> <<EMAIL>>
 *         <NAME> <<EMAIL>>
 *
 * This file is part of Rygel.
 *
 * Rygel is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Rygel is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

using GUPnP;
using Gst;
using Gst.PbUtils;

/**
 * Represents MediaExport item.
 */
namespace Rygel.MediaExport.ItemFactory {
    internal errordomain ItemFactoryError {
        DESERIALIZATION,
        MISMATCH
    }

    private const string INVALID_CHARS = "()[]<>{}!@#$^&*+=|\\/\"'?~";
    private const string CONVERT_CHARS = "\t_\\.";
    private const string BLOCK_PATTERN = "%s[^%s]*%s";
    private const string[] BLOCKS = { "()", "{}", "[]", "<>" };
    private const string[] BLACKLIST = {
        "720p", "1080p", "x264", "ws", "proper", "real.repack", "repack",
        "hdtv", "pdtv", "notv", "dsr", "DVDRip", "divx", "xvid"
    };

    private const string[] VIDEO_SUFFIXES = {
        "webm", "mkv", "flv", "ogv", "ogg", "avi", "mov", "wmv", "mp4",
        "m4v", "mpeg", "mpg", "iso"
    };

    private static Regex char_remove_regex;
    private static Regex char_convert_regex;
    private static Regex space_compress_regex;
    private static Regex[] block_regexes;
    private static Regex[] blacklist_regexes;
    private static Regex[] video_suffix_regexes;

    private static bool check_variant_type (Variant v,
                                            string typestring) throws Error {
        if (!v.is_of_type (new VariantType (typestring))) {
            var msg = "Variant type mismatch, expected %s, got %s";
            throw new ItemFactoryError.DESERIALIZATION (msg,
                                                        v.get_type_string (),
                                                        typestring);
        }

        return true;
    }

    private static MediaFileItem? create_playlist_item (File file,
                                                        MediaContainer parent,
                                                        string fallback_title) {
        try {
            uint8[] contents;

            if (!file.load_contents (null, out contents, null)) {
                return null;
            }

            /* Do some heuristic check if this file looks like XML */
            var i = 0;
            while (((char) contents[i]).isspace () && i < contents.length) {
                i++;
            }

            if (contents[i] != '<') {
                return null;
            }

            var didl_s = new MediaCollection.from_string ((string) contents);
            var author = didl_s.author;
            var title = didl_s.title;

            if (author == null &&
                title == null &&
                didl_s.get_items () == null) {
                return null;
            }

            if (title == null) {
                title = fallback_title;
            }

            var item = new PlaylistItem (MediaCache.get_id (file),
                                         parent,
                                         title);

            if (author != null) {
                item.creator = author;
            }

            item.dlna_profile = "DIDL_S";

            return item;
        } catch (Error e) {
            return null;
        }
    }

    static MediaObject? create_from_variant (MediaContainer parent,
                                             File           file,
                                             Variant?       v)
                                             throws Error {

        if (v == null) {
            return null;
        }

        ItemFactory.check_variant_type (v,"(smvmvmvmvmvmv)");

        Variant? upnp_class,
                 file_info,
                 dlna_profile,
                 info,
                 video_info,
                 audio_info,
                 meta_data;

        var it = v.iterator ();

        var id = MediaCache.get_id (file);

        upnp_class = it.next_value ();

        file_info = it.next_value ().get_maybe ();
        if (file_info != null) {
            file_info = file_info.get_variant ();
        }

        dlna_profile = it.next_value ().get_maybe ();
        if (dlna_profile != null) {
            dlna_profile = dlna_profile.get_variant ();
        }

        info = it.next_value ().get_maybe ();
        if (info != null) {
            info = info.get_variant ();
        }

        audio_info = it.next_value ().get_maybe ();
        if (audio_info != null) {
            audio_info = audio_info.get_variant ();
        }

        video_info = it.next_value ().get_maybe ();
        if (video_info != null) {
            video_info = video_info.get_variant ();
        }

        meta_data = it.next_value ().get_maybe ();
        if (meta_data != null) {
            meta_data = meta_data.get_variant ();
        }

        MediaFileItem item = null;
        MediaObject object = null;
        switch (upnp_class.get_string ()) {
            case Rygel.PhotoItem.UPNP_CLASS:
                item = new PhotoItem (id, parent, "");
                break;
            case Rygel.VideoItem.UPNP_CLASS:
                item = new VideoItem (id, parent, "");
                break;
            case Rygel.MusicItem.UPNP_CLASS:
                item = new MusicItem (id, parent, "");
                break;
            case Rygel.PlaylistItem.UPNP_CLASS:
                item = ItemFactory.create_playlist_item (file, parent, "");
                if (item == null) {
                    return null;
                }
                break;
            case DVDContainer.UPNP_CLASS:
                var container = new DVDContainer ("dvd:" + id, parent, "", file.get_path ());
                object = container;

                if (file_info != null) {
                    apply_file_info (object, file_info);
                    object.title = strip_invalid_entities (object.title);
                }

                // If the DVD has a single track, just export that as a plain
{'fraction_non_alphanumeric': 0.1045938993017273, 'fraction_numerical': 0.006909224549797868, 'mean_word_length': 1.5224323322209863, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6887863', 'n_tokens_mistral': 3791, 'n_tokens_neox': 3562, 'n_words': 1050}