<commit_before>import express from 'express';
import Q from 'bluebird-q';
import React from 'react';
import { take, map, find, keys } from 'lodash';
import { renderToStaticMarkup } from 'react-dom/server';
import { Provider } from 'react-redux';
import configureStore from '../../common/store/configure_store';
import { isURL } from 'validator';
import Explore from './explore.js';
import render from '../render.js';
import cachedLink from '../../common/api/cached_link';
import { getPath } from '../../common/api/path';
import prefetchLinks from '../../common/lib/prefetch_links';

let app = express();

const { APP_URL } = process.env;

app
  .get('/:url', (req, res, next) => {
    const url = req.params.url;
    cachedLink(url, req).then( results => {
      // set initial state as fetched info
      const store = configureStore({
        root_link: url,
        links: {
          [url]: results
        },
        preview_url: false,
        hovered_link: false,
        path: [url],
        loading: false,
        path_url: false,
        scroll_index: 0,
        view_mode: 'explore'
      });

      // Render the component to a raw string
      const html = renderToStaticMarkup(
        <Provider store={store}>
          <Explore />
        </Provider>
      );

      // Render our boilerplate page with HTML and the initial state set
      res.send(render(html, store.getState(), results.title));
      prefetchLinks(results.hrefs);
    }).catch( err => {
      console.log('ERROR | ', err.stack)
      next()
    })
  })
  .get('/path/:id', (req, res, next) => {
    const id = req.params.id;
    getPath(id).then( pathData => {
      Q.all(map(pathData.path, url => cachedLink(url))).then((results) => {
        let links = {};
        map(pathData.path, (url)=>{
          let linkData = find(results, { url: url });
          links[url] = linkData;
        });

        const store = configureStore({
          root_link: pathData.root_link,
          links: links,
          preview_url: false,
          hovered_link: false,
          path: pathData.path,
          loading: false,
          path_url: id,
          scroll_index: pathData.path.length,
          view_mode: 'explore'
        });

        // Render the component to a raw string
        const html = renderToStaticMarkup(
          <Provider store={store}>
            <Explore />
          </Provider>
        );

        // Render our boilerplate page with HTML and the initial state set
        return res.send(render(html, store.getState(), results[0].title));
      });
    }).catch( err => {
      console.log('ERROR | ', err.stack)
      next()
    });
  })

export default app;
<commit_msg>fix path scroll_index<commit_after>import express from 'express';
import Q from 'bluebird-q';
import React from 'react';
import { take, map, find, keys } from 'lodash';
import { renderToStaticMarkup } from 'react-dom/server';
import { Provider } from 'react-redux';
import configureStore from '../../common/store/configure_store';
import { isURL } from 'validator';
import Explore from './explore.js';
import render from '../render.js';
import cachedLink from '../../common/api/cached_link';
import { getPath } from '../../common/api/path';
import prefetchLinks from '../../common/lib/prefetch_links';

let app = express();

const { APP_URL } = process.env;

app
  .get('/:url', (req, res, next) => {
    const url = req.params.url;
    cachedLink(url, req).then( results => {
      // set initial state as fetched info
      const store = configureStore({
        root_link: url,
        links: {
          [url]: results
        },
        preview_url: false,
        hovered_link: false,
        path: [url],
        loading: false,
        path_url: false,
        scroll_index: 0,
        view_mode: 'explore'
      });

      // Render the component to a raw string
      const html = renderToStaticMarkup(
        <Provider store={store}>
          <Explore />
        </Provider>
      );

      // Render our boilerplate page with HTML and the initial state set
      res.send(render(html, store.getState(), results.title));
      prefetchLinks(results.hrefs);
    }).catch( err => {
      console.log('ERROR | ', err.stack)
      next()
    })
  })
  .get('/path/:id', (req, res, next) => {
    const id = req.params.id;
    getPath(id).then( pathData => {
      Q.all(map(pathData.path, url => cachedLink(url))).then((results) => {
        let links = {};
        map(pathData.path, (url)=>{
          let linkData = find(results, { url: url });
          links[url] = linkData;
        });

        const store = configureStore({
          root_link: pathData.root_link,
          links: links,
          preview_url: false,
          hovered_link: false,
          path: pathData.path,
          loading: false,
          path_url: id,
          scroll_index: pathData.path.length - 1,
          view_mode: 'explore'
        });

        // Render the component to a raw string
        const html = renderToStaticMarkup(
          <Provider store={store}>
            <Explore />
          </Provider>
        );

        // Render our boilerplate page with HTML and the initial state set
        return res.send(render(html, store.getState(), results[0].title));
      });
    }).catch( err => {
      console.log('ERROR | ', err.stack)
      next()
    });
  })

export default app;
<|endoftext|>


<commit_before>/**
 * check multiple files upload
 */
var gripload = (function() {

	var tools = {
		// return merged object. obj2 is injected into obj1
		mergeObjects: function(obj1, obj2) {
			var mergedObj = {};
			for (var attr in obj1) {
				mergedObj[attr] = obj1[attr];
			}

			for (var attr in obj2) {
				mergedObj[attr] = obj2[attr];
			}

			return mergedObj;
		},

		// method, url, params, successFn, failureFn
		ajax: function(d,e,b,h,k){var a;if("undefined"!==typeof XMLHttpRequest)a=new XMLHttpRequest;else for(var c=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"],g=0,l=c.length;g<l;g++)try{a=new ActiveXObject(c[g]);break}catch(m){}c=[];if(b&&b instanceof Object&&0<Object.keys(b).length)for(var f in b)c.push(f+"="+encodeURIComponent(b[f]));c=c.join("&");"GET"==d&&b&&0<Object.keys(b).length&&(f=e.indexOf("?"),e+=(0<f?"&":"?")+c);a.open(d,e,!0);d=d.toUpperCase();"POST"==d&&b&&0<Object.keys(b).length&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded");a.onreadystatechange=function(){4==a.readyState&&(200<=a.status&&299>=a.status?"function"==typeof h&&h(a.responseText):"function"==typeof k&&k(a.responseText))};a.send(c)}
	};

	var defaultOptions = {
		target: 'upload.php',
		chunkSize: 1 * 768 * 1024, // optimal upload chunk bytes (ubuntu amd64)
		onComplete: function(fileData) {
		},
		onFailure: function() {
			console.warn('upload failed')
		},
		onProgress: function(fileData, percentage) {
		},
		onBeforeUpload: function(files) {
		}
	};

	var uploadBinaryData = function(fileName, binaryData, options, callbackFn, failureCallbackFn) {
		// split into chunks and upload one by one
		var size = binaryData.length;
		var totalChunksToUpload = Math.ceil(size / options.chunkSize);
		var totalChunks = totalChunksToUpload;
		var currentChunk = 0;
		var uploadToken = null;

		// upload one chunk
		var uploadChunk = function(chunkNumber, chunkContent, uploadChunkCallbackFn, uploadChunkFailureCallbackFn) {
			tools.ajax('post', options.target, {
				fileName: fileName,
				chunkNumber: chunkNumber,
				chunkContent: chunkContent,
				uploadToken: uploadToken,
				size: size,
				last: (totalChunksToUpload == 1),
				chunkSize: options.chunkSize
			}, function(res) {
				try {
					res = JSON.parse(res);
				} catch (e) {
					if (typeof(uploadChunkFailureCallbackFn) == 'function') {
						uploadChunkFailureCallbackFn()
						return;
					}
				}

				if (res && res.result == 'ok' && res.token) {
					// upload local upload token
					uploadToken = res.token;

					if (typeof(uploadChunkCallbackFn) == 'function') {
						uploadChunkCallbackFn(res.token);
						return;
					}
				} else {
					if (typeof(uploadChunkFailureCallbackFn) == 'function') {
						uploadChunkFailureCallbackFn();
						return;
					}
				}

			}, uploadChunkFailureCallbackFn);
		}

		// upload all the chunks, one by one
		var uploadChunks = function(callbackFn, failureCallbackFn) {
			chunkContent = binaryData.substr(currentChunk * options.chunkSize, options.chunkSize);
			uploadChunk(currentChunk++, chunkContent, function() {

				if (typeof(options.onProgress) == 'function') {
					var currentPercent = Math.round( ((currentChunk) / totalChunks) * 100 );
					options.onProgress(fileName, currentPercent);
				}

				if (--totalChunksToUpload == 0) {
					// upload finished. call the callback
					if (typeof(callbackFn) == 'function') {
						callbackFn();
					}
				} else {
					// upload the next chunk
					uploadChunks(callbackFn, failureCallbackFn);
				}
			}, function() {
				if (typeof(failureCallbackFn) == 'function') {
					failureCallbackFn();
				}
			});
		};

		// perform he upload
		uploadChunks(callbackFn, failureCallbackFn);
	};

	/**
	 * Manage FileReaders with their options (fileName, options)
	 */
	var fileReaders = (function() {

		var readers = [];

		var self = {
			add: function(readerObj) {
				if (!self.exists(readerObj.reader)) {
					readers.push(readerObj);
				}
			},

			get: function(theFileReader) {
				var foundReaderObj = null;
				readers.forEach(function(readerObj) {
					if (readerObj.reader === theFileReader) {
						foundReaderObj = readerObj;
						return false;
					}
				});
				return foundReaderObj;
			},

			exists: function(theFileReader) {
				return (self.get(theFileReader) !== null);
			}
		}

	})();

	// read files as binary data
	var readAndUploadFiles = function(theInput) {
		// check that files were selected
		var files = theInput.files;
		if (!files || !files.length) return;

		// get the user options of the input
		var storedInputData = fileInputs.get(theInput);

		var totalFilesToUpload = files.length;
		var uploadedFileNames = [];

		var readers = {};
		for (var i = 0; file = files[i++];) {
			readers[i] = readers[i] || {};
			readers[i].fileName = file['name'];
			readers[i].reader  = new FileReader();
			readers[i].reader.onloadend = function(event) {
				var theReader = event.target;
				var theFileName = null;
				for (var readerIdx in readers) {
					if (readers[readerIdx].reader === theReader) {
						theFileName = readers[readerIdx].fileName;
						break;
					}
				}
				if (!theFileName) return;
				uploadedFileNames.push(theFileName);
				uploadBinaryData(theFileName, theReader.result, storedInputData.options, function() {
					// success. if this is the last file, call the callback
					if (--totalFilesToUpload == 0 && typeof(storedInputData.options.onComplete) == 'function') {
						storedInputData.options.onComplete(uploadedFileNames);
					}
				}, function() {
					// failure
					if (typeof(storedInputData.options.onFailure) == 'function') {
						storedInputData.options.onFailure(storedInputData.options.fileName);
					}
				});
			};
			readers[i].reader.readAsDataURL(file);
		}
	};

	// list of inputs type file
	var fileInputs = (function() {
		var storedInputs = [];

		return {
			// add the input to the list and assign 'change' event
			addAndAssign: function(fInput, options) {
				storedInputs.push({
					'input': fInput,
					'options': options
				});
				fInput.addEventListener('change', function(event) {
					var theInput = event.target;
					var inputOptions = fileInputs.get(theInput);
					if (typeof(inputOptions.options.onBeforeUpload) == 'function') {
						inputOptions.options.onBeforeUpload(theInput.files);
					}

					readAndUploadFiles(event.target);
				});
			},

			// get the stored input record, by the input element
			get: function(fileInput) {
				// find the input in stored inputs
				var storedInputData = null;
				for (var i=0, totalRecords = storedInputs.length; i < totalRecords; i++) {
					if (storedInputs[i].input === fileInput) {
						return storedInputs[i];
					}
				}

				return null;
			},

			// check if the input is already inside
			exists: function(fInput) {
				var found = false;
				storedInputs.every(function(fInput) {
					if (storedInputs.input === fInput) {
						found = true;
						return false;
					}
				});

				return found;
			}
		};
	})();

	var mainFn = function (fileInput, options) {

		if (!fileInput || !fileInput.tagName == 'INPUT') {
			console.error('supplied bad file input to `gripload`');
			return false;
		}

		// merge with default
		options = tools.mergeObjects(defaultOptions, options);

		// register the file input
		if (!fileInputs.exists(fileInput)) {
			fileInputs.addAndAssign(fileInput, options);
		}

	};

	return mainFn;
})();

