<commit_before>
var SureliaError = require("./error");
var user = require("./user");
var config = require("./config");
var gearmanode = require("gearmanode");
var mongoose = require("mongoose");
var sqlite3 = require("sqlite3");
var os = require("os");

mongoose.connect(config.db)
var worker = gearmanode.worker({servers: config.gearmand});

var stringifyDate = function(date) {
  return date.getFullYear() + "-" +
    ((date.getMonth() + 1) < 10 ? "0" : "") +
    (date.getMonth() + 1) + "-" +
    (date.getDate() < 10 ? "0" : "") +
    date.getDate();
}

worker.addFunction("statProcessMailbox", function(job) {
  var spawn = require("child_process").spawn,
      mta = spawn("pidof", ["qmail-send"]),
      imap = spawn("pidof", ["dovecot"]),
      smtp = spawn("pidof", ["tcpserver"]);

  var states = {};

  imap.on('close', function (code) {
    if (code == 1) {
      states["imap"] = "not running";
      check();
    } else {
      states["imap"] = "running";
      check();
    }
  });

  smtp.on('close', function (code) {
    if (code == 1) {
      states["smtp"] = "not running";
      check();
    } else {
      states["smtp"] = "running";
      check();
    }
  });

  mta.on('close', function (code) {
    if (code == 1) {
      states["mta"] = "not running";
      check();
    } else {
      states["mta"] = "running";
      check();
    }
  });

  var check = function() {
    if (states.mta &&
        states.imap &&
        states.smtp) {
      job.workComplete(JSON.stringify({result: states}));
    }
  }

});

worker.addFunction("statOS", function(job) {
  var retval = {
    name: os.type(),
    platform: os.platform(),
    arch: os.arch(),
    release: os.release(),
    uptime: os.uptime(),
    load: os.loadavg(),
    totalMemory: os.totalmem(),
    freeMemory: os.freemem(),
    cpus: os.cpus(),
    networkInterfaces: os.networkInterfaces(),

  }
  job.workComplete(JSON.stringify({result: retval}));
});

