示例#1
0
文件: models.py 项目: sistason/pa3
class WaitingNumberBatch(models.Model):
    choices_src = list(
        zip(USER_TO_NAMES.keys(),
            [i.get('placement', '?') for i in USER_TO_NAMES.values()]))
    src = models.CharField(choices=choices_src, db_index=True, max_length=50)
    src_ip = models.GenericIPAddressField()

    date = models.DateTimeField(db_index=True, default=timezone.now)
    date_delta = models.IntegerField(null=True)
    proc_delay = models.FloatField(null=True)
    numbers = models.ManyToManyField(WaitingNumber)

    class Meta:
        ordering = ['-date', 'src']

    def __unicode__(self):
        return '{} | {}'.format(self.src, str(self.date))

    def serialize_numbers(self, verbose=False):
        return [num.serialize(verbose) for num in self.numbers.all()]

    def serialize(self, verbose=False):
        return {
            'src': self.src,
            'date': self.date.strftime('%s'),
            'src_ip': self.src_ip,
            'numbers': [num.serialize(verbose) for num in self.numbers.all()],
            'proc_delay': self.proc_delay,
            'date_delta': self.date_delta,
            'placement': USER_TO_NAMES.get(self.src, {}).get('placement')
        }
示例#2
0
def get_current_numbers(src=None):
    sources = [src] if src in USER_TO_NAMES.keys() else USER_TO_NAMES.keys()
    data = []
    for k in sources:
        try:
            newest = NewestNumberBatch.objects.get(src=k)
            data.append(newest.serialize(verbose=True))
        except ObjectDoesNotExist:
            logging.warning(
                'Warning! Database for the Display above Room {} is empty!'.
                format(k))

    return data
示例#3
0
def get_config(request):
    if not request.POST or 'user' not in request.POST or 'password' not in request.POST:
        logger.info("Received an invalid config request {} from {}".format(request.POST,
                                                                           request.META.get('HTTP_X_FORWARDED_FOR')))
        return HttpResponse(status=401, content='POST request incomplete!\n')

    user = request.POST.get('user')
    if user not in USER_TO_NAMES.keys() or RECOGNIZER_AUTH != request.POST.get('password'):
        logger.info("Received an unauthorized config request {} from {}".format(request.POST,
                                                                                request.META.get('HTTP_X_FORWARDED_FOR')))
        return HttpResponse(status=401, content="permission denied!\n")

    config = RECOGNIZER_CONFIG.get(user)

    num_batches_newest = NewestNumberBatch.objects.filter(src=user)
    if num_batches_newest.exists():
        config['current_numbers'] = num_batches_newest.latest('date').newest.serialize_numbers()
    else:
        num_batches = WaitingNumberBatch.objects.filter(src=user)
        if num_batches.exists():
            config['current_numbers'] = num_batches.latest('date').serialize_numbers()

    template_path = os.path.join(RECOGNITION_TEMPLATES_PATH, 'template_{}.png'.format(user))
    if os.path.exists(template_path):
        with open(template_path, 'rb') as f:
            config['template'] = b64encode(f.read()).decode('utf-8')

    digit_mask_path = os.path.join(RECOGNITION_TEMPLATES_PATH, 'digit_mask.png')
    if os.path.exists(digit_mask_path):
        with open(digit_mask_path, 'rb') as f:
            config['digit_mask'] = b64encode(f.read()).decode('utf-8')

    return JsonResponse(config, safe=False)
示例#4
0
文件: models.py 项目: sistason/pa3
 def serialize(self, verbose=False):
     return {
         'src': self.src,
         'date': self.date.strftime('%s'),
         'src_ip': self.src_ip,
         'numbers': [num.serialize(verbose) for num in self.numbers.all()],
         'proc_delay': self.proc_delay,
         'date_delta': self.date_delta,
         'placement': USER_TO_NAMES.get(self.src, {}).get('placement')
     }
