Beispiel #1
0
def friendrequest_post_save(sender, instance=None, **kwargs):
    if instance is None:
        return
    fr = instance
    sent_to = fr.sent_to
    sent_by = fr.sent_by

    extra_msgs = []
    if fr.answered_at:
        extra_msgs.append('answered_at=%s' % fr.answered_at.strftime('%Y-%m-%d'))
        extra_msgs.append('accepted=%s' % fr.accepted)

    extra = ''
    if len(extra_msgs):
        extra = ', ' + ', '.join(extra_msgs)
    get_logger('baljan.friends').info(
            'friend request %s → %s saved%s' % (
                sent_by, sent_to, extra))

    if fr.answered_at:
        if fr.accepted:
            send_type = 'friend_request_accepted'
        else:
            send_type = 'friend_request_denied'
        notifications.send(send_type, sent_by, 
            requestee=sent_to.get_full_name())
    else:
        notifications.send('friend_request_received', 
            sent_to, requestor=sent_by.get_full_name())
Beispiel #2
0
def signup_pre_delete(sender, instance=None, **kwargs):
    if instance is None:
        return
    signup = instance
    signup_post(sender, signup, **kwargs)

    signup_notice_delete(signup)
    get_logger('baljan.signups').info("%s deleted" % instance)
Beispiel #3
0
def friendrequest_post_delete(sender, instance=None, **kwargs):
    if instance is None:
        return
    fr = instance
    sent_to = fr.sent_to
    sent_by = fr.sent_by

    get_logger('baljan.friends').info('friend request %s → %s deleted' % (
        fr.sent_by, fr.sent_to))
    if fr.answered_at:
        pass # a notification has already been sent in this case
    else:
        notifications.send('friend_request_canceled', 
            sent_to, requestor=sent_by.get_full_name())
Beispiel #4
0
def credits(request):
    user = request.user
    profile = user.get_profile()
    tpl = {}

    refill_form = baljan.forms.RefillForm()
    import_form = baljan.forms.ImportOldCardForm()
    credits_log = get_logger('baljan.views.credits')

    if request.method == 'POST':
        try:
            foo = request.POST['task']
        except:
            credits_log.error('no task in form!')
        else:
            if request.POST['task'] == 'refill':
                refill_form = baljan.forms.RefillForm(request.POST)
                if refill_form.is_valid():
                    entered_code = refill_form.cleaned_data['code']
                    creditsmodule.is_used(entered_code, user) # for logging
                    try:
                        creditsmodule.manual_refill(entered_code, user)
                        tpl['used_card'] = True
                    except creditsmodule.BadCode, e:
                        tpl['invalid_card'] = True
            elif request.POST['task'] == 'import-old':
                import_form = baljan.forms.ImportOldCardForm(request.POST)
                if import_form.is_valid():
                    entered_code = import_form.cleaned_data['code']
                    creditsmodule.is_used(entered_code, user, old_card=True) # for logging
                    try:
                        creditsmodule.manual_import(entered_code, user)
                        tpl['used_card'] = True
                    except creditsmodule.BadCode, e:
                        tpl['invalid_card'] = True
Beispiel #5
0
def semester_post_save(sender, instance, **kwargs):
    sem = instance
    shifts = sem.shift_set.filter(
            Q(when__lt=sem.start) | Q(when__gt=sem.end))
    deleted_count = len(shifts)
    shifts.delete()

    weekdays = (5, 6)
    created_count = 0
    for day in sem.date_range():
        if day.weekday() in weekdays:
            continue 
        for early_or_lunch_or_late in (0, 1, 2):
            obj, created = Shift.objects.get_or_create(
                    semester=sem,
                    span=early_or_lunch_or_late,
                    when=day)
            if created:
                created_count += 1
    logger = get_logger('baljan.semesters')
    logger.info('%s: %d/%d shifts added/deleted, signups=%s' % (
        sem.name, created_count, deleted_count, sem.signup_possible))

    # Create new shift combinations for job openings.
    from baljan import workdist
    sched = workdist.Scheduler(sem)
    try:
        sched.save()
    except workdist.Scheduler.Unsolvable:
        logger.warning('could not save shift combs for %r' % sem)
