<commit_before>console.log( __dirname );

const express = require('express'),
      fs = require('fs'),
      path = require('path'),
      app = express.createServer(),
      MongoStore = require('connect-mongo')(express),
      stylus = require('stylus'),
      CONFIG = require('config'),
      TEMPLATES_DIR =  CONFIG.dirs.templates,
      PUBLISH_DIR = CONFIG.dirs.publish,
      PUBLISH_PREFIX = CONFIG.dirs.hostname,
      WWW_ROOT = path.resolve( CONFIG.dirs.wwwRoot || path.join( __dirname, ".." ) ),
      VALID_TEMPLATES = CONFIG.templates,
      EXPORT_ASSETS = CONFIG.exportAssets;

var canStoreData = true;

console.log( "Templates Dir:", TEMPLATES_DIR );
console.log( "Publish Dir:", PUBLISH_DIR );

var mongoose = require('mongoose'),
    db = mongoose.connect('mongodb://localhost/test', function( err ) {
      if ( err ) {
        console.error( "MongoDB: " + err + "\n  You will not be able to store any data." );
        canStoreData = false;
      }
    }),
    Schema = mongoose.Schema,

    Project = new Schema({
      name: String,
      html: String,
      data: String,
      template: String,
      customData: String
    }),
    ProjectModel = mongoose.model( 'Project', Project ),

    User = new Schema({
      email: String,
      projects: [Project],
    }),
    UserModel = mongoose.model( 'User', User );

CONFIG.session.store = new MongoStore({ db: "test" });

if ( !path.existsSync( PUBLISH_DIR ) ) {
  fs.mkdirSync( PUBLISH_DIR );
}

app.use(express.logger(CONFIG.logger))
  .use(express.bodyParser())
  .use(express.cookieParser())
  .use( express.session( CONFIG.session ) )
  .use(stylus.middleware({
    src: WWW_ROOT
  }))
  .use(express.static( WWW_ROOT ))
  .use(express.static( PUBLISH_DIR ))
  .use(express.directory( WWW_ROOT, { icons: true } ) );

require('express-browserid').plugAll(app);