<commit_msg>fixed default options<commit_after>/**
 * check multiple files upload
 */
var gripload = (function() {

	var tools = {
		// return merged object. obj2 is injected into obj1
		mergeObjects: function(obj1, obj2) {
			var mergedObj = {};
			for (var attr in obj1) {
				mergedObj[attr] = obj1[attr];
			}

			for (var attr in obj2) {
				mergedObj[attr] = obj2[attr];
			}

			return mergedObj;
		},

		// method, url, params, successFn, failureFn
		ajax: function(d,e,b,h,k){var a;if("undefined"!==typeof XMLHttpRequest)a=new XMLHttpRequest;else for(var c=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"],g=0,l=c.length;g<l;g++)try{a=new ActiveXObject(c[g]);break}catch(m){}c=[];if(b&&b instanceof Object&&0<Object.keys(b).length)for(var f in b)c.push(f+"="+encodeURIComponent(b[f]));c=c.join("&");"GET"==d&&b&&0<Object.keys(b).length&&(f=e.indexOf("?"),e+=(0<f?"&":"?")+c);a.open(d,e,!0);d=d.toUpperCase();"POST"==d&&b&&0<Object.keys(b).length&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded");a.onreadystatechange=function(){4==a.readyState&&(200<=a.status&&299>=a.status?"function"==typeof h&&h(a.responseText):"function"==typeof k&&k(a.responseText))};a.send(c)}
	};

	var defaultOptions = {
		target: 'upload.php',
		chunkSize: 1 * 768 * 1024, // optimal upload chunk bytes (ubuntu amd64)
		onComplete: function(fileData) {
		},
		onFailure: function() {
			console.warn('upload failed')
		},
		onProgress: function(fileName, percentage) {
		},
		onBeforeUpload: function(files) {
		}
	};

	var uploadBinaryData = function(fileName, binaryData, options, callbackFn, failureCallbackFn) {
		// split into chunks and upload one by one
		var size = binaryData.length;
		var totalChunksToUpload = Math.ceil(size / options.chunkSize);
		var totalChunks = totalChunksToUpload;
		var currentChunk = 0;
		var uploadToken = null;

		// upload one chunk
		var uploadChunk = function(chunkNumber, chunkContent, uploadChunkCallbackFn, uploadChunkFailureCallbackFn) {
			tools.ajax('post', options.target, {
				fileName: fileName,
				chunkNumber: chunkNumber,
				chunkContent: chunkContent,
				uploadToken: uploadToken,
				size: size,
				last: (totalChunksToUpload == 1),
				chunkSize: options.chunkSize
			}, function(res) {
				try {
					res = JSON.parse(res);
				} catch (e) {
					if (typeof(uploadChunkFailureCallbackFn) == 'function') {
						uploadChunkFailureCallbackFn()
						return;
					}
				}

				if (res && res.result == 'ok' && res.token) {
					// upload local upload token
					uploadToken = res.token;

					if (typeof(uploadChunkCallbackFn) == 'function') {
						uploadChunkCallbackFn(res.token);
						return;
					}
				} else {
					if (typeof(uploadChunkFailureCallbackFn) == 'function') {
						uploadChunkFailureCallbackFn();
						return;
					}
				}

			}, uploadChunkFailureCallbackFn);
		}

		// upload all the chunks, one by one
		var uploadChunks = function(callbackFn, failureCallbackFn) {
			chunkContent = binaryData.substr(currentChunk * options.chunkSize, options.chunkSize);
			uploadChunk(currentChunk++, chunkContent, function() {

				if (typeof(options.onProgress) == 'function') {
					var currentPercent = Math.round( ((currentChunk) / totalChunks) * 100 );
					options.onProgress(fileName, currentPercent);
				}

				if (--totalChunksToUpload == 0) {
					// upload finished. call the callback
					if (typeof(callbackFn) == 'function') {
						callbackFn();
					}
				} else {
					// upload the next chunk
					uploadChunks(callbackFn, failureCallbackFn);
				}
			}, function() {
				if (typeof(failureCallbackFn) == 'function') {
					failureCallbackFn();
				}
			});
		};

		// perform he upload
		uploadChunks(callbackFn, failureCallbackFn);
	};

	/**
	 * Manage FileReaders with their options (fileName, options)
	 */
	var fileReaders = (function() {

		var readers = [];

		var self = {
			add: function(readerObj) {
				if (!self.exists(readerObj.reader)) {
					readers.push(readerObj);
				}
			},

			get: function(theFileReader) {
				var foundReaderObj = null;
				readers.forEach(function(readerObj) {
					if (readerObj.reader === theFileReader) {
						foundReaderObj = readerObj;
						return false;
					}
				});
				return foundReaderObj;
			},

			exists: function(theFileReader) {
				return (self.get(theFileReader) !== null);
			}
		}

	})();

	// read files as binary data
	var readAndUploadFiles = function(theInput) {
		// check that files were selected
		var files = theInput.files;
		if (!files || !files.length) return;

		// get the user options of the input
		var storedInputData = fileInputs.get(theInput);

		var totalFilesToUpload = files.length;
		var uploadedFileNames = [];

		var readers = {};
		for (var i = 0; file = files[i++];) {
			readers[i] = readers[i] || {};
			readers[i].fileName = file['name'];
			readers[i].reader  = new FileReader();
			readers[i].reader.onloadend = function(event) {
				var theReader = event.target;
				var theFileName = null;
				for (var readerIdx in readers) {
					if (readers[readerIdx].reader === theReader) {
						theFileName = readers[readerIdx].fileName;
						break;
					}
				}
				if (!theFileName) return;
				uploadedFileNames.push(theFileName);
				uploadBinaryData(theFileName, theReader.result, storedInputData.options, function() {
					// success. if this is the last file, call the callback
					if (--totalFilesToUpload == 0 && typeof(storedInputData.options.onComplete) == 'function') {
						storedInputData.options.onComplete(uploadedFileNames);
					}
				}, function() {
					// failure
					if (typeof(storedInputData.options.onFailure) == 'function') {
						storedInputData.options.onFailure(storedInputData.options.fileName);
					}
				});
			};
			readers[i].reader.readAsDataURL(file);
		}
	};

	// list of inputs type file
	var fileInputs = (function() {
		var storedInputs = [];

		return {
			// add the input to the list and assign 'change' event
			addAndAssign: function(fInput, options) {
				storedInputs.push({
					'input': fInput,
					'options': options
				});
				fInput.addEventListener('change', function(event) {
					var theInput = event.target;
					var inputOptions = fileInputs.get(theInput);
					if (typeof(inputOptions.options.onBeforeUpload) == 'function') {
						inputOptions.options.onBeforeUpload(theInput.files);
					}

					readAndUploadFiles(event.target);
				});
			},

			// get the stored input record, by the input element
			get: function(fileInput) {
				// find the input in stored inputs
				var storedInputData = null;
				for (var i=0, totalRecords = storedInputs.length; i < totalRecords; i++) {
					if (storedInputs[i].input === fileInput) {
						return storedInputs[i];
					}
				}

				return null;
			},

			// check if the input is already inside
			exists: function(fInput) {
				var found = false;
				storedInputs.every(function(fInput) {
					if (storedInputs.input === fInput) {
						found = true;
						return false;
					}
				});

				return found;
			}
		};
	})();

	var mainFn = function (fileInput, options) {

		if (!fileInput || !fileInput.tagName == 'INPUT') {
			console.error('supplied bad file input to `gripload`');
			return false;
		}

		// merge with default
		options = tools.mergeObjects(defaultOptions, options);

		// register the file input
		if (!fileInputs.exists(fileInput)) {
			fileInputs.addAndAssign(fileInput, options);
		}

	};

	return mainFn;
})();

<|endoftext|>


<commit_before>Registrants.after.insert(function (userId, document) {
    var to = document.createdByEmail,
        from = process.env.MAIL_FROM,
        name = document.first_name,
        html = 'We have received your event registration for PYM 2015.
 \
                        View your registration(s) by visiting:
 \
                        \
                        http://register.pacificyearlymeeting.org/view';

    Email.send({
        from: from,
        to: to,
        subject: "[PYM 2015] Registration success!",
        html: html
    });
});
<commit_msg>Check if SMTP is enabled.<commit_after>Registrants.after.insert(function (userId, document) {
    // If SMTP is configured, send email when registration is added
    // Check whether email sending is enabled
    var emailEnabled = process.env.ENABLE_SMTP;

    if (emailEnabled) {
        // Email settings

        // Email address from registration
        var to = document.createdByEmail;

        // From address from mail configuration
        var from = process.env.MAIL_FROM;

        // HTML message
        var html = 'We have received your event registration for PYM 2015.
 \
                                View your registration(s) by visiting:
\
                                \
                                http://register.pacificyearlymeeting.org/view';

        Email.send({
            from: from,
            to: to,
            subject: "[PYM 2015] Registration success!",
            html: html
        });
    }
});
<|endoftext|>


