wipo-gbd-transformation 1.1.36__py3-none-any.whl → 1.1.37__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of wipo-gbd-transformation might be problematic. Click here for more details.

Files changed (53) hide show
  1. gbdtransformation/.DS_Store +0 -0
  2. gbdtransformation/brands/brtm/filters.py +66 -3
  3. gbdtransformation/brands/brtm/template.yml +21 -0
  4. gbdtransformation/brands/emtm/filters.py +1 -1
  5. gbdtransformation/brands/estm/filters.py +4 -3
  6. gbdtransformation/brands/estm/template.yml +1 -1
  7. gbdtransformation/brands/filters.py +7 -2
  8. gbdtransformation/brands/gbtm/filters.py +5 -3
  9. gbdtransformation/brands/ipas/filters.py +10 -1
  10. gbdtransformation/brands/ipas/template.yml +9 -2
  11. gbdtransformation/brands/mctm/filters.py +1 -1
  12. gbdtransformation/brands/rotm/__init__.py +3 -0
  13. gbdtransformation/brands/rotm/filters.py +82 -0
  14. gbdtransformation/brands/rotm/schema +128 -0
  15. gbdtransformation/brands/rotm/template.yml +121 -0
  16. gbdtransformation/brands/rutm/__init__.py +1 -0
  17. gbdtransformation/brands/rutm/filters.py +26 -23
  18. gbdtransformation/brands/rutm/template.yml +38 -33
  19. gbdtransformation/brands/sgtm/filters.py +1 -1
  20. gbdtransformation/brands/sttm/__init__.py +16 -0
  21. gbdtransformation/brands/sttm/filters.py +70 -0
  22. gbdtransformation/brands/sttm/schema +83 -0
  23. gbdtransformation/brands/sttm/template.yml +1 -0
  24. gbdtransformation/brands/sttm/tests/__init__.py +0 -0
  25. gbdtransformation/brands/ustm/filters.py +1 -3
  26. gbdtransformation/brands/vntm/__init__.py +2 -1
  27. gbdtransformation/brands/vntm/filters.py +14 -6
  28. gbdtransformation/brands/xxtm/__init__.py +2 -0
  29. gbdtransformation/brands/xxtm/filters.py +60 -0
  30. gbdtransformation/brands/xxtm/schema +4 -0
  31. gbdtransformation/brands/xxtm/template.yml +183 -0
  32. gbdtransformation/common/filters.py +9 -3
  33. gbdtransformation/designs/alid/__init__.py +5 -0
  34. gbdtransformation/designs/alid/filters.py +56 -0
  35. gbdtransformation/designs/alid/schema +89 -0
  36. gbdtransformation/designs/alid/template.yml +1 -0
  37. gbdtransformation/designs/bnid/__init__.py +5 -0
  38. gbdtransformation/designs/bnid/filters.py +57 -0
  39. gbdtransformation/designs/bnid/schema +80 -0
  40. gbdtransformation/designs/bnid/template.yml +1 -0
  41. gbdtransformation/designs/ipas/__init__.py +0 -0
  42. gbdtransformation/designs/ipas/filters.py +99 -0
  43. gbdtransformation/designs/ipas/template.yml +163 -0
  44. gbdtransformation/designs/xxid/__init__.py +2 -0
  45. gbdtransformation/designs/xxid/filters.py +60 -0
  46. gbdtransformation/designs/xxid/schema +4 -0
  47. gbdtransformation/designs/xxid/template.yml +146 -0
  48. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/METADATA +1 -4
  49. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/RECORD +53 -24
  50. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/WHEEL +1 -1
  51. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/entry_points.txt +0 -1
  52. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/top_level.txt +0 -0
  53. {wipo_gbd_transformation-1.1.36.dist-info → wipo_gbd_transformation-1.1.37.dist-info}/LICENSE.md +0 -0
