<commit_before>/*
 * One Controller per layout view
 */

const fs = require('fs');
const pathUtils = require('path').posix;
const url = require('url');
const mime = require('mime');
const api = require('../api');
const rp = require('request-promise');
const express = require('express');
const router = express.Router();
const authHelper = require('../helpers/authentication');
const multer  = require('multer');
const upload = multer({ storage: multer.memoryStorage() });

const thumbs = {
    default: "/images/thumbs/default.png",
    psd: "/images/thumbs/psds.png",
    txt: "/images/thumbs/txts.png",
    doc: "/images/thumbs/docs.png",
    png: "/images/thumbs/pngs.png",
    mp4: "/images/thumbs/mp4s.png",
    mp3: "/images/thumbs/mp3s.png",
    aac: "/images/thumbs/aacs.png",
    avi: "/images/thumbs/avis.png",
    gif: "/images/thumbs/gifs.png",
    html: "/images/thumbs/htmls.png",
    js: "/images/thumbs/jss.png",
    mov: "/images/thumbs/movs.png",
    xls: "/images/thumbs/xlss.png",
    xlsx: "/images/thumbs/xlss.png",
    pdf: "/images/thumbs/pdfs.png",
    flac: "/images/thumbs/flacs.png",
    jpg: "/images/thumbs/jpgs.png",
    jpeg: "/images/thumbs/jpgs.png",
    docx: "/images/thumbs/docs.png",
    ai: "/images/thumbs/ais.png",
    tiff: "/images/thumbs/tiffs.png"
};

const requestSignedUrl = (req, data) => {
    return api(req).post('/fileStorage/signedUrl', {
        json: data
    });
};

const changeQueryParams = (originalUrl, params = {}, pathname = '') => {
    const urlParts = url.parse(originalUrl, true);

    Object.keys(params).forEach(param => {
        urlParts.query[param] = params[param];
    });

    if(pathname) {
        urlParts.pathname = pathname;
    }

    delete urlParts.search;
    return url.format(urlParts);
};

const getBreadcrumbs = (req, {dir = '', baseLabel = '', basePath = '/files/'} = {}) => {
    let dirParts = '';
    const currentDir = dir || req.query.dir || '';
    let pathComponents = currentDir.split('/') || [];
    if(pathComponents[0] === 'users' || pathComponents[0] === 'courses' || pathComponents[0] === 'classes') pathComponents = pathComponents.slice(2);   // remove context and ID, if present
    const breadcrumbs = pathComponents.filter(value => value).map(dirPart => {
        dirParts += '/' + dirPart;
        return {
            label: dirPart,
            url: changeQueryParams(req.originalUrl, {dir: dirParts}, basePath)
        };
    });

    if (baseLabel) {
        breadcrumbs.unshift({
            label: baseLabel,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        });
    }

    return breadcrumbs;
};

const getStorageContext = (req, res, options = {}) => {

    if (req.query.storageContext) {
        return pathUtils.normalize(req.query.storageContext + '/');
    }

    let currentDir = options.dir || req.query.dir || '/';
    const urlParts = url.parse((options.url || req.originalUrl), true);

    let storageContext = urlParts.pathname.replace('/files/', '/');

    if (storageContext === '/') {
        storageContext = 'users/' + res.locals.currentUser._id + '/';
    }

    if(currentDir.slice(-1) != '/') currentDir = currentDir + '/';
    return pathUtils.join(storageContext, currentDir);
};

const FileGetter = (req, res, next) => {
    let path = getStorageContext(req, res);
    let pathComponents = path.split('/');
    if(pathComponents[0] === '') pathComponents = pathComponents.slice(1); // remove leading slash, if present
    const currentDir = pathComponents.slice(2).join('/') || '/';

    path = pathComponents.join('/');

    return api(req).get('/fileStorage', {
        qs: {path}
    }).then(data => {
        let {files, directories} = data;

        files = files.map(file => {
            file.file = pathUtils.join(file.path, file.name);
            return file;
        });

        directories = directories.map(dir => {
            const targetUrl = pathUtils.join(currentDir, dir.name);
            dir.url = changeQueryParams(req.originalUrl, {dir: targetUrl});
            dir.path = pathUtils.join(path, dir.name);
            return dir;
        });

        res.locals.files = {
            files,
            directories,
            path
        };

        next();
    }).catch(err => {
        next(err);
    });
};

const getScopeDirs = (req, res, scope) => {
    return api(req).get('/' + scope + '/', {
        qs: {
            $or: [
                {userIds: res.locals.currentUser._id},
                {teacherIds: res.locals.currentUser._id}
            ]
        }
    }).then(records => {
        return records.data.map(record => {
            return Object.assign(record, {
                url: '/files/' + scope + '/' + record._id
            });
        });
    });
};

/**
 * register a new filePermission for the given user for the given file
 * @param userId {String} - the user which should be granted permission
 * @param filePath {String} - the file for which a new permission should be created
 */
const registerSharedPermission = (userId, filePath, req) => {
    // check whether a filePermission entry already exist for the given file
    return api(req).get('/filePermissions/', {qs: {key: filePath}}).then(res => {
        if (res.data.length <= 0) {
            // owner permits sharing of given file
            return Promise.reject("Zu dieser Datei haben Sie keinen Zugriff!");
        } else {
            let filePermission = res.data[0];
            filePermission.permissions.push({
                userId: userId,
                permissions: ['can-read', 'can-write'] // todo: make it selectable
            });
            return api(req).patch('/filePermissions/' + res.data[0]._id, {json: filePermission});
        }
    });
};

// secure routes
router.use(authHelper.authChecker);

const getSignedUrl = function (req, res, next) {
    let {type, path, action = 'putObject'} = req.body;
    path = path || req.query.path;
    const filename = (req.file || {}).originalname;
    if(filename) path = path + '/' + filename;

    const data = {
        path,
        fileType: (type || 'application/octet-stream'),
        action: action
    };

    return requestSignedUrl(req, data).then(signedUrl => {
       if(res) res.json({signedUrl, path});
        else return Promise.resolve({signedUrl, path});
    }).catch(err => {
        if(res) res.status((err.statusCode || 500)).send(err);
        else return Promise.reject(err);
    });
};

// get signed url to upload file
router.post('/file', getSignedUrl);