function publishRoute( req, res ){
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var i;
    if ( err ) {
      res.json({ error: 'internal db error' }, 500);
      return;
    }

    if ( !doc ) {
      res.json({ error: 'user not found' }, 500);
      return;
    }

    var project;
    for ( i=0; i<doc.projects.length; ++i ) {
      if ( String( doc.projects[ i ]._id ) === id ) {
        project = doc.projects[ i ];
        break;
      }
    }

    if ( project ) {
      var template = project.template,
          customData = project.customData;

      if ( template && VALID_TEMPLATES[ template ] ) {
        var projectPath = PUBLISH_DIR + "/" + id + ".html",
            url = PUBLISH_PREFIX + "/" + id + ".html",
            projectData = JSON.parse( project.data ),
            templateBase = VALID_TEMPLATES[ template ].replace( '{{templateBase}}', TEMPLATES_DIR + '/' );

        fs.readFile( templateBase, 'utf8', function(err, conf){
          var templateConfig = JSON.parse( conf ),
              templateFile = path.resolve( templateBase, '..', templateConfig.template );

          fs.readFile( templateFile, 'utf8', function( err, data ){
            var headEndTagIndex,
                bodyEndTagIndex,
                externalAssetsString = '',
                popcornString = '',
                currentMedia,
                currentTrack,
                currentTrackEvent,
                mediaPopcornOptions,
                templateURL,
                baseString,
                headStartTagIndex,
                templateScripts,
                startString,
                j, k;

            templateURL = templateFile.substring( templateFile.indexOf( '/templates' ), templateFile.lastIndexOf( '/' ) );
            baseString = '\n  <base href="' + PUBLISH_PREFIX + templateURL + '/"/>';

            // look for script tags with data-butter-exclude in particular (e.g. butter's js script)
            data = data.replace( /\s*<script[\.\/='":_-\w\s]*data-butter-exclude[\.\/='":_-\w\s]*><\/script>/g, '' );

            // Adding 6 to cut out the actual head tag
            headStartTagIndex = data.indexOf( '<head>' ) + 6;
            headEndTagIndex = data.indexOf( '</head>' );
            bodyEndTagIndex = data.indexOf( '</body>' );

            templateScripts = data.substring( headStartTagIndex, headEndTagIndex );
            startString = data.substring( 0, headStartTagIndex );

            for ( i = 0; i < EXPORT_ASSETS.length; ++i ) {
              externalAssetsString += '\n  <script src="' + path.relative( templateFile, path.resolve( EXPORT_ASSETS[ i ] ) ) + '"></script>\n';
            }

            // If the template has custom plugins defined in it's config, add them to our exported page
            if ( templateConfig.plugin && templateConfig.plugin.plugins ) {
              var plugins = templateConfig.plugin.plugins;

              for ( i = 0, len = plugins.length; i < len; i++ ) {
                externalAssetsString += '\n  <script src="' + PUBLISH_PREFIX + '/' + plugins[ i ].path.split( '{{baseDir}}' ).pop() + '"></script>';
              }
              externalAssetsString += '\n';
            }

            popcornString += '<script>'

            for ( i = 0; i < projectData.media.length; ++i ) {
              var mediaUrls = '[ "',
                  numSources;
              currentMedia = projectData.media[ i ];
              mediaPopcornOptions = currentMedia.popcornOptions || {};
              numSources = currentMedia.url.length;
              
              for ( k = 0; k < numSources - 1; k++ ) {
                mediaUrls += currentMedia.url[ k ] + '" , "';
              }
              mediaUrls += currentMedia.url[ numSources - 1 ] + '" ]';

              popcornString += '\n(function(){';
              popcornString += '\nvar popcorn = Popcorn.smart("#' + currentMedia.target + '", ' + mediaUrls + ', ' + JSON.stringify( mediaPopcornOptions ) + ');';
              for ( j = 0; j < currentMedia.tracks.length; ++ j ) {
                currentTrack = currentMedia.tracks[ j ];
                for ( k = 0; k < currentTrack.trackEvents.length; ++k ) {
                  currentTrackEvent = currentTrack.trackEvents[ k ];
                  popcornString += '\npopcorn.' + currentTrackEvent.type + '(';
                  popcornString += JSON.stringify( currentTrackEvent.popcornOptions, null, 2 );
                  popcornString += ');';
                }
              }
              popcornString += '}());\n';
            }<commit_msg>[t1577] Deal with string vs. array for media URLs in export<commit_after>console.log( __dirname );

const express = require('express'),
      fs = require('fs'),
      path = require('path'),
      app = express.createServer(),
      MongoStore = require('connect-mongo')(express),
      stylus = require('stylus'),
      CONFIG = require('config'),
      TEMPLATES_DIR =  CONFIG.dirs.templates,
      PUBLISH_DIR = CONFIG.dirs.publish,
      PUBLISH_PREFIX = CONFIG.dirs.hostname,
      WWW_ROOT = path.resolve( CONFIG.dirs.wwwRoot || path.join( __dirname, ".." ) ),
      VALID_TEMPLATES = CONFIG.templates,
      EXPORT_ASSETS = CONFIG.exportAssets;

var canStoreData = true;

console.log( "Templates Dir:", TEMPLATES_DIR );
console.log( "Publish Dir:", PUBLISH_DIR );

var mongoose = require('mongoose'),
    db = mongoose.connect('mongodb://localhost/test', function( err ) {
      if ( err ) {
        console.error( "MongoDB: " + err + "\n  You will not be able to store any data." );
        canStoreData = false;
      }
    }),
    Schema = mongoose.Schema,

    Project = new Schema({
      name: String,
      html: String,
      data: String,
      template: String,
      customData: String
    }),
    ProjectModel = mongoose.model( 'Project', Project ),

    User = new Schema({
      email: String,
      projects: [Project],
    }),
    UserModel = mongoose.model( 'User', User );

CONFIG.session.store = new MongoStore({ db: "test" });

if ( !path.existsSync( PUBLISH_DIR ) ) {
  fs.mkdirSync( PUBLISH_DIR );
}

app.use(express.logger(CONFIG.logger))
  .use(express.bodyParser())
  .use(express.cookieParser())
  .use( express.session( CONFIG.session ) )
  .use(stylus.middleware({
    src: WWW_ROOT
  }))
  .use(express.static( WWW_ROOT ))
  .use(express.static( PUBLISH_DIR ))
  .use(express.directory( WWW_ROOT, { icons: true } ) );

require('express-browserid').plugAll(app);

function publishRoute( req, res ){
  var email = req.session.email,
      id = req.params.id;

  if (!email) {
    res.json({ error: 'unauthorized' }, 403);
    return;
  }

  if (!canStoreData) {
    res.json({ error: 'storage service is not running' }, 500);
    return;
  }

  UserModel.findOne( { email: email }, function( err, doc ) {
    var i;
    if ( err ) {
      res.json({ error: 'internal db error' }, 500);
      return;
    }

    if ( !doc ) {
      res.json({ error: 'user not found' }, 500);
      return;
    }

    var project;
    for ( i=0; i<doc.projects.length; ++i ) {
      if ( String( doc.projects[ i ]._id ) === id ) {
        project = doc.projects[ i ];
        break;
      }
    }

    if ( project ) {
      var template = project.template,
          customData = project.customData;

      if ( template && VALID_TEMPLATES[ template ] ) {
        var projectPath = PUBLISH_DIR + "/" + id + ".html",
            url = PUBLISH_PREFIX + "/" + id + ".html",
            projectData = JSON.parse( project.data ),
            templateBase = VALID_TEMPLATES[ template ].replace( '{{templateBase}}', TEMPLATES_DIR + '/' );

        fs.readFile( templateBase, 'utf8', function(err, conf){
          var templateConfig = JSON.parse( conf ),
              templateFile = path.resolve( templateBase, '..', templateConfig.template );

          fs.readFile( templateFile, 'utf8', function( err, data ){
            var headEndTagIndex,
                bodyEndTagIndex,
                externalAssetsString = '',
                popcornString = '',
                currentMedia,
                currentTrack,
                currentTrackEvent,
                mediaPopcornOptions,
                templateURL,
                baseString,
                headStartTagIndex,
                templateScripts,
                startString,
                j, k;

            templateURL = templateFile.substring( templateFile.indexOf( '/templates' ), templateFile.lastIndexOf( '/' ) );
            baseString = '\n  <base href="' + PUBLISH_PREFIX + templateURL + '/"/>';

            // look for script tags with data-butter-exclude in particular (e.g. butter's js script)
            data = data.replace( /\s*<script[\.\/='":_-\w\s]*data-butter-exclude[\.\/='":_-\w\s]*><\/script>/g, '' );

            // Adding 6 to cut out the actual head tag
            headStartTagIndex = data.indexOf( '<head>' ) + 6;
            headEndTagIndex = data.indexOf( '</head>' );
            bodyEndTagIndex = data.indexOf( '</body>' );

            templateScripts = data.substring( headStartTagIndex, headEndTagIndex );
            startString = data.substring( 0, headStartTagIndex );

            for ( i = 0; i < EXPORT_ASSETS.length; ++i ) {
              externalAssetsString += '\n  <script src="' + path.relative( templateFile, path.resolve( EXPORT_ASSETS[ i ] ) ) + '"></script>\n';
            }

            // If the template has custom plugins defined in it's config, add them to our exported page
            if ( templateConfig.plugin && templateConfig.plugin.plugins ) {
              var plugins = templateConfig.plugin.plugins;

              for ( i = 0, len = plugins.length; i < len; i++ ) {
                externalAssetsString += '\n  <script src="' + PUBLISH_PREFIX + '/' + plugins[ i ].path.split( '{{baseDir}}' ).pop() + '"></script>';
              }
              externalAssetsString += '\n';
            }

            popcornString += '<script>';

            for ( i = 0; i < projectData.media.length; ++i ) {
              var mediaUrls,
                  mediaUrlsString = '[ "';

              currentMedia = projectData.media[ i ];
              // We expect a string (one url) or an array of url strings.
              // Turn a single url into an array of 1 string.
              mediaUrls = typeof currentMedia.url === "string" ? [ currentMedia.url ] : currentMedia.url;
              mediaPopcornOptions = currentMedia.popcornOptions || {};
              numSources = mediaUrls.length;

              for ( k = 0; k < numSources - 1; k++ ) {
                mediaUrlsString += mediaUrls[ k ] + '" , "';
              }
              mediaUrlsString += mediaUrls[ numSources - 1 ] + '" ]';

              popcornString += '\n(function(){';
              popcornString += '\nvar popcorn = Popcorn.smart("#' + currentMedia.target + '", ' +
                               mediaUrlsString + ', ' + JSON.stringify( mediaPopcornOptions ) + ');';
              for ( j = 0; j < currentMedia.tracks.length; ++ j ) {
                currentTrack = currentMedia.tracks[ j ];
                for ( k = 0; k < currentTrack.trackEvents.length; ++k ) {
                  currentTrackEvent = currentTrack.trackEvents[ k ];
                  popcornString += '\npopcorn.' + currentTrackEvent.type + '(';
                  popcornString += JSON.stringify( currentTrackEvent.popcornOptions, null, 2 );
                  popcornString += ');';
                }
              }
              popcornString += '}());\n';
            }
{'fraction_non_alphanumeric': 0.1428361390869661, 'fraction_numerical': 0.004337278541498199, 'mean_word_length': 2.0030905077262693, 'pattern_counts': {'":': 4, '<': 39, '<?xml version=': 0, '>': 25, 'https://': 0, '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': '1726541', 'n_tokens_mistral': 4139, 'n_tokens_neox': 3878, 'n_words': 920}