Skip to content
This repository has been archived by the owner on Oct 7, 2021. It is now read-only.

Commit

Permalink
calendar as a vcal export
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe committed Dec 19, 2011
1 parent 667ec1c commit 64ca290
Show file tree
Hide file tree
Showing 11 changed files with 426 additions and 89 deletions.
3 changes: 2 additions & 1 deletion apps/dates/helpers.py
Expand Up @@ -50,7 +50,8 @@ def media(context, url, key='MEDIA_URL'):
elif url.endswith('.css'):
build = context['BUILD_ID_CSS']
else:
build = context['BUILD_ID_IMG']
#build = context['BUILD_ID_IMG']
build = context['BUILD_ID_JS']
return context[key] + urlparams(url, b=build)


Expand Down
66 changes: 63 additions & 3 deletions apps/dates/models.py
@@ -1,3 +1,40 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Sheriff Duty.
#
# The Initial Developer of the Original Code is Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Peter Bengtsson <peterbe@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

import uuid
import datetime
from django.db import models
from django.contrib.auth.models import User
Expand Down Expand Up @@ -38,7 +75,8 @@ class Hours(models.Model):


class BlacklistedUser(models.Model):
observer = models.ForeignKey(User, related_name='observer') # FIXME: need to figure out the right on_delete here
# FIXME: need to figure out the right on_delete here
observer = models.ForeignKey(User, related_name='observer')
observable = models.ForeignKey(User, related_name='observable')
add_date = models.DateTimeField(default=datetime.datetime.utcnow)

Expand All @@ -49,7 +87,8 @@ def __repr__(self): # pragma: no cover


class FollowingUser(models.Model):
follower = models.ForeignKey(User, related_name='follower') # FIXME: need to figure out the right on_delete here
# FIXME: need to figure out the right on_delete here
follower = models.ForeignKey(User, related_name='follower')
following = models.ForeignKey(User, related_name='following')
add_date = models.DateTimeField(default=datetime.datetime.utcnow)

Expand All @@ -59,25 +98,46 @@ def __repr__(self): # pragma: no cover
self.following.username)



@receiver(post_save, sender=BlacklistedUser)
def blacklist_cleanup_check(sender, instance, **kwargs):
(FollowingUser.objects
.filter(follower=instance.observer, following=instance.observable)
.delete())


@receiver(post_save, sender=FollowingUser)
def follow_cleanup_check(sender, instance, **kwargs):
(BlacklistedUser.objects
.filter(observer=instance.follower, observable=instance.following)
.delete())


@receiver(pre_save, sender=BlacklistedUser)
def blacklist_integrity_check(sender, instance, **kwargs):
if instance.observer == instance.observable:
raise BlacklistIntegityError("can't blacklist self")


@receiver(pre_save, sender=FollowingUser)
def following_integrity_check(sender, instance, **kwargs):
if instance.follower == instance.following:
raise FollowingIntegrityError("can't follow self")


def generate_random_key(length=None):
if length is None:
length = UserKey.KEY_LENGTH
key = uuid.uuid4().hex[:length]
while UserKey.objects.filter(key=key).exists():
key = uuid.uuid4().hex[:length]
return key


class UserKey(models.Model):

KEY_LENGTH = 10

user = models.ForeignKey(User)
key = models.CharField(max_length=KEY_LENGTH, db_index=True,
default=generate_random_key)
add_date = models.DateTimeField(default=datetime.datetime.utcnow)
13 changes: 12 additions & 1 deletion apps/dates/templates/dates/home.html
Expand Up @@ -8,8 +8,19 @@
{% block content %}

<div id="calendar">

<p><a name="calendarurl">

<a href="{{ calendar_url }}"><img src="{{ media('img/calendar-icon.png') }}" alt="Calendar"></a>
To add this to an external calendar you need this URL:
<a href="{{ calendar_url }}">{{ calendar_url }}</a>
<span class="reset-link">
(<a href="{{ url('dates.reset_calendar_url') }}" class="reset-link">reset your calendar URL</a>)
</span>

</div>


<div id="rightnow" class="extra-info">
<h2>Who's on PTO right now?</h2>

Expand All @@ -21,7 +32,7 @@ <h2>Who's on PTO right now?</h2>
{% else %}
{{ full_name_form(user) }}
{% endif %}

</dt>
{% for days_left, entry in right_nows[user] %}
<dd><a href="{{ entry_to_list_url(entry) }}"
Expand Down
30 changes: 29 additions & 1 deletion apps/dates/tests/test_models.py
Expand Up @@ -18,6 +18,7 @@
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Peter Bengtsson <peterbe@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
Expand All @@ -38,7 +39,8 @@
from django.test import TestCase
from dates.models import (Entry, Hours, BlacklistedUser, FollowingUser,
FollowingIntegrityError,
BlacklistIntegityError)
BlacklistIntegityError,
UserKey)
from nose.tools import eq_, ok_


Expand Down Expand Up @@ -127,3 +129,29 @@ def test_self_blacklisting_integrity_check(self):
observer=peter,
observable=peter
)

def test_user_keys(self):
peter = User.objects.create(username='peter')
uk = UserKey.objects.create(user=peter)

ok_(uk.add_date)
ok_(uk.key)
eq_(len(uk.key), UserKey.KEY_LENGTH)

peter2 = User.objects.create(username='peter2')
uk2 = UserKey.objects.create(user=peter2)
ok_(uk.key != uk2.key)

eq_(UserKey.objects.all().count(), 2)

peter.delete()
eq_(UserKey.objects.all().count(), 1)

def test_user_keys_uniqueness(self):
peter = User.objects.create(username='peter')
keys = set()
for i in range(1000):
uk = UserKey.objects.create(user=peter)
if uk.key in keys:
raise AssertionError('same key reused')
keys.add(uk.key)

0 comments on commit 64ca290

Please sign in to comment.