示例#5
0
def api(request, pa=None):
    src = [pa] if pa else USER_TO_NAMES.keys()
    result = {'entries': [], 'errors': [], 'openings': OPENINGS}

    for s in src:
        try:
            newest = NewestNumberBatch.objects.get(src=s)
            result['entries'].append(newest.newest.serialize())
        except (MultipleObjectsReturned, ObjectDoesNotExist):
            result['errors'].append("Pruefungsamt '{}' not found!".format(s))

    return HttpResponse(json.dumps(result),
                        content_type='application/json; charset=utf8')
示例#6
0
文件: models.py 项目: sistason/pa3
class NewestNumberBatch(models.Model):
    # To minimze database queries, the newest Batch gets stored seperately and
    # only contains the newest WaitingNumberBatch
    choices_src = list(
        zip(USER_TO_NAMES.keys(),
            [i.get('placement', '?') for i in USER_TO_NAMES.values()]))
    src = models.CharField(choices=choices_src, max_length=50)
    date = models.DateTimeField()
    newest = models.ForeignKey(WaitingNumberBatch, on_delete=None)

    def __unicode__(self):
        return '{} | {}'.format(self.src, str(self.newest))

    def serialize(self, verbose=False):
        serialized = {
            'newest': self.newest.serialize(verbose),
            'date': self.date.strftime('%s')
        }
        if verbose:
            updated = (timezone.now() - self.date).seconds
            serialized['updated'] = "" if updated < 10 else _(
                "Warning! Last check {} ago".format(
                    timesincesecondsonly(self.date)))
        return serialized
示例#7
0
def check_notify(request):
    down = []
    for k in USER_TO_NAMES.keys():
        try:
            newest = NewestNumberBatch.objects.get(src=k)
        except (ObjectDoesNotExist, MultipleObjectsReturned):
            continue
        offline_m = (timezone.now() - newest.date).seconds / 60
        if offline_m > 5:
            status = '{0} down for {1} minutes'.format(k, int(offline_m))
            down.append(status)
            if (offline_m < 60 or not offline_m % 10) and offline_m < 600:
                logger_req.fatal(status)
    return HttpResponse(
        status=200,
        content='Everything\'s fine' if not down else '\n'.join(down))
