Merge branch 'hotfixes'

This commit is contained in:
Tom Price
2015-05-29 02:06:58 +01:00
17 changed files with 255 additions and 8692 deletions

View File

@@ -188,7 +188,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_DIRS = (

View File

@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.core.validators
import django.contrib.auth.models
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0022_auto_20150424_2104'),
]
operations = [
migrations.AlterModelOptions(
name='profile',
options={'permissions': (('view_profile', 'Can view Profile'),)},
),
migrations.AlterModelManagers(
name='profile',
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.AlterField(
model_name='event',
name='collector',
field=models.CharField(max_length=255, null=True, verbose_name=b'collected by', blank=True),
),
migrations.AlterField(
model_name='organisation',
name='email',
field=models.EmailField(max_length=254, null=True, blank=True),
),
migrations.AlterField(
model_name='person',
name='email',
field=models.EmailField(max_length=254, null=True, blank=True),
),
migrations.AlterField(
model_name='profile',
name='email',
field=models.EmailField(max_length=254, verbose_name='email address', blank=True),
),
migrations.AlterField(
model_name='profile',
name='groups',
field=models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', verbose_name='groups'),
),
migrations.AlterField(
model_name='profile',
name='last_login',
field=models.DateTimeField(null=True, verbose_name='last login', blank=True),
),
migrations.AlterField(
model_name='profile',
name='username',
field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, max_length=30, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username'),
),
migrations.AlterField(
model_name='venue',
name='email',
field=models.EmailField(max_length=254, null=True, blank=True),
),
]

View File

@@ -14,6 +14,7 @@ from django.core.urlresolvers import reverse_lazy
from decimal import Decimal
# Create your models here.
@python_2_unicode_compatible
class Profile(AbstractUser):
initials = models.CharField(max_length=5, unique=True, null=True, blank=False)
phone = models.CharField(max_length=13, null=True, blank=True)
@@ -37,6 +38,18 @@ class Profile(AbstractUser):
def name(self):
return self.get_full_name() + ' "' + self.initials + '"'
@property
def latest_events(self):
return self.event_mic.order_by('-start_date').select_related('person', 'organisation', 'venue', 'mic')
def __str__(self):
return self.name
class Meta:
permissions = (
('view_profile', 'Can view Profile'),
)
class RevisionMixin(object):
@property
def last_edited_at(self):
@@ -265,7 +278,7 @@ class Event(models.Model, RevisionMixin):
payment_method = models.CharField(max_length=255, blank=True, null=True)
payment_received = models.CharField(max_length=255, blank=True, null=True)
purchase_order = models.CharField(max_length=255, blank=True, null=True, verbose_name='PO')
collector = models.CharField(max_length=255, blank=True, null=True, verbose_name='Collected by')
collector = models.CharField(max_length=255, blank=True, null=True, verbose_name='collected by')
# Calculated values
"""

View File

@@ -1,5 +0,0 @@
/* Welcome to Compass. Use this file to write IE specific override styles.
* Import this file using the following HTML or equivalent:
* <!--[if IE]>
* <link href="/stylesheets/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
* <![endif]--> */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -377,7 +377,7 @@ $navbar-inverse-bg: #222 !default;
$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default;
// Inverted navbar links
$navbar-inverse-link-color: $gray-light !default;
$navbar-inverse-link-color: lighten($gray-light, 20%) !default;
$navbar-inverse-link-hover-color: #fff !default;
$navbar-inverse-link-hover-bg: transparent !default;
$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default;

View File

@@ -5,7 +5,7 @@
{% load to_class_name from filters %}
{% block content %}
{% if request.is_ajax %}
<div class="list-group-item">
<div class="media">
{% for version in object_list %}
@@ -19,9 +19,11 @@
<div class="media">
{% endif %}
<div class="media-left">
<a href="#">
<img class="media-object img-rounded" src="{{ version.revision.user.profile_picture}}" />
</a>
{% if version.revision.user %}
<a href="{% url 'profile_detail' pk=version.revision.user.pk %}" class="modal-href">
<img class="media-object img-rounded" src="{{ version.revision.user.profile_picture}}" />
</a>
{% endif %}
</div>
<div class="media-body">
<h5>{{ version.revision.user.name }}
@@ -45,5 +47,5 @@
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -109,7 +109,15 @@
{% if event.is_rig %}
<dt>Event MIC</dt>
<dd>{{ event.mic.name }}</dd>
<dd>
{% if perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
{{ event.mic.name }}
</a>
{% else %}
{{ event.mic.name }}
{% endif %}
</dd>
{% endif %}
<dt>Status</dt>
@@ -119,18 +127,18 @@
{% if event.is_rig %}
<dt>Crew Meet</dt>
<dd>{{ event.meet_at|date:"d M Y H:i"|default:"" }}</dd>
<dd>{{ event.meet_at|date:"D d M Y H:i"|default:"" }}</dd>
<dd>{{ event.meet_info|default:"" }}</dd>
<dt>Access From</dt>
<dd>{{ event.access_at|date:"d M Y H:i"|default:"" }}</dd>
<dd>{{ event.access_at|date:"D d M Y H:i"|default:"" }}</dd>
{% endif %}
<dt>Event Starts</dt>
<dd>{{ event.start_date|date:"d M Y" }} {{ event.start_time|date:"H:i" }}</dd>
<dd>{{ event.start_date|date:"D d M Y" }} {{ event.start_time|date:"H:i" }}</dd>
<dt>Event Ends</dt>
<dd>{{ event.end_date|date:"d M Y" }} {{ event.end_time|date:"H:i" }}</dd>
<dd>{{ event.end_date|date:"D d M Y" }} {{ event.end_time|date:"H:i" }}</dd>
<dd>&nbsp;</dd>

View File

@@ -189,12 +189,18 @@
<keepTogether>
<blockTable style="totalTable" colWidths="300,115,80">
<tr>
<td></td>
<td>{% if not invoice %}VAT Registration Number: 116252989{% endif %}</td>
<td>Total (ex. VAT)</td>
<td>£ {{ object.sum_total|floatformat:2 }}</td>
</tr>
<tr>
<td>{% if not invoice %}VAT Registration Number: 116252989{% endif %}</td>
<td>
{% if not invoice %}
<para>
<b>The full hire fee is payable at least 10 days before the event.</b>
</para>
{% endif %}
</td>
<td>VAT @ {{ object.vat_rate.as_percent|floatformat:2 }}%</td>
<td>£ {{ object.vat|floatformat:2 }}</td>
</tr>
@@ -205,7 +211,7 @@
{% if invoice %}
VAT Registration Number: 116252989
{% else %}
<b>The full hire fee is payable at least 10 days before the event.</b>
<b>This contract is not an invoice.</b>
{% endif %}
</para>

View File

@@ -25,9 +25,9 @@
">
<td class="hidden-xs">{{ event.pk }}</td>
<td>
<div><strong>{{ event.start_date|date:"SHORT_DATE_FORMAT" }}</strong></div>
<div><strong>{{ event.start_date|date:"D d/m/Y" }}</strong></div>
{% if event.end_date and event.end_date != event.start_date %}
<div><strong>{{ event.end_date|date:"SHORT_DATE_FORMAT" }}</strong></div>
<div><strong>{{ event.end_date|date:"D d/m/Y" }}</strong></div>
{% endif %}
<span class="text-muted">{{ event.get_status_display }}</span>
</td>
@@ -83,7 +83,13 @@
{% if event.mic %}
{{ event.mic.initials }}
<div>
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
{% if perms.RIGS.view_profile %}
<a href="{% url 'profile_detail' event.mic.pk %}" class="modal-href">
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
</a>
{% else %}
<img src="{{ event.mic.profile_picture }}" class="event-mic-photo"/>
{% endif %}
</div>
{% elif event.is_rig %}
<span class="glyphicon glyphicon-exclamation-sign"></span>

View File

@@ -44,8 +44,8 @@
<tr id="new-item-row" class="item_row">
<td>
<span class="name"></span>
<div class="description">
<em></em>
<div class="item-description">
<em class="description"></em>
</div>
</td>
<td>£&nbsp;<span class="cost"></span></td>

View File

@@ -1,91 +1,104 @@
{% extends 'base.html' %}
{% extends request.is_ajax|yesno:"base_ajax.html,base.html" %}
{% block title %}RIGS Profile {{object.pk}}{% endblock %}
{% block content %}
<div class="col-md-10 col-md-offset-1">
<div class="col-sm-12">
<div class="col-sm-6">
<h3>{{object.name}}</h3>
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="col-sm-6">
<h3>{{object.name}}</h3>
</div>
{% if not request.is_ajax %}
{% if object.pk == user.pk %}
<div class="col-sm-6 text-right">
<div class="btn-group btn-page">
<a href="{% url 'profile_update_self' %}" class="btn btn-default">
Edit Profile <span class="glyphicon glyphicon-pencil"></span>
</a>
<a href="{% url 'password_change' %}" class="btn btn-default">
Change Password <span class="glyphicon glyphicon-lock"></span>
</a>
</div>
</div>
{% endif %}
{% endif %}
<div class="col-sm-8 ">
<dl class="dl-horizontal">
<dt>First Name</dt>
<dd>{{object.first_name}}</dd>
<dt>Last Name</dt>
<dd>{{object.last_name}}</dd>
<dt>Email</dt>
<dd>{{object.email}}</dd>
<dt>Last Login</dt>
<dd>{{object.last_login|date:"d/m/Y H:i"}}</dd>
<dt>Date Joined</dt>
<dd>{{object.date_joined|date:"d/m/Y H:i"}}</dd>
<dt>Initials</dt>
<dd>{{object.initials}}</dd>
<dt>Phone</dt>
<dd>{{object.phone}}</dd>
</dl>
{% if not request.is_ajax %}
{% if object.pk == user.pk %}
<div class="pull-right">
<a href="{% url 'reset_api_key' %}" class="btn btn-default">
{% if user.api_key %}Reset API Key{% else %}Generate API Key{% endif %}
<span class="glyphicon glyphicon-repeat"></span>
</a>
</div>
<h4>Personal iCal Details</h4>
<dl class="dl-horizontal">
<dt>API Key</dt>
<dd>
{% if user.api_key %}
{{user.api_key}}
{% else %}
No API Key Generated
{% endif %}
</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/>
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 %}
{% endif %}
</div>
<div class="col-sm-3">
<div class="center-block">
<img src="{{object.profile_picture}}" class="img-responsive img-rounded" />
</div>
</div>
{% if object.pk == user.pk %}
<div class="col-sm-6 text-right">
<div class="btn-group btn-page">
<a href="{% url 'profile_update_self' %}" class="btn btn-default">
Edit Profile <span class="glyphicon glyphicon-pencil"></span>
</a>
<a href="{% url 'password_change' %}" class="btn btn-default">
Change Password <span class="glyphicon glyphicon-lock"></span>
</a>
<div class="row">
<div class="col-sm-12">
<h4>Events</h4>
{% with object.latest_events as events %}
{% include 'RIGS/event_table.html' %}
{% endwith %}
</div>
</div>
{% endif %}
<div class="col-sm-8 ">
<dl class="dl-horizontal">
<dt>First Name</dt>
<dd>{{object.first_name}}</dd>
<dt>Last Name</dt>
<dd>{{object.last_name}}</dd>
<dt>Email</dt>
<dd>{{object.email}}</dd>
<dt>Last Login</dt>
<dd>{{object.last_login|date:"d/m/Y H:i"}}</dd>
<dt>Date Joined</dt>
<dd>{{object.date_joined|date:"d/m/Y H:i"}}</dd>
<dt>Initials</dt>
<dd>{{object.initials}}</dd>
<dt>Phone</dt>
<dd>{{object.phone}}</dd>
</dl>
{% if object.pk == user.pk %}
<div class="pull-right">
<a href="{% url 'reset_api_key' %}" class="btn btn-default">
{% if user.api_key %}Reset API Key{% else %}Generate API Key{% endif %}
<span class="glyphicon glyphicon-repeat"></span>
</a>
</div>
<h4>Personal iCal Details</h4>
<dl class="dl-horizontal">
<dt>API Key</dt>
<dd>
{% if user.api_key %}
{{user.api_key}}
{% else %}
No API Key Generated
{% endif %}
</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/>
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 "PyRIGS Calendar".</small>
{% else %}
<pre>No API Key Generated</pre>
{% endif %}
</dd>
</dl>
{% endif %}
</div>
<div class="col-sm-3">
<div class="center-block">
<img src="{{object.profile_picture}}" class="img-responsive img-rounded" />
</div>
</div>
{% endblock %}

View File

@@ -2,8 +2,8 @@
<button title="Changes to {{ change.field.verbose_name }}" type="button" class="btn btn-default btn-xs" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='
{% if change.new %}<div class="alert alert-success">{{change.new}}</div>{% endif %}
{% if change.old %}<div class="alert alert-danger">{{change.old}}</div>{% endif %}
{% if change.new %}<div class="alert alert-success {% if change.long %}overflow-ellipsis{% endif %}">{{change.new|linebreaksbr}}</div>{% endif %}
{% if change.old %}<div class="alert alert-danger {% if change.long %}overflow-ellipsis{% endif %}">{{change.old|linebreaksbr}}</div>{% endif %}
'>{{ change.field.verbose_name }}</button>
@@ -14,8 +14,8 @@
{% for change in itemChange.changes %}
<h4>{{ change.field.verbose_name }}</h4>
{% if change.new %}<div class="alert alert-success">{{change.new}}</div>{% endif %}
{% if change.old %}<div class="alert alert-danger">{{change.old}}</div>{% endif %}
{% if change.new %}<div class="alert alert-success">{{change.new|linebreaksbr}}</div>{% endif %}
{% if change.old %}<div class="alert alert-danger">{{change.old|linebreaksbr}}</div>{% endif %}
{% endfor %}

View File

@@ -16,6 +16,7 @@ import simplejson
from reversion.models import Version
from django.contrib.contenttypes.models import ContentType # Used to lookup the content_type
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import ForeignKey, IntegerField, EmailField
from RIGS import models, forms
import datetime
@@ -35,8 +36,27 @@ def model_compare(oldObj, newObj, excluded_keys=[]):
class FieldCompare(object):
def __init__(self, field=None, old=None, new=None):
self.field = field
self.old = old
self.new = new
self._old = old
self._new = new
def display_value(self, value):
if isinstance(self.field, IntegerField) and len(self.field.choices) > 0:
return [x[1] for x in self.field.choices if x[0] == value][0]
return value
@property
def old(self):
return self.display_value(self._old)
@property
def new(self):
return self.display_value(self._new)
@property
def long(self):
if isinstance(self.field, EmailField):
return True
return False
changes = []

Binary file not shown.

View File

@@ -11,8 +11,8 @@
<meta name="viewport" content="initial-scale=1">
<link rel="icon" type="image/png" href="/static/imgs/pyrigs-avatar.png">
<link rel="apple-touch-icon" href="/static/imgs/pyrigs-avatar.png">
<link rel="icon" type="image/png" href="{% static "imgs/pyrigs-avatar.png" %}">
<link rel="apple-touch-icon" href="{% static "imgs/pyrigs-avatar.png" %}">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400italic,700,300,400' rel='stylesheet' type='text/css'>
@@ -172,12 +172,14 @@
<script>
jQuery(document).ready(function () {
jQuery(document).on('click', '.modal-href', function (e) {
e.preventDefault()
modaltarget = jQuery(this).data('target')
modalobject = "";
jQuery('#modal').load(jQuery(this).attr('href'), function (e) {
jQuery('#modal').modal();
});
$link = jQuery(this);
// Anti modal inception
if($link.parents('#modal').length == 0) {
e.preventDefault();
jQuery('#modal').load($link.attr('href'), function (e) {
jQuery('#modal').modal();
});
}
});
@@ -186,7 +188,7 @@
var s = document.createElement('script');
s.type='text/javascript';
document.body.appendChild(s);
s.src='/static/js/asteroids.min.js';
s.src='{% static "js/asteroids.min.js"%}';
ga('send', 'event', 'easter_egg', 'activated');
}
easter_egg.load();