<commit_before>Meteor.methods({
  addUser (user) {
    // Add new user
    var userId = Accounts.createUser(user);

    return userId;
  },
  addUsersAndSendEnrollmentEmails (enrollmentDocument) {
    // Get emails from enrollment document
    const emailAddresses = enrollmentDocument.emailAddresses;

    // Create user and send enrollment email for each email address
    emailAddresses.forEach((emailAddress) => {
      console.log(emailAddress);
    });
  }
  addUserToAdminRole (userId) {
    // Add user to admin role
    Roles.addUsersToRoles(userId, "admin");
  },
  deleteUser (user) {
    console.log(user);
    // Make sure user object provided with '_id' property
    check(user, Object);
    check(user._id, String);

    // Get current user id, for security check
    const currentUserId = this.userId;

    // Make sure current user has 'admin' role
    if (Roles.userIsInRole(currentUserId, 'admin')) {
      // Make sure user can't delete own Account
      if (currentUserId !== user._id) {
        // If safe, delete provided user Object
        Meteor.users.remove(user);
      }
    }
  },
  editUserFormSubmit (user) {
    // Get user email
    var userEmail = user.email;

    var userId = user._id;

    // Edit user, setting first email
    Meteor.users.update(userId, {$set: {"emails.0.address": userEmail}});

    return userId;
  },
  removeUserFromAdminRole (userId) {
    // Add user to admin role
    Roles.removeUsersFromRoles(userId, "admin");
  }
});
<commit_msg>fix typo<commit_after>Meteor.methods({
  addUser (user) {
    // Add new user
    var userId = Accounts.createUser(user);

    return userId;
  },
  addUsersAndSendEnrollmentEmails (enrollmentDocument) {
    // Get emails from enrollment document
    const emailAddresses = enrollmentDocument.emailAddresses;

    // Create user and send enrollment email for each email address
    emailAddresses.forEach((emailAddress) => {
      console.log(emailAddress);
    });
  },
  addUserToAdminRole (userId) {
    // Add user to admin role
    Roles.addUsersToRoles(userId, "admin");
  },
  deleteUser (user) {
    console.log(user);
    // Make sure user object provided with '_id' property
    check(user, Object);
    check(user._id, String);

    // Get current user id, for security check
    const currentUserId = this.userId;

    // Make sure current user has 'admin' role
    if (Roles.userIsInRole(currentUserId, 'admin')) {
      // Make sure user can't delete own Account
      if (currentUserId !== user._id) {
        // If safe, delete provided user Object
        Meteor.users.remove(user);
      }
    }
  },
  editUserFormSubmit (user) {
    // Get user email
    var userEmail = user.email;

    var userId = user._id;

    // Edit user, setting first email
    Meteor.users.update(userId, {$set: {"emails.0.address": userEmail}});

    return userId;
  },
  removeUserFromAdminRole (userId) {
    // Add user to admin role
    Roles.removeUsersFromRoles(userId, "admin");
  }
});
<|endoftext|>


<commit_before>var ObjectID = require('mongodb').ObjectID;
var DBRef = require('mongodb').DBRef;
var EventProxy = require('eventproxy');
var EventEmitter = require('events').EventEmitter;
var us = require('underscore');

var db = require('./db');
var ERR = require('../errorcode');
var U = require('../util');
var mFile = require('./file');

exports.create = function(params, callback){
    var groupId = params.groupId;
    var folderId = params.folderId;

    var that = this;

    var proxy = EventProxy.create('folder', function(folder){
        var doc = {
            name: params.name,
            creator: DBRef('user', ObjectID(params.creator)),
            mark: params.mark || '',
            createTime: Date.now(),
            updateTime: Date.now(),
            type: 0,
            parent: null,
            deletable: ('deletable' in params) ? params.deletable : true,
            top: null, //params.topId ? DBRef('folder', params.topId) : null,
            hasChild: false
        };
        if(groupId){
            doc.group = DBRef('group', ObjectID(groupId));
            doc.closeTime = Number(params.closeTime) || 0;
        }else{
            doc.prepare = params.prepareId ? DBRef('group', ObjectID(params.prepareId)) : null;
        }
        if(folder){
            doc.parent = DBRef('folder', folder._id);
            doc.top = folder.top || doc.parent;

            folder.hasChild = true;
            db.folder.save(folder, function(err){
                if(err){
                    console.log('models/folder/create', err);
                }
            });
        }else{
            doc.parent = doc.top = null;
        }
        db.folder.insert(doc, function(err, result){
            if(err){
                return proxy.emit('error', err);
            }
            result = result[0];
            if(folder){
                result.idpath = folder.idpath + ',' + result._id;
            }else{
                result.idpath = result._id.toString();
            }

            db.folder.save(result, function(err){
                if(err){
                    console.log('models/folder/create', err);
                }
            });
            callback(err, result);
        });

    });

    proxy.fail(callback);

    if(folderId){
        db.folder.findOne({ _id: new ObjectID(folderId.toString())}, proxy.done("folder"));
    }else{
        proxy.emit('folder', null);
    }
}

exports.getFolder = function(query, callback){

    db.folder.findOne(query, function(err, doc){
        if(err || !doc){
            callback(err, doc);
            return;
        }
        db.dereference(doc, {'parent': ['_id', 'name'], 'top': ['_id', 'name']}, callback);
    });

}

exports.modify = function(params, doc, callback){
    var folderId = params.folderId;
    var groupId = params.groupId;
    var creator = params.creator;

    doc.updatetime = Date.now();
    var query = {
        _id: new ObjectID(folderId)
    }

    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }

    db.folder.findAndModify(query, [], { $set: doc },
            { 'new':true }, callback);
}

function deleteFolderAndFiles(oFolderId, callback){
    db.folder.remove({ _id: oFolderId }, function(err){
        if(err){
            console.log('>>>folder.delete [folder]', err);
            callback(err);
            return;
        }
        mFile.batchDelete({ 'folder.$id': oFolderId }, function(err, count){
            if(err){
                console.log('>>>folder.delete [file]', err);
                callback(err);
                return;
            }
            callback(null, 1 + (count || 0));
        });
    });

}

exports.delete = function(params, callback){
    var groupId = params.groupId;
    var folderId = params.folderId;
    var creator = params.creator;

    var query = {
        _id: new ObjectID(folderId)
    }

    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }

    var ep = new EventProxy();

    ep.fail(callback);

    db.folder.findOne(query, ep.doneLater('getFolderSucc'));
    ep.on('getFolderSucc', function(folder){
        if(!folder){
            return ep.emit('error', 'no such folder', ERR.NOT_FOUND);
        }
        if(folder.hasChild){

            var query = {
                idpath: new RegExp('.*' + folderId + '.*')
            };

            db.folder.find(query, ep.done('findAllChild'));
        }else{
            deleteFolderAndFiles(folder._id, callback);

        }
    });

    ep.all('getFolderSucc', 'findAllChild', function(folder, docs){
        if(!docs.length){
            deleteFolderAndFiles(folder._id, callback);
            return;
        }

        ep.after('delete', docs.length, function(list){
            callback(null, U.calculate(list));
        });

        docs.forEach(function(doc){

            deleteFolderAndFiles(doc._id, ep.group('delete'));
        });
    });
}

exports.isFolderCreator = function(folderId, userId, callback){
    var query = {
        '_id': ObjectID(folderId),
        'creator.$id': ObjectID(userId)
    };

    db.folder.findOne(query, function(err, doc){
        if(doc){
            callback(null, true, doc);
        }else{
            callback(null, false);
        }
    });
}

exports.list = function(params, callback){

    var folderId = params.folderId;
    var groupId = params.groupId || null;
    var order = null;

    var query = {
        'parent.$id': ObjectID(folderId)
    };
    if(params.creator){
        query['creator.$id'] = ObjectID(params.creator);
    }
    if(params.order){
        order = U.jsonParse(order);
    }

    db.folder.find(query, { sort: order}, function(err, docs){
        if(err){
            callback(err)
        }else{
            db.dereferences(docs, {'creator': ['_id', 'nick']}, callback);
        }
    });

}

exports.search = function(params, callback){

    var folderId = params.folderId;
    var groupId = params.groupId || null;
    var creator = params.creator || null;
    var keyword = params.keyword || '';

    var query = {
        $or: [
            { 'parent.$id': new ObjectID(folderId) },
            { idpath: new RegExp('.*' + folderId + '.*') }
        ]
    };
    if(keyword){
        query['name'] = new RegExp('.*' + U.encodeRegexp(keyword) + '.*');
    }
    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }
    db.search('folder', query, params, function(err, total, docs){
        if(err){
            callback(err);
        }else if(total && docs){
            db.dereferences(docs, {'creator': ['_id', 'nick']}, function(err, docs){
                if(err){
                    callback(err)
                }else{
                    callback(null, total || 0, docs);
                }
            });
        }else{
            callback(null, total || 0, docs);
        }
    });
}
<commit_msg>文件夹增加公开和只读属性<commit_after>var ObjectID = require('mongodb').ObjectID;
var DBRef = require('mongodb').DBRef;
var EventProxy = require('eventproxy');
var EventEmitter = require('events').EventEmitter;
var us = require('underscore');

var db = require('./db');
var ERR = require('../errorcode');
var U = require('../util');
var mFile = require('./file');

