allocine 0.1.0__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.
@@ -0,0 +1,448 @@
1
+ # Based on https://gist.github.com/Mathieu-Castets/e36488c518d1fc4a03fa (thank you!)
2
+ nationalities = {
3
+ "AD": ("andorran", "andorrane"),
4
+ "AE": ("émirien", "émirienne"),
5
+ "AF": ("afghan", "afghane"),
6
+ "AG": ("antiguayen", "antiguayenne"),
7
+ "AI": ("anguillais", "anguillaise"),
8
+ "AL": ("albanais", "albanaise"),
9
+ "AM": ("arménien", "arménienne"),
10
+ "AO": ("angolais", "angolaise"),
11
+ "AR": ("argentin", "argentine"),
12
+ "AS": ("samoan", "samoane"),
13
+ "AT": ("autrichien", "autrichienne"),
14
+ "AU": ("australien", "australienne"),
15
+ "AW": ("arubain", "arubaine"),
16
+ "AX": ("ålandais", "ålandaise"),
17
+ "AZ": ("azerbaïdjanais", "azerbaïdjanaise"),
18
+ "BA": ("bosnien", "bosnienne"),
19
+ "BB": ("barbadien", "barbadienne"),
20
+ "BD": ("bangladais", "bangladaise"),
21
+ "BE": ("belge", "belge"),
22
+ "BF": ("burkinabè", "burkinabè"),
23
+ "BG": ("bulgare", "bulgare"),
24
+ "BH": ("bahreïnien", "bahreïnienne"),
25
+ "BI": ("burundais", "burundaise"),
26
+ "BJ": ("béninois", "béninoise"),
27
+ "BM": ("bermudien", "bermudienne"),
28
+ "BN": ("brunéiens", "brunéiennes"),
29
+ "BO": ("bolivien", "bolivienne"),
30
+ "BR": ("brésilien", "brésilienne"),
31
+ "BS": ("bahamien", "bahamienne"),
32
+ "BT": ("bhoutanais", "bhoutanaise"),
33
+ "BW": ("botswanais", "botswanaise"),
34
+ "BY": ("biélorusse", "biélorusse"),
35
+ "BZ": ("bélizien", "bélizienne"),
36
+ "CA": ("canadien", "canadienne"),
37
+ "CD": ("congolais", "congolaise"),
38
+ "CF": ("centrafricain", "centrafricaine"),
39
+ "CG": ("congolais", "congolaise"),
40
+ "CH": ("suisse", "suissesse"),
41
+ "CI": ("ivoirien", "ivoirienne"),
42
+ "CK": ("cookien", "cookienne"),
43
+ "CL": ("chilien", "chilienne"),
44
+ "CM": ("camerounais", "camerounaise"),
45
+ "CN": ("chinois", "chinoise"),
46
+ "CO": ("colombien", "colombienne"),
47
+ "CR": ("costaricien", "costaricienne"),
48
+ "CU": ("cubain", "cubaine"),
49
+ "CV": ("cap-verdien", "cap-verdienne"),
50
+ "CY": ("chypriote", "chypriote"),
51
+ "CS": ("tchécoslovaque", "tchécoslovaque"),
52
+ "CZ": ("tchèque", "tchèque"),
53
+ "DE": ("allemand", "allemande"),
54
+ "DJ": ("djiboutien", "djiboutienne"),
55
+ "DK": ("danois", "danoise"),
56
+ "DM": ("dominiquais", "dominiquaise"),
57
+ "DO": ("dominicain", "dominicaine"),
58
+ "DZ": ("algérien", "algérienne"),
59
+ "EC": ("équatorien", "équatorienne"),
60
+ "EE": ("estonien", "estonienne"),
61
+ "EG": ("égyptien", "égyptienne"),
62
+ "EH": ("sahraoui", "sahraouie"),
63
+ "EL": ("grec", "grecque"),
64
+ "ER": ("érythréen", "érythréenne"),
65
+ "ES": ("espagnol", "espagnole"),
66
+ "ET": ("éthiopien", "éthiopienne"),
67
+ "FI": ("finlandais", "finlandaise"),
68
+ "FJ": ("fidjien", "fidjienne"),
69
+ "FK": ("malouin", "malouine"),
70
+ "FM": ("micronésien", "micronésienne"),
71
+ "FO": ("féroïen", "féroïenne"),
72
+ "FR": ("français", "française"),
73
+ "GA": ("gabonais", "gabonaise"),
74
+ "GB": ("britannique", "britannique"),
75
+ "GD": ("grenadin", "grenadine"),
76
+ "GE": ("géorgien", "géorgienne"),
77
+ "GH": ("ghanéen", "ghanéenne"),
78
+ "GI": ("gibraltarien", "gibraltarienne"),
79
+ "GL": ("groenlandais", "groenlandaise"),
80
+ "GM": ("gambien", "gambienne"),
81
+ "GN": ("guinéen", "guinéenne"),
82
+ "GQ": ("équatoguinéen", "équatoguinéenne"),
83
+ "GR": ("grec", "grecque"),
84
+ "GT": ("guatémaltèque", "guatémaltèque"),
85
+ "GU": ("guamien", "guamienne"),
86
+ "GW": ("bissaoguinéen", "bissaoguinéenne"),
87
+ "GY": ("guyanien", "guyanienne"),
88
+ "HK": ("hongkongais", "hongkongaise"),
89
+ "HN": ("hondurien", "hondurienne"),
90
+ "HR": ("croate", "croate"),
91
+ "HT": ("haïtien", "haïtienne"),
92
+ "HU": ("hongrois", "hongroise"),
93
+ "ID": ("indonésien", "indonésienne"),
94
+ "IE": ("irlandais", "iirlandaise"),
95
+ "IL": ("israélien", "israélienne"),
96
+ "IN": ("indien", "indienne"),
97
+ "IQ": ("iraquien", "iraquienne"),
98
+ "IR": ("iranien", "iranienne"),
99
+ "IS": ("islandais", "islandaise"),
100
+ "IT": ("italien", "italienne"),
101
+ "JM": ("jamaïcain", "jamaïcaine"),
102
+ "JO": ("jordanien", "jordanienne"),
103
+ "JP": ("japonais", "japonaise"),
104
+ "KE": ("kényan", "kényane"),
105
+ "KG": ("kirghize", "kirghize"),
106
+ "KH": ("cambodgien", "cambodgienne"),
107
+ "KI": ("kiribatien", "kiribatienne"),
108
+ "KM": ("comorien", "comorienne"),
109
+ "KN": ("christophien", "christophienne"),
110
+ "KP": ("nord-coréen", "nord-coréenne"),
111
+ "KR": ("sud-coréen", "sud-coréenne"),
112
+ "KW": ("koweïtien", "koweïtienne"),
113
+ "KY": ("caïmanais", "caïmanaise"),
114
+ "KZ": ("kazakh", "kazakhe"),
115
+ "LA": ("laotien", "laotienne"),
116
+ "LB": ("libanais", "libanaise"),
117
+ "LC": ("saint-lucien", "saint-lucienne"),
118
+ "LI": ("liechtensteinois", "liechtensteinoise"),
119
+ "LK": ("sri-lankais", "sri-lankaise"),
120
+ "LR": ("libérien", "libérienne"),
121
+ "LS": ("mosotho", "mosotho"),
122
+ "LT": ("lituanien", "lituanienne"),
123
+ "LU": ("luxembourgeois", "luxembourgeoise"),
124
+ "LV": ("letton", "lettone"),
125
+ "LY": ("libyen", "libyenne"),
126
+ "MA": ("marocain", "marocaine"),
127
+ "MC": ("monégasque", "monégasque"),
128
+ "MD": ("moldave", "moldave"),
129
+ "ME": ("monténégrin", "monténégrine"),
130
+ "MG": ("malgache", "malgache"),
131
+ "MH": ("marshallais", "marshallaise"),
132
+ "MK": ("macédonien", "macédonienne"),
133
+ "ML": ("malien", "malienne"),
134
+ "MM": ("birman", "birmane"),
135
+ "MN": ("mongol", "mongole"),
136
+ "MO": ("macanais", "macanaise"),
137
+ "MP": ("mariannais", "mariannaise"),
138
+ "MR": ("mauritanien", "mauritanienne"),
139
+ "MS": ("montserratien", "montserratienne"),
140
+ "MT": ("maltais", "maltaise"),
141
+ "MU": ("mauricien", "mauricienne"),
142
+ "MV": ("maldivien", "maldivienne"),
143
+ "MW": ("malawien", "malawienne"),
144
+ "MX": ("mexicain", "mexicaine"),
145
+ "MY": ("malaisien", "malaisienne"),
146
+ "MZ": ("mozambicain", "mozambicaine"),
147
+ "NA": ("namibien", "namibienne"),
148
+ "NE": ("nigérien", "nigérienne"),
149
+ "NG": ("nigérian", "nigériane"),
150
+ "NI": ("nicaraguayen", "nicaraguayenne"),
151
+ "NL": ("néerlandais", "néerlandaise"),
152
+ "NO": ("norvégien", "norvégienne"),
153
+ "NP": ("népalais", "népalaise"),
154
+ "NR": ("nauruan", "nauruane"),
155
+ "NU": ("niuéan", "niuéane"),
156
+ "NZ": ("néo-zélandais", "néo-zélandaise"),
157
+ "OM": ("omanais", "omanaise"),
158
+ "PA": ("panaméen", "panaméenne"),
159
+ "PE": ("péruvien", "péruvienne"),
160
+ "PG": ("papouasien", "papouasienne"),
161
+ "PH": ("philippin", "philippine"),
162
+ "PK": ("pakistanais", "pakistanaise"),
163
+ "PL": ("polonais", "polonaise"),
164
+ "PR": ("portoricain", "portoricaine"),
165
+ "PS": ("palestinien", "palestinienne"),
166
+ "PT": ("portugais", "portugaise"),
167
+ "PW": ("palaois", "palaoise"),
168
+ "PY": ("paraguayen", "paraguayenne"),
169
+ "QA": ("qatarien", "qatarienne"),
170
+ "RO": ("roumain", "roumaine"),
171
+ "RS": ("serbe", "serbe"),
172
+ "RU": ("russe", "russe"),
173
+ "RW": ("rwandais", "rwandaise"),
174
+ "SA": ("saoudien", "saoudienne"),
175
+ "SB": ("salomonais", "salomonaise"),
176
+ "SC": ("seychellois", "seychelloise"),
177
+ "SD": ("soudanais", "soudanaise"),
178
+ "SE": ("suédois", "suédoise"),
179
+ "SG": ("singapourien", "singapourienne"),
180
+ "SI": ("slovène", "slovène"),
181
+ "SK": ("slovaque", "slovaque"),
182
+ "SL": ("sierraléonais", "sierraléonaise"),
183
+ "SM": ("saint-marinais", "saint-marinaise"),
184
+ "SN": ("sénégalais", "sénégalaise"),
185
+ "SO": ("somalien", "somalienne"),
186
+ "SR": ("surinamais", "surinamaise"),
187
+ "SS": ("sud-soudanais", "sud-soudanaise"),
188
+ "ST": ("santoméen", "santoméenne"),
189
+ "SU": ("soviétique", "soviétique"),
190
+ "SV": ("salvadorien", "salvadorienne"),
191
+ "SY": ("syrien", "syrienne"),
192
+ "SZ": ("swazi", "swazie"),
193
+ "TC": ("émirats arabes unis", "émirats arabes unis"),
194
+ "TD": ("tchadien", "tchadienne"),
195
+ "TG": ("togolais", "togolaise"),
196
+ "TH": ("thaïlandais", "thaïlandaise"),
197
+ "TJ": ("tadjik", "tadjike"),
198
+ "TK": ("tokélaouen", "tokélaouenne"),
199
+ "TL": ("timorais", "timoraise"),
200
+ "TM": ("turkmène", "turkmène"),
201
+ "TN": ("tunisien", "tunisienne"),
202
+ "TO": ("tongan", "tongane"),
203
+ "TP": ("est-timorais", "est-timoraise"),
204
+ "TR": ("turc", "turque"),
205
+ "TT": ("trinidadien", "trinidadienne"),
206
+ "TV": ("tuvaluan", "tuvaluane"),
207
+ "TW": ("taïwanais", "taïwanaise"),
208
+ "TZ": ("tanzanien", "tanzanienne"),
209
+ "UA": ("ukrainien", "ukrainienne"),
210
+ "UG": ("ougandais", "ougandaise"),
211
+ "UK": ("britannique", "britannique"),
212
+ "US": ("américain", "américaine"),
213
+ "UY": ("uruguayen", "uruguayenne"),
214
+ "UZ": ("ouzbek", "ouzbèke"),
215
+ "VC": ("vincentais", "vincentaise"),
216
+ "VE": ("vénézuélien", "vénézuélienne"),
217
+ "VG": ("insulaires des îles vierges britanniques", "insulaires des îles vierges britanniques"),
218
+ "VI": ("insulaires des îles vierges", "insulaires des îles vierges"),
219
+ "VN": ("vietnamien", "vietnamienne"),
220
+ "VU": ("vanuatuan", "vanuatuane"),
221
+ "WS": ("samoan", "samoane"),
222
+ "XK": ("kosovar", "kosovare"),
223
+ "YE": ("yéménite", "yéménite"),
224
+ "YU": ("serbe", "serbe"),
225
+ "ZA": ("sud-africain", "sud-africaine"),
226
+ "ZM": ("zambien", "zambienne"),
227
+ "ZW": ("zimbabwéen", "zimbabwéenne"),
228
+ }
229
+
230
+
231
+ countries = {
232
+ "andorre": "AD",
233
+ "emirats arabes unis": "AE",
234
+ "afghanistan": "AF",
235
+ "antigua et barbuda": "AG",
236
+ "anguilla": "AI",
237
+ "albanie": "AL",
238
+ "curacao": "AN",
239
+ "angola": "AO",
240
+ "argentine": "AR",
241
+ "samoa americaines": "AS",
242
+ "autriche": "AT",
243
+ "australie": "AU",
244
+ "aruba": "AW",
245
+ "azerbaidjan": "AZ",
246
+ "bosnie-herzegovine": "BA",
247
+ "barbade": "BB",
248
+ "bangladesh": "BD",
249
+ "belgique": "BE",
250
+ "burkina faso": "BF",
251
+ "bulgarie": "BG",
252
+ "bahrein": "BH",
253
+ "burundi": "BI",
254
+ "benin": "BJ",
255
+ "bermudes": "BM",
256
+ "brunei": "BN",
257
+ "bolivie": "BO",
258
+ "bresil": "BR",
259
+ "bahamas": "BS",
260
+ "bhoutan": "BT",
261
+ "botswana": "BW",
262
+ "bielorussie": "BY",
263
+ "belize": "BZ",
264
+ "canada": "CA",
265
+ "congo rdc": "CD",
266
+ "republique centrafricaine": "CF",
267
+ "congo (brazzaville)": "CG",
268
+ "suisse": "CH",
269
+ "cote d'ivoire": "CI",
270
+ "iles cook": "CK",
271
+ "chili": "CL",
272
+ "cameroun": "CM",
273
+ "chine": "CN",
274
+ "colombie": "CO",
275
+ "costa rica": "CR",
276
+ "cuba": "CU",
277
+ "cap vert": "CV",
278
+ "chypre": "CY",
279
+ "republique tcheque": "CZ",
280
+ "tchecoslovaquie": "CS",
281
+ "allemagne": "DE",
282
+ "allemagne de l'ouest": "DE",
283
+ "allemagne de l'est": "DE",
284
+ "djibouti": "DJ",
285
+ "danemark": "DK",
286
+ "dominique": "DM",
287
+ "republique dominicaine": "DO",
288
+ "algerie": "DZ",
289
+ "equateur": "EC",
290
+ "estonie": "EE",
291
+ "egypte": "EG",
292
+ "erythree": "ER",
293
+ "espagne": "ES",
294
+ "ethiopie": "ET",
295
+ "finlande": "FI",
296
+ "fidji": "FJ",
297
+ "iles malouines": "FK",
298
+ "micronesie": "FM",
299
+ "france": "FR",
300
+ "gabon": "GA",
301
+ "grande-bretagne": "GB", # modified based on allocine value, originally 'Royaume-Uni'
302
+ "grenade": "GD",
303
+ "georgie": "GE",
304
+ "ghana": "GH",
305
+ "gibraltar": "GI",
306
+ "gambie": "GM",
307
+ "guinee": "GN",
308
+ "guinee equatoriale": "GQ",
309
+ "grece": "GR",
310
+ "guatemala": "GT",
311
+ "guam": "GU",
312
+ "guinee-bissau": "GW",
313
+ "guyana": "GY",
314
+ "hong kong": "HK",
315
+ "hong-kong": "HK",
316
+ "honduras": "HN",
317
+ "croatie": "HR",
318
+ "haiti": "HT",
319
+ "hongrie": "HU",
320
+ "indonesie": "ID",
321
+ "irlande": "IE",
322
+ "israel": "IL",
323
+ "inde": "IN",
324
+ "irak": "IQ",
325
+ "islande": "IS",
326
+ "italie": "IT",
327
+ "jamaique": "JM",
328
+ "jordanie": "JO",
329
+ "japon": "JP",
330
+ "kenya": "KE",
331
+ "kyrghyzstan": "KG",
332
+ "cambodge": "KH",
333
+ "kiribati": "KI",
334
+ "comores": "KM",
335
+ "saint-christophe-et-nieves": "KN",
336
+ "coree du sud": "KR", # modified based on allocine value, originally 'Coree, Republique de'
337
+ "koweit": "KW",
338
+ "iles caimans": "KY",
339
+ "kazakhstan": "KZ",
340
+ "laos": "LA",
341
+ "liban": "LB",
342
+ "sainte-lucie": "LC",
343
+ "liechtenstein": "LI",
344
+ "sri lanka": "LK",
345
+ "liberia": "LR",
346
+ "lesotho": "LS",
347
+ "lituanie": "LT",
348
+ "luxembourg": "LU",
349
+ "lettonie": "LV",
350
+ "libye": "LY",
351
+ "maroc": "MA",
352
+ "monaco": "MC",
353
+ "moldavie": "MD",
354
+ "montenegro": "ME",
355
+ "madagascar": "MG",
356
+ "iles marshall": "MH",
357
+ "macedoine": "MK",
358
+ "mali": "ML",
359
+ "birmanie": "MM",
360
+ "mongolie": "MN",
361
+ "macao": "MO",
362
+ "iles mariannes du nord": "MP",
363
+ "mauritanie": "MR",
364
+ "montserrat": "MS",
365
+ "malte": "MT",
366
+ "maurice": "MU",
367
+ "maldives": "MV",
368
+ "malawi": "MW",
369
+ "mexique": "MX",
370
+ "malaisie": "MY",
371
+ "mozambique": "MZ",
372
+ "namibie": "NA",
373
+ "niger": "NE",
374
+ "nigeria": "NG",
375
+ "nicaragua": "NI",
376
+ "pays-bas": "NL",
377
+ "norvege": "NO",
378
+ "nepal": "NP",
379
+ "nauru": "NR",
380
+ "nioue": "NU",
381
+ "nouvelle-zelande": "NZ",
382
+ "oman": "OM",
383
+ "panama": "PA",
384
+ "perou": "PE",
385
+ "papouasie-nouvelle-guinee": "PG",
386
+ "philippines": "PH",
387
+ "pakistan": "PK",
388
+ "pologne": "PL",
389
+ "porto rico": "PR",
390
+ "autorite palestinienne": "PS",
391
+ "palestine": "PS",
392
+ "portugal": "PT",
393
+ "palaos": "PW",
394
+ "paraguay": "PY",
395
+ "qatar": "QA",
396
+ "roumanie": "RO",
397
+ "russie": "RU",
398
+ "rwanda": "RW",
399
+ "arabie saoudite": "SA",
400
+ "iles salomon": "SB",
401
+ "soudan": "SD",
402
+ "suede": "SE",
403
+ "singapour": "SG",
404
+ "slovenie": "SI",
405
+ "slovaquie": "SK",
406
+ "sierra leone": "SL",
407
+ "senegal": "SN",
408
+ "somalie": "SO",
409
+ "suriname": "SR",
410
+ "sao tome-et-principe": "ST",
411
+ "el salvador": "SV",
412
+ "saint-martin": "SX",
413
+ "syrie": "SY",
414
+ "iles turques-et-caiques": "TC",
415
+ "tchad": "TD",
416
+ "togo": "TG",
417
+ "thailande": "TH",
418
+ "tadjikistan": "TJ",
419
+ "turkmenistan": "TM",
420
+ "tunisie": "TN",
421
+ "tonga": "TO",
422
+ "timor oriental": "TP",
423
+ "turquie": "TR",
424
+ "trinite-et-tobago": "TT",
425
+ "tuvalu": "TV",
426
+ "taiwan": "TW",
427
+ "tanzanie": "TZ",
428
+ "ukraine": "UA",
429
+ "ouganda": "UG",
430
+ "u.r.s.s.": "SU",
431
+ "urss": "SU",
432
+ "u.s.a.": "US", # modified based on allocine value, originally 'etats-unis'
433
+ "uruguay": "UY",
434
+ "ouzbekistan": "UZ",
435
+ "saint-vincent-et-les grenadines": "VC",
436
+ "venezuela": "VE",
437
+ "iles vierges (britanniques)": "VG",
438
+ "iles vierges": "VI",
439
+ "vietnam": "VN",
440
+ "vanuatu": "VU",
441
+ "samoa occidentales": "WS",
442
+ "kosovo": "XK",
443
+ "yemen": "YE",
444
+ "serbie": "YU",
445
+ "afrique du sud": "ZA",
446
+ "zambie": "ZM",
447
+ "zimbabwe": "ZW",
448
+ }
allocine/schedules.py ADDED
@@ -0,0 +1,162 @@
1
+ from collections import OrderedDict
2
+ from datetime import date as Date
3
+ from datetime import time as Time
4
+ from datetime import timedelta
5
+ from typing import List, Tuple
6
+
7
+ from allocine.models import Schedule, Showtime, get_hour_short_str, to_french_short_weekday
8
+
9
+
10
+ def get_available_dates(showtimes: List[Showtime]):
11
+ dates = [s.date for s in showtimes]
12
+ return sorted(list(set(dates)))
13
+
14
+
15
+ def group_showtimes_per_schedule(showtimes: List[Showtime]):
16
+ showtimes_per_date = {}
17
+ available_dates = get_available_dates(showtimes=showtimes)
18
+ for available_date in available_dates:
19
+ showtimes_per_date[available_date] = get_showtimes_of_a_day(showtimes=showtimes, date=available_date)
20
+
21
+ grouped_showtimes = {}
22
+ for available_date in available_dates:
23
+ hours = [s.hour_short_str for s in showtimes_per_date[available_date]]
24
+ hours_str = ", ".join(hours)
25
+ if grouped_showtimes.get(hours_str) is None:
26
+ grouped_showtimes[hours_str] = []
27
+ grouped_showtimes[hours_str].append(available_date)
28
+ return grouped_showtimes
29
+
30
+
31
+ def build_program_str(showtimes: List[Showtime]):
32
+ schedules = [Schedule(s.date_time) for s in showtimes]
33
+ return build_weekly_schedule_str(schedules)
34
+
35
+
36
+ def check_schedules_within_week(schedule_list: List[Schedule]) -> bool:
37
+ schedule_dates = [s.date for s in schedule_list]
38
+ min_date = min(schedule_dates)
39
+ max_date = max(schedule_dates)
40
+ delta = max_date - min_date
41
+ if delta >= timedelta(days=7):
42
+ raise ValueError("Schedule list contains more days than the typical movie week")
43
+ # Check that the week is not from Mon/Tue to Wed/Thu/Fri/Sat/Sun
44
+ # because a typical week is from Wed to Tue
45
+ # but we need to handle the case of a schedule_list with only a few day
46
+ # ex: Wed, Mon = OK ; Tue = OK ; Mon, Wed : NOK
47
+ monday = 0
48
+ tuesday = 1
49
+ wednesday = 2
50
+ if delta > timedelta(days=0):
51
+ if (min_date.weekday() == monday and max_date.weekday() >= wednesday) or (min_date.weekday() == tuesday):
52
+ raise ValueError("Schedule list should not start before wednesday or end after tuesday")
53
+
54
+ return True
55
+
56
+
57
+ def create_weekdays_str(dates: List[Date]) -> str:
58
+ """
59
+ Returns a compact string from a list of dates.
60
+ Examples:
61
+ - [0,1] -> 'Lun, Mar'
62
+ - [0,1,2,3,4] -> 'sf Sam, Dim'
63
+ - [0,1,2,3,4,5,6] -> '' # Everyday is empty string
64
+ - [0,2] -> 'Mer, Lun' # And not 'Lun, Mer' because we sort chrologically
65
+ """
66
+ full_week = range(0, 7)
67
+ unique_dates = sorted(list(set(dates)))
68
+ week_days = [d.weekday() for d in unique_dates]
69
+
70
+ if len(unique_dates) == 7:
71
+ return ""
72
+ elif len(unique_dates) <= 4:
73
+ return ", ".join([to_french_short_weekday(d) for d in week_days])
74
+ else:
75
+ missing_days = list(set(week_days).symmetric_difference(full_week))
76
+ return "sf {}".format(", ".join([to_french_short_weekday(d) for d in missing_days]))
77
+
78
+
79
+ def _get_time_weight_in_list(item: Tuple[str, List[Time]]) -> timedelta:
80
+ """Returns the minimum time weight from the time list contained in the dict values
81
+ ex: {'key': [time(hour=12), time(hour=9)]} => timedelta(hour=9)
82
+ """
83
+ weights = [_get_time_weight(t) for t in item[1]]
84
+ return min(weights)
85
+
86
+
87
+ def _get_time_weight(t: Time) -> timedelta:
88
+ """Return a timedelta taking into account night time.
89
+ Basically, it allows to sort a list of times 18h>23h>0h30
90
+ and not 0h30>18h>23h
91
+ """
92
+ night_time = [Time(hour=0), Time(hour=5)]
93
+ delta = timedelta(hours=t.hour, minutes=t.minute)
94
+ if t >= min(night_time) and t <= max(night_time):
95
+ delta += timedelta(days=1)
96
+ return delta
97
+
98
+
99
+ def build_weekly_schedule_str(schedule_list: List[Schedule]) -> str:
100
+ check_schedules_within_week(schedule_list)
101
+
102
+ hours_hashmap_raw = {} # ex: {16h: [Lun, Mar], 17h: [Lun], 17h30: [Lun]}
103
+ grouped_date_hashmap_raw = {} # ex: {[Lun]: [16h, 17h30], [Lun, Mar]: [17h]}
104
+
105
+ for schedule in schedule_list:
106
+ if hours_hashmap_raw.get(schedule.hour) is None:
107
+ hours_hashmap_raw[schedule.hour] = []
108
+ hours_hashmap_raw[schedule.hour].append(schedule.date)
109
+
110
+ for hour, grouped_dates in hours_hashmap_raw.items():
111
+ grouped_dates_str = create_weekdays_str(grouped_dates)
112
+ if grouped_date_hashmap_raw.get(grouped_dates_str) is None:
113
+ grouped_date_hashmap_raw[grouped_dates_str] = []
114
+ grouped_date_hashmap_raw[grouped_dates_str].append(hour)
115
+
116
+ # Then sort it chronologically
117
+ for grouped_dates_str, hours in grouped_date_hashmap_raw.items():
118
+ # Sort the hours inside
119
+ hours = list(set(hours))
120
+ hours.sort()
121
+ grouped_date_hashmap_raw[grouped_dates_str] = hours
122
+
123
+ grouped_date_hashmap_raw = sorted(grouped_date_hashmap_raw.items(), key=_get_time_weight_in_list)
124
+ grouped_date_hashmap = OrderedDict(grouped_date_hashmap_raw)
125
+
126
+ hours_hashmap = OrderedDict()
127
+ for hour in sorted(hours_hashmap_raw.keys(), key=_get_time_weight):
128
+ hours_hashmap[hour] = hours_hashmap_raw.get(hour)
129
+
130
+ different_showtimes = len(grouped_date_hashmap)
131
+
132
+ # True if at least one schedule is available everyday
133
+ some_schedules_available_everyday = grouped_date_hashmap.get("") is not None
134
+
135
+ weekly_schedule = ""
136
+
137
+ if some_schedules_available_everyday:
138
+ for hour, grouped_dates in hours_hashmap.items():
139
+ hour_str = get_hour_short_str(hour)
140
+ grouped_dates_str = create_weekdays_str(grouped_dates)
141
+ if grouped_dates_str:
142
+ weekly_schedule += f"{hour_str} ({grouped_dates_str}), "
143
+ else: # Available everyday
144
+ weekly_schedule += f"{hour_str}, "
145
+ else:
146
+ for grouped_dates, hours in grouped_date_hashmap.items():
147
+ hours_str = ", ".join([get_hour_short_str(h) for h in hours])
148
+ if different_showtimes == 1:
149
+ weekly_schedule += f"{grouped_dates} {hours_str}, "
150
+ else:
151
+ if some_schedules_available_everyday:
152
+ weekly_schedule += f"{hours_str} ({grouped_dates}), "
153
+ else:
154
+ weekly_schedule += f"{grouped_dates} {hours_str}; "
155
+
156
+ if weekly_schedule:
157
+ weekly_schedule = weekly_schedule[:-2] # Remove trailing comma
158
+ return weekly_schedule
159
+
160
+
161
+ def get_showtimes_of_a_day(showtimes: List[Showtime], *, date: Date):
162
+ return [showtime for showtime in showtimes if showtime.date == date]