worker.addFunction("statTopReceiver", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(size) as size from stat where target=0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by size desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        size: row.size
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("statTopFailures", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(retries) as retries from stat where target=0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by retries desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        retries: row.retries
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("statTopRemoteFailures", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(retries) as retries from stat where target=1 and retries > 0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by retries desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        retries: row.retries
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("setPassword", function(job) {
  var payload = JSON.parse(job.payload.toString());
  try {
    user.setPassword([payload.username, payload.oldPassword, payload.newPassword], function(result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      console.log(result);
      job.workComplete(JSON.stringify({result: result}));
    });
  } catch (e) {
    console.log("x");
    job.workComplete(JSON.stringify({result: false, error: e}));
  }
});

worker.addFunction("profile", function(job) {
  var payload = JSON.parse(job.payload.toString());
  try {
    user.profile([payload.username], function(result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      console.log(result);
      job.workComplete(JSON.stringify({result: result}));
    });
  } catch (e) {
    job.workComplete(JSON.stringify({result: false, error: e}));
  }
});

worker.addFunction("updateAlias", function(job) {
  var payload = {};
  try {
    payload = JSON.parse(job.payload.toString());
  } catch (err) {
    console.log("invalid payload JSON");
  }
  if (payload == null) {
      return job.workComplete(JSON.stringify({result: false, error: err}));
  }
  if (payload.data != null && payload.data.alias && payload.data.source) {
    user.updateAlias([payload.data.alias,payload.data.source], function(err, result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      if (err) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      job.workComplete(JSON.stringify({result: result}));
    });
  } else if (payload.data && !payload.data.source) {
    user.updateAlias([payload.data.alias,false], function(err, result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      if (err) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      job.workComplete(JSON.stringify({result: result}));
    });
  }
});
<commit_msg>revisi<commit_after>
var SureliaError = require("./error");
var user = require("./user");
var config = require("./config");
var gearmanode = require("gearmanode");
var mongoose = require("mongoose");
var sqlite3 = require("sqlite3");
var os = require("os");

mongoose.connect(config.db)
var worker = gearmanode.worker({servers: config.gearmand});

var stringifyDate = function(date) {
  return date.getFullYear() + "-" +
    ((date.getMonth() + 1) < 10 ? "0" : "") +
    (date.getMonth() + 1) + "-" +
    (date.getDate() < 10 ? "0" : "") +
    date.getDate();
}

worker.addFunction("statProcessMailbox", function(job) {
  var spawn = require("child_process").spawn,
      mta = spawn("pidof", ["qmail-send"]),
      imap = spawn("pidof", ["dovecot"]),
      smtp = spawn("pidof", ["tcpserver"]);

  var states = {};

  imap.on('close', function (code) {
    if (code == 1) {
      states["imap"] = "not running";
      check();
    } else {
      states["imap"] = "running";
      check();
    }
  });

  smtp.on('close', function (code) {
    if (code == 1) {
      states["smtp"] = "not running";
      check();
    } else {
      states["smtp"] = "running";
      check();
    }
  });

  mta.on('close', function (code) {
    if (code == 1) {
      states["mta"] = "not running";
      check();
    } else {
      states["mta"] = "running";
      check();
    }
  });

  var check = function() {
    if (states.mta &&
        states.imap &&
        states.smtp) {
      job.workComplete(JSON.stringify({result: states}));
    }
  }

});

worker.addFunction("statOS", function(job) {
  var retval = {
    name: os.type(),
    platform: os.platform(),
    arch: os.arch(),
    release: os.release(),
    uptime: os.uptime(),
    load: os.loadavg(),
    totalMemory: os.totalmem(),
    freeMemory: os.freemem(),
    cpus: os.cpus(),
    networkInterfaces: os.networkInterfaces(),

  }
  job.workComplete(JSON.stringify({result: retval}));
});

worker.addFunction("statTopReceiver", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(size) as size from stat where target=0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by size desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        size: row.size
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("statTopFailures", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(retries) as retries from stat where target=0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by retries desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        retries: row.retries
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("statTopRemoteFailures", function(job) {
  var payload = {};
  if (job.payload && job.payload.length > 0) {
    payload = JSON.parse(job.payload.toString());
  }
  var startDate = new Date(), endDate = new Date(startDate);

  startDate.setYear(2000);

  if (payload.startDate) {
    startDate = new Date(payload.startDate);
  }
  if (payload.endDate) {
    endDate = new Date(payload.endDate);
  }

  var db = new sqlite3.Database(config.stat);
  var retval = [];

  db.serialize(function() {
    var start = stringifyDate(startDate);
    var end = stringifyDate(endDate);

    var query = "select eto, sum(retries) as retries from stat where target=1 and retries > 0 and strftime('%Y-%m-%d', start) between '" + start + "' and '" + end + "' group by eto order by retries desc limit 20";
    console.log(query);
    db.each(query, function(err, row) {
      retval.push({
        address: row.eto.replace(config.statStripEmail, ""),
        retries: row.retries
      });
    }, function() {
      db.close();
      job.workComplete(JSON.stringify({result: retval}));
    });
  });
});

worker.addFunction("setPassword", function(job) {
  var payload = JSON.parse(job.payload.toString());
  try {
    user.setPassword([payload.username, payload.oldPassword, payload.newPassword], function(result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      console.log(result);
      job.workComplete(JSON.stringify({result: result}));
    });
  } catch (e) {
    console.log("x");
    job.workComplete(JSON.stringify({result: false, error: e}));
  }
});

worker.addFunction("profile", function(job) {
  var payload = JSON.parse(job.payload.toString());
  try {
    user.profile([payload.username], function(result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      console.log(result);
      job.workComplete(JSON.stringify({result: result}));
    });
  } catch (e) {
    job.workComplete(JSON.stringify({result: false, error: e}));
  }
});

worker.addFunction("updateAlias", function(job) {
  var payload = {};
  try {
    payload = JSON.parse(job.payload.toString());
  } catch (err) {
    console.log("invalid payload JSON");
  }
  if (payload == null) {
      return job.workComplete(JSON.stringify({result: false, error: err}));
  }
  if (payload.data != null && payload.data.alias && payload.data.source) {
    user.updateAlias([payload.data.alias,payload.data.source], function(err, result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      if (err) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      job.workComplete(JSON.stringify({result: result}));
    });
  } else if (payload.data && !payload.data.source) {
    user.updateAlias([payload.data.alias,false], function(err, result){
      if (result instanceof SureliaError) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      if (err) {
        return job.workComplete(JSON.stringify({result: false, error: result}));
      }
      job.workComplete(JSON.stringify({result: result}));
    });
  } else {
    return job.workComplete(JSON.stringify({result: false}));
  }
});
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import AppCard from '../components/AppCard'
import ContentHeader from '../components/ContentHeader'
import Content from '../components/Content'
import Box from '@material-ui/core/Box'
import Container from '@material-ui/core/Container'
import Grid from '@material-ui/core/Grid'
import Paper from '@material-ui/core/Paper'
import Typography from '@material-ui/core/Typography'
import graphql from "../graphql/client"
import { APPS } from "../graphql/queries"

export default class AppListContainer extends Component {

  state = {
    apps: []
  }

  componentDidMount(){

    graphql(APPS ,{} ,{
      success: (data)=>{
        this.setState({ apps: data.apps })
      },
      error: (error)=>{

      }
    })

    /*
    axios.get("/apps.json")
    .then( (response)=> {
      this.setState({apps: response.data.collection}, ()=>{
      })
    })
    .catch( (error)=> {
      console.log(error);
    });*/

    //this.updateNavLinks()
  }

  render(){
     return

              <ContentHeader title={"Apps"}/>

                <Container maxWidth="md">
                  <Box component="span" m={1}>

                      <Typography variant={"h4"} gutterBottom>
                        Your applications
                      </Typography>

                      <Grid container spacing={2}>
                      {
                        this.state.apps.map((o)=> (
                          <Grid
                            key={`app-lst-item-${o.key}`}
                            item xs={12} md={4}>
                            <AppCard
                              app={o}
                              onClick={() => this.props.history.push(`/apps/${o.key}`)}
                            />
                          </Grid>

                        )
                      )}
                      </Grid>

                  </Box>
                </Container>

  }
}<commit_msg>create new button on apps dashboard<commit_after>import React, {Component} from 'react'
import AppCard from '../components/AppCard'
import ContentHeader from '../components/ContentHeader'
import Content from '../components/Content'
import Box from '@material-ui/core/Box'
import Container from '@material-ui/core/Container'
import Grid from '@material-ui/core/Grid'
import Paper from '@material-ui/core/Paper'
import Typography from '@material-ui/core/Typography'
import graphql from "../graphql/client"
import {LinkButton} from '../shared/RouterLink'
import AddIcon from '@material-ui/icons/Add'

import { APPS } from "../graphql/queries"

export default class AppListContainer extends Component {

  state = {
    apps: []
  }

  componentDidMount(){

    graphql(APPS ,{} ,{
      success: (data)=>{
        this.setState({ apps: data.apps })
      },
      error: (error)=>{

      }
    })

    /*
    axios.get("/apps.json")
    .then( (response)=> {
      this.setState({apps: response.data.collection}, ()=>{
      })
    })
    .catch( (error)=> {
      console.log(error);
    });*/

    //this.updateNavLinks()
  }

  render(){
     return

              <ContentHeader title={"Apps"}/>

                <Container maxWidth="md">
                  <Box component="span" m={1}>

                      <Typography variant={"h4"} gutterBottom>
                        Your applications
                      </Typography>

                      <LinkButton
                        variant={'contained'}
                        color={'primary'}
                        onClick={()=> this.props.history.push(`/apps/new`)}>
                        <AddIcon />
                        {"Create new app"}
                      </LinkButton>

                      <Grid container spacing={2}>
                      {
                        this.state.apps.map((o)=> (
                          <Grid
                            key={`app-lst-item-${o.key}`}
                            item xs={12} md={4}>
                            <AppCard
                              app={o}
                              onClick={() => this.props.history.push(`/apps/${o.key}`)}
                            />
                          </Grid>

                        )
                      )}
                      </Grid>

                  </Box>
                </Container>

  }
}<|endoftext|>


<commit_before>var XAJAX;

(function (window, document) {

    var serverCache = {};

    XAJAX = function (serverUrl, callback) {

        var initializationDelay = 1000,
            queue = [],
        // if the iFrame has been initialized
            initialized = false,
        // true, if we can communicate with the iFrame
            loaded = false,
            checkInitializedTimer = null,
            iFrame = null,
            publicMethods,
            messageCount = 0,

        // stores all sent messages, identified by the messageId
            messages = {};

        if (window.addEventListener) {
            addEventListener("message", receiveMessage, false);
        } else {
            attachEvent("onmessage", receiveMessage);
        }

        function receiveMessage(event) {

            var trailingSlash = /\/$/;

            if (event.origin.replace(trailingSlash, "") !== serverUrl.replace(trailingSlash, "")) {
                return;
            }

            if (event.data === "initialized") {
                if (initialized) {
                    return;
                }

                checkInitializedTimer && clearTimeout(checkInitializedTimer);

                initialized = true;
                loaded = true;

                callback && callback(null, publicMethods);

                // progress queue
                for (var i = 0; i < queue.length; i++) {
                    var request = queue[i];
                    publicMethods.ajax(request.url, request.options, request.callback);
                }

                queue = [];
            } else if (initialized) {

                var eventData = JSON.parse(event.data),
                    messageId = eventData.messageId,
                    messageObject = messages[messageId];

                if (messageObject && messageObject.callback) {
                    messageObject.callback(eventData.error, eventData.data);
                }

                delete messages[messageId];
            }
        }

        initializeIFrame();

        function initializeIFrame() {

            iFrame = document.createElement("iframe");
            iFrame.onload = function () {

                if (!initialized) {
                    checkInitializedTimer = setTimeout(function () {
                        initialized = true;
                        callback(new Error("Initialisation failed"), publicMethods);
                    }, initializationDelay);
                }

            };

            iFrame.src = serverUrl;
            iFrame.style.visibility = "hidden";
            iFrame.style.display = "none";

            //noinspection XHTMLIncompatabilitiesJS
            var body = document.body || document.getElementsByTagName("body")[0];

            body.appendChild(iFrame);

        }

        function sendMessage(type, data, callback) {
            messageCount++;

            var message = {
                type: type,
                data: data,
                messageId: messageCount
            };

            messages[messageCount] = {
                message: message,
                callback: callback
            };

            iFrame.contentWindow.postMessage(JSON.stringify(message), serverUrl);
        }

        // Public methods
        publicMethods = {

            /***
             * make cross domain ajax calls
             *
             * @param url - the request url
             * @param [options]
             * @param [callback] - callback function(err, result)
             */
            ajax: function (url, options, callback) {

                if (initialized) {
                    if (loaded) {
                        // perform post message on iFrame window

                        sendMessage("ajax", {
                            url: url,
                            options: options
                        }, callback);

                    } else {
                        callback && callback(new Error("Cannot communicate with iFrame"));
                    }

                } else {
                    // queue it
                    queue.push({
                        url: url,
                        options: options,
                        callback: callback
                    });
                }
            }
        };

        return publicMethods;
    };

    /***
     *
     * @param serverUrl - the url where the receiveMessage proxy lives
     * @param [callback]
     * @returns {XAJAX}
     */
    XAJAX.create = function (serverUrl, callback) {

        var instance;

        if (!serverCache.hasOwnProperty(serverUrl)) {

            instance = new XAJAX(serverUrl, function (err) {

                var cacheEntry = serverCache[serverUrl];

                cacheEntry.initialized = true;
                cacheEntry.initializedError = err;

                // invoke all callbacks
                var callbacks = cacheEntry.callbacks;

                for (var i = 0; i < callbacks.length; i++) {
                    callbacks[i] && callbacks[i](err);
                }
            });

            serverCache[serverUrl] = {
                callbacks: [callback],
                initialized: false,
                initializedError: null,
                instance: instance
            };
        } else {

            var cacheEntry = serverCache[serverUrl];

            if (cacheEntry.initialized) {
                callback && callback(cacheEntry.initializedError);
            } else {
                cacheEntry.callbacks.push(callback);
            }

            instance = cacheEntry.instance;
        }

        return instance;

    }

})(window, document);<commit_msg>check same origin<commit_after>var XAJAX;

(function (window, document) {

    var serverCache = {};

    XAJAX = function (serverUrl, callback) {

        var initializationDelay = 1000,
            queue = [],
        // if the iFrame has been initialized
            initialized = false,
        // true, if we can communicate with the iFrame
            loaded = false,
            checkInitializedTimer = null,
            iFrame = null,
            publicMethods,
            messageCount = 0,

        // stores all sent messages, identified by the messageId
            messages = {};

        if (window.addEventListener) {
            addEventListener("message", receiveMessage, false);
        } else {
            attachEvent("onmessage", receiveMessage);
        }

        function receiveMessage(event) {

            if (serverUrl.indexOf(event.origin) !== 0) {
                return;
            }

            if (event.data === "initialized") {
                if (initialized) {
                    return;
                }

                checkInitializedTimer && clearTimeout(checkInitializedTimer);

                initialized = true;
                loaded = true;

                callback && callback(null, publicMethods);

                // progress queue
                for (var i = 0; i < queue.length; i++) {
                    var request = queue[i];
                    publicMethods.ajax(request.url, request.options, request.callback);
                }

                queue = [];
            } else if (initialized) {

                var eventData = JSON.parse(event.data),
                    messageId = eventData.messageId,
                    messageObject = messages[messageId];

                if (messageObject && messageObject.callback) {
                    messageObject.callback(eventData.error, eventData.data);
                }

                delete messages[messageId];
            }
        }

        initializeIFrame();

        function initializeIFrame() {

            iFrame = document.createElement("iframe");
            iFrame.onload = function () {

                if (!initialized) {
                    checkInitializedTimer = setTimeout(function () {
                        initialized = true;
                        callback(new Error("Initialisation failed"), publicMethods);
                    }, initializationDelay);
                }

            };

            iFrame.src = serverUrl;
            iFrame.style.visibility = "hidden";
            iFrame.style.display = "none";

            //noinspection XHTMLIncompatabilitiesJS
            var body = document.body || document.getElementsByTagName("body")[0];

            body.appendChild(iFrame);

        }

        function sendMessage(type, data, callback) {
            messageCount++;

            var message = {
                type: type,
                data: data,
                messageId: messageCount
            };

            messages[messageCount] = {
                message: message,
                callback: callback
            };

            iFrame.contentWindow.postMessage(JSON.stringify(message), serverUrl);
        }

        // Public methods
        publicMethods = {

            /***
             * make cross domain ajax calls
             *
             * @param url - the request url
             * @param [options]
             * @param [callback] - callback function(err, result)
             */
            ajax: function (url, options, callback) {

                if (initialized) {
                    if (loaded) {
                        // perform post message on iFrame window

                        sendMessage("ajax", {
                            url: url,
                            options: options
                        }, callback);

                    } else {
                        callback && callback(new Error("Cannot communicate with iFrame"));
                    }

                } else {
                    // queue it
                    queue.push({
                        url: url,
                        options: options,
                        callback: callback
                    });
                }
            }
        };

        return publicMethods;
    };

    /***
     *
     * @param serverUrl - the url where the receiveMessage proxy lives
     * @param [callback]
     * @returns {XAJAX}
     */
    XAJAX.create = function (serverUrl, callback) {

        var instance;

        if (!serverCache.hasOwnProperty(serverUrl)) {

            instance = new XAJAX(serverUrl, function (err) {

                var cacheEntry = serverCache[serverUrl];

                cacheEntry.initialized = true;
                cacheEntry.initializedError = err;

                // invoke all callbacks
                var callbacks = cacheEntry.callbacks;

                for (var i = 0; i < callbacks.length; i++) {
                    callbacks[i] && callbacks[i](err);
                }
            });

            serverCache[serverUrl] = {
                callbacks: [callback],
                initialized: false,
                initializedError: null,
                instance: instance
            };
        } else {

            var cacheEntry = serverCache[serverUrl];

            if (cacheEntry.initialized) {
                callback && callback(cacheEntry.initializedError);
            } else {
                cacheEntry.callbacks.push(callback);
            }

            instance = cacheEntry.instance;
        }

        return instance;

    }

})(window, document);<|endoftext|>


<commit_before>var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var app = express();
const serverPort = 8091; // default port

var deviceName = 'Google Home';
var ip = '192.168.1.20'; // default IP

var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.post('/google-home-notifier', urlencodedParser, function (req, res) {

  if (!req.body) return res.sendStatus(400)
  console.log(req.body);

  var text = req.body.text;

  if (req.query.ip) {
     ip = req.query.ip;
  }

  var language = 'pl'; // default language code
  if (req.query.language) {
    language;
  }

  googlehome.ip(ip, language);

  if (text){
    try {
      if (text.startsWith('http'){
        var mp3_url = text;
        googlehome.play(mp3_url, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will play sound from url: ' + mp3_url + '\n');
        });
      } else {
        googlehome.notify(text, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will say: ' + text + '\n');
        });
      }
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please GET "text=Hello Google Home"');
  }
})

app.get('/google-home-notifier', function (req, res) {

  console.log(req.query);

  var text = req.query.text;

  if (req.query.ip) {
     ip = req.query.ip;
  }

  var language = 'pl'; // default language code
  if (req.query.language) {
    language;
  }

  googlehome.ip(ip, language);

  if (text) {
    try {
      googlehome.notify(text, function(notifyRes) {
        console.log(notifyRes);
        res.send(deviceName + ' will say: ' + text + '\n');
      });
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please GET "text=Hello+Google+Home"');
  }
})

app.listen(serverPort, function () {
  ngrok.connect(serverPort, function (err, url) {
    console.log('Endpoints:');
    console.log('    http://' + ip + ':' + serverPort + '/google-home-notifier');
    console.log('    ' + url + '/google-home-notifier');
    console.log('GET example:');
    console.log('curl -X GET ' + url + '/google-home-notifier?text=Hello+Google+Home');
	console.log('POST example:');
	console.log('curl -X POST -d "text=Hello Google Home" ' + url + '/google-home-notifier');
  });
})
<commit_msg>play file from url when text starts with http<commit_after>var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var app = express();
const serverPort = 8091; // default port

var deviceName = 'Google Home';
var ip = '192.168.1.20'; // default IP

var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.post('/google-home-notifier', urlencodedParser, function (req, res) {

  if (!req.body) return res.sendStatus(400)
  console.log(req.body);

  var text = req.body.text;

  if (req.query.ip) {
     ip = req.query.ip;
  }

  var language = 'pl'; // default language code
  if (req.query.language) {
    language;
  }

  googlehome.ip(ip, language);

  if (text){
    try {
      if (text.startsWith('http')){
        var mp3_url = text;
        googlehome.play(mp3_url, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will play sound from url: ' + mp3_url + '\n');
        });
      } else {
        googlehome.notify(text, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will say: ' + text + '\n');
        });
      }
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please GET "text=Hello Google Home"');
  }
})

app.get('/google-home-notifier', function (req, res) {

  console.log(req.query);

  var text = req.query.text;

  if (req.query.ip) {
     ip = req.query.ip;
  }

  var language = 'pl'; // default language code
  if (req.query.language) {
    language;
  }

  googlehome.ip(ip, language);

  if (text) {
    try {
      if (text.startsWith('http')){
        var mp3_url = text;
        googlehome.play(mp3_url, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will play sound from url: ' + mp3_url + '\n');
        });
      } else {
        googlehome.notify(text, function(notifyRes) {
          console.log(notifyRes);
          res.send(deviceName + ' will say: ' + text + '\n');
        });
      }
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please GET "text=Hello+Google+Home"');
  }
})

app.listen(serverPort, function () {
  ngrok.connect(serverPort, function (err, url) {
    console.log('Endpoints:');
    console.log('    http://' + ip + ':' + serverPort + '/google-home-notifier');
    console.log('    ' + url + '/google-home-notifier');
    console.log('GET example:');
    console.log('curl -X GET ' + url + '/google-home-notifier?text=Hello+Google+Home');
	console.log('POST example:');
	console.log('curl -X POST -d "text=Hello Google Home" ' + url + '/google-home-notifier');
  });
})
<|endoftext|>


<commit_before>export function updateQueryParams(params) {
  // store current query in an object
  const search = document.location.search.replace('?', '')
  const queryObj = {}
  if (search.length) {
    const searchArr = search.split('&')
    for (const str of searchArr) {
      const keyValueArr = str.split('=')
      queryObj[keyValueArr[0]] = keyValueArr[1]
    }
  }
  // set/delete params
  for (const param in params) {
    if (params[param] !== null) {
      queryObj[param] = params[param]
    } else {
      delete queryObj[param]
    }
  }
  // create query array
  const queryArr = []
  for (const key in queryObj) {
    if (queryObj[key] !== null) {
      queryArr.push(`${key}=${queryObj[key]}`)
    }
  }
  // re-assemble the query string
  let query = ''
  if (queryArr.length) {
    query = '?' + queryArr.join('&')
  }
  return query
}

<commit_msg>Encode query param values on search.<commit_after>export function updateQueryParams(params) {
  // store current query in an object
  const search = document.location.search.replace('?', '')
  const queryObj = {}
  if (search.length) {
    const searchArr = search.split('&')
    for (const str of searchArr) {
      const keyValueArr = str.split('=')
      queryObj[keyValueArr[0]] = keyValueArr[1]
    }
  }
  // set/delete params
  for (const param in params) {
    if (params[param] !== null) {
      queryObj[param] = window.encodeURIComponent(params[param])
    } else {
      delete queryObj[param]
    }
  }
  // create query array
  const queryArr = []
  for (const key in queryObj) {
    if (queryObj[key] !== null) {
      queryArr.push(`${key}=${queryObj[key]}`)
    }
  }
  // re-assemble the query string
  let query = ''
  if (queryArr.length) {
    query = '?' + queryArr.join('&')
  }
  return query
}

<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Dropdown, Button, Tabs, Input, Card, Menu, Icon, Col, Spin } from 'antd';
import { withRouter, withCollection, withItems, Link, withApollo, throttleInput } from 'olymp';
import Image from '../../edits/image';
import { createComponent } from 'react-fela';
import tinycolor from 'tinycolor2';
import Filter from './filter';

const StyledSidebar = createComponent(() => ({
  left: 0,
  top: 0,
  width: '340px',
  bottom: 0,
  position: 'fixed',
  backgroundColor: '#f9f9f9',
  borderRight: '1px solid #e0e0e0',
  zIndex: 3,
}));

const StyledPanel = createComponent(({ seperator, align, padding }) => ({
  padding: padding || '5px 10px',
  borderTop: seperator ? '1px solid #e6e6e6' : 0,
  textAlign: align,
}));

const StyledTitle = createComponent(() => ({
  fontSize: '20px',
  paddingTop: '10px',
  paddingBottm: '5px',
}), 'h1');

const StyledButton = createComponent(({ theme }) => ({
  ':hover': {
    color: `${theme.color}!important`,
    borderColor: `${theme.color}!important`,
  },
}), props => <Button {...props} />, ['placeholder']);

const StyledCard = createComponent(({ isActive, color }) => {
  const colorStyle = {};
  if (color) {
    colorStyle.backgroundColor = tinycolor(color).setAlpha(0.33).toRgbString();
    // colorStyle.color = tinycolor(item.farbe).isLight ? '#333' : '#CCC';
    colorStyle.color = '#333';
  }

  const activeStyle = {};
  if (isActive) {
    activeStyle.left = '15px';
    activeStyle.borderWidth = '0!important';
    activeStyle.boxShadow = '0 0 5px 0 rgba(0, 0, 0, .33)';
  }

  return {
    cursor: 'pointer',
    margin: '3px 0',
    ...activeStyle,
    ...colorStyle,
    '> .ant-card-extra': {
      top: '5px',
      right: '5px',
    },
    '> .ant-card-body': {
      padding: 0,
      ...colorStyle,
    },
  };
}, props => <Card {...props} />, ['onClick', 'extra']);

const StyledCardContent = createComponent(() => ({
  padding: '5px',
  position: 'absolute',
  left: '65px',
  top: '50%',
  transform: 'translateY(-50%)',
}));

const StyledCardTitle = createComponent(() => ({
  textOverflow: 'ellipsis',
  overflow: 'hidden',
  width: '200px',
  whiteSpace: 'nowrap',
}), 'h6');

const StyledCardParagraph = createComponent(() => ({
  margin: 0,
  textOverflow: 'ellipsis',
  overflow: 'hidden',
  width: '200px',
  whiteSpace: 'nowrap',
}), 'p');

@withItems({ })
@withRouter
class CollectionList extends Component {
  getLink = (item) => {
    const { collection, location } = this.props;
    const { pathname } = location;
    return { pathname, query: { ...location.query, [`@${collection.name.toLowerCase()}`]: item ? item.id : null } };
  }

  renderMenu = () => {
    const { name } = this.props;

    return (
      <Menu>
        <Menu.Item>
          Bearbeiten
        </Menu.Item>
        <Menu.Item>
          Kopieren
        </Menu.Item>
        <Menu.Item>
          {name !== 'REMOVED'
            ? 'Löschen'
            : 'Wiederherstellen'
          }
        </Menu.Item>
      </Menu>
    );
  }

  renderCard = (item) => {
    const { id, router } = this.props;

    return (

        </StyledCardContent>
      </StyledCard>
    );
  }

  render() {
    const { items, isLoading } = this.props;

    if (isLoading) return <Spin />;

    return (

        {items && items.map(item => this.renderCard(item))}

    );
  }
}

const states = {
  PUBLISHED: 'Öffentlich',
  DRAFT: 'Entwurf',
  ARCHIVED: 'Archiv',
  REMOVED: 'Papierkorb',
};

@withApollo
@withRouter
@withCollection
export default class CollectionListSidebar extends Component {
  state = { query: { state: { eq: 'PUBLISHED' } }, filtering: false, searchText: '' };
  throttle = throttleInput();

  setQuery = (query) => {
    this.setState({
      filtering: true,
      searchText: '',
      query,
    });
  }

  setQueryToState = (eq = 'PUBLISHED') => {
    this.setState({
      filtering: false,
      query: { state: { eq } },
      searchText: '',
    });
  }

  search = (e) => {
    if (!e.target.value) return this.setQueryToState();
    const searchText = e.target.value;
    this.setState({
      searchText,
    });
    this.throttle(() => {
      if (!this.state.searchText) return;
      this.setState({
        filtering: true,
        query: { name: { contains: this.state.searchText } },
      });
    });
  }

  getLink = (item) => {
    const { onClick, collection, name, saveCollectionItem, removeCollectionItem, location, items } = this.props;
    const { pathname } = location;
    return { pathname, query: { ...location.query, [`@${collection.name.toLowerCase()}`]: item ? item.id : null } };
  }

  render() {
    const { onClick, collection, name, saveCollectionItem, removeCollectionItem, location, items, id, router } = this.props;
    const { query, filtering, searchText } = this.state;

    return (

        </StyledPanel>

        {!filtering && (

        )}

      </StyledSidebar>
    );
  }
}
<commit_msg>Remove shadows in active cards<commit_after>import React, { Component } from 'react';
import { Dropdown, Button, Tabs, Input, Card, Menu, Icon, Col, Spin } from 'antd';
import { withRouter, withCollection, withItems, Link, withApollo, throttleInput } from 'olymp';
import Image from '../../edits/image';
import { createComponent } from 'react-fela';
import tinycolor from 'tinycolor2';
import Filter from './filter';

const StyledSidebar = createComponent(() => ({
  left: 0,
  top: 0,
  width: '340px',
  bottom: 0,
  position: 'fixed',
  backgroundColor: '#f9f9f9',
  borderRight: '1px solid #e0e0e0',
  zIndex: 3,
}));

const StyledPanel = createComponent(({ seperator, align, padding }) => ({
  padding: padding || '5px 10px',
  borderTop: seperator ? '1px solid #e6e6e6' : 0,
  textAlign: align,
}));

const StyledTitle = createComponent(() => ({
  fontSize: '20px',
  paddingTop: '10px',
  paddingBottm: '5px',
}), 'h1');

const StyledButton = createComponent(({ theme }) => ({
  ':hover': {
    color: `${theme.color}!important`,
    borderColor: `${theme.color}!important`,
  },
}), props => <Button {...props} />, ['placeholder']);

const StyledCard = createComponent(({ isActive, color }) => {
  const colorStyle = {};
  if (color) {
    colorStyle.backgroundColor = tinycolor(color).setAlpha(0.33).toRgbString();
    // colorStyle.color = tinycolor(item.farbe).isLight ? '#333' : '#CCC';
    colorStyle.color = '#333';
  }

  const activeStyle = {};
  if (isActive) {
    activeStyle.left = '15px';
    // activeStyle.borderWidth = '0!important';
    // activeStyle.boxShadow = '0 0 5px 0 rgba(0, 0, 0, .33)';
  }

  return {
    cursor: 'pointer',
    margin: '3px 0',
    ...activeStyle,
    ...colorStyle,
    '> .ant-card-extra': {
      top: '5px',
      right: '5px',
    },
    '> .ant-card-body': {
      padding: 0,
      ...colorStyle,
    },
  };
}, props => <Card {...props} />, ['onClick', 'extra']);

const StyledCardContent = createComponent(() => ({
  padding: '5px',
  position: 'absolute',
  left: '65px',
  top: '50%',
  transform: 'translateY(-50%)',
}));

const StyledCardTitle = createComponent(() => ({
  textOverflow: 'ellipsis',
  overflow: 'hidden',
  width: '200px',
  whiteSpace: 'nowrap',
}), 'h6');

const StyledCardParagraph = createComponent(() => ({
  margin: 0,
  textOverflow: 'ellipsis',
  overflow: 'hidden',
  width: '200px',
  whiteSpace: 'nowrap',
}), 'p');

@withItems({ })
@withRouter
class CollectionList extends Component {
  getLink = (item) => {
    const { collection, location } = this.props;
    const { pathname } = location;
    return { pathname, query: { ...location.query, [`@${collection.name.toLowerCase()}`]: item ? item.id : null } };
  }

  renderMenu = () => {
    const { name } = this.props;

    return (
      <Menu>
        <Menu.Item>
          Bearbeiten
        </Menu.Item>
        <Menu.Item>
          Kopieren
        </Menu.Item>
        <Menu.Item>
          {name !== 'REMOVED'
            ? 'Löschen'
            : 'Wiederherstellen'
          }
        </Menu.Item>
      </Menu>
    );
  }

  renderCard = (item) => {
    const { id, router } = this.props;

    return (

        </StyledCardContent>
      </StyledCard>
    );
  }

  render() {
    const { items, isLoading } = this.props;

    if (isLoading) return <Spin />;

    return (

        {items && items.map(item => this.renderCard(item))}

    );
  }
}

const states = {
  PUBLISHED: 'Öffentlich',
  DRAFT: 'Entwurf',
  ARCHIVED: 'Archiv',
  REMOVED: 'Papierkorb',
};

@withApollo
@withRouter
@withCollection
export default class CollectionListSidebar extends Component {
  state = { query: { state: { eq: 'PUBLISHED' } }, filtering: false, searchText: '' };
  throttle = throttleInput();

  setQuery = (query) => {
    this.setState({
      filtering: true,
      searchText: '',
      query,
    });
  }

  setQueryToState = (eq = 'PUBLISHED') => {
    this.setState({
      filtering: false,
      query: { state: { eq } },
      searchText: '',
    });
  }

  search = (e) => {
    if (!e.target.value) return this.setQueryToState();
    const searchText = e.target.value;
    this.setState({
      searchText,
    });
    this.throttle(() => {
      if (!this.state.searchText) return;
      this.setState({
        filtering: true,
        query: { name: { contains: this.state.searchText } },
      });
    });
  }

  getLink = (item) => {
    const { onClick, collection, name, saveCollectionItem, removeCollectionItem, location, items } = this.props;
    const { pathname } = location;
    return { pathname, query: { ...location.query, [`@${collection.name.toLowerCase()}`]: item ? item.id : null } };
  }

  render() {
    const { onClick, collection, name, saveCollectionItem, removeCollectionItem, location, items, id, router } = this.props;
    const { query, filtering, searchText } = this.state;

    return (

        </StyledPanel>

        {!filtering && (

        )}

      </StyledSidebar>
    );
  }
}
<|endoftext|>


<commit_before>/**
 * @author Benjamin Hollis
 *
 * This component provides a stream converter that can translate from JSON to HTML.
 * It is compatible with Firefox 3 and up, since it uses many components that are new
 * to Firefox 3.
 */

// Save some tedious typing
const Ci = Components.interfaces;
const Cc = Components.classes;

// Import XPCOMUtils to help set up our JSONView XPCOM component (new to FF3)
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

// Let us use FUEL
var Application = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);

/*
 * The JSONFormatter helper object. This contains two major functions, jsonToHTML and errorPage,
 * each of which returns an HTML document.
 */
function JSONFormatter() {
  var src = 'chrome://jsonview/locale/jsonview.properties';
  var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);

  var appLocale = localeService.getApplicationLocale();
  var stringBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
  this.stringbundle = stringBundleService.createBundle(src, appLocale);
}
JSONFormatter.prototype = {
  htmlEncode: function (t) {
    return t ? t.toString().replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">") : '';
  },

  decorateWithSpan: function (value, className) {
    return '' + this.htmlEncode(value) + '';
  },

  // Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
  valueToHTML: function(value) {
    var valueType = typeof value;

    var output = "";
    if (value == null) {
      output += this.decorateWithSpan('null', 'null');
    }
    else if (value && value.constructor == Array) {
      output += this.arrayToHTML(value);
    }
    else if (valueType == 'object') {
      output += this.objectToHTML(value);
    }
    else if (valueType == 'number') {
      output += this.decorateWithSpan(value, 'num');
    }
    else if (valueType == 'string') {
      if (/^(http|https):\/\/[^\s]+$/.test(value)) {
        output += '' + this.htmlEncode(value) + '';
      } else {
        output += this.decorateWithSpan('"' + value + '"', 'string');
      }
    }
    else if (valueType == 'boolean') {
      output += this.decorateWithSpan(value, 'bool');
    }

    return output;
  },

  // Convert an array into an HTML fragment
  arrayToHTML: function(json) {
    var output = '[
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
]';

    if ( ! hasContents ) {
      output = "[ ]";
    }

    return output;
  },

  // Convert a JSON object to an HTML fragment
  objectToHTML: function(json) {
    var output = '{
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += '' + this.htmlEncode(prop) + ': '
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
}';

    if ( ! hasContents ) {
      output = "{ }";
    }

    return output;
  },

  // Convert a whole JSON object into a formatted HTML document.
  jsonToHTML: function(json, callback, uri) {
    var output = '';
    if( callback ){
      output += '
' + callback + ' (
';
      output += '
';
    }else{
      output += '
';
    }
    output += this.valueToHTML(json);
    output += '
';
    if( callback ){
      output += '
)
';
    }
    return this.toHTML(output, uri);
  },

  // Produce an error document for when parsing fails.
  errorPage: function(error, data, uri) {
    var output = '
' + this.stringbundle.GetStringFromName('errorParsing') + '
';
    output += '
' + this.stringbundle.GetStringFromName('docContents') + ':
';
    output += '
' + this.htmlEncode(data) + '
';
    return this.toHTML(output, uri + ' - Error');
  },

  // Wrap the HTML fragment in a full document. Used by jsonToHTML and errorPage.
  toHTML: function(content, title) {
    return '<doctype html>' +
      '<title>' + title + '</title>' +
      '<link rel="stylesheet" type="text/css" href="chrome://jsonview/content/default.css">' +
      '' +
      '' +
      content +
      '';
  }
};

