wipo-gbd-transformation 1.1.49__py3-none-any.whl → 1.1.51__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 (84) hide show
  1. gbdtransformation/brands/istm/filters.py +22 -14
  2. gbdtransformation/brands/sgtm/filters.py +1 -1
  3. gbdtransformation/brands/sgtm/template.trademark.yml +1 -1
  4. gbdtransformation/designs/__init__.py +2 -3
  5. gbdtransformation/designs/bnid/__init__.py +5 -0
  6. gbdtransformation/designs/bnid/filters.py +49 -0
  7. gbdtransformation/designs/bnid/schema +80 -0
  8. gbdtransformation/designs/bnid/template.yml +1 -0
  9. gbdtransformation/designs/bwid/__init__.py +6 -0
  10. gbdtransformation/designs/bwid/filters.py +52 -0
  11. gbdtransformation/designs/bwid/schema +101 -0
  12. gbdtransformation/designs/bwid/template.yml +1 -0
  13. gbdtransformation/designs/crid/__init__.py +5 -0
  14. gbdtransformation/designs/crid/filters.py +50 -0
  15. gbdtransformation/designs/crid/schema +94 -0
  16. gbdtransformation/designs/crid/template.yml +1 -0
  17. gbdtransformation/designs/cuid/__init__.py +5 -0
  18. gbdtransformation/designs/cuid/filters.py +47 -0
  19. gbdtransformation/designs/cuid/schema +98 -0
  20. gbdtransformation/designs/cuid/template.yml +1 -0
  21. gbdtransformation/designs/egid/__init__.py +5 -0
  22. gbdtransformation/designs/egid/filters.py +49 -0
  23. gbdtransformation/designs/egid/schema +82 -0
  24. gbdtransformation/designs/egid/template.yml +1 -0
  25. gbdtransformation/designs/filters.py +13 -1
  26. gbdtransformation/designs/idid/__init__.py +5 -0
  27. gbdtransformation/designs/idid/filters.py +54 -0
  28. gbdtransformation/designs/idid/schema +102 -0
  29. gbdtransformation/designs/idid/template.yml +1 -0
  30. gbdtransformation/designs/ipas/filters.py +1 -1
  31. gbdtransformation/designs/ipas/template.yml +85 -76
  32. gbdtransformation/designs/joid/__init__.py +6 -0
  33. gbdtransformation/designs/joid/filters.py +49 -0
  34. gbdtransformation/designs/joid/schema +97 -0
  35. gbdtransformation/designs/joid/template.yml +1 -0
  36. gbdtransformation/designs/keid/__init__.py +5 -0
  37. gbdtransformation/designs/keid/filters.py +49 -0
  38. gbdtransformation/designs/keid/schema +99 -0
  39. gbdtransformation/designs/keid/template.yml +1 -0
  40. gbdtransformation/designs/khid/__init__.py +5 -0
  41. gbdtransformation/designs/khid/filters.py +50 -0
  42. gbdtransformation/designs/khid/schema +100 -0
  43. gbdtransformation/designs/khid/template.yml +1 -0
  44. gbdtransformation/designs/laid/__init__.py +5 -0
  45. gbdtransformation/designs/laid/filters.py +49 -0
  46. gbdtransformation/designs/laid/schema +94 -0
  47. gbdtransformation/designs/laid/template.yml +1 -0
  48. gbdtransformation/designs/mnid/__init__.py +6 -0
  49. gbdtransformation/designs/mnid/filters.py +49 -0
  50. gbdtransformation/designs/mnid/schema +98 -0
  51. gbdtransformation/designs/mnid/template.yml +1 -0
  52. gbdtransformation/designs/myid/__init__.py +5 -0
  53. gbdtransformation/designs/myid/filters.py +48 -0
  54. gbdtransformation/designs/myid/schema +95 -0
  55. gbdtransformation/designs/myid/template.yml +1 -0
  56. gbdtransformation/designs/phid/__init__.py +5 -0
  57. gbdtransformation/designs/phid/filters.py +58 -0
  58. gbdtransformation/designs/phid/schema +95 -0
  59. gbdtransformation/designs/phid/template.yml +1 -0
  60. gbdtransformation/designs/sgid/__init__.py +6 -0
  61. gbdtransformation/designs/sgid/filters.py +53 -0
  62. gbdtransformation/designs/sgid/schema +115 -0
  63. gbdtransformation/designs/sgid/template.yml +1 -0
  64. gbdtransformation/designs/thid/__init__.py +4 -0
  65. gbdtransformation/designs/thid/filters.py +52 -0
  66. gbdtransformation/designs/thid/schema +98 -0
  67. gbdtransformation/designs/thid/template.yml +1 -0
  68. gbdtransformation/designs/tnid/__init__.py +5 -0
  69. gbdtransformation/designs/tnid/filters.py +54 -0
  70. gbdtransformation/designs/tnid/schema +96 -0
  71. gbdtransformation/designs/tnid/template.yml +1 -0
  72. gbdtransformation/designs/woid/__init__.py +2 -0
  73. gbdtransformation/designs/woid/filters.py +342 -0
  74. gbdtransformation/designs/woid/schema +592 -0
  75. gbdtransformation/designs/woid/template.yml +342 -0
  76. gbdtransformation/designs/xxid/template.yml +211 -123
  77. gbdtransformation/execs.py +9 -3
  78. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/METADATA +6 -2
  79. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/RECORD +83 -16
  80. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/WHEEL +1 -1
  81. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/entry_points.txt +1 -0
  82. gbdtransformation/.DS_Store +0 -0
  83. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/LICENSE.md +0 -0
  84. {wipo_gbd_transformation-1.1.49.dist-info → wipo_gbd_transformation-1.1.51.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,98 @@
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=th]
28
+ ________________/DesignCurrentStatusCode
29
+ ________________/DesignCurrentStatusDate
30
+ ________________/DesignDescription
31
+ ________________/DesignEventDetails
32
+ __________________/DesignEvent
33
+ ____________________/DesignEventCode
34
+ ____________________/DesignEventDate
35
+ ____________________/OfficeSpecificDesignEventCode
36
+ ____________________/OfficeSpecificDesignEventDescription
37
+ ____________________/OfficeSpecificDesignEventDescription[@languageCode=th]
38
+ ____________________/OfficeSpecificDesignEventName
39
+ ________________/DesignIdentifier
40
+ ________________/DesignRepresentationSheetDetails
41
+ __________________/DesignRepresentationSheet
42
+ ____________________/RepresentationSheetFilename
43
+ ________________/DesignSpecimenDetails
44
+ __________________/DesignSpecimen
45
+ ____________________/SpecimenDescription
46
+ ____________________/SpecimenDescription[@languageCode=th]
47
+ ____________________/SpecimenIdentifier
48
+ ________________/DesignTitle
49
+ ________________/DesignTitle[@languageCode=th]
50
+ ________________/DesignTitle[@sequenceNumber=1]
51
+ ________________/DesignerDetails
52
+ __________________/Designer
53
+ ____________________/DesignerAddressBook
54
+ ______________________/FormattedNameAddress
55
+ ________________________/Address
56
+ __________________________/AddressCountryCode
57
+ __________________________/FreeFormatAddress
58
+ ____________________________/FreeFormatAddressLine
59
+ ________________________/Name
60
+ __________________________/FreeFormatName
61
+ ____________________________/FreeFormatNameDetails
62
+ ______________________________/FreeFormatNameLine
63
+ ______________________________/FreeFormatNameLine[@languageCode=th]
64
+ ________________/ExpiryDate
65
+ ________________/IndicationProductDetails
66
+ __________________/IndicationProduct
67
+ ____________________/ClassDescriptionDetails
68
+ ______________________/ClassDescription
69
+ ________________________/ClassNumber
70
+ ____________________/ClassificationKindCode
71
+ ____________________/ClassificationVersion
72
+ ________________/PriorityDetails
73
+ __________________/Priority
74
+ ____________________/PriorityCountryCode
75
+ ____________________/PriorityDate
76
+ ____________________/PriorityNumber
77
+ ________________/PublicationDetails
78
+ __________________/Publication
79
+ ____________________/PublicationDate
80
+ ____________________/PublicationIdentifier
81
+ ________________/RegistrationDate
82
+ ________________/RegistrationNumber
83
+ ________________/RepresentativeDetails
84
+ __________________/Representative
85
+ ____________________/RepresentativeAddressBook
86
+ ______________________/FormattedNameAddress
87
+ ________________________/Address
88
+ __________________________/AddressCountryCode
89
+ __________________________/FreeFormatAddress
90
+ ____________________________/FreeFormatAddressLine
91
+ ________________________/Name
92
+ __________________________/FreeFormatName
93
+ ____________________________/FreeFormatNameDetails
94
+ ______________________________/FreeFormatNameLine
95
+ ______________________________/FreeFormatNameLine[@languageCode=th]
96
+ ____________/RegistrationOfficeCode
97
+ ______/TransactionIdentifier
98
+ ______/TransactionSubCode
@@ -0,0 +1 @@
1
+ {% include "ipas/template.yml" %}
@@ -0,0 +1,5 @@
1
+ render = 'JSON'
2
+ source = 'national'
3
+
4
+ # AL/I/1996/000003
5
+ appnum_mask = 'TN/[L|D]/\\d*/(\\d*)'
@@ -0,0 +1,54 @@
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 appdate
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 == 'dm national':
23
+ return 'Industrial Design'
24
+ if code == 'dm hague':
25
+ return 'Industrial Design'
26
+ raise Exception('Type "%s" "%s" is not mapped.' % (code, subcode))
27
+
28
+ def translate_status(design):
29
+ status = design.DesignCurrentStatusCode
30
+ return ipas.translate_status(status)
31
+
32
+
33
+ def get_registration_nb(design, idstatus):
34
+ if design.RegistrationNumber:
35
+ return design.RegistrationNumber
36
+
37
+ return None
38
+
39
+
40
+ def get_expiry_date(design, idstatus):
41
+ return ipas.get_expiry_date(design, idstatus)
42
+
43
+ def get_registration_date(design, idstatus):
44
+ return ipas.get_registration_date(design, idstatus)
45
+
46
+ def is_international(header):
47
+ code = header.TransactionCode.lower()
48
+ if code == 'dm national':
49
+ return False
50
+ if code == 'dm hague':
51
+ return True
52
+
53
+ def get_ir_refnum(appnum):
54
+ return appnum
@@ -0,0 +1,96 @@
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=fr]
28
+ ________________/DesignCurrentStatusCode
29
+ ________________/DesignCurrentStatusDate
30
+ ________________/DesignDescription
31
+ ________________/DesignEventDetails
32
+ __________________/DesignEvent
33
+ ____________________/DesignEventCode
34
+ ____________________/DesignEventDate
35
+ ____________________/OfficeSpecificDesignEventCode
36
+ ____________________/OfficeSpecificDesignEventDescription
37
+ ____________________/OfficeSpecificDesignEventDescription[@languageCode=fr]
38
+ ____________________/OfficeSpecificDesignEventName
39
+ ________________/DesignIdentifier
40
+ ________________/DesignRepresentationSheetDetails
41
+ __________________/DesignRepresentationSheet
42
+ ____________________/RepresentationSheetFilename
43
+ ________________/DesignTitle
44
+ ________________/DesignTitle[@languageCode=fr]
45
+ ________________/DesignTitle[@sequenceNumber=1]
46
+ ________________/DesignerDetails
47
+ __________________/Designer
48
+ ____________________/DesignerAddressBook
49
+ ______________________/FormattedNameAddress
50
+ ________________________/Address
51
+ __________________________/AddressCountryCode
52
+ __________________________/FreeFormatAddress
53
+ ____________________________/FreeFormatAddressLine
54
+ ________________________/Name
55
+ __________________________/FreeFormatName
56
+ ____________________________/FreeFormatNameDetails
57
+ ______________________________/FreeFormatNameLine
58
+ ______________________________/FreeFormatNameLine[@languageCode=fr]
59
+ ________________/ExpiryDate
60
+ ________________/IndicationProductDetails
61
+ __________________/IndicationProduct
62
+ ____________________/ClassDescriptionDetails
63
+ ______________________/ClassDescription
64
+ ________________________/ClassNumber
65
+ ________________________/ProductDescription
66
+ ____________________/ClassificationKindCode
67
+ ____________________/ClassificationVersion
68
+ ________________/NoveltyStatement
69
+ ________________/NoveltyStatement[@languageCode=fr]
70
+ ________________/PriorityDetails
71
+ __________________/Priority
72
+ ____________________/PriorityCountryCode
73
+ ____________________/PriorityDate
74
+ ____________________/PriorityNumber
75
+ ________________/PublicationDetails
76
+ __________________/Publication
77
+ ____________________/PublicationDate
78
+ ____________________/PublicationIdentifier
79
+ ________________/RegistrationDate
80
+ ________________/RegistrationNumber
81
+ ________________/RepresentativeDetails
82
+ __________________/Representative
83
+ ____________________/RepresentativeAddressBook
84
+ ______________________/FormattedNameAddress
85
+ ________________________/Address
86
+ __________________________/AddressCountryCode
87
+ __________________________/FreeFormatAddress
88
+ ____________________________/FreeFormatAddressLine
89
+ ________________________/Name
90
+ __________________________/FreeFormatName
91
+ ____________________________/FreeFormatNameDetails
92
+ ______________________________/FreeFormatNameLine
93
+ ______________________________/FreeFormatNameLine[@languageCode=fr]
94
+ ____________/RegistrationOfficeCode
95
+ ______/TransactionIdentifier
96
+ ______/TransactionSubCode
@@ -0,0 +1 @@
1
+ {% include "ipas/template.yml" %}
@@ -0,0 +1,2 @@
1
+ # instruction to render the output to JSON format
2
+ render = 'JSON'
@@ -0,0 +1,342 @@
1
+ # standard gdd definitions
2
+ from gbdtransformation.designs import kinds as std_kinds
3
+ from gbdtransformation.designs import status as std_status
4
+ from gbdtransformation.designs.filters import st13
5
+ from datetime import datetime, date
6
+
7
+ # namespaces defined in XML and to be ignored in procecssing
8
+ ignore_namespace = [ "http://www.wipo.int/standards/XMLSchema/ST96/Design",
9
+ "http://www.wipo.int/standards/XMLSchema/ST96/Common" ]
10
+
11
+ # -------------------------------------------------------------
12
+ # data translation helpers:
13
+ # translate values from office interpretation to gbd equivalent
14
+ # -------------------------------------------------------------
15
+
16
+ def detectSealedDepositIndicator(HagueExpressTransaction):
17
+ return 'Open'
18
+
19
+ def cleanHagueAgreementActCategory(category):
20
+ return category.replace("Act", "") if category else None
21
+
22
+ def getExpiryDate(expiryDate, histories, designIdentifier=None, countryCode=None):
23
+ '''
24
+ Return last seen expiry date in the history events, if any
25
+ restricted to the identified design if specified
26
+ '''
27
+ #print("getExpiryDate")
28
+ #print(expiryDate)
29
+ #print(histories)
30
+
31
+ if histories == None or len(histories) == 0:
32
+ return expiryDate
33
+
34
+ if not isinstance(histories, list):
35
+ histories = [histories]
36
+
37
+ for history in histories:
38
+ if "HagueRenewal" in history:
39
+ if "ExpiryDate" in history.HagueRenewal:
40
+ if designIdentifier == None:
41
+ # no design restriction
42
+ expiryDate = history.HagueRenewal.ExpiryDate
43
+ else:
44
+ # is the design identifier in the list of affected designs?
45
+ if isAffectedDesignIdentifier(designIdentifier, history.HagueRenewal.AffectedDesign):
46
+ if countryCode == None:
47
+ expiryDate = history.HagueRenewal.ExpiryDate
48
+ else:
49
+ if isApplicableToCountry(countryCode, history.HagueRenewal):
50
+ expiryDate = history.HagueRenewal.ExpiryDate
51
+ return expiryDate
52
+
53
+ def getLastRenewalDate(histories, designIdentifier=None, countryCode=None):
54
+ '''
55
+ Return the renewal date if the last seen expiry date is in the history events
56
+ Renewal date can be restricted optionally by design identifier and country
57
+ '''
58
+ #print("getLastRenewalDate")
59
+
60
+ if histories == None or len(histories) == 0:
61
+ return None
62
+
63
+ if not isinstance(histories, list):
64
+ histories = [histories]
65
+
66
+ renewalDate = None
67
+ for history in histories:
68
+ if "HagueRenewal" in history:
69
+ if "ExpiryDate" in history.HagueRenewal:
70
+ if designIdentifier == None:
71
+ # no design restriction
72
+ renewalDate = history.HagueRenewal.RenewalDate
73
+ else:
74
+ # is the design identifier in the list of affected designs?
75
+ if isAffectedDesignIdentifier(designIdentifier, history.HagueRenewal.AffectedDesign):
76
+ if countryCode == None:
77
+ renewalDate = history.HagueRenewal.RenewalDate
78
+ else:
79
+ if isApplicableToCountry(countryCode, history.HagueRenewal):
80
+ renewalDate = history.HagueRenewal.RenewalDate
81
+ return renewalDate
82
+
83
+ def getRefusalDate(histories, designIdentifier=None, countryCode=None):
84
+ '''
85
+ Return refusal date, if any
86
+ Refusal datecan be restricted optionally by design identifier and country
87
+ '''
88
+ # check refusal
89
+ refusalDate = None
90
+ for history in histories:
91
+ if "HagueRefusal" in history:
92
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueRefusal.AffectedDesign):
93
+ if countryCode == None or isApplicableToCountry(countryCode, history.HagueRefusal):
94
+ if "DecisionEffectiveDate" in history.HagueRefusal:
95
+ refusalDate = history.HagueRefusal.DecisionEffectiveDate
96
+ elif "DecisionDate" in history.HagueRefusal:
97
+ refusalDate = history.HagueRefusal.DecisionDate
98
+ return refusalDate
99
+
100
+ def build_person_name(name_struct):
101
+ first_name = None
102
+ if "FirstName" in name_struct:
103
+ first_name = name_struct.FirstName
104
+ last_name = None
105
+ if "LastName" in name_struct:
106
+ last_name = name_struct.LastName
107
+ if first_name is None and last_name is None:
108
+ return None
109
+ name = ""
110
+ if first_name is not None:
111
+ name += first_name
112
+ if last_name is not None:
113
+ name += " " + last_name.upper()
114
+ return name
115
+
116
+ def render_and_sort_views(viewBag):
117
+ views = []
118
+ for localViewKey in viewBag:
119
+ localView = viewBag[localViewKey]
120
+ #print(localView)
121
+ view = {}
122
+ if "ViewIdentifier" in localView:
123
+ rank = int(localView.ViewIdentifier)
124
+ localView["rank"] = rank
125
+ if "FileName" in localView:
126
+ name = localView.FileName
127
+ localView["name"] = name
128
+ if "ViewTypeCategory" in localView:
129
+ localType = localView.ViewTypeCategory
130
+ localView["type"] = localType
131
+ legends = []
132
+ if "ViewTypeTextBag" in localView:
133
+ for local_legend in localView.ViewTypeTextBag:
134
+ legend = {}
135
+ legend["languageCode"] = local_legend._languageCode
136
+ legend["legend"] = local_legend.__value
137
+ legends.append(legend)
138
+ if len(legends) > 0:
139
+ localView["legends"] = legends
140
+ return views
141
+
142
+ def format_address(address_lines):
143
+ address = ""
144
+ if not isinstance(address_lines, list):
145
+ address_lines = [address_lines]
146
+ for address_line in address_lines:
147
+ if "__value" in address_line:
148
+ address += address_line.__value + ' \n'
149
+ if len(address) > 0:
150
+ return address.strip()
151
+ else:
152
+ return None
153
+
154
+ def format_complete_address(PostalStructuredAddress):
155
+ adr_lines = format_address(PostalStructuredAddress.AddressLineText)
156
+ address = []
157
+ if adr_lines:
158
+ address.append(adr_lines)
159
+ if PostalStructuredAddress.CityName:
160
+ address.append(PostalStructuredAddress.CityName.strip())
161
+ if PostalStructuredAddress.GeographicRegionName:
162
+ address.append(PostalStructuredAddress.GeographicRegionName.strip())
163
+ if PostalStructuredAddress.PostalCode:
164
+ address.append(PostalStructuredAddress.PostalCode.strip())
165
+ if PostalStructuredAddress.CountryCode:
166
+ address.append(PostalStructuredAddress.CountryCode.strip())
167
+ return ' '.join(address)
168
+
169
+ def getOfficeStatusDate(registrationDate, expiryDate, histories, designIdentifier, countryCode=None):
170
+ expiryDate = getExpiryDate(expiryDate, histories, designIdentifier)
171
+ grantedDate = None
172
+ if countryCode != None:
173
+ # check possible renunciation including the particular country if specified
174
+ for history in histories:
175
+ if "HagueRenunciation" in history:
176
+ # is the design identifier in the list of affected designs?
177
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueRenunciation):
178
+ if "DesignatedCountryBag" in history.HagueRenunciation:
179
+ for designatedCountry in history.HagueRenunciation.DesignatedCountryBag.DesignatedCountry:
180
+ if isinstance(designatedCountry, str):
181
+ if history.HagueRenunciation.DesignatedCountryBag.DesignatedCountry.DesignatedCountryCode == countryCode:
182
+ history.HagueRenunciation.InternationalRecordingDate
183
+ elif designatedCountry.DesignatedCountryCode == countryCode:
184
+ return history.HagueRenunciation.InternationalRecordingDate
185
+
186
+ # to be tested: same for HagueLimitation, which is very similar to HagueRenunciation
187
+ if "HagueLimitation" in history:
188
+ # is the design identifier in the list of affected designs?
189
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueLimitation):
190
+ if "DesignatedCountryBag" in history.HagueLimitation:
191
+ for designatedCountry in history.HagueLimitation.DesignatedCountryBag.DesignatedCountry:
192
+ if isinstance(designatedCountry, str):
193
+ if history.HagueLimitation.DesignatedCountryBag.DesignatedCountry.DesignatedCountryCode == countryCode:
194
+ return history.HagueLimitation.InternationalRecordingDate
195
+ elif designatedCountry.DesignatedCountryCode == countryCode:
196
+ return history.HagueLimitation.InternationalRecordingDate
197
+
198
+ if "HagueGrantProtection" in history:
199
+ # is the design identifier in the list of affected designs?
200
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueGrantProtection.AffectedDesign):
201
+ if "RecordNotifyingOfficeCode" in history.HagueGrantProtection:
202
+ if history.HagueGrantProtection.RecordNotifyingOfficeCode == countryCode:
203
+ grantedDate = history.HagueGrantProtection.InternationalRecordingDate
204
+
205
+ # other events potentially impacting status:
206
+ # to check: HagueInvalidation, HagueMerger, however no occurance since 2018 data
207
+
208
+ refusalDate = getRefusalDate(histories, designIdentifier, countryCode)
209
+ # refusal is per designated countries, not just by design
210
+ if refusalDate != None and len(refusalDate) >= 0 and grantedDate is None:
211
+ return refusalDate
212
+
213
+ if grantedDate is not None:
214
+ registrationDate = grantedDate
215
+
216
+ if expiryDate == None or len(expiryDate) == 0:
217
+ return registrationDate
218
+
219
+ registrationDateObject = datetime.strptime(registrationDate, '%Y-%m-%d').date()
220
+ expiryDateObject = datetime.strptime(expiryDate, '%Y-%m-%d').date()
221
+
222
+ # the following gives the date of the last extension, if any
223
+ lastRenewalDate = getLastRenewalDate(histories, designIdentifier)
224
+ lastRenewalDateObject = datetime.strptime(expiryDate, '%Y-%m-%d').date()
225
+
226
+ if lastRenewalDateObject > registrationDateObject:
227
+ return lastRenewalDate
228
+ else:
229
+ return registrationDate
230
+
231
+ def getGbdStatus(registrationDate, expiryDate, histories, designIdentifier, countryCode=None):
232
+ # (Ended|Expired|Pending|Registered|Unknown)
233
+ # note: Ended is for every non-active cases except expired ones, so withdrawal, refusal,
234
+ # renunciation
235
+
236
+ # if we have specified a country, check if the country is not part of a renunciation,
237
+ # then the status would be Ended for all design following Hague XML schema explanations
238
+ grantedDate = None
239
+ if countryCode != None:
240
+ for history in histories:
241
+ if "HagueRenunciation" in history:
242
+ # is the design identifier in the list of affected designs?
243
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueRenunciation):
244
+ if "DesignatedCountryBag" in history.HagueRenunciation:
245
+ for designatedCountry in history.HagueRenunciation.DesignatedCountryBag.DesignatedCountry:
246
+ if isinstance(designatedCountry, str):
247
+ if history.HagueRenunciation.DesignatedCountryBag.DesignatedCountry.DesignatedCountryCode == countryCode:
248
+ return "Ended"
249
+ elif designatedCountry.DesignatedCountryCode == countryCode:
250
+ return "Ended"
251
+
252
+ # to be tested: same for HagueLimitation, which is very similar to HagueRenunciation
253
+ if "HagueLimitation" in history:
254
+ # is the design identifier in the list of affected designs?
255
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueLimitation):
256
+ if "DesignatedCountryBag" in history.HagueLimitation:
257
+ for designatedCountry in history.HagueLimitation.DesignatedCountryBag.DesignatedCountry:
258
+ if isinstance(designatedCountry, str):
259
+ if history.HagueLimitation.DesignatedCountryBag.DesignatedCountry.DesignatedCountryCode == countryCode:
260
+ return "Ended"
261
+ elif designatedCountry.DesignatedCountryCode == countryCode:
262
+ return "Ended"
263
+
264
+ if "HagueGrantProtection" in history:
265
+ # is the design identifier in the list of affected designs?
266
+ if designIdentifier == None or isAffectedDesignIdentifier(designIdentifier, history.HagueGrantProtection.AffectedDesign):
267
+ if "RecordNotifyingOfficeCode" in history.HagueGrantProtection:
268
+ if history.HagueGrantProtection.RecordNotifyingOfficeCode == countryCode:
269
+ grantedDate = history.HagueGrantProtection.InternationalRecordingDate
270
+
271
+ # other events potentially impacting status:
272
+ # to check: HagueInvalidation, HagueMerger, however no occurance since 2018 data
273
+
274
+ # check refusal, refusal is per designated countries, not just by design
275
+ # unfortunately it seems that conditional refusal are encoded as refusal, so
276
+ # so we have to look for a follow-up grant to recover this problem
277
+ if countryCode != None:
278
+ refusalDate = getRefusalDate(histories, designIdentifier, countryCode)
279
+ if refusalDate != None and len(refusalDate)>0 and grantedDate is None:
280
+ return "Ended"
281
+
282
+ if grantedDate is not None:
283
+ registrationDate = grantedDate
284
+
285
+ if registrationDate == None or len(registrationDate) == 0:
286
+ return "Pending"
287
+
288
+ expiryDate = getExpiryDate(expiryDate, histories, designIdentifier, countryCode)
289
+ if expiryDate == None or len(expiryDate) == 0:
290
+ return "Registered"
291
+
292
+ try:
293
+ registrationDateObject = datetime.strptime(registrationDate, '%Y-%m-%d').date()
294
+ expiryDateObject = datetime.strptime(expiryDate, '%Y-%m-%d').date()
295
+ currentDate = date.today()
296
+
297
+ if expiryDateObject < currentDate:
298
+ return "Expired"
299
+ else:
300
+ return "Registered"
301
+ except Exception as e:
302
+ print("invalid date")
303
+ print(e)
304
+
305
+ return "Unknown"
306
+
307
+ def isAffectedDesignIdentifier(designIdentifier, affectedDesignBlock):
308
+ '''
309
+ Return True if the identified design is included in the affected design information
310
+ '''
311
+ if "AllDesignsIndicator" in affectedDesignBlock:
312
+ return True
313
+ elif "DesignIdentifierBag" in affectedDesignBlock:
314
+ affectedDesignIdentifiers = []
315
+ for identifier in affectedDesignBlock.DesignIdentifierBag.DesignIdentifier:
316
+ affectedDesignIdentifiers.append(identifier)
317
+ if designIdentifier in affectedDesignIdentifiers:
318
+ return True
319
+ else:
320
+ return False
321
+ return False
322
+
323
+ possibleEventsFromOffice = [ "HagueGrantProtection", "HagueRefusal" ]
324
+
325
+ def isApplicableToCountry(countryCode, hagueHistoryEvent):
326
+ '''
327
+ Return True if the history event is applicable to the provided country
328
+ '''
329
+ if "RecordNotifyingOfficeCode" in hagueHistoryEvent:
330
+ if hagueHistoryEvent.RecordNotifyingOfficeCode == countryCode:
331
+ return True
332
+ elif "DesignatedCountryBag" in hagueHistoryEvent:
333
+ if "DesignatedCountry" in hagueHistoryEvent.DesignatedCountryBag:
334
+ for designatedCountry in hagueHistoryEvent.DesignatedCountryBag.DesignatedCountry:
335
+ if isinstance(designatedCountry, str):
336
+ if hagueHistoryEvent.DesignatedCountryBag.DesignatedCountry.DesignatedCountryCode == countryCode:
337
+ return True
338
+ elif designatedCountry.DesignatedCountryCode == countryCode:
339
+ return True
340
+ return False
341
+
342
+