// upload file directly
router.post('/upload', upload.single('upload'), function (req, res, next) {
    let _path;
    return getSignedUrl(req, null, next).then(({signedUrl, path}) => {
        _path = path;
        return rp.put({
            url: signedUrl.url,
            headers: Object.assign({}, signedUrl.header, {
                'content-type': req.file.mimetype
            }),
            body: req.file.buffer
        });
    }).then(_ => {
        res.json({
            "uploaded": 1,
            "fileName": req.file.originalname,
            "url": "/files/file?path=" + _path
        });
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// delete file
router.delete('/file', function (req, res, next) {
    const {name, dir = ''} = req.body;
    const data = {
        path: dir + name,
        fileType: null,
        action: null
    };

    api(req).delete('/fileStorage/', {
        qs: data
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// get file
router.get('/file', function (req, res, next) {

    const {file, download = false, path, shared = false} = req.query;
    const data = {
        path: path || file,
        fileType: mime.lookup(file || pathUtils.basename(path)),
        action: 'getObject'
    };

    let sharedPromise = shared ? registerSharedPermission(res.locals.currentUser._id, data.path, req) : Promise.resolve();
    sharedPromise.then(_ => {
        return requestSignedUrl(req, data).then(signedUrl => {
            return rp.get(signedUrl.url, {encoding: null}).then(awsFile => {
                if (download) {
                    res.type('application/octet-stream');
                    res.set('Content-Disposition', 'attachment;filename=' + pathUtils.basename(file));
                } else if (signedUrl.header['Content-Type']) {
                    res.type(signedUrl.header['Content-Type']);
                }

                res.end(awsFile, 'binary');
            });
        });
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// create directory
router.post('/directory', function (req, res, next) {
    const {name, dir} = req.body;

    const basePath = dir;
    const dirName = name || 'Neuer Ordner';
    api(req).post('/fileStorage/directories', {
        json: {
            path: basePath + "/" + dirName,
        }
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// delete directory
router.delete('/directory', function (req, res) {
    const data = {
        path: req.body.dir
    };

    api(req).delete('/fileStorage/directories/', {
        qs: data
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

router.get('/', FileGetter, function (req, res, next) {
    let files = res.locals.files.files;
    files.map(file => {
       let ending = file.name.split('.').pop();
       file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
    });
    res.render('files/files', Object.assign({
        title: 'Dateien',
        path: res.locals.files.path,
        breadcrumbs: getBreadcrumbs(req, {
            baseLabel: 'Meine persönlichen Dateien'
        }),
        canUploadFile: true,
        canCreateDir: true,
        inline: req.query.inline || req.query.CKEditor,
        CKEditor: req.query.CKEditor
    }, res.locals.files));
});

router.get('/courses/', function (req, res, next) {
    const basePath = '/files/courses/';
    getScopeDirs(req, res, 'courses').then(directories => {
        const breadcrumbs = getBreadcrumbs(req, {basePath});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Fächern und Kursen',
            url: changeQueryParams(req.originalUrl, {dir: ''}, '/files/courses/')
        });

        res.render('files/files', {
            title: 'Dateien',
            path: getStorageContext(req, res),
            breadcrumbs,
            files: [],
            directories
        });
    });
});

router.get('/courses/:courseId', FileGetter, function (req, res, next) {
    const basePath = '/files/courses/';
    api(req).get('/courses/' + req.params.courseId).then(record => {
        let files = res.locals.files.files;
        files.map(file => {
            let ending = file.name.split('.').pop();
            file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
        });

        const breadcrumbs = getBreadcrumbs(req, {basePath: basePath + record._id});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Fächern und Kursen',
            url: req.query.CKEditor ? '#' : changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        }, {
            label: record.name,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath + record._id)
        });

        res.render('files/files', Object.assign({
            title: 'Dateien',
            canUploadFile: true,
            canCreateDir: true,
            path: res.locals.files.path,
            inline: req.query.inline || req.query.CKEditor,
            CKEditor: req.query.CKEditor,
            breadcrumbs,
            courseId: req.params.courseId,
            courseUrl: `/courses/${req.params.courseId}/`
        }, res.locals.files));

    });
});

router.get('/classes/', function (req, res, next) {
    getScopeDirs(req, res, 'classes').then(directories => {
        const breadcrumbs = getBreadcrumbs(req);

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Klassen',
            url: changeQueryParams(req.originalUrl, {dir: ''}, '/files/classes/')
        });

        res.render('files/files', {
            title: 'Dateien',
            path: getStorageContext(req, res),
            breadcrumbs,
            files: [],
            directories
        });
    });
});

router.get('/classes/:classId', FileGetter, function (req, res, next) {
    const basePath = '/files/classes/';
    api(req).get('/classes/' + req.params.classId).then(record => {
        let files = res.locals.files.files;
        files.map(file => {
            let ending = file.name.split('.').pop();
            file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
        });

        const breadcrumbs = getBreadcrumbs(req, {basePath});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Klassen',
            url: req.query.CKEditor ? '#' : changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        }, {
            label: record.name,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath + record._id)
        });

        res.render('files/files', Object.assign({
            title: 'Dateien',
            path: res.locals.files.path,
            canUploadFile: true,
            breadcrumbs,
            inline: req.query.inline || req.query.CKEditor,
            CKEditor: req.query.CKEditor,
        }, res.locals.files));

    });
});

router.post('/permissions/', function (req, res, next) {
    // todo: refactoring sharing!
    api(req).get('/files/', { qs: {key: req.body.key} }).then(filePermission => {
        if (filePermission.data.length > 0) {
            res.json(filePermission.data[0]);
        } else {
            api(req).post("/files/", { json: req.body }).then(filePermission => {
                res.json(filePermission);
            });
        }
    });
});

/**** File and Directory proxy models ****/
router.post('/fileModel', function (req, res, next) {
    api(req).post('/files/', { json: req.body }).then(file => res.json(file)).catch(err => next(err));
});

module.exports = router;
<commit_msg>fix for creating directories<commit_after>/*
 * One Controller per layout view
 */

const fs = require('fs');
const pathUtils = require('path').posix;
const url = require('url');
const mime = require('mime');
const api = require('../api');
const rp = require('request-promise');
const express = require('express');
const router = express.Router();
const authHelper = require('../helpers/authentication');
const multer  = require('multer');
const upload = multer({ storage: multer.memoryStorage() });

const thumbs = {
    default: "/images/thumbs/default.png",
    psd: "/images/thumbs/psds.png",
    txt: "/images/thumbs/txts.png",
    doc: "/images/thumbs/docs.png",
    png: "/images/thumbs/pngs.png",
    mp4: "/images/thumbs/mp4s.png",
    mp3: "/images/thumbs/mp3s.png",
    aac: "/images/thumbs/aacs.png",
    avi: "/images/thumbs/avis.png",
    gif: "/images/thumbs/gifs.png",
    html: "/images/thumbs/htmls.png",
    js: "/images/thumbs/jss.png",
    mov: "/images/thumbs/movs.png",
    xls: "/images/thumbs/xlss.png",
    xlsx: "/images/thumbs/xlss.png",
    pdf: "/images/thumbs/pdfs.png",
    flac: "/images/thumbs/flacs.png",
    jpg: "/images/thumbs/jpgs.png",
    jpeg: "/images/thumbs/jpgs.png",
    docx: "/images/thumbs/docs.png",
    ai: "/images/thumbs/ais.png",
    tiff: "/images/thumbs/tiffs.png"
};

const requestSignedUrl = (req, data) => {
    return api(req).post('/fileStorage/signedUrl', {
        json: data
    });
};

const changeQueryParams = (originalUrl, params = {}, pathname = '') => {
    const urlParts = url.parse(originalUrl, true);

    Object.keys(params).forEach(param => {
        urlParts.query[param] = params[param];
    });

    if(pathname) {
        urlParts.pathname = pathname;
    }

    delete urlParts.search;
    return url.format(urlParts);
};

const getBreadcrumbs = (req, {dir = '', baseLabel = '', basePath = '/files/'} = {}) => {
    let dirParts = '';
    const currentDir = dir || req.query.dir || '';
    let pathComponents = currentDir.split('/') || [];
    if(pathComponents[0] === 'users' || pathComponents[0] === 'courses' || pathComponents[0] === 'classes') pathComponents = pathComponents.slice(2);   // remove context and ID, if present
    const breadcrumbs = pathComponents.filter(value => value).map(dirPart => {
        dirParts += '/' + dirPart;
        return {
            label: dirPart,
            url: changeQueryParams(req.originalUrl, {dir: dirParts}, basePath)
        };
    });

    if (baseLabel) {
        breadcrumbs.unshift({
            label: baseLabel,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        });
    }

    return breadcrumbs;
};

const getStorageContext = (req, res, options = {}) => {

    if (req.query.storageContext) {
        return pathUtils.normalize(req.query.storageContext + '/');
    }

    let currentDir = options.dir || req.query.dir || '/';
    const urlParts = url.parse((options.url || req.originalUrl), true);

    let storageContext = urlParts.pathname.replace('/files/', '/');

    if (storageContext === '/') {
        storageContext = 'users/' + res.locals.currentUser._id + '/';
    }

    if(currentDir.slice(-1) != '/') currentDir = currentDir + '/';
    return pathUtils.join(storageContext, currentDir);
};

const FileGetter = (req, res, next) => {
    let path = getStorageContext(req, res);
    let pathComponents = path.split('/');
    if(pathComponents[0] === '') pathComponents = pathComponents.slice(1); // remove leading slash, if present
    const currentDir = pathComponents.slice(2).join('/') || '/';

    path = pathComponents.join('/');

    return api(req).get('/fileStorage', {
        qs: {path}
    }).then(data => {
        let {files, directories} = data;

        files = files.map(file => {
            file.file = pathUtils.join(file.path, file.name);
            return file;
        });

        directories = directories.map(dir => {
            const targetUrl = pathUtils.join(currentDir, dir.name);
            dir.url = changeQueryParams(req.originalUrl, {dir: targetUrl});
            dir.path = pathUtils.join(path, dir.name);
            return dir;
        });

        res.locals.files = {
            files,
            directories,
            path
        };

        next();
    }).catch(err => {
        next(err);
    });
};

const getScopeDirs = (req, res, scope) => {
    return api(req).get('/' + scope + '/', {
        qs: {
            $or: [
                {userIds: res.locals.currentUser._id},
                {teacherIds: res.locals.currentUser._id}
            ]
        }
    }).then(records => {
        return records.data.map(record => {
            return Object.assign(record, {
                url: '/files/' + scope + '/' + record._id
            });
        });
    });
};

/**
 * register a new filePermission for the given user for the given file
 * @param userId {String} - the user which should be granted permission
 * @param filePath {String} - the file for which a new permission should be created
 */
const registerSharedPermission = (userId, filePath, req) => {
    // check whether a filePermission entry already exist for the given file
    return api(req).get('/filePermissions/', {qs: {key: filePath}}).then(res => {
        if (res.data.length <= 0) {
            // owner permits sharing of given file
            return Promise.reject("Zu dieser Datei haben Sie keinen Zugriff!");
        } else {
            let filePermission = res.data[0];
            filePermission.permissions.push({
                userId: userId,
                permissions: ['can-read', 'can-write'] // todo: make it selectable
            });
            return api(req).patch('/filePermissions/' + res.data[0]._id, {json: filePermission});
        }
    });
};

// secure routes
router.use(authHelper.authChecker);

const getSignedUrl = function (req, res, next) {
    let {type, path, action = 'putObject'} = req.body;
    path = path || req.query.path;
    const filename = (req.file || {}).originalname;
    if(filename) path = path + '/' + filename;

    const data = {
        path,
        fileType: (type || 'application/octet-stream'),
        action: action
    };

    return requestSignedUrl(req, data).then(signedUrl => {
       if(res) res.json({signedUrl, path});
        else return Promise.resolve({signedUrl, path});
    }).catch(err => {
        if(res) res.status((err.statusCode || 500)).send(err);
        else return Promise.reject(err);
    });
};

// get signed url to upload file
router.post('/file', getSignedUrl);

// upload file directly
router.post('/upload', upload.single('upload'), function (req, res, next) {
    let _path;
    return getSignedUrl(req, null, next).then(({signedUrl, path}) => {
        _path = path;
        return rp.put({
            url: signedUrl.url,
            headers: Object.assign({}, signedUrl.header, {
                'content-type': req.file.mimetype
            }),
            body: req.file.buffer
        });
    }).then(_ => {
        res.json({
            "uploaded": 1,
            "fileName": req.file.originalname,
            "url": "/files/file?path=" + _path
        });
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// delete file
router.delete('/file', function (req, res, next) {
    const {name, dir = ''} = req.body;
    const data = {
        path: dir + name,
        fileType: null,
        action: null
    };

    api(req).delete('/fileStorage/', {
        qs: data
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// get file
router.get('/file', function (req, res, next) {

    const {file, download = false, path, shared = false} = req.query;
    const data = {
        path: path || file,
        fileType: mime.lookup(file || pathUtils.basename(path)),
        action: 'getObject'
    };

    let sharedPromise = shared ? registerSharedPermission(res.locals.currentUser._id, data.path, req) : Promise.resolve();
    sharedPromise.then(_ => {
        return requestSignedUrl(req, data).then(signedUrl => {
            return rp.get(signedUrl.url, {encoding: null}).then(awsFile => {
                if (download) {
                    res.type('application/octet-stream');
                    res.set('Content-Disposition', 'attachment;filename=' + pathUtils.basename(file));
                } else if (signedUrl.header['Content-Type']) {
                    res.type(signedUrl.header['Content-Type']);
                }

                res.end(awsFile, 'binary');
            });
        });
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// create directory
router.post('/directory', function (req, res, next) {
    const {name, dir} = req.body;

    const basePath = dir;
    const dirName = name || 'Neuer Ordner';
    api(req).post('/fileStorage/directories', {
        json: {
            path: basePath + dirName,
        }
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

// delete directory
router.delete('/directory', function (req, res) {
    const data = {
        path: req.body.dir
    };

    api(req).delete('/fileStorage/directories/', {
        qs: data
    }).then(_ => {
        res.sendStatus(200);
    }).catch(err => {
        res.status((err.statusCode || 500)).send(err);
    });
});

router.get('/', FileGetter, function (req, res, next) {
    let files = res.locals.files.files;
    files.map(file => {
       let ending = file.name.split('.').pop();
       file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
    });
    res.render('files/files', Object.assign({
        title: 'Dateien',
        path: res.locals.files.path,
        breadcrumbs: getBreadcrumbs(req, {
            baseLabel: 'Meine persönlichen Dateien'
        }),
        canUploadFile: true,
        canCreateDir: true,
        inline: req.query.inline || req.query.CKEditor,
        CKEditor: req.query.CKEditor
    }, res.locals.files));
});

router.get('/courses/', function (req, res, next) {
    const basePath = '/files/courses/';
    getScopeDirs(req, res, 'courses').then(directories => {
        const breadcrumbs = getBreadcrumbs(req, {basePath});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Fächern und Kursen',
            url: changeQueryParams(req.originalUrl, {dir: ''}, '/files/courses/')
        });

        res.render('files/files', {
            title: 'Dateien',
            path: getStorageContext(req, res),
            breadcrumbs,
            files: [],
            directories
        });
    });
});

router.get('/courses/:courseId', FileGetter, function (req, res, next) {
    const basePath = '/files/courses/';
    api(req).get('/courses/' + req.params.courseId).then(record => {
        let files = res.locals.files.files;
        files.map(file => {
            let ending = file.name.split('.').pop();
            file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
        });

        const breadcrumbs = getBreadcrumbs(req, {basePath: basePath + record._id});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Fächern und Kursen',
            url: req.query.CKEditor ? '#' : changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        }, {
            label: record.name,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath + record._id)
        });

        res.render('files/files', Object.assign({
            title: 'Dateien',
            canUploadFile: true,
            canCreateDir: true,
            path: res.locals.files.path,
            inline: req.query.inline || req.query.CKEditor,
            CKEditor: req.query.CKEditor,
            breadcrumbs,
            courseId: req.params.courseId,
            courseUrl: `/courses/${req.params.courseId}/`
        }, res.locals.files));

    });
});

router.get('/classes/', function (req, res, next) {
    getScopeDirs(req, res, 'classes').then(directories => {
        const breadcrumbs = getBreadcrumbs(req);

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Klassen',
            url: changeQueryParams(req.originalUrl, {dir: ''}, '/files/classes/')
        });

        res.render('files/files', {
            title: 'Dateien',
            path: getStorageContext(req, res),
            breadcrumbs,
            files: [],
            directories
        });
    });
});

router.get('/classes/:classId', FileGetter, function (req, res, next) {
    const basePath = '/files/classes/';
    api(req).get('/classes/' + req.params.classId).then(record => {
        let files = res.locals.files.files;
        files.map(file => {
            let ending = file.name.split('.').pop();
            file.thumbnail = thumbs[ending] ? thumbs[ending] : thumbs['default'];
        });

        const breadcrumbs = getBreadcrumbs(req, {basePath});

        breadcrumbs.unshift({
            label: 'Dateien aus meinen Klassen',
            url: req.query.CKEditor ? '#' : changeQueryParams(req.originalUrl, {dir: ''}, basePath)
        }, {
            label: record.name,
            url: changeQueryParams(req.originalUrl, {dir: ''}, basePath + record._id)
        });

        res.render('files/files', Object.assign({
            title: 'Dateien',
            path: res.locals.files.path,
            canUploadFile: true,
            breadcrumbs,
            inline: req.query.inline || req.query.CKEditor,
            CKEditor: req.query.CKEditor,
        }, res.locals.files));

    });
});

router.post('/permissions/', function (req, res, next) {
    // todo: refactoring sharing!
    api(req).get('/files/', { qs: {key: req.body.key} }).then(filePermission => {
        if (filePermission.data.length > 0) {
            res.json(filePermission.data[0]);
        } else {
            api(req).post("/files/", { json: req.body }).then(filePermission => {
                res.json(filePermission);
            });
        }
    });
});

/**** File and Directory proxy models ****/
router.post('/fileModel', function (req, res, next) {
    api(req).post('/files/', { json: req.body }).then(file => res.json(file)).catch(err => next(err));
});

module.exports = router;
<|endoftext|>


<commit_before>$.register({
  rule: {
    host: /^(?:(\w+)\.)?(coinurl\.com|cur\.lv)$/,
    path: /^\/([-\w]+)$/
  },
  ready: function (m) {
    'use strict';

    $.removeNodes('iframe');

    var host = 'http://cur.lv/redirect_curlv.php';
    var param = m.host[1] === undefined ? {
      code: m.path[1],
    } : {
      zone: m.host[1],
      name: m.path[1],
    };

    // Retrieve the main frame
    $.get(host, param).then(function(mainFrameContent) {
      try {
        // Convert it to HTML nodes
        var docMainFrame = $.toDOM(mainFrameContent);
      } catch (e) {
        throw new _.AdsBypasserError('main frame changed');
      }

      // Regex allowing to extract the link from a subframe
      var rExtractLink = /onclick="open_url\('([^']+)',\s*'go'\)/;

      // Iterate each frame
      var innerFrames = $.$$('frameset > frame', docMainFrame).each(function (currFrame) {
        // Fix the host of the frame
        // NOTE Webkit does not strictly follow HTMLElement spec, can not use HTMLFrameElement.src
        var currFrameAddr = window.location.origin + '/' + currFrame.getAttribute('src');

        // Get the content of the current frame
        $.get(currFrameAddr).then(function(currFrameContent) {
          // Try to find the link in the current frame
          var aRealLink = rExtractLink.exec(currFrameContent);

          // Could not find it? Try to find it in the next frame
          if (aRealLink === undefined || aRealLink[1] === undefined) {
            return;
          }

          // Otherwise redirect to the link
          var realLink = aRealLink[1];
          $.openLink(realLink);
        });
      });
    });
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>cur.lv<commit_after>$.register({
  rule: {
    host: /^(?:(\w+)\.)?(coinurl\.com|cur\.lv)$/,
    path: /^\/([-\w]+)$/
  },
  ready: function (m) {
    'use strict';

    $.removeNodes('iframe');

    var host = 'http://cur.lv/redirect_curlv.php';
    var param = m.host[1] === undefined ? {
      code: m.path[1],
    } : {
      zone: m.host[1],
      name: m.path[1],
    };

    // Retrieve the main frame
    $.get(host, param).then(function(mainFrameContent) {
      try {
        // Convert it to HTML nodes
        var docMainFrame = $.toDOM(mainFrameContent);
      } catch (e) {
        throw new _.AdsBypasserError('main frame changed');
      }

      // Regex allowing to extract the link from a subframe
      var rExtractLink = /onclick="open_url\('([^']+)',\s*'go'\)/;

      // Iterate each frame
      var innerFrames = $.$$('iframe', docMainFrame).each(function (currFrame) {
        // Fix the host of the frame
        // NOTE Webkit does not strictly follow HTMLElement spec, can not use HTMLFrameElement.src
        var currFrameAddr = currFrame.getAttribute('src');

        // Get the content of the current frame
        $.get(currFrameAddr).then(function(currFrameContent) {
          // Try to find the link in the current frame
          var aRealLink = rExtractLink.exec(currFrameContent);

          // Could not find it? Try to find it in the next frame
          if (aRealLink === undefined || aRealLink[1] === undefined) {
            return;
          }

          // Otherwise redirect to the link
          var realLink = aRealLink[1];
          $.openLink(realLink);
        });
      });
    });
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>


<commit_before>var twilio = require('twilio'),
    controllers = {
        twilio: require('./twilio'),
        home: require('./home'),
        admin: require('./admin')
    };

module.exports = function(app) {
    // Routes used as webhooks by Twilio should all be secured by checking the
    // Twilio request signature - we can do this by using Express middleware
    // Provided by the Twilio module
    var webhook = twilio.webhook({
        // Only validate requests in production
        validate: process.env.NODE_ENV === 'production',

        // Manually configure the host and protocol used for webhook config
        host:'leavejoeamessage.herokuapp.com',
        protocol:'https'
    });

    // Twilio webhooks
    app.post('/voice', webhook, controllers.twilio.voice);
    app.post('/recording', webhook, controllers.twilio.recording);
    app.post('/sms', webhook, controllers.twilio.sms);

    // Home page and associated ajax endpoints
    // Render a public home page which displays the latest messages
    app.get('/', controllers.home.index);
    app.get('/messages', controllers.home.list);

};<commit_msg>temporarily change request signing URL<commit_after>var twilio = require('twilio'),
    controllers = {
        twilio: require('./twilio'),
        home: require('./home'),
        admin: require('./admin')
    };

module.exports = function(app) {
    // Routes used as webhooks by Twilio should all be secured by checking the
    // Twilio request signature - we can do this by using Express middleware
    // Provided by the Twilio module
    var webhook = twilio.webhook({
        // Only validate requests in production
        validate: process.env.NODE_ENV === 'production',

        // Manually configure the host and protocol used for webhook config
        host:'rev-answering-machine.herokuapp.com',
        protocol:'https'
    });

    // Twilio webhooks
    app.post('/voice', webhook, controllers.twilio.voice);
    app.post('/recording', webhook, controllers.twilio.recording);
    app.post('/sms', webhook, controllers.twilio.sms);

    // Home page and associated ajax endpoints
    // Render a public home page which displays the latest messages
    app.get('/', controllers.home.index);
    app.get('/messages', controllers.home.list);

};<|endoftext|>


<commit_before>/**
 * 路由
 */
var utils = require('../utils');
var simi = require('../services/simi');
var task = require('../services/later');

exports.home = function* () {
  this.body = 'hello world';
  this.status = 200;
};

exports.handle = function* () {
  var content = this.request.body;
  console.log(content)
  var trigger_word = content.trigger_word;
  var text = content.text;
  if (text.indexOf('!') === 0) {
    return this.body = {};
  }
  if (trigger_word === 'test') {
    yield utils.getImg('http://finance.sina.com.cn/stock/','test2', '#wmt_contents', 'iphone 5s');
    this.body = {
      text: 'http://i.imgur.com/JQ8GA1p.jpg',
      "attachments": [
        {
          "fallback": "Network traffic (kb/s): How does this look? @slack-ops - Sent by Julie Dodd - https://datadog.com/path/to/event",
          "title": "Network traffic (kb/s)",
          "title_link": "https://datadog.com/path/to/event",
          "text": "How does this look? @slack-ops - Sent by Julie Dodd",
          "image_url": "http://i.imgur.com/JQ8GA1p.jpg",
          "color": "#764FA5"
        }
      ]
    };
  }
  if (text) {
    var reply = (yield simi.chat(text)) || '呵呵';
    console.log(reply)
    return this.body = {
      "attachments": [
        {
          "text": '!' + reply
        }
      ]
    };
  }
};<commit_msg>add send message task<commit_after>/**
 * 路由
 */
var utils = require('../utils');
var simi = require('../services/simi');
var task = require('../services/later');

exports.home = function* () {
  this.body = 'hello world';
  this.status = 200;
};

exports.handle = function* () {
  var content = this.request.body;
  console.log(content)
  var trigger_word = content.trigger_word;
  var text = content.text;
  if (text.indexOf('!') === 0) {
    return this.body = {};
  }
  if (trigger_word === 'test') {
    yield utils.getImg('http://finance.sina.com.cn/stock/','test2', '#wmt_contents', 'iphone 5s');
    this.body = {
      text: 'http://i.imgur.com/JQ8GA1p.jpg',
      "attachments": [
        {
          "fallback": "Network traffic (kb/s): How does this look? @slack-ops - Sent by Julie Dodd - https://datadog.com/path/to/event",
          "title": "Network traffic (kb/s)",
          "title_link": "https://datadog.com/path/to/event",
          "text": "How does this look? @slack-ops - Sent by Julie Dodd",
          "image_url": "http://i.imgur.com/JQ8GA1p.jpg",
          "color": "#764FA5"
        }
      ]
    };
  }
  if (text) {
    var reply = (yield simi.chat(text)) || '呵呵';
    console.log(reply)
    return this.body = {
      "attachments": [
        {
          "text": "!" + reply,
          "color": "good"
        }
      ]
    };
  }
};<|endoftext|>


<commit_before>// const {Translate} = require('@google-cloud/translate').v2;
// const translate = new Translate({projectId: process.env.GOOGLE_PROJECT_ID});
const {auth} = require('google-auth-library');
const keysEnvVar = process.env['CREDS'];
if (!keysEnvVar) {
  throw new Error('The $CREDS environment variable was not found!');
}
const authKeys = JSON.parse(keysEnvVar);
const client = auth.fromJSON(authKeys);
client.scopes = ['https://www.googleapis.com/auth/cloud-platform'];

async function translateText(data, targetLanguage) {
  // The text to translate
  const text = data;

  // The target language
  const target = targetLanguage;

  const url = `https://translation.googleapis.com/language/translate/v2?key=${process.env.GOOGLE_MAPS_API_KEY}&target=${target}&q=${text}`;
  const res = await client.request({url});
  console.log(res.data.data.translations);
}

translateText('Hello World. This is a translation test.', 'th').catch(console.error);<commit_msg>refactor test script<commit_after>// const {Translate} = require('@google-cloud/translate').v2;
// const translate = new Translate({projectId: process.env.GOOGLE_PROJECT_ID});
const {auth} = require('google-auth-library');
const keysEnvVar = process.env['CREDS'];
if (!keysEnvVar) {
  throw new Error('The $CREDS environment variable was not found!');
}
const authKeys = JSON.parse(keysEnvVar);
const client = auth.fromJSON(authKeys);
client.scopes = ['https://www.googleapis.com/auth/cloud-platform'];

async function translateText(data, targetLanguage) {
  // The text to translate
  const text = data;

  // The target language
  const target = targetLanguage;

  const url = `https://translation.googleapis.com/language/translate/v2?key=${process.env.GOOGLE_MAPS_API_KEY}&target=${target}&q=${text}`;
  const res = await client.request({url});

  if (res.data.data.translations.length > 0) {
    return res.data.data.translations[0].translatedText;
  }
  return null;
}

async function testTranslate() {
  const newtext = await translateText('Hello World. This is a translation test.', 'th');
  console.log(newtext);
}

testTranslate();<|endoftext|>


<commit_before>/* this route creates tasks for our customers */
const taskrouterHelper = require('./helpers/taskrouter-helper.js');
const chatHelper = require('./helpers/chat-helper.js');
const videoHelper = require('./helpers/video-helper.js');

module.exports.createCallback = function (req, res) {
  taskrouterHelper
    .createTask(req.configuration.twilio.workflowSid, req.body)
    .then((task) => {
      res.status(200).end();
    })
    .catch((error) => {
      res.status(500).send(res.convertErrorToJSON(error));
    });
};

module.exports.createChat = function (req, res) {
  const friendlyName = 'Support Chat with ' + req.body.identity;
  const uniqueName = `chat_room_${Math.random().toString(36).substring(7)}`;

  let payload = {
    identity: req.body.identity,
    token: chatHelper.createAccessToken(req.body.identity, req.body.endpoint).toJwt()
  };

  chatHelper
    .createChannel(friendlyName, uniqueName)
    .then((channel) => {
      payload.chat = {
        sid: channel.sid,
        friendlyName: channel.friendlyName,
        uniqueName: channel.uniqueName
      };

      const attributes = {
        title: 'Chat request',
        text: 'Customer entered chat via support page',
        channel: 'chat',
        name: payload.identity,
        channelSid: channel.sid
      };

      return taskrouterHelper
        .createTask(req.configuration.twilio.workflowSid, attributes)
        .then((task) => {
          payload.task = task.sid;
          res.status(200).json(payload);
        });
    })
    .catch((error) => {
      res.status(500).json(error);
    });
};

module.exports.createVideo = function (req, res) {
  const uid = Math.random().toString(36).substring(7);

  let payload = {
    identity: req.body.identity,
    token: videoHelper.createAccessToken(req.body.identity, uid).toJwt(),
    video: {
      name: uid
    }
  };

  const attributes = {
    title: 'Video request',
    text: 'Customer requested video support on web page',
    channel: 'video',
    name: payload.identity,
    roomName: payload.video.name
  };

  taskrouterHelper
    .createTask(req.configuration.twilio.workflowSid, attributes)
    .then((task) => {
      payload.task = task.sid;
      res.status(200).json(payload);
    })
    .catch((error) => {
      res.status(500).send(res.convertErrorToJSON(error));
    });
};
<commit_msg>fixed task attributes<commit_after>/* this route creates tasks for our customers */
const taskrouterHelper = require('./helpers/taskrouter-helper.js');
const chatHelper = require('./helpers/chat-helper.js');
const videoHelper = require('./helpers/video-helper.js');

module.exports.createCallback = function (req, res) {
  taskrouterHelper
    .createTask(req.configuration.twilio.workflowSid, req.body)
    .then((task) => {
      res.status(200).end();
    })
    .catch((error) => {
      res.status(500).send(res.convertErrorToJSON(error));
    });
};

module.exports.createChat = function (req, res) {
  const friendlyName = 'Support Chat with ' + req.body.identity;
  const uniqueName = `chat_room_${Math.random().toString(36).substring(7)}`;

  let payload = {
    identity: req.body.identity,
    token: chatHelper.createAccessToken(req.body.identity, req.body.endpoint).toJwt()
  };

  chatHelper
    .createChannel(friendlyName, uniqueName)
    .then((channel) => {
      payload.chat = {
        sid: channel.sid,
        friendlyName: channel.friendlyName,
        uniqueName: channel.uniqueName
      };

      const attributes = {
        title: 'Chat request',
        text: 'Customer entered chat via support page',
        channel: 'chat',
        name: payload.identity,
        chat: {
          sid: channel.sid
        }
      };

      return taskrouterHelper
        .createTask(req.configuration.twilio.workflowSid, attributes)
        .then((task) => {
          payload.task = task.sid;
          res.status(200).json(payload);
        });
    })
    .catch((error) => {
      res.status(500).json(error);
    });
};

module.exports.createVideo = function (req, res) {
  const uid = Math.random().toString(36).substring(7);

  let payload = {
    identity: req.body.identity,
    token: videoHelper.createAccessToken(req.body.identity, uid).toJwt(),
    video: {
      name: uid
    }
  };

  const attributes = {
    title: 'Video request',
    text: 'Customer requested video support on web page',
    channel: 'video',
    name: payload.identity,
    video: {
      roomName: uid
    }
  };

  taskrouterHelper
    .createTask(req.configuration.twilio.workflowSid, attributes)
    .then((task) => {
      payload.task = task.sid;
      res.status(200).json(payload);
    })
    .catch((error) => {
      res.status(500).send(res.convertErrorToJSON(error));
    });
};
<|endoftext|>


<commit_before>var User = require('../models/user.js');
var Task = require('../models/task.js');
var Team = require('../models/team.js');

var request = require('request');

function createTask (req, res) {
  // Team.findById(req.body.team_id, function (err, team) {

    if (!req.body.lon) {
      req.body.lat = "51.5286416"
      req.body.lon = "-0.1015987"
    }
    if (!req.body.task.location) {
      var query = "London";
    } else {
      var query = req.body.task.location.name
    }

    request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
     if (!error && response.statusCode == 200) {
      var resp = JSON.parse(body)

      Task.create(req.body.task, function (er, task) {
       if (er) res.status(403).send({ message: "Could not create task, error occurred"});

       var d = new Date();
       task.start_time = d;
       var addedMinutes = d.getMinutes() + task.minutes;

       var then = new Date();
       then.setMinutes(then.getMinutes() + 30);
       task.end_time =  then;

       if (resp.results[0]) {
         task.location.lat = resp.results[0].geometry.location.lat
         task.location.lon = resp.results[0].geometry.location.lng
       }

       task.save(function (err) {
        if (err) res.status(403).send({ message: "Could not save task"});
        res.send(task);
        // team.tasks.push(task);
        // team.save(function (error) {

        // })
     })

     });
    } })
// })
}

function reviewTaskCompletion (req, res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "could not find task"});
    if (req.body.completed)  {task.completed = true; }
    else { task.completed = false }
     task.updated_at = Date.now;
   task.save(function (err) {
    res.status(200).send(task);
  })
 })
}

function completeTask (req, res) {

  Task.findById(req.body.task._id, function (err, task) {
    if (err) res.status(403).send({ message: "Could not find task"});
    task.completion.message = req.body.task.completion.message;
    task.completion.img_url = req.body.task.completion.img_url;
    task.updated_at = Date.now;

    if (!req.body.lon) {
     req.body.lat = "51.5286416"
     req.body.lon = "-0.1015987"
   }

   if (!req.body.task.completion.location) {
    req.body.task.completion.location = {
      "name": null
    }
    var query = "London";
  } else {
   var query = req.body.task.completion.location.name
   task.completion.location.name = req.body.task.completion.location.name;
 }

 request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+ ','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
  if (!error && response.statusCode == 200) {
   var resp = JSON.parse(body);
   console.log(resp);

   var latlon = [resp.results[0].geometry.location.lat, resp.results[0].geometry.location.lng]
   task.completion.time_completed = Date.now;
   task.completion.location.lat = latlon[0];
   task.completion.location.lon = latlon[1];
   task.completed = false;
   task.save(function (err) {
    res.status(200).send(task);
  });
 }

})
});
}
function rejectTask (req, res) {

  Task.findById(req.params.id).populate('_creator').exec( function (err, task) {
    if (err) res.status(403).send({ message: "Could not find task"});
    task._tagged_member = null;
    task.updated_at = Date.now;
    task.save( function (error) {
      if (error) res.status(403).send({ message: "Could not save task."});
      res.status(200).send(task);
    })
  })
}

function pendingTasks (req, res) {
  console.log('in pending tasks');
  Task.find({ "_tagged_member": { $eq: req.body.userId }, "completed": { $ne : true } }).sort({ updated_at:-1}).populate('_creator').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: "Error in finding pending tasks"});
    res.send(tasks);
  });
}
function updateTask(req, res) {
  var update = req.body;
  Task.findByIdAndUpdate(req.params.id, update , function (err, task) {
    if(err) res.status(403).send({ message: "Error in finding task"});
    task.updated_at = Date.now;
    task.save(function (error) {
      if (error) res.status(403).send({ message: "Error saving task on update"})
        res.status(200).send(task);
    });
  })
}
function showTask (req, res) {
 Task.findById(req.params.id).populate('_creator').populate('_tagged_member').exec(function (err, task) {
   if (err) res.status(403).send({ message: "Error finding task"});
   res.send(task);
 });

}
function createdTasks (req,res) {
  Task.find( { "_creator": {$eq: req.body.userId } }).sort({ updated_at:-1}).populate('_tagged_member').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: "An error occured when looking for tasks"});
    res.status(200).send(tasks);
  })
}
function completedTasks (req,res) {
  Task.find({ "_tagged_member": { $eq: req.body.userId }, "completed": { $eq:  true } }).sort({ updated_at: -1 }).populate('_creator').exec(function (err,tasks) {
    if (err) res.status(403).send({ message: "An error occured when looking for tasks"});
    res.status(200).send(tasks);
  });
}
function acceptResponse (req,res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "An error occured when finding task to accept."});

    task.completed = true;
    task.updated_at = Date.now;

    task.save(function (error) {
      if (error) res.status(403).send({ message: "could not save task on accept response"});
      User.findById(task._tagged_member, function (er, user) {
          if (er) res.status(403).send({ message: "could not find user to add coin"});
          user.total_points++;

          user.save(function (erro) {
            if (erro) res.status(403).send({ message: "could not save user on coin update"});
            res.status(200).send(task);
          })
      })
    })
  })
}
function rejectResponse (req, res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "An error occured when finding task to reject."});

    task.completed = null;
    task.updated_at = Date.now;
    task.save(function (error) {
      res.status(200).send(task);
    });
  })
}
function indexTeamTasks (req,res) {
  Team.findById(req.body.team_id).sort({ updated_at:-1}).populate('tasks').populate('tasks._creator').populate('tasks._tagged_member').exec(function (err, team) {
    if (err) res.status(403).send({ message: 'Error occurred when finding tasks'});
    res.status(200).send(team.tasks);
  })
}

function indexPublicPendingTasks (req, res) {
  Task.find({ "completed": { $ne : true } }).populate('_tagged_member').populate('_creator').exec( function (err, tasks) {
    if (err) res.status(403).send({ message: 'Error occurred when finding tasks'});
    res.status(200).send(tasks);
  })
}
function copyTask (req,res) {
  console.log('inside controller function - copy task')
  Task.create(req.body.task, function (err, task) {
    console.log('in create copy task')
    if (err) res.status(403).send({ message: 'Error occurred when creating task'});
    // if (req.body.task.location) {
    //   if (!req.body.task.location.name) {
    //     var query = "London";
    //   } else {
    //     var query = req.body.task.location.name
    //   }
    //   request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
    //    if (!error && response.statusCode == 200) {
    //     var resp = JSON.parse(body);
    //     if (resp.results[0]) {
    //       task.location.lat = resp.results[0].geometry.location.lat;
    //       task.location.lon = resp.results[0].geometry.location.lng;
    //       task.save(function (error) {
    //         if(error) res.status(403).send({ message: "Could not save on location change"});
    //         res.send(task)
    //       });
    //     }
    //   } else {
    //     res.status(200).send(task);
    //   }
    // });

    // } else {
      res.status(200).send(task);

  });
}
function indexTasks (req,res) {
  Task.find({}).sort({ updated_at:-1}).populate('_creator').populate('_tagged_member').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: 'Error occurred in indexing tasks'});
    res.status(200).send(tasks);
  })
}
module.exports = {
  acceptResponse: acceptResponse,
  rejectResponse: rejectResponse,
  completedTasks: completedTasks,
  createdTasks: createdTasks,
  rejectTask: rejectTask,
  reviewTaskCompletion: reviewTaskCompletion,
  indexPublicPendingTasks: indexPublicPendingTasks,
  completeTask: completeTask,
  updateTask: updateTask,
  pendingTasks : pendingTasks,
  indexTasks : indexTasks,
  createTask : createTask,
  indexTeamTasks : indexTeamTasks,
  showTask : showTask,
  copyTask: copyTask
}<commit_msg>updated added coin to accept response<commit_after>var User = require('../models/user.js');
var Task = require('../models/task.js');
var Team = require('../models/team.js');

