<commit_before>export { AsyncWorker_Proxy as Proxy };

import * as Pool from "../Pool.js";
import * as Recyclable from "../Recyclable.js";
import { PromiseResolveReject } from "./AsyncWorker_PromiseResolveReject.js";
import { processingId_Resulter_Map } from "./AsyncWorker_processingId_Resulter_Map.js";
import { Resulter } from "./AsyncWorker_Resulter.js";

/**
 * Hold the worker and its related promise map. It is a wrapper of a neural network
 * web worker for handling and communicating easily.
 *
 * @member {string} workerURL
 *   The worker's source codes URL.
 *
 * @member {Worker} worker
 *   The worker.
 *
 * @member {number} processingId_next
 *   The next processing id. Zero means no command has been sent. Every
 * postCommand_and_expectResult() call will use a new id.
 *
 * @member {processingId_Resulter_Map} the_processingId_Resulter_Map
 *   Every worker has a result pending promise map. The key of the map is processing
 * id. The value of the map is a AsyncWorker.Resulter.
 *
 */
class AsyncWorker_Proxy extends Recyclable.Root {

  /**
   * Used as default AsyncWorker.Proxy provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "AsyncWorker.Proxy.Pool",
    AsyncWorker_Proxy, AsyncWorker_Proxy.setAsConstructor );

  /** */
  constructor( workerURL ) {
    super();
    AsyncWorker_Proxy.setAsConstructor_self.call( this, workerURL );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    AsyncWorker_Proxy.setAsConstructor_self.call( this, workerURL );
    return this;
  }

  /** @override */
  static setAsConstructor_self( workerURL ) {

    // Q: What if processingId become too large (e.g. infinity)?
    // A: Because Number.MAX_SAFE_INTEGER is pretty large (at least, 2 ** 52 ),
    //    it is not so easy to become out of bounds.
    //
    this.processingId_next = 0;

    if ( this.the_processingId_Resulter_Map )
      this.the_processingId_Resulter_Map.clear();
    else
      this.the_processingId_Resulter_Map = new processingId_Resulter_Map();

    AsyncWorker_Proxy.createWorker.call( this, workerURL );
  }

  /** @override */
  disposeResources() {

    if ( this.worker ) {
      // Note: No processingId, because this command needs not return value.
      this.postCommandArgs( "disposeResources" );
      this.worker = null;
    }

    this.workerOptions = undefined;
    this.workerURL = workerURL;

    this.the_processingId_Resulter_Map.clear();

    this.processingId_next = undefined;

    super.disposeResources();
  }

  /**
   * @param {AsyncWorker_Proxy} this
   *   The worker proxy.
   */
  static createWorker( workerURL ) {

//!!! ...unfinished... (2022/09/13)
// Perhaps, use a data uri contains the following source codes as workerURL:
//
// ( async () => {
//   await import( worker_body_relative_path );
// } )();
//
//

  let workerDataURI;
  {
    let codes = ``
      + `import( "${workerURL}" );`
      + `onmessage = ( e ) => {`
      + `  console.log( "Hello" );`
      + `  console.log( e );`
      + `};`
      ;

    workerDataURI
      = AsyncWorker_Proxy.createDataURI_byStringASCII( "text/javascript", codes );
  }
  this.workerURL = workerDataURI;

//!!! (2022/09/13 Temp Remarked) Test workerDataURI
//    this.workerURL = workerURL;

    // Should not use "module" type worker, otherwise the worker can not use
    // importScripts() to load tensorflow.js library.
    //
    //this.workerOptions = { type: "module" }; // So that the worker script could use import statement.
    this.workerOptions = null;

    this.worker = new Worker( this.workerURL, this.workerOptions );

    // Register callback from the web worker.
    this.worker.onmessage = AsyncWorker_Proxy.onmessage_from_AsyncWorker_Body.bind( this );
  }