// This component is an implementation of nsIStreamConverter that converts application/json to html
const JSONVIEW_CONVERSION =
    "?from=application/json&to=*/*";
const JSONVIEW_CONTRACT_ID =
    "@mozilla.org/streamconv;1" + JSONVIEW_CONVERSION;
const JSONVIEW_COMPONENT_ID =
    Components.ID("{64890660-53c4-11dd-ae16-0800200c9a66}");

// JSONView class constructor. Not much to see here.
function JSONView() {
  // Allow us to directly access this from JavaScript
  this.wrappedJSObject = this;

  // Native JSON implementation, new to FF3
  this.nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  this.jsonFormatter = new JSONFormatter();
};

// This defines an object that implements our converter, and is set up to be XPCOM-ified by XPCOMUtils
JSONView.prototype = {

  // properties required for XPCOM registration:
  classDescription: "JSONView XPCOM Component",
  classID:          JSONVIEW_COMPONENT_ID,
  contractID:       JSONVIEW_CONTRACT_ID,

  _xpcom_categories: [{
    category: "@mozilla.org/streamconv;1",
    entry: JSONVIEW_CONVERSION,
    value: "JSON to HTML stream converter"
  }],

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  /*
   * This component works as such:
   * 1. asyncConvertData captures the listener
   * 2. onStartRequest fires, initializes stuff, modifies the listener to match our output type
   * 3. onDataAvailable transcodes the data into a UTF-8 string
   * 4. onStopRequest gets the collected data and converts it, spits it to the listener
   * 5. convert does nothing, it's just the synchronous version of asyncConvertData
   */

  // nsIStreamConverter::convert
  convert: function (aFromStream, aFromType, aToType, aCtxt) {
      return aFromStream;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function (aFromType, aToType, aListener, aCtxt) {
    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
    // From https://developer.mozilla.org/en/Reading_textual_data
    var is = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
    is.init(aInputStream, this.charset, -1, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);

    var str = {};

    // This used to read in a loop until readString returned 0, but it caused it to crash Firefox on OSX/Win32 (but not Win64)
    // It seems just reading once with -1 (default buffer size) gets the file done.
    is.readString(-1, str)
    this.data += str.value;
  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function (aRequest, aContext) {
    this.data = '';
    this.uri = aRequest.QueryInterface(Ci.nsIChannel).URI.spec;

    // Sets the charset if it is available. (For documents loaded from the
    // filesystem, this is not set.)
    this.charset = aRequest.QueryInterface(Ci.nsIChannel).contentCharset || 'UTF-8';

    this.channel = aRequest;
    this.channel.contentType = "text/html";
    // All our data will be coerced to UTF-8
    this.channel.contentCharset = "UTF-8";

    this.listener.onStartRequest (this.channel, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function (aRequest, aContext, aStatusCode) {
    /*
     * This should go something like this:
     * 1. Make sure we have a unicode string.
     * 2. Convert it to a Javascript object.
     * 2.1 Removes the callback
     * 3. Convert that to HTML? Or XUL?
     * 4. Spit it back out at the listener
     */

    var converter = Components
        .classes["@mozilla.org/intl/scriptableunicodeconverter"]
        .createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = this.charset;
    var outputDoc = "";

    var cleanData = '',
        callback = '';

    // This regex attempts to match a JSONP structure:
    //    * Any amount of whitespace (including unicode nonbreaking spaces) between the start of the file and the callback name
    //    * Callback name (any valid JavaScript function name according to ECMA-262 Edition 3 spec)
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Open parentheses
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Either { or [, the only two valid characters to start a JSON string.
    //    * Any character, any number of times
    //    * Either } or ], the only two valid closing characters of a JSON string.
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * A closing parenthesis, an optional semicolon, and any amount of whitespace (including unicode nonbreaking spaces) until the end of the file.
    // This will miss anything that has comments, or more than one callback, or requires modification before use.
    var callback_results = /^[\s\u200B\uFEFF]*([\w$\[\]\.]+)[\s\u200B\uFEFF]*\([\s\u200B\uFEFF]*([\[{][\s\S]*[\]}])[\s\u200B\uFEFF]*\);?[\s\u200B\uFEFF]*$/.exec(this.data);
    if( callback_results && callback_results.length == 3 ){
      callback = callback_results[1];
      cleanData = callback_results[2];
    }else{
      cleanData = this.data;
    }

    try {
      var jsonObj = this.nativeJSON.decode(cleanData);
      if ( jsonObj ) {
        outputDoc = this.jsonFormatter.jsonToHTML(jsonObj, callback, this.uri);
      } else {
        throw "There was no object!";
      }
    }
    catch(e) {
      outputDoc = this.jsonFormatter.errorPage(e, this.data, this.uri);
    }

    // I don't really understand this part, but basically it's a way to get our UTF-8 stuff
    // spit back out as a byte stream
    // See http://www.mail-archive.com/mozilla-xpcom@mozilla.org/msg04194.html
    var storage = Cc["@mozilla.org/storagestream;1"]
    .createInstance(Ci.nsIStorageStream);

    // I have no idea what to pick for the first parameter (segments)
    storage.init(4, 0xffffffff, null);
    var out = storage.getOutputStream(0);

    var binout = Cc["@mozilla.org/binaryoutputstream;1"]
    .createInstance(Ci.nsIBinaryOutputStream);
    binout.setOutputStream(out);
    binout.writeUtf8Z(outputDoc);
    binout.close();

    // I can't explain it, but we need to trim 4 bytes off the front or else it includes random crap
    var trunc = 4;
    var instream = storage.newInputStream(trunc);

    // Pass the data to the main content listener
    this.listener.onDataAvailable(this.channel, aContext, instream, 0, storage.length - trunc);

    this.listener.onStopRequest(this.channel, aContext, aStatusCode);
  }
};

// We only have one component to register
var components = [JSONView];

// The actual hook into XPCOM
function NSGetModule(compMgr, fileSpec) {
  function postRegister() {
     var catMgr = XPCOMUtils.categoryManager;
     catMgr.addCategoryEntry('ext-to-type-mapping','json','application/json',true,true);
  }

  function preUnregister() {
     var catMgr = XPCOMUtils.categoryManager;
     catMgr.addCategoryEntry('ext-to-type-mapping','json',true);
  }

  return XPCOMUtils.generateModule(components, postRegister, preUnregister);
}
<commit_msg>Remove unnecessary wrappedJSObject property.<commit_after>/**
 * @author Benjamin Hollis
 *
 * This component provides a stream converter that can translate from JSON to HTML.
 * It is compatible with Firefox 3 and up, since it uses many components that are new
 * to Firefox 3.
 */

// Save some tedious typing
const Ci = Components.interfaces;
const Cc = Components.classes;

// Import XPCOMUtils to help set up our JSONView XPCOM component (new to FF3)
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

// Let us use FUEL
var Application = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);

/*
 * The JSONFormatter helper object. This contains two major functions, jsonToHTML and errorPage,
 * each of which returns an HTML document.
 */
function JSONFormatter() {
  var src = 'chrome://jsonview/locale/jsonview.properties';
  var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);

  var appLocale = localeService.getApplicationLocale();
  var stringBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
  this.stringbundle = stringBundleService.createBundle(src, appLocale);
}
JSONFormatter.prototype = {
  htmlEncode: function (t) {
    return t ? t.toString().replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">") : '';
  },

  decorateWithSpan: function (value, className) {
    return '' + this.htmlEncode(value) + '';
  },

  // Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
  valueToHTML: function(value) {
    var valueType = typeof value;

    var output = "";
    if (value == null) {
      output += this.decorateWithSpan('null', 'null');
    }
    else if (value && value.constructor == Array) {
      output += this.arrayToHTML(value);
    }
    else if (valueType == 'object') {
      output += this.objectToHTML(value);
    }
    else if (valueType == 'number') {
      output += this.decorateWithSpan(value, 'num');
    }
    else if (valueType == 'string') {
      if (/^(http|https):\/\/[^\s]+$/.test(value)) {
        output += '' + this.htmlEncode(value) + '';
      } else {
        output += this.decorateWithSpan('"' + value + '"', 'string');
      }
    }
    else if (valueType == 'boolean') {
      output += this.decorateWithSpan(value, 'bool');
    }

    return output;
  },

  // Convert an array into an HTML fragment
  arrayToHTML: function(json) {
    var output = '[
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
]';

    if ( ! hasContents ) {
      output = "[ ]";
    }

    return output;
  },

  // Convert a JSON object to an HTML fragment
  objectToHTML: function(json) {
    var output = '{
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += '' + this.htmlEncode(prop) + ': '
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
}';

    if ( ! hasContents ) {
      output = "{ }";
    }

    return output;
  },

  // Convert a whole JSON object into a formatted HTML document.
  jsonToHTML: function(json, callback, uri) {
    var output = '';
    if( callback ){
      output += '
' + callback + ' (
';
      output += '
';
    }else{
      output += '
';
    }
    output += this.valueToHTML(json);
    output += '
';
    if( callback ){
      output += '
)
';
    }
    return this.toHTML(output, uri);
  },

  // Produce an error document for when parsing fails.
  errorPage: function(error, data, uri) {
    var output = '
' + this.stringbundle.GetStringFromName('errorParsing') + '
';
    output += '
' + this.stringbundle.GetStringFromName('docContents') + ':
';
    output += '
' + this.htmlEncode(data) + '
';
    return this.toHTML(output, uri + ' - Error');
  },

  // Wrap the HTML fragment in a full document. Used by jsonToHTML and errorPage.
  toHTML: function(content, title) {
    return '<doctype html>' +
      '<title>' + title + '</title>' +
      '<link rel="stylesheet" type="text/css" href="chrome://jsonview/content/default.css">' +
      '' +
      '' +
      content +
      '';
  }
};

// This component is an implementation of nsIStreamConverter that converts application/json to html
const JSONVIEW_CONVERSION =
    "?from=application/json&to=*/*";
const JSONVIEW_CONTRACT_ID =
    "@mozilla.org/streamconv;1" + JSONVIEW_CONVERSION;
const JSONVIEW_COMPONENT_ID =
    Components.ID("{64890660-53c4-11dd-ae16-0800200c9a66}");

// JSONView class constructor. Not much to see here.
function JSONView() {
  // Native JSON implementation, new to FF3
  this.nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
  this.jsonFormatter = new JSONFormatter();
};

// This defines an object that implements our converter, and is set up to be XPCOM-ified by XPCOMUtils
JSONView.prototype = {

  // properties required for XPCOM registration:
  classDescription: "JSONView XPCOM Component",
  classID:          JSONVIEW_COMPONENT_ID,
  contractID:       JSONVIEW_CONTRACT_ID,

  _xpcom_categories: [{
    category: "@mozilla.org/streamconv;1",
    entry: JSONVIEW_CONVERSION,
    value: "JSON to HTML stream converter"
  }],

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  /*
   * This component works as such:
   * 1. asyncConvertData captures the listener
   * 2. onStartRequest fires, initializes stuff, modifies the listener to match our output type
   * 3. onDataAvailable transcodes the data into a UTF-8 string
   * 4. onStopRequest gets the collected data and converts it, spits it to the listener
   * 5. convert does nothing, it's just the synchronous version of asyncConvertData
   */

  // nsIStreamConverter::convert
  convert: function (aFromStream, aFromType, aToType, aCtxt) {
      return aFromStream;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function (aFromType, aToType, aListener, aCtxt) {
    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
    // From https://developer.mozilla.org/en/Reading_textual_data
    var is = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
    is.init(aInputStream, this.charset, -1, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);

    var str = {};

    // This used to read in a loop until readString returned 0, but it caused it to crash Firefox on OSX/Win32 (but not Win64)
    // It seems just reading once with -1 (default buffer size) gets the file done.
    is.readString(-1, str)
    this.data += str.value;
  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function (aRequest, aContext) {
    this.data = '';
    this.uri = aRequest.QueryInterface(Ci.nsIChannel).URI.spec;

    // Sets the charset if it is available. (For documents loaded from the
    // filesystem, this is not set.)
    this.charset = aRequest.QueryInterface(Ci.nsIChannel).contentCharset || 'UTF-8';

    this.channel = aRequest;
    this.channel.contentType = "text/html";
    // All our data will be coerced to UTF-8
    this.channel.contentCharset = "UTF-8";

    this.listener.onStartRequest (this.channel, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function (aRequest, aContext, aStatusCode) {
    /*
     * This should go something like this:
     * 1. Make sure we have a unicode string.
     * 2. Convert it to a Javascript object.
     * 2.1 Removes the callback
     * 3. Convert that to HTML? Or XUL?
     * 4. Spit it back out at the listener
     */

    var converter = Components
        .classes["@mozilla.org/intl/scriptableunicodeconverter"]
        .createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = this.charset;
    var outputDoc = "";

    var cleanData = '',
        callback = '';

    // This regex attempts to match a JSONP structure:
    //    * Any amount of whitespace (including unicode nonbreaking spaces) between the start of the file and the callback name
    //    * Callback name (any valid JavaScript function name according to ECMA-262 Edition 3 spec)
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Open parentheses
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Either { or [, the only two valid characters to start a JSON string.
    //    * Any character, any number of times
    //    * Either } or ], the only two valid closing characters of a JSON string.
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * A closing parenthesis, an optional semicolon, and any amount of whitespace (including unicode nonbreaking spaces) until the end of the file.
    // This will miss anything that has comments, or more than one callback, or requires modification before use.
    var callback_results = /^[\s\u200B\uFEFF]*([\w$\[\]\.]+)[\s\u200B\uFEFF]*\([\s\u200B\uFEFF]*([\[{][\s\S]*[\]}])[\s\u200B\uFEFF]*\);?[\s\u200B\uFEFF]*$/.exec(this.data);
    if( callback_results && callback_results.length == 3 ){
      callback = callback_results[1];
      cleanData = callback_results[2];
    }else{
      cleanData = this.data;
    }

    try {
      var jsonObj = this.nativeJSON.decode(cleanData);
      if ( jsonObj ) {
        outputDoc = this.jsonFormatter.jsonToHTML(jsonObj, callback, this.uri);
      } else {
        throw "There was no object!";
      }
    }
    catch(e) {
      outputDoc = this.jsonFormatter.errorPage(e, this.data, this.uri);
    }

    // I don't really understand this part, but basically it's a way to get our UTF-8 stuff
    // spit back out as a byte stream
    // See http://www.mail-archive.com/mozilla-xpcom@mozilla.org/msg04194.html
    var storage = Cc["@mozilla.org/storagestream;1"]
    .createInstance(Ci.nsIStorageStream);

    // I have no idea what to pick for the first parameter (segments)
    storage.init(4, 0xffffffff, null);
    var out = storage.getOutputStream(0);

    var binout = Cc["@mozilla.org/binaryoutputstream;1"]
    .createInstance(Ci.nsIBinaryOutputStream);
    binout.setOutputStream(out);
    binout.writeUtf8Z(outputDoc);
    binout.close();

    // I can't explain it, but we need to trim 4 bytes off the front or else it includes random crap
    var trunc = 4;
    var instream = storage.newInputStream(trunc);

    // Pass the data to the main content listener
    this.listener.onDataAvailable(this.channel, aContext, instream, 0, storage.length - trunc);

    this.listener.onStopRequest(this.channel, aContext, aStatusCode);
  }
};

// We only have one component to register
var components = [JSONView];

// The actual hook into XPCOM
function NSGetModule(compMgr, fileSpec) {
  function postRegister() {
     var catMgr = XPCOMUtils.categoryManager;
     catMgr.addCategoryEntry('ext-to-type-mapping','json','application/json',true,true);
  }

  function preUnregister() {
     var catMgr = XPCOMUtils.categoryManager;
     catMgr.addCategoryEntry('ext-to-type-mapping','json',true);
  }

  return XPCOMUtils.generateModule(components, postRegister, preUnregister);
}
<|endoftext|>


<commit_before>//
// Server side activity detection for the session timeout
//
// Meteor settings:
// - staleSessionInactivityTimeout: the amount of time (in ms) after which, if no activity is noticed, a session will be considered stale
// - staleSessionPurgeInterval: interval (in ms) at which stale sessions are purged i.e. found and forcibly logged out
//
var staleSessionPurgeInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionPurgeInterval || (1*60*1000); // 1min
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
var usersRoles = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionUserRoles || null; // null
//
// provide a user activity heartbeat method which stamps the user record with a timestamp of the last
// received activity heartbeat.
//
Meteor.methods({
    heartbeat: function(options) {
        if (!this.userId) { return; }
        var user = Meteor.users.findOne(this.userId);
        if (user) {
            if(usersRoles) {
                for (var x = 0, count = user.roles.length; x < count; x++) {
                    for (var y = 0, count1 = usersRoles.length; y < count1; y++) {
                        if (user.roles[x] === usersRoles[y]) {
                            return
                        }
                    }
                }
            }
            Meteor.users.update(user._id, {$set: {heartbeat: new Date()}});
        }
    }
});

//
// periodically purge any stale sessions, removing their login tokens and clearing out the stale heartbeat.
//
var self = this;
Meteor.setInterval(function() {
    var now = new Date(), overdueTimestamp = new Date(now-inactivityTimeout);
    Meteor.users.update({heartbeat: {$lt: overdueTimestamp}},
                        {$set: {'services.resume.loginTokens': []},
                         $unset: {heartbeat:1}},
                        {multi: true});
}, staleSessionPurgeInterval);
<commit_msg>Cleaned up the code<commit_after>//
// Server side activity detection for the session timeout
//
// Meteor settings:
// - staleSessionInactivityTimeout: the amount of time (in ms) after which, if no activity is noticed, a session will be considered stale
// - staleSessionPurgeInterval: interval (in ms) at which stale sessions are purged i.e. found and forcibly logged out
//
var staleSessionPurgeInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionPurgeInterval || (1*60*1000); // 1min
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
var usersRoles = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionUserRoles || null; // null
//
// provide a user activity heartbeat method which stamps the user record with a timestamp of the last
// received activity heartbeat.
//
Meteor.methods({
    heartbeat: function(options) {
        if (!this.userId) { return; }
        var user = Meteor.users.findOne(this.userId);
        if (user) {
            if(usersRoles) {
                for (var x = 0, count = user.roles.length; x < count; x++) {
                    for (var y = 0, count1 = usersRoles.length; y < count1; y++) {
                        if (user.roles[x] === usersRoles[y]) {
                            return
                        }
                    }
                }
            }
            Meteor.users.update(user._id, {$set: {heartbeat: new Date()}});
        }
    }
});

//
// periodically purge any stale sessions, removing their login tokens and clearing out the stale heartbeat.
//
Meteor.setInterval(function() {
    var now = new Date(), overdueTimestamp = new Date(now-inactivityTimeout);
    Meteor.users.update({heartbeat: {$lt: overdueTimestamp}},
                        {$set: {'services.resume.loginTokens': []},
                         $unset: {heartbeat:1}},
                        {multi: true});
}, staleSessionPurgeInterval);
<|endoftext|>


<commit_before>function Gallery() {
    var _gallery = this;

    var configuration = require('./config');
    var fs = require('fs');
    var path = require('path');

    _gallery.buildThumbPath = function(relative) {
        var extension = path.extname(relative);
        var fileName = path.basename(relative, extension);

        return path.join(path.dirname(relative), configuration.thumbsDir, extension.replace('.', ''), fileName + ".jpg");
    }

    _gallery.buildList = function(dir, files) {
        var ret = [];
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var fullPath = path.join(dir, file);

            var relative = fullPath.substring(configuration.galleryRoot.length-1);

            var type;
            switch (path.extname(file).replace('.', '')) {
                case 'webm':
                case 'mp4':
                case 'gif':
                    type = 'video';
                    break;
                default:
                    type = 'image';
                    break;
            }

            ret.push({
                        name: path.join(configuration.galleryEntryPoint, path.join(relative)),
                        thumb: path.join(configuration.galleryEntryPoint, _gallery.buildThumbPath(relative)),
                        type: type
            });
        }

        return ret;
    }

    _gallery.buildDirectoriesList = function(dir) {
        var ret = [];
        var files = fs.readdirSync(dir).filter(function(file) {
                return fs.statSync(path.join(dir, file)).isDirectory() && file != configuration.thumbsDir;
            });

        for (var i = 0; i < files.length; i++) {
            var relative = path.join(dir, files[i]).substring(configuration.galleryRoot.length-1);
            ret.push({
                path: path.join(relative).replace('/', '%2F'),
                name: path.basename(relative)
            });

            ret = ret.concat(_gallery.buildDirectoriesList(path.join(dir, files[i])));
        }

        return ret;
    }

    return {
        list: function(req, res) {
            var requestedDirectory = req.params.directory || '';
            var basedir = path.join(configuration.galleryRoot, requestedDirectory);

            var files = fs.readdirSync(basedir).filter(function(file) {
                return !fs.statSync(path.join(basedir, file)).isDirectory();
            });

            var response = {
                files: _gallery.buildList(basedir, files)
            };

            res.json(response.files);
        },

        listDirectories: function(req, res) {
            var response = {
              dirs: [{ path: '', name: '/'}].concat(_gallery.buildDirectoriesList(configuration.galleryRoot))
            };

            res.json(response.dirs);
        }
    }
}

module.exports = Gallery;<commit_msg>Gallery structure made explicit<commit_after>function Gallery() {
    var _gallery = this;

    var configuration = require('./config');
    var fs = require('fs');
    var path = require('path');

    _gallery.buildThumbPath = function(relative) {
        var extension = path.extname(relative);
        var fileName = path.basename(relative, extension);

        return path.join(path.dirname(relative), configuration.thumbsDir, extension.replace('.', ''), fileName + ".jpg");
    }

    _gallery.buildList = function(dir, files) {
        var ret = [];
        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            var fullPath = path.join(dir, file);

            var relative = fullPath.substring(configuration.galleryRoot.length-1);

            var type;
            switch (path.extname(file).replace('.', '')) {
                case 'webm':
                case 'mp4':
                case 'gif':
                    type = 'video';
                    break;
                default:
                    type = 'image';
                    break;
            }

            ret.push({
                        name: path.join(configuration.galleryEntryPoint, path.join(relative)),
                        thumb: path.join(configuration.galleryEntryPoint, _gallery.buildThumbPath(relative)),
                        type: type
            });
        }

        return ret;
    }

    _gallery.buildDirectoriesList = function(dir) {
        var ret = [];
        var files = fs.readdirSync(dir).filter(function(file) {
                return fs.statSync(path.join(dir, file)).isDirectory() && file != configuration.thumbsDir;
            });

        for (var i = 0; i < files.length; i++) {
            var relative = path.join(dir, files[i]).substring(configuration.galleryRoot.length-1);
            ret.push({
                path: path.join(relative).replace('/', '%2F'),
                name: path.join(relative)
            });

            ret = ret.concat(_gallery.buildDirectoriesList(path.join(dir, files[i])));
        }

        return ret;
    }

    return {
        list: function(req, res) {
            var requestedDirectory = req.params.directory || '';
            var basedir = path.join(configuration.galleryRoot, requestedDirectory);

            var files = fs.readdirSync(basedir).filter(function(file) {
                return !fs.statSync(path.join(basedir, file)).isDirectory();
            });

            var response = {
                files: _gallery.buildList(basedir, files)
            };

            res.json(response.files);
        },

        listDirectories: function(req, res) {
            var response = {
              dirs: [{ path: '', name: '/'}].concat(_gallery.buildDirectoriesList(configuration.galleryRoot))
            };

            res.json(response.dirs);
        }
    }
}

module.exports = Gallery;<|endoftext|>


<commit_before>/* jshint node: true, esnext: true */

const elasticsearch = require('elasticsearch');
const http = require('http');
const url = require('url');
const htmlEncode = require('js-htmlencode');

const server_port = 9615;

var client = new elasticsearch.Client({
  host: 'localhost:9200',
  log: 'trace'
});

function query(q, page, page_size) {
  var body = {
      "query": {
          "query_string": {
              "query": q,
              "default_operator": "AND"
          }
      },
      "highlight": {
          "order" : "score",
          "require_field_match": false,
          "encoder": "html",
          "fields": {
              "*": {
                  "number_of_fragments" : 1
              }
          }
      },
      "_source": [
        "metadata.title", "metadata.name", "metadata.description",
        "references", "size"
      ]
  };

  return client.search({
    index: 'ipfs',
    body: body,
    size: page_size,
    from: page*page_size
  });
}

function error_response(response, code, error) {
  console.trace(code+": "+error.message);

  response.writeHead(code, {"Content-Type": "application/json"});
  response.write(JSON.stringify({
    "error": error
  }));
  response.end();
}

function get_title(result) {
  // Get title from result

  // Highlights take preference
  var hl = result.highlight;

  if (hl) {
    const highlight_priority = [
      "metadata.title", "references.name"
    ];

    // Return the first one from the priority list
    for (var i=0; i<highlight_priority.length; i++) {
      if (hl[highlight_priority[i]]) {
        return hl[highlight_priority[i]][0];
      }
    }
  }

  // Try metadata
  var src = result._source;
  var titles = [];

  if ("metadata" in src) {
    const metadata_priority = [
      "title", "name"
    ];

    metadata_priority.forEach(function (item) {
      if (src.metadata[item]) {
        titles.push(src.metadata[item][0]);
      }
    });
  }

  // Try references
  src.references.forEach(function (item) {
    if (item.name) {
      titles.push(item.name[0]);
    }
  });

  // Pick longest title
  if (titles.length > 0) {
    titles.sort(function (a, b) { return b.length - a.length; });

    return htmlEncode.htmlEncode(titles[0]);
  } else {
    // Fallback to id
    return htmlEncode.htmlEncode(result._id);
  }
}

function get_description(result) {
  // Use highlights, if available
  if (result.highlight) {
    if (result.highlight.content) {
      return result.highlight.content[0];
    }

    if (result.highlight["links.Name"]) {
      // Reference name matching
      return "Links to “"+result.highlight["links.Name"][0]+"”";
    }

    if (result.highlight["links.Hash"]) {
      // Reference name matching
      return "Links to “"+result.highlight["links.Hash"][0]+"”";
    }
  }

  var metadata = result._source.metadata;
  if (metadata) {
    // Description, if available
    if (metadata.description) {
      return htmlEncode.htmlEncode(metadata.description[0]);
    }

  }

  // Default to nothing
  return null;
}

function transform_results(results) {
  var hits = [];

  results.hits.forEach(function (item) {
    hits.push({
      "hash": item._id,
      "title": get_title(item),
      "description": get_description(item),
      "type": item._type,
      "size": item._source.size
    });
  });

  // Overwrite existing list of hits
  results.hits = hits;
}

console.info("Starting server on http://localhost:"+server_port+"/");

http.createServer(function(request, response) {
  const page_size = 15;
  var parsed_url;

  try {
    console.log(request.url);

    try {
      parsed_url = url.parse(request.url, true);
    } catch(err) {
      error_response(response, 400, err.message);
    }

    if (parsed_url.pathname === "/search") {
      if (!"q" in parsed_url.query) {
        error_response(response, 422, "query argument missing");
      }

      var page = 0;
      const max_page = 100;

      if ("page" in parsed_url.query) {
        page = parseInt(parsed_url.query.page, 10);

        // For performance reasons, don't allow paging too far down
        if (page > 100) {
          error_response(422, "paging not allowed beyond 100");
        }
      }

      query(parsed_url.query.q, page, page_size).then(function (body) {
        console.info("200: Returning "+body.hits.hits.length+" results");

        body.hits.page_size = page_size;

        transform_results(body.hits);

        response.writeHead(200, {"Content-Type": "application/json"});
        response.write(JSON.stringify(body.hits, null, 4));
        response.end();
      }, function (error) {
        throw(error);
      });

    } else {
        error_response(response, 404, "file not found");
    }

  } catch(err) {
    // Catch generic errors
    error_response(response, 500, err.message);
  } finally {

  }
}).listen(server_port);

<commit_msg>Less verbose API server logging.<commit_after>/* jshint node: true, esnext: true */

const elasticsearch = require('elasticsearch');
const http = require('http');
const url = require('url');
const htmlEncode = require('js-htmlencode');

const server_port = 9615;

var client = new elasticsearch.Client({
  host: 'localhost:9201',
  log: 'info'
});

function query(q, page, page_size) {
  var body = {
      "query": {
          "query_string": {
              "query": q,
              "default_operator": "AND"
          }
      },
      "highlight": {
          "order" : "score",
          "require_field_match": false,
          "encoder": "html",
          "fields": {
              "*": {
                  "number_of_fragments" : 1
              }
          }
      },
      "_source": [
        "metadata.title", "metadata.name", "metadata.description",
        "references", "size"
      ]
  };

  return client.search({
    index: 'ipfs',
    body: body,
    size: page_size,
    from: page*page_size
  });
}

function error_response(response, code, error) {
  console.trace(code+": "+error.message);

  response.writeHead(code, {"Content-Type": "application/json"});
  response.write(JSON.stringify({
    "error": error
  }));
  response.end();
}

function get_title(result) {
  // Get title from result

  // Highlights take preference
  var hl = result.highlight;

  if (hl) {
    const highlight_priority = [
      "metadata.title", "references.name"
    ];

    // Return the first one from the priority list
    for (var i=0; i<highlight_priority.length; i++) {
      if (hl[highlight_priority[i]]) {
        return hl[highlight_priority[i]][0];
      }
    }
  }

  // Try metadata
  var src = result._source;
  var titles = [];

  if ("metadata" in src) {
    const metadata_priority = [
      "title", "name"
    ];

    metadata_priority.forEach(function (item) {
      if (src.metadata[item]) {
        titles.push(src.metadata[item][0]);
      }
    });
  }

  // Try references
  src.references.forEach(function (item) {
    if (item.name) {
      titles.push(item.name[0]);
    }
  });

  // Pick longest title
  if (titles.length > 0) {
    titles.sort(function (a, b) { return b.length - a.length; });

    return htmlEncode.htmlEncode(titles[0]);
  } else {
    // Fallback to id
    return htmlEncode.htmlEncode(result._id);
  }
}

function get_description(result) {
  // Use highlights, if available
  if (result.highlight) {
    if (result.highlight.content) {
      return result.highlight.content[0];
    }

    if (result.highlight["links.Name"]) {
      // Reference name matching
      return "Links to “"+result.highlight["links.Name"][0]+"”";
    }

    if (result.highlight["links.Hash"]) {
      // Reference name matching
      return "Links to “"+result.highlight["links.Hash"][0]+"”";
    }
  }

  var metadata = result._source.metadata;
  if (metadata) {
    // Description, if available
    if (metadata.description) {
      return htmlEncode.htmlEncode(metadata.description[0]);
    }

  }

  // Default to nothing
  return null;
}

function transform_results(results) {
  var hits = [];

  results.hits.forEach(function (item) {
    hits.push({
      "hash": item._id,
      "title": get_title(item),
      "description": get_description(item),
      "type": item._type,
      "size": item._source.size
    });
  });

  // Overwrite existing list of hits
  results.hits = hits;
}

console.info("Starting server on http://localhost:"+server_port+"/");

http.createServer(function(request, response) {
  const page_size = 15;
  var parsed_url;

  try {
    console.log(request.url);

    try {
      parsed_url = url.parse(request.url, true);
    } catch(err) {
      error_response(response, 400, err.message);
    }

    if (parsed_url.pathname === "/search") {
      if (!"q" in parsed_url.query) {
        error_response(response, 422, "query argument missing");
      }

      var page = 0;
      const max_page = 100;

      if ("page" in parsed_url.query) {
        page = parseInt(parsed_url.query.page, 10);

        // For performance reasons, don't allow paging too far down
        if (page > 100) {
          error_response(422, "paging not allowed beyond 100");
        }
      }

      query(parsed_url.query.q, page, page_size).then(function (body) {
        console.info("200: Returning "+body.hits.hits.length+" results");

        body.hits.page_size = page_size;

        transform_results(body.hits);

        response.writeHead(200, {"Content-Type": "application/json"});
        response.write(JSON.stringify(body.hits, null, 4));
        response.end();
      }, function (error) {
        throw(error);
      });

    } else {
        error_response(response, 404, "file not found");
    }

  } catch(err) {
    // Catch generic errors
    error_response(response, 500, err.message);
  } finally {

  }
}).listen(server_port);

<|endoftext|>


<commit_before>(function($) {

    var defaultSettings = {
        highlightImageName: 'circle',
        arrowImageName: 'arrow',
        imagesPath: '/img/',
        verticalPosition: 'top',
        horizontalPosition: 'left',
        arrowDimensions: {width: 80, height: 80},
        helptextDimensions: null, // {width, height}
        helptextOffset: null, // {left/right, top/bottom}
        visible: true,
        text: null,
        extra_id: null
    };

    $.fn.guides = function(settings) {
        settings = jQuery.extend(settings, jQuery.extend({}, defaultSettings, settings));

        this.each(function() {
            var guideLayerObj = $('
');
            if (!settings.visible)
                guideLayerObj.css('display', 'none');
            var $this = $(this);
            $this.css({'z-index': 2, position: 'relative'});
            $this.find('a').css({'z-index': 2, position: 'relative'});
            var guideRelativeLayerObj = $('
');
            var offset = $this.offset();
            var this_top = offset.top;
            var this_left = offset.left;
            if (settings.highlightImageName === null)
                var highlighterDimensions = {width: $this.outerWidth(), height: $this.outerHeight()};
            else
                var highlighterDimensions = {width: $this.outerWidth() + 10, height: $this.outerHeight() + 10};
            var highlighterOffset = {};
            var arrowOffset = {};
            var helptextOffset = settings.helptextOffset;
            if (settings.helptextOffset === null)
                helptextOffset = {};
            var layerDimensions = {
                width: (settings.arrowDimensions.width + highlighterDimensions.width * 0.8),
                height: (settings.arrowDimensions.height + highlighterDimensions.height * 0.8)
            };
            var layerOffset = {};
            switch (settings.verticalPosition) {
                case 'top':
                    layerOffset['top'] = -settings.arrowDimensions.height + highlighterDimensions.height * 0.1;
                    highlighterOffset['bottom'] = 0;
                    arrowOffset['top'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['top'] = 20;
                    break;
                case 'bottom':
                    layerOffset['top'] = -highlighterDimensions.height * 0.1;
                    highlighterOffset['top'] = 0;
                    arrowOffset['bottom'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['bottom'] = 20;
            }
            switch (settings.horizontalPosition) {
                case 'left':
                    layerOffset['left'] = -settings.arrowDimensions.width + highlighterDimensions.width * 0.1;
                    highlighterOffset['right'] = 0;
                    arrowOffset['left'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['right'] = highlighterDimensions.width + settings.arrowDimensions.width / 2;
                    break;
                case 'right':
                    layerOffset['left'] = -highlighterDimensions.height * 0.1;
                    highlighterOffset['left'] = 0;
                    arrowOffset['right'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['left'] = highlighterDimensions.width + settings.arrowDimensions.width / 2;
            }
            guideLayerObj.css({position: 'absolute', 'z-index': 1});
            guideLayerObj.css(layerDimensions);
            guideLayerObj.css(layerOffset);

            if (settings.highlightImageName !== null) {
                var highlighter = $('');
                highlighter.css(highlighterDimensions);
                highlighter.css(highlighterOffset);
                guideRelativeLayerObj.append(highlighter);
            }

            var arrow = $('');
            arrow.css(settings.arrowDimensions);
            arrow.css(arrowOffset);
            guideRelativeLayerObj.append(arrow);

            var helptext = $('
');
            helptext.css(settings.helptextDimensions);
            helptext.css(helptextOffset);
            if (settings.text === null)
                helptext.html($this.attr('title'));
            else
                helptext.html(settings.text);
            guideRelativeLayerObj.append(helptext);

            guideRelativeLayerObj.css(layerDimensions);

            guideLayerObj.append(guideRelativeLayerObj);
            if (settings.extra_id !== null)
                guideLayerObj.data('extra_id', settings.extra_id);
            $this.append(guideLayerObj);
        });
        return this;
    };
})(jQuery);
<commit_msg>smallfix<commit_after>(function($) {

    var defaultSettings = {
        highlightImageName: 'circle',
        arrowImageName: 'arrow',
        imagesPath: '/img/',
        verticalPosition: 'top',
        horizontalPosition: 'left',
        arrowDimensions: {width: 80, height: 80},
        helptextDimensions: null, // {width, height}
        helptextOffset: null, // {left/right, top/bottom}
        visible: true,
        text: null,
        extra_id: null
    };

    $.fn.guide = function(settings) {
        settings = jQuery.extend(settings, jQuery.extend({}, defaultSettings, settings));

        this.each(function() {
            var guideLayerObj = $('
');
            if (!settings.visible)
                guideLayerObj.css('display', 'none');
            var $this = $(this);
            $this.css({'z-index': 2, position: 'relative'});
            $this.find('a').css({'z-index': 2, position: 'relative'});
            var guideRelativeLayerObj = $('
');
            var offset = $this.offset();
            var this_top = offset.top;
            var this_left = offset.left;
            if (settings.highlightImageName === null)
                var highlighterDimensions = {width: $this.outerWidth(), height: $this.outerHeight()};
            else
                var highlighterDimensions = {width: $this.outerWidth() + 10, height: $this.outerHeight() + 10};
            var highlighterOffset = {};
            var arrowOffset = {};
            var helptextOffset = settings.helptextOffset;
            if (settings.helptextOffset === null)
                helptextOffset = {};
            var layerDimensions = {
                width: (settings.arrowDimensions.width + highlighterDimensions.width * 0.8),
                height: (settings.arrowDimensions.height + highlighterDimensions.height * 0.8)
            };
            var layerOffset = {};
            switch (settings.verticalPosition) {
                case 'top':
                    layerOffset['top'] = -settings.arrowDimensions.height + highlighterDimensions.height * 0.1;
                    highlighterOffset['bottom'] = 0;
                    arrowOffset['top'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['top'] = 20;
                    break;
                case 'bottom':
                    layerOffset['top'] = -highlighterDimensions.height * 0.1;
                    highlighterOffset['top'] = 0;
                    arrowOffset['bottom'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['bottom'] = 20;
            }
            switch (settings.horizontalPosition) {
                case 'left':
                    layerOffset['left'] = -settings.arrowDimensions.width + highlighterDimensions.width * 0.1;
                    highlighterOffset['right'] = 0;
                    arrowOffset['left'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['right'] = highlighterDimensions.width + settings.arrowDimensions.width / 2;
                    break;
                case 'right':
                    layerOffset['left'] = -highlighterDimensions.height * 0.1;
                    highlighterOffset['left'] = 0;
                    arrowOffset['right'] = 0;
                    if (settings.helptextOffset === null)
                        helptextOffset['left'] = highlighterDimensions.width + settings.arrowDimensions.width / 2;
            }
            guideLayerObj.css({position: 'absolute', 'z-index': 1});
            guideLayerObj.css(layerDimensions);
            guideLayerObj.css(layerOffset);

            if (settings.highlightImageName !== null) {
                var highlighter = $('');
                highlighter.css(highlighterDimensions);
                highlighter.css(highlighterOffset);
                guideRelativeLayerObj.append(highlighter);
            }

            var arrow = $('');
            arrow.css(settings.arrowDimensions);
            arrow.css(arrowOffset);
            guideRelativeLayerObj.append(arrow);

            var helptext = $('
');
            helptext.css(settings.helptextDimensions);
            helptext.css(helptextOffset);
            if (settings.text === null)
                helptext.html($this.attr('title'));
            else
                helptext.html(settings.text);
            guideRelativeLayerObj.append(helptext);

            guideRelativeLayerObj.css(layerDimensions);

            guideLayerObj.append(guideRelativeLayerObj);
            if (settings.extra_id !== null)
                guideLayerObj.data('extra_id', settings.extra_id);
            $this.append(guideLayerObj);
        });
        return this;
    };
})(jQuery);
<|endoftext|>