Skip to content

Commit

Permalink
Initial import.
Browse files Browse the repository at this point in the history
  • Loading branch information
hop committed Mar 21, 2012
0 parents commit 50d4813
Show file tree
Hide file tree
Showing 182 changed files with 12,572 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
*.pyc
9 changes: 9 additions & 0 deletions README.rst
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
Metalab OS
==========

This is the django project that runs our web site at the Metalab hackerspace
in Vienna, Austria (http://metalab.at/).

The official source repository and bug tracker as of 2012-03-21 can be
found at: https://github.com/Metalab/mos .

Empty file added __init__.py
Empty file.
28 changes: 28 additions & 0 deletions admin.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,28 @@
from django.contrib import admin
from django.contrib.auth.models import User

from mos.cal.models import Event, Category, Location
from mos.members.models import MemberAdmin
from mos.projects.models import Project
from mos.scrooge.models import Account, AccountAdmin, Product, ProductAdmin

#models for event admin site
calendar_admin = admin.AdminSite()
calendar_admin.register(Event)
calendar_admin.register(Category)
calendar_admin.register(Location)

#models for project admin site
project_admin = admin.AdminSite()
project_admin.register(Project)

#models for user admin site
member_admin = admin.AdminSite()
member_admin.register(User, MemberAdmin)

#models for scrooge
scrooge_admin = admin.AdminSite()
scrooge_admin.register(Account, AccountAdmin)
#scrooge_admin.register(Account)
scrooge_admin.register(Product, ProductAdmin)

Empty file added announce/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions announce/urls.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.conf.urls.defaults import *
from mos import settings

urlpatterns = patterns('',
(r'^$', 'mos.announce.views.announce'),
)
65 changes: 65 additions & 0 deletions announce/views.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,65 @@
#
# Views for issueing announcements to all active members.
#
from django.shortcuts import render_to_response
from django.conf import settings
from django.contrib.auth.decorators import user_passes_test
import django.forms as forms
from mos.members.models import get_active_members, ContactInfo
from django.core.mail import send_mail
import smtplib
from datetime import *


class AnnouncementForm(forms.Form):
subject = forms.CharField(required=True, label="Thema", max_length=40)
body = forms.CharField(required=True, label="Mitteilung",widget=forms.Textarea,)
to = forms.ChoiceField(required=True, label="An", choices=(('all','all'), ('collection','collection'),))


@user_passes_test(lambda u: (u.is_staff and u.is_authenticated()))
def announce(request):
print 'wtf:' + repr(request.user)
form = AnnouncementForm(request.POST or None)
if not request.POST or not form.is_valid():
return render_to_response('announce/write_message.html',
{
'form': form,
'user': request.user,
})
# Valid message: send it!
s = ''

users = get_active_members()
if form.cleaned_data['to']!='all':
users = users.filter(paymentinfo__bank_collection_allowed=True)\
.filter(paymentinfo__bank_collection_mode__id=4)
for u in users:
debt = u.contactinfo_set.all()[0].get_debt_for_month(date.today())
if debt == 0:
users = users.exclude(pk=u.pk)

for user in users:
ci = ContactInfo.objects.get(user=user)
try:
send_mail(form.cleaned_data['subject'],
form.cleaned_data['body'],
settings.HOS_ANNOUNCE_FROM,
[user.email],
fail_silently=False)
ci.last_email_ok = True
ci.save()
except smtplib.SMTPException, instance:
f = open('/announcelog.log', 'a')
f.write('\n\n'+user.email)
f.write('\n'+repr(instance))
ci.last_email_ok = False
ci.save()
f.close()

return render_to_response('announce/message_sent.html',
{
'form': form,
'user': request.user,
'users': users,
})
Empty file added billing/__init__.py
Empty file.
25 changes: 25 additions & 0 deletions billing/models.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,25 @@
from django.db import models


class Invoice(models.Model):
number = models.PositiveIntegerField(null=False, unique_for_year="date")
invoice_recipient = models.TextField(null=False)
invoice_address = models.TextField(null=False)
date = models.DateField(null=False)
invoice_mail_recipient = models.EmailField()
invoice_mailed_at = models.DateTimeField()

class Admin:
pass


class InoviceItem(models.Model):
invoice = models.ForeignKey(Invoice, null=False,
edit_inline=models.TABULAR, core=True)
text = models.TextField(null=False, core=True)
value = models.DecimalField(null=False, decimal_places=2, max_digits=7,
core=True)
order = models.PositiveIntegerField(null=False, core=True)

class Admin:
pass
12 changes: 12 additions & 0 deletions cal/__init__.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,12 @@
from icalendar import Calendar

def create_calendar(components):
c = Calendar()
c.add('version', '2.0')
c.add('prodid', '-//Hackerspace OS//code.google.com/p/hackerspace-os//')
c.add('X-WR-TIMEZONE', 'Europe/Vienna')
c.add('X-WR-CALNAME', 'Metalab');
c.add('X-WR-CALDESC', 'Metalab Events Calendar');
for component in components:
c.add_component(component)
return c
14 changes: 14 additions & 0 deletions cal/feeds.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.contrib.syndication.feeds import Feed
from models import Event
import datetime


class EventFeed(Feed):
title=u'Zukuenftige Veranstaltungen'
link='/'
description=u'''zukuenftige Veranstaltungen in und um den Wiener
Hackerspace Metalab'''

def items(self):
return Event.all.filter(startDate__gte=datetime.datetime.now()).\
order_by('startDate')
27 changes: 27 additions & 0 deletions cal/fields.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,27 @@
import datetime

import django.forms as forms
from django.forms import ValidationError

from mos.cal.widgets import DateTimeCombiWidget


class DateTimeCombiField(forms.MultiValueField):
"""
A newform field, which provides a seperate input tag for date
and time, the output is merged again
"""

def __init__(self, required=True, label=None, widget=None, initial=None):
fields = (forms.DateField(), forms.TimeField())
widget = widget or DateTimeCombiWidget()
super(DateTimeCombiField, self).__init__(fields, required,
widget, label, initial)

def compress(self, data_list):
if data_list:
try:
return datetime.datetime.combine(data_list[0], data_list[1])
except:
return None
return None
19 changes: 19 additions & 0 deletions cal/forms.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.forms import ModelForm
import django.forms as forms

from mos.cal.fields import DateTimeCombiField
from mos.cal.models import Event


class EventForm(ModelForm):
"""
Form to add an event
"""

startDate = DateTimeCombiField()
endDate = DateTimeCombiField(required=False)
teaser = forms.CharField(required=False)

class Meta:
model = Event
exclude = ('where', 'created_at', 'created_by', 'deleted', 'who')
161 changes: 161 additions & 0 deletions cal/models.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,161 @@
import datetime
import locale

from icalendar import Event as icalEvent
from icalendar.prop import vDatetime

from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.db import models
from django.db.models import permalink, Q

from mos.core.models import Category, Location
from mos.cal import create_calendar
import urllib

locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')


class EventManager(models.Manager):

def get_query_set(self):
return super(EventManager, self).get_query_set().filter(deleted=False)


class FutureEventFixedNumberManager(EventManager):

def get_query_set(self):
"""
Get <num> future events, or if there aren't enough,
get <num> latest+future events.
"""

DEFAULT_NUM = 5
if(hasattr(settings, 'HOS_HOME_EVENT_NUM')):
num = settings.HOS_HOME_EVENT_NUM
else:
num = DEFAULT_NUM

return self.get_n(num)

def get_n(self, num):

all = super(FutureEventFixedNumberManager, self).get_query_set().\
order_by('startDate')

if num==0:
return all

future = all.filter((Q(endDate__gte=datetime.datetime.now())) |
(Q(endDate__isnull=True) &
Q(startDate__gte=datetime.datetime.now()-\
datetime.timedelta(hours=5))))\
.order_by('startDate') # event visible 5 hours
# after it started

if(future.count()<num):
if(all.count()-num>=0):
latest = all[all.count()-num:all.count()]
else:
latest = all
else:
latest = future[:num]

return latest


class Event(models.Model):
"""
Represents an event
"""

name = models.CharField(max_length=200)
teaser = models.TextField(max_length=200, blank=True, null=True)
wikiPage = models.CharField(max_length=200)

startDate = models.DateTimeField()
endDate = models.DateTimeField(blank=True, null=True)

who = models.CharField(max_length=200, blank=True)
where = models.CharField(max_length=200, blank=True)

created_at = models.DateTimeField(default=datetime.datetime.now())
created_by = models.ForeignKey(User)

deleted = models.BooleanField(default=False)

category = models.ForeignKey(Category, blank=True, null=True)
location = models.ForeignKey(Location, blank=True, null=True)

objects = models.Manager()
all = EventManager()
future = FutureEventFixedNumberManager()

def __unicode__(self):
status = ''
if self.deleted:
status = ' [deleted]'
return u'%s (%s)%s' % (self.name, self.startDate, status)

def past(self):
return self.startDate < datetime.datetime.now()

@permalink
def get_absolute_url(self):
return ('cal_event_detail', (self.id,),)

def save(self, editor=False, new=False):
if new and editor != False:
self.created_by = editor
self.created_by.save()

super(Event, self).save()

def start_end_date_eq(self):
return self.startDate.date() == self.endDate.date()

def delete(self):
self.deleted = True



def get_icalendar_event(self):
domain = Site.objects.get_current().domain
rv = icalEvent()

rv.add('uid', u'%d@%s' % (self.id, domain))

rv.add('summary', unicode(self.name))
rv.add('dtstart', vDatetime(self.startDate).ical(), encode=0)
rv.add('dtstamp', vDatetime(self.created_at).ical(), encode=0)
rv.add('url', urllib.quote((u'http://%s/wiki/%s' % (domain, unicode(self.wikiPage))).encode('utf-8')) )

if self.teaser:
rv.add('description', unicode(self.teaser))

if self.endDate:
rv.add('dtend', vDatetime(self.endDate).ical(), encode=0)

if self.who:
rv.add('organizer', unicode(self.who))
elif self.created_by_id and User.objects.filter(id=self.created_by_id):
rv.add('organizer', unicode(self.created_by))

if self.location:
rv.add('location', u'Metalab ' + unicode(self.location))
elif self.where:
rv.add('location', u'Metalab ' + unicode(self.where))

if self.category:
rv.add('categories', unicode(self.category))

return rv

def get_icalendar(self):
return create_calendar([self.get_icalendar_event()])

@permalink
def get_icalendar_url(self):
return ( 'cal_event_icalendar', (self.id,) )

Empty file added cal/templatetags/__init__.py
Empty file.
Loading

0 comments on commit 50d4813

Please sign in to comment.