  /**
   * @param {string} strMimeType  The result mime type of the data URI.
   * @param {string} strASCII     The ASCII text to be embedded in data URI.
   *
   * @return {string} Return the data URI string.
   */
  static createDataURI_byStringASCII( strMimeType, strASCII ) {
    // let textEncoder = new TextEncoder();
    // let str_utf8 = textEncoder.encode( str );
    // let str_base64 = btoa( str_utf8 );
    let str_base64 = btoa( strASCII );
    let dataURI = `data:${strMimeType};base64,${str_base64}`;
    return dataURI;
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * and expect the final result.
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   *   - The command is a string which is the WorkerBody's method function to be
   *       called.
   *
   *   - The args is an array which will be destructured into multiple argements
   *       and passed into the WorkerBody's method function.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   *
   * @return {Promise}
   *   Return a promise resolved to the final value of the processing's resulter
   * from WorkerBody. (i.e. Only the Xxx of { done: true, value: Xxx } resolved.
   * All other intermediate result { done: false, value: Yyy } are discarded.)
   */
  createPromise_by_postCommandArgs( commandArgs, transferableObjectArray ) {
    let resulter = this.createResulter_by_postCommandArgs(
      commandArgs, transferableObjectArray );
    return resulter.untilDone();
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * and expect result.
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   *   - The command is a string which is the WorkerBody's method function to be
   *       called.
   *
   *   - The args is an array which will be destructured into multiple argements
   *       and passed into the WorkerBody's method function.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   *
   * @return {AsyncWorker.Resulter}
   *   Return an async generator for receving result from WorkerBody of the processing.
   */
  createResulter_by_postCommandArgs( commandArgs, transferableObjectArray ) {
    let processingId = this.processingId_next;
    ++this.processingId_next;

    // Prepare the processing's result's receiving queue before sending it.
    let resulter = this.the_processingId_Resulter_Map.createResulter_by_processingId(
      processingId );

    this.worker.postMessage( commandArgs, transferableObjectArray );
    return resulter;
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * without expecting result. (i.e. fire-and-forget)
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   */
  postCommandArgs( commandArgs, transferableObjectArray ) {
    this.worker.postMessage( commandArgs, transferableObjectArray );
  }

  /**
   * Dispatch messages come from the owned web worker. Please register this method
   * as this WorkerProxy's Worker.onmessage.
   *
   * @param {AsyncWorker_Proxy} this
   *   The "this" should be binded to this AsyncWorker_Proxy object.
   */
  static onmessage_from_AsyncWorker_Body( e ) {

    // ( e.data == [ processingId, done, value ] )
    let [ processingId, done, value ] = e.data;

    this.the_processingId_Resulter_Map.resolve_by_processingId_done_value(
      processingId, done, value );
  }

}
<commit_msg>create_WorkerBodyStub_Codes_DataURI<commit_after>export { AsyncWorker_Proxy as Proxy };

import * as Pool from "../Pool.js";
import * as Recyclable from "../Recyclable.js";
import { PromiseResolveReject } from "./AsyncWorker_PromiseResolveReject.js";
import { processingId_Resulter_Map } from "./AsyncWorker_processingId_Resulter_Map.js";
import { Resulter } from "./AsyncWorker_Resulter.js";

/**
 * Hold the worker and its related promise map. It is a wrapper of a neural network
 * web worker for handling and communicating easily.
 *
 * @member {string} workerURL
 *   The worker's source codes URL.
 *
 * @member {Worker} worker
 *   The worker.
 *
 * @member {number} processingId_next
 *   The next processing id. Zero means no command has been sent. Every
 * postCommand_and_expectResult() call will use a new id.
 *
 * @member {processingId_Resulter_Map} the_processingId_Resulter_Map
 *   Every worker has a result pending promise map. The key of the map is processing
 * id. The value of the map is a AsyncWorker.Resulter.
 *
 */
class AsyncWorker_Proxy extends Recyclable.Root {

  /**
   * Used as default AsyncWorker.Proxy provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "AsyncWorker.Proxy.Pool",
    AsyncWorker_Proxy, AsyncWorker_Proxy.setAsConstructor );

  /** */
  constructor( workerURL ) {
    super();
    AsyncWorker_Proxy.setAsConstructor_self.call( this, workerURL );
  }

  /** @override */
  static setAsConstructor() {
    super.setAsConstructor();
    AsyncWorker_Proxy.setAsConstructor_self.call( this, workerURL );
    return this;
  }

  /** @override */
  static setAsConstructor_self( workerURL ) {

    // Q: What if processingId become too large (e.g. infinity)?
    // A: Because Number.MAX_SAFE_INTEGER is pretty large (at least, 2 ** 52 ),
    //    it is not so easy to become out of bounds.
    //
    this.processingId_next = 0;

    if ( this.the_processingId_Resulter_Map )
      this.the_processingId_Resulter_Map.clear();
    else
      this.the_processingId_Resulter_Map = new processingId_Resulter_Map();

    AsyncWorker_Proxy.createWorker.call( this, workerURL );
  }

  /** @override */
  disposeResources() {

    if ( this.worker ) {
      // Note: No processingId, because this command needs not return value.
      this.postCommandArgs( "disposeResources" );
      this.worker = null;
    }

    this.workerOptions = undefined;
    this.workerURL = workerURL;

    this.the_processingId_Resulter_Map.clear();

    this.processingId_next = undefined;

    super.disposeResources();
  }

  /**
   * @param {AsyncWorker_Proxy} this
   *   The worker proxy.
   */
  static createWorker( workerURL ) {

//!!! ...unfinished... (2022/09/13)

    let workerDataURI
      = AsyncWorker_Proxy.create_WorkerBodyStub_Codes_DataURI( workerURL );

    this.workerURL = workerDataURI;

//!!! (2022/09/13 Temp Remarked) Test workerDataURI
//    this.workerURL = workerURL;

    // Should not use "module" type worker, otherwise the worker can not use
    // importScripts() to load tensorflow.js library.
    //
    //this.workerOptions = { type: "module" }; // So that the worker script could use import statement.
    this.workerOptions = null;

    this.worker = new Worker( this.workerURL, this.workerOptions );

    // Register callback from the web worker.
    this.worker.onmessage = AsyncWorker_Proxy.onmessage_from_AsyncWorker_Body.bind( this );
  }

  /**
   * Create a data URI representing the main (i.e. body) javascript file of web worker.
   * It is viewed as a classic javascript file (i.e. not an importable module). But
   * it will load specified workerURL as a module.
   *
   * In module (non-classic) web worker, static import is available. But the function
   * importScripts() will not be avbailable. For solving this problem, using
   * classic (non-module) web worker so that some global library (e.g. tensorflow.js)
   * can be loaded by importScripts(). And use dynamic import() to load ourselves
   * modules because import() can be used in classic (non-module) script.
   *
   * @param {string} moduleURL
   *   An (absolute) URL to a javascript module file. It will be imported
   * (asynchronously) by this generated classic javascript file (as a dataURI).
   */
  static create_WorkerBodyStub_Codes_DataURI( moduleURL ) {

//!!! ...unfinished... (2022/09/13)
// Perhaps, use a data uri contains the following source codes as workerURL:
//
// ( async () => {
//   await import( worker_body_relative_path );
// } )();
//
//

    let codes = ``
      + `import( "${moduleURL}" );`

//!!! ...unfinished... (2022/09/13)
// needs create a temporary message queue for collecting message before
// AsyncWorker_Proxy.onmessage_from_AsyncWorker_Body() be registered
// as message handler.
//

      + `onmessage = ( e ) => {`
      + `  console.log( "Hello" );`
      + `  console.log( e );`
      + `};`
      ;

    let workerDataURI
      = AsyncWorker_Proxy.createDataURI_byStringASCII( "text/javascript", codes );

    return workerDataURI;
  }

  /**
   * @param {string} strMimeType  The result mime type of the data URI.
   * @param {string} strASCII     The ASCII text to be embedded in data URI.
   *
   * @return {string} Return the data URI string.
   */
  static createDataURI_byStringASCII( strMimeType, strASCII ) {
    // let textEncoder = new TextEncoder();
    // let str_utf8 = textEncoder.encode( str );
    // let str_base64 = btoa( str_utf8 );
    let str_base64 = btoa( strASCII );
    let dataURI = `data:${strMimeType};base64,${str_base64}`;
    return dataURI;
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * and expect the final result.
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   *   - The command is a string which is the WorkerBody's method function to be
   *       called.
   *
   *   - The args is an array which will be destructured into multiple argements
   *       and passed into the WorkerBody's method function.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   *
   * @return {Promise}
   *   Return a promise resolved to the final value of the processing's resulter
   * from WorkerBody. (i.e. Only the Xxx of { done: true, value: Xxx } resolved.
   * All other intermediate result { done: false, value: Yyy } are discarded.)
   */
  createPromise_by_postCommandArgs( commandArgs, transferableObjectArray ) {
    let resulter = this.createResulter_by_postCommandArgs(
      commandArgs, transferableObjectArray );
    return resulter.untilDone();
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * and expect result.
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   *   - The command is a string which is the WorkerBody's method function to be
   *       called.
   *
   *   - The args is an array which will be destructured into multiple argements
   *       and passed into the WorkerBody's method function.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   *
   * @return {AsyncWorker.Resulter}
   *   Return an async generator for receving result from WorkerBody of the processing.
   */
  createResulter_by_postCommandArgs( commandArgs, transferableObjectArray ) {
    let processingId = this.processingId_next;
    ++this.processingId_next;

    // Prepare the processing's result's receiving queue before sending it.
    let resulter = this.the_processingId_Resulter_Map.createResulter_by_processingId(
      processingId );

    this.worker.postMessage( commandArgs, transferableObjectArray );
    return resulter;
  }

  /**
   * Send command and args (perhaps, with transferable object array) to WorkerBody
   * without expecting result. (i.e. fire-and-forget)
   *
   * @param {Array} commandArgs
   *   An array (i.e. [ comand, ...args ]) which will be sent to the WorkerBody.
   *
   * @param {Array} transferableObjectArray
   *   The transferable object array when postMessage. It could be undefined (but
   * can not be null).
   */
  postCommandArgs( commandArgs, transferableObjectArray ) {
    this.worker.postMessage( commandArgs, transferableObjectArray );
  }

  /**
   * Dispatch messages come from the owned web worker. Please register this method
   * as this WorkerProxy's Worker.onmessage.
   *
   * @param {AsyncWorker_Proxy} this
   *   The "this" should be binded to this AsyncWorker_Proxy object.
   */
  static onmessage_from_AsyncWorker_Body( e ) {

    // ( e.data == [ processingId, done, value ] )
    let [ processingId, done, value ] = e.data;

    this.the_processingId_Resulter_Map.resolve_by_processingId_done_value(
      processingId, done, value );
  }

}
<|endoftext|>


<commit_before>const express = require('express');
const router = express.Router();
const path = require('path');
const multer = require('multer');
const easyimg = require('easyimage');
const fs = require('fs');
const config = require('config');

const IMAGE_TYPES = ['image/jpeg', 'image/png'];

/* Save uploaded files (profile images) in the public images folder under the naming scheme 'user-<user-id>.<extenstion>' */
const storage = multer.diskStorage({
    destination: (req, file, cb) => cb(null, __dirname + '/../../client/public/images'),
    filename: (req, file, cb) => cb(null, 'user-' + req.user._id + '.' + file.originalname.split('.')[1]),
    fileFilter: (req, file, cb) => {
        if(IMAGE_TYPES.includes(file.mimetype)) {
            cb(null, true)
        } else {
            cb(null, false)
        }
    }
});

const upload = multer({
    storage,
    limits: {
        fileSize: 1000000, // 1 Megabyte
        files: 1,
    }
});

/* Determine which homepage to show based on whether logged in and verified or not */
router.get('/', (req, res, next) => {
    // Not logged in users get shown the info page
    if (!req.isAuthenticated()) return res.render('index/info');

    req.db.Update.findOne()
        .populate('author')
        .exec()
        .then(update => {
            res.locals.latestUpdate = update;

            return res.render('index/homepage');
        })
        .catch(next);
});

/* Show login form page */
router.get('/login', (req, res) => {
    if (req.isAuthenticated()) {
        req.flash('warning', 'You are already logged in!');
        return res.redirect('/');
    }

    res.redirect('/auth/slack');
});

/* Allow admins to login as any user based on email */
router.get('/loginas', (req, res, next) => {
    if (!req.query.id) return next(new Error('Invalid user id.'));
    if (config.util.getEnv('NODE_ENV') != 'development') return next(new Error('Not in development mode!'));

    req.db.User.findById(req.query.id)
        .exec()
        .then(user => {
            if(!user) throw new Error('Invalid user!');

            return req.logIn(user, err => {
                if (err) throw err;

                req.flash('info', `Successfully logged in as ${req.user.name.full}`);
                res.redirect('/');
            });
        })
        .catch(next);
});

router.get('/logout', function(req, res){
    req.logout();
    req.flash('info', 'Successful logout.');
    res.redirect('/');
});

router.get('/profile', requireLogin, (req, res, next) => {
    res.locals.pageTitle = 'Your Profile';

    res.render('users/profile');
});

/* Update logged in user's profile */
router.post('/profile', requireLogin, upload.single('profileImage'), (req, res, next) => {
    // Gather form data
    const firstName = req.body.firstName;
    const lastName = req.body.lastName;
    const grade = req.body.grade;
    const age = req.body.age;
    const phoneNumber = req.body.phoneNumber;
    const location = req.body.location;

    // Update user (isn't saved until user.save() is called)
    req.user.name.first = firstName;
    req.user.name.last = lastName;
    req.user.grade = grade;
    req.user.age = age;
    req.user.phoneNumber = phoneNumber;
    req.user.location = location;

    /* If a profile picture was uploaded then resize and convert the picture to standards then save the user, otherwise just save the user */
    if (req.file) {
        req.user.profileImageName = req.file.filename;
        const imgPath = path.join(__dirname, '..', '..', 'client', 'public', 'images', req.file.filename);

        // Resize image to roughly 200 by 250 (keeps ratio so may not be perfect)
        return easyimg.resize({
            src: imgPath, dst: imgPath,
            width: 200, height: 250,
        })
        .then(image => {
            const newPath = imgPath.replace('.' + imgPath.split('.')[1], '.jpg');

            // Convert to JPG image
            return easyimg.convert({
                src: imgPath, dst: newPath, quality: 90
            });
        }).then(image => {
            if (req.user.profileImageName !== image.name) {
                fs.unlinkSync(imgPath, err => {
                    if (err) console.error(err);
                });
            }

            // Set profile image name (url) to new one with JPG extension
            req.user.profileImageName = image.name;
            return req.user.save();
        }).then(user => {
            req.flash('success', 'Successfully updated profile and photo.');
            res.redirect('/profile');
        })
        .catch(next);
    }

    // Called if no profile picture was uploaded
    return req.user.save()
        .then(user => {
            req.flash('success', 'Successfully updated profile.');
            res.redirect('/profile');
        })
        .catch(next);
});

module.exports = router;
<commit_msg>Fixed login as<commit_after>const express = require('express');
const router = express.Router();
const path = require('path');
const multer = require('multer');
const easyimg = require('easyimage');
const fs = require('fs');
const config = require('config');

const IMAGE_TYPES = ['image/jpeg', 'image/png'];

/* Save uploaded files (profile images) in the public images folder under the naming scheme 'user-<user-id>.<extenstion>' */
const storage = multer.diskStorage({
    destination: (req, file, cb) => cb(null, __dirname + '/../../client/public/images'),
    filename: (req, file, cb) => cb(null, 'user-' + req.user._id + '.' + file.originalname.split('.')[1]),
    fileFilter: (req, file, cb) => {
        if(IMAGE_TYPES.includes(file.mimetype)) {
            cb(null, true)
        } else {
            cb(null, false)
        }
    }
});

const upload = multer({
    storage,
    limits: {
        fileSize: 1000000, // 1 Megabyte
        files: 1,
    }
});

/* Determine which homepage to show based on whether logged in and verified or not */
router.get('/', (req, res, next) => {
    // Not logged in users get shown the info page
    if (!req.isAuthenticated()) return res.render('index/info');

    req.db.Update.findOne()
        .populate('author')
        .exec()
        .then(update => {
            res.locals.latestUpdate = update;

            return res.render('index/homepage');
        })
        .catch(next);
});

/* Show login form page */
router.get('/login', (req, res) => {
    if (req.isAuthenticated()) {
        req.flash('warning', 'You are already logged in!');
        return res.redirect('/');
    }

    res.redirect('/auth/slack');
});

/* Allow admins to login as any user based on email */
/* Allows anyone to do it if in dev mode */
router.get('/loginas', (req, res, next) => {
    if (!req.query.id) return next(new Error('Invalid user id.'));

    if (config.util.getEnv('NODE_ENV') !== 'development' && !req.user.admin) return next(new Error('Not admin or in development mode!'));

    req.db.User.findById(req.query.id)
        .exec()
        .then(user => {
            if(!user) throw new Error('Invalid user!');

            return req.logIn(user, err => {
                if (err) throw err;

                req.flash('info', `Successfully logged in as ${req.user.name.full}`);
                res.redirect('/');
            });
        })
        .catch(next);
});

router.get('/logout', function(req, res){
    req.logout();
    req.flash('info', 'Successful logout.');
    res.redirect('/');
});

router.get('/profile', requireLogin, (req, res, next) => {
    res.locals.pageTitle = 'Your Profile';

    res.render('users/profile');
});

/* Update logged in user's profile */
router.post('/profile', requireLogin, upload.single('profileImage'), (req, res, next) => {
    // Gather form data
    const firstName = req.body.firstName;
    const lastName = req.body.lastName;
    const grade = req.body.grade;
    const age = req.body.age;
    const phoneNumber = req.body.phoneNumber;
    const location = req.body.location;

    // Update user (isn't saved until user.save() is called)
    req.user.name.first = firstName;
    req.user.name.last = lastName;
    req.user.grade = grade;
    req.user.age = age;
    req.user.phoneNumber = phoneNumber;
    req.user.location = location;

    /* If a profile picture was uploaded then resize and convert the picture to standards then save the user, otherwise just save the user */
    if (req.file) {
        req.user.profileImageName = req.file.filename;
        const imgPath = path.join(__dirname, '..', '..', 'client', 'public', 'images', req.file.filename);

        // Resize image to roughly 200 by 250 (keeps ratio so may not be perfect)
        return easyimg.resize({
            src: imgPath, dst: imgPath,
            width: 200, height: 250,
        })
        .then(image => {
            const newPath = imgPath.replace('.' + imgPath.split('.')[1], '.jpg');

            // Convert to JPG image
            return easyimg.convert({
                src: imgPath, dst: newPath, quality: 90
            });
        }).then(image => {
            if (req.user.profileImageName !== image.name) {
                fs.unlinkSync(imgPath, err => {
                    if (err) console.error(err);
                });
            }

            // Set profile image name (url) to new one with JPG extension
            req.user.profileImageName = image.name;
            return req.user.save();
        }).then(user => {
            req.flash('success', 'Successfully updated profile and photo.');
            res.redirect('/profile');
        })
        .catch(next);
    }

    // Called if no profile picture was uploaded
    return req.user.save()
        .then(user => {
            req.flash('success', 'Successfully updated profile.');
            res.redirect('/profile');
        })
        .catch(next);
});

module.exports = router;
<|endoftext|>


<commit_before>// ===================================================================================================
//                           _  __     _ _
//                          | |/ /__ _| | |_ _  _ _ _ __ _
//                          | ' </ _` | |  _| || | '_/ _` |
//                          |_|\_\__,_|_|\__|\_,_|_| \__,_|
//
// This file is part of the Kaltura Collaborative Media Suite which allows users
// to do with audio, video, and animation what Wiki platfroms allow them to do with
// text.
//
// Copyright (C) 2006-2020  Kaltura Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// @ignore
// ===================================================================================================
/**
 * The Kaltura Client - this is the facade through which all service actions should be called.
 * @param config the Kaltura configuration object holding partner credentials (type: KalturaConfiguration).
 */
var util = require('util');
var kaltura = require('./KalturaClientBase');
kaltura.services = require('./KalturaServices');
kaltura.objects = require('./KalturaModel');
kaltura.enums = require('./KalturaTypes');

class Client extends kaltura.ClientBase {

	/**
	 * @param Configuration config
	 */
	constructor(config) {
		super(config);
		this.setApiVersion('16.0.0');
		this.setClientTag('node:20-04-10');
	}
}

module.exports = kaltura;
module.exports.Client = Client;

<commit_msg>New clientlib ver<commit_after>// ===================================================================================================
//                           _  __     _ _
//                          | |/ /__ _| | |_ _  _ _ _ __ _
//                          | ' </ _` | |  _| || | '_/ _` |
//                          |_|\_\__,_|_|\__|\_,_|_| \__,_|
//
// This file is part of the Kaltura Collaborative Media Suite which allows users
// to do with audio, video, and animation what Wiki platfroms allow them to do with
// text.
//
// Copyright (C) 2006-2020  Kaltura Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// @ignore
// ===================================================================================================
/**
 * The Kaltura Client - this is the facade through which all service actions should be called.
 * @param config the Kaltura configuration object holding partner credentials (type: KalturaConfiguration).
 */
var util = require('util');
var kaltura = require('./KalturaClientBase');
kaltura.services = require('./KalturaServices');
kaltura.objects = require('./KalturaModel');
kaltura.enums = require('./KalturaTypes');

class Client extends kaltura.ClientBase {

	/**
	 * @param Configuration config
	 */
	constructor(config) {
		super(config);
		this.setApiVersion('16.0.0');
		this.setClientTag('node:20-04-11');
	}
}

module.exports = kaltura;
module.exports.Client = Client;

<|endoftext|>


<commit_before>'use strict'

const { Router } = require('express')
const router = Router()

const session = require('../controllers/session')
const wishlist = require('../controllers/wishlist')

router.post('/register', session.register)

router.post('/login', session.login)

router.post('/api/addToWishlist', wishlist.addToWishlist)

router.get('/api/getWishlist', wishlist.getWishlist)

router.post('/api/removeFromWishlist', wishlist.removeFromWishlist)

module.exports = router<commit_msg>added all currently reading routes to routes index.js<commit_after>'use strict'

const { Router } = require('express')
const router = Router()

const session = require('../controllers/session')
const wishlist = require('../controllers/wishlist')
const currentlyReading = require('../controllers/currently_reading')

router.post('/register', session.register)

router.post('/login', session.login)

router.post('/api/addToWishlist', wishlist.addToWishlist)

router.post('/api/removeFromWishlist', wishlist.removeFromWishlist)

router.get('/api/getWishlist', wishlist.getWishlist)

router.post('/api/addToCurrentlyReading', currentlyReading.addToCurrentlyReading)

router.post('/api/removeFromCurrentlyReading', currentlyReading.removeFromCurrentlyReading)

router.get('/api/getCurrentlyReading', currentlyReading.getCurrentlyReading)

module.exports = router<|endoftext|>


<commit_before>/**
 * Module composer, which uses stringify.js internally to serialize
 * module parts.
 */
const defaultOpts = require('./defaultOpts.js');
const constants = require('./constants.js');
const stringify = require('./stringify.js');

/**
 * Creates a string representing the module specified by the input parameters
 *
 * @param {Array} imports
 * @param {Array} exports
 * @param {Array} contents
 * @param {object} opts
 *
 * @return {string}     The composed module
 */
var compose = function(imports, _exports, contents, opts){
    opts = Object.assign({}, defaultOpts, opts);

    //Stringify each import, content item, and export
    imports = imports.map(function(importObj){
        return `var ${importObj.varName} = require(${stringify(importObj.importLoc, opts)});`
    })
    contents = contents.map(function(contentObj){
        //3 types of contents: Var, VarExpression, and Procedure
        switch(contentObj.type) {
            case constants.contentTypes.var:
                return `var ${contentObj.varName} = ${stringify(contentObj.payload, opts)};`
            case constants.contentTypes.varExpression:
                return `var ${contentObj.varName} = (${stringify(contentObj.payload, opts)})();`
            case constants.contentTypes.procedure:
                return getFunctionBody(contentObj.payload, opts);
            default:
                return '';
        }
    });
    _exports = processExports(_exports, opts);

    //Add breaks between items
    imports = imports.length ? imports.join(opts.lineBreak) : '';
    contents = contents.length ? contents.join(opts.lineBreak+opts.lineBreak) : '';
    _exports = _exports.length ? 'module.exports = { '+_exports.join(', ')+' };' : '';

    //Return non-empty statement groups with line breaks in between
    return [ imports, contents, _exports ].filter(function(statements){
        return statements !== '';
    }).join(opts.lineBreak+opts.lineBreak);
};

//Recursive function to handle nested arrays of exports
var processExports = function(_exports, opts){
    let result = [];
    _exports.forEach(function(exportItem){
        if(Array.isArray(exportItem)){
            result = result.concat(processExports(exportItem));
        }else if(typeof exportItem === 'string'){
            result.push(exportItem);
        }
    });
    return result;
};

//Simple function to return only the bodies of functions
var getFunctionBody = function(fn, opts){
    let bracketContents;
    let leadingSpaces;
    let arrowContents;
    fn = stringify(fn, opts);

    bracketContents = /{([\s\S]*)}[^}]*$/.exec(fn);
    if(bracketContents && bracketContents[1]){
        //Function has a standard body
        fn = bracketContents[1];

        //Remove first indent level (may not match opts.indent)
        leadingSpaces = (new RegExp(`${opts.lineBreak}(\\s*)`)).exec(fn);
        console.log('Leading Spaces: "'+leadingSpaces[1]+'"');
        if(leadingSpaces && leadingSpaces[1]){
            fn = fn.replace(new RegExp(opts.lineBreak+leadingSpaces[1], 'g'), opts.lineBreak);
        }
        //Remove newline at beginning of body
        fn = fn.replace(new RegExp(`^${opts.lineBreak}`), '');
        return fn;
    }else{
        //This may be a bracketless arrow function
        arrowContents = /=>([\s\S]*)$/.exec(fn);
        if(arrowContents && arrowContents[1]){
            return arrowContents[1].trim()+';';
        }
    }
    return '';
};

module.exports = compose;<commit_msg>Fix to trailing newline bug<commit_after>/**
 * Module composer, which uses stringify.js internally to serialize
 * module parts.
 */
const defaultOpts = require('./defaultOpts.js');
const constants = require('./constants.js');
const stringify = require('./stringify.js');

/**
 * Creates a string representing the module specified by the input parameters
 *
 * @param {Array} imports
 * @param {Array} exports
 * @param {Array} contents
 * @param {object} opts
 *
 * @return {string}     The composed module
 */
var compose = function(imports, _exports, contents, opts){
    opts = Object.assign({}, defaultOpts, opts);

    //Stringify each import, content item, and export
    imports = imports.map(function(importObj){
        return `var ${importObj.varName} = require(${stringify(importObj.importLoc, opts)});`
    })
    contents = contents.map(function(contentObj){
        //3 types of contents: Var, VarExpression, and Procedure
        switch(contentObj.type) {
            case constants.contentTypes.var:
                return `var ${contentObj.varName} = ${stringify(contentObj.payload, opts)};`
            case constants.contentTypes.varExpression:
                return `var ${contentObj.varName} = (${stringify(contentObj.payload, opts)})();`
            case constants.contentTypes.procedure:
                return getFunctionBody(contentObj.payload, opts);
            default:
                return '';
        }
    });
    _exports = processExports(_exports, opts);

    //Add breaks between items
    imports = imports.length ? imports.join(opts.lineBreak) : '';
    contents = contents.length ? contents.join(opts.lineBreak+opts.lineBreak) : '';
    _exports = _exports.length ? 'module.exports = { '+_exports.join(', ')+' };' : '';

    //Return non-empty statement groups with line breaks in between
    return [ imports, contents, _exports ].filter(function(statements){
        return statements !== '';
    }).join(opts.lineBreak+opts.lineBreak);
};

//Recursive function to handle nested arrays of exports
var processExports = function(_exports, opts){
    let result = [];
    _exports.forEach(function(exportItem){
        if(Array.isArray(exportItem)){
            result = result.concat(processExports(exportItem));
        }else if(typeof exportItem === 'string'){
            result.push(exportItem);
        }
    });
    return result;
};

//Simple function to return only the bodies of functions
var getFunctionBody = function(fn, opts){
    let bracketContents;
    let leadingSpaces;
    let arrowContents;
    fn = stringify(fn, opts);

    bracketContents = /{([\s\S]*)}[^}]*$/.exec(fn);
    if(bracketContents && bracketContents[1]){
        //Function has a standard body
        fn = bracketContents[1];

        //Remove first indent level (may not match opts.indent)
        leadingSpaces = (new RegExp(`${opts.lineBreak}(\\s*)`)).exec(fn);
        if(leadingSpaces && leadingSpaces[1]){
            fn = fn.replace(new RegExp(opts.lineBreak+leadingSpaces[1], 'g'), opts.lineBreak);
        }
        //Remove newline at beginning and end of body if there was no code on the same line as the outer brackets
        fn = fn.replace(new RegExp(`^\\s*${opts.lineBreak}`), '').replace(new RegExp(`${opts.lineBreak}\\s*$`), '');
        return fn;
    }else{
        //This may be a bracketless arrow function
        arrowContents = /=>([\s\S]*)$/.exec(fn);
        if(arrowContents && arrowContents[1]){
            return arrowContents[1].trim()+';';
        }
    }
    return '';
};

module.exports = compose;<|endoftext|>


<commit_before>/*
 * ChanChan Orion REST API
 */

var utils = require('../utils');
var orion_url = "orion"; // To be changed to PEP for auth

// Return the list of available entities in Orion
exports.contexts = function(req, res) {
    // TODO: Check auth
    // Is it possible to get all contexts from the API?
    // Right now we get all contexts from a type
    contextType = "Room";

    return_get = function(res, buffer) {
        res.send(buffer);
    };

    var options = {
        host: orion_url,
        port: 10026,
        path: '/NGSI10/contextEntityTypes/'+contextType,
        method: 'GET',
        headers: {
            accept: 'application/json'
        }
    };

    utils.do_get(options, return_get, res);
};

//Create a new Context subscription in CKAN for an organization
exports.subscribe_context = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var cygnus_ckan_url = "http://localhost";
  var org_id = req.params.org_id;
  var context_id = req.params.context_id;
  var org_port;

    if (org_id == "org_a" || org_id == "organization_a") {
      org_port = "5001";
  } else if (org_id == "org_b" || org_id == "organizatiob_b") {
      org_port = "5002";
  } else {
      res.status(404);
      res.send(err.message || "Org " + org_id + " not found.");
      return;
  }

  post_data = {
      "entities": [
           {
               "type": context_id,
               "isPattern": "false",
               "id": "FirstEntity"
           }
       ],
       "attributes": [
           "temperature"
       ],
       "reference": cygnus_ckan_url + ":" + org_port +"/notify",
       "duration": "P1M",
       "notifyConditions": [
           {
               "type": "ONCHANGE",
               "condValues": [
                   "pressure"
               ]
           }
       ],
       "throttling": "PT1S"
  };

  post_data = JSON.stringify(post_data);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/subscribeContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};

// Update entities data (temperature)
exports.update_context_temperature = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var org_id = req.params.org_id;
  var context_id = req.params.context_id;
  var temperature_id = req.params.temperature_id;

    post_data = {
        "contextElements": [
                {
                    "type": org_id,
                    "isPattern": "false",
                    "id": context_id,
                    "attributes": [
                    {
                        "name": "temperature",
                        "type": "centigrade",
                        "value": temperature_id
                    },
                    {
                        "name": "pressure",
                        "type": "mmHg",
                        "value": "720"
                    }
                    ]
                }
            ],
            "updateAction": "APPEND"
    };

  post_data = JSON.stringify(post_data);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/updateContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};

function get_orion_items(type, restaurant_name_regexp, req, res) {
    return_post = function(res, buffer, headers) {
        res.setHeader('Content-Type', 'application/json');
        res.send(unescape(buffer));
    };

    var name = restaurant_name_regexp;
    var orion_url = "orion";
    var orion_port = 10026;
    var orion_res_limit = 1000; // Max orion items to avoid pagination

    post_data = {
          "entities": [
           {
               "type": type,
               "isPattern": "true",
               "id": ".*"+name+".*"
           }]
    };

    // In geoqueries we get: lat=<lat>&long=<long>&radius=<radius>

    if (req.query.lat !== undefined && req.query.long !== undefined &&
        req.query.radius !== undefined) {

        console.log("GEO query")

        post_data ["restriction"] = {
            "scopes": [
               {
                 "type" : "FIWARE::Location",
                 "value" : {
                   "circle": {
                     "centerLatitude": req.query.lat,
                     "centerLongitude": req.query.long,
                     "radius": req.query.radius
                   }
                 }
               }
           ]
        }
    }

    if (name === undefined) {
        // Get all restaurants
        post_data.entities[0].id=".*";
    }

    post_data = JSON.stringify(post_data);

    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Content-Length': Buffer.byteLength(post_data)
    };