exports.create = function(params, callback){
    var groupId = params.groupId;
    var folderId = params.folderId;

    var that = this;

    var proxy = EventProxy.create('folder', function(folder){
        var doc = {
            name: params.name,
            creator: DBRef('user', ObjectID(params.creator)),
            mark: params.mark || '',
            createTime: Date.now(),
            updateTime: Date.now(),
            type: 0,
            parent: null,
            deletable: ('deletable' in params) ? params.deletable : true,
            isOpen: params.isOpen === 1, // 0 非公开, 1 公开
            isReadonly: params.isReadonly === 1, // 0 读写, 1 只读
            top: null,
            hasChild: false
        };
        if(groupId){
            doc.group = DBRef('group', ObjectID(groupId));
            doc.closeTime = Number(params.closeTime) || 0;
        }else{
            doc.prepare = params.prepareId ? DBRef('group', ObjectID(params.prepareId)) : null;
        }
        if(folder){
            doc.parent = DBRef('folder', folder._id);
            doc.top = folder.top || doc.parent;

            folder.hasChild = true;
            db.folder.save(folder, function(err){
                if(err){
                    console.log('models/folder/create', err);
                }
            });
        }else{
            doc.parent = doc.top = null;
        }
        db.folder.insert(doc, function(err, result){
            if(err){
                return proxy.emit('error', err);
            }
            result = result[0];
            if(folder){
                result.idpath = folder.idpath + ',' + result._id;
            }else{
                result.idpath = result._id.toString();
            }

            db.folder.save(result, function(err){
                if(err){
                    console.log('models/folder/create', err);
                }
            });
            callback(err, result);
        });

    });

    proxy.fail(callback);

    if(folderId){
        db.folder.findOne({ _id: new ObjectID(folderId.toString())}, proxy.done("folder"));
    }else{
        proxy.emit('folder', null);
    }
}

exports.getFolder = function(query, callback){

    db.folder.findOne(query, function(err, doc){
        if(err || !doc){
            callback(err, doc);
            return;
        }
        db.dereference(doc, {'parent': ['_id', 'name'], 'top': ['_id', 'name']}, callback);
    });

}

exports.modify = function(params, doc, callback){
    var folderId = params.folderId;
    var groupId = params.groupId;
    var creator = params.creator;

    doc.updatetime = Date.now();
    var query = {
        _id: new ObjectID(folderId)
    }

    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }

    db.folder.findAndModify(query, [], { $set: doc },
            { 'new':true }, callback);
}

function deleteFolderAndFiles(oFolderId, callback){
    db.folder.remove({ _id: oFolderId }, function(err){
        if(err){
            console.log('>>>folder.delete [folder]', err);
            callback(err);
            return;
        }
        mFile.batchDelete({ 'folder.$id': oFolderId }, function(err, count){
            if(err){
                console.log('>>>folder.delete [file]', err);
                callback(err);
                return;
            }
            callback(null, 1 + (count || 0));
        });
    });

}

exports.delete = function(params, callback){
    var groupId = params.groupId;
    var folderId = params.folderId;
    var creator = params.creator;

    var query = {
        _id: new ObjectID(folderId)
    }

    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }

    var ep = new EventProxy();

    ep.fail(callback);

    db.folder.findOne(query, ep.doneLater('getFolderSucc'));
    ep.on('getFolderSucc', function(folder){
        if(!folder){
            return ep.emit('error', 'no such folder', ERR.NOT_FOUND);
        }
        if(folder.hasChild){

            var query = {
                idpath: new RegExp('.*' + folderId + '.*')
            };

            db.folder.find(query, ep.done('findAllChild'));
        }else{
            deleteFolderAndFiles(folder._id, callback);

        }
    });

    ep.all('getFolderSucc', 'findAllChild', function(folder, docs){
        if(!docs.length){
            deleteFolderAndFiles(folder._id, callback);
            return;
        }

        ep.after('delete', docs.length, function(list){
            callback(null, U.calculate(list));
        });

        docs.forEach(function(doc){

            deleteFolderAndFiles(doc._id, ep.group('delete'));
        });
    });
}

exports.isFolderCreator = function(folderId, userId, callback){
    var query = {
        '_id': ObjectID(folderId),
        'creator.$id': ObjectID(userId)
    };

    db.folder.findOne(query, function(err, doc){
        if(doc){
            callback(null, true, doc);
        }else{
            callback(null, false);
        }
    });
}

exports.list = function(params, callback){

    var folderId = params.folderId;
    var groupId = params.groupId || null;
    var order = null;

    var query = {
        'parent.$id': ObjectID(folderId)
    };
    if(params.creator){
        query['creator.$id'] = ObjectID(params.creator);
    }
    if(params.order){
        order = U.jsonParse(order);
    }

    db.folder.find(query, { sort: order}, function(err, docs){
        if(err){
            callback(err)
        }else{
            db.dereferences(docs, {'creator': ['_id', 'nick']}, callback);
        }
    });

}

exports.search = function(params, callback){

    var folderId = params.folderId;
    var groupId = params.groupId || null;
    var creator = params.creator || null;
    var keyword = params.keyword || '';

    var query = {
        $or: [
            { 'parent.$id': new ObjectID(folderId) },
            { idpath: new RegExp('.*' + folderId + '.*') }
        ]
    };
    if(keyword){
        query['name'] = new RegExp('.*' + U.encodeRegexp(keyword) + '.*');
    }
    if(creator){
        query['creator.$id'] = ObjectID(creator);
    }
    if(groupId){
        query['group.$id'] = ObjectID(groupId);
    }
    db.search('folder', query, params, function(err, total, docs){
        if(err){
            callback(err);
        }else if(total && docs){
            db.dereferences(docs, {'creator': ['_id', 'nick']}, function(err, docs){
                if(err){
                    callback(err)
                }else{
                    callback(null, total || 0, docs);
                }
            });
        }else{
            callback(null, total || 0, docs);
        }
    });
}
<|endoftext|>


<commit_before>//@ts-check

const fs = require('fs');
const http = require('http');
const ipInfo = require('ipinfo');
const path = require('path');
const url = require('url');
const WebSocketServer = require('websocket').server;
const port = process.argv[2] || 80;
const basePath = process.argv[3] || 'web';

// prepare a random data buffer of 128KB
const buffer = Buffer.alloc(128 * 1024);
for (let bufferIndex = 0; bufferIndex < buffer.byteLength; bufferIndex++) {
    buffer[bufferIndex] = Math.random();
}

const getRandomData = (size = 8 * 1024 * 1024) => {
    // build the data array of desired size from the buffer
    const data = Buffer.alloc(size);
    for (let dataIndex = 0; dataIndex * buffer.byteLength < size; dataIndex++) {
        data.set(
            buffer,
            dataIndex * buffer.byteLength
        );
    }

    return data;
};