Beispiel #6
0
def signup_pre_save(sender, instance=None, **kwargs):
    if instance is None:
        return

    signup = instance
    signup_post(sender, signup, **kwargs)
    
    # Remove pending trade requests that, if accepted, would result in a user
    # being double-booked for a shift.
    trs_possible_doubles = TradeRequest.objects.filter(
            Q(wanted_signup__shift=signup.shift,
                offered_signup__user=signup.user) |
            Q(wanted_signup__user=signup.user,
                offered_signup__shift=signup.shift))
    trs_possible_doubles.delete()

    if signup.tradable:
        get_logger('baljan.signups').info("%s saved (tradable)" % signup)
    else:
        get_logger('baljan.signups').info("%s saved (not tradable)" % signup)
        signup_notice_save(signup)
Beispiel #7
0
def traderequest_post_delete(sender, instance=None, **kwargs):
    if instance is None:
        return

    tr = instance

    # Mark other trade requests involving the wanted or offered sign-up as
    # denied and answered, so that notifications will be sent for them. Do not
    # mark requests where the requester and wanted shift is the same as this
    # one, to prevent sending unnecessary notifications. Save configurations for
    # sign-ups to be created and delete the current ones. If the request was
    # denied, there is no need to do anything besides sending the appropriate
    # notifications.
    if tr.accepted:
        answerer = tr.wanted_signup.user
        requester = tr.offered_signup.user
        logger = get_logger('baljan.trades')
        logger.info('%s accepted' % tr, trade_request=tr)
        TradeRequest.objects.filter(
                Q(wanted_signup=tr.wanted_signup) |
                Q(wanted_signup=tr.offered_signup) |
                Q(offered_signup=tr.wanted_signup) |
                Q(offered_signup=tr.offered_signup)).exclude(
                        Q(pk=tr.pk) | 
                        Q(offered_signup__user=requester, 
                            wanted_signup=tr.wanted_signup)).update(
                            accepted=False, answered=True)
        accepter_kwargs = {
                'user': answerer,
                'shift': tr.offered_signup.shift,
                }
        requester_kwargs = {
                'user': requester,
                'shift': tr.wanted_signup.shift,
                }
        tr.offered_signup.delete()
        tr.wanted_signup.delete()

        accepter_signup = ShiftSignup(**accepter_kwargs)
        accepter_signup.save()

        requester_signup = ShiftSignup(**requester_kwargs)
        requester_signup.save()
Beispiel #8
0
def job_opening_projector(request, semester_name):
    opening_log = get_logger('baljan.jobopening')
    tpl = {}
    tpl['semester'] = sem = baljan.models.Semester.objects.get(name__exact=semester_name)
    user = request.user

    sched = workdist.Scheduler(sem)
    pairs = sched.pairs_from_db()
    slots = _pair_matrix(pairs)
    tpl['now'] = now = datetime.now().strftime('%H:%M:%S')

    if request.is_ajax(): 
        pair_info = []
        for pair in pairs:
            pair_info.append({
                'label': pair.label,
                'free': pair.is_free(),
            })
        return HttpResponse(simplejson.dumps({'now': now, 'pairs': pair_info}))

    tpl['slots'] = slots
    return render_to_response('baljan/job_opening_projector.html', tpl, 
            context_instance=RequestContext(request))
Beispiel #9
0
def traderequest_notice_delete(tr):
    if tr.answered:
        cancel = False
        if tr.wanted_signup.shift.when < date.today():
            cancel = True
        if tr.offered_signup.shift.when < date.today():
            cancel = True
        if cancel:
            logger = get_logger('baljan.trades')
            logger.info('not sending message about trade request deletion because the offered or wanted shift was in the past')
            return

        if tr.accepted:
            send_type = 'trade_request_accepted'
        else:
            send_type = 'trade_request_denied'
        requestor = tr.offered_signup.user
        notifications.send(send_type,
            requestor,
            wanted_shift=tr.wanted_signup.shift.name(),
            offered_shift=tr.offered_signup.shift.name(),
        )
    else:
        pass # FIXME: notifications should be sent here as well