    var options = {
        host: orion_url,
        port: orion_port,
        path: '/NGSI10/queryContext?limit='+orion_res_limit,
        method: 'POST',
        headers: headers
    };

    utils.do_post(options, post_data, return_post, res);
}

// Find the restaurants given a name
exports.get_restaurants = function(req, res) {
    get_orion_items("restaurant", req.params.name, req, res);
};

// Find the reviews given a restaurant name regexp
exports.get_reviews = function(req, res) {
    get_orion_items("review", req.params.name, req, res);
};

// Find the reservations given a restaurant name regexp
exports.get_reservations = function(req, res) {
    get_orion_items("reservation", req.params.name, req, res);
};

// Update entities in orion
exports.update_entities = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var org_id = req.params.org_id;
  var post_data = JSON.stringify(req.body);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/updateContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};
<commit_msg>Added extra param to requests to Orion so PEP Wilma could use them to check auth.<commit_after>/*
 * ChanChan Orion REST API
 */

var utils = require('../utils');
var orion_url = "orion"; // To be changed to PEP for auth

// Return the list of available entities in Orion
exports.contexts = function(req, res) {
    // TODO: Check auth
    // Is it possible to get all contexts from the API?
    // Right now we get all contexts from a type
    contextType = "Room";

    return_get = function(res, buffer) {
        res.send(buffer);
    };

    var options = {
        host: orion_url,
        port: 10026,
        path: '/NGSI10/contextEntityTypes/'+contextType,
        method: 'GET',
        headers: {
            accept: 'application/json'
        }
    };

    utils.do_get(options, return_get, res);
};