示例#8
0
def api2(request, paT=None, ops=None, pa=None):
    entries = []

    pa_rooms = [paT] if paT else USER_TO_NAMES.keys()
    for pa_room in pa_rooms:
        try:
            newest = NewestNumberBatch.objects.get(
                src=pa_room)  # get newest WaitingNumberBatch via newest-table
        except (MultipleObjectsReturned, ObjectDoesNotExist):
            #			dict['errors'].append("Table '%s' not found!" % pa_room)
            continue
        num = newest.newest
        nums = num.numbers.all()

        nums = nums.filter(src='H ' + pa) if pa else nums
        if not nums:
            #			dict['errors'].append("Pruefungsamt '%s' not found!" % pa)
            continue

        ticket_place = {
            "type":
            "Place",
            "uid":
            _md5.md5(str(pa_room)).hexdigest(),
            "subType":
            "Prüfungsamt",
            "name":
            pa_room,
            "alternateName": ["H {0}".format(pa_room)],
            "url":
            "http://www.pruefungen.tu-berlin.de/",
            "description":
            "Prüfungsamt der TU Berlin, Raum {0}".format(pa_room),
            "image":
            "http://www.tu-berlin.de/fileadmin/Aperto_design/img/logo_01.gif",
            "video":
            "https://www.youtube.com/watch?v=BROWqjuTM0g",
            "address": {
                "addressCountry": "Germany",
                "addressLocality": "Berlin",
                "addressRegion": "Berlin",
                "postOfficeBoxNumber": "",
                "postalCode": "10623",
                "streetAddress": "Straße des 17. Juni 135"
            },
            "openingHours": [{
                'opens':
                ':'.join([str(op['begin'])[:-2],
                          str(op['begin'])[-2:]]),
                'closes':
                ':'.join([str(op['end'])[:-2],
                          str(op['end'])[-2:]]),
                'validFrom':
                timezone.datetime(1970, 1, 1).ctime(),
                'validThrough':
                timezone.datetime(2030, 1, 1).ctime(),
                'dayOfWeek':
                timezone.datetime(1970, 1, 4 + op['weekday']).strftime('%A')
            } for op in OPENINGS if op.has_key('begin')],
            "geo": {
                "type":
                "GeoShape",
                "uid":
                "74398574398768945874",
                "polygon": [
                    "12.323590,53.518139,0.000000",
                    "13.324133,53.518108,1.000000",
                    "14.323690,-53.518250,2.000000",
                    "15.323590,-53.518139,3.000000"
                ]
            }
        }

        for src_counter in nums:
            try:
                avg = StatisticalData.objects.get(
                    src=src_counter.src).avg_whole
            except (MultipleObjectsReturned, ObjectDoesNotExist):
                #				dict['errors'].append("Statistical Data for {0} not availible!".format(src_counter.src))
                avg = 0

            ticket = {
                'type':
                "Ticket",
                'uid':
                _md5.md5(str(src_counter.pk)).hexdigest(),
                'currentTicketNumber':
                src_counter.number,
                'approxwaittime':
                (timezone.now() + timezone.timedelta(0, int(avg))).ctime(),
                'date':
                src_counter.date.ctime(),
                'room':
                src_counter.src,
                'servicetype': {
                    "name": "Prüfungsamt"
                },
                'counter':
                src_counter.pk,
            }
            ticket_place_copy = copy.deepcopy(ticket_place)
            ticket['place'] = ticket_place_copy

            entries.append(ticket)

    resp = HttpResponse(json.dumps(entries),
                        content_type='application/json; charset=utf8')
    resp['Access-Control-Allow-Origin'] = '*'
    return resp