const server = http.createServer((request, response) => {
    const {
        pathname: uri,
        query: query
    } = url.parse(request.url, true);

    // process HTTP request
    try {
        switch (uri) {
            case '/ip':
                response.writeHead(200);
                const ip = /\:\:ffff\:((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/.test(request.connection.remoteAddress)
                    ? request.connection.remoteAddress.replace('::ffff:', '')
                    : request.connection.remoteAddress;
                ipInfo(`${ip}/org`, (err, org) => {
                    response.write(org ? `${ip} (${org})` : ip);
                    response.end();
                });
                break;
            case '/ping':
            case '/upload':
                response.writeHead(200);
                response.end();
                break;
            case '/download':
                response.writeHead(200, {
                    'Content-Type': 'application/octet-stream',
                    'Content-Length': +query.size
                });
                response.write(
                    getRandomData(+query.size),
                    'binary'
                );
                response.end();
                break;
            default:
                let filename = path.join(process.cwd(), basePath, uri);

                fs.exists(filename, exists => {
                    if (!exists) {
                        response.writeHead(404, {
                            'Content-Type': 'text/plain'
                        });
                        response.write('Not Found');
                        response.end();
                        return;
                    }

                    if (fs.statSync(filename).isDirectory()) {
                        filename += 'index.html';
                    }

                    fs.readFile(filename, 'binary', (err, data) => {
                        if (err) {
                            response.writeHead(500, {
                                'Content-Type': 'text/plain'
                            });
                            response.write(err.message);
                            response.end();
                            return;
                        }

                        let contentType = 'text/plain';
                        switch(path.extname(filename)) {
                            case '.css':
                                contentType = 'text/css';
                                break;
                            case '.html':
                                contentType = 'text/html';
                                break;
                            case '.js':
                                contentType = 'application/javascript';
                                break;
                        }
                        response.writeHead(200, {
                            'Content-Type': contentType,
                            'Content-Length': data.length
                        });
                        response.write(data, 'binary');
                        response.end();
                    });
                });

                break;
        }
    } catch (err) {
        response.writeHead(500, {
            'Content-Type': 'text/plain'
        });
        response.write(err);
        response.end();
    }
});
server.listen(port);

if (!server.listening) {
    throw new Error(`Server failed listening on port ${port}`);
}

console.log(`Server listening at http://0.0.0.0:${port}/`);

// create the server
const wsServer = new WebSocketServer({
    httpServer: server,
    maxReceivedFrameSize: 20 * 1024 * 1024
});

// WebSocket server
wsServer.on('request', request => {
    let downloadData;
    const connection = request.accept(null, request.origin);

    // handle messages
    connection.on('message', message => {
        if (message.type === 'utf8') {
            try {
                const data = JSON.parse(message.utf8Data);

                switch (data.action) {
                    case 'ping':
                        connection.send(JSON.stringify({
                            action: 'pong',
                            index: data.index
                        }));
                        break;

                    case 'prepare':
                        downloadData = getRandomData(data.size);
                        break;

                    case 'download':
                        connection.send(downloadData);
                        break;
                }
            } catch (error) {
                // nothing
            }
        }

        if (message.type === 'binary') {
            connection.send('');
            return;
        }
    });

    connection.on('close', connection => {
        downloadData = null;
    });
});
<commit_msg>Handle X-Forwarded-For header in server<commit_after>//@ts-check

const fs = require('fs');
const http = require('http');
const ipInfo = require('ipinfo');
const path = require('path');
const url = require('url');
const WebSocketServer = require('websocket').server;
const port = process.argv[2] || 80;
const basePath = process.argv[3] || 'web';

// prepare a random data buffer of 128KB
const buffer = Buffer.alloc(128 * 1024);
for (let bufferIndex = 0; bufferIndex < buffer.byteLength; bufferIndex++) {
    buffer[bufferIndex] = Math.random();
}

const getRandomData = (size = 8 * 1024 * 1024) => {
    // build the data array of desired size from the buffer
    const data = Buffer.alloc(size);
    for (let dataIndex = 0; dataIndex * buffer.byteLength < size; dataIndex++) {
        data.set(
            buffer,
            dataIndex * buffer.byteLength
        );
    }

    return data;
};

const server = http.createServer((request, response) => {
    const {
        pathname: uri,
        query: query
    } = url.parse(request.url, true);

    // process HTTP request
    try {
        switch (uri) {
            case '/ip':
                response.writeHead(200);
                const ipRegex = /\:\:ffff\:((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/;
                const ip =  ipRegex.test(request.headers['x-forwarded-for'] || request.connection.remoteAddress)
                    ? request.connection.remoteAddress.replace('::ffff:', '')
                    : request.connection.remoteAddress;
                ipInfo(`${ip}/org`, (err, org) => {
                    response.write(org ? `${ip} (${org})` : ip);
                    response.end();
                });
                break;
            case '/ping':
            case '/upload':
                response.writeHead(200);
                response.end();
                break;
            case '/download':
                response.writeHead(200, {
                    'Content-Type': 'application/octet-stream',
                    'Content-Length': +query.size
                });
                response.write(
                    getRandomData(+query.size),
                    'binary'
                );
                response.end();
                break;
            default:
                let filename = path.join(process.cwd(), basePath, uri);

                fs.exists(filename, exists => {
                    if (!exists) {
                        response.writeHead(404, {
                            'Content-Type': 'text/plain'
                        });
                        response.write('Not Found');
                        response.end();
                        return;
                    }

                    if (fs.statSync(filename).isDirectory()) {
                        filename += 'index.html';
                    }

                    fs.readFile(filename, 'binary', (err, data) => {
                        if (err) {
                            response.writeHead(500, {
                                'Content-Type': 'text/plain'
                            });
                            response.write(err.message);
                            response.end();
                            return;
                        }

                        let contentType = 'text/plain';
                        switch(path.extname(filename)) {
                            case '.css':
                                contentType = 'text/css';
                                break;
                            case '.html':
                                contentType = 'text/html';
                                break;
                            case '.js':
                                contentType = 'application/javascript';
                                break;
                        }
                        response.writeHead(200, {
                            'Content-Type': contentType,
                            'Content-Length': data.length
                        });
                        response.write(data, 'binary');
                        response.end();
                    });
                });

                break;
        }
    } catch (err) {
        response.writeHead(500, {
            'Content-Type': 'text/plain'
        });
        response.write(err);
        response.end();
    }
});
server.listen(port);

if (!server.listening) {
    throw new Error(`Server failed listening on port ${port}`);
}

console.log(`Server listening at http://0.0.0.0:${port}/`);

// create the server
const wsServer = new WebSocketServer({
    httpServer: server,
    maxReceivedFrameSize: 20 * 1024 * 1024
});

// WebSocket server
wsServer.on('request', request => {
    let downloadData;
    const connection = request.accept(null, request.origin);

    // handle messages
    connection.on('message', message => {
        if (message.type === 'utf8') {
            try {
                const data = JSON.parse(message.utf8Data);

                switch (data.action) {
                    case 'ping':
                        connection.send(JSON.stringify({
                            action: 'pong',
                            index: data.index
                        }));
                        break;

                    case 'prepare':
                        downloadData = getRandomData(data.size);
                        break;

                    case 'download':
                        connection.send(downloadData);
                        break;
                }
            } catch (error) {
                // nothing
            }
        }

        if (message.type === 'binary') {
            connection.send('');
            return;
        }
    });

    connection.on('close', connection => {
        downloadData = null;
    });
});
<|endoftext|>


<commit_before>
var EventProxy = require('eventproxy');
var ObjectID = require('mongodb').ObjectID;

var config = require('../config');
var ERR = require('../errorcode');
var mFolder = require('../models/folder');
var mGroup = require('../models/group');
var mLog = require('../models/log');
var U = require('../util');
var fileHelper = require('../helper/file_helper');

exports.create = function(req, res){
    var loginUser = req.loginUser;

    var params = req.body;
    var groupId = params.groupId;
    var folderId = params.folderId;
    var name = params.name;

    params.creator = loginUser._id;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role, folder){
        if(!role || role === 'department'){
            ep.emit('error', 'not auth to create folder on this folder', ERR.NOT_AUTH);
            return;
        }

        // 检查重名
        mFolder.getFolder({
            name: name,
            'parent.$id': ObjectID(folderId)
        }, ep.done('checkName'));

    });

    ep.on('checkName', function(folder){
        if(folder){
            ep.emit('error', 'has the same folder name', ERR.DUPLICATE);
            return;
        }

        mFolder.create(params, ep.done('create'));

    });

    ep.on('create', function(folder){
        res.json({
            err: ERR.SUCCESS,
            result: {
                data: folder
            }
        });
        // 记录该操作
        mLog.create({
            fromUserId: loginUser._id,
            fromUserName: loginUser.nick,

            folderId: folder._id.toString(),
            folderName: folder.name,

            //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
            //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
            //11: delete(移动到回收站) 12: 创建文件夹
            operateType: 12,

            srcFolderId: folderId,
            // distFolderId: params.targetId,
            fromGroupId: folder.group && folder.group.oid.toString()
            // toGroupId: toGroupId
        });
    });

}

exports.get = function(req, res){
    var params = req.query;

    mFolder.getFolder({ _id: ObjectID(params.folderId) }, function(err, doc){
        if(err){
            res.json({ err: ERR.SERVER_ERROR, msg: err});
        }else{
            res.json({
                err: ERR.SUCCESS,
                result: {
                    data: doc
                }
            });
        }
    });
}

exports.modify = function(req, res){
    // 只能修改自己的
    var params = req.body;
    var folderId = params.folderId;
    var loginUser = req.loginUser;
    params.creator = loginUser._id;

    var doc = {};
    if(params.mark){
        doc.mark = params.mark;
    }
    if(params.name){
        doc.name = params.name;
    }

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mFolder.getFolder({
        _id: ObjectID(folderId)
    }, ep.doneLater('getFolder'));

    ep.on('getFolder', function(folder){
        if(!folder){
            ep.emit('error', 'no such folder', ERR.NOT_FOUND);
            return;
        }
        if(folder.creator.oid.toString() !== params.creator){
            ep.emit('error', 'no allow', ERR.NOT_AUTH);
            return;
        }
        if(params.name){
            if(params.name === folder.name){
                // 名字没变过, 就不要改了
                delete doc.name;
                delete params.name;
                ep.emit('checkName', true);
                return;
            }
            mFolder.getFolder({
                name: params.name,
                'parent.$id': folder.parent._id
            }, function(err, doc){
                if(doc){
                    ep.emit('checkName', false);
                }else{
                    ep.emit('checkName', true);
                }
            });
        }else{
            ep.emit('checkName', true);
        }

    });

    ep.all('getFolder', 'checkName', function(folder, result){
        if(!result){
            ep.emit('error', 'has the same name in this folder', ERR.DUPLICATE);
            return;
        }
        var oldFolderName = folder.name;
        mFolder.modify(params, doc, function(err, doc){
            if(err){
                res.json({ err: ERR.SERVER_ERROR, msg: err});
            }else if(!doc){
                res.json({ err: ERR.NOT_FOUND, msg: 'no such folder'});
            }else{
                res.json({ err: ERR.SUCCESS , result: { data: doc }});
                // 记录该操作
                mLog.create({
                    fromUserId: loginUser._id,
                    fromUserName: loginUser.nick,

                    folderId: doc._id.toString(),
                    folderName: oldFolderName,
                    newFolderName: doc.name,

                    //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
                    //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
                    //11: delete(移动到回收站) 12: 创建文件夹
                    operateType: 5,

                    srcFolderId: folder.parent._id,
                    // distFolderId: params.targetId,
                    fromGroupId: folder.group && folder.group.oid.toString()
                    // toGroupId: toGroupId
                });
            }
        });
    });

}

function deleteFolder(params, callback){
    // 检查改目录下是否有不是自己的文件, 有就不能删
    // 管理员不受限制
    var ep = new EventProxy();
    ep.fail(callback);

    mFolder.getFolder({
        _id: ObjectID(params.folderId),
        'creator.$id': ObjectID(params.creator)
    }, ep.doneLater('getFolderSucc'));

    ep.on('getFolderSucc', function(folder){
        if(!folder){
            ep.emit('error', 'no such folder', ERR.NOT_FOUND);
            return;
        }
        if(('deletable' in folder) && !folder.deletable){
            ep.emit('error', 'can not delete this folder', ERR.UNDELETABLE);
            return;
        }
        //TODO 检查是否有不属于自己的文件, 有就不能删
        mFolder.delete(params, callback);
        // if(folder.parent && !folder.parent.oid){
        //     console.log('ugly folder: ', folder);
        // }
        // 记录该操作
        mLog.create({
            fromUserId: params.creator,

            folderId: params.folderId,

            //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
            //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
            //11: delete(移动到回收站) 12: 创建文件夹
            operateType: 6,
            // 这里要用 parent._id, 因为 getFolder 方法把它解开了
            srcFolderId: folder.parent && folder.parent._id && folder.parent._id.toString(),
            // distFolderId: params.targetId,
            fromGroupId: folder.group && folder.group.oid.toString()
            // toGroupId: toGroupId
        });
    });

}

exports.delete = function(req, res){
    var params = req.body;
    var folderIds = params.folderId;
    var groupId = params.groupId;
    var loginUser = req.loginUser;
    var creator = loginUser._id;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    ep.after('delete', folderIds.length, function(list){
        res.json({
            err: ERR.SUCCESS,
            result: {
                count: U.calculate(list)
            }
        });
    });

    folderIds.forEach(function(folderId){

        deleteFolder({
            folderId: folderId,
            groupId: groupId,
            creator: creator
        }, ep.group('delete'));

    });

}

exports.list = function(req, res){
    var params = req.query;

    var folderId = params.folderId;
    var groupId = params.groupId || null;

    var loginUser = req.loginUser;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role){
        if(!role){
            ep.emit('error', 'not auth to search this folder', ERR.NOT_AUTH);
            return;
        }
        if(role === 'creator'){
            params.creator = loginUser._id;
        }else if(role === 'pubFolder' || role === 'department'){
            params.extendQuery = {// 公開文件夾可以搜索文件夾, 非公開就不返回內容
                isOpen: true
            };
        }
        params.isDeref = true;
        mFolder.list(params, ep.done('search'));
    });
    ep.on('search', function(total, docs){
        res.json({
            err: ERR.SUCCESS,
            result: {
                total: total,
                list: docs
            }
        });
    });
}