//Create a new Context subscription in CKAN for an organization
exports.subscribe_context = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var cygnus_ckan_url = "http://localhost";
  var org_id = req.params.org_id;
  var context_id = req.params.context_id;
  var org_port;

    if (org_id == "org_a" || org_id == "organization_a") {
      org_port = "5001";
  } else if (org_id == "org_b" || org_id == "organizatiob_b") {
      org_port = "5002";
  } else {
      res.status(404);
      res.send(err.message || "Org " + org_id + " not found.");
      return;
  }

  post_data = {
      "entities": [
           {
               "type": context_id,
               "isPattern": "false",
               "id": "FirstEntity"
           }
       ],
       "attributes": [
           "temperature"
       ],
       "reference": cygnus_ckan_url + ":" + org_port +"/notify",
       "duration": "P1M",
       "notifyConditions": [
           {
               "type": "ONCHANGE",
               "condValues": [
                   "pressure"
               ]
           }
       ],
       "throttling": "PT1S"
  };

  post_data = JSON.stringify(post_data);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/subscribeContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};

// Update entities data (temperature)
exports.update_context_temperature = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var org_id = req.params.org_id;
  var context_id = req.params.context_id;
  var temperature_id = req.params.temperature_id;

    post_data = {
        "contextElements": [
                {
                    "type": org_id,
                    "isPattern": "false",
                    "id": context_id,
                    "attributes": [
                    {
                        "name": "temperature",
                        "type": "centigrade",
                        "value": temperature_id
                    },
                    {
                        "name": "pressure",
                        "type": "mmHg",
                        "value": "720"
                    }
                    ]
                }
            ],
            "updateAction": "APPEND"
    };

  post_data = JSON.stringify(post_data);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/updateContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};

function get_orion_items(type, restaurant_name_regexp, req, res) {
    return_post = function(res, buffer, headers) {
        res.setHeader('Content-Type', 'application/json');
        res.send(unescape(buffer));
    };

    var name = restaurant_name_regexp;
    var orion_url = "orion";
    var orion_port = 10026;
    var orion_res_limit = 1000; // Max orion items to avoid pagination

    post_data = {
          "entities": [
           {
               "type": type,
               "isPattern": "true",
               "id": ".*"+name+".*"
           }]
    };

    // In geoqueries we get: lat=<lat>&long=<long>&radius=<radius>

    if (req.query.lat !== undefined && req.query.long !== undefined &&
        req.query.radius !== undefined) {

        console.log("GEO query")

        post_data ["restriction"] = {
            "scopes": [
               {
                 "type" : "FIWARE::Location",
                 "value" : {
                   "circle": {
                     "centerLatitude": req.query.lat,
                     "centerLongitude": req.query.long,
                     "radius": req.query.radius
                   }
                 }
               }
           ]
        }
    }

    if (name === undefined) {
        // Get all restaurants
        post_data.entities[0].id=".*";
    }

    post_data = JSON.stringify(post_data);

    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Content-Length': Buffer.byteLength(post_data)
    };

    var orion_path = '/NGSI10/queryContext?limit='+orion_res_limit;
    var pep_extra_path = 'type='+type;  // For auth purposes

    var options = {
        host: orion_url,
        port: orion_port,
        path: orion_path + '&' + pep_extra_path,
        method: 'POST',
        headers: headers
    };

    utils.do_post(options, post_data, return_post, res);
}

// Find the restaurants given a name
exports.get_restaurants = function(req, res) {
    get_orion_items("restaurant", req.params.name, req, res);
};

// Find the reviews given a restaurant name regexp
exports.get_reviews = function(req, res) {
    get_orion_items("review", req.params.name, req, res);
};

// Find the reservations given a restaurant name regexp
exports.get_reservations = function(req, res) {
    get_orion_items("reservation", req.params.name, req, res);
};

// Update entities in orion
exports.update_entities = function(req, res) {
  return_post = function(res, buffer, headers) {
      res.send(buffer);
  };

  var org_id = req.params.org_id;
  var post_data = JSON.stringify(req.body);

  headers = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
  };

  var options = {
      host: orion_url,
      port: 10026,
      path: '/NGSI10/updateContext',
      method: 'POST',
      headers: headers
  };

  utils.do_post(options, post_data, return_post, res);
};
<|endoftext|>


