Large diffs are not rendered by default.

@@ -3,18 +3,26 @@
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
"dev": "babel-node src/server.js",
"clean": "rm -rf build && mkdir build && babel src -d build",
"production": "rm -rf build && mkdir build && babel src -d build && babel src -d build && node build/server.js",
"production-pm2": "rm -rf build && mkdir build && babel src -d build && babel src -d build && pm2 start build/server.js"
},
"dependencies": {
"bluebird": "~3.3.4",
"body-parser": "~1.15.0",
"debug": "~2.2.0",
"express": "~4.13.3",
"body-parser": "^1.15.0",
"express": "^4.13.4",
"fraction.js": "^3.2.5",
"morgan": "~1.7.0",
"multer": "~1.1.0",
"lodash": "^4.11.1",
"morgan": "^1.7.0",
"multer": "^1.1.0",
"mz": "^2.4.0",
"parse-server": "^2.1.4",
"request": "~2.69.0",
"underscore": "^1.8.3"
"request-promise": "^3.0.0"
},
"devDependencies": {
"babel-cli": "^6.7.5",
"babel-preset-es2015-node5": "^1.2.0",
"nodemon": "^1.9.1",
"debug": "latest"
}
}

This file was deleted.

Binary file not shown.
Binary file not shown.

This file was deleted.

@@ -1,25 +1,25 @@
var express = require('express');
var path = require('path');
var logger = require('morgan');
var morgan = require('morgan');
var bodyParser = require('body-parser');
var multer = require('multer');

var ocr = require('./routes/ocr');
var apple = require('./routes/apple/apple');
var parse = require('./routes/parse/parse');

var app = express();

app.use(logger('dev'));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', apple);
app.use('/api', ocr);
app.use('/api/data', parse);


// error handlers