var request = require('request');

function createTask (req, res) {
  // Team.findById(req.body.team_id, function (err, team) {

    if (!req.body.lon) {
      req.body.lat = "51.5286416"
      req.body.lon = "-0.1015987"
    }
    if (!req.body.task.location) {
      var query = "London";
    } else {
      var query = req.body.task.location.name
    }

    request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
     if (!error && response.statusCode == 200) {
      var resp = JSON.parse(body)

      Task.create(req.body.task, function (er, task) {
       if (er) res.status(403).send({ message: "Could not create task, error occurred"});

       var d = new Date();
       task.start_time = d;
       var addedMinutes = d.getMinutes() + task.minutes;

       var then = new Date();
       then.setMinutes(then.getMinutes() + 30);
       task.end_time =  then;

       if (resp.results[0]) {
         task.location.lat = resp.results[0].geometry.location.lat
         task.location.lon = resp.results[0].geometry.location.lng
       }

       task.save(function (err) {
        if (err) res.status(403).send({ message: "Could not save task"});
        res.send(task);
        // team.tasks.push(task);
        // team.save(function (error) {

        // })
     })

     });
    } })
// })
}

function reviewTaskCompletion (req, res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "could not find task"});
    if (req.body.completed)  {task.completed = true; }
    else { task.completed = false }
     task.updated_at = Date.now;
   task.save(function (err) {
    res.status(200).send(task);
  })
 })
}

