19 __authors__ = [ |
19 __authors__ = [ |
20 '"Todd Larsen" <tlarsen@google.com>', |
20 '"Todd Larsen" <tlarsen@google.com>', |
21 ] |
21 ] |
22 |
22 |
23 |
23 |
|
24 import re |
|
25 |
24 from google.appengine.ext import db |
26 from google.appengine.ext import db |
25 |
27 |
26 from django.utils.translation import ugettext_lazy |
28 from django.utils.translation import ugettext_lazy |
27 |
29 |
28 from soc.models import base |
30 from soc.models import base |
|
31 |
|
32 |
|
33 # start with ASCII digit or lowercase |
|
34 # (additional ASCII digit or lowercase |
|
35 # -OR- |
|
36 # underscore and ASCII digit or lowercase) |
|
37 # zero or more of OR group |
|
38 # |
|
39 # * starting or ending underscores are *not* permitted |
|
40 # * double internal underscores are *not* permitted |
|
41 # |
|
42 LINK_ID_PATTERN_CORE = r'[0-9a-z](?:[0-9a-z]|_[0-9a-z])*' |
|
43 LINK_ID_ARG_PATTERN = r'(?P<link_id>%s)' % LINK_ID_PATTERN_CORE |
|
44 LINK_ID_PATTERN = r'^%s$' % LINK_ID_PATTERN_CORE |
|
45 LINK_ID_REGEX = re.compile(LINK_ID_PATTERN) |
29 |
46 |
30 |
47 |
31 class Linkable(base.ModelWithFieldAttributes): |
48 class Linkable(base.ModelWithFieldAttributes): |
32 """A base class for Model classes that are "linkable". |
49 """A base class for Model classes that are "linkable". |
33 |
50 |
69 changing them can break bookmarked URLs. Changing the link IDs of |
86 changing them can break bookmarked URLs. Changing the link IDs of |
70 "leaf" entities (such as the Document in the example above) could |
87 "leaf" entities (such as the Document in the example above) could |
71 be allowed. |
88 be allowed. |
72 """ |
89 """ |
73 #: Required field storing "ID" used in URLS. Lower ASCII characters, |
90 #: Required field storing "ID" used in URLS. Lower ASCII characters, |
74 #: digits and underscores only. |
91 #: digits and underscores only. Valid link IDs successfully match |
|
92 #: the LINK_ID_REGEX. |
75 id = db.StringProperty(required=True, |
93 id = db.StringProperty(required=True, |
76 verbose_name=ugettext_lazy('Link ID')) |
94 verbose_name=ugettext_lazy('Link ID')) |
77 id.help_text = ugettext_lazy( |
95 id.help_text = ugettext_lazy( |
78 '"ID" used in URLs.' |
96 '"ID" used in URLs.' |
79 ' Lower ASCII characters, digits and underscores only.') |
97 ' Lower ASCII characters, digits, and underscores only.') |
80 |
98 |
81 #: Optional Self Reference property to another Linkable entity which defines |
99 #: Optional Self Reference property to another Linkable entity which defines |
82 #: the "scope" of this Linkable entity. The back-reference in the Linkable |
100 #: the "scope" of this Linkable entity. The back-reference in the Linkable |
83 #: model is a Query named 'links'. |
101 #: model is a Query named 'links'. |
84 scope = db.SelfReferenceProperty(required=False, |
102 scope = db.SelfReferenceProperty(required=False, |