// catch and handle parse.com errors
app.use(function (err, req, res, next) {
if (err.parseCode == 209) {
@@ -36,20 +36,12 @@ app.use(function (req, res, next) {
next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
console.trace(err.message);
res.status(err.status || 500);
});
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
// print stacktrace if in dev mode
if (app.get('env') === 'development') {
console.trace(err);
}

res.status(err.status || 500);
});

File renamed without changes.
File renamed without changes.
@@ -0,0 +1,69 @@
var express = require('express');
var router = express.Router();
var request = require('request-promise');
var fs = require('mz/fs');
var execFile = require('mz/child_process').execFile;
var path = require('path');
var multer = require('multer');
var receipts = multer({ dest: './receipts/' });

router.route('/receipt')
.post(receipts.single('receipt'), function (req, res, next) {
req.socket.setTimeout(0);

var sessionToken = req.body.sessionToken;
var receipt = req.file;

// validateSessionToken(sessionToken)
// .then(() => performOcr(receipt))
// .then(result => res.json(result))
// .catch(e => next(e));

performOcr(receipt)
.then(result => res.json(result))
.catch(e => next(e));
});

function validateSessionToken(sessionToken) {
return request({
url: 'http://localhost:3000/sessions/me',
method: 'GET',
headers: {
'X-Parse-Application-Id': 'yLuL6xJB2dUD2hjfh4W2EcZizcPsJZKDgDzbrPji',
'X-Parse-Session-Token': sessionToken
}
})
.spread((response, body) => {
var statusCode = response.statusCode;
if (statusCode != 200) {
var parseResponse = JSON.parse(body);
var error = new Error(parseResponse.error);
error.status = 401;
error.parseCode = parseResponse.code;
throw error;
}
});
}

function performOcr(receipt) {
var imagePath = path.resolve(process.cwd(), receipt.path);
var scriptPath = path.resolve(process.cwd(), 'bin/Run.py');
var args = [imagePath];

return execFile(scriptPath, args, {cwd: path.resolve(process.cwd(), 'bin/')})
.spread((stdout, stderr) => {
console.log('stdout', stdout);
console.log('stderr', stderr);
return JSON.parse(stdout);
// var jsonOutput = removeExtension(imagePath) + '.json';
// return fs.readFile(jsonOutput, 'utf8');
});
// .then(data => JSON.parse(data));
}

function removeExtension(filename) {
var lastDotPosition = filename.lastIndexOf(".");
return lastDotPosition === -1 ? filename : filename.substr(0, lastDotPosition);
}

module.exports = router;
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,57 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'Compensation';
export const GROUP = 'group';
export const CREDITOR = 'creditor';
export const DEBTOR = 'debtor';
export const AMOUNT = 'amount';
export const PAID = 'paid';

export default class Compensation extends Parse.Object {
constructor() {
super(CLASS);
}

get group() {
return this.get(GROUP);
}

set group(group) {
this.set(GROUP, group);
}

get creditor() {
return this.get(CREDITOR);
}

set creditor(creditor) {
this.set(CREDITOR, creditor);
}

get debtor() {
return this.get(DEBTOR);
}

set debtor(debtor) {
this.set(DEBTOR, debtor);
}

get amount() {
const amount = this.get(AMOUNT);
return amount[0] / amount[1];
}

set amount(amount) {
this.set(AMOUNT, amount);
}

get paid() {
return this.get(PAID);
}

set paid(paid) {
this.set(PAID, paid);
}
}
@@ -0,0 +1,29 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'Group';
export const NAME = 'name';
export const CURRENCY = 'currency';

export default class Group extends Parse.Object {
constructor() {
super(CLASS);
}

get name() {
return this.get(NAME)
}

set name(name) {
this.set(NAME, name)
}

get currency() {
return this.get(CURRENCY)
}

set currency(currency) {
this.set(CURRENCY, currency)
}
}
@@ -0,0 +1,69 @@
/**
* Created by fabio on 18.04.16.
*/

const Fraction = require('fraction.js');
import {isEmpty} from 'lodash';

export const CLASS = 'Identity';
export const ACTIVE = 'active';
export const PENDING = 'pending';
export const GROUP = 'group';
export const NICKNAME = 'nickname';
export const AVATAR = 'avatar';
export const BALANCE = 'balance';

export default class Identity extends Parse.Object {
constructor() {
super(CLASS);
}

get active() {
return this.get(ACTIVE)
}

set active(active) {
this.set(ACTIVE, active)
}

get pending() {
return this.get(PENDING)
}

set pending(pending) {
this.set(PENDING, pending)
}

get group() {
return this.get(GROUP)
}

set group(group) {
this.set(GROUP, group)
}

get nickname() {
return this.get(NICKNAME)
}

set nickname(nickname) {
this.set(NICKNAME, nickname)
}

get avatar() {
return this.get(AVATAR)
}

set avatar(avatar) {
this.set(AVATAR, avatar)
}

get balance() {
const balance = this.get(BALANCE);
return isEmpty(balance) ? new Fraction(0, 1) : new Fraction(balance[0], balance[1]);
}

set balance(balance) {
this.set(BALANCE, balance);
}
}
@@ -0,0 +1,42 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'Item';
export const NAME = 'name';
export const PRICE = 'price';
export const IDENTITIES = 'identities';

export default class Item extends Parse.Object {
constructor() {
super(CLASS);
}

get name() {
return this.get(NAME)
}

set name(name) {
this.set(NAME, name)
}

get price() {
return this.get(PRICE)
}

set price(price) {
this.set(PRICE, price)
}

get identities() {
return this.get(IDENTITIES)
}

set identities(identities) {
this.set(IDENTITIES, identities)
}

getIdentitiesIds() {
return this.identities.map(identity => identity.id)
}
}
@@ -0,0 +1,123 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'Purchase';
export const BUYER = 'buyer';
export const GROUP = 'group';
export const DATE = 'date';
export const STORE = 'store';
export const ITEMS = 'items';
export const TOTAL_PRICE = 'totalPrice';
export const IDENTITIES = 'identities';
export const CURRENCY = 'currency';
export const EXCHANGE_RATE = 'exchangeRate';
export const READ_BY = 'readBy';
export const RECEIPT = 'receipt';
export const NOTE = 'note';

export default class Purchase extends Parse.Object {
constructor() {
super(CLASS);
}

get buyer() {
return this.get(BUYER)
}

set buyer(buyer) {
this.set(BUYER, buyer)
}

get group() {
return this.get(GROUP)
}

set group(group) {
this.set(GROUP, group)
}

get date() {
return this.get(DATE)
}

set date(date) {
this.set(DATE, date)
}

get store() {
return this.get(STORE)
}

set store(store) {
this.set(STORE, store)
}

get items() {
return this.get(ITEMS)
}

set items(items) {
this.set(ITEMS, items)
}

get totalPrice() {
return this.get(TOTAL_PRICE)
}

set totalPrice(totalPrice) {
this.set(TOTAL_PRICE, totalPrice)
}

get identities() {
return this.get(IDENTITIES)
}

set identities(identities) {
this.set(IDENTITIES, identities)
}

get currency() {
return this.get(CURRENCY)
}

set currency(currency) {
this.set(CURRENCY, currency)
}

get exchangeRate() {
return this.get(EXCHANGE_RATE)
}

set exchangeRate(exchangeRate) {
this.set(EXCHANGE_RATE, exchangeRate)
}

get readBy() {
return this.get(READ_BY)
}

set readBy(readBy) {
this.set(READ_BY, readBy)
}

get receipt() {
return this.get(RECEIPT)
}

set receipt(receipt) {
this.set(RECEIPT, receipt)
}

get note() {
return this.get(NOTE)
}

set note(note) {
this.set(NOTE, note)
}

getIdentitiesIds() {
return this.identities.map(identity => identity.id)
}
}
@@ -0,0 +1,60 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'Task';
export const TITLE = 'title';
export const GROUP = 'group';
export const TIME_FRAME = 'timeFrame';
export const INITIATOR = 'initiator';
export const IDENTITIES = 'identities';

export default class Task extends Parse.Object {
constructor() {
super(CLASS);
}

get title() {
return this.get(TITLE)
}

set title(title) {
this.set(TITLE, title)
}

get group() {
return this.get(GROUP)
}

set group(group) {
this.set(GROUP, group)
}

get initiator() {
return this.get(INITIATOR)
}

set initiator(initiator) {
this.set(INITIATOR, initiator)
}

get timeFrame() {
return this.get(TIME_FRAME)
}

set timeFrame(timeFrame) {
this.set(TIME_FRAME, timeFrame)
}

get identities() {
return this.get(IDENTITIES)
}

set identities(identities) {
this.set(IDENTITIES, identities)
}

getIdentitiesIds() {
return this.identities.map(identity => identity.id)
}
}
@@ -0,0 +1,29 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'TaskHistoryEvent';
export const TASK = 'task';
export const IDENTITY = 'identity';

export default class TaskHistoryEvent extends Parse.Object {
constructor() {
super(CLASS);
}

get task() {
return this.get(TASK)
}

set task(task) {
this.set(TASK, task)
}

get identity() {
return this.get(IDENTITY)
}

set identity(identity) {
this.set(IDENTITY, identity)
}
}
@@ -0,0 +1,78 @@
/**
* Created by fabio on 18.04.16.
*/

export const CLASS = 'User';
export const NAME = 'username';
export const PASSWORD = 'password';
export const IDENTITIES = 'identities';
export const ARCHIVED_IDENTITIES = 'archivedIdentities';
export const CURRENT_IDENTITY = 'currentIdentity';
export const GOOGLE_ID = 'googleId';

export default class User extends Parse.User {
constructor() {
super(CLASS);
}

get name() {
return this.get(NAME);
}

set name(name) {
this.set(NAME, name);
}

set password(password) {
this.set(PASSWORD, password);
}

get identities() {
return this.get(IDENTITIES);
}

set identities(identities) {
this.set(IDENTITIES, identities);
}

addIdentity(identity) {
this.addUnique(IDENTITIES, identity);
}

removeIdentity() {
this.remove(IDENTITIES, identity);
this.remove(ARCHIVED_IDENTITIES, identity);
}

get archivedIdentities() {
return this.get(ARCHIVED_IDENTITIES);
}

set archivedIdentities(archivedIdentities) {
this.set(ARCHIVED_IDENTITIES, archivedIdentities);
}

addArchivedIdentity(identity) {
this.addUnique(ARCHIVED_IDENTITIES, identity);
}

get currentIdentity() {
return this.get(CURRENT_IDENTITY);
}

set currentIdentity(currentIdentity) {
this.set(CURRENT_IDENTITY, currentIdentity);
}

removeCurrentIdentity() {
this.unset(CURRENT_IDENTITY);
}

get googleId() {
return this.get(GOOGLE_ID);
}

set googleId(googleId) {
this.set(GOOGLE_ID, googleId);
}
}

Large diffs are not rendered by default.

@@ -12,12 +12,12 @@ var parseApi = new ParseServer({
},
ios: [
{
pfx: __dirname + '/ParseDevelopmentPushCertificate.p12',
pfx: __dirname + '/ParsePushDevelopmentCertificate.p12',
bundleId: 'ch.giantific.qwittig',
production: false
},
{
pfx: __dirname + '/ParseProductionPushCertificate.p12',
pfx: __dirname + '/ParsePushProductionCertificate.p12',
bundleId: 'ch.giantific.qwittig',
production: true
}
@@ -4,7 +4,7 @@
* Module dependencies.
*/

var app = require('../app');
var app = require('./app.js');
var debug = require('debug')('Node:server');
var http = require('http');