exports.search = function(req, res){
    var params = req.query;

    var folderId = params.folderId;
    var groupId = params.groupId || null;

    var loginUser = req.loginUser;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role){
        if(!role){
            ep.emit('error', 'not auth to search this folder', ERR.NOT_AUTH);
            return;
        }
        if(role === 'creator'){
            params.creator = loginUser._id;
        }else if(role === 'pubFolder' || role === 'department'){
            params.extendQuery = {// 公開文件夾可以搜索文件夾, 非公開就不返回內容
                isOpen: true
            };
        }
        params.isDeref = true;
        mFolder.search(params, ep.done('search'));
    });

    ep.on('search', function(total, docs){
        res.json({
            err: ERR.SUCCESS,
            result: {
                total: total,
                list: docs
            }
        });
    });
}
<commit_msg>公开文件夹的新建子文件夹继承父文件夹的公开和读写状态<commit_after>
var EventProxy = require('eventproxy');
var ObjectID = require('mongodb').ObjectID;

var config = require('../config');
var ERR = require('../errorcode');
var mFolder = require('../models/folder');
var mGroup = require('../models/group');
var mLog = require('../models/log');
var U = require('../util');
var fileHelper = require('../helper/file_helper');

exports.create = function(req, res){
    var loginUser = req.loginUser;

    var params = req.body;
    var groupId = params.groupId;
    var folderId = params.folderId;
    var name = params.name;

    params.creator = loginUser._id;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role, folder){
        if(!role || role === 'department'){
            ep.emit('error', 'not auth to create folder on this folder', ERR.NOT_AUTH);
            return;
        }

        // 继承父文件夹的公开和读写状态
        params.isOpen = folder.isOpen ? 1 : 0;
        params.isReadonly = folder.isReadonly ? 1 : 0;
        // 检查重名
        mFolder.getFolder({
            name: name,
            'parent.$id': ObjectID(folderId)
        }, ep.done('checkName'));

    });

    ep.on('checkName', function(folder){
        if(folder){
            ep.emit('error', 'has the same folder name', ERR.DUPLICATE);
            return;
        }

        mFolder.create(params, ep.done('create'));

    });

    ep.on('create', function(folder){
        res.json({
            err: ERR.SUCCESS,
            result: {
                data: folder
            }
        });
        // 记录该操作
        mLog.create({
            fromUserId: loginUser._id,
            fromUserName: loginUser.nick,

            folderId: folder._id.toString(),
            folderName: folder.name,

            //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
            //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
            //11: delete(移动到回收站) 12: 创建文件夹
            operateType: 12,

            srcFolderId: folderId,
            // distFolderId: params.targetId,
            fromGroupId: folder.group && folder.group.oid.toString()
            // toGroupId: toGroupId
        });
    });

}

exports.get = function(req, res){
    var params = req.query;

    mFolder.getFolder({ _id: ObjectID(params.folderId) }, function(err, doc){
        if(err){
            res.json({ err: ERR.SERVER_ERROR, msg: err});
        }else{
            res.json({
                err: ERR.SUCCESS,
                result: {
                    data: doc
                }
            });
        }
    });
}

exports.modify = function(req, res){
    // 只能修改自己的
    var params = req.body;
    var folderId = params.folderId;
    var loginUser = req.loginUser;
    params.creator = loginUser._id;

    var doc = {};
    if(params.mark){
        doc.mark = params.mark;
    }
    if(params.name){
        doc.name = params.name;
    }

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mFolder.getFolder({
        _id: ObjectID(folderId)
    }, ep.doneLater('getFolder'));

    ep.on('getFolder', function(folder){
        if(!folder){
            ep.emit('error', 'no such folder', ERR.NOT_FOUND);
            return;
        }
        if(folder.creator.oid.toString() !== params.creator){
            ep.emit('error', 'no allow', ERR.NOT_AUTH);
            return;
        }
        if(params.name){
            if(params.name === folder.name){
                // 名字没变过, 就不要改了
                delete doc.name;
                delete params.name;
                ep.emit('checkName', true);
                return;
            }
            mFolder.getFolder({
                name: params.name,
                'parent.$id': folder.parent._id
            }, function(err, doc){
                if(doc){
                    ep.emit('checkName', false);
                }else{
                    ep.emit('checkName', true);
                }
            });
        }else{
            ep.emit('checkName', true);
        }

    });

    ep.all('getFolder', 'checkName', function(folder, result){
        if(!result){
            ep.emit('error', 'has the same name in this folder', ERR.DUPLICATE);
            return;
        }
        var oldFolderName = folder.name;
        mFolder.modify(params, doc, function(err, doc){
            if(err){
                res.json({ err: ERR.SERVER_ERROR, msg: err});
            }else if(!doc){
                res.json({ err: ERR.NOT_FOUND, msg: 'no such folder'});
            }else{
                res.json({ err: ERR.SUCCESS , result: { data: doc }});
                // 记录该操作
                mLog.create({
                    fromUserId: loginUser._id,
                    fromUserName: loginUser.nick,

                    folderId: doc._id.toString(),
                    folderName: oldFolderName,
                    newFolderName: doc.name,

                    //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
                    //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
                    //11: delete(移动到回收站) 12: 创建文件夹
                    operateType: 5,

                    srcFolderId: folder.parent._id,
                    // distFolderId: params.targetId,
                    fromGroupId: folder.group && folder.group.oid.toString()
                    // toGroupId: toGroupId
                });
            }
        });
    });

}

function deleteFolder(params, callback){
    // 检查改目录下是否有不是自己的文件, 有就不能删
    // 管理员不受限制
    var ep = new EventProxy();
    ep.fail(callback);

    mFolder.getFolder({
        _id: ObjectID(params.folderId),
        'creator.$id': ObjectID(params.creator)
    }, ep.doneLater('getFolderSucc'));

    ep.on('getFolderSucc', function(folder){
        if(!folder){
            ep.emit('error', 'no such folder', ERR.NOT_FOUND);
            return;
        }
        if(('deletable' in folder) && !folder.deletable){
            ep.emit('error', 'can not delete this folder', ERR.UNDELETABLE);
            return;
        }
        //TODO 检查是否有不属于自己的文件, 有就不能删
        mFolder.delete(params, callback);
        // if(folder.parent && !folder.parent.oid){
        //     console.log('ugly folder: ', folder);
        // }
        // 记录该操作
        mLog.create({
            fromUserId: params.creator,

            folderId: params.folderId,

            //操作类型 1: 上传, 2: 下载, 3: copy, 4: move, 5: modify
            //6: delete 7: 预览 8: 保存, 9: 分享给用户 10: 分享给小组,
            //11: delete(移动到回收站) 12: 创建文件夹
            operateType: 6,
            // 这里要用 parent._id, 因为 getFolder 方法把它解开了
            srcFolderId: folder.parent && folder.parent._id && folder.parent._id.toString(),
            // distFolderId: params.targetId,
            fromGroupId: folder.group && folder.group.oid.toString()
            // toGroupId: toGroupId
        });
    });

}

exports.delete = function(req, res){
    var params = req.body;
    var folderIds = params.folderId;
    var groupId = params.groupId;
    var loginUser = req.loginUser;
    var creator = loginUser._id;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    ep.after('delete', folderIds.length, function(list){
        res.json({
            err: ERR.SUCCESS,
            result: {
                count: U.calculate(list)
            }
        });
    });

    folderIds.forEach(function(folderId){

        deleteFolder({
            folderId: folderId,
            groupId: groupId,
            creator: creator
        }, ep.group('delete'));

    });

}

exports.list = function(req, res){
    var params = req.query;

    var folderId = params.folderId;
    var groupId = params.groupId || null;

    var loginUser = req.loginUser;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role){
        if(!role){
            ep.emit('error', 'not auth to search this folder', ERR.NOT_AUTH);
            return;
        }
        if(role === 'creator'){
            params.creator = loginUser._id;
        }else if(role === 'pubFolder' || role === 'department'){
            params.extendQuery = {// 公開文件夾可以搜索文件夾, 非公開就不返回內容
                isOpen: true
            };
        }
        params.isDeref = true;
        mFolder.list(params, ep.done('search'));
    });
    ep.on('search', function(total, docs){
        res.json({
            err: ERR.SUCCESS,
            result: {
                total: total,
                list: docs
            }
        });
    });
}