示例#9
0
def write(request):
    if not request.POST or not {'user', 'password', 'ts',
                                'numbers', 'begin'}.issubset(request.POST):
        logger.info("received an invalid write request: %s" % request)
        return HttpResponse(status=401, content='POST request incomplete!\n')

    if request.POST.get('user') not in USER_TO_NAMES.keys() or \
            RECOGNIZER_AUTH != request.POST.get('password'):
        logger.info("received an unauthorized write request: %s" % request)
        return HttpResponse(status=401, content="permission denied!\n")

    #---------------------- validating input ---------------------

    numbers = []
    for number in request.POST.get('numbers', '').strip().split(' '):
        if number.isdigit():
            numbers.append(int(number))
        else:
            numbers.append(-1)

    try:
        ts = int(request.POST.get('ts', 0))
        begin_ts = float(request.POST.get('begin', 0.0))
    except ValueError:
        ts = 0
        begin_ts = 0.0

    src = request.POST.get('user')
    displays = USER_TO_NAMES.get(src, {}).get('displays', [])

    logging.warning(src)
    logging.warning(ts)
    logging.warning(begin_ts)
    logging.warning(len(numbers))
    logging.warning(len(displays))

    if not src or not ts or not begin_ts \
            or len(numbers) != len(displays):
        return HttpResponse(status=400, content='did not validate!\n')

    request_ip = request.META.get('HTTP_X_FORWARDED_FOR', '')
    if not request_ip:
        request_ip = request.META.get('REMOTE_ADDR', '')

    # get todays opening times for validation
    date_ = timezone.datetime.fromtimestamp(ts, tz=pytz.timezone(TIME_ZONE))
    for i_ in OPENINGS:
        if date_.isoweekday() == i_['weekday']:
            opening_time = i_
            break
    else:
        opening_time = None

    num_batch_newest, old_num_batch = _get_old_batches(src)
    old_numbers = list(old_num_batch.numbers.all()) if old_num_batch else []
    new_batch = None
    for num, _src in zip(numbers, displays):
        if _src == "H 25":
            num += 1000     # H25 hat ne angetapte 1 vorne dran
        old_num_obj = None
        if old_num_batch is not None:
            old_number_ = [i for i in old_numbers if i.src == _src]
            if old_number_:
                old_num_obj = old_number_[0]
                if old_num_obj.number == num or num == -1:
                    # if number stays or comes outside of the opening times, just update
                    continue
                #    if not opening_time or 'begin' not in opening_time or \
                #        opening_time['begin'] > int(date_.strftime('%H%M')) or \
                #        opening_time['end'] < int(date_.strftime('%H%M'))-60:    #60min buffer
                #       continue

        # compute delta, if not first DB-Entry
        new_number_date_delta = (date_ - old_num_obj.date).seconds if old_num_obj else -1
        src_statistic = statistics_handling.get_src_statistic(_src)
        if src_statistic is None:
            src_statistic = statistics_handling.create_statistic(_src, date_)
        new_num_obj = WaitingNumber(number=num, src=_src, date=date_,
                                    date_delta=new_number_date_delta,
                                    proc_delay=time.time() - begin_ts,
                                    statistic=src_statistic)
        new_num_obj.save()

        if not new_batch:
            # proc_delay will be set after EVERYTHING else
            new_batch = WaitingNumberBatch(src=src, src_ip=request_ip, date=date_, proc_delay=None,
                                           date_delta=(date_-old_num_batch.date).seconds if old_num_batch else -1)
            new_batch.save()
            [new_batch.numbers.add(i) for i in old_numbers]

        [new_batch.numbers.remove(i) for i in old_numbers if i.src == _src]
        new_batch.numbers.add(new_num_obj)

        if new_number_date_delta < (opening_time.get('end', 0)-opening_time.get('begin', 0))*60:
            # Update Stats if num is not first of the day, e.g. date_delta < openings
            statistics_handling.update_statistic(_src, new_number_date_delta, new_batch, date_)

        for subscriber in Subscriber.objects.filter(src=_src, protocol='sms'):
            subscriber.handle(num)

    if num_batch_newest is None:
        num_batch_newest = NewestNumberBatch(src=src, newest=old_num_batch)
    if new_batch:
        new_batch.proc_delay = time.time() - begin_ts
        new_batch.save()
        # replace NewestNumberBatch
        num_batch_newest.newest = new_batch

    num_batch_newest.date = date_
    num_batch_newest.save()

    if request.FILES:
        _save_images(request, displays)

    return HttpResponse(status=201)
示例#10
0
文件: models.py 项目: sistason/pa3
from django.db import models
from django.utils.translation import ugettext as _
from django.utils import timezone

from pa3.settings import USER_TO_NAMES
from pa3_web.templatetags.pa3_timesinceseconds import timesincesecondsonly, timesinceseconds

all_displays = []
[all_displays.extend(i.get('displays', [])) for i in USER_TO_NAMES.values()]
choices_displays = zip(all_displays, all_displays)


class StatisticalData(models.Model):
    # Stores statistical information on the numbers, to minimize the
    # computation effort
    src = models.CharField(max_length=50, choices=choices_displays)

    date = models.DateTimeField(default=timezone.now)  # for sorting purposes

    avg = models.FloatField(default=0.0)  # current Average
    avg_len = models.IntegerField(
        default=-1)  # Length over which the avg is computed (count())
    avg_sum = models.IntegerField(
        default=0)  # Sum from which the avg is computed (avg=sum/len)

    avg_proc_delay_sum = models.IntegerField(
        default=0
    )  # Sum from which the avg_proc_delay is computed (avg=sum/len)
    avg_proc_delay_len = models.IntegerField(
        default=-1
    )  # Len from which the avg_proc_delay is computed (avg=sum/len)