const express = require('express') const bodyParser = require('body-parser') const path = require('path') require('dotenv').config() // set up debug let DEBUG if (process.env.DEBUG || process.env.CROWDFUNDING_SITE_DEBUG) { DEBUG = true } else { DEBUG = false } if (DEBUG) console.log('Starting website in debug mode') // get goal details const goalPeople = Number(process.env.CROWDFUNDING_SITE_GOAL_PEOPLE) || 750 const goalRupees = Number(process.env.CROWDFUNDING_SITE_GOAL_RUPEES) || 500000 // set up knex (for database) const knex = require('knex')({ client:'sqlite3', connection:{ filename:'./donors.sqlite' }, useNullAsDefault: true }) knex.schema.hasTable('pledges').then(function(exists) { if (!exists) { if (DEBUG) console.debug('No table exists! Creating one now...') return knex.schema.createTable('pledges', function(t) { t.increments('id').primary() t.timestamp('created_at').defaultTo(knex.fn.now()).notNullable() t.boolean('was_robot').defaultTo(true) t.integer('amount').notNullable() t.boolean('overseas') t.string('name', 128) t.boolean('anonymous') t.string('email', 128) t.string('phone', 32) t.integer('retry_times').defaultTo(10) t.boolean('get_newsletter').defaultTo(false) t.text('other_message') }) } }) // set up bookshelf (for easy interface for database) bookshelf = require('bookshelf')(knex) const Pledge = bookshelf.model('Pledge', { tableName: 'pledges', }) // decide base url and port for app (can be configured) const baseUrl = process.env.CROWDFUNDING_SITE_BASE_URL || '/' const port = process.env.CROWDFUNDING_SITE_PORT || 5000 // set up twing const {TwingEnvironment, TwingLoaderFilesystem} = require('twing') let loader = new TwingLoaderFilesystem(path.resolve(__dirname, '..', 'dist')) let twing = new TwingEnvironment(loader) // set up express const app = express() const router = express.Router() app.use(baseUrl, router) router.use(bodyParser.urlencoded({ extended: true, })) // main views router.get('/', async (req, res) => { if (DEBUG) console.debug('Returning home page') // count people // TODO: optimise to do using SQL only let total_people = 0 let total_rupees = 0 let result = await Pledge.fetchAll() for (let pledge of result.models) { total_people += 1 total_rupees += pledge.get('amount') } twing.render('index.html', { 'goal_rupees': Number(goalRupees).toLocaleString('en-IN'), 'goal_people': Number(goalPeople).toLocaleString('en-IN'), 'progress_rupees': Number(total_rupees).toLocaleString('en-IN'), 'progress_people': Number(total_people).toLocaleString('en-IN'), 'percent_rupees': `style="width: ${total_rupees/goalRupees*100}%"`, 'percent_people': `style="width: ${total_people/goalPeople*100}%"`, }).then((output) => { res.end(output) }) }) router.post('/pledge', async (req, res) => { if (DEBUG) console.debug('New pledge:', req.body) // validate pledge let errors = [] let submit = req.body.submit if (submit != 'Save Pledge') { errors.push("This request seems to have been tampered with. Are you sure it wasn't you doing the tampering?") } let robo = req.body.robo if(robo != 'no') { errors.push('Only humans are allowed to donate money. Robots are too digital 🙁') } let amount = req.body.amount if (!amount || amount == 'custom') { amount = req.body['amount-custom'] } if (!amount || amount <= 0) { errors.push('Pledge amount too small. Please choose at least a rupee!') } try { amount = Number(amount) } catch (err) { errors.push('Invalid amount. Please choose a positive number!') } let name = req.body.name if (name.length <=0) { errors.push('What is your name? You can be anonymous to the world but at least we should know...') } let anonymous = req.body.anonymous == 'on' ? true : false let email = req.body.email if (email.length < 5) { errors.push('Please enter a valid email address') } let phone = req.body.phone let newsletter = req.body.newsletter == 'yes' ? true : false let overseas = req.body.overseas == 'yes' ? true : false let messages = req.body.messages if (!!errors.length) { res.send(`Errors: ${'' + errors}`) return } // save the info let pledge = new Pledge() pledge.set('was_robot', robo) pledge.set('amount', amount) pledge.set('overseas', overseas) pledge.set('name', name) pledge.set('anonymous', anonymous) pledge.set('email', email) pledge.set('phone', phone) pledge.set('get_newsletter', newsletter) pledge.set('other_message', messages) if (DEBUG) console.debug (`Saving pledge: ${JSON.stringify(pledge)}`) try { await pledge.save() } catch (err) { res.send("Sorry, something went wrong while saving your pledge and we don't know what 🙁. Please try again...") return } res.send("Thank you! We're still working on setting up this website, so as you can see this page doesn't look great at the moment, but we will be sending you a confirmation email in a few days. Watch out for an email from editors@snipettemag.com, and if it doesn't reach, check your spam box :P") }) router.use(express.static('dist')) // start the listener! app.listen(port, () => { console.log(`Server is up at port ${port}`) }) // end note: in case we want to import this somewhere for testing module.exports = { knex, bookshelf, Pledge, router, }