function completeTask (req, res) {

  Task.findById(req.body.task._id, function (err, task) {
    if (err) res.status(403).send({ message: "Could not find task"});
    task.completion.message = req.body.task.completion.message;
    task.completion.img_url = req.body.task.completion.img_url;
    task.updated_at = Date.now;

    if (!req.body.lon) {
     req.body.lat = "51.5286416"
     req.body.lon = "-0.1015987"
   }

   if (!req.body.task.completion.location) {
    req.body.task.completion.location = {
      "name": null
    }
    var query = "London";
  } else {
   var query = req.body.task.completion.location.name
   task.completion.location.name = req.body.task.completion.location.name;
 }

 request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+ ','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
  if (!error && response.statusCode == 200) {
   var resp = JSON.parse(body);
   console.log(resp);

   var latlon = [resp.results[0].geometry.location.lat, resp.results[0].geometry.location.lng]
   task.completion.time_completed = Date.now;
   task.completion.location.lat = latlon[0];
   task.completion.location.lon = latlon[1];
   task.completed = false;
   task.save(function (err) {
    res.status(200).send(task);
  });
 }

})
});
}
function rejectTask (req, res) {

  Task.findById(req.params.id).populate('_creator').exec( function (err, task) {
    if (err) res.status(403).send({ message: "Could not find task"});
    task._tagged_member = null;
    task.updated_at = Date.now;
    task.save( function (error) {
      if (error) res.status(403).send({ message: "Could not save task."});
      res.status(200).send(task);
    })
  })
}