exports.search = function(req, res){
    var params = req.query;

    var folderId = params.folderId;
    var groupId = params.groupId || null;

    var loginUser = req.loginUser;

    var ep = new EventProxy();
    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    // 检查权限
    fileHelper.hasFolderAccessRight(loginUser._id, folderId, groupId, ep.doneLater('checkRight'));

    ep.on('checkRight', function(role){
        if(!role){
            ep.emit('error', 'not auth to search this folder', ERR.NOT_AUTH);
            return;
        }
        if(role === 'creator'){
            params.creator = loginUser._id;
        }else if(role === 'pubFolder' || role === 'department'){
            params.extendQuery = {// 公開文件夾可以搜索文件夾, 非公開就不返回內容
                isOpen: true
            };
        }
        params.isDeref = true;
        mFolder.search(params, ep.done('search'));
    });

    ep.on('search', function(total, docs){
        res.json({
            err: ERR.SUCCESS,
            result: {
                total: total,
                list: docs
            }
        });
    });
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');

router.post('/', function(req, res) {
  if (req.query.secret !== process.env.SECRET) {
    res.sendStatus(404);
  }

  var alertMessage = 'Some alert message';
  var type = req.query.type;

  switch(type) {
    case 'boxerror':
      alertMessage = 'Box Error';
      break;
    case 'elevatedclientalerts':
      alertMessage = 'Elevated Client Alerts';
      break;
    case 'elevatedserveralerts':
      alertMessage = 'Elevated Server Alerts';
      break;
    case 'jobfailed':
      alertMessage = 'Job Failed';
      break;
    case 'memoryquotaexceeded':
      alertMessage = 'Memory Quota Exceeded';
      break;
    case 'requesttimeouts':
      alertMessage = 'Request Timeouts';
      break;
    case 'slowrequests':
      alertMessage = 'Slow Requests';
      break;
  }

  var payload = {
    channel: '#hackers',
    username: 'DoomGuy',
    icon_emoji: ':godmode:',
    attachments: [{
      fallback: 'Alert',
      color: 'danger',
      text: '<!channel>',
      fields: [{
        title: 'Alert From',
        value: 'Loggly',
        short: 'true'
      }, {
        title: 'Type',
        value: alertMessage,
        short: 'true'
      }]
    }]
  };

  request({
    url: process.env.URL,
    method: 'POST',
    body: JSON.stringify(payload)
  }, function() {
    res.sendStatus(201);
  });
});

module.exports = router;
<commit_msg>Add end request.<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');

router.post('/', function(req, res) {
  if (req.query.secret !== process.env.SECRET) {
    res.sendStatus(404).end();
  }

  var alertMessage = 'Some alert message';
  var type = req.query.type;

  switch(type) {
    case 'boxerror':
      alertMessage = 'Box Error';
      break;
    case 'elevatedclientalerts':
      alertMessage = 'Elevated Client Alerts';
      break;
    case 'elevatedserveralerts':
      alertMessage = 'Elevated Server Alerts';
      break;
    case 'jobfailed':
      alertMessage = 'Job Failed';
      break;
    case 'memoryquotaexceeded':
      alertMessage = 'Memory Quota Exceeded';
      break;
    case 'requesttimeouts':
      alertMessage = 'Request Timeouts';
      break;
    case 'slowrequests':
      alertMessage = 'Slow Requests';
      break;
  }

  var payload = {
    channel: '#hackers',
    username: 'DoomGuy',
    icon_emoji: ':godmode:',
    attachments: [{
      fallback: 'Alert',
      color: 'danger',
      text: '<!channel>',
      fields: [{
        title: 'Alert From',
        value: 'Loggly',
        short: 'true'
      }, {
        title: 'Type',
        value: alertMessage,
        short: 'true'
      }]
    }]
  };

  request({
    url: process.env.URL,
    method: 'POST',
    body: JSON.stringify(payload)
  }, function() {
    res.sendStatus(201);
  });
});

module.exports = router;
<|endoftext|>


<commit_before>/*
* @Author: kuychaco
* @Date:   2015-06-03 11:57:45
* @Last Modified by:   kuychaco
* @Last Modified time: 2015-06-08 16:43:02
*/

'use strict';

var dbController = require('../database/db');
var express = require('express');
var router = express.Router();
var data = require('../database/data-stubs');

var graph;
router.get('/', function(req, res) {
  res.json({message: 'welcome to our api!'});
});
router.get('/cluster/:cluster_id', function(req, res) {
  console.log('get request for cluster', req.params.cluster_id);

  if (req.params.cluster_id === '1') {
    return res.json(data.graph1);
  }
  else if (req.params.cluster_id === '5') {
    return res.json(data.graph2);
  }
  res.end('could not find cluster');
});

router.post('/cluster/:cluster_id', function(req, res) {
  console.log(req.body);
  dbController.postCluster(req.body);
  res.end('cluster received');
});

router.post('/nodes', function(req, res) {
  console.log(req.body);
  dbController.postNodes(req.body);
  res.end('nodes received');
});

module.exports = router;
<commit_msg>(feat) Implement endpoint for cluster_id<commit_after>/*
* @Author: kuychaco
* @Date:   2015-06-03 11:57:45
* @Last Modified by:   kuychaco
* @Last Modified time: 2015-06-09 20:20:05
*/

'use strict';

var Bluebird = require('bluebird');
var dbController = Bluebird.promisifyAll(require('../database/db-controller'));
var express = require('express');
var router = express.Router();
var data = require('../database/data-stubs');

router.get('/', function(req, res) {
  res.json({message: 'welcome to our api!'});
});

router.get('/cluster/:cluster_id', function(req, res) {
  console.log('get request for cluster', req.params.cluster_id);
  var clusterId = req.params.cluster_id;

  dbController.getGraphAsync(clusterId)
    .then(function(graph) {
      res.json(graph);
    })
    .catch(function(err) {
      res.status(500).send(err.message);
    })
    .finally(function() {
      res.end('could not find cluster');
      // TODO: Research when to close connection
      // dbController.closeConnection();
    });

});

router.post('/cluster/:cluster_id', function(req, res) {
  console.log(req.body);
  dbController.postCluster(req.body);
  res.end('cluster received');
});

router.post('/nodes', function(req, res) {
  console.log(req.body);
  dbController.postNodes(req.body);
  res.end('nodes received');
});

module.exports = router;
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var Tweet = require('../models/tweet.js');
var Datastore = require('nedb')
  , db = new Datastore();

router.get('/', function (req, res, next) {
    db.find({}).sort({ timestamp: -1}).exec(function (err, tweets) {
        if (err) {
            return next({ status: 500, message: err });
        }

        res.json({ tweets: tweets });
    });
});

router.post('/', function (req, res, next) {
    if (!req.body.tweet) {
        return next({ status: 400 });
    }

    var author = req.body.tweet.author;
    var message = req.body.tweet.message;

    if (!author || !message) {
        return next({ status: 400 });
    }

    var tweet = new Tweet(author, message);
    db.insert(tweet, function (err) {
        if (err) {
            return next({ status: 500, message: err });
        }

        return res.status(201).json({ tweets: tweet });
    });
});

module.exports = router;<commit_msg>file based db<commit_after>var express = require('express');
var router = express.Router();
var Tweet = require('../models/tweet.js');
var Datastore = require('nedb')
  , db = new Datastore({ filename: "techreadytweets", autoload: true });

router.get('/', function (req, res, next) {
    db.find({}).sort({ timestamp: -1}).exec(function (err, tweets) {
        if (err) {
            return next({ status: 500, message: err });
        }

        res.json({ tweets: tweets });
    });
});

router.post('/', function (req, res, next) {
    if (!req.body.tweet) {
        return next({ status: 400 });
    }

    var author = req.body.tweet.author;
    var message = req.body.tweet.message;

    if (!author || !message) {
        return next({ status: 400 });
    }

    var tweet = new Tweet(author, message);
    db.insert(tweet, function (err) {
        if (err) {
            return next({ status: 500, message: err });
        }

        return res.status(201).json({ tweets: tweet });
    });
});

module.exports = router;<|endoftext|>


<commit_before>/*jshint node:true*/
"use strict";

var nodemailer = require('nodemailer');
var mustache = require('mustache');
var fs = require('fs');
var templates = ['base', 'register'];

module.exports = function(server) {
	server.Mailer = function() { return this.init.apply(this, arguments); };
	server.Mailer.prototype = {

		init: function(options) {
			this.options = options;
			this.transport = nodemailer.createTransport(this.options.transport.type, this.options.transport.options);

			this.templates = {};
			for (var i=0; i<templates.length; i++) {
				this.templates[templates[i] + '-text'] = fs.readFileSync('server/mails/' + templates[i] + '-text.mustache', 'utf8');
				this.templates[templates[i] + '-html'] = fs.readFileSync('server/mails/' + templates[i] + '-html.mustache', 'utf8');
			}
		},

		sendRegister: function(email, username) {
			this.send('register', {to: {name: username, email: email}, subject: "Nice! You've just joined jsdares.", username: username});
		},

		send: function(type, data) {
			var mailOptions = {
				from: this.options.from.name + '<' + this.options.from.email + '>',
				to: data.to.name + '<' + data.to.email + '>',
				subject: data.subject,
				text: mustache.render(this.templates['base-text'], {subject: data.subject, content: mustache.render(this.templates[type + '-text'], data)}),
				html: mustache.render(this.templates['base-html'], {subject: data.subject, content: mustache.render(this.templates[type + '-html'], data)})
			};

			this.transport.sendMail(mailOptions, (function(error, response) {
				if (error) {
					console.error('Error in mailer @ ' + type + ' @ DATA : ' + JSON.stringify(data) + ' @ ERROR: '  + error);
				} else if (this.options.log) {
					console.log('SENT MAIL ' + type + ' - ' + data.to.name + '<' + data.to.email + '>');
				}
			}).bind(this));
		}
	};
};
<commit_msg>Tiny commit to force app reload<commit_after>/*jshint node:true*/
"use strict";

var nodemailer = require('nodemailer');
var mustache = require('mustache');
var fs = require('fs');
var templates = ['base', 'register'];

module.exports = function(server) {
	server.Mailer = function() { return this.init.apply(this, arguments); };
	server.Mailer.prototype = {

		init: function(options) {
			this.options = options;
			this.transport = nodemailer.createTransport(this.options.transport.type, this.options.transport.options);

			this.templates = {};
			for (var i=0; i<templates.length; i++) {
				this.templates[templates[i] + '-text'] = fs.readFileSync('server/mails/' + templates[i] + '-text.mustache', 'utf8');
				this.templates[templates[i] + '-html'] = fs.readFileSync('server/mails/' + templates[i] + '-html.mustache', 'utf8');
			}
		},

		sendRegister: function(email, username) {
			this.send('register', {to: {name: username, email: email}, subject: "Nice! You've just joined jsdares.", username: username});
		},

		send: function(type, data) {
			var mailOptions = {
				from: this.options.from.name + '<' + this.options.from.email + '>',
				to: data.to.name + ' <' + data.to.email + '>',
				subject: data.subject,
				text: mustache.render(this.templates['base-text'], {subject: data.subject, content: mustache.render(this.templates[type + '-text'], data)}),
				html: mustache.render(this.templates['base-html'], {subject: data.subject, content: mustache.render(this.templates[type + '-html'], data)})
			};

			this.transport.sendMail(mailOptions, (function(error, response) {
				if (error) {
					console.error('Error in mailer @ ' + type + ' @ DATA : ' + JSON.stringify(data) + ' @ ERROR: '  + error);
				} else if (this.options.log) {
					console.log('SENT MAIL ' + type + ' - ' + data.to.name + '<' + data.to.email + '>');
				}
			}).bind(this));
		}
	};
};
<|endoftext|>


<commit_before>enyo.kind({
    name: "moon.MovieImageItem",
    classes: "moon-movie-list-item moon-3h moon-2v",
    spotlight: true,
    published: {
        option: {
            src: "",
            caption: ""
        }
    },
    handlers: {
        onSpotlightFocused: "focused",
        onSpotlightBlur: "released"
    },
    components: [
        {name: "caption", classes: "moon-movie-list-item-text"}
    ],
    create: function() {
        this.inherited(arguments);
        this.optionChanged();
    },
    getCaption: function() {
        return this.$.caption;
    },
    optionChanged: function(inOld) {
        this.applyStyle("background-image", 'url(' + this.option.src + ')');
        this.$.caption.setContent(this.option.caption);
    },
    focused: function() {
        this.$.caption.addClass("spotlight");
        return true;
    },
    released: function() {
        this.$.caption.removeClass("spotlight");
        return true;
    }
});

// Sample view

enyo.kind({
    name: "moon.sample.login.ContextualPopupSample",
    kind: "moon.Panel",
    layoutKind: "FittableColumnsLayout",
    titleAbove: "01",
    title: "Main Menu",
    components: [
        {kind: "enyo.Spotlight"},
        {
            name: "menuList",
            kind: "enyo.DataList",
            style: "width: 300px;",
            components: [
                {bindFrom: "menuItem", kind: "moon.Item", ontap: "changePanel"}
            ]
        },
        {
            fit: true,
            layoutkind: "FittableRowsLayout",
            components: [
            {
                name: "contentList",
                kind: "enyo.DataGridList",
                fit: true,
                components: [
                    {kind: "moon.MovieImageItem", bindFrom: "itemOption", bindTo: "option"}
                ]
            },
            {
                name: "buttonList",
                kind: "enyo.DataGridList",
                layoutkind: "FittableRowsLayout",
                components: [
                    {kind: "moon.IconButton", bindFrom: "iconSrc", bindTo: "src", bindFrom: "content"},
                    {kind: "moon.Button", bindFrom: "content", bindTo: "content"}
                ]
            }
        ]}

    ],
    bindings: [
        {from: ".controller.menus", to: "$.menuList.controller"},
        {from: ".controller.contents", to: "$.contentList.controller"},
        {from: ".controller.buttons", to: "$.buttonList.controller"}
    ]
 });

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        menus: new enyo.Collection([
            {menuItem: "Browser Movies"},
            {menuItem: "Browser TV Shows"},
            {menuItem: "Queue"},
            {menuItem: "Search"}
        ]),
        contents: new enyo.Collection([
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}}
        ]),
        buttons: new enyo.Collection([
            {iconSrc: "assets/icon-like.png", content: "LIKE"},
            {iconSrc: "", content: "SHARE"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {
                    kind: "moon.sample.login.ContextualPopupSample",
                    controller: ".app.controllers.movieController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "movieController",
                kind: "enyo.ModelController",
                model: sampleModel,
                changePanel: function(inSender, inEvent) {
                    enyo.log("Item: " + inEvent.originator.parent.controller.model.get("menuItem"));
                }
            }
        ]
    });
});<commit_msg>GF-5509: Use contextual Popup<commit_after>enyo.kind({
    name: "moon.MovieImageItem",
    classes: "moon-movie-list-item moon-3h moon-2v",
    spotlight: true,
    published: {
        option: {
            src: "",
            caption: ""
        }
    },
    handlers: {
        onSpotlightFocused: "focused",
        onSpotlightBlur: "released"
    },
    components: [
        {name: "caption", classes: "moon-movie-list-item-text"}
    ],
    create: function() {
        this.inherited(arguments);
        this.optionChanged();
    },
    getCaption: function() {
        return this.$.caption;
    },
    optionChanged: function(inOld) {
        this.applyStyle("background-image", 'url(' + this.option.src + ')');
        this.$.caption.setContent(this.option.caption);
    },
    focused: function() {
        this.$.caption.addClass("spotlight");
        return true;
    },
    released: function() {
        this.$.caption.removeClass("spotlight");
        return true;
    }
});