@@ -0,0 +1,183 @@
1
+ {% from 'navigation.tmpl' import match %}
2
+
3
+ # common filter methods accessible in this template
4
+ # gbdtransformation.common.filters
5
+ # .convertdate
6
+ # .contains
7
+ # .append
8
+ # .guess_language
9
+ # . ...
10
+ # gbdtransformation.brands.filters
11
+ # .st13
12
+ # .pad_vienna
13
+ # .split_terms (for goods and services)
14
+ #
15
+ # TESTING:
16
+ # developing the template:
17
+ # see the transformation output:
18
+ # gbd-transform /data/brands/collections/xxtm/ xxtm -t1
19
+ # test for transformation errors:
20
+ # gbd-transform /data/brands/collections/xxtm/ xxtm -r200 -w4 -q
21
+ # validating the template:
22
+ # gbd-transform /data/brands/collections/xxtm/ xxtm -r2000 -w40 -q --qc
23
+
24
+ brand:
25
+ type: # (TRADEMARK|EMBLEM|AOP|INN)
26
+ kind: # (Individual|Collective|Certificate|Guarantee|Defensive|Other)
27
+ markFeature: # (Word|Stylized characters|Figurative|Combined|Three dimensional|Colour|Sound|Hologram|Olfactory|Motion|Municipal|Chimney|Other|Undefined)
28
+
29
+ registrationOfficeCode:
30
+ designatedCountries:
31
+ - str (CountryCode)
32
+
33
+ # rarely passed
34
+ filingPlace:
35
+
36
+ # some collections indicate that the application
37
+ # originates from international filing and provide IR number
38
+ # (question to ask in GBD participation questionnaire)
39
+ applicationRefNumber:
40
+ applicationRefOrigin:
41
+
42
+ # can be deduced from appnum given office cc and (optional) appdate
43
+ st13: # {{ Trademark.ApplicationNumber | st13('XX', appdate=... }}
44
+
45
+ applicationNumber:
46
+ # dates can be converted if not matching expected format
47
+ applicationDate: # ex: {{ Trademark.ApplicationDate | convertdate('%Y%m%d') }}
48
+
49
+ # some collections have registration number
50
+ # equals application number when registered
51
+ registrationNumber:
52
+ # some collections we can guess registration date
53
+ # from event list
54
+ registrationDate:
55
+
56
+ applicationLanguageCode:
57
+ # rarely passed
58
+ secondLanguageCode:
59
+
60
+ expiryDate:
61
+ # rarely passed
62
+ terminationDate:
63
+
64
+ # status as is in the document
65
+ officeStatus:
66
+ # status as translated to gbdFormat
67
+ gbdStatus: # (Ended|Expired|Pending|Registered|Unknown)
68
+ # can also be the date of the last event in markevents if given
69
+ statusDate:
70
+
71
+ markDisclaimerDetails:
72
+ - languageCode: # use guess_language to set it if not passed
73
+ # ex {{ Trademark.MarkDisclaimerDetails | guess_language(lang='..', default='..') }}
74
+ # lang: the language if provided in doc
75
+ # default: default language if lang not provided.
76
+ # if no lang no default => use langdetect library
77
+ text:
78
+
79
+ markDescriptionDetails:
80
+ - languageCode:
81
+ text:
82
+
83
+ wordMarkSpecification:
84
+ markVerbalElement:
85
+ - languageCode:
86
+ text:
87
+ markSignificantVerbalElement:
88
+ - languageCode:
89
+ text:
90
+ markTranslation:
91
+ - languageCode:
92
+ text:
93
+ markTransliteration:
94
+
95
+ markImageDetails:
96
+ - name:
97
+ colourIndicator:
98
+ colourClaimed:
99
+ - languageCode:
100
+ text:
101
+ classification:
102
+ kind: Vienna #mostly
103
+ version: 7 #mostly
104
+ code:
105
+ - string
106
+
107
+ markSoundDetails:
108
+ - filename:
109
+ fileformat:
110
+
111
+ markVideo:
112
+ - filename:
113
+ fileformat:
114
+
115
+ goodsServices:
116
+ - nice:
117
+ version: 11 #mostly
118
+ terms:
119
+ - languageCode:
120
+ text:
121
+
122
+ # some datasets have goods and services
123
+ # terms that are not classified under a
124
+ # nice class
125
+ goodsServicesceUnclassified:
126
+ - languageCode:
127
+ text:
128
+
129
+ priorities:
130
+ - countryCode:
131
+ number:
132
+ date:
133
+ comment:
134
+
135
+ publications:
136
+ - identifier:
137
+ date:
138
+ section:
139
+
140
+ applicants:
141
+ - identifier:
142
+ kind:
143
+ fullName:
144
+ - languageCode:
145
+ text:
146
+ fullAddress:
147
+ - languageCode:
148
+ text:
149
+ countryCode: # sometimes, country name is provided instead
150
+
151
+ representatives:
152
+ - identifier:
153
+ kind:
154
+ fullName:
155
+ - languageCode:
156
+ text:
157
+ fullAddress:
158
+ - languageCode:
159
+ text:
160
+ countryCode:
161
+
162
+ correspondence:
163
+ fullName:
164
+ - languageCode:
165
+ text:
166
+ fullAddress:
167
+ - languageCode:
168
+ text:
169
+ countryCode:
170
+
171
+ events:
172
+ - officeKind:
173
+ gbdKind: # Filed, Registered, Published, Pending, Inactive,
174
+ # Opposed, Withdrawn, Expired, Examined, Invalidated,
175
+ # Rejected, Abandoned, Suspended, Surrendered, Appealed,
176
+ # Awaiting court action, Converted, Notification, Unknown
177
+ date:
178
+
179
+ appeals:
180
+ - kind:
181
+ date:
182
+ # here goes extra information that is office specific and that is pertinent for us to retain.
183
+ extra:
@@ -73,15 +73,21 @@ def to_str(input):
73
73
  # split goods and services terms