function pendingTasks (req, res) {
  console.log('in pending tasks');
  Task.find({ "_tagged_member": { $eq: req.body.userId }, "completed": { $ne : true } }).sort({ updated_at:-1}).populate('_creator').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: "Error in finding pending tasks"});
    res.send(tasks);
  });
}
function updateTask(req, res) {
  var update = req.body;
  Task.findByIdAndUpdate(req.params.id, update , function (err, task) {
    if(err) res.status(403).send({ message: "Error in finding task"});
    task.updated_at = Date.now;
    task.save(function (error) {
      if (error) res.status(403).send({ message: "Error saving task on update"})
        res.status(200).send(task);
    });
  })
}
function showTask (req, res) {
 Task.findById(req.params.id).populate('_creator').populate('_tagged_member').exec(function (err, task) {
   if (err) res.status(403).send({ message: "Error finding task"});
   res.send(task);
 });

}
function createdTasks (req,res) {
  Task.find( { "_creator": {$eq: req.body.userId } }).sort({ updated_at:-1}).populate('_tagged_member').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: "An error occured when looking for tasks"});
    res.status(200).send(tasks);
  })
}
function completedTasks (req,res) {
  Task.find({ "_tagged_member": { $eq: req.body.userId }, "completed": { $eq:  true } }).sort({ updated_at: -1 }).populate('_creator').exec(function (err,tasks) {
    if (err) res.status(403).send({ message: "An error occured when looking for tasks"});
    res.status(200).send(tasks);
  });
}
function acceptResponse (req,res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "An error occured when finding task to accept."});

    task.completed = true;
    task.updated_at = Date.now;

    task.save(function (error) {
      if (error) res.status(403).send({ message: "could not save task on accept response"});
      User.findById(task._tagged_member, function (er, user) {
          if (er) res.status(403).send({ message: "could not find user to add coin"});
          user.total_coins++;

          user.save(function (erro) {
            if (erro) res.status(403).send({ message: "could not save user on coin update"});
            res.status(200).send(task);
          })
      })
    })
  })
}
function rejectResponse (req, res) {
  Task.findById(req.params.id, function (err, task) {
    if (err) res.status(403).send({ message: "An error occured when finding task to reject."});

    task.completed = null;
    task.updated_at = Date.now;
    task.save(function (error) {
      res.status(200).send(task);
    });
  })
}
function indexTeamTasks (req,res) {
  Team.findById(req.body.team_id).sort({ updated_at:-1}).populate('tasks').populate('tasks._creator').populate('tasks._tagged_member').exec(function (err, team) {
    if (err) res.status(403).send({ message: 'Error occurred when finding tasks'});
    res.status(200).send(team.tasks);
  })
}