<commit_before>https = require("https");

// Return the ISO 8601 format
// Ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example.3a_ISO_8601_formatted_dates
function ISODateString(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+'-'
      + pad(d.getUTCMonth()+1)+'-'
      + pad(d.getUTCDate())+'T'
      + pad(d.getUTCHours())+':'
      + pad(d.getUTCMinutes())+':'
      + pad(d.getUTCSeconds())+'Z'
}

function GithubModule(settings) {
  this.settings = settings;

  // Created new date instance for the first time running
  // Set the time to midnight...
  this.intervals = [[ function(cb){
    var d = new Date();
    options = {
      host: "api.github.com",
      path: '/repos/' + settings.repo +  '/issues?since=' + ISODateString(d)
    };
    // Storing the current time. This time will be used
    // to pase in request next time
    https.get(options,function(res){
      data = "";
      res.on('data',function(d){
        data = data + d;
      });
      res.on('end',function(){
        data = JSON.parse(data);
        for(var i=0; i<data.length; i++){
          issue = data[i];
          msg = "*" + issue.title + "* reported by " + issue.user.login + ": " + issue.html_url;
          cb(msg);
        }
      })
    });
  }, this.settings.interval]];
}

exports.Module = GithubModule;
<commit_msg>Coding style<commit_after>https = require("https");

// Return the ISO 8601 format
// Ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example.3a_ISO_8601_formatted_dates
function ISODateString(d){
 var pad = function(n) { return n < 10 ? '0' + n : n };
 return d.getUTCFullYear() + '-'
      + pad(d.getUTCMonth() + 1) + '-'
      + pad(d.getUTCDate()) + 'T'
      + pad(d.getUTCHours()) + ':'
      + pad(d.getUTCMinutes()) + ':'
      + pad(d.getUTCSeconds()) + 'Z'
}

function GithubModule(settings) {
  this.settings = settings;

  this.intervals = [[ function(cb) {
    var d = new Date();
    options = {
      host: "api.github.com",
      path: '/repos/' + settings.repo +  '/issues?since=' + ISODateString(d)
    };

    https.get(options, function(res) {
      var data = "";
      res.on('data', function(chunk) {
        data = data + chunk;
      });
      res.on('end', function() {
        data = JSON.parse(data);
        for (var i = 0; i < data.length; i++) {
          issue = data[i];
          msg = "*" + issue.title + "* reported by " + issue.user.login + ": " + issue.html_url;
          cb(msg);
        }
      })
    });
  }, this.settings.interval]];
}

exports.Module = GithubModule;

<|endoftext|>


<commit_before>'use strict';

const MongoClient   = require('mongodb').MongoClient,
      debug         = require('debug')('mongo-observer'),
      Oplog         = require('./oplog'),
      Emitter       = require('create-emitter'),
      connOptions   = {
        server: {
            poolSize: 10,
            socketOptions: {
                autoReconnect: true,
                noDelay: true,
                keepAlive: 1000,
                connectTimeoutMS: 30000
            }
        }
      };

module.exports = require('tofactory')(MongoObserver);

function MongoObserver(spec) {
    const emitter   = Emitter.create(),
          INSERT    = 'isert',
          UPDATE    = 'update',
          REMOVE    = 'remove';

    let count = 0,
        db, oplog, colOpts;

    init();

    return {
        on: emitter.on,
        off: emitter.off,
        observe
    };

    function init() {
        getDbConn(function (err) {
            if (err) throw err;
            defineObserver();
        });
    }

    function observe() {
        if (count > 10) return new Error('Oplog creation timeout!');
        if (oplog) {
            oplog.listen();
        } else {
            setTimeout(observe, 200);
            count += 1;
        }
    }

    function insertOp(collection, data) {
        emitter.emit(`${collection}:${INSERT}:${data._id}`, data);
    }

    function removeOp(collection, data) {
        emitter.emit(`${collection}:${REMOVE}:${data._id}`);
    }

    function updateOp(collection, data, _id) {
        if (data) {
            emitter.emit(`${collection}:${UPDATE}:${_id}`, data);
        } else {
            getDataFromDb(collection, _id);
        }
    }

    function getDataFromDb(collection, _id) {
        findOneById(collection, _id, function (err, doc) {
            if (err) return debug(err);
            emitter.emit(`${collection}:${UPDATE}`, doc);
        });
    }

    function findOneById(colName, _id, next) {
        db.collection(colName, function (err, col) {
            if (err) return next(err);
            col.find({_id: _id}).limit(1).next(function (err, doc) {
                if (err) return next(err);
                return next(undefined, doc);
            });
        });
    }

    function getDbConn(next) {
        db = spec.db;
        if (!db) {
            let host    = spec.host,
                port    = spec.port,
                dbName  = spec.dbName,
                dbURL   = spec.dbURL || `mongodb://${host}:${port}/${dbName}`,
                options = spec.connOptions || connOptions;

            MongoClient.connect(dbURL, options, function (err, dbConn) {
                if (err) return next(err);
                db = dbConn;
                spec.db = dbConn;
                next();
            });
        } else {
            next();
        }
    }

    function defineObserver() {
        colOpts = spec.collections || [];
        Array.isArray(colOpts) && (colOpts = colOpts.join('|'));
        oplog = Oplog.create(Object.assign(spec, {
            onInsert: insertOp,
            onUpdate: updateOp,
            onRemove: removeOp
        }));
        count = 0;
    }
}
<commit_msg>removed getDbConn as a function and added as a module<commit_after>'use strict';

const debug         = require('debug')('mongo-observer'),
      Oplog         = require('./oplog'),
      Emitter       = require('create-emitter'),
      getDbConn     = require('./get-db-connection');

module.exports = require('tofactory')(MongoObserver);

function MongoObserver(spec) {
    const emitter   = Emitter.create(),
          INSERT    = 'isert',
          UPDATE    = 'update',
          REMOVE    = 'remove';

    let count = 0,
        db, oplog, colOpts;

    init();

    return {
        on: emitter.on,
        off: emitter.off,
        observe
    };

    function init() {
        getDbConn(spec, function (err) {
            if (err) throw err;
            defineObserver();
        });
    }

    function observe() {
        if (count > 10) return new Error('Oplog creation timeout!');
        if (oplog) {
            oplog.listen();
        } else {
            setTimeout(observe, 200);
            count += 1;
        }
    }

    function insertOp(collection, data) {
        emitter.emit(`${collection}:${INSERT}:${data._id}`, data);
    }

    function removeOp(collection, data) {
        emitter.emit(`${collection}:${REMOVE}:${data._id}`);
    }

    function updateOp(collection, data, _id) {
        if (data) {
            emitter.emit(`${collection}:${UPDATE}:${_id}`, data);
        } else {
            getDataFromDb(collection, _id);
        }
    }

    function getDataFromDb(collection, _id) {
        findOneById(collection, _id, function (err, doc) {
            if (err) return debug(err);
            emitter.emit(`${collection}:${UPDATE}`, doc);
        });
    }

    function findOneById(colName, _id, next) {
        db.collection(colName, function (err, col) {
            if (err) return next(err);
            col.find({_id: _id}).limit(1).next(function (err, doc) {
                if (err) return next(err);
                return next(undefined, doc);
            });
        });
    }

    function defineObserver() {
        colOpts = spec.collections || [];
        Array.isArray(colOpts) && (colOpts = colOpts.join('|'));
        oplog = Oplog.create(Object.assign(spec, {
            onInsert: insertOp,
            onUpdate: updateOp,
            onRemove: removeOp
        }));
        count = 0;
    }
}
<|endoftext|>


<commit_before>const fs = require('fs');
const {
  getIndex,
  iterator
} = require('./util');
const exec = require('child_process').exec;
const articleJson = './json/article.json';

const pushGit = function () {
  const cmdList = ['git pull origin master', 'git add .', 'git commit -am "[update] article"', 'git push origin master'];
  iterator(cmdList, function (item, next, list) {
    exec(item, (error, stdout, stderr) => {
      if (error) {
        console.error(`exec error: ${error}`);
        return exec('start ./server/helper/update.sh', (error, stdout, stderr) => {
          if (error) {
            console.log('push到远程git仓库出现异常，请手动提交');
          }
        });
      }
      console.log('>', item);
      console.log(stdout || stderr);
      if(list.length > 0){
        next();
      }else{
        console.log('已经push到远程git仓库');
      }
    });
  });
};

const updateJSON = (callback)=> getIndex('blog', function(data){
  fs.writeFile(articleJson,
    JSON.stringify(data, null, 1),
    function (err) {
      if (err) throw err;
      console.log('文章索引更新成功', 'It\'s saved to '+articleJson+'!');
      if(callback)callback();
    }
  );
});

if(module.parent){
  module.exports = updateJSON;
}else{
  updateJSON(pushGit);
}
<commit_msg>[update] article<commit_after>const fs = require('fs');
const {
  getIndex,
  iterator
} = require('./util');
const exec = require('child_process').exec;
const articleJson = './json/article.json';

const pushGit = function (cmdList) {
  //const cmdList = ['git pull origin master', 'git add .', 'git commit -am "[update] article"', 'git push origin master'];
  return new Promise(function(resolve){
      iterator(cmdList, function (item, next, list) {
        exec(item, (error, stdout, stderr) => {
          if (error) {
            console.error(`exec error: ${error}`);
            return exec('start ./server/helper/update.sh', (error, stdout, stderr) => {
              if (error) {
                console.log('push到远程git仓库出现异常，请手动提交');
              }
            });
          }
          console.log('>', item);
          console.log(stdout || stderr);
          if(list.length > 0){
            next();
          }else{
            resolve();
          }
        });
      });
  });
};

const updateJSON = (callback)=> pushGit(['git pull origin master', 'git add .', 'git commit -am "[update] article"']).then(()=>getIndex('blog', function(data){
  fs.writeFile(articleJson,
    JSON.stringify(data, null, 1),
    function (err) {
      if (err) throw err;
      console.log('文章索引更新成功', 'It\'s saved to '+articleJson+'!');
      if(callback)callback();
    }
  );
}));

if(module.parent){
  module.exports = updateJSON;
}else{
  updateJSON(function(){
    pushGit(['git commit -am "[update] article"', 'git push origin master']).then(()=>console.log('已经push到远程git仓库'));
  });
}
<|endoftext|>


<commit_before>// Load modules

var ChildProcess = require('child_process');
var Fs = require('fs');
var Os = require('os');
var Utils = require('../utils');

// Declare internals

var internals = {};

/**
* Operating System Monitor Constructor
*
* @api public
*/
OSMonitor = function () {

    this.builtins = ['loadavg', 'uptime', 'freemem', 'totalmem', 'cpus'];

    // Expose Node os functions as async fns
    Utils.inheritAsync(OSMonitor, Os, this.public_methods);

    return this;
};

