signature.py
150 lines
| 4.4 KiB
| text/x-python
|
PythonLexer
neko259
|
r827 | import xml.etree.ElementTree as et | ||
neko259
|
r820 | from django.db import models | ||
neko259
|
r1560 | from boards.models import KeyPair | ||
neko259
|
r820 | |||
neko259
|
r841 | TAG_MODEL = 'model' | ||
TAG_REQUEST = 'request' | ||||
TAG_ID = 'id' | ||||
TYPE_GET = 'get' | ||||
neko259
|
r1566 | TYPE_LIST = 'list' | ||
neko259
|
r841 | |||
ATTR_VERSION = 'version' | ||||
ATTR_TYPE = 'type' | ||||
ATTR_NAME = 'name' | ||||
neko259
|
r827 | ATTR_KEY = 'key' | ||
ATTR_KEY_TYPE = 'type' | ||||
ATTR_LOCAL_ID = 'local-id' | ||||
neko259
|
r841 | class GlobalIdManager(models.Manager): | ||
def generate_request_get(self, global_id_list: list): | ||||
""" | ||||
Form a get request from a list of ModelId objects. | ||||
""" | ||||
request = et.Element(TAG_REQUEST) | ||||
request.set(ATTR_TYPE, TYPE_GET) | ||||
request.set(ATTR_VERSION, '1.0') | ||||
model = et.SubElement(request, TAG_MODEL) | ||||
model.set(ATTR_VERSION, '1.0') | ||||
model.set(ATTR_NAME, 'post') | ||||
for global_id in global_id_list: | ||||
tag_id = et.SubElement(model, TAG_ID) | ||||
global_id.to_xml_element(tag_id) | ||||
return et.tostring(request, 'unicode') | ||||
neko259
|
r1566 | def generate_request_list(self): | ||
neko259
|
r1321 | """ | ||
Form a pull request from a list of ModelId objects. | ||||
""" | ||||
request = et.Element(TAG_REQUEST) | ||||
neko259
|
r1566 | request.set(ATTR_TYPE, TYPE_LIST) | ||
neko259
|
r1321 | request.set(ATTR_VERSION, '1.0') | ||
model = et.SubElement(request, TAG_MODEL) | ||||
model.set(ATTR_VERSION, '1.0') | ||||
model.set(ATTR_NAME, 'post') | ||||
return et.tostring(request, 'unicode') | ||||
neko259
|
r1232 | def global_id_exists(self, global_id): | ||
""" | ||||
Checks if the same global id already exists in the system. | ||||
""" | ||||
return self.filter(key=global_id.key, | ||||
key_type=global_id.key_type, | ||||
local_id=global_id.local_id).exists() | ||||
neko259
|
r841 | |||
neko259
|
r820 | class GlobalId(models.Model): | ||
neko259
|
r1520 | """ | ||
Global model ID and cache. | ||||
Key, key type and local ID make a single global identificator of the model. | ||||
Content is an XML cache of the model that can be passed along between nodes | ||||
without manual serialization each time. | ||||
""" | ||||
neko259
|
r820 | class Meta: | ||
app_label = 'boards' | ||||
neko259
|
r841 | objects = GlobalIdManager() | ||
neko259
|
r820 | def __init__(self, *args, **kwargs): | ||
models.Model.__init__(self, *args, **kwargs) | ||||
if 'key' in kwargs and 'key_type' in kwargs and 'local_id' in kwargs: | ||||
self.key = kwargs['key'] | ||||
self.key_type = kwargs['key_type'] | ||||
self.local_id = kwargs['local_id'] | ||||
key = models.TextField() | ||||
key_type = models.TextField() | ||||
local_id = models.IntegerField() | ||||
neko259
|
r1519 | content = models.TextField(blank=True, null=True) | ||
neko259
|
r820 | |||
def __str__(self): | ||||
neko259
|
r841 | return '%s::%s::%d' % (self.key_type, self.key, self.local_id) | ||
neko259
|
r820 | |||
neko259
|
r836 | def to_xml_element(self, element: et.Element): | ||
neko259
|
r827 | """ | ||
Exports global id to an XML element. | ||||
""" | ||||
element.set(ATTR_KEY, self.key) | ||||
element.set(ATTR_KEY_TYPE, self.key_type) | ||||
element.set(ATTR_LOCAL_ID, str(self.local_id)) | ||||
neko259
|
r836 | @staticmethod | ||
neko259
|
r1233 | def from_xml_element(element: et.Element): | ||
neko259
|
r836 | """ | ||
Parses XML id tag and gets global id from it. | ||||
Arguments: | ||||
element -- the XML 'id' element | ||||
neko259
|
r1233 | |||
Returns: | ||||
global_id -- id itself | ||||
exists -- True if the global id was taken from database, False if it | ||||
did not exist and was created. | ||||
neko259
|
r836 | """ | ||
neko259
|
r1233 | try: | ||
neko259
|
r836 | return GlobalId.objects.get(key=element.get(ATTR_KEY), | ||
key_type=element.get(ATTR_KEY_TYPE), | ||||
local_id=int(element.get( | ||||
neko259
|
r1233 | ATTR_LOCAL_ID))), True | ||
except GlobalId.DoesNotExist: | ||||
neko259
|
r836 | return GlobalId(key=element.get(ATTR_KEY), | ||
key_type=element.get(ATTR_KEY_TYPE), | ||||
neko259
|
r1233 | local_id=int(element.get(ATTR_LOCAL_ID))), False | ||
neko259
|
r836 | |||
neko259
|
r1560 | def is_local(self): | ||
"""Checks fo the ID is local model's""" | ||||
return KeyPair.objects.filter( | ||||
key_type=self.key_type, public_key=self.key).exists() | ||||
neko259
|
r820 | |||
class Signature(models.Model): | ||||
class Meta: | ||||
app_label = 'boards' | ||||
neko259
|
r837 | def __init__(self, *args, **kwargs): | ||
models.Model.__init__(self, *args, **kwargs) | ||||
if 'key' in kwargs and 'key_type' in kwargs and 'signature' in kwargs: | ||||
self.key_type = kwargs['key_type'] | ||||
self.key = kwargs['key'] | ||||
self.signature = kwargs['signature'] | ||||
neko259
|
r820 | key_type = models.TextField() | ||
key = models.TextField() | ||||
signature = models.TextField() | ||||
neko259
|
r1242 | |||
global_id = models.ForeignKey('GlobalId') | ||||