<commit_before>/**
 * Copyright 2015 Longtail Ad Solutions Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 **/

(function () {

    angular
        .module('jwShowcase.core')
        .decorator('$httpBackend', $httpBackendDecorator)
        .service('api', apiService);

    /**
     * @ngdoc service
     * @name jwShowcase.core.api
     *
     * @requires $http
     * @requires $log
     */
    apiService.$inject = ['$http', '$q', 'JW_PLATFORM_URL'];
    function apiService ($http, $q, JW_PLATFORM_URL) {

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} feedId Id of the feed
         * @description
         * Get feed from jw platform
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which will be resolved when the request is completed.
         */
        this.getFeed = function (feedId) {

            // reject when feedId is empty or no string
            if (!angular.isString(feedId) || feedId === '') {
                return $q.reject(new Error('feedId is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feeds/' + feedId + '.json');
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getSearchFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} searchPlaylist Search playlist
         * @param {string} phrase Search phrase
         * @description
         * Get search feed from jw platform with given search phrase
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getSearchFeed = function (searchPlaylist, phrase) {

            // reject when searchPlaylist is missing
            if (!searchPlaylist) {
                return $q.reject(new Error('searchPlaylist is missing'));
            }

            // reject when feedId is empty or no string
            if (!angular.isString(phrase) || phrase === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feed.json?feed_id=' + searchPlaylist + '&search=' + encodeURIComponent(phrase));
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getRecommendationsFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} recommendationsPlaylist Recommendations playlist
         * @param {string} mediaId Id of item to get related items
         * @description
         * Get recommendations feed from jw platform with given mediaId
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getRecommendationsFeed = function (recommendationsPlaylist, mediaId) {

            // reject when recommendationsPlaylist is missing
            if (!recommendationsPlaylist) {
                return $q.reject(new Error('recommendationsPlaylist is missing'));
            }

            // reject when mediaId is empty or no string
            if (!angular.isString(mediaId) || mediaId === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feed.json?feed_id=' + recommendationsPlaylist + '&related_media_id=' + mediaId)
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getPlayer
         * @methodOf jwShowcase.core.api
         *
         * @param {string} playerId Id of the player
         * @description
         * Get JW Player library from jw platform by including the library in the DOM
         *
         * @resolves
         * @returns {Promise} Promise which be resolved when the library is loaded.
         */
        this.getPlayer = function (playerId) {

            var defer  = $q.defer(),
                script = document.createElement('script');

            script.type = 'text/javascript';

            script.onload = function () {
                defer.resolve();
            };

            script.onerror = function () {
                defer.reject(new Error('Player with id `' + playerId + '` could not been loaded'));
            };

            script.src = JW_PLATFORM_URL + '/libraries/' + playerId + '.js';
            document.head.appendChild(script);

            return defer.promise;
        };

        /**
         * Get feed from the given URL.
         *
         * @param {string} url
         * @returns {Promise}
         */
        function getFeed (url) {

            return $http.get(url)
                .then(getFeedCompleted, getFeedFailed);

            function getFeedCompleted (response) {

                var feed = response.data;

                // the search feed can return an empty playlist, so we can show "No results for ..."
                if (feed && 'SEARCH' === feed.kind) {
                    feed.playlist = feed.playlist || [];
                }

                if (!feed || !angular.isArray(feed.playlist)) {
                    return getFeedFailed(response);
                }

                feed.playlist = feed.playlist
                    .map(function (item) {

                        if (!item.feedId) {
                            item.feedid = feed.feedid;
                        }

                        return item;
                    })
                    .map(fixItemUrls);

                return feed;
            }

            function getFeedFailed (response) {

                var message = 'Failed to get feed from `' + url + '`';

                if (404 === response.status) {
                    message = 'Feed with url `' + url + '` does not exist';
                }

                return $q.reject(new Error(message));
            }
        }

        /**
         * Fix urls in item and sources
         *
         * @param {jwShowcase.core.item} [item]
         * @returns {jwShowcase.core.item}
         */
        function fixItemUrls (item) {

            if (!angular.isObject(item)) {
                return item;
            }

            item.image = fixUrl(item.image);

            if (angular.isArray(item.sources)) {
                item.sources = item.sources.map(function (source) {
                    source.file = fixUrl(source.file);
                    return source;
                });
            }

            return item;
        }

        /**
         * Fix url by replacing '//' with 'https://'
         *
         * @param {string} [url]
         * @returns {*}
         */
        function fixUrl (url) {

            if (angular.isString(url) && 0 === url.indexOf('//')) {
                return 'https://' + url.substr(2);
            }

            return url;
        }
    }

    /**
     * @name jwShowcase.core.feed
     * @type Object
     * @property {string}               description    Feed description
     * @property {string}               feedid         Feed id<commit_msg>Update file protocol in tracks<commit_after>/**
 * Copyright 2015 Longtail Ad Solutions Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 **/

(function () {

    angular
        .module('jwShowcase.core')
        .decorator('$httpBackend', $httpBackendDecorator)
        .service('api', apiService);

    /**
     * @ngdoc service
     * @name jwShowcase.core.api
     *
     * @requires $http
     * @requires $log
     */
    apiService.$inject = ['$http', '$q', 'JW_PLATFORM_URL'];
    function apiService ($http, $q, JW_PLATFORM_URL) {

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} feedId Id of the feed
         * @description
         * Get feed from jw platform
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which will be resolved when the request is completed.
         */
        this.getFeed = function (feedId) {

            // reject when feedId is empty or no string
            if (!angular.isString(feedId) || feedId === '') {
                return $q.reject(new Error('feedId is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feeds/' + feedId + '.json');
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getSearchFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} searchPlaylist Search playlist
         * @param {string} phrase Search phrase
         * @description
         * Get search feed from jw platform with given search phrase
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getSearchFeed = function (searchPlaylist, phrase) {

            // reject when searchPlaylist is missing
            if (!searchPlaylist) {
                return $q.reject(new Error('searchPlaylist is missing'));
            }

            // reject when feedId is empty or no string
            if (!angular.isString(phrase) || phrase === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feed.json?feed_id=' + searchPlaylist + '&search=' + encodeURIComponent(phrase));
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getRecommendationsFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} recommendationsPlaylist Recommendations playlist
         * @param {string} mediaId Id of item to get related items
         * @description
         * Get recommendations feed from jw platform with given mediaId
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getRecommendationsFeed = function (recommendationsPlaylist, mediaId) {

            // reject when recommendationsPlaylist is missing
            if (!recommendationsPlaylist) {
                return $q.reject(new Error('recommendationsPlaylist is missing'));
            }

            // reject when mediaId is empty or no string
            if (!angular.isString(mediaId) || mediaId === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(JW_PLATFORM_URL + '/feed.json?feed_id=' + recommendationsPlaylist + '&related_media_id=' + mediaId)
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getPlayer
         * @methodOf jwShowcase.core.api
         *
         * @param {string} playerId Id of the player
         * @description
         * Get JW Player library from jw platform by including the library in the DOM
         *
         * @resolves
         * @returns {Promise} Promise which be resolved when the library is loaded.
         */
        this.getPlayer = function (playerId) {

            var defer  = $q.defer(),
                script = document.createElement('script');

            script.type = 'text/javascript';

            script.onload = function () {
                defer.resolve();
            };

            script.onerror = function () {
                defer.reject(new Error('Player with id `' + playerId + '` could not been loaded'));
            };

            script.src = JW_PLATFORM_URL + '/libraries/' + playerId + '.js';
            document.head.appendChild(script);

            return defer.promise;
        };

        /**
         * Get feed from the given URL.
         *
         * @param {string} url
         * @returns {Promise}
         */
        function getFeed (url) {

            return $http.get(url)
                .then(getFeedCompleted, getFeedFailed);

            function getFeedCompleted (response) {

                var feed = response.data;

                // the search feed can return an empty playlist, so we can show "No results for ..."
                if (feed && 'SEARCH' === feed.kind) {
                    feed.playlist = feed.playlist || [];
                }

                if (!feed || !angular.isArray(feed.playlist)) {
                    return getFeedFailed(response);
                }

                feed.playlist = feed.playlist
                    .map(function (item) {

                        if (!item.feedId) {
                            item.feedid = feed.feedid;
                        }

                        return item;
                    })
                    .map(fixItemUrls);

                return feed;
            }

            function getFeedFailed (response) {

                var message = 'Failed to get feed from `' + url + '`';

                if (404 === response.status) {
                    message = 'Feed with url `' + url + '` does not exist';
                }

                return $q.reject(new Error(message));
            }
        }

        /**
         * Fix urls in item and sources
         *
         * @param {jwShowcase.core.item} [item]
         * @returns {jwShowcase.core.item}
         */
        function fixItemUrls (item) {

            if (!angular.isObject(item)) {
                return item;
            }

            item.image = fixUrl(item.image);

            if (angular.isArray(item.sources)) {
                item.sources = item.sources.map(function (source) {
                    source.file = fixUrl(source.file);
                    return source;
                });
            }

            if (angular.isArray(item.tracks)) {
                item.tracks = item.tracks.map(function (track) {
                    track.file = fixUrl(track.file);
                    return track;
                });
            }

            return item;
        }

        /**
         * Fix url by replacing '//' with 'https://'
         *
         * @param {string} [url]
         * @returns {*}
         */
        function fixUrl (url) {

            if (angular.isString(url) && 0 === url.indexOf('//')) {
                return 'https://' + url.substr(2);
            }

            return url;
        }
    }

    /**
     * @name jwShowcase.core.feed
     * @type Object
     * @property {string}               description    Feed description
     * @property {string}               feedid         Feed id
{'fraction_non_alphanumeric': 0.10500127583567237, 'fraction_numerical': 0.001658586374075019, 'mean_word_length': 1.546621182586095, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '903945', 'n_tokens_mistral': 4205, 'n_tokens_neox': 4003, 'n_words': 1152}