-
Notifications
You must be signed in to change notification settings - Fork 55
/
creative.py
86 lines (64 loc) · 3.62 KB
/
creative.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import logging
from django.db import models
from django.db import transaction
from django.utils.translation import ugettext_lazy as _
from share.models.base import ShareObject
from share.models.base import TypedShareObjectMeta
from share.models.meta import Tag, Subject
from share.models.change import Change
from share.models.fields import ShareManyToManyField, ShareURLField
from share.util import strip_whitespace, ModelGenerator
logger = logging.getLogger(__name__)
# Base Creative Work class
class AbstractCreativeWork(ShareObject, metaclass=TypedShareObjectMeta):
title = models.TextField(blank=True, help_text='')
description = models.TextField(blank=True, help_text='')
is_deleted = models.BooleanField(default=False, help_text=_('Determines whether or not this record will be discoverable via search.'))
date_published = models.DateTimeField(blank=True, null=True)
date_updated = models.DateTimeField(blank=True, null=True)
free_to_read_type = ShareURLField(blank=True)
free_to_read_date = models.DateTimeField(blank=True, null=True)
rights = models.TextField(blank=True, null=True)
language = models.TextField(blank=True, null=True, help_text=_('The ISO 3166-1 alpha-2 country code indicating the language of this record.'))
subjects = ShareManyToManyField(Subject, related_name='subjected_works', through='ThroughSubjects')
tags = ShareManyToManyField(Tag, related_name='tagged_works', through='ThroughTags')
related_agents = ShareManyToManyField('AbstractAgent', through='AbstractAgentWorkRelation')
related_works = ShareManyToManyField('AbstractCreativeWork', through='AbstractWorkRelation', through_fields=('subject', 'related'), symmetrical=False)
@classmethod
def normalize(self, node, graph):
for k, v in tuple(node.attrs.items()):
if isinstance(v, str):
node.attrs[k] = strip_whitespace(v)
if node.attrs[k] == 'null':
node.attrs[k] = ''
class Disambiguation:
any = ('identifiers',)
class Meta(ShareObject.Meta):
db_table = 'share_creativework'
verbose_name_plural = 'Creative Works'
def defrankenize(self, *_, im_really_sure_about_this=False):
if not im_really_sure_about_this:
raise ValueError('You have to be really sure about this')
logger.info('Defrankenizing %r', self)
with transaction.atomic():
logger.info('Removing relations')
for field in AbstractCreativeWork._meta.get_fields():
if not field.one_to_many or field.name in ('changes', 'versions'):
continue
logger.warning('Removing all %s', field.related_name)
relation = getattr(self, field.get_accessor_name())
num_deleted, stats = Change.objects.filter(id__in=relation.values_list('change_id', flat=True)).delete()
logger.warning('Deleted %d changes to remove %s', num_deleted, field.related_name)
assert num_deleted == stats.pop('share.Change', 0)
if stats:
logger.error('Unexpectedly removed other rows, %r', stats)
raise ValueError('Unexpectedly removed other rows, {!r}'.format(stats))
logger.info('Relations removed')
self.administrative_change(is_deleted=True, title='Defrankenized work')
def __str__(self):
return self.title
generator = ModelGenerator(field_types={
'text': models.TextField,
'boolean': models.NullBooleanField, # Has to be nullable for types models :(
})
globals().update(generator.subclasses_from_yaml(__file__, AbstractCreativeWork))