<commit_before>'use strict';

var express = require('express');
var router = express.Router();

var models = require('../models');

var ical = require('ical-generator');
var moment = require('moment');

router.get('/', function(req, res) {
	res.send('try .../json or .../ical');
});

function parseOpts(req) {
	const dateFormat = 'YYYY-MM-DD';

	let start = moment(req.query.start, dateFormat);
	if (!start.isValid()) {
		start.set(new Date());
	}

	let end = moment(req.query.end, dateFormat);
	if (!end.isValid()) {
		end.set(new Date()).add(3, 'months');
	}

	return [
		'state="approved"',
		'startdt >= date("' + start.format(dateFormat) + '", "localtime")',
		'startdt <= date("' + end.format(dateFormat) + '", "localtime")'
	];
}

router.get('/json', function(req, res) {
	const clauses = parseOpts(req);

	// This particular kind of JSON output is designed to be suitable input
	// to FullCalendar.

	models.Event.findAll({
		where: [ clauses.join(' AND '), [] ],
		attributes: [ 'id', 'title', 'startdt', 'enddt' ],
		order: 'startdt ASC',
	}).then(function(events) {
		let data = events.map(e =>
			({ id: e.id, title: e.title, start: e.startdt, end: e.enddt })
		);

		req.header('Content-Type', 'application/json');
		res.send(JSON.stringify(data, ' '));
	}).catch(function(err) {
		res.status(500).end();
	});
});

router.get('/json/locations', function(req, res) {
	models.Location.findAll(
		{ attributes: [ 'id', 'name', 'address' ]
	}).then(function(locations) {
		req.header('Content-Type', 'application/json');

		for (let location of locations) {
			// FIXME: Maybe do this client-side
			location.address = location.address.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1, ');
		}

		res.send(JSON.stringify(locations, null, ' '));
	}).catch(function(err) {
		res.status(500).end();
	});
});

function generateCalendar(events) {
	let cal = ical({
		domain: 'echomanchester.net',
		name: '<NAME>',
		timezone: 'Europe/London',
		prodId: {
			company: 'Chamber Products',
			product: 'Echo',
			language: 'EN'
		},
		ttl: 60 * 60 * 12
	});

	for (let evt of events) {
		cal.createEvent({
			uid: evt.id,
			timezone: 'Europe/London',
			start: evt.startdt.toDate(),
			end: evt.enddt ? evt.enddt.toDate() : undefined,
			allDay: evt.allday,
			summary: evt.title,
			description: evt.blurb,
			location: evt.location,
			url: evt.url || undefined,
		});
	}

	return cal;
}

router.get('/ical', function(req, res) {
	const clauses = parseOpts(req);

	models.Event.findAll({
		where: [ clauses.join(' AND '), [] ],
		attributes: [ 'id', 'title', 'startdt', 'enddt', 'location_text', 'blurb', 'url', 'host' ],
		order: 'startdt ASC',
	}).then(function(events) {
		let cal = generateCalendar(events);
		cal.serve(res);
	}).catch(function(err) {
		res.status(500).end();
	});
});

module.exports = router;<commit_msg>Clean up clause formation in API route<commit_after>'use strict';

var express = require('express');
var router = express.Router();

var models = require('../models');
var Sequelize = models.db;

var ical = require('ical-generator');
var moment = require('moment');

router.get('/', function(req, res) {
	res.send('try .../json or .../ical');
});

function parseOpts(req) {
	const dateFormat = 'YYYY-MM-DD';

	let start = moment(req.query.start, dateFormat);
	if (!start.isValid()) {
		start.set(new Date());
	}

	let end = moment(req.query.end, dateFormat);
	if (!end.isValid()) {
		end.set(new Date()).add(3, 'months');
	}

	return {
		state: 'approved',
		startdt: {
			$gte: Sequelize.fn('date', start.format(dateFormat), 'localtime'),
			$lte: Sequelize.fn('date', end.format(dateFormat), 'localtime'),
		}
	}
}

router.get('/json', function(req, res) {
	const clauses = parseOpts(req);

	// This particular kind of JSON output is designed to be suitable input
	// to FullCalendar.

	models.Event.findAll({
		where: clauses,
		attributes: [ 'id', 'title', 'startdt', 'enddt' ],
		order: 'startdt ASC',
	}).then(function(events) {
		let data = events.map(e =>
			({ id: e.id, title: e.title, start: e.startdt, end: e.enddt })
		);

		req.header('Content-Type', 'application/json');
		res.send(JSON.stringify(data, ' '));
	}).catch(function(err) {
		res.status(500).end();
	});
});

router.get('/json/locations', function(req, res) {
	models.Location.findAll(
		{ attributes: [ 'id', 'name', 'address' ]
	}).then(function(locations) {
		req.header('Content-Type', 'application/json');

		for (let location of locations) {
			// FIXME: Maybe do this client-side
			location.address = location.address.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1, ');
		}

		res.send(JSON.stringify(locations, null, ' '));
	}).catch(function(err) {
		res.status(500).end();
	});
});

function generateCalendar(events) {
	let cal = ical({
		domain: 'echomanchester.net',
		name: '<NAME>',
		timezone: 'Europe/London',
		prodId: {
			company: 'Chamber Products',
			product: 'Echo',
			language: 'EN'
		},
		ttl: 60 * 60 * 12
	});

	for (let evt of events) {
		cal.createEvent({
			uid: evt.id,
			timezone: 'Europe/London',
			start: evt.startdt.toDate(),
			end: evt.enddt ? evt.enddt.toDate() : undefined,
			allDay: evt.allday,
			summary: evt.title,
			description: evt.blurb,
			location: evt.location,
			url: evt.url || undefined,
		});
	}

	return cal;
}

router.get('/ical', function(req, res) {
	const clauses = parseOpts(req);

	models.Event.findAll({
		where: clauses,
		attributes: [ 'id', 'title', 'startdt', 'enddt', 'location_text', 'blurb', 'url', 'host' ],
		order: 'startdt ASC',
	}).then(function(events) {
		let cal = generateCalendar(events);
		cal.serve(res);
	}).catch(function(err) {
		res.status(500).end();
	});
});

module.exports = router;
{'fraction_non_alphanumeric': 0.20880281690140845, 'fraction_numerical': 0.005985915492957746, 'mean_word_length': 3.9058721934369602, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2586214', 'n_tokens_mistral': 2226, 'n_tokens_neox': 2064, 'n_words': 440}