enyo.kind({
    name: "moon.ContextualLoginPopup",
    kind: "moon.ContextualPopup",
    classes: "moon-5h moon-3v",
    components: [
        {kind: "moon.Divider", content: "Log in to Service"},
        {kind: "moon.InputDecorator", spotlight: true, components: [
            {kind: "moon.Input", placeholder: "E-mail", onchange:""}
        ]},
        {kind: "moon.InputDecorator", spotlight: true, components: [
            {kind: "moon.Input", placeholder: "Password", onchange:""}
        ]},
        {content: "Log in setting Menu"},
        {kind: "moon.Button", content: "Log in"},
        {content: "or Connected with"},
        {kind: "moon.Button", content: "FACEBOOK"},
        {kind: "moon.Button", content: "TWITTER"}
    ]
});

// Sample view

enyo.kind({
    name: "moon.sample.login.ContextualPopupSample",
    kind: "moon.Panel",
    layoutKind: "FittableColumnsLayout",
    titleAbove: "01",
    title: "Main Menu",
    components: [
        {kind: "enyo.Spotlight"},
        {
            name: "menuList",
            kind: "enyo.DataList",
            style: "width: 300px;",
            components: [
                {bindFrom: "menuItem", kind: "moon.Item", ontap: "changePanel"}
            ]
        },
        {
            fit: true,
            layoutkind: "FittableRowsLayout",
            components: [
            {
                name: "contentList",
                kind: "enyo.DataGridList",
                fit: true,
                components: [
                    {kind: "moon.MovieImageItem", bindFrom: "itemOption", bindTo: "option"}
                ]
            },
            {
                name: "buttonList",
                kind: "enyo.DataGridList",
                //layoutkind: "FittableRowsLayout",
                components: [
                    {kind: "moon.ContextualPopupDecorator", components: [
                        {bindFrom: "content", bindTo: "content"},
                        {kind: "moon.ContextualLoginPopup"}
                    ]},
                ]
            }
        ]}

    ],
    bindings: [
        {from: ".controller.menus", to: "$.menuList.controller"},
        {from: ".controller.contents", to: "$.contentList.controller"},
        {from: ".controller.buttons", to: "$.buttonList.controller"}
    ]
 });

// Sample model

enyo.ready(function(){
    var sampleModel = new enyo.Model({
        menus: new enyo.Collection([
            {menuItem: "Browser Movies"},
            {menuItem: "Browser TV Shows"},
            {menuItem: "Queue"},
            {menuItem: "Search"}
        ]),
        contents: new enyo.Collection([
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}},
            {itemOption: {src: "assets/default-movie-vertical.png"}}
        ]),
        buttons: new enyo.Collection([
            {iconSrc: "assets/icon-like.png", content: "LIKE"},
            {iconSrc: "", content: "SHARE"}
        ])
    });

//  Application to render sample

    new enyo.Application({
        view: {
            classes: "enyo-unselectable moon",
            components: [
                {
                    kind: "moon.sample.login.ContextualPopupSample",
                    controller: ".app.controllers.movieController",
                    classes: "enyo-fit"
                }
            ]
        },
        controllers: [
            {
                name: "movieController",
                kind: "enyo.ModelController",
                model: sampleModel,
                changePanel: function(inSender, inEvent) {
                    enyo.log("Item: " + inEvent.originator.parent.controller.model.get("menuItem"));
                }
            }
        ]
    });
});<|endoftext|>


<commit_before>import React from 'react';
import {
  Container,
  Content,
  ListItem,
  Thumbnail,
  List,
  Badge,
  Button
} from 'native-base';
import {Text, TouchableOpacity, View, Text as RNText} from 'react-native';

const themeColor = '#FC8A67' //#f6b19c

export default function Meal (props) {

    const mealsArray = props.meals
    console.log("Day component props", props)

    return (
      <Container style={{marginTop: 10, marginBottom: 50}}>
        <RNText style={{color: '#000', fontWeight: 'bold', textAlign: 'center'}}>{props.label}</RNText>
        <Content>
          <List>
             { (mealsArray.length > 0) && mealsArray.map((meal, i) => { return (
               <ListItem key={i}>
                  <TouchableOpacity onPress={() => props.handleMealClick(meal)}>
                  <Thumbnail style={{width: 120, height: 120}} square source={{uri: meal.photoUrl}} />
                  </TouchableOpacity>
                  <View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap'}}>
                    {meal.tags.map((food, i) => {
                    return (
                      <TouchableOpacity key={i} onPress={() => props.handleTagClick(food)}>
                      <Badge key={i} style={{margin: 5, backgroundColor: themeColor}}><RNText>{food}</RNText></Badge>
                      </TouchableOpacity>
                    )
                    })}
                  </View>
              </ListItem>)
             })}
          </List>

          {props.meals.length && props.label.includes('20') ?
           <Button block style={{backgroundColor: themeColor, marginBottom: 10}} onPress={() => props.goToDailySummary(mealsArray)}>
            <Text>See Daily Nutritional Summary</Text>
          </Button>
           :
          <Button block style={{backgroundColor: themeColor, marginBottom: 10}} onPress={() => props.handleTagReset()}>
            <Text>Back to Calendar</Text>
          </Button>}
        </Content>
      </Container>
    );
  }

<commit_msg>Fixed reducers and added color to the calendar<commit_after>import React from 'react';
import {
  Container,
  Content,
  ListItem,
  Thumbnail,
  List,
  Badge,
  Button
} from 'native-base';
import {Text, TouchableOpacity, View, Text as RNText} from 'react-native';

const themeColor = '#FC8A67' //#f6b19c

export default function Meal (props) {

    const mealsArray = props.meals

    return (
      <Container style={{marginTop: 10, marginBottom: 50}}>
        <RNText style={{color: '#000', fontWeight: 'bold', textAlign: 'center'}}>{props.label}</RNText>
        <Content>
          <List>
             { (mealsArray.length > 0) && mealsArray.map((meal, i) => { return (
               <ListItem key={i}>
                  <TouchableOpacity onPress={() => props.handleMealClick(meal)}>
                  <Thumbnail style={{width: 120, height: 120}} square source={{uri: meal.photoUrl}} />
                  </TouchableOpacity>
                  <View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap'}}>
                    {meal.tags.map((food, i) => {
                    return (
                      <TouchableOpacity key={i} onPress={() => props.handleTagClick(food)}>
                      <Badge key={i} style={{margin: 5, backgroundColor: themeColor}}><RNText>{food}</RNText></Badge>
                      </TouchableOpacity>
                    )
                    })}
                  </View>
              </ListItem>)
             })}
          </List>

          {props.meals.length && props.label.includes('20') ?
           <Button block style={{backgroundColor: themeColor, marginBottom: 10}} onPress={() => props.goToDailySummary(mealsArray)}>
            <Text>See Daily Nutritional Summary</Text>
          </Button>
           :
          <Button block style={{backgroundColor: themeColor, marginBottom: 10}} onPress={() => props.handleTagReset()}>
            <Text>Back to Calendar</Text>
          </Button>}
        </Content>
      </Container>
    );
  }

<|endoftext|>