/**
* Return memory statistics to a callback
*
* @param {Function} callback
* @api public
*/
OSMonitor.prototype.mem = function (callback) {

    callback(null, {
        total: Os.totalmem(),
        free: Os.freemem()
    });
}

/**
* Grab slice of CPU usage information for all cores from /proc/stat
*
* @param {String} target (optional) allow user to specify individual CPU by number
* @param {Function} callback function to process the asynchronous result
* @api private
*/
OSMonitor.prototype.poll_cpu = function (target, callback) {

    var statfile = '/proc/stat';
    try {
        Fs.readFile(statfile, function (err, contents) {

            if (err) {
                throw err;
            }

            // TODO: FUTURE: optimization for later, if target known, customize regexp for that
            var pattern = /cpu[\d]?[\s]+(.*)/g;
            var file_contents = contents.toString();

            var result;
            var cpulines = {};
            while ((result = pattern.exec(file_contents)) !== null) {
                var source = result[0].split(/\s+/);
                var cpu = source.shift(); // remove 'cpu(\d?)' from string
                var line = source.map(function (d) {

                    return +d;
                }); // convert all to Number

                // line = line.slice(0, 4); // strip non-relevant numbers
                cpulines[cpu] = line;

                if (target === cpu) {
                    break; // short circuit if found
                }
            }

            if (!cpulines.hasOwnProperty(target)) {
                return callback('No such target found for Monitor.poll_cpu (' + target + ' does not exist)');
            }

            var cpuline = cpulines[target];
            var cpustats = {
                idle: cpuline[3],
                total: cpuline.reduce(function (a, b) {

                    return a + b;
                })
            };

            return callback(null, cpustats);
        });
    }
    catch (err) {
        return callback(err);
    }
};

/**
* Return 1-second slice of total cpu usage percentage from across all cores
*
* @param {Function} callback function to handle response
* @api public
*/
OSMonitor.prototype.cpu = function (target, callback) {

    // TODO: OS-support: only tested on RHEL, doesn't work on OSX
    if (typeof target === 'function') {
        callback = target;
        target = 'cpu';
    }

    if (process.platform !== 'linux') {
        return callback(null, '-');
    }

    // var self = this;
    var self = new OSMonitor();
    self.poll_cpu(target, function (err, stats_start) {

        setTimeout((function () {

            self.poll_cpu(target, function (err, stats_end) {

                var idle_delta = parseFloat(stats_end.idle - stats_start.idle);
                var total_delta = parseFloat(stats_end.total - stats_start.total);
                var cpuUsage = ((total_delta - idle_delta) / (total_delta)) * 100;

                callback(null, cpuUsage.toFixed(2));
            });
        }), 1000);
    });
};

/**
* Returns disk usage percentage for a specified filesystem
*
* @param {String} filesystem filesystem to check disk usage for (default '/')
* @param {Function} callback function to process results
* @api public
*/
OSMonitor.prototype.disk = function (filesystem, callback) {

    if (typeof filesystem === 'function') {
        callback = filesystem;
        filesystem = null;
    }

    filesystem = filesystem || '/';

    ChildProcess.exec('df -m ' + filesystem + ' | tail -1 | tr -s " "', function (err, stdout, stderr) {

        if (err ||
            stderr !== '') {

            return callback(err || stderr);
        }

        var values = stdout.replace(/^\s+/g, '').split(' ')

        if (isNaN(parseInt(values[0]))) {
            var total = values[1];
            var used = values[2];
        }
        else {
            var total = values[0];
            var used = values[1]
        }

        var output = {
            total: parseInt(total),
            used: parseInt(used)
        };

        return callback(null, output);

        // return callback(null, stdout.replace(/\s/g, '').replace('%', ''));
    });
};

module.exports = new OSMonitor();
module.exports.Monitor = OSMonitor;

<commit_msg>simpler disk fn<commit_after>// Load modules

var ChildProcess = require('child_process');
var Fs = require('fs');
var Os = require('os');
var Utils = require('../utils');

// Declare internals

var internals = {};

/**
* Operating System Monitor Constructor
*
* @api public
*/
OSMonitor = function () {

    this.builtins = ['loadavg', 'uptime', 'freemem', 'totalmem', 'cpus'];

    // Expose Node os functions as async fns
    Utils.inheritAsync(OSMonitor, Os, this.public_methods);

    return this;
};

/**
* Return memory statistics to a callback
*
* @param {Function} callback
* @api public
*/
OSMonitor.prototype.mem = function (callback) {

    callback(null, {
        total: Os.totalmem(),
        free: Os.freemem()
    });
}

/**
* Grab slice of CPU usage information for all cores from /proc/stat
*
* @param {String} target (optional) allow user to specify individual CPU by number
* @param {Function} callback function to process the asynchronous result
* @api private
*/
OSMonitor.prototype.poll_cpu = function (target, callback) {

    var statfile = '/proc/stat';
    try {
        Fs.readFile(statfile, function (err, contents) {

            if (err) {
                throw err;
            }

            // TODO: FUTURE: optimization for later, if target known, customize regexp for that
            var pattern = /cpu[\d]?[\s]+(.*)/g;
            var file_contents = contents.toString();

            var result;
            var cpulines = {};
            while ((result = pattern.exec(file_contents)) !== null) {
                var source = result[0].split(/\s+/);
                var cpu = source.shift(); // remove 'cpu(\d?)' from string
                var line = source.map(function (d) {

                    return +d;
                }); // convert all to Number

                // line = line.slice(0, 4); // strip non-relevant numbers
                cpulines[cpu] = line;

                if (target === cpu) {
                    break; // short circuit if found
                }
            }

            if (!cpulines.hasOwnProperty(target)) {
                return callback('No such target found for Monitor.poll_cpu (' + target + ' does not exist)');
            }

            var cpuline = cpulines[target];
            var cpustats = {
                idle: cpuline[3],
                total: cpuline.reduce(function (a, b) {

                    return a + b;
                })
            };

            return callback(null, cpustats);
        });
    }
    catch (err) {
        return callback(err);
    }
};

/**
* Return 1-second slice of total cpu usage percentage from across all cores
*
* @param {Function} callback function to handle response
* @api public
*/
OSMonitor.prototype.cpu = function (target, callback) {

    // TODO: OS-support: only tested on RHEL, doesn't work on OSX
    if (typeof target === 'function') {
        callback = target;
        target = 'cpu';
    }

    if (process.platform !== 'linux') {
        return callback(null, '-');
    }

    // var self = this;
    var self = new OSMonitor();
    self.poll_cpu(target, function (err, stats_start) {

        setTimeout((function () {

            self.poll_cpu(target, function (err, stats_end) {

                var idle_delta = parseFloat(stats_end.idle - stats_start.idle);
                var total_delta = parseFloat(stats_end.total - stats_start.total);
                var cpuUsage = ((total_delta - idle_delta) / (total_delta)) * 100;

                callback(null, cpuUsage.toFixed(2));
            });
        }), 1000);
    });
};

/**
* Returns disk usage percentage for a specified filesystem
*
* @param {String} filesystem filesystem to check disk usage for (default '/')
* @param {Function} callback function to process results
* @api public
*/
OSMonitor.prototype.disk = function (filesystem, callback) {

    if (typeof filesystem === 'function') {
        callback = filesystem;
        filesystem = null;
    }

    filesystem = filesystem || '/';

    ChildProcess.exec('df -m ' + filesystem, function (err, stdout, stderr) {

        if (err ||
            stderr !== '') {

            return callback(err || stderr);
        }

        var lines = stdout.split("\n");
        var dfInfo = lines[1].replace(/[\s\n\r]+/g, " ").split(" ");

        var output = {
            total: parseInt(dfInfo[1]),
            free: parseInt(dfInfo[3])
        }

        if (output.total < output.free) {

            return callback("system reports total disk space less than free disk space");
        }

        return callback(null, output);

        // var values = stdout.replace(/^\s+/g, '').split(' ')

        // if (isNaN(parseInt(values[0]))) {
        //     var total = values[1];
        //     var used = values[2];
        // }
        // else {
        //     var total = values[0];
        //     var used = values[1]
        // }

        // var output = {
        //     total: parseInt(total),
        //     used: parseInt(used)
        // };

        // return callback(null, output);

        // return callback(null, stdout.replace(/\s/g, '').replace('%', ''));
    });
};

module.exports = new OSMonitor();
module.exports.Monitor = OSMonitor;

<|endoftext|>


<commit_before>'use strict';

const fetch = require('node-fetch');
const cache = require('memory-cache');
/*
 * Setting up link to GitHub
 */
function getCode(cb) {
    const githubcache = cache.get('githubrepos');
    if (githubcache) {
       cb(null, { repos: githubcache });
    } else {
        fetch('https://api.github.com/orgs/jaxnode-ug/repos',
            {
                headers: {
                    Accept: 'application/vnd.github.v3+json',
                    'User-Agent': 'JaxNode'
                }
            }).then(response => {
                return response.json();
            }).then(json => {
                cache.put('githubrepos', json, 3600000);
                cb(null, { repos: json });
            }).catch(err => {
                console.error(err);
                cb(err, { repos: [] });
            });
    }
}

module.exports = getCode;
<commit_msg>Fixed linting errors<commit_after>'use strict';

const fetch = require('node-fetch');
const cache = require('memory-cache');
/*
 * Setting up link to GitHub
 */
function getCode(cb) {
    const githubcache = cache.get('githubrepos');
    if (githubcache) {
        cb(null, { repos: githubcache });
    } else {
        fetch('https://api.github.com/orgs/jaxnode-ug/repos',
            {
                headers: {
                    Accept: 'application/vnd.github.v3+json',
                    'User-Agent': 'JaxNode'
                }
            }).then(response => {
            return response.json();
        }).then(json => {
            cache.put('githubrepos', json, 3600000);
            cb(null, { repos: json });
        }).catch(err => {
            console.error(err);
            cb(err, { repos: [] });
        });
    }
}

module.exports = getCode;
<|endoftext|>


<commit_before>// 作业 4
//
// var difference = function(a, b) { }
//
// a b 都是 array
//
// 返回一个 array, 里面的元素是
// 所有在 a 中有 b 中没有的元素
// 这个 array 中不包含重复元素
//

// 以下是提交作业代码
/* ------------------------------------------------------------------------- */
var log = console.log.bind(console)

var ensure = function(condition, message) {
    if (!condition) {
        log("测试失败:", condition, "->", message)
    } else {
        log("测试成功:", condition)
    }
}

var arrayEquals = function(arr1, arr2) {
    if (arr1.length != arr2.length) {
        return false
    }

    for (var i = 0; i < arr1.length; i++) {
        if (arr1[i] != arr2[i]) {
            return false
        }
    }

    return true
}

