mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
95
RIGS/ical.py
95
RIGS/ical.py
@@ -17,15 +17,58 @@ class CalendarICS(ICalFeed):
|
||||
timezone = settings.TIME_ZONE
|
||||
file_name = "rigs.ics"
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
timezone.activate(timezone.UTC)
|
||||
return super(CalendarICS, self).get(*args, **kwargs)
|
||||
# Cancelled = 'cancelled' = False
|
||||
# Dry Hire = 'dry-hire' = True
|
||||
# Non Rig = 'non-rig' = True
|
||||
# Rig = 'rig' = True
|
||||
# Provisional = 'provisional' = True
|
||||
# Confirmed/Booked = 'confirmed' = True
|
||||
|
||||
def get_object(self, request, *args, **kwargs):
|
||||
params = {}
|
||||
|
||||
def items(self):
|
||||
params['dry-hire'] = request.GET.get('dry-hire','true') == 'true'
|
||||
params['non-rig'] = request.GET.get('non-rig','true') == 'true'
|
||||
params['rig'] = request.GET.get('rig','true') == 'true'
|
||||
|
||||
params['cancelled'] = request.GET.get('cancelled','false') == 'true'
|
||||
params['provisional'] = request.GET.get('provisional','true') == 'true'
|
||||
params['confirmed'] = request.GET.get('confirmed','true') == 'true'
|
||||
|
||||
return params
|
||||
|
||||
def description(self,params):
|
||||
desc = "Calendar generated by RIGS system. This includes event types: " + ('Rig, ' if params['rig'] else '') + ('Non-rig, ' if params['non-rig'] else '') + ('Dry Hire ' if params['dry-hire'] else '') + '\n'
|
||||
desc = desc + "Includes events with status: " + ('Cancelled, ' if params['cancelled'] else '') + ('Provisional, ' if params['provisional'] else '') + ('Confirmed/Booked, ' if params['confirmed'] else '')
|
||||
|
||||
return desc
|
||||
|
||||
def items(self, params):
|
||||
#include events from up to 1 year ago
|
||||
start = datetime.datetime.now() - datetime.timedelta(days=365)
|
||||
filter = Q(start_date__gte=start) & ~Q(status=models.Event.CANCELLED)
|
||||
filter = Q(start_date__gte=start)
|
||||
|
||||
typeFilters = Q(pk=None) #Need something that is false for every entry
|
||||
|
||||
if params['dry-hire']:
|
||||
typeFilters = typeFilters | Q(dry_hire=True, is_rig=True)
|
||||
|
||||
if params['non-rig']:
|
||||
typeFilters = typeFilters | Q(is_rig=False)
|
||||
|
||||
if params['rig']:
|
||||
typeFilters = typeFilters | Q(is_rig=True, dry_hire=False)
|
||||
|
||||
statusFilters = Q(pk=None) #Need something that is false for every entry
|
||||
|
||||
if params['cancelled']:
|
||||
statusFilters = statusFilters | Q(status=models.Event.CANCELLED)
|
||||
if params['provisional']:
|
||||
statusFilters = statusFilters | Q(status=models.Event.PROVISIONAL)
|
||||
if params['confirmed']:
|
||||
statusFilters = statusFilters | Q(status=models.Event.CONFIRMED) | Q(status=models.Event.BOOKED)
|
||||
|
||||
filter = filter & typeFilters & statusFilters
|
||||
|
||||
return models.Event.objects.filter(filter).order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
|
||||
|
||||
@@ -51,38 +94,10 @@ class CalendarICS(ICalFeed):
|
||||
return title
|
||||
|
||||
def item_start_datetime(self, item):
|
||||
#set start date to the earliest defined time for the event
|
||||
if item.meet_at:
|
||||
startDateTime = item.meet_at
|
||||
elif item.access_at:
|
||||
startDateTime = item.access_at
|
||||
elif item.has_start_time:
|
||||
startDateTime = datetime.datetime.combine(item.start_date,item.start_time)
|
||||
tz = pytz.timezone(settings.TIME_ZONE)
|
||||
startDateTime = tz.normalize(tz.localize(startDateTime)).astimezone(pytz.timezone(self.timezone))
|
||||
else:
|
||||
startDateTime = item.start_date
|
||||
|
||||
return startDateTime
|
||||
return item.earliest_time
|
||||
|
||||
def item_end_datetime(self, item):
|
||||
# Assume end is same as start
|
||||
endDateTime = item.start_date
|
||||
|
||||
# If end date defined then use it
|
||||
if item.end_date:
|
||||
endDateTime = item.end_date
|
||||
|
||||
if item.has_start_time and item.has_end_time: # don't allow an event with specific end but no specific start
|
||||
endDateTime = datetime.datetime.combine(endDateTime,item.end_time)
|
||||
tz = pytz.timezone(settings.TIME_ZONE)
|
||||
endDateTime = tz.normalize(tz.localize(endDateTime)).astimezone(pytz.timezone(self.timezone))
|
||||
elif item.has_end_time: # if there's a start time specified then an end time should also be specified
|
||||
endDateTime = datetime.datetime.combine(endDateTime+datetime.timedelta(days=1),datetime.time(00, 00))
|
||||
#elif item.end_time: # end time but no start time - this is weird - don't think ICS will like it so ignoring
|
||||
# do nothing
|
||||
|
||||
return endDateTime
|
||||
return item.latest_time
|
||||
|
||||
def item_location(self,item):
|
||||
return item.venue
|
||||
@@ -91,6 +106,8 @@ class CalendarICS(ICalFeed):
|
||||
# Create a nice information-rich description
|
||||
# note: only making use of information available to "non-keyholders"
|
||||
|
||||
tz = pytz.timezone(self.timezone)
|
||||
|
||||
desc = 'Rig ID = '+str(item.pk)+'\n'
|
||||
desc += 'Event = ' + item.name + '\n'
|
||||
desc += 'Venue = ' + (item.venue.name if item.venue else '---') + '\n'
|
||||
@@ -102,9 +119,9 @@ class CalendarICS(ICalFeed):
|
||||
|
||||
desc += '\n'
|
||||
if item.meet_at:
|
||||
desc += 'Crew Meet = ' + (item.meet_at.strftime('%Y-%m-%d %H:%M') if item.meet_at else '---') + '\n'
|
||||
desc += 'Crew Meet = ' + (item.meet_at.astimezone(tz).strftime('%Y-%m-%d %H:%M') if item.meet_at else '---') + '\n'
|
||||
if item.access_at:
|
||||
desc += 'Access At = ' + item.access_at.strftime('%Y-%m-%d %H:%M') + '\n'
|
||||
desc += 'Access At = ' + (item.access_at.astimezone(tz).strftime('%Y-%m-%d %H:%M') if item.access_at else '---') + '\n'
|
||||
if item.start_date:
|
||||
desc += 'Event Start = ' + item.start_date.strftime('%Y-%m-%d') + ((' '+item.start_time.strftime('%H:%M')) if item.has_start_time else '') + '\n'
|
||||
if item.end_date:
|
||||
@@ -113,8 +130,8 @@ class CalendarICS(ICalFeed):
|
||||
desc += '\n'
|
||||
if item.description:
|
||||
desc += 'Event Description:\n'+item.description+'\n\n'
|
||||
if item.notes:
|
||||
desc += 'Notes:\n'+item.notes+'\n\n'
|
||||
# if item.notes: // Need to add proper keyholder checks before this gets put back
|
||||
# desc += 'Notes:\n'+item.notes+'\n\n'
|
||||
|
||||
base_url = "http://rigs.nottinghamtec.co.uk"
|
||||
desc += 'URL = '+base_url+str(item.get_absolute_url())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import hashlib
|
||||
import datetime
|
||||
import datetime, pytz
|
||||
|
||||
from django.db import models, connection
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
@@ -239,7 +239,14 @@ class EventManager(models.Manager):
|
||||
(models.Q(start_date__gte=start.date(), start_date__lte=end.date())) | # Start date in bounds
|
||||
(models.Q(end_date__gte=start.date(), end_date__lte=end.date())) | # End date in bounds
|
||||
(models.Q(access_at__gte=start, access_at__lte=end)) | # Access at in bounds
|
||||
(models.Q(meet_at__gte=start, meet_at__lte=end)) # Meet at in bounds
|
||||
(models.Q(meet_at__gte=start, meet_at__lte=end)) | # Meet at in bounds
|
||||
|
||||
(models.Q(start_date__lte=start, end_date__gte=end)) | # Start before, end after
|
||||
(models.Q(access_at__lte=start, start_date__gte=end)) | # Access before, start after
|
||||
(models.Q(access_at__lte=start, end_date__gte=end)) | # Access before, end after
|
||||
(models.Q(meet_at__lte=start, start_date__gte=end)) | # Meet before, start after
|
||||
(models.Q(meet_at__lte=start, end_date__gte=end)) # Meet before, end after
|
||||
|
||||
).order_by('start_date', 'end_date', 'start_time', 'end_time', 'meet_at').select_related('person', 'organisation', 'venue', 'mic')
|
||||
return events
|
||||
|
||||
@@ -359,6 +366,59 @@ class Event(models.Model, RevisionMixin):
|
||||
def has_end_time(self):
|
||||
return self.end_time is not None
|
||||
|
||||
@property
|
||||
def earliest_time(self):
|
||||
"""Finds the earliest time defined in the event - this function could return either a tzaware datetime, or a naiive date object"""
|
||||
|
||||
#Put all the datetimes in a list
|
||||
datetime_list = []
|
||||
|
||||
if self.access_at:
|
||||
datetime_list.append(self.access_at)
|
||||
|
||||
if self.meet_at:
|
||||
datetime_list.append(self.meet_at)
|
||||
|
||||
# If there is no start time defined, pretend it's midnight
|
||||
startTimeFaked = False
|
||||
if self.has_start_time:
|
||||
startDateTime = datetime.datetime.combine(self.start_date,self.start_time)
|
||||
else:
|
||||
startDateTime = datetime.datetime.combine(self.start_date,datetime.time(00,00))
|
||||
startTimeFaked = True
|
||||
|
||||
#timezoneIssues - apply the default timezone to the naiive datetime
|
||||
tz = pytz.timezone(settings.TIME_ZONE)
|
||||
startDateTime = tz.localize(startDateTime)
|
||||
datetime_list.append(startDateTime) # then add it to the list
|
||||
|
||||
earliest = min(datetime_list).astimezone(tz) #find the earliest datetime in the list
|
||||
|
||||
# if we faked it & it's the earliest, better own up
|
||||
if startTimeFaked and earliest==startDateTime:
|
||||
return self.start_date
|
||||
|
||||
return earliest
|
||||
|
||||
@property
|
||||
def latest_time(self):
|
||||
"""Returns the end of the event - this function could return either a tzaware datetime, or a naiive date object"""
|
||||
tz = pytz.timezone(settings.TIME_ZONE)
|
||||
endDate = self.end_date
|
||||
if endDate is None:
|
||||
endDate = self.start_date
|
||||
|
||||
if self.has_end_time:
|
||||
endDateTime = datetime.datetime.combine(endDate,self.end_time)
|
||||
tz = pytz.timezone(settings.TIME_ZONE)
|
||||
endDateTime = tz.localize(endDateTime)
|
||||
|
||||
return endDateTime
|
||||
|
||||
else:
|
||||
return endDate
|
||||
|
||||
|
||||
objects = EventManager()
|
||||
|
||||
def get_absolute_url(self):
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
$('#calendar').fullCalendar({
|
||||
//defaultDate: '2015-02-12',
|
||||
editable: false,
|
||||
eventLimit: true, // allow "more" link when too many events
|
||||
firstDay: 1,
|
||||
@@ -37,75 +36,156 @@
|
||||
// options apply to basicDay and agendaDay views
|
||||
}
|
||||
},
|
||||
buttonText:{
|
||||
today: 'Today',
|
||||
month: 'Month',
|
||||
week: 'Week',
|
||||
day: 'Day'
|
||||
},
|
||||
header:{
|
||||
left: 'title',
|
||||
center: '',
|
||||
right: 'today prev,next month,agendaWeek,agendaDay'
|
||||
},
|
||||
header:false,
|
||||
|
||||
events: function(start_moment, end_moment, timezone, callback) {
|
||||
|
||||
$.ajax({
|
||||
url: '/api/event',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
start: moment(start_moment).format("YYYY-MM-DD[T]HH:mm:ss[Z]"),
|
||||
end: moment(end_moment).format("YYYY-MM-DD[T]HH:mm:ss[Z]")
|
||||
start: moment(start_moment).format("YYYY-MM-DD[T]HH:mm:ss"),
|
||||
end: moment(end_moment).format("YYYY-MM-DD[T]HH:mm:ss")
|
||||
},
|
||||
success: function(doc) {
|
||||
var events = [];
|
||||
var colours =
|
||||
colours = {'Provisional': '#f0ad4e',
|
||||
'Confirmed': '#5cb85c' ,
|
||||
'Booked': '#5cb85c' ,
|
||||
'Cancelled': 'grey' ,
|
||||
'non-rig': '#5bc0de'
|
||||
};
|
||||
$(doc).each(function() {
|
||||
thisEvent = [];
|
||||
colours = {'Provisional': 'orange',
|
||||
'Confirmed': 'green' ,
|
||||
'Booked': 'green' ,
|
||||
'Cancelled': 'grey'
|
||||
};
|
||||
|
||||
thisEvent['start'] = $(this).attr('start_date');
|
||||
if ($(this).attr('start_time')) {
|
||||
thisEvent['start'] += 'T' + $(this).attr('start_time');
|
||||
|
||||
}
|
||||
|
||||
if ($(this).attr('end_date')) {
|
||||
thisEvent['end'] = $(this).attr('end_date');
|
||||
if ($(this).attr('end_time')) {
|
||||
thisEvent['end'] += 'T' + $(this).attr('end_time');
|
||||
}
|
||||
}
|
||||
thisEvent['className'] = 'modal-href';
|
||||
|
||||
thisEvent['title'] = $(this).attr('title');
|
||||
|
||||
thisEvent['color'] = colours[$(this).attr('status')];
|
||||
|
||||
thisEvent['url'] = $(this).attr('url');
|
||||
thisEvent = {
|
||||
'start': $(this).attr('earliest'),
|
||||
'end': $(this).attr('latest'),
|
||||
'className': 'modal-href',
|
||||
'title': $(this).attr('title'),
|
||||
'url': $(this).attr('url')
|
||||
}
|
||||
|
||||
if($(this).attr('is_rig')==true || $(this).attr('status') == "Cancelled"){
|
||||
thisEvent['color'] = colours[$(this).attr('status')];
|
||||
}else{
|
||||
thisEvent['color'] = colours['non-rig'];
|
||||
}
|
||||
|
||||
events.push(thisEvent);
|
||||
});
|
||||
callback(events);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
viewRender: function(view, element){
|
||||
// Set the title of the view
|
||||
$('#calendar-header').text(view.title);
|
||||
|
||||
// Enable/Disable "Today" button as required
|
||||
if(moment().isBetween(view.intervalStart, view.intervalEnd)){
|
||||
//Today is within the current view
|
||||
$('#today-button').prop('disabled', true);
|
||||
}else{
|
||||
$('#today-button').prop('disabled', false);
|
||||
}
|
||||
|
||||
// Set active view select button
|
||||
switch(view.name){
|
||||
case 'month':
|
||||
$('#month-button').addClass('active');
|
||||
$('#week-button').removeClass('active');
|
||||
$('#day-button').removeClass('active');
|
||||
break;
|
||||
|
||||
case 'agendaWeek':
|
||||
$('#month-button').removeClass('active');
|
||||
$('#week-button').addClass('active');
|
||||
$('#day-button').removeClass('active');
|
||||
break;
|
||||
|
||||
case 'agendaDay':
|
||||
$('#month-button').removeClass('active');
|
||||
$('#week-button').removeClass('active');
|
||||
$('#day-button').addClass('active');
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// set some button listeners
|
||||
|
||||
$('#next-button').click(function(){ $('#calendar').fullCalendar('next') });
|
||||
$('#prev-button').click(function(){ $('#calendar').fullCalendar('prev') });
|
||||
$('#today-button').click(function(){ $('#calendar').fullCalendar('today') });
|
||||
|
||||
$('#month-button').click(function(){ $('#calendar').fullCalendar('changeView','month') });
|
||||
$('#week-button').click(function(){ $('#calendar').fullCalendar('changeView','agendaWeek') });
|
||||
$('#day-button').click(function(){ $('#calendar').fullCalendar('changeView','agendaDay') });
|
||||
|
||||
$('#go-to-date-input').change(function(){
|
||||
if( moment($('#go-to-date-input').val()).isValid() ){
|
||||
$('#go-to-date-button').prop('disabled', false);
|
||||
}else{
|
||||
$('#go-to-date-button').prop('disabled', true);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('#go-to-date-button').click(function(){
|
||||
day = moment($('#go-to-date-input').val()) ;
|
||||
if(day.isValid()){
|
||||
$('#calendar').fullCalendar( 'gotoDate', day);
|
||||
}else{
|
||||
alert('Invalid Date');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div style="col-sm-12">
|
||||
<div id='calendar'>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<div class="pull-left">
|
||||
<span id="calendar-header" class="h2"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-inline pull-right btn-page">
|
||||
<div class="input-group">
|
||||
<input type="date" class="form-control" id="go-to-date-input" placeholder="Go to date...">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" id="go-to-date-button" type="button" disabled>Go!</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary" id="today-button">Today</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default" id="prev-button"><span class="glyphicon glyphicon-chevron-left"></span></button>
|
||||
<button type="button" class="btn btn-default" id="next-button"><span class="glyphicon glyphicon-chevron-right"></span></button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default" id="month-button">Month</button>
|
||||
<button type="button" class="btn btn-default" id="week-button">Week</button>
|
||||
<button type="button" class="btn btn-default" id="day-button">Day</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div id='calendar'>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -2,6 +2,33 @@
|
||||
|
||||
{% block title %}RIGS Profile {{object.pk}}{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#urlParamForm').change(function(){
|
||||
url = "?";
|
||||
$('#urlParamForm *').filter(':input').each(function(index, value){
|
||||
defaultVal = $(value).data('default');
|
||||
param = $(value).val();
|
||||
val = $(value).prop('checked');
|
||||
|
||||
if(val != defaultVal){
|
||||
url = url+param+"="+val+"&";
|
||||
}
|
||||
});
|
||||
ics_url = $('#cal-url').data('url') + url.substring(0, url.length - 1);
|
||||
$('#cal-url').text(ics_url);
|
||||
|
||||
gcal_url = $('#gcal-link').data('url') + encodeURIComponent(url.substring(0, url.length - 1));
|
||||
$('#gcal-link').attr('href',gcal_url);
|
||||
});
|
||||
|
||||
$('#urlParamForm').change(); //Do the initial setting
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
@@ -68,16 +95,42 @@
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>Calendar Options</dt>
|
||||
<dd>
|
||||
<div class="well well-sm text-center">
|
||||
<form class="form-inline" id="urlParamForm">
|
||||
<div class="form-group">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="rig" data-default="true" checked> Rigs
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="non-rig" data-default="true" checked> Non-Rigs
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="dry-hire" data-default="true" checked> Dry-Hires
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="cancelled" data-default="false" > Cancelled
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="provisional" data-default="true" checked> Provisional
|
||||
</label>
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" value="confirmed" data-default="true" checked> Confirmed/Booked
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</dd>
|
||||
<dt>Calendar URL</dt>
|
||||
<dd>
|
||||
{% if user.api_key %}
|
||||
<pre>http{{ request.is_secure|yesno:"s,"}}://{{ request.get_host }}{% url 'ics_calendar' api_pk=user.pk api_key=user.api_key %}</pre>
|
||||
<small><a href="http://www.google.com/calendar/render?cid=http{{ request.is_secure|yesno:"s,"}}://{{ request.get_host }}{% url 'ics_calendar' api_pk=user.pk api_key=user.api_key %}">Click here</a> to add to google calendar.<br/>
|
||||
<pre id="cal-url" data-url="http{{ request.is_secure|yesno:"s,"}}://{{ request.get_host }}{% url 'ics_calendar' api_pk=user.pk api_key=user.api_key %}"></pre>
|
||||
<small><a id="gcal-link" data-url="http://www.google.com/calendar/render?cid=http{{ request.is_secure|yesno:"s,"}}://{{ request.get_host }}{% url 'ics_calendar' api_pk=user.pk api_key=user.api_key %}" href="">Click here</a> to add to google calendar.<br/>
|
||||
To sync from google calendar to mobile device, visit <a href="https://www.google.com/calendar/syncselect" target="_blank">this page</a> on your device and tick "RIGS Calendar".</small>
|
||||
{% else %}
|
||||
<pre>No API Key Generated</pre>
|
||||
{% endif %}
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.test import LiveServerTestCase
|
||||
from django.test.client import Client
|
||||
from django.core import mail
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
@@ -8,6 +9,7 @@ from selenium.webdriver.support.ui import WebDriverWait
|
||||
from RIGS import models
|
||||
import re
|
||||
import os
|
||||
from datetime import date, timedelta
|
||||
from django.db import transaction
|
||||
import reversion
|
||||
import json
|
||||
@@ -576,6 +578,195 @@ class EventTest(LiveServerTestCase):
|
||||
|
||||
organisationPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Contact Details")]/..')
|
||||
|
||||
class IcalTest(LiveServerTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.all_events = set(range(1, 18))
|
||||
self.current_events = (1, 2, 3, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18)
|
||||
self.not_current_events = set(self.all_events) - set(self.current_events)
|
||||
|
||||
self.vatrate = models.VatRate.objects.create(start_at='2014-03-05',rate=0.20,comment='test1')
|
||||
self.profile = models.Profile(
|
||||
username="EventTest", first_name="Event", last_name="Test", initials="ETU", is_superuser=True)
|
||||
self.profile.set_password("EventTestPassword")
|
||||
self.profile.save()
|
||||
|
||||
# produce 7 normal events - 5 current - 1 last week - 1 two years ago - 2 provisional - 2 confirmed - 3 booked
|
||||
models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL, start_date=date.today() + timedelta(days=6), description="start future no end")
|
||||
models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL, start_date=date.today(), description="start today no end")
|
||||
models.Event.objects.create(name="TE E3", status=models.Event.CONFIRMED, start_date=date.today(), end_date=date.today(), description="start today with end today")
|
||||
models.Event.objects.create(name="TE E4", status=models.Event.CONFIRMED, start_date=date.today()-timedelta(weeks=104), description="start past 2 years no end")
|
||||
models.Event.objects.create(name="TE E5", status=models.Event.BOOKED, start_date=date.today()-timedelta(days=7), end_date=date.today()-timedelta(days=1), description="start past 1 week with end past")
|
||||
models.Event.objects.create(name="TE E6", status=models.Event.BOOKED, start_date=date.today()-timedelta(days=2), end_date=date.today()+timedelta(days=2), description="start past, end future")
|
||||
models.Event.objects.create(name="TE E7", status=models.Event.BOOKED, start_date=date.today()+timedelta(days=2), end_date=date.today()+timedelta(days=2), description="start + end in future")
|
||||
|
||||
# 2 cancelled - 1 current
|
||||
models.Event.objects.create(name="TE E8", start_date=date.today()+timedelta(days=2), end_date=date.today()+timedelta(days=2), status=models.Event.CANCELLED, description="cancelled in future")
|
||||
models.Event.objects.create(name="TE E9", start_date=date.today()-timedelta(days=1), end_date=date.today()+timedelta(days=2), status=models.Event.CANCELLED, description="cancelled and started")
|
||||
|
||||
# 5 dry hire - 3 current - 1 cancelled
|
||||
models.Event.objects.create(name="TE E10", start_date=date.today(), dry_hire=True, description="dryhire today")
|
||||
models.Event.objects.create(name="TE E11", start_date=date.today(), dry_hire=True, checked_in_by=self.profile, description="dryhire today, checked in")
|
||||
models.Event.objects.create(name="TE E12", start_date=date.today()-timedelta(days=1), dry_hire=True, status=models.Event.BOOKED, description="dryhire past")
|
||||
models.Event.objects.create(name="TE E13", start_date=date.today()-timedelta(days=2), dry_hire=True, checked_in_by=self.profile, description="dryhire past checked in")
|
||||
models.Event.objects.create(name="TE E14", start_date=date.today(), dry_hire=True, status=models.Event.CANCELLED, description="dryhire today cancelled")
|
||||
|
||||
# 4 non rig - 3 current
|
||||
models.Event.objects.create(name="TE E15", start_date=date.today(), is_rig=False, description="non rig today")
|
||||
models.Event.objects.create(name="TE E16", start_date=date.today()+timedelta(days=1), is_rig=False, description="non rig tomorrow")
|
||||
models.Event.objects.create(name="TE E17", start_date=date.today()-timedelta(days=1), is_rig=False, description="non rig yesterday")
|
||||
models.Event.objects.create(name="TE E18", start_date=date.today(), is_rig=False, status=models.Event.CANCELLED, description="non rig today cancelled")
|
||||
|
||||
self.browser = webdriver.Firefox()
|
||||
os.environ['RECAPTCHA_TESTING'] = 'True'
|
||||
|
||||
def tearDown(self):
|
||||
self.browser.quit()
|
||||
os.environ['RECAPTCHA_TESTING'] = 'False'
|
||||
|
||||
def authenticate(self, n=None):
|
||||
self.assertIn(
|
||||
self.live_server_url + '/user/login/', self.browser.current_url)
|
||||
if n:
|
||||
self.assertIn('?next=%s' % n, self.browser.current_url)
|
||||
username = self.browser.find_element_by_id('id_username')
|
||||
password = self.browser.find_element_by_id('id_password')
|
||||
submit = self.browser.find_element_by_css_selector(
|
||||
'input[type=submit]')
|
||||
|
||||
username.send_keys("EventTest")
|
||||
password.send_keys("EventTestPassword")
|
||||
self.browser.execute_script(
|
||||
"return jQuery('#g-recaptcha-response').val('PASSED')")
|
||||
submit.click()
|
||||
|
||||
self.assertEqual(self.live_server_url + n, self.browser.current_url)
|
||||
|
||||
def testApiKeyGeneration(self):
|
||||
# Requests address
|
||||
self.browser.get(self.live_server_url + '/user/')
|
||||
# Gets redirected to login
|
||||
self.authenticate('/user/')
|
||||
|
||||
# Completes and comes back to /user/
|
||||
# Checks that no api key is displayed
|
||||
self.assertEqual("No API Key Generated", self.browser.find_element_by_xpath("//div[@id='content']/div/div/div[3]/dl[2]/dd").text)
|
||||
self.assertEqual("No API Key Generated", self.browser.find_element_by_css_selector("pre").text)
|
||||
|
||||
# Now creates an API key, and check a URL is displayed one
|
||||
self.browser.find_element_by_link_text("Generate API Key").click()
|
||||
self.assertIn("rigs.ics", self.browser.find_element_by_id("cal-url").text)
|
||||
self.assertNotIn("?", self.browser.find_element_by_id("cal-url").text)
|
||||
|
||||
# Lets change everything so it's not the default value
|
||||
self.browser.find_element_by_xpath("//input[@value='rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='non-rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='dry-hire']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='cancelled']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='provisional']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='confirmed']").click()
|
||||
|
||||
# and then check the url is correct
|
||||
self.assertIn("rigs.ics?rig=false&non-rig=false&dry-hire=false&cancelled=true&provisional=false&confirmed=false", self.browser.find_element_by_id("cal-url").text)
|
||||
|
||||
# Awesome - all seems to work
|
||||
|
||||
def testICSFiles(self):
|
||||
# Requests address
|
||||
self.browser.get(self.live_server_url + '/user/')
|
||||
# Gets redirected to login
|
||||
self.authenticate('/user/')
|
||||
|
||||
# Now creates an API key, and check a URL is displayed one
|
||||
self.browser.find_element_by_link_text("Generate API Key").click()
|
||||
|
||||
|
||||
|
||||
c = Client()
|
||||
|
||||
# Default settings - should have all non-cancelled events
|
||||
# Get the ical file (can't do this in selanium because reasons)
|
||||
icalUrl = self.browser.find_element_by_id("cal-url").text
|
||||
response = c.get(icalUrl)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
#Check has entire file
|
||||
self.assertIn("BEGIN:VCALENDAR", response.content)
|
||||
self.assertIn("END:VCALENDAR", response.content)
|
||||
|
||||
expectedIn= [1,2,3,5,6,7,10,11,12,13,15,16,17]
|
||||
for test in range(1,18):
|
||||
if test in expectedIn:
|
||||
self.assertIn("TE E"+str(test)+" ", response.content)
|
||||
else:
|
||||
self.assertNotIn("TE E"+str(test)+" ", response.content)
|
||||
|
||||
|
||||
# Only dry hires
|
||||
self.browser.find_element_by_xpath("//input[@value='rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='non-rig']").click()
|
||||
|
||||
icalUrl = self.browser.find_element_by_id("cal-url").text
|
||||
response = c.get(icalUrl)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
expectedIn= [10,11,12,13]
|
||||
for test in range(1,18):
|
||||
if test in expectedIn:
|
||||
self.assertIn("TE E"+str(test)+" ", response.content)
|
||||
else:
|
||||
self.assertNotIn("TE E"+str(test)+" ", response.content)
|
||||
|
||||
|
||||
# Only provisional rigs
|
||||
self.browser.find_element_by_xpath("//input[@value='rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='dry-hire']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='confirmed']").click()
|
||||
|
||||
icalUrl = self.browser.find_element_by_id("cal-url").text
|
||||
response = c.get(icalUrl)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
expectedIn= [1,2]
|
||||
for test in range(1,18):
|
||||
if test in expectedIn:
|
||||
self.assertIn("TE E"+str(test)+" ", response.content)
|
||||
else:
|
||||
self.assertNotIn("TE E"+str(test)+" ", response.content)
|
||||
|
||||
# Only cancelled non-rigs
|
||||
self.browser.find_element_by_xpath("//input[@value='rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='non-rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='provisional']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='cancelled']").click()
|
||||
|
||||
icalUrl = self.browser.find_element_by_id("cal-url").text
|
||||
response = c.get(icalUrl)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
expectedIn= [18]
|
||||
for test in range(1,18):
|
||||
if test in expectedIn:
|
||||
self.assertIn("TE E"+str(test)+" ", response.content)
|
||||
else:
|
||||
self.assertNotIn("TE E"+str(test)+" ", response.content)
|
||||
|
||||
# Nothing selected
|
||||
self.browser.find_element_by_xpath("//input[@value='non-rig']").click()
|
||||
self.browser.find_element_by_xpath("//input[@value='cancelled']").click()
|
||||
|
||||
icalUrl = self.browser.find_element_by_id("cal-url").text
|
||||
response = c.get(icalUrl)
|
||||
self.assertEqual(200, response.status_code)
|
||||
|
||||
expectedIn= []
|
||||
for test in range(1,18):
|
||||
if test in expectedIn:
|
||||
self.assertIn("TE E"+str(test)+" ", response.content)
|
||||
else:
|
||||
self.assertNotIn("TE E"+str(test)+" ", response.content)
|
||||
|
||||
# Wow - that was a lot of tests
|
||||
|
||||
class animation_is_finished(object):
|
||||
""" Checks if animation is done """
|
||||
|
||||
@@ -6,9 +6,10 @@ from django.views import generic
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.core import serializers
|
||||
from django.conf import settings
|
||||
import simplejson
|
||||
from django.contrib import messages
|
||||
import datetime
|
||||
import datetime, pytz
|
||||
import operator
|
||||
from registration.views import RegistrationView
|
||||
|
||||
@@ -298,39 +299,22 @@ class SecureAPIRequest(generic.View):
|
||||
|
||||
if model == "event" and start and end:
|
||||
# Probably a calendar request
|
||||
start_datetime = datetime.datetime.strptime( start, "%Y-%m-%dT%H:%M:%SZ" )
|
||||
end_datetime = datetime.datetime.strptime( end, "%Y-%m-%dT%H:%M:%SZ" )
|
||||
start_datetime = datetime.datetime.strptime( start, "%Y-%m-%dT%H:%M:%S" )
|
||||
end_datetime = datetime.datetime.strptime( end, "%Y-%m-%dT%H:%M:%S" )
|
||||
|
||||
objects = self.models[model].objects.events_in_bounds(start_datetime,end_datetime)
|
||||
|
||||
results = []
|
||||
for item in objects:
|
||||
data = {
|
||||
'pk': item.pk,
|
||||
'title': item.name
|
||||
'title': item.name,
|
||||
'is_rig': item.is_rig,
|
||||
'status': str(item.get_status_display()),
|
||||
'earliest': item.earliest_time.isoformat(),
|
||||
'latest': item.latest_time.isoformat(),
|
||||
'url': str(item.get_absolute_url())
|
||||
}
|
||||
|
||||
data['is_rig'] = item.is_rig
|
||||
data['status'] = str(item.get_status_display())
|
||||
|
||||
if item.start_date:
|
||||
data['start_date'] = item.start_date.strftime('%Y-%m-%d')
|
||||
|
||||
if item.has_start_time:
|
||||
data['start_time'] = item.start_time.strftime('%H:%M:%SZ')
|
||||
|
||||
if item.end_date:
|
||||
data['end_date'] = item.end_date.strftime('%Y-%m-%d')
|
||||
|
||||
if item.has_end_time:
|
||||
data['end_time'] = item.end_time.strftime('%H:%M:%SZ')
|
||||
|
||||
if item.meet_at:
|
||||
data['meet_at'] = item.meet_at.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
if item.access_at:
|
||||
data['access_at'] = item.access_at.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
|
||||
data['url'] = str(reverse_lazy('event_detail',kwargs={'pk':item.pk}))
|
||||
|
||||
results.append(data)
|
||||
json = simplejson.dumps(results)
|
||||
|
||||
@@ -18,7 +18,7 @@ PyPDF2==1.24
|
||||
python-dateutil==2.4.2
|
||||
pytz==2015.4
|
||||
reportlab==3.1.44
|
||||
selenium==2.45.0
|
||||
selenium==2.46.0
|
||||
simplejson==3.7.2
|
||||
six==1.9.0
|
||||
sqlparse==0.1.15
|
||||
|
||||
Reference in New Issue
Block a user