<commit_before>// ======== DB-Model: ========
// "_id" -> ID
// "title" -> string
// "description" -> string
// start       time the events starts
// end         time the event ends
// "location" -> ...............
// "createdBy" -> userId
// "time_created" -> timestamp
// "time_lastedit" -> timestamp
// "course_id" -> ID_course          (maybe list in Future)
// ===========================

Events = new Meteor.Collection("Events");

mayEditEvent = function(user, event) {
	if (!user) return false;
	if (event.createdBy == user._id) return true;
	if (privileged(user, 'admin')) return true;
	if (event.course_id) {
		var course = Courses.findOne({_id: event.course_id, members: {$elemMatch: { user: user._id, roles: 'team' }}});
		if (course) return true;
	}
	return false;
}

affectedReplicaSelectors = function(event) {
	// Only replicas future from the edited event are updated
	// replicas in the past are never updated
	var futureDate = event.start;
	if (futureDate < new Date) futureDate = new Date;
	
	var selector = {
		_id: { $ne: event._id }, // so the event is not considered to be its own replica
		start: { $gte: futureDate }
	};
	
	var selectors;
	if (event.replicaOf) {
		selector.$or = [
			{ replicaOf: event.replicaOf },
			{ _id: event.replicaOf }
		];
	} else {
		selector.replicaOf = event._id;
	}

	return selector;
}

Meteor.methods({
	saveEvent: function(eventId, changes, updateReplicas) {
		check(eventId, String);
		
		var expectedFields = {
			title:       String,
			description: String,
			location:    String,
			room:        Match.Optional(String),
			start:       Match.Optional(Date),
			end:         Match.Optional(Date),
			files:       Match.Optional(Array),
			mentors:	 Match.Optional(Array),
			host:        Match.Optional(Array),
			replicaOf:   Match.Optional(String),
			course_id:	 Match.Optional(String),
		};
		
		var isNew = eventId === '';
		if (isNew) {
			expectedFields.region = String;
		}

		check(changes, expectedFields);
		
		var user = Meteor.user();
		if (!user) {
			if (Meteor.isClient) {
				pleaseLogin();
				return;
			} else {
				throw new Meteor.Error(401, "please log in");
			}
		}
		
		var now = new Date();
		
		changes.time_lastedit = now;
		
		var event = false;
		if (isNew) {
			changes.time_created = now;
			if (changes.course_id && !mayEditEvent(user, changes)) {
				throw new Meteor.Error(401, "not permitted");
			}		

			if (!changes.start || changes.start < now) {
				throw new Meteor.Error(400, "Event date in the past or not provided");
			}
			
			// Coerce faulty end dates
			if (!changes.end || changes.end < changes.start) {
				changes.end = changes.start;
			}
		} else {
			event = Events.findOne(eventId);
			if (!event) throw new Meteor.Error(404, "No such event");
			if (!mayEditEvent(user, event)) throw new Meteor.Error(401, "not permitted");

			// Not allowed to update
			delete changes.replicaOf;
		}

		// Don't allow moving past events or moving events into the past
		if (!changes.start || changes.start < now) {
			changes.start = event.start;<commit_msg>new events inherit group listing from the course<commit_after>// ======== DB-Model: ========
// "_id" -> ID
// "title" -> string
// "description" -> string
// start       time the events starts
// end         time the event ends
// "location" -> ...............
// "createdBy" -> userId
// "time_created" -> timestamp
// "time_lastedit" -> timestamp
// "course_id" -> ID_course          (maybe list in Future)
// ===========================

Events = new Meteor.Collection("Events");

mayEditEvent = function(user, event) {
	if (!user) return false;
	if (event.createdBy == user._id) return true;
	if (privileged(user, 'admin')) return true;
	if (event.course_id) {
		var course = Courses.findOne({_id: event.course_id, members: {$elemMatch: { user: user._id, roles: 'team' }}});
		if (course) return true;
	}
	return false;
}

affectedReplicaSelectors = function(event) {
	// Only replicas future from the edited event are updated
	// replicas in the past are never updated
	var futureDate = event.start;
	if (futureDate < new Date) futureDate = new Date;
	
	var selector = {
		_id: { $ne: event._id }, // so the event is not considered to be its own replica
		start: { $gte: futureDate }
	};
	
	var selectors;
	if (event.replicaOf) {
		selector.$or = [
			{ replicaOf: event.replicaOf },
			{ _id: event.replicaOf }
		];
	} else {
		selector.replicaOf = event._id;
	}

	return selector;
}

Meteor.methods({
	saveEvent: function(eventId, changes, updateReplicas) {
		check(eventId, String);
		
		var expectedFields = {
			title:       String,
			description: String,
			location:    String,
			room:        Match.Optional(String),
			start:       Match.Optional(Date),
			end:         Match.Optional(Date),
			files:       Match.Optional(Array),
			mentors:	 Match.Optional(Array),
			host:        Match.Optional(Array),
			replicaOf:   Match.Optional(String),
			course_id:	 Match.Optional(String),
		};
		
		var isNew = eventId === '';
		if (isNew) {
			expectedFields.region = String;
		}

		check(changes, expectedFields);
		
		var user = Meteor.user();
		if (!user) {
			if (Meteor.isClient) {
				pleaseLogin();
				return;
			} else {
				throw new Meteor.Error(401, "please log in");
			}
		}
		
		var now = new Date();
		
		changes.time_lastedit = now;
		
		var event = false;
		if (isNew) {
			changes.time_created = now;
			if (changes.course_id && !mayEditEvent(user, changes)) {
				throw new Meteor.Error(401, "not permitted");
			}		

			if (!changes.start || changes.start < now) {
				throw new Meteor.Error(400, "Event date in the past or not provided");
			}

			// Inherit groups from the course
			var course = Courses.findOne(changes.course_id);
			changes.groups = course.groups;

			// Coerce faulty end dates
			if (!changes.end || changes.end < changes.start) {
				changes.end = changes.start;
			}
		} else {
			event = Events.findOne(eventId);
			if (!event) throw new Meteor.Error(404, "No such event");
			if (!mayEditEvent(user, event)) throw new Meteor.Error(401, "not permitted");

			// Not allowed to update
			delete changes.replicaOf;
		}

		// Don't allow moving past events or moving events into the past
		if (!changes.start || changes.start < now) {
			changes.start = event.start;
{'fraction_non_alphanumeric': 0.1529168653632173, 'fraction_numerical': 0.004768717215069146, 'mean_word_length': 2.9473023839397743, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, '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': '3909328', 'n_tokens_mistral': 2341, 'n_tokens_neox': 2010, 'n_words': 566}