var findNum = function(source, targetNum) {
    for (var i = 0; i < source.length; i++) {
        log("source[i]:", source[i], "\ttargetNum:", targetNum)
        if (targetNum == source[i]) {
            log("found")
            return i
        }
    }

    return undefined
}

var unique = function(a) {
    var result = []
    for (var i = 0; i < a.length; i++) {
        if (findNum(result, a[i]) == undefined) {
            result.push(a[i])
        }
    }

    return result
}

function difference(a, b) {
    var result = []
    for (var i = 0; i < a.length; i++) {
        if (b.indexOf(a[i]) == -1) {
            result.push(a[i])
        }
    }

    return result
}

var testDifference = function() {
    var test1 = [1, 3, 6, 9, 11]
    var test2 = [3, 6, 9]
    var test3 = [1, 2, 3, 4]
    var test4 = [2, 4]

    ensure(arrayEquals(difference(test1, test2), [1, 11]), 'difference test 1')
    ensure(arrayEquals(difference(test3, test4), [1, 3]), 'difference test 2')
}

testDifference()
<commit_msg>Delete task08-04.js<commit_after><|endoftext|>


<commit_before>var amz = require('./amazon/amazon.js');
var sd = require('./snapdeal/snapdeal.js');
var parser = require('./services.js');

var amazon = {
		'searching' : function(page,item){
			var forSearchingRules = amz.forSearching;

			// don't use console inside here
			page.evaluate(function(forSearching,item) {
				document.getElementById(forSearching.inputBoxID).value = item;
				document.querySelector("."+forSearching.formClass).submit();
			},forSearchingRules,item);
		},

		'forGettingFromList' : function(page){
			var gettingFromListRules = amz.forGettingItemFromList;
			page.evaluate(function(forList) {
				var firstItem = document.getElementById(forList.firstItem);
				firstItem = firstItem.getElementsByTagName(forList.tagToOpen);
				// 0 but does not matter
				firstItem[0].click();
			},gettingFromListRules);
		},

		'forGettingPrice' : function(page){
			var getPriceRules = amz.forGettingPrice;
			console.log(getPriceRules);
			var price =   page.evaluate(function(priceRules) {
				if(document.getElementById(priceRules.priceTagId1) != null){
					return document.getElementById(priceRules.priceTagId1).innerHTML;
				}else if(document.getElementById(priceRules.priceTagId2) != null){
					return document.getElementById(priceRules.priceTagId2).innerHTML;
				}
				else
				{
					return 'not able to fetch price';
				}
			},getPriceRules);
			var finalP = parser.getNumbersFromString(price);
			return finalP;
		},
		'forGettingUserRatings' : function(page){
			var userRatingRules = amz.forGettingUserRating;
			console.log('====amazonUserRating=====pageInject========'+page.injectJs('./services/amazon/amazonUserRatingFilter.js'));
			var ratings =   page.evaluate(function(ratingRules) {
				var block = document.getElementById(ratingRules.ratingBlockId);
				var list = block.getElementsByTagName(ratingRules.listOfRatings);
				var jsonObject = {
						'1' : '',
						'2' : '',
						'3' : '',
						'4' : '',
						'5' : ''
				};
				for(var i = 0; i < list.length ; i++){
					jsonObject[5-i]=getDataFromInnerHtmlOfTag(ratingRules.tagToFetch,list[i].getElementsByClassName(ratingRules.ratingDivClass)[ratingRules.indexForRatingDiv].innerHTML);
				}

				return jsonObject;
			},userRatingRules);
			return ratings;
		},
		'forGettingProductImage' : function(page){
			var imageRules = amz.forGettingProductImage;
			console.log(imageRules);
			var image =   page.evaluate(function(imageRules) {
				var block = document.getElementById('product-slider').getElementsByTagName('img');
//				var img = block.getElementsByTagName('img')[0];
//				var jsonObject = {
//				top : img.offsetTop,
//				left : img.offsetLeft,
//				width : img.width,
//				height : img.height
//				}
				return block;
			},imageRules);
			consosole.log(image);

		},
		'forGettingProductName' : function(page){
			var productNameRules = amz.forGettingProductName;
			var title = page.evaluate(function(productNameRules){
				var title = document.getElementById(productNameRules.titleId).innerHTML;
				return title;
			},productNameRules)

			return title;
		},
		'forGettingProductDescription' : function(page){
			var productDescRules = amz.forGettingProductDescription;
			var desc = page.evaluate(function(productDescRules){
				var main = document.getElementById(productDescRules.mainDivId);
				var desc = main.getElementsByClassName(productDescRules.contentClass)[productDescRules.contentIndex].innerHTML;
				return desc;
			},productDescRules)

			return desc;
		}
}

var snapdeal = {
		'searching' : function(page,item){
			var forSearchingRules = sd.forSearching;
			console.log('hrer in searching');
			// page.includeJs('http://code.jquery.com/jquery-2.1.4.min.js', function() {
			// don't use console inside here
			page.evaluate(function(forSearching) {
				document.getElementById(forSearching.inputBoxID).value = item;
				document.getElementById(forSearching.formId).submit();
			},forSearchingRules,item);
			// });
		},

		'forGettingFromList' : function(page,item){
			var gettingFromListRules = sd.forGettingItemFromList;

			console.log('======hashmap=======pageInject======='+page.injectJs('./scripts/lib/hashmap.js'));
			console.log('====snapdealFilter=====pageInject======'+page.injectJs('./services/snapdeal/snapdealFilters.js'));
			page.evaluate(function(forList,item,funDef) {
				var mainDiv = document.getElementById(forList.SearchListBoxId);
				mainDiv = mainDiv.getElementsByClassName(forList.productGridRowClass);
				mainDiv = mainDiv[forList.rowPref].getElementsByClassName(forList.singleProductClass);

				// here to call filter on mainDiv
				var arrayOfItems = [];

				for(var i = 0 ; i < mainDiv.length ; i++){
					var div = mainDiv[i];
					div = div.getElementsByClassName('product-title')[0];
					div = div.getElementsByTagName('a')[0];
					arrayOfItems[i] = div.innerHTML;
				}

				var index = forGettingSingleItemFromList(arrayOfItems,item);
				console.log(index);
				mainDiv = mainDiv[index].getElementsByTagName(forList.itemTag);

				// 1 but does not matter
				mainDiv[forList.tagPref].click();
			},gettingFromListRules,item);
		},

		'forGettingPrice' : function(page){
			var getPriceRules = sd.forGettingPrice;
			console.log(getPriceRules);
			var price =   page.evaluate(function(priceRules) {
				if(document.getElementById(priceRules.priceTagId1) != null){
					return document.getElementById(priceRules.priceTagId1).innerHTML;
				}
				else return 'not able to fetch Price';
			},getPriceRules);
			var finalP = parser.getNumbersFromString(price);
			return finalP;
		},

		'forGettingUserRating' : function(page){
			var userRatingRules = sd.forGettingUserRating;

			var userRating =   page.evaluate(function(ratingRules) {
				var div = document.getElementById(ratingRules.userRatingBlockId);

				// there was single index so it really does not matter
				div = div.getElementsByClassName(ratingRules.userRating)[0];

				var list = div.getElementsByTagName(ratingRules.divForUserRating);

				var jsonObject = {
						'rating' : '',
						'usersRated' : ''
				};

				jsonObject['rating'] = list[0].innerHTML;
				jsonObject['usersRated'] = list[1].innerHTML;

				return jsonObject;

			},userRatingRules);
			return userRating;
		},
//		'forGettingProductImage' : function(page){
//		var imageRules = sd.forGettingProductImage;
//		console.log(imageRules);
//		var image =   page.evaluate(function(imageRules) {
//		var block = document.getElementById('product-slider');
//		var img = block.getElementsByTagName('img')[0];
//		var jsonObject = {
//		top : img.offsetTop,
//		left : img.offsetLeft,
//		width : img.width,
//		height : img.height
//		}
//		return jsonObject;
//		},imageRules);
//		return image;
//		},
//		'getBasicDetails' : function(page){

//		},
		'forGettingProductName' : function(page){
			var productNameRules = sd.forGettingProductName;
			console.log(productNameRules);
			var productName =   page.evaluate(function(productNameRules) {
				var block = document.getElementsByClassName(productNameRules.mainBlockClass);
				block = block[productNameRules.mainBlockIndex].getElementsByTagName(productNameRules.tagsName);
				var name = block[productNameRules.tagsNameIndex].innerHTML;

				return name;
			},productNameRules);
			console.log(productName);
			return productName;
		},
		'forGettingProductDescription' : function(page){
			var productDescriptionRules = sd.forGettingProductDescription;
			console.log(productDescriptionRules);
			var productDescription = page.evaluate(function(productDesriptionRules){
				var block = document.getElementsByClassName(productDesriptionRules.mainBlockClass);
				block = block[productDesriptionRules.mainBlockClassIndex].getElementsByClassName(productDesriptionRules.detailDivClass);
				var description = block[productDesriptionRules.detailDivIndex].getElementsByTagName(productDesriptionRules.tagsName)[productDesriptionRules.tagsNameIndex].innerHTML;
				return description;
			},productDescriptionRules);
			return productDescription;
		}
}

exports.amazon = amazon;
exports.snapdeal = snapdeal;<commit_msg>snapdeal error fixed<commit_after>var amz = require('./amazon/amazon.js');
var sd = require('./snapdeal/snapdeal.js');
var parser = require('./services.js');