74
74
  def split_terms(data, separator=';'):
75
75
  """ Splits text base on seprator"""
76
-
77
76
  if not data:
78
77
  return []
79
78
  elif hasattr(data, '__value'): data = data.__value
80
79
 
81
80
  if not data:
82
81
  return []
83
- terms = [str(x).strip() for x in data.split(separator) if str(x).strip()]
84
- terms = [x for x in terms if x != 'true' and x != 'false']
82
+ terms = []
83
+ if type(data) == list:
84
+ for d in data:
85
+ tmp = [str(x).strip() for x in d.split(separator) if str(x).strip()]
86
+ tmp = [x for x in tmp if x != 'true' and x != 'false']
87
+ terms.extend(tmp)
88
+ else:
89
+ terms = [str(x).strip() for x in data.split(separator) if str(x).strip()]
90
+ terms = [x for x in terms if x != 'true' and x != 'false']
85
91
  return terms
86
92
 
87
93
 
@@ -0,0 +1,5 @@
1
+ render = 'JSON'
2
+ source = 'national'
3
+
4
+ # AL/I/1996/000003
5
+ appnum_mask = 'AL/(I|E|D)/\\d*/(\\d*)'
@@ -0,0 +1,56 @@
1
+ # standard gbd definitions
2
+ import gbdtransformation.designs.ipas.filters as ipas
3
+
4
+
5
+ # namespaces defined in XML and to be ignored in procecssing
6
+ ignore_namespace = [
7
+ 'http://www.wipo.int/standards/XMLSchema/designs',
8
+ 'http://www.wipo.int/standards/XMLSchema/wo-designs'
9
+ ]
10
+ def get_appdate(appdate, appnum):
11
+ return appnum.split('/')[-2]
12
+
13
+ def get_designs_count(design, header):
14
+ return '1'
15
+
16
+ def get_designs_pos(design, header):
17
+ return '1'
18
+ def translate_kind(desgin, header):
19
+ code = header.TransactionCode.lower()
20
+ subcode = header.TransactionSubCode.lower()
21
+ if code == 'disenjo industriale':
22
+ return 'Industrial Design'
23
+ raise Exception('Type "%s" "%s" is not mapped.' % (code, subcode))
24
+
25
+ def translate_status(design):
26
+ status = design.DesignCurrentStatusCode
27
+
28
+ if status == '2295': return 'Unknown'
29
+ if status == '2353': return 'Unknown'
30
+ if status == '2366': return 'Unknown'
31
+ if status == '2387': return 'Unknown'
32
+ if status == '2389': return 'Unknown'
33
+ if status == '2394': return 'Unknown'
34
+ if status == 'Reinstated': return 'Pending'
35
+
36
+ return ipas.translate_status(status)
37
+
38
+
39
+ def get_registration_nb(design, idstatus):
40
+ if design.RegistrationNumber:
41
+ return design.RegistrationNumber
42
+
43
+ return None
44
+
45
+
46
+ def get_expiry_date(design, idstatus):
47
+ return ipas.get_expiry_date(design, idstatus)
48
+
49
+ def get_registration_date(design, idstatus):
50
+ return ipas.get_registration_date(design, idstatus)
51
+
52
+ def is_international(header):
53
+ return False
54
+
55
+ def get_ir_refnum(appnum):
56
+ return appnum
@@ -0,0 +1,89 @@
1
+ /Transaction
2
+ __/DesignTransactionBody
3
+ ____/TransactionContentDetails
4
+ ______/TransactionCode
5
+ ______/TransactionData
6
+ ________/DesignApplicationDetails
7
+ __________/DesignApplication
8
+ ____________/ApplicantDetails
9
+ ______________/ApplicantKey
10
+ ____________/DesignApplicationDate
11
+ ____________/DesignApplicationLanguageCode
12
+ ____________/DesignApplicationNumber
13
+ ____________/DesignDetails
14
+ ______________/Design
15
+ ________________/ApplicantDetails
16
+ __________________/Applicant
17
+ ____________________/ApplicantAddressBook
18
+ ______________________/FormattedNameAddress
19
+ ________________________/Address
20
+ __________________________/AddressCountryCode
21
+ __________________________/FreeFormatAddress
22
+ ____________________________/FreeFormatAddressLine
23
+ ________________________/Name
24
+ __________________________/FreeFormatName
25
+ ____________________________/FreeFormatNameDetails
26
+ ______________________________/FreeFormatNameLine
27
+ ______________________________/FreeFormatNameLine[@languageCode=sq]
28
+ ________________/DesignCurrentStatusCode
29
+ ________________/DesignCurrentStatusDate
30
+ ________________/DesignDescription
31
+ ________________/DesignIdentifier
32
+ ________________/DesignRepresentationSheetDetails
33
+ __________________/DesignRepresentationSheet
34
+ ____________________/RepresentationSheetFilename
35
+ ________________/DesignTitle
36
+ ________________/DesignTitle[@languageCode=sq]
37
+ ________________/DesignTitle[@sequenceNumber=1]
38
+ ________________/DesignerDetails
39
+ __________________/Designer
40
+ ____________________/DesignerAddressBook
41
+ ______________________/FormattedNameAddress
42
+ ________________________/Address
43
+ __________________________/AddressCountryCode
44
+ __________________________/FreeFormatAddress
45
+ ____________________________/FreeFormatAddressLine
46
+ ________________________/Name
47
+ __________________________/FreeFormatName
48
+ ____________________________/FreeFormatNameDetails
49
+ ______________________________/FreeFormatNameLine
50
+ ______________________________/FreeFormatNameLine[@languageCode=sq]
51
+ ________________/ExpiryDate
52
+ ________________/IndicationProductDetails
53
+ __________________/IndicationProduct
54
+ ____________________/ClassDescriptionDetails
55
+ ______________________/ClassDescription
56
+ ________________________/ClassNumber
57
+ ________________________/ProductDescription
58
+ ____________________/ClassificationKindCode
59
+ ____________________/ClassificationVersion
60
+ ________________/NoveltyStatement
61
+ ________________/NoveltyStatement[@languageCode=]
62
+ ________________/NoveltyStatement[@languageCode=sq]
63
+ ________________/PriorityDetails
64
+ __________________/Priority
65
+ ____________________/PriorityCountryCode
66
+ ____________________/PriorityDate
67
+ ____________________/PriorityNumber
68
+ ________________/PublicationDetails
69
+ __________________/Publication
70
+ ____________________/PublicationDate
71
+ ____________________/PublicationIdentifier
72
+ ________________/RegistrationDate
73
+ ________________/RegistrationNumber
74
+ ________________/RepresentativeDetails
75
+ __________________/Representative
76
+ ____________________/RepresentativeAddressBook
77
+ ______________________/FormattedNameAddress
78
+ ________________________/Address
79
+ __________________________/AddressCountryCode
80
+ __________________________/FreeFormatAddress
81
+ ____________________________/FreeFormatAddressLine
82
+ ________________________/Name
83
+ __________________________/FreeFormatName
84
+ ____________________________/FreeFormatNameDetails
85
+ ______________________________/FreeFormatNameLine
86
+ ______________________________/FreeFormatNameLine[@languageCode=sq]
87
+ ____________/RegistrationOfficeCode
88
+ ______/TransactionIdentifier
89
+ ______/TransactionSubCode
@@ -0,0 +1 @@
1
+ {% include "ipas/template.yml" %}
@@ -0,0 +1,5 @@
1
+ render = 'JSON'
2
+ source = 'national'
3
+
4
+ # BN/2009/0025
5
+ appnum_mask = 'BN/\\d*/(\\d*)'
@@ -0,0 +1,57 @@
1
+ # standard gbd definitions
2
+ import gbdtransformation.designs.ipas.filters as ipas
3
+
4
+
5
+ # namespaces defined in XML and to be ignored in procecssing
6
+ ignore_namespace = [
7
+ 'http://www.wipo.int/standards/XMLSchema/designs',
8
+ 'http://www.wipo.int/standards/XMLSchema/wo-designs'
9
+ ]
10
+ def get_appdate(appdate, appnum):
11
+ return appnum.split('/')[-2]
12
+
13
+ def get_designs_count(design, header):
14
+ return '1'
15
+
16
+ def get_designs_pos(design, header):
17
+ return '1'
18
+
19
+ def translate_kind(desgin, header):
20
+ code = header.TransactionCode.lower()
21
+ subcode = header.TransactionSubCode.lower()
22
+ if code == 'industrial design':
23
+ return 'Industrial Design'
24
+ raise Exception('Type "%s" "%s" is not mapped.' % (code, subcode))
25
+
26
+ def translate_status(design):
27
+ status = design.DesignCurrentStatusCode
28
+
29
+ if status == '2295': return 'Unknown'
30
+ if status == '2353': return 'Unknown'
31
+ if status == '2366': return 'Unknown'
32
+ if status == '2387': return 'Unknown'
33
+ if status == '2389': return 'Unknown'
34
+ if status == '2394': return 'Unknown'
35
+ if status == 'Reinstated': return 'Pending'
36
+
37
+ return ipas.translate_status(status)
38
+
39
+
40
+ def get_registration_nb(design, idstatus):
41
+ if design.RegistrationNumber:
42
+ return design.RegistrationNumber
43
+
44
+ return None
45
+
46
+
47
+ def get_expiry_date(design, idstatus):
48
+ return ipas.get_expiry_date(design, idstatus)
49
+
50
+ def get_registration_date(design, idstatus):
51
+ return ipas.get_registration_date(design, idstatus)
52
+
53
+ def is_international(header):
54
+ return False
55
+
56
+ def get_ir_refnum(appnum):
57
+ return appnum
@@ -0,0 +1,80 @@
1
+ /Transaction
2
+ __/DesignTransactionBody
3
+ ____/TransactionContentDetails
4
+ ______/TransactionCode
5
+ ______/TransactionData
6
+ ________/DesignApplicationDetails
7
+ __________/DesignApplication
8
+ ____________/ApplicantDetails
9
+ ______________/ApplicantKey
10
+ ____________/DesignApplicationDate
11
+ ____________/DesignApplicationLanguageCode
12
+ ____________/DesignApplicationNumber
13
+ ____________/DesignDetails
14
+ ______________/Design
15
+ ________________/ApplicantDetails
16
+ __________________/Applicant
17
+ ____________________/ApplicantAddressBook
18
+ ______________________/FormattedNameAddress
19
+ ________________________/Address
20
+ __________________________/AddressCountryCode
21
+ __________________________/FreeFormatAddress
22
+ ____________________________/FreeFormatAddressLine
23
+ ________________________/Name
24
+ __________________________/FreeFormatName
25
+ ____________________________/FreeFormatNameDetails
26
+ ______________________________/FreeFormatNameLine
27
+ ______________________________/FreeFormatNameLine[@languageCode=en]
28
+ ________________/DesignCurrentStatusCode
29
+ ________________/DesignCurrentStatusDate
30
+ ________________/DesignDescription
31
+ ________________/DesignEventDetails
32
+ __________________/DesignEvent
33
+ ____________________/DesignEventCode
34
+ ____________________/DesignEventDate
35
+ ____________________/OfficeSpecificDesignEventCode
36
+ ____________________/OfficeSpecificDesignEventDescription
37
+ ____________________/OfficeSpecificDesignEventDescription[@languageCode=en]
38
+ ________________/DesignIdentifier
39
+ ________________/DesignRepresentationSheetDetails
40
+ __________________/DesignRepresentationSheet
41
+ ____________________/RepresentationSheetFilename
42
+ ________________/DesignTitle
43
+ ________________/DesignTitle[@languageCode=en]
44
+ ________________/DesignTitle[@sequenceNumber=1]
45
+ ________________/IndicationProductDetails
46
+ __________________/IndicationProduct
47
+ ____________________/ClassDescriptionDetails
48
+ ______________________/ClassDescription
49
+ ________________________/ClassNumber
50
+ ________________________/ProductDescription
51
+ ____________________/ClassificationKindCode
52
+ ____________________/ClassificationVersion
53
+ ________________/NoveltyStatement
54
+ ________________/NoveltyStatement[@languageCode=en]
55
+ ________________/PriorityDetails
56
+ __________________/Priority
57
+ ____________________/PriorityCountryCode
58
+ ____________________/PriorityDate
59
+ ____________________/PriorityNumber
60
+ ________________/PublicationDetails
61
+ __________________/Publication
62
+ ____________________/PublicationDate
63
+ ________________/RegistrationDate
64
+ ________________/RegistrationNumber
65
+ ________________/RepresentativeDetails
66
+ __________________/Representative
67
+ ____________________/RepresentativeAddressBook
68
+ ______________________/FormattedNameAddress
69
+ ________________________/Address
70
+ __________________________/AddressCountryCode
71
+ __________________________/FreeFormatAddress
72
+ ____________________________/FreeFormatAddressLine
73
+ ________________________/Name
74
+ __________________________/FreeFormatName
75
+ ____________________________/FreeFormatNameDetails
76
+ ______________________________/FreeFormatNameLine
77
+ ______________________________/FreeFormatNameLine[@languageCode=en]
78
+ ____________/RegistrationOfficeCode
79
+ ______/TransactionIdentifier
80
+ ______/TransactionSubCode
@@ -0,0 +1 @@
1
+ {% include "ipas/template.yml" %}
File without changes
@@ -0,0 +1,99 @@
1
+ # standard gbd definitions
2
+ from gbdtransformation.designs import kinds as std_kinds
3
+ from gbdtransformation.designs import status as std_status
4
+ from gbdtransformation.brands import events as std_events
5
+
6
+ # namespaces defined in XML and to be ignored in procecssing
7
+ ignore_namespace = []
8
+
9
+
10
+ # -------------------------------------------------------------
11
+ # data translation helpers:
12
+ # translate values from office interpretation to gbd equivalent
13
+ # -------------------------------------------------------------
14
+
15
+ def translate_kind(kind):
16
+ """translation of the kind of trademark to a
17
+ multivalue gbd interpretation"""
18
+
19
+ # out-of-the-box match
20
+ if kind.capitalize() in std_kinds:
21
+ return [kind.capitalize()]
22
+
23
+ # __insert here__ : translation logic
24
+
25
+ # raise Exception to recognize unmapped values
26
+ raise Exception('kind "%s" is not mapped.' % kind)
27
+
28
+ # Expired trademarks with no Expiry date
29
+ # => get it from Expired event
30
+ def get_expiry_date(design, idstatus):
31
+ if design.ExpiryDate:
32
+ return design.ExpiryDate
33
+
34
+ if not idstatus == 'Expired':
35
+ return None
36
+
37
+ # find the MarkEvent Expired and get its date
38
+ events = design.get('MarkEventDetails', {}).get('MarkEvent', [])
39
+ for event in events:
40
+ if hasattr(event, 'MarkEventCode'):
41
+ if(event.MarkEventCode == 'Expired'):
42
+ return event.MarkEventDate
43
+
44
+
45
+ # Registered or Expired trademarks with no registration date
46
+ # => get it from Registered or Published Event
47
+ def get_registration_date(trademark, tmstatus):
48
+ if trademark.RegistrationDate:
49
+ return trademark.RegistrationDate
50
+
51
+ if not tmstatus in ['Expired', 'Registered']:
52
+ return None
53
+
54
+ # find the MarkEvent Expired and get its date
55
+ events = trademark.get('MarkEventDetails', {}).get('MarkEvent', [])
56
+
57
+ # first priority is to get the Registered Event
58
+ for event in events:
59
+ if hasattr(event, 'MarkEventCode'):
60
+ if event.MarkEventCode == 'Registered':
61
+ return event.MarkEventDate
62
+ # second priority is to get the Published Event
63
+ for event in events:
64
+ if hasattr(event, 'MarkEventCode'):
65
+ if event.MarkEventCode == 'Published':
66
+ return event.MarkEventDate
67
+
68
+ def translate_status(status):
69
+ status = status.lower()
70
+
71
+ if status == 'registered': return 'Registered'
72
+ if status == 'active': return 'Registered'
73
+ if status == 'reinstated': return 'Registered'
74
+ if status == 'expired': return 'Expired'
75
+ if status == 'inactive': return 'Expired'
76
+ if status == 'published': return 'Pending'
77
+ if status == 'examined': return 'Pending'
78
+ if status == 'filed': return 'Pending'
79
+ if status == 'converted': return 'Pending'
80
+ if status == 'opposed': return 'Pending'
81
+ if status == 'pending': return 'Pending'
82
+ if status == 'appealed': return 'Pending'
83
+ if status == 'awaiting court action': return 'Pending'
84
+ if status == 'application published': return 'Pending'
85
+ if status == 'abandoned': return 'Ended'
86
+ if status == 'withdrawn': return 'Ended'
87
+ if status == 'rejected': return 'Ended'
88
+ if status == 'finalrefusal': return 'Ended'
89
+ if status == 'suspended': return 'Ended'
90
+ if status == 'invalidated': return 'Ended'
91
+ if status == 'surrendered': return 'Ended'
92
+ if status == 'suspended': return 'Ended'
93
+ if status == 'renewed': return 'Registered'
94
+ if status == 'renewalprocess': return 'Registered'
95
+ if status == 'canceled': return 'Ended'
96
+ if status == 'cancelled': return 'Ended'
97
+
98
+ #return 'Unknown'
99
+ raise Exception('Status "%s" not mapped.' % status)