Beispiel #10
0
# -*- coding: utf-8 -*-
from celery.decorators import task, periodic_task
from celery.task.schedules import crontab
from baljan.sounds import play_sound
from baljan.util import get_logger
from django.conf import settings
from django.contrib.auth.models import User, Group
from datetime import datetime
from baljan import orders
from baljan.card2user import Card2User
from baljan import stats
from django.core.cache import cache

log = get_logger('baljan.tasks', with_sentry=False)

try:
    from baljan.lcd import LCD, ADUNO, get_lcd
    lcd = get_lcd()
except Exception, e:
    log.warning('no LCD support (%s)' % e)

tasklog = get_logger('baljan.cardreader.tasks', with_sentry=False)
user_finder = Card2User()

def _do_prefetch():
    tasklog.info('prefetching users for blipper, this can take some time')
    user_finder.prefetch_all()

@task(ignore_result=True)
def blipper_prefetch_users():
    _do_prefetch()
Beispiel #11
0
# -*- coding: utf-8 -*-
from optparse import make_option
import os
import readline
import sys

from django.conf import settings
from django.contrib.auth.models import User, Permission, Group
from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import ugettext as _
from django.db import transaction

from baljan.models import Semester
from baljan.util import get_logger, asciilize, random_string

log = get_logger('baljan.commands.updateworkers')

class Command(BaseCommand):
    args = 'SEMESTER'
    help = 'Set workers to everyone signed up for a shift in SEMESTER.'

    def handle(self, *args, **options):
        valid = True 
        if not valid:
            raise CommandError('invalid config')

        if len(args) != 1:
            raise CommandError('usage: updateworkers SEMESTER')

        worker_group = Group.objects.get(name__exact=settings.WORKER_GROUP)
Beispiel #12
0
# -*- coding: utf-8 -*-
from django.conf import settings
from django.core.cache import cache
from django.contrib.auth.models import User
from django.utils.importlib import import_module
from baljan.util import get_logger

log = get_logger('baljan.card2user', with_sentry=False)

class Cacher(object):
    prefix = 'baljan.card2user.cards'

    def _key(self, card_id):
        return "%s.%s" % (self.prefix, card_id)

    def store(self, card_id, user, silent=False):
        key = self._key(card_id)
        one_week = 604800 # seconds
        cache.set(key, user.id, one_week)
        if not silent:
            log.info('set cache of %s to %s' % (card_id, user))
        return self

    def get(self, card_id):
        key = self._key(card_id)
        cached = cache.get(key)
        if cached is None:
            log.info('%s not in cache' % card_id)
            return None

        try:
Beispiel #13
0
# -*- coding: utf-8 -*-
import os
from subprocess import Popen, PIPE
from django.conf import settings
from baljan.util import get_logger

log = get_logger('baljan.parport', with_sentry=False)
PIN_GREEN = 2
PIN_RED = 3
PIN_BEEP = 4
PIN_LCD = 7

class ParPortError(Exception):
    pass