var amazon = {
		'searching' : function(page,item){
			var forSearchingRules = amz.forSearching;

			// don't use console inside here
			page.evaluate(function(forSearching,item) {
				document.getElementById(forSearching.inputBoxID).value = item;
				document.querySelector("."+forSearching.formClass).submit();
			},forSearchingRules,item);
		},

		'forGettingFromList' : function(page){
			var gettingFromListRules = amz.forGettingItemFromList;
			page.evaluate(function(forList) {
				var firstItem = document.getElementById(forList.firstItem);
				firstItem = firstItem.getElementsByTagName(forList.tagToOpen);
				// 0 but does not matter
				firstItem[0].click();
			},gettingFromListRules);
		},

		'forGettingPrice' : function(page){
			var getPriceRules = amz.forGettingPrice;
			console.log(getPriceRules);
			var price =   page.evaluate(function(priceRules) {
				if(document.getElementById(priceRules.priceTagId1) != null){
					return document.getElementById(priceRules.priceTagId1).innerHTML;
				}else if(document.getElementById(priceRules.priceTagId2) != null){
					return document.getElementById(priceRules.priceTagId2).innerHTML;
				}
				else
				{
					return 'not able to fetch price';
				}
			},getPriceRules);
			var finalP = parser.getNumbersFromString(price);
			return finalP;
		},
		'forGettingUserRatings' : function(page){
			var userRatingRules = amz.forGettingUserRating;
			console.log('====amazonUserRating=====pageInject========'+page.injectJs('./services/amazon/amazonUserRatingFilter.js'));
			var ratings =   page.evaluate(function(ratingRules) {
				var block = document.getElementById(ratingRules.ratingBlockId);
				var list = block.getElementsByTagName(ratingRules.listOfRatings);
				var jsonObject = {
						'1' : '',
						'2' : '',
						'3' : '',
						'4' : '',
						'5' : ''
				};
				for(var i = 0; i < list.length ; i++){
					jsonObject[5-i]=getDataFromInnerHtmlOfTag(ratingRules.tagToFetch,list[i].getElementsByClassName(ratingRules.ratingDivClass)[ratingRules.indexForRatingDiv].innerHTML);
				}

				return jsonObject;
			},userRatingRules);
			return ratings;
		},
		'forGettingProductImage' : function(page){
			var imageRules = amz.forGettingProductImage;
			console.log(imageRules);
			var image =   page.evaluate(function(imageRules) {
				var block = document.getElementById('product-slider').getElementsByTagName('img');
//				var img = block.getElementsByTagName('img')[0];
//				var jsonObject = {
//				top : img.offsetTop,
//				left : img.offsetLeft,
//				width : img.width,
//				height : img.height
//				}
				return block;
			},imageRules);
			consosole.log(image);

		},
		'forGettingProductName' : function(page){
			var productNameRules = amz.forGettingProductName;
			var title = page.evaluate(function(productNameRules){
				var title = document.getElementById(productNameRules.titleId).innerHTML;
				return title;
			},productNameRules)

			return title;
		},
		'forGettingProductDescription' : function(page){
			var productDescRules = amz.forGettingProductDescription;
			var desc = page.evaluate(function(productDescRules){
				var main = document.getElementById(productDescRules.mainDivId);
				var desc = main.getElementsByClassName(productDescRules.contentClass)[productDescRules.contentIndex].innerHTML;
				return desc;
			},productDescRules)

			return desc;
		}
}

var snapdeal = {
		'searching' : function(page,item){
			var forSearchingRules = sd.forSearching;
			console.log('hrer in searching');
			// page.includeJs('http://code.jquery.com/jquery-2.1.4.min.js', function() {
			// don't use console inside here
			page.evaluate(function(forSearching,item) {
				document.getElementById(forSearching.inputBoxID).value = item;
				document.getElementById(forSearching.formId).submit();
			},forSearchingRules,item);
			// });
		},

		'forGettingFromList' : function(page,item){
			var gettingFromListRules = sd.forGettingItemFromList;

			console.log('======hashmap=======pageInject======='+page.injectJs('./scripts/lib/hashmap.js'));
			console.log('====snapdealFilter=====pageInject======'+page.injectJs('./services/snapdeal/snapdealFilters.js'));
			page.evaluate(function(forList,item,funDef) {
				var mainDiv = document.getElementById(forList.SearchListBoxId);
				mainDiv = mainDiv.getElementsByClassName(forList.productGridRowClass);
				mainDiv = mainDiv[forList.rowPref].getElementsByClassName(forList.singleProductClass);

				// here to call filter on mainDiv
				var arrayOfItems = [];

				for(var i = 0 ; i < mainDiv.length ; i++){
					var div = mainDiv[i];
					div = div.getElementsByClassName('product-title')[0];
					div = div.getElementsByTagName('a')[0];
					arrayOfItems[i] = div.innerHTML;
				}

				var index = forGettingSingleItemFromList(arrayOfItems,item);
				console.log(index);
				mainDiv = mainDiv[index].getElementsByTagName(forList.itemTag);

				// 1 but does not matter
				mainDiv[forList.tagPref].click();
			},gettingFromListRules,item);
		},

		'forGettingPrice' : function(page){
			var getPriceRules = sd.forGettingPrice;
			console.log(getPriceRules);
			var price =   page.evaluate(function(priceRules) {
				if(document.getElementById(priceRules.priceTagId1) != null){
					return document.getElementById(priceRules.priceTagId1).innerHTML;
				}
				else return 'not able to fetch Price';
			},getPriceRules);
			var finalP = parser.getNumbersFromString(price);
			return finalP;
		},

		'forGettingUserRating' : function(page){
			var userRatingRules = sd.forGettingUserRating;

			var userRating =   page.evaluate(function(ratingRules) {
				var div = document.getElementById(ratingRules.userRatingBlockId);

				// there was single index so it really does not matter
				div = div.getElementsByClassName(ratingRules.userRating)[0];

				var list = div.getElementsByTagName(ratingRules.divForUserRating);

				var jsonObject = {
						'rating' : '',
						'usersRated' : ''
				};

				jsonObject['rating'] = list[0].innerHTML;
				jsonObject['usersRated'] = list[1].innerHTML;

				return jsonObject;

			},userRatingRules);
			return userRating;
		},
//		'forGettingProductImage' : function(page){
//		var imageRules = sd.forGettingProductImage;
//		console.log(imageRules);
//		var image =   page.evaluate(function(imageRules) {
//		var block = document.getElementById('product-slider');
//		var img = block.getElementsByTagName('img')[0];
//		var jsonObject = {
//		top : img.offsetTop,
//		left : img.offsetLeft,
//		width : img.width,
//		height : img.height
//		}
//		return jsonObject;
//		},imageRules);
//		return image;
//		},
//		'getBasicDetails' : function(page){

//		},
		'forGettingProductName' : function(page){
			var productNameRules = sd.forGettingProductName;
			console.log(productNameRules);
			var productName =   page.evaluate(function(productNameRules) {
				var block = document.getElementsByClassName(productNameRules.mainBlockClass);
				block = block[productNameRules.mainBlockIndex].getElementsByTagName(productNameRules.tagsName);
				var name = block[productNameRules.tagsNameIndex].innerHTML;

				return name;
			},productNameRules);
			console.log(productName);
			return productName;
		},
		'forGettingProductDescription' : function(page){
			var productDescriptionRules = sd.forGettingProductDescription;
			console.log(productDescriptionRules);
			var productDescription = page.evaluate(function(productDesriptionRules){
				var block = document.getElementsByClassName(productDesriptionRules.mainBlockClass);
				block = block[productDesriptionRules.mainBlockClassIndex].getElementsByClassName(productDesriptionRules.detailDivClass);
				var description = block[productDesriptionRules.detailDivIndex].getElementsByTagName(productDesriptionRules.tagsName)[productDesriptionRules.tagsNameIndex].innerHTML;
				return description;
			},productDescriptionRules);
			return productDescription;
		}
}

exports.amazon = amazon;
exports.snapdeal = snapdeal;<|endoftext|>


<commit_before>defineClass('Consoloid.Service.AsyncRPC.BrowserPeer', 'Consoloid.Service.AsyncRPC.BasePeer',
  {
    __constructor: function(options)
    {
      this.__base(options);
      this._setupConnection();
    },

    _setupConnection: function()
    {
      if (!('io' in window)) {
        eval.call(window, this.get('resource_loader').getJs('node_modules/socket.io-client/dist/socket.io.min'));
      }

      this.get('logger').log('debug', 'Connecting to socket.io server at ' + this.get('server').url);

      this.socket = io.connect(this.get('server').url);
      if (!this.socket) {
        throw new Error('Unable to connect to socket.io server at ' + this.get('server').url);
      }

      this._setupListeners();

      this.get('logger').log('debug', 'Connected to socket.io server.');
    },

    __getSessionId: function()
    {
      return decodeURIComponent(document.cookie).match('connect.sid=s:([^\.]+)')[1];
    },

    _handleActualSharedServiceCall: function(req, response)
    {
      var service = this.get(req.service);
      req.args.unshift(function(err, result) {
        if (err) {
          response.sendError(err);
          return true;
        }

        response.sendResult(result);
      });
      service[req.method].apply(service, req.args);
    },
  }
);
<commit_msg>AsyncRPC: reading session id from correct cookie (refs agmen-hu/tada#14)<commit_after>defineClass('Consoloid.Service.AsyncRPC.BrowserPeer', 'Consoloid.Service.AsyncRPC.BasePeer',
  {
    __constructor: function(options)
    {
      this.__base(options);
      this._setupConnection();
    },

    _setupConnection: function()
    {
      if (!('io' in window)) {
        eval.call(window, this.get('resource_loader').getJs('node_modules/socket.io-client/dist/socket.io.min'));
      }

      this.get('logger').log('debug', 'Connecting to socket.io server at ' + this.get('server').url);

      this.socket = io.connect(this.get('server').url);
      if (!this.socket) {
        throw new Error('Unable to connect to socket.io server at ' + this.get('server').url);
      }

      this._setupListeners();

      this.get('logger').log('debug', 'Connected to socket.io server.');
    },

    __getSessionId: function()
    {
      return decodeURIComponent(document.cookie).match(this.get('server').cookie + '=s:([^\.]+)')[1];
    },

    _handleActualSharedServiceCall: function(req, response)
    {
      var service = this.get(req.service);
      req.args.unshift(function(err, result) {
        if (err) {
          response.sendError(err);
          return true;
        }

        response.sendResult(result);
      });
      service[req.method].apply(service, req.args);
    },
  }
);
<|endoftext|>


<commit_before><commit_msg>fixing bug of comparing different types<commit_after><|endoftext|>


<commit_before>/*! Simple CSS JS loader asynchronously for all browsers by cara-tm.com, MIT License */
var LoadCSSJS=function(e,t,o){"use strict";var f="",s;if(f.indexOf("["+e+"]")==-1){f+="["+e+"]";switch(t){case "css":s=document.createElement("link");s.rel=(o.rel||"stylesheet");s.href=e;s.media=(o.media||"all");break;case "js":s=document.createElement("script");o.defer?s.defer="defer":s.async="async";s.type="text/javascript";s.src=e;break;}}if("undefined"!=typeof s){var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(s,a);}else{alert("File: \""+e+"\" already loaded (keep only one)!");}};
<commit_msg>Update LoadCSSJS.min.js<commit_after>/*! Simple CSS JS loader asynchronously for all browsers by cara-tm.com, MIT License */
var LoadCSSJS=function(e,t,o){"use strict";var f="",s;if(f.indexOf("["+e+"]")==-1){f+="["+e+"]";switch(t){case "css":s=document.createElement("link");s.rel=(o.rel||"stylesheet");s.href=e;s.media=(o.media||"all");break;case "js":s=document.createElement("script");if(o.defer)s.defer="defer";else s.async="async";s.src=e;break;}}if("undefined"!=typeof s){var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(s,a);}else{alert("File: \""+e+"\" already loaded (keep only one)!");}};
<|endoftext|>