-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cherijs develop #29
Cherijs develop #29
Changes from all commits
0e12a2d
a00b0df
fc5de76
a7a18fc
1ad7809
605a03b
3b33657
7a69f41
6d6d7b2
ed0c197
020428c
203f19c
4a9b21f
7efc96f
aa5e3d2
88d14e1
3c3178e
9e08466
3d4b755
62cd074
4daee23
2127221
160a175
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,104 @@ | ||
from django.contrib import admin | ||
from django_walletpass.models import Pass, Registration, Log | ||
from django.template import Context, Template | ||
from django.urls import reverse | ||
from django.utils.html import format_html | ||
|
||
admin.site.register(Pass) | ||
admin.site.register(Registration) | ||
admin.site.register(Log) | ||
from django_walletpass.models import Log, Pass, Registration | ||
|
||
|
||
@admin.register(Log) | ||
class LogAdmin(admin.ModelAdmin): | ||
list_display = ( | ||
"created_at", | ||
"status", | ||
"task_type", | ||
# "pass_type_identifier", | ||
# "serial_number", | ||
"pass_", | ||
# "web_service_url", | ||
"device_id", | ||
"msg", | ||
) | ||
list_filter = ("status", "task_type", "pass_type_identifier") | ||
search_fields = ( | ||
"pass_type_identifier", | ||
"serial_number", | ||
"device_id", | ||
"msg", | ||
"message", | ||
) | ||
readonly_fields = ("created_at", "pass_") | ||
raw_id_fields = ("pazz",) | ||
list_select_related = ("pazz",) | ||
|
||
def pass_(self, obj: Log): | ||
if obj.pazz_id: | ||
url = reverse( | ||
"admin:%s_%s_change" | ||
% (obj.pazz._meta.app_label, obj.pazz._meta.model_name), | ||
args=[obj.pazz_id], | ||
) | ||
return format_html( | ||
"<a href='{url}'>{title}</a>", | ||
url=url, | ||
title=obj.serial_number, | ||
) | ||
return obj.serial_number | ||
|
||
pass_.short_description = "Pass" | ||
|
||
|
||
@admin.register(Pass) | ||
class PassAdmin(admin.ModelAdmin): | ||
list_display = ( | ||
"serial_number", | ||
"updated_at", | ||
"pass_type_identifier", | ||
"wallet_pass_", | ||
) | ||
search_fields = ( | ||
"serial_number", | ||
"pass_type_identifier", | ||
"authentication_token", | ||
"data", | ||
) | ||
list_filter = ("pass_type_identifier", "updated_at") | ||
date_hierarchy = "updated_at" | ||
readonly_fields = ("wallet_pass_", "updated_at") | ||
|
||
def wallet_pass_(self, obj: Pass): | ||
if obj.data: | ||
return format_html( | ||
Template( | ||
"{% load static %}<a href='{url}' alt='{title}'><img src='{% static 'admin/passbook_icon.svg' %}'/></a>" | ||
).render(Context({})), | ||
url=obj.data.url, | ||
title=obj.data.name, | ||
) | ||
return | ||
|
||
wallet_pass_.short_description = "Pass" | ||
|
||
|
||
@admin.register(Registration) | ||
class RegistrationAdmin(admin.ModelAdmin): | ||
list_display = ("device_library_identifier", "push_token", "pass_") | ||
search_fields = ("device_library_identifier", "push_token", "pazz__serial_number") | ||
raw_id_fields = ("pazz",) | ||
readonly_fields = ("pass_",) | ||
|
||
def pass_(self, obj: Registration): | ||
if obj.pazz_id: | ||
url = reverse( | ||
"admin:%s_%s_change" | ||
% (obj.pazz._meta.app_label, obj.pazz._meta.model_name), | ||
args=[obj.pazz_id], | ||
) | ||
return format_html( | ||
"<a href='{url}'>{title}</a>", | ||
url=url, | ||
title=obj.pazz.serial_number, | ||
) | ||
return | ||
|
||
pass_.short_description = "Pass" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Generated by Django 3.2.14 on 2023-07-09 18:43 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import django.utils.timezone | ||
import django_walletpass.storage | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('django_walletpass', '0008_alter_pass_data'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='log', | ||
name='created_at', | ||
field=models.DateTimeField(default=django.utils.timezone.now), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='device_id', | ||
field=models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='msg', | ||
field=models.TextField(blank=True, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='pass_type_identifier', | ||
field=models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='pazz', | ||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='logs', to='django_walletpass.pass'), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='serial_number', | ||
field=models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='status', | ||
field=models.CharField(blank=True, max_length=100, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='task_type', | ||
field=models.CharField(blank=True, max_length=255, null=True), | ||
), | ||
migrations.AddField( | ||
model_name='log', | ||
name='web_service_url', | ||
field=models.URLField(blank=True, null=True), | ||
), | ||
migrations.AlterField( | ||
model_name='pass', | ||
name='data', | ||
field=models.FileField(storage=django_walletpass.storage.WalletPassStorage(), upload_to='passes'), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Generated by Django 3.2.14 on 2023-07-13 10:41 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('django_walletpass', '0009_auto_20230709_2143'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name='registration', | ||
name='push_token', | ||
field=models.CharField(max_length=255), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
import datetime | ||
import os | ||
import re | ||
import uuid | ||
import hashlib | ||
import json | ||
|
@@ -7,6 +9,7 @@ | |
import zipfile | ||
from glob import glob | ||
from django.core.exceptions import ValidationError | ||
from django.utils import timezone | ||
from django.utils.module_loading import import_string | ||
from django.db import models | ||
from django.utils.translation import gettext_lazy as _ | ||
|
@@ -285,6 +288,9 @@ def get_pass_builder(self): | |
def __unicode__(self): | ||
return self.serial_number | ||
|
||
def __str__(self): | ||
return self.serial_number | ||
|
||
class Meta: | ||
verbose_name_plural = "passes" | ||
unique_together = ( | ||
|
@@ -298,7 +304,7 @@ class Registration(models.Model): | |
Registration of a Pass on a device | ||
""" | ||
device_library_identifier = models.CharField(max_length=150) | ||
push_token = models.CharField(max_length=150) | ||
push_token = models.CharField(max_length=255) | ||
pazz = models.ForeignKey( | ||
Pass, | ||
on_delete=models.CASCADE, | ||
|
@@ -308,12 +314,83 @@ class Registration(models.Model): | |
def __unicode__(self): | ||
return self.device_library_identifier | ||
|
||
def __str__(self): | ||
return self.device_library_identifier | ||
|
||
|
||
class Log(models.Model): | ||
""" | ||
Log message sent by a device | ||
""" | ||
created_at = models.DateTimeField(default=timezone.now) | ||
status = models.CharField(max_length=100, null=True, blank=True) | ||
task_type = models.CharField(max_length=255, null=True, blank=True) | ||
pass_type_identifier = models.CharField(max_length=255, null=True, blank=True) | ||
serial_number = models.CharField(max_length=255, null=True, blank=True) | ||
pazz = models.ForeignKey(Pass, null=True, blank=True, on_delete=models.CASCADE, related_name='logs') | ||
web_service_url = models.URLField(null=True, blank=True) | ||
device_id = models.CharField(max_length=255, null=True, blank=True) | ||
msg = models.TextField(null=True, blank=True) | ||
message = models.TextField() | ||
|
||
def __unicode__(self): | ||
return self.message | ||
|
||
def __str__(self): | ||
return self.created_at.strftime('%d/%m/%y %H:%M:%S') | ||
|
||
@classmethod | ||
def parse_log(cls, log, message): | ||
pattern_register = r"\[(.*?)\]\s(.*?)\s\(for device (.*?), pass type (.*?), serial number (.*?); with web service url (.*?)\)\s(.*?): (.*$)" | ||
pattern_get = r"\[(.*?)\]\s(.*?)\s\(pass type (.*?), serial number (.*?), if-modified-since \(.*?\); with web service url (.*?)\) (.*?): (.*$)" | ||
pattern_web_service_error = r"\[(.*?)\]\s(.*?)\sfor (.*?)\s\((.*?)\):\s(.*$)" | ||
pattern_get_warning = r"\[(.*?)\]\s(.*?)\s\(pass type (.*?), serial number (.*?), if-modified-since \(.*?\); with web service url (.*?)\) (.*?): (.*\.)\s(.*$)" | ||
|
||
match_register = re.match(pattern_register, message) | ||
match_get = re.match(pattern_get, message) | ||
match_web_service_error = re.match(pattern_web_service_error, message) | ||
match_get_warning = re.match(pattern_get_warning, message) | ||
|
||
if match_register: | ||
timestamp_str, task_type, device_id, pass_type_identifier, serial_number, web_service_url, status, msg = match_register.groups() | ||
elif match_get: | ||
timestamp_str, task_type, pass_type_identifier, serial_number, web_service_url, status, msg = match_get.groups() | ||
device_id = None # 'Get pass task' entries don't include device_id | ||
elif match_web_service_error: | ||
timestamp_str, task_type, pass_type_identifier, web_service_url, msg = match_web_service_error.groups() | ||
serial_number = None | ||
device_id = None | ||
status = "error" | ||
elif match_get_warning: | ||
timestamp_str, task_type, pass_type_identifier, serial_number, web_service_url, status, msg = match_get_warning.groups() | ||
device_id = None | ||
status = "warning" | ||
else: | ||
log.status = 'unknown' | ||
log.message = message | ||
log.save() | ||
return # Log entry didn't match any known pattern | ||
|
||
if 'error' in status: | ||
status = 'error' | ||
elif 'warning' in status: | ||
status = 'warning' | ||
|
||
log.created_at = datetime.datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S %z") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will crash if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good morning, the final There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ohh, true! hmmm... 🤔... maybe add a new TextField and store the raw received message? This way we won't loose any messages (that might be useful, but we didn't have the right pattern match for them). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😅 time for another coffee I guess |
||
log.status = status | ||
log.task_type = task_type | ||
log.device_id = device_id | ||
log.pass_type_identifier = pass_type_identifier | ||
log.serial_number = serial_number | ||
log.web_service_url = web_service_url | ||
log.msg = msg | ||
log.message = message | ||
|
||
if serial_number: | ||
try: | ||
pazz = Pass.objects.get(serial_number=serial_number) | ||
log.pazz = pazz | ||
except Pass.DoesNotExist: | ||
pass | ||
|
||
log.save() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