class ParPort(object):
    def __init__(self):
        self.path = settings.PAR_PORT_PROG
        if os.path.isfile(self.path):
            pass
        else:
            msg = "%r does not exist" % self.path
            log.error(msg)

    def go(self, flags):
        """Blocking."""
        # FIXME: sudo should not be needed!
        p = Popen(["/usr/bin/sudo", self.path] + flags,
            stdin=PIPE,
            stderr=PIPE,
            stdout=PIPE,
Beispiel #14
0
# -*- coding: utf-8 -*-

from django.core.urlresolvers import reverse
from django.core.mail import send_mail
from django.utils.translation import ugettext_lazy
from django.contrib.sites.models import Site
from django.conf import settings

from baljan.util import get_logger

logger = get_logger('baljan.notifications')

TITLE_TEMPLATES = {
    'friend_request_denied': ugettext_lazy("""%(requestee)s denied your friend request"""),

    'friend_request_accepted': ugettext_lazy("""You are now friends with %(requestee)s"""),

    'friend_request_received': ugettext_lazy("""You have received a friend request from %(requestor)s"""),

    'friend_request_canceled': ugettext_lazy("""The friend request from %(requestor)s was canceled"""),

    'added_to_shift': ugettext_lazy("""You were signed up for %(shift)s"""),

    'removed_from_shift': ugettext_lazy("""You were removed from %(shift)s"""),

    'new_trade_request': ugettext_lazy("""%(requestor)s wants %(wanted_shift)s in exchange for %(offered_shift)s"""),

    'trade_request_accepted': ugettext_lazy("""Your request to trade %(wanted_shift)s for %(offered_shift)s was accepted"""),

    'trade_request_denied': ugettext_lazy("""Your request to trade %(wanted_shift)s for %(offered_shift)s was denied"""),
}
Beispiel #15
0
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from baljan.tasks import test_play_all, SOUND_FUNCS_AND_DESCS
from baljan.tasks import SOUND_FUNCS_AND_LIKELINESS 
from baljan.util import get_logger
from django.utils.translation import ugettext as _
import os
from time import sleep
import readline
from random import uniform, normalvariate

log = get_logger('baljan.commands.demosound')

def play_random():
    rand = uniform(0, 1)
    for func, thres in SOUND_FUNCS_AND_LIKELINESS:
        if rand < thres:
            func.delay()
            break
    else:
        SOUND_FUNCS_AND_LIKELINESS[-1][0].delay()


def sleep_random():
    mean, var = 3, 5
    rand = max(mean, abs(normalvariate(mean, var)))
    print "sleeping for %.2fs" % rand
    sleep(rand)

Beispiel #16
0
def oncallduty_post_delete(sender, instance=None, **kwargs):
    if instance is None:
        return
    signup_notice_delete(instance)
    get_logger('baljan.signups').info("%s deleted" % instance)
Beispiel #17
0
def semester_post_delete(sender, instance, **kwargs):
    if instance is None:
        return
    sem = instance
    logger = get_logger('baljan.semesters')
    logger.info('%s: deleted' % sem.name)
Beispiel #18
0
def admin_semester(request, name=None):
    if name is None:
        sem = baljan.models.Semester.objects.current()
        if sem is None:
            try:
                upcoming_sems = baljan.models.Semester.objects.upcoming()
                sem = upcoming_sems[0]
            except:
                pass
    else:
        sem = baljan.models.Semester.objects.by_name(name)

    user = request.user
    
    new_sem_form = baljan.forms.SemesterForm()
    if request.method == 'POST':
        if request.POST['task'] == 'new_semester':
            new_sem_form = baljan.forms.SemesterForm(request.POST)
        elif request.POST['task'] == 'edit_shifts':
            assert sem is not None
            raw_ids = request.POST['shift-ids'].strip()
            edit_shift_ids = []
            if len(raw_ids):
                edit_shift_ids = [int(x) for x in raw_ids.split('|')]

            make = request.POST['make']
            shifts_to_edit = baljan.models.Shift.objects.filter(
                id__in=edit_shift_ids).distinct()

            if make == 'normal':
                shifts_to_edit.update(exam_period=False, enabled=True)
            elif make == 'disabled':
                shifts_to_edit.update(exam_period=False, enabled=False)
            elif make == 'exam-period':
                shifts_to_edit.update(exam_period=True, enabled=True)
            elif make == 'none':
                pass
            else:
                get_logger('baljan.semesters').warning('unexpected task %r' % make)
                assert False

            if make != 'none':
                sem.save() # generates new shift combinations

    new_sem_failed = False
    if new_sem_form.is_bound:
        if new_sem_form.is_valid():
            new_sem = new_sem_form.save()
            new_sem_url = reverse('baljan.views.admin_semester', 
                args=(new_sem.name,)
            )
            messages.add_message(request, messages.SUCCESS, 
                _("%s was added successfully.") % new_sem.name
            )
            return HttpResponseRedirect(new_sem_url)
        else:
            new_sem_failed = True

    tpl = {}
    tpl['semester'] = sem
    tpl['new_semester_form'] = new_sem_form
    tpl['semesters'] = baljan.models.Semester.objects.order_by('-start').all()
    tpl['admin_semester_base_url'] = reverse('baljan.views.admin_semester')
    tpl['new_semester_failed'] = new_sem_failed
    if sem:
        tpl['shifts'] = shifts = sem.shift_set.order_by('when', 'span')
        tpl['day_count'] = len(list(sem.date_range()))
        
        worker_shifts = shifts.exclude(enabled=False).exclude(span=1)
        tpl['worker_shift_count'] = worker_shifts.count()
        tpl['exam_period_count'] = worker_shifts.filter(exam_period=True).count()

    return render_to_response('baljan/admin_semester.html', tpl, 
            context_instance=RequestContext(request))
Beispiel #19
0
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.auth.models import User, Group

from baljan.util import get_logger

log = get_logger('baljan.card2user.manualdb', with_sentry=False)

class Finder(object):
    def search(self, card_id):
        try:
            user = User.objects.get(profile__card_id=card_id)
            log.info('found %s in local db' % user)
            return user
        except:
            log.info('owner of card %s could not be fetched' % card_id)
            return None
Beispiel #20
0
# -*- coding: utf-8 -*-
from django.contrib.auth.models import User, Permission, Group
from baljan.models import FriendRequest
from django.db.models import Q
from datetime import date
from baljan.util import get_logger

logger = get_logger('baljan.friends')

def pending_between(usera, userb):
    if usera == userb:
        return None
    p = FriendRequest.objects.filter(
            Q(sent_by=usera) | Q(sent_by=userb),
            Q(sent_to=usera) | Q(sent_to=userb),
            answered_at__isnull=True)
    if p.count():
        assert p.count() == 1
        return p[0]
    return None


def answer_to(frequest, accept):
    sent_by = frequest.sent_by.get_profile()
    sent_to = frequest.sent_to.get_profile()
    
    if accept:
        if sent_to in sent_by.friend_profiles.all():
            pass
        else:
            sent_by.friend_profiles.add(sent_to)
Beispiel #21
0
# -*- coding: utf-8 -*-
from django.conf import settings
from django.contrib.auth.models import User, check_password
from baljan.util import get_logger, get_or_create_user
import ldap
import re

log = get_logger('baljan.ldap')

def valid_username(username):
    return re.match('^[a-z]{2,5}[0-9]{3,3}$', username) is not None


def exists_in_ldap(username):
    return fetch_user(username, bind=False, create=False)


def search(username, password=None, bind=False):
    if not valid_username(username):
        log.error('invalid username %r' % username)
        return None

    base = "ou=people,dc=student,dc=liu,dc=se"
    uid_kw = "uid=%s" % username
    ldap_bind_str = "%s, %s" % (uid_kw, base)
    scope = ldap.SCOPE_SUBTREE
    ret = None
    try:
        l = ldap.initialize(settings.LDAP_SERVER)
        l.protocol_version = ldap.VERSION3
        if bind:
Beispiel #22
0
# -*- coding: utf-8 -*-
from baljan.models import Shift
from baljan.util import year_and_week, get_logger
from baljan.util import available_for_call_duty
from baljan.util import initials, all_initials
from baljan.grids import ShiftGrid
from django.contrib.auth.models import User, Permission, Group

log = get_logger('baljan.planning')

class BoardWeek(object):
    """Board activities of a week. Used for editing people on call and such
    things.
    """

    @staticmethod
    def current_week():
        return BoardWeek(*year_and_week())

    def __init__(self, year, week):
        self.shifts = Shift.objects.for_week(year, week)
    
    @staticmethod
    def dom_id(shift):
        daynum = int(shift.when.strftime('%w'))
        return "shift-%d-%d" % (daynum, shift.span)

    def dom_ids(self):
        return [BoardWeek.dom_id(sh) for sh in self.shifts]

    def oncall(self):
Beispiel #23
0
# -*- coding: utf-8 -*-
from baljan.models import Order, OrderGood
from baljan.models import OnCallDuty, Good
from django.utils.translation import ugettext_lazy as _
from datetime import date, datetime
from django.conf import settings
from django.contrib.auth.models import User, Group
from baljan.util import get_logger
from baljan.pseudogroups import was_worker, was_board
from dateutil.relativedelta import relativedelta

log = get_logger('baljan.orders', with_sentry=False)
prelog = get_logger('baljan.orders.pre', with_sentry=False)
rebatelog = get_logger('baljan.orders.rebate', with_sentry=False)

class Processed(object):
    default_reason = _("The order was processed.") 

    def __init__(self, preorder, reason=None):
        self.free = preorder.free
        self.rebate = preorder.rebate
        self.preorder = preorder
        self.reason = self.default_reason if reason is None else reason

    def accepted(self):
        raise NotImplementedError()

    def create_order_and_update_balance(self):
        raise NotImplementedError()

Beispiel #24
0
from django.conf import settings
from django.contrib.auth.models import User, Group
import MySQLdb
import MySQLdb.cursors
from datetime import date, datetime
from baljan.models import Profile, Semester, ShiftSignup, Shift, BoardPost
from baljan.models import OnCallDuty, Good, Order
from baljan.models import OldCoffeeCard, OldCoffeeCardSet
from baljan.util import get_logger, get_or_create_user
from baljan import pseudogroups
from baljan import orders
from dateutil.relativedelta import relativedelta
import re
from emailconfirmation.models import EmailAddress

log = get_logger('baljan.migration', with_sentry=False)

manual_board = []

class Import(object):
    def __init__(self):
        self._users = {}

        # Make sure that all needed settings and such are configured.
        settingfmt = 'OLD_SYSTEM_MYSQL_%s'
        valid = True
        errs = []
        for setting in (
                'LOGIN',
                'PASSWORD',
                'DB',
Beispiel #25
0
def job_opening(request, semester_name):
    opening_log = get_logger('baljan.jobopening')
    tpl = {}
    tpl['semester'] = sem = baljan.models.Semester.objects.get(name__exact=semester_name)
    user = request.user

    found_user = None
    if request.method == 'POST':
        if request.is_ajax(): # find user
            searched_for = request.POST['liu_id']
            valid_search = valid_username(searched_for)

            if valid_search:
                results = baljan.search.for_person(searched_for, use_cache=False)
                if len(results) == 1:
                    found_user = results[0]

            if valid_search and found_user is None:
                # FIXME: User should not be created immediately. First we 
                # should tell whether or not he exists, then the operator
                # may choose to import the user.
                if exists_in_ldap(searched_for):
                    opening_log.info('%s found in LDAP' % searched_for)
                    found_user = fetch_user(searched_for)
                else:
                    opening_log.info('%s not found in LDAP' % searched_for)

            info = {}
            info['user'] = None
            info['msg'] = _('enter liu id')
            info['msg_class'] = 'pending'
            info['all_ok'] = False
            if found_user:
                info['user'] = {
                        'username': found_user.username,
                        'text': "%s (%s)" % (
                            found_user.get_full_name(), 
                            found_user.username
                        ),
                        'phone': found_user.get_profile().mobile_phone,
                        'url': found_user.get_absolute_url(),
                        }
                info['msg'] = _('OK')
                info['msg_class'] = 'saved'
                info['all_ok'] = True
            else:
                if valid_search:
                    info['msg'] = _('liu id unfound')
                    info['msg_class'] = 'invalid'
            return HttpResponse(simplejson.dumps(info))
        else: # the user hit save, assign users to shifts
            shift_ids = [int(x) for x in request.POST['shift-ids'].split('|')]
            usernames = request.POST['user-ids'].split('|')
            phones = request.POST['phones'].split('|')

            # Update phone numbers.
            for uname, phone in zip(usernames, phones):
                try:
                    to_update = baljan.models.Profile.objects.get(
                        user__username__exact=uname
                    )
                    to_update.mobile_phone = phone
                    to_update.save()
                except:
                    opening_log.error('invalid phone for %s: %r' % (uname, phone))

            # Assign to shifts.
            shifts_to_save = baljan.models.Shift.objects.filter(pk__in=shift_ids)
            users_to_save = User.objects.filter(username__in=usernames)
            for shift_to_save in shifts_to_save:
                for user_to_save in users_to_save:
                    signup, created = baljan.models.ShiftSignup.objects.get_or_create(
                        user=user_to_save,
                        shift=shift_to_save
                    )
                    if created:
                        opening_log.info('%r created' % signup)
                    else:
                        opening_log.info('%r already existed' % signup)

    sched = workdist.Scheduler(sem)
    pairs = sched.pairs_from_db()
    slots = _pair_matrix(pairs)

    pair_javascript = {}
    for pair in pairs:
        pair_javascript[pair.label] = {
            'shifts': [unicode(sh.name()) for sh in pair.shifts],
            'ids': [sh.pk for sh in pair.shifts],
        }

    tpl['slots'] = slots
    tpl['pair_javascript'] = simplejson.dumps(pair_javascript)
    tpl['pairs_free'] = pairs_free = len([p for p in pairs if p.is_free()])
    tpl['pairs_taken'] = pairs_taken = len([p for p in pairs if p.is_taken()])
    tpl['pairs_total'] = pairs_total = pairs_free + pairs_taken
    tpl['pairs_taken_percent'] = int(round(pairs_taken * 100.0 / pairs_total))
    return render_to_response('baljan/job_opening.html', tpl, 
            context_instance=RequestContext(request))
Beispiel #26
0
# -*- coding: utf-8 -*-
from baljan.util import get_logger
from django.conf import settings
from threading import Lock
from time import sleep
import serial
import string
from baljan.parport import ParPort
from datetime import datetime
from celery.decorators import task

log = get_logger('baljan.lcd', with_sentry=False)

SEND_SLEEP_SECONDS = 0.0021

BYTE_CMD = chr(254)
CMD_ROWS = [
    BYTE_CMD + chr(128), # move cursor to 0th col in row 0
    BYTE_CMD + chr(192), # move cursor to 0th col in row 1
]
CMD_CLEAR = BYTE_CMD + chr(1)

ADUNO = u'\\(o_O)/'

COLS = 16
ROWS = len(CMD_ROWS)

def encode(msg):
    """`msg` will be converted to a regular string if it is of unicode type.
    """
    # TODO: make complete
Beispiel #27
0
# -*- coding: utf-8 -*-
from baljan.models import BalanceCode, OldCoffeeCard
from datetime import datetime
from baljan.util import get_logger
from datetime import datetime
from django.conf import settings

log = get_logger('baljan.credits')

class CreditsError(Exception):
    pass

class BadCode(CreditsError):
    pass

def used_by(user, old_card=False):
    if old_card:
        return OldCoffeeCard.objects.filter(
            user=user,
        ).order_by('-id')
    else:
        return BalanceCode.objects.filter(
            used_by=user,
        ).order_by('-used_at', '-id')


def get_unused_code(entered_code, old_card=False):
    """Can return either an `OldCoffeeCard` or a `BalanceCode` depending
    on the value of the `old_card` parameter."""
    now = datetime.now()
    try:
Beispiel #28
0
# -*- coding: utf-8 -*-
import os
from subprocess import Popen, PIPE
from django.conf import settings
from baljan.util import get_logger

log = get_logger('baljan.sounds', with_sentry=False)

class SoundError(Exception):
    pass
class NoSuchFile(SoundError):
    pass
class CouldNotPlay(SoundError):
    pass


class Sound(object):
    def __init__(self, basename):
        self.path = os.path.join(settings.SOUND_DIR, basename)
        if os.path.isfile(self.path):
            pass
        else:
            msg = "%r does not exist" % self.path
            log.error(msg)
            raise NoSuchFile(msg)

    def play(self):
        """Blocking."""
        p = Popen([settings.SOUND_CMD, self.path],
            stdin=PIPE,
            stderr=PIPE,
Beispiel #29
0
# -*- coding: utf-8 -*-

from django.contrib.auth.models import User, Permission, Group
from django.conf import settings
from django.utils.translation import ugettext as _ 
from baljan.models import Semester, BoardPost
from baljan.util import get_logger
from django.db.models import Q
from datetime import date, datetime

log = get_logger('baljan.pseudogroups')

def real_only():
    return Group.objects.all().exclude(name__startswith='_')

class PseudoGroupError(Exception):
    pass

def _semname(is_spring, year):
    pre = 'HT'
    if is_spring:
        pre = 'VT'
    return "%s%d" % (pre, year)


def manual_group_from_semester(base_group, sem):
    return manual_group(base_group, sem.spring(), sem.year())


def manual_group(base_group, is_spring, year):
    if base_group.name == settings.BOARD_GROUP: