<commit_before>var sequelize = require('sequelize');
var url = require('url');
var moment = require('moment');
var marked = require('marked');
var slug = require('slug');

module.exports = function(db) {
	return db.define('event', {
		id: { type: sequelize.INTEGER, primaryKey: true, autoIncrement: true },
		slug: { type: sequelize.TEXT },

		title: {
			type: sequelize.TEXT,
			allowNull: false,
			validate:  {
				notEmpty: true
			}
		},
		location_text: {
			type: sequelize.TEXT,
		},
		blurb: {
			type: sequelize.TEXT,
			allowNull: false,
			validate: {
				notEmpty: true
			}
		},
		type: {
			type: sequelize.TEXT
		},
		cost: {
			type: sequelize.TEXT,
			allowNull: false,
			validate: {
				notEmpty: true
			}
		},
		url: {
			type: sequelize.TEXT,
			get: function() {
				var urlValue = this.getDataValue('url');
				if (urlValue) {
					var urlObj = url.parse(urlValue);
					urlObj.hostNoWww = urlObj.hostname.replace(/^www\./, "");
					urlObj.toString = function() {
						return urlValue;
					}
					return urlObj;
				}
			}
		},
		host: {
			type: sequelize.TEXT,
			validate: {
				notEmpty: true
			}
		},

		startdt: {
			type: sequelize.DATE,
			get: function() { return moment(this.getDataValue('startdt')); },
		},
		enddt: {
			type: sequelize.DATE,
			get: function() {
				var val = this.getDataValue('enddt');
				if (val) {
					var d = moment(val);
					return (d.isValid() ? d : null);
				}
			}
		},
		allday: { type: sequelize.BOOLEAN },

		state: {
			type: sequelize.ENUM,
			values: [ 'submitted', 'approved', 'imported', 'hidden' ]
		},
		email: {
			type: sequelize.TEXT,
			validate:  {
				isEmail: true
			}
		},
		key: { type: sequelize.TEXT },
		importid: { type: sequelize.TEXT },
	}, {
		timestamps: false,
		createdAt: false,
		underscored: true,
		instanceMethods: {
			isImported: function() {
				return this.importid ? true : false;
			},
			blurbAsHTML: function() {
				return marked(this.blurb);
			},
			isMultiDay: function() {
				if (!this.enddt)
					return false;
				return !this.startdt.isSame(this.enddt, 'day');
			},

			shortBlurb: function(readMore) {
				if (readMore === undefined)
					readMore = true;

				// FIXME: This could be done with more finesse
				if (this.blurb.length >= 180)
					return this.blurb.substr(0, 179) + (readMore ? '… <i>(read more)</i>' : '...');
				return this.blurb;
			},

			generateSlug: function() {
				if (!this.getDataValue('slug')) {
					var text = slug(this.getDataValue('title')) + "-" + this.id;
					this.setDataValue('slug', text.toLowerCase());
				}
				return this;
			}
		},
		getterMethods: {
			absolute_url: function() {
				var url = moment(this.getDataValue('startdt')).format('[/]YYYY[/]MM/') + this.getDataValue('slug');
				return '/event'
					+ moment(this.getDataValue('startdt')).format('[/]YYYY[/]MM/')
					+ this.getDataValue('slug');
			},

			shortLocation: function() {
				if (this.location) {
					return this.location.singleLine;
				} else {
					return this.getDataValue('location_text');
				}
			}
		},
		classMethods: {
			groupByDays: function(options, callback) {
				var max,
					Event = this;

				Event.max('enddt').then(function(_max) {
					max = _max;

					Event.findAll(options).then(function(events) {
						// This will look like
						// [ { date: moment, events: [ models.Event(), models.Event(), ... ] }, ... ]
						var ordered = {},
							chunk,
							last,
							ongoing = [],
							list = [],
							one_day_past = moment().subtract(1, 'days');

						for (var d = moment(); d.isBefore(max); d.add(1, 'days')) {
							var chunk = {
								date: d,
								longDate: d.format("dddd, Do MMMM YYYY"),
								events: []
							}

							if (d.diff(moment(), 'days') < 7){
								chunk.shortDate = d.calendar();
							}

							ordered[d.format('YYYY-MM-DD')] = chunk;
						}

						// Group events by date
						events.forEach(function(e) {
							// Add event to current chunk
							if (!e.isMultiDay()
									&& e.startdt.isAfter(one_day_past)) {
								return ordered[e.startdt.format('YYYY-MM-DD')].events.push(e);
							}

							if (e.enddt.diff(e.startdt, 'days') > 7){
								return ongoing.push(e);
							}

							for (var d_ = e.startdt.isBefore(one_day_past) ? moment() : e.startdt;
									d_.isBefore(max);
									d_.add(1, 'days')) {
								ordered[d_.format('YYYY-MM-DD')].events.push(e);
							}
						});

						for (var key in ordered) {
							if (ordered[key].events.length > 0)
								list.push(ordered[key]);
						}

						list.push({
							longDate: 'Ongoing',
							events: ongoing,<commit_msg>Stop multiday events repeating endlessly<commit_after>var sequelize = require('sequelize');
var url = require('url');
var moment = require('moment');
var marked = require('marked');
var slug = require('slug');

module.exports = function(db) {
	return db.define('event', {
		id: { type: sequelize.INTEGER, primaryKey: true, autoIncrement: true },
		slug: { type: sequelize.TEXT },

		title: {
			type: sequelize.TEXT,
			allowNull: false,
			validate:  {
				notEmpty: true
			}
		},
		location_text: {
			type: sequelize.TEXT,
		},
		blurb: {
			type: sequelize.TEXT,
			allowNull: false,
			validate: {
				notEmpty: true
			}
		},
		type: {
			type: sequelize.TEXT
		},
		cost: {
			type: sequelize.TEXT,
			allowNull: false,
			validate: {
				notEmpty: true
			}
		},
		url: {
			type: sequelize.TEXT,
			get: function() {
				var urlValue = this.getDataValue('url');
				if (urlValue) {
					var urlObj = url.parse(urlValue);
					urlObj.hostNoWww = urlObj.hostname.replace(/^www\./, "");
					urlObj.toString = function() {
						return urlValue;
					}
					return urlObj;
				}
			}
		},
		host: {
			type: sequelize.TEXT,
			validate: {
				notEmpty: true
			}
		},

		startdt: {
			type: sequelize.DATE,
			get: function() { return moment(this.getDataValue('startdt')); },
		},
		enddt: {
			type: sequelize.DATE,
			get: function() {
				var val = this.getDataValue('enddt');
				if (val) {
					var d = moment(val);
					return (d.isValid() ? d : null);
				}
			}
		},
		allday: { type: sequelize.BOOLEAN },

		state: {
			type: sequelize.ENUM,
			values: [ 'submitted', 'approved', 'imported', 'hidden' ]
		},
		email: {
			type: sequelize.TEXT,
			validate:  {
				isEmail: true
			}
		},
		key: { type: sequelize.TEXT },
		importid: { type: sequelize.TEXT },
	}, {
		timestamps: false,
		createdAt: false,
		underscored: true,
		instanceMethods: {
			isImported: function() {
				return this.importid ? true : false;
			},
			blurbAsHTML: function() {
				return marked(this.blurb);
			},
			isMultiDay: function() {
				if (!this.enddt)
					return false;
				return !this.startdt.isSame(this.enddt, 'day');
			},

			shortBlurb: function(readMore) {
				if (readMore === undefined)
					readMore = true;

				// FIXME: This could be done with more finesse
				if (this.blurb.length >= 180)
					return this.blurb.substr(0, 179) + (readMore ? '… <i>(read more)</i>' : '...');
				return this.blurb;
			},

			generateSlug: function() {
				if (!this.getDataValue('slug')) {
					var text = slug(this.getDataValue('title')) + "-" + this.id;
					this.setDataValue('slug', text.toLowerCase());
				}
				return this;
			}
		},
		getterMethods: {
			absolute_url: function() {
				var url = moment(this.getDataValue('startdt')).format('[/]YYYY[/]MM/') + this.getDataValue('slug');
				return '/event'
					+ moment(this.getDataValue('startdt')).format('[/]YYYY[/]MM/')
					+ this.getDataValue('slug');
			},

			shortLocation: function() {
				if (this.location) {
					return this.location.singleLine;
				} else {
					return this.getDataValue('location_text');
				}
			}
		},
		classMethods: {
			groupByDays: function(options, callback) {
				var max,
					Event = this;

				Event.max('enddt').then(function(_max) {
					max = _max;

					Event.findAll(options).then(function(events) {
						// This will look like
						// [ { date: moment, events: [ models.Event(), models.Event(), ... ] }, ... ]
						var ordered = {},
							chunk,
							last,
							ongoing = [],
							list = [],
							one_day_past = moment().subtract(1, 'days');

						for (var d = moment(); d.isBefore(max); d.add(1, 'days')) {
							var chunk = {
								date: d,
								longDate: d.format("dddd, Do MMMM YYYY"),
								events: []
							}

							if (d.diff(moment(), 'days') < 7){
								chunk.shortDate = d.calendar();
							}

							ordered[d.format('YYYY-MM-DD')] = chunk;
						}

						// Group events by date
						events.forEach(function(e) {
							// Add event to current chunk
							if (!e.isMultiDay()
									&& e.startdt.isAfter(one_day_past)) {
								return ordered[e.startdt.format('YYYY-MM-DD')].events.push(e);
							}

							if (e.enddt.diff(e.startdt, 'days') > 7){
								return ongoing.push(e);
							}

							for (var d_ = e.startdt.isBefore(one_day_past) ? moment() : e.startdt;
									d_.isBefore(e.enddt);
									d_.add(1, 'days')) {
								ordered[d_.format('YYYY-MM-DD')].events.push(e);
							}
						});

						for (var key in ordered) {
							if (ordered[key].events.length > 0)
								list.push(ordered[key]);
						}

						list.push({
							longDate: 'Ongoing',
							events: ongoing,
{'fraction_non_alphanumeric': 0.16898823021272, 'fraction_numerical': 0.002807472195227297, 'mean_word_length': 2.410162002945508, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5346787', 'n_tokens_mistral': 4381, 'n_tokens_neox': 3239, 'n_words': 639}