<commit_before>/**
 * Copyright 2015 CANAL+ Group
 *
 * 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.
 */

import { Observable } from "rxjs/Observable";
import { bytesToStr } from "../../../utils/bytes";
import log from "../../../utils/log";
import { resolveURL } from "../../../utils/url";

import request from "../../../utils/request";
import createSmoothStreamingParser from "./parser";

import mp4Utils from "./mp4.js";
import { parseBif } from "../../parsers/bif";
import { parseSami } from "../../parsers/texttracks/sami.js";
import { parseTTML } from "../../parsers/texttracks/ttml.js";

const {
  patchSegment,
  createVideoInitSegment,
  createAudioInitSegment,
  getMdat,
  getTraf,
  parseTfrf,
  parseTfxd,
} = mp4Utils;

const TT_PARSERS = {
  "application/x-sami":       parseSami,
  "application/smil":         parseSami,
  "application/ttml+xml":     parseTTML,
  "application/ttml+xml+mp4": parseTTML,
  "text/vtt":                 (text) => text,
};

const ISM_REG = /\.(isml?)(\?token=\S+)?$/;
const WSX_REG = /\.wsx?(\?token=\S+)?/;
const TOKEN_REG = /\?token=(\S+)/;

function byteRange([start, end]) {
  if (!end || end === Infinity) {
    return "bytes=" + (+start) + "-";
  } else {
    return "bytes=" + (+start) + "-" + (+end);
  }
}

function extractISML({ responseData }) {
  return responseData.getElementsByTagName("media")[0].getAttribute("src");
}

/**
 * Returns string corresponding to the token contained in the url's querystring.
 * Empty string if no token is found.
 * @param {string} url
 * @returns {string}
 */
function extractToken(url) {
  const tokenMatch = url.match(TOKEN_REG);
  return (tokenMatch && tokenMatch[1]) || "";
}

/**
 * Replace/Remove token from the url's querystring
 * @param {string} url
 * @param {string} [token]
 * @returns {string}
 */
function replaceToken(url, token) {
  if (token) {
    return url.replace(TOKEN_REG, "?token=" + token);
  } else {
    return url.replace(TOKEN_REG, "");
  }
}

function resolveManifest(url) {
  const ismMatch = url.match(ISM_REG);
  if (ismMatch) {
    return url.replace(ismMatch[1], ismMatch[1] + "/manifest");
  } else {
    return url;
  }
}

function buildSegmentURL(url, representation, segment) {
  return url
    .replace(/\{bitrate\}/g,    representation.bitrate)
    .replace(/\{start time\}/g, segment.time);
}

function mapRequestResponses({ type, value }) {
  if (type === "response") {
    return {
      type: "response",
      value: {
        responseData: value.responseData,
        size: value.size,
        duration: value.receivedTime - value.sentTime,
        url: value.url,
      },
    };
  }

  return {
    type: "progress",
    value: {
      size: value.loadedSize,
      totalSize: value.totalSize,
      duration: value.currentTime - value.sentTime,
      url: value.url,
    },
  };
}

const parsedRequest = requestData =>
  request(requestData).map(mapRequestResponses);

export default function(options={}) {
  const smoothManifestParser = createSmoothStreamingParser(options);

  const manifestPipeline = {
    resolver({ url }) {
      let resolving;
      const token = extractToken(url);

      if (WSX_REG.test(url)) {
        resolving = request({
          url: replaceToken(url, ""),
          responseType: "document",
          resultSelector: extractISML, // XXX to does not work for now
          ignoreProgressEvents: true,
        }).map(({ value }) => value);
      }
      else {<commit_msg>smooth: fix isml extraction with the new request lib<commit_after>/**
 * Copyright 2015 CANAL+ Group
 *
 * 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.
 */

import { Observable } from "rxjs/Observable";
import { bytesToStr } from "../../../utils/bytes";
import log from "../../../utils/log";
import { resolveURL } from "../../../utils/url";

import request from "../../../utils/request";
import createSmoothStreamingParser from "./parser";

import mp4Utils from "./mp4.js";
import { parseBif } from "../../parsers/bif";
import { parseSami } from "../../parsers/texttracks/sami.js";
import { parseTTML } from "../../parsers/texttracks/ttml.js";

const {
  patchSegment,
  createVideoInitSegment,
  createAudioInitSegment,
  getMdat,
  getTraf,
  parseTfrf,
  parseTfxd,
} = mp4Utils;

const TT_PARSERS = {
  "application/x-sami":       parseSami,
  "application/smil":         parseSami,
  "application/ttml+xml":     parseTTML,
  "application/ttml+xml+mp4": parseTTML,
  "text/vtt":                 (text) => text,
};

const ISM_REG = /\.(isml?)(\?token=\S+)?$/;
const WSX_REG = /\.wsx?(\?token=\S+)?/;
const TOKEN_REG = /\?token=(\S+)/;

function byteRange([start, end]) {
  if (!end || end === Infinity) {
    return "bytes=" + (+start) + "-";
  } else {
    return "bytes=" + (+start) + "-" + (+end);
  }
}

/**
 * TODO Remove this logic completely from the player
 */
function extractISML({ responseData }) {
  return responseData.getElementsByTagName("media")[0].getAttribute("src");
}

/**
 * Returns string corresponding to the token contained in the url's querystring.
 * Empty string if no token is found.
 * @param {string} url
 * @returns {string}
 */
function extractToken(url) {
  const tokenMatch = url.match(TOKEN_REG);
  return (tokenMatch && tokenMatch[1]) || "";
}

/**
 * Replace/Remove token from the url's querystring
 * @param {string} url
 * @param {string} [token]
 * @returns {string}
 */
function replaceToken(url, token) {
  if (token) {
    return url.replace(TOKEN_REG, "?token=" + token);
  } else {
    return url.replace(TOKEN_REG, "");
  }
}

function resolveManifest(url) {
  const ismMatch = url.match(ISM_REG);
  if (ismMatch) {
    return url.replace(ismMatch[1], ismMatch[1] + "/manifest");
  } else {
    return url;
  }
}

function buildSegmentURL(url, representation, segment) {
  return url
    .replace(/\{bitrate\}/g,    representation.bitrate)
    .replace(/\{start time\}/g, segment.time);
}

function mapRequestResponses({ type, value }) {
  if (type === "response") {
    return {
      type: "response",
      value: {
        responseData: value.responseData,
        size: value.size,
        duration: value.receivedTime - value.sentTime,
        url: value.url,
      },
    };
  }

  return {
    type: "progress",
    value: {
      size: value.loadedSize,
      totalSize: value.totalSize,
      duration: value.currentTime - value.sentTime,
      url: value.url,
    },
  };
}

const parsedRequest = requestData =>
  request(requestData).map(mapRequestResponses);

export default function(options={}) {
  const smoothManifestParser = createSmoothStreamingParser(options);

  const manifestPipeline = {
    resolver({ url }) {
      let resolving;
      const token = extractToken(url);

      if (WSX_REG.test(url)) {
        resolving = request({
          url: replaceToken(url, ""),
          responseType: "document",
          ignoreProgressEvents: true,
        })
          .map(extractISML) // TODO test that or remove completely
          .map(({ value }) => value);
      }
      else {
{'fraction_non_alphanumeric': 0.15075502308748284, 'fraction_numerical': 0.003993510545363784, 'mean_word_length': 3.055668016194332, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, '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': '6324466', 'n_tokens_mistral': 2519, 'n_tokens_neox': 2484, 'n_words': 676}