function indexPublicPendingTasks (req, res) {
  Task.find({ "completed": { $ne : true } }).populate('_tagged_member').populate('_creator').exec( function (err, tasks) {
    if (err) res.status(403).send({ message: 'Error occurred when finding tasks'});
    res.status(200).send(tasks);
  })
}
function copyTask (req,res) {
  console.log('inside controller function - copy task')
  Task.create(req.body.task, function (err, task) {
    console.log('in create copy task')
    if (err) res.status(403).send({ message: 'Error occurred when creating task'});
    // if (req.body.task.location) {
    //   if (!req.body.task.location.name) {
    //     var query = "London";
    //   } else {
    //     var query = req.body.task.location.name
    //   }
    //   request('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location='+ req.body.lat+','+ req.body.lon+'&radius=5000&name='+ query + '&key='+ process.env.GOOGLE_API_KEY, function (error, response, body) {
    //    if (!error && response.statusCode == 200) {
    //     var resp = JSON.parse(body);
    //     if (resp.results[0]) {
    //       task.location.lat = resp.results[0].geometry.location.lat;
    //       task.location.lon = resp.results[0].geometry.location.lng;
    //       task.save(function (error) {
    //         if(error) res.status(403).send({ message: "Could not save on location change"});
    //         res.send(task)
    //       });
    //     }
    //   } else {
    //     res.status(200).send(task);
    //   }
    // });

    // } else {
      res.status(200).send(task);

  });
}
function indexTasks (req,res) {
  Task.find({}).sort({ updated_at:-1}).populate('_creator').populate('_tagged_member').exec(function (err, tasks) {
    if (err) res.status(403).send({ message: 'Error occurred in indexing tasks'});
    res.status(200).send(tasks);
  })
}
module.exports = {
  acceptResponse: acceptResponse,
  rejectResponse: rejectResponse,
  completedTasks: completedTasks,
  createdTasks: createdTasks,
  rejectTask: rejectTask,
  reviewTaskCompletion: reviewTaskCompletion,
  indexPublicPendingTasks: indexPublicPendingTasks,
  completeTask: completeTask,
  updateTask: updateTask,
  pendingTasks : pendingTasks,
  indexTasks : indexTasks,
  createTask : createTask,
  indexTeamTasks : indexTeamTasks,
  showTask : showTask,
  copyTask: copyTask
}<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////////
////// Users
////////////////////////////////////////////////////////////////////////////////////
'use strict';

// DI
var db,
	responseHandler;

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findAll = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	db.findAllUsers({'application_id': appid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findById = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.findUserById({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findBadgesById = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').isInt();
	req.check('userid', '"userid": must be a valid identifier').isInt();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.findUserBadgesByUserId({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.create = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('login', '"login": must be a valid string').notNull();
	req.check('firstname', '"firstname": must be a valid string').notNull();
	req.check('lastname', '"lastname": must be a valid string').notNull();
	req.check('email', '"email": must be a valid Email adress').isEmail();
	var errors = req.validationErrors(),
		appid,
		login,
		firstname,
		lastname,
		email;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	login = req.params.login;
	firstname = req.params.firstname;
	lastname = req.params.lastname;
	email = req.params.email;
	db.createUser(
		{'application_id': appid, 'login': login, 'firstname': firstname, 'lastname': lastname, 'email': email},
		responseHandler(res, next)
	);
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.update = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	req.check('login', '"login": must be a valid string').notNull();
	req.check('firstname', '"firstname": must be a valid string').notNull();
	req.check('lastname', '"lastname": must be a valid string').notNull();
	req.check('email', '"email": must be a valid Email adress').isEmail();
	var errors = req.validationErrors(),
		appid,
		userid,
		login,
		firstname,
		lastname,
		email;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	login = req.params.login;
	firstname = req.params.firstname;
	lastname = req.params.lastname;
	email = req.params.email;
	db.updateUser(
		{'application_id': appid, 'user_id': userid, 'login': login, 'firstname': firstname, 'lastname': lastname, 'email': email},
		responseHandler(res, next)
	);
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.remove = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.deleteUser({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};
<commit_msg>isInt => notNull<commit_after>////////////////////////////////////////////////////////////////////////////////////
////// Users
////////////////////////////////////////////////////////////////////////////////////
'use strict';

// DI
var db,
	responseHandler;

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findAll = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	db.findAllUsers({'application_id': appid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findById = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.findUserById({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.findBadgesById = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.findUserBadgesByUserId({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.create = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('login', '"login": must be a valid string').notNull();
	req.check('firstname', '"firstname": must be a valid string').notNull();
	req.check('lastname', '"lastname": must be a valid string').notNull();
	req.check('email', '"email": must be a valid Email adress').isEmail();
	var errors = req.validationErrors(),
		appid,
		login,
		firstname,
		lastname,
		email;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	login = req.params.login;
	firstname = req.params.firstname;
	lastname = req.params.lastname;
	email = req.params.email;
	db.createUser(
		{'application_id': appid, 'login': login, 'firstname': firstname, 'lastname': lastname, 'email': email},
		responseHandler(res, next)
	);
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.update = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	req.check('login', '"login": must be a valid string').notNull();
	req.check('firstname', '"firstname": must be a valid string').notNull();
	req.check('lastname', '"lastname": must be a valid string').notNull();
	req.check('email', '"email": must be a valid Email adress').isEmail();
	var errors = req.validationErrors(),
		appid,
		userid,
		login,
		firstname,
		lastname,
		email;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	login = req.params.login;
	firstname = req.params.firstname;
	lastname = req.params.lastname;
	email = req.params.email;
	db.updateUser(
		{'application_id': appid, 'user_id': userid, 'login': login, 'firstname': firstname, 'lastname': lastname, 'email': email},
		responseHandler(res, next)
	);
};

/**
 *
 * @param req the HTTP requests, contains header and body parameters
 * @param res the callback to which send HTTP response
 * @param next facilitate restify function chaining
 */
exports.remove = function (req, res, next) {
	req.check('appid', '"appid": must be a valid identifier').notNull();
	req.check('userid', '"userid": must be a valid identifier').notNull();
	var errors = req.validationErrors(),
		appid,
		userid;
	if (errors) {
		responseHandler(res).error(400, errors);
		return;
	}

	appid = req.params.appid;
	userid = req.params.userid;
	db.deleteUser({'application_id': appid, 'user_id': userid}, responseHandler(res, next));
};
<|endoftext|>


<commit_before>app.controller('webCV', function($scope) {
  $scope.header = {
    first: 'Maxine',
    second: 'Ellah'

  };

  $scope.subHeader = {
    text: 'Web Developer'
  };

  $scope.links = [{
    text: 'Github',
    link: 'https://github.com/maxine-ellah'
  },
  {
    text: 'Resume',
    link: 'https://docs.google.com/document/d/1lnLSrh6rwcikrYyQd7dF8p_pRk9t9CfQ36cHBDt6fSA/pub'
  },
  {
    text: 'Contact',
    link: 'mailto:maxine.ellah@gmail.com'
  }]

})
<commit_msg>removed link to google drive<commit_after>app.controller('webCV', function($scope) {
  $scope.header = {
    first: 'Maxine',
    second: 'Ellah'

  };

  $scope.subHeader = {
    text: 'Web Developer'
  };

  $scope.links = [{
    text: 'Github',
    link: 'https://github.com/maxine-ellah'
  },
  {
    text: 'Resume',
    link: '/images/MaxineEllahCV.pdf'
  },
  {
    text: 'Contact',
    link: 'mailto:maxine.ellah@gmail.com'
  }]

})
<|endoftext|>


<commit_before>const TrelloHandler = index.TrelloHandler;
const DateFormat = index.DateFormat;

const boards = {
    '284746138995785729': '59392df2d36f09ca35556339', // Veil
};

const lists = {
    mutes: '59392e154996d41c2127c335',
    kicks: '59392e1330235b9cc7a28f94',
    bans: '59392e1037e46c4d8b1af98c',
};

const labels = {
    reverted: '59396434a65061821399b435',
};

const cache = {};
exports.cache = cache;

/*

    cache {
        guildId: {
            listId: {
                id: 123,
                cards: [ // Ordered from newest
                    {
                        id: 123,
                        stampCreated: 123,
                        targetId: 123,
                    }
                ]
            }
        }
    }

    -UnMute
        -Mark last card for that user as dueComplete

    -Mute
        -Mark last card for that user as dueComplete
        -Create new card

    -IncMute
        -Change due date to new date

    -UndoMute
        -Mark last card for that user as dueComplete
        -Mark last card for that user *without Reverted label* with Reverted label

*/

/*

    -Cache all lists in board
        -Cache all cards in lists

    -When a new card is added or a card is altered, alter it in cache and API

    -Get card data from cache

*/

function fixDesc(cardDesc) {
    let cardDescStr;

    if (Util.isObject(cardDesc)) {
        const cardDescNew = [];

        for (const [key, value] of Object.entries(cardDesc)) {
            if (typeof key === 'number') {
                cardDescNew.push(`${value}`);
            } else {
                cardDescNew.push(`${key}: ${value}`);
            }
        }

        cardDescStr = cardDescNew.join('\n\n');
    } else {
        cardDescStr = cardDesc;
    }

    cardDescStr = cardDescStr.substr(0, 16384);

    return cardDescStr;
}

function getStampFromId(id) {
    return 1000 * parseInt(id.substring(0, 8), 16);
}

function sortCards(a, b) { // Newest first
    return b.stampCreated - a.stampCreated;
}

function makeCacheCard(nowCard, targetId) {
    if (targetId == null) targetId = null;

    const nowCardId = nowCard.id;

    const cacheCard = Util.cloneObj(nowCard);
    cacheCard.stampCreated = getStampFromId(nowCardId);
    cacheCard.targetId = targetId;

    return cacheCard;
}

exports.findCard = function (guild, listName, targetId, callback) {
    listName = listName.toLowerCase();

    if (!has.call(lists, listName)) {
        console.log(`List ${listName} does not exist`);
        return false;
    }

    const guildId = guild.id;
    const listId = lists[listName];

    const cacheCards = cache[guildId][listId].cards;

    for (let i = 0; i < cacheCards.length; i++) {
        if (cacheCards[i].targetId === targetId) {
            console.log(`>> FOUND CARD FOR ${targetId} FROM CACHE <<`);
            callback(true, cacheCards[i]);
            return undefined;
        }
    }

    TrelloHandler.get('/1/search', {
        query: targetId,
        modelTypes: 'cards',
        card_fields: 'desc',
        cards_limit: 1,
    }, (err, data) => {
        console.log('--[FindCard] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[FindCard] TRELLO FEEDBACK END--');

        const ok = err == null && data.cards.length > 0;

        if (ok) {
            const cardData = data.cards[0];
            const cardId = cardData.id;

            let cacheCard = null;

            for (let i = 0; i < cacheCards.length; i++) {
                if (cacheCards[i].id === cardId) {
                    cacheCard = cacheCards[i];
                    cacheCard.targetId = targetId;
                    console.log(`>> UPDATED EXISTING TARGETID FOR ${targetId} <<`);
                    break;
                }
            }

            if (cacheCard == null) {
                cacheCard = makeCacheCard(cardData, targetId);

                cacheCards.push(cacheCard);
                cacheCards.sort(sortCards);
            }

            callback(ok, cacheCard);
        } else {
            callback(ok, err);
        }
    });

    return undefined;
};

exports.dueComplete = function (guild, cardId, callback) {
    TrelloHandler.put(`/1/cards/${cardId}/dueComplete`, {
        value: true,
    }, (err, data) => {
        console.log('--[DueComplete] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[DueComplete] TRELLO FEEDBACK END--');

        if (callback) callback();
    });
};

exports.setDesc = function (guild, cardId, cardDesc) {
    cardDesc = fixDesc(cardDesc);

    TrelloHandler.put(`/1/cards/${cardId}/desc`, {
        value: cardDesc,
    }, (err, data) => {
        console.log('--[SetDesc] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[SetDesc] TRELLO FEEDBACK END--');
    });
};

exports.setDue = function (guild, cardId, dueDate) {
    TrelloHandler.put(`/1/cards/${cardId}/due`, {
        value: dueDate,
    }, (err, data) => {
        console.log('--[SetDue] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[SetDue] TRELLO FEEDBACK END--');
    });
};

exports.addLabel = function (guild, cardId, labelName) {
    labelName = labelName.toLowerCase();

    if (!has.call(labels, labelName)) {
        console.log(`Label ${labelName} does not exist`);
        return false;
    }

    const labelId = labels[labelName];

    TrelloHandler.post(`/1/cards/${cardId}/idLabels`, {
        value: labelId,
    }, (err, data) => {
        console.log('--[AddLabel] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[AddLabel] TRELLO FEEDBACK END--');
    });

    return true;
};

exports.addCard = function (guild, listName, cardName, cardDesc, dueDate) {
    listName = listName.toLowerCase();

    if (!has.call(lists, listName)) {
        console.log(`List ${listName} does not exist`);
        return false;
    }

    const guildId = guild.id;
    const listId = lists[listName];

    if (dueDate == null) dueDate = null;

    const targetId = cardDesc['User ID'];

    cardDesc = fixDesc(cardDesc);

    const nowDate = new Date();
    const nowDateStr = DateFormat(nowDate, '[dd/mm/yyyy]');

    TrelloHandler.post('/1/cards', {
        idList: listId,
        name: `${nowDateStr} ${cardName}`,
        desc: cardDesc,
        pos: 'top',
        due: dueDate,
    }, (err, data) => {
        console.log('--[AddCard] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);

        console.log('--[AddCard] TRELLO FEEDBACK END--');

        if (!err && data) {
            const cacheCards = cache[guildId][listId].cards;
            const cacheCard = makeCacheCard(data, targetId);

            cacheCards.push(cacheCard);
            cacheCards.sort(sortCards);
        }
    });

    return true;
};

exports.setupCache = function (guild) {
    const guildId = guild.id;

    if (!has.call(boards, guildId)) {
        // console.log(`Board ${guildId} does not exist`);
        return false;
    }

    const boardId = boards[guildId];

    console.log(`\nFetching trello data for ${guildId}`);

    TrelloHandler.get(`/1/boards/${boardId}`, {
        'lists': 'open',
        'cards': 'open',
    }, (err, data) => {
        if (err) {
            console.log(err);
            console.log('--<>--');
            console.log(data);
            return;
        }

        console.log(`Cached trello data for ${guildId}`);

        cache[guildId] = {};

        const nowLists = data.lists;
        for (let i = 0; i < nowLists.length; i++) {
            const nowList = nowLists[i];
            const nowListId = nowList.id;

            const cacheList = Util.cloneObj(nowList);
            cacheList.cards = [];

            cache[guildId][nowListId] = cacheList;
        }

        const nowCards = data.cards;
        for (let i = 0; i < nowCards.length; i++) {
            const nowCard = nowCards[i];
            const cacheList = cache[guildId][nowCard.idList];

            const cacheCard = makeCacheCard(nowCard);

            cacheList.cards.push(cacheCard);
        }

        for (const cacheListId of Object.keys(cache[guildId])) {
            const cacheList = cache[guildId][cacheListId];
            const cacheCards = cacheList.cards;
            cacheCards.sort(sortCards);
            console.log(cacheCards);
        }
    });

    return true;
};
<commit_msg>Changed debugging<commit_after>const TrelloHandler = index.TrelloHandler;
const DateFormat = index.DateFormat;

const boards = {
    '284746138995785729': '59392df2d36f09ca35556339', // Veil
};

const lists = {
    mutes: '59392e154996d41c2127c335',
    kicks: '59392e1330235b9cc7a28f94',
    bans: '59392e1037e46c4d8b1af98c',
};

const labels = {
    reverted: '59396434a65061821399b435',
};

const cache = {};
exports.cache = cache;

/*

    cache {
        guildId: {
            listId: {
                id: 123,
                cards: [ // Ordered from newest
                    {
                        id: 123,
                        stampCreated: 123,
                        targetId: 123,
                    }
                ]
            }
        }
    }

    -UnMute
        -Mark last card for that user as dueComplete

    -Mute
        -Mark last card for that user as dueComplete
        -Create new card

    -IncMute
        -Change due date to new date

    -UndoMute
        -Mark last card for that user as dueComplete
        -Mark last card for that user *without Reverted label* with Reverted label

*/

/*

    -Cache all lists in board
        -Cache all cards in lists

    -When a new card is added or a card is altered, alter it in cache and API

    -Get card data from cache

*/

function fixDesc(cardDesc) {
    let cardDescStr;

    if (Util.isObject(cardDesc)) {
        const cardDescNew = [];

        for (const [key, value] of Object.entries(cardDesc)) {
            if (typeof key === 'number') {
                cardDescNew.push(`${value}`);
            } else {
                cardDescNew.push(`${key}: ${value}`);
            }
        }

        cardDescStr = cardDescNew.join('\n\n');
    } else {
        cardDescStr = cardDesc;
    }

    cardDescStr = cardDescStr.substr(0, 16384);

    return cardDescStr;
}

function getStampFromId(id) {
    return 1000 * parseInt(id.substring(0, 8), 16);
}

function sortCards(a, b) { // Newest first
    return b.stampCreated - a.stampCreated;
}

function makeCacheCard(nowCard, targetId) {
    if (targetId == null) targetId = null;

    const nowCardId = nowCard.id;

    const cacheCard = Util.cloneObj(nowCard);
    cacheCard.stampCreated = getStampFromId(nowCardId);
    cacheCard.targetId = targetId;

    return cacheCard;
}

exports.findCard = function (guild, listName, targetId, callback) {
    listName = listName.toLowerCase();

    if (!has.call(lists, listName)) {
        console.log(`List ${listName} does not exist`);
        return false;
    }

    const guildId = guild.id;
    const listId = lists[listName];

    const cacheCards = cache[guildId][listId].cards;

    for (let i = 0; i < cacheCards.length; i++) {
        if (cacheCards[i].targetId === targetId) {
            console.log(`>> FOUND CARD FOR ${targetId} FROM CACHE <<`);
            callback(true, cacheCards[i]);
            return undefined;
        }
    }

    TrelloHandler.get('/1/search', {
        query: targetId,
        modelTypes: 'cards',
        card_fields: 'desc',
        cards_limit: 1,
    }, (err, data) => {
        console.log('--[FindCard] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[FindCard] TRELLO FEEDBACK END--');

        const ok = err == null && data.cards.length > 0;

        if (ok) {
            const cardData = data.cards[0];
            const cardId = cardData.id;

            let cacheCard = null;

            for (let i = 0; i < cacheCards.length; i++) {
                if (cacheCards[i].id === cardId) {
                    cacheCard = cacheCards[i];
                    cacheCard.targetId = targetId;
                    console.log(`>> UPDATED EXISTING TARGETID FOR ${targetId} <<`);
                    break;
                }
            }

            if (cacheCard == null) {
                cacheCard = makeCacheCard(cardData, targetId);

                cacheCards.push(cacheCard);
                cacheCards.sort(sortCards);
            }

            callback(ok, cacheCard);
        } else {
            callback(ok, err);
        }
    });

    return undefined;
};

exports.dueComplete = function (guild, cardId, callback) {
    TrelloHandler.put(`/1/cards/${cardId}/dueComplete`, {
        value: true,
    }, (err, data) => {
        console.log('--[DueComplete] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[DueComplete] TRELLO FEEDBACK END--');

        if (callback) callback();
    });
};

exports.setDesc = function (guild, cardId, cardDesc) {
    cardDesc = fixDesc(cardDesc);

    TrelloHandler.put(`/1/cards/${cardId}/desc`, {
        value: cardDesc,
    }, (err, data) => {
        console.log('--[SetDesc] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[SetDesc] TRELLO FEEDBACK END--');
    });
};

exports.setDue = function (guild, cardId, dueDate) {
    TrelloHandler.put(`/1/cards/${cardId}/due`, {
        value: dueDate,
    }, (err, data) => {
        console.log('--[SetDue] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[SetDue] TRELLO FEEDBACK END--');
    });
};

exports.addLabel = function (guild, cardId, labelName) {
    labelName = labelName.toLowerCase();

    if (!has.call(labels, labelName)) {
        console.log(`Label ${labelName} does not exist`);
        return false;
    }

    const labelId = labels[labelName];

    TrelloHandler.post(`/1/cards/${cardId}/idLabels`, {
        value: labelId,
    }, (err, data) => {
        console.log('--[AddLabel] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);
        console.log('--[AddLabel] TRELLO FEEDBACK END--');
    });

    return true;
};

exports.addCard = function (guild, listName, cardName, cardDesc, dueDate) {
    listName = listName.toLowerCase();

    if (!has.call(lists, listName)) {
        console.log(`List ${listName} does not exist`);
        return false;
    }

    const guildId = guild.id;
    const listId = lists[listName];

    if (dueDate == null) dueDate = null;

    const targetId = cardDesc['User ID'];

    cardDesc = fixDesc(cardDesc);

    const nowDate = new Date();
    const nowDateStr = DateFormat(nowDate, '[dd/mm/yyyy]');

    TrelloHandler.post('/1/cards', {
        idList: listId,
        name: `${nowDateStr} ${cardName}`,
        desc: cardDesc,
        pos: 'top',
        due: dueDate,
    }, (err, data) => {
        console.log('--[AddCard] TRELLO FEEDBACK START--');
        console.log(err);
        console.log('--<>--');
        console.log(data);

        console.log('--[AddCard] TRELLO FEEDBACK END--');

        if (!err && data) {
            const cacheCards = cache[guildId][listId].cards;
            const cacheCard = makeCacheCard(data, targetId);

            cacheCards.push(cacheCard);
            cacheCards.sort(sortCards);
        }
    });

    return true;
};

exports.setupCache = function (guild) {
    const guildId = guild.id;

    if (!has.call(boards, guildId)) {
        // console.log(`Board ${guildId} does not exist`);
        return false;
    }

    const boardId = boards[guildId];

    console.log(`\nFetching trello data for ${guild.name}\n`);

    TrelloHandler.get(`/1/boards/${boardId}`, {
        'lists': 'open',
        'cards': 'open',
    }, (err, data) => {
        if (err) {
            console.log(err);
            console.log('--<>--');
            console.log(data);
            return;
        }

        console.log(`\nCached trello data for ${guild.name}\n`);

        cache[guildId] = {};

        const nowLists = data.lists;
        for (let i = 0; i < nowLists.length; i++) {
            const nowList = nowLists[i];
            const nowListId = nowList.id;

            const cacheList = Util.cloneObj(nowList);
            cacheList.cards = [];

            cache[guildId][nowListId] = cacheList;
        }

        const nowCards = data.cards;
        for (let i = 0; i < nowCards.length; i++) {
            const nowCard = nowCards[i];
            const cacheList = cache[guildId][nowCard.idList];

            const cacheCard = makeCacheCard(nowCard);

            cacheList.cards.push(cacheCard);
        }

        for (const cacheListId of Object.keys(cache[guildId])) {
            const cacheList = cache[guildId][cacheListId];
            const cacheCards = cacheList.cards;
            cacheCards.sort(sortCards);
            // console.log(cacheCards);
        }
    });

    return true;
};
<|endoftext|>


<commit_before><commit_msg>reverse window.scrollTo on catch<commit_after><|endoftext|>


<commit_before>var numSegments = 1000;
var roadWidth = 150;
var treeWidth = 40;
var treeHeight = 40;

function run(ctx, width, height, car, carImage, treeImage) {
    var yPosition = 0;
    var lastTime = performance.now();

    car.yPosition = height-1;
    car.xPosition = getRoadCenter(-car.yPosition) - 30;

    function getRoadCenter(y) {
        return Math.sin(y/100) * (width /2) + width/2
    }

    var trees = [];
    var numTrees = 10;
    function genTree(yPos) {
        var nextY = -Math.random()*5 + yPos;
        var roadX = getRoadCenter(-nextY);

        while (true) {
            var nextX = Math.random()*width;

            if (nextX < (roadX - roadWidth/2 - treeWidth) || nextX > (roadX + roadWidth/2 + treeWidth)) {
                return {x: nextX, y: nextY};
            }
        }
    }

    function genTrees() {
        for (var i =0 ; i < numTrees; i++)  {
            trees.push(genTree(yPosition + height/numTrees * i));
        }
    }

    function checkIfTreeIsOver() {
        for (var i = 0; i < numTrees; i++) {
            if ((trees[i].y + yPosition - treeHeight) > height) {
                trees[i] = genTree(-yPosition);
            }
        }
    }

    genTrees();

    function draw(yPos) {

        ctx.fillStyle = "black";
        for (var roadSegment = 0; roadSegment < numSegments; roadSegment++) {
            var roadStart = (roadSegment/numSegments) * height;
            var roadEnd = (roadSegment +1)/numSegments * height;

            var roadCenterStart = getRoadCenter(yPos - roadStart);
            var roadCenterEnd = getRoadCenter(yPos - roadEnd);

            ctx.fillRect(roadCenterStart-roadWidth/2, roadStart, roadWidth, height/numSegments);
        }

        ctx.fillStyle = "green";
        for (var i =0; i < numTrees; i++) {
            ctx.drawImage(treeImage, trees[i].x - treeWidth/2, trees[i].y + yPos - treeHeight/2, treeWidth, treeHeight);
        }

        ctx.translate(+(car.xPosition), +(car.yPosition + yPos));
        ctx.rotate((-Math.PI/2 + car.turn));
        ctx.drawImage(carImage, -20, -20, 40, 40);
        ctx.rotate(-(-Math.PI/2 + car.turn));
        ctx.translate(-(car.xPosition), -(car.yPosition + yPos));
    }

    function notInRoad() {
        var roadCenter = getRoadCenter(-car.yPosition);
        return (car.xPosition < (roadCenter - roadWidth/2) || car.xPosition > (roadCenter + roadWidth/2));
    }

    function haveLost() {
        var offOfRoadSides = (car.xPosition < 0 || car.xPosition > width);
        var offOfRoadTop = (car.yPosition + yPosition) < 0 || (car.yPosition + yPosition) > height;
        return offOfRoadSides || offOfRoadTop || notInRoad();
    }

    function step(timestamp) {
        var dTime = timestamp - lastTime;
        lastTime = timestamp;

        yPosition += dTime * .01;

        ctx.clearRect(0, 0, width, height);

        car.magnitude = dTime * .04 * car.speed/100;
        car.dY = -car.magnitude * Math.cos(car.turn);
        car.dX = car.magnitude * Math.sin(car.turn);

        car.yPosition += car.dY;
        car.xPosition += car.dX;

        checkIfTreeIsOver();

        draw(yPosition);

        if (haveLost()) {
            alert("You lose");
            didThePlayerLoseTheGameYet = true;
            return;
        }

        window.requestAnimationFrame(step);
    }

    window.requestAnimationFrame(step);

    function getScore() {
        return Math.floor(yPosition);
    }

    return getScore;
}
<commit_msg>Added scenery changes<commit_after>var numSegments = 1000;
var roadWidth = 150;
var treeWidth = 40;
var treeHeight = 40;

function calcSceneryColour(distance) {
    var scenery = [
        {pos: 0, colour: {r: 0, g: 102, b: 0}}, // nice grass
        {pos: 30, colour: {r: 153, g: 153, b: 102}}, // plains
        {pos: 60, colour: {r: 204, g: 153, b: 0}}, // desert
        {pos: 90, colour: {r: 102, g: 153, b: 153}} // ice plains
    ];

    // loop sceneries
    distance = distance % 90;

    function lerp(e, a, b) {
        return (b-a) * e + a;
    }

    var r, g, b;

    for (var i = 1; i < scenery.length; i++) {
        if (scenery[i].pos > distance) {
            var e = (scenery[i].pos - distance) / (scenery[i].pos - scenery[i-1].pos);
            var cb = scenery[i-1].colour;
            var ca = scenery[i].colour;
            r = lerp(e, ca.r, cb.r);
            g = lerp(e, ca.g, cb.g);
            b = lerp(e, ca.b, cb.b);
            break;
        }
    }

    return "rgb(" + Math.floor(r) + "," + Math.floor(g) + "," + Math.floor(b) + ")";
}

function run(ctx, width, height, car, carImage, treeImage) {
    var yPosition = 0;
    var lastTime = performance.now();

    car.yPosition = height-1;
    car.xPosition = getRoadCenter(-car.yPosition) - 30;

    function getRoadCenter(y) {
        return Math.sin(y/100) * (width /2) + width/2
    }

    var trees = [];
    var numTrees = 10;
    function genTree(yPos) {
        var nextY = -Math.random()*5 + yPos;
        var roadX = getRoadCenter(-nextY);

        while (true) {
            var nextX = Math.random()*width;

            if (nextX < (roadX - roadWidth/2 - treeWidth) || nextX > (roadX + roadWidth/2 + treeWidth)) {
                return {x: nextX, y: nextY};
            }
        }
    }

    function genTrees() {
        for (var i =0 ; i < numTrees; i++)  {
            trees.push(genTree(yPosition + height/numTrees * i));
        }
    }

    function checkIfTreeIsOver() {
        for (var i = 0; i < numTrees; i++) {
            if ((trees[i].y + yPosition - treeHeight) > height) {
                trees[i] = genTree(-yPosition);
            }
        }
    }

    genTrees();

    function draw(yPos) {
        ctx.fillStyle = calcSceneryColour(getScore());
        ctx.fillRect(0, 0, width, height);

        ctx.fillStyle = "black";
        for (var roadSegment = 0; roadSegment < numSegments; roadSegment++) {
            var roadStart = (roadSegment/numSegments) * height;
            var roadEnd = (roadSegment +1)/numSegments * height;

            var roadCenterStart = getRoadCenter(yPos - roadStart);
            var roadCenterEnd = getRoadCenter(yPos - roadEnd);

            ctx.fillRect(roadCenterStart-roadWidth/2, roadStart, roadWidth, height/numSegments);
        }

        ctx.fillStyle = "green";
        for (var i =0; i < numTrees; i++) {
            ctx.drawImage(treeImage, trees[i].x - treeWidth/2, trees[i].y + yPos - treeHeight/2, treeWidth, treeHeight);
        }

        ctx.translate(+(car.xPosition), +(car.yPosition + yPos));
        ctx.rotate((-Math.PI/2 + car.turn));
        ctx.drawImage(carImage, -20, -20, 40, 40);
        ctx.rotate(-(-Math.PI/2 + car.turn));
        ctx.translate(-(car.xPosition), -(car.yPosition + yPos));
    }

    function notInRoad() {
        var roadCenter = getRoadCenter(-car.yPosition);
        return (car.xPosition < (roadCenter - roadWidth/2) || car.xPosition > (roadCenter + roadWidth/2));
    }

    function haveLost() {
        var offOfRoadSides = (car.xPosition < 0 || car.xPosition > width);
        var offOfRoadTop = (car.yPosition + yPosition) < 0 || (car.yPosition + yPosition) > height;
        return offOfRoadSides || offOfRoadTop || notInRoad();
    }

    function step(timestamp) {
        var dTime = timestamp - lastTime;
        lastTime = timestamp;

        yPosition += dTime * .01;

        car.magnitude = dTime * .04 * car.speed/100;
        car.dY = -car.magnitude * Math.cos(car.turn);
        car.dX = car.magnitude * Math.sin(car.turn);

        car.yPosition += car.dY;
        car.xPosition += car.dX;

        checkIfTreeIsOver();

        draw(yPosition);

        if (haveLost()) {
            alert("You lose");
            didThePlayerLoseTheGameYet = true;
            return;
        }

        window.requestAnimationFrame(step);
    }

    window.requestAnimationFrame(step);

    function getScore() {
        return Math.floor(yPosition);
    }

    return getScore;
}
<|endoftext|>


<commit_before>export const agBiomass2agCarbon = (agb) => 0.5 * agb;

export const agBiomass2bgCarbon = (agb) => 0.5 * 0.26 * agb;
<commit_msg>add all calculations<commit_after>export const tonsToTonnes = (value) => value * 0.907185;

export const biomassToCO2 = (value) => value * 0.47;

export const carbonToCO2 = (value) => (value * 12) / 44;

export const agBiomass2agCarbon = (agb) => 0.5 * agb;

export const agBiomass2bgBiomass = (agb) => 0.26 * agb;

export const agBiomass2TotalBiomass = (agb) => 1.26 * agb;

export const agBiomass2bgCarbon = (agb) => 0.5 * 0.26 * agb;

export const agBiomass2TotalCarbon = (agb) => 0.5 * 1.26 * agb;
<|endoftext|>