zou 0.20.26__py3-none-any.whl → 0.20.28__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.
zou/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.20.26"
1
+ __version__ = "0.20.28"
@@ -332,7 +332,8 @@ class AddAttachmentToCommentResource(Resource):
332
332
  user = persons_service.get_current_user()
333
333
  comment = tasks_service.get_comment(comment_id)
334
334
  if comment["person_id"] != user["id"]:
335
- permissions.check_admin_permissions()
335
+ task = tasks_service.get_task(task_id)
336
+ user_service.check_manager_project_access(task["project_id"])
336
337
 
337
338
  files = request.files
338
339
  comment = comments_service.add_attachments_to_comment(comment, files)
@@ -532,12 +532,12 @@ class PersonDayTimeSpentsResource(PersonDurationTimeSpentsResource):
532
532
  abort(404)
533
533
 
534
534
 
535
- class PersonQuotaMixin:
535
+ class PersonQuotaMixin(ArgsMixin):
536
536
 
537
537
  def get_quota_arguments(self):
538
538
  project_id = self.get_project_id()
539
539
  task_type_id = self.get_task_type_id()
540
- count_mode = self.get_text_parameter("count_mode", default="weigthed")
540
+ count_mode = self.get_text_parameter("count_mode", default="weighted")
541
541
  if count_mode not in ["weighted", "weighteddone", "feedback", "done"]:
542
542
  raise WrongParameterException(
543
543
  "count_mode must be equal to weighted, weigtheddone, feedback"
@@ -546,14 +546,49 @@ class PersonQuotaMixin:
546
546
  feedback = "done" not in count_mode
547
547
  weighted = "weighted" in count_mode
548
548
 
549
- return (project_id, task_type_id, count_mode, feedback, weighted)
549
+ return (project_id, task_type_id, feedback, weighted)
550
+
551
+ def check_permissions(self, person_id, project_id=None):
552
+ if permissions.has_manager_permissions():
553
+ user_service.check_manager_project_access(project_id)
554
+ else:
555
+ user_service.check_person_access(person_id)
556
+
557
+ def get_person_quotas(self):
558
+ pass
559
+
560
+ @jwt_required()
561
+ def get(self, person_id, *args, **kwargs):
562
+ user_service.check_person_is_not_bot(person_id)
563
+ (project_id, task_type_id, feedback, weighted) = (
564
+ self.get_quota_arguments()
565
+ )
566
+ self.check_permissions(person_id, project_id)
567
+
568
+ try:
569
+ return self.get_person_quotas(
570
+ person_id,
571
+ *args,
572
+ **kwargs,
573
+ project_id=project_id,
574
+ task_type_id=task_type_id,
575
+ feedback=feedback,
576
+ weighted=weighted,
577
+ )
578
+ except WrongDateFormatException:
579
+ abort(404)
550
580
 
551
581
 
552
- class PersonMonthQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
582
+ class PersonMonthQuotaShotsResource(Resource, PersonQuotaMixin):
553
583
  """
554
584
  Get ended shots used for quota calculation of this month.
555
585
  """
556
586
 
587
+ def get_person_quotas(self, person_id, year, month, **kwargs):
588
+ return shots_service.get_month_quota_shots(
589
+ person_id, year, month, **kwargs
590
+ )
591
+
557
592
  @jwt_required()
558
593
  def get(self, person_id, year, month):
559
594
  """
@@ -592,31 +627,19 @@ class PersonMonthQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
592
627
  404:
593
628
  description: Wrong date format
594
629
  """
595
- user_service.check_person_is_not_bot(person_id)
596
- user_service.check_person_access(person_id)
597
- (project_id, task_type_id, count_mode, feedback, weighted) = (
598
- self.get_quota_arguments()
599
- )
630
+ super().get(person_id, year, month)
600
631
 
601
- try:
602
- return shots_service.get_month_quota_shots(
603
- person_id,
604
- year,
605
- month,
606
- project_id=project_id,
607
- task_type_id=task_type_id,
608
- weighted=weighted,
609
- feedback=feedback,
610
- )
611
- except WrongDateFormatException:
612
- abort(404)
613
632
 
614
-
615
- class PersonWeekQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
633
+ class PersonWeekQuotaShotsResource(Resource, PersonQuotaMixin):
616
634
  """
617
635
  Get ended shots used for quota calculation of this week.
618
636
  """
619
637
 
638
+ def get_person_quotas(self, person_id, year, week, **kwargs):
639
+ return shots_service.get_week_quota_shots(
640
+ person_id, year, week, **kwargs
641
+ )
642
+
620
643
  @jwt_required()
621
644
  def get(self, person_id, year, week):
622
645
  """
@@ -655,31 +678,19 @@ class PersonWeekQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
655
678
  404:
656
679
  description: Wrong date format
657
680
  """
658
- user_service.check_person_is_not_bot(person_id)
659
- user_service.check_person_access(person_id)
660
- (project_id, task_type_id, count_mode, feedback, weighted) = (
661
- self.get_quota_arguments()
662
- )
663
-
664
- try:
665
- return shots_service.get_week_quota_shots(
666
- person_id,
667
- year,
668
- week,
669
- project_id=project_id,
670
- task_type_id=task_type_id,
671
- weighted=weighted,
672
- feedback=feedback,
673
- )
674
- except WrongDateFormatException:
675
- abort(404)
681
+ super().get(person_id, year, week)
676
682
 
677
683
 
678
- class PersonDayQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
684
+ class PersonDayQuotaShotsResource(Resource, PersonQuotaMixin):
679
685
  """
680
686
  Get ended shots used for quota calculation of this day.
681
687
  """
682
688
 
689
+ def get_person_quotas(self, person_id, year, month, day, **kwargs):
690
+ return shots_service.get_day_quota_shots(
691
+ person_id, year, month, day, **kwargs
692
+ )
693
+
683
694
  @jwt_required()
684
695
  def get(self, person_id, year, month, day):
685
696
  """
@@ -725,25 +736,7 @@ class PersonDayQuotaShotsResource(Resource, ArgsMixin, PersonQuotaMixin):
725
736
  404:
726
737
  description: Wrong date format
727
738
  """
728
- user_service.check_person_is_not_bot(person_id)
729
- user_service.check_person_access(person_id)
730
- (project_id, task_type_id, count_mode, feedback, weighted) = (
731
- self.get_quota_arguments()
732
- )
733
-
734
- try:
735
- return shots_service.get_day_quota_shots(
736
- person_id,
737
- year,
738
- month,
739
- day,
740
- project_id=project_id,
741
- task_type_id=task_type_id,
742
- weighted=weighted,
743
- feedback=feedback,
744
- )
745
- except WrongDateFormatException:
746
- abort(404)
739
+ super().get(person_id, year, month, day)
747
740
 
748
741
 
749
742
  class TimeSpentDurationResource(Resource, ArgsMixin):
@@ -1008,9 +1001,7 @@ class PersonWeekDayOffResource(Resource, ArgsMixin):
1008
1001
  description: All day off recorded for given week and person
1009
1002
  """
1010
1003
  user_service.check_person_is_not_bot(person_id)
1011
- user_id = persons_service.get_current_user()["id"]
1012
- if person_id != user_id:
1013
- permissions.check_admin_permissions()
1004
+ user_service.check_person_access(person_id)
1014
1005
  return time_spents_service.get_person_day_offs_for_week(
1015
1006
  person_id, year, week
1016
1007
  )
@@ -1052,9 +1043,7 @@ class PersonMonthDayOffResource(Resource, ArgsMixin):
1052
1043
  description: All day off recorded for given month and person
1053
1044
  """
1054
1045
  user_service.check_person_is_not_bot(person_id)
1055
- user_id = persons_service.get_current_user()["id"]
1056
- if person_id != user_id:
1057
- permissions.check_admin_permissions()
1046
+ user_service.check_person_access(person_id)
1058
1047
  return time_spents_service.get_person_day_offs_for_month(
1059
1048
  person_id, year, month
1060
1049
  )
@@ -1089,9 +1078,7 @@ class PersonYearDayOffResource(Resource, ArgsMixin):
1089
1078
  description: All day off recorded for given year and person
1090
1079
  """
1091
1080
  user_service.check_person_is_not_bot(person_id)
1092
- user_id = persons_service.get_current_user()["id"]
1093
- if person_id != user_id:
1094
- permissions.check_admin_permissions()
1081
+ user_service.check_person_access(person_id)
1095
1082
  return time_spents_service.get_person_day_offs_for_year(
1096
1083
  person_id, year
1097
1084
  )
@@ -1121,9 +1108,7 @@ class PersonDayOffResource(Resource, ArgsMixin):
1121
1108
  description: All day off recorded for given person.
1122
1109
  """
1123
1110
  user_service.check_person_is_not_bot(person_id)
1124
- user_id = persons_service.get_current_user()["id"]
1125
- if person_id != user_id:
1126
- permissions.check_admin_permissions()
1111
+ user_service.check_person_access(person_id)
1127
1112
  return time_spents_service.get_day_offs_between(
1128
1113
  person_id=person_id,
1129
1114
  )
@@ -1192,11 +1192,7 @@ class PersonThumbnailResource(BaseThumbnailResource):
1192
1192
  )
1193
1193
 
1194
1194
  def check_allowed_to_post(self, instance_id):
1195
- is_current_user = (
1196
- persons_service.get_current_user()["id"] == instance_id
1197
- )
1198
- if not is_current_user and not permissions.has_admin_permissions():
1199
- raise permissions.PermissionDenied
1195
+ user_service.check_person_access(instance_id)
1200
1196
 
1201
1197
  def prepare_creation(self, instance_id):
1202
1198
  self.model = self.update_model_func(
@@ -1646,7 +1646,13 @@ class ProjectPersonQuotasResource(Resource, ArgsMixin):
1646
1646
  description: Quotas statistics for shots
1647
1647
  """
1648
1648
  projects_service.get_project(project_id)
1649
- user_service.check_project_access(project_id)
1649
+ if (
1650
+ permissions.has_manager_permissions()
1651
+ or permissions.has_supervisor_permissions()
1652
+ ):
1653
+ user_service.check_project_access(project_id)
1654
+ else:
1655
+ user_service.check_person_access(person_id)
1650
1656
  args = self.get_args(
1651
1657
  [
1652
1658
  ("count_mode", "weighted", False, str),
@@ -1433,7 +1433,7 @@ def get_month_quota_shots(
1433
1433
  feedback=True,
1434
1434
  ):
1435
1435
  """
1436
- Return shots that are included in quota comptutation for given
1436
+ Return shots that are included in quota computation for given
1437
1437
  person and month.
1438
1438
  """
1439
1439
  start, end = date_helpers.get_month_interval(year, month)
@@ -395,8 +395,10 @@ def check_person_access(person_id):
395
395
  """
396
396
  Return True if user is an admin or is matching given person id.
397
397
  """
398
- current_user = persons_service.get_current_user()
399
- if permissions.has_admin_permissions() or current_user["id"] == person_id:
398
+ if (
399
+ permissions.has_admin_permissions()
400
+ or persons_service.get_current_user()["id"] == person_id
401
+ ):
400
402
  return True
401
403
  else:
402
404
  raise permissions.PermissionDenied
@@ -417,7 +419,7 @@ def check_belong_to_project(project_id):
417
419
 
418
420
  def has_project_access(project_id):
419
421
  """
420
- Return true if current user is a manager or has a task assigned for this
422
+ Return true if current user is an admin or has a task assigned for this
421
423
  project.
422
424
  """
423
425
  return permissions.has_admin_permissions() or check_belong_to_project(
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: zou
3
- Version: 0.20.26
3
+ Version: 0.20.28
4
4
  Summary: API to store and manage the data of your animation production
5
5
  Home-page: https://zou.cg-wire.com
6
6
  Author: CG Wire
@@ -51,26 +51,26 @@ Requires-Dist: ldap3==2.9.1
51
51
  Requires-Dist: matterhook==0.2
52
52
  Requires-Dist: meilisearch==0.34.0
53
53
  Requires-Dist: numpy==2.0.1; python_version == "3.9"
54
- Requires-Dist: numpy==2.2.3; python_version >= "3.10"
54
+ Requires-Dist: numpy==2.2.4; python_version >= "3.10"
55
55
  Requires-Dist: opencv-python==4.11.0.86
56
56
  Requires-Dist: OpenTimelineIO==0.17.0
57
57
  Requires-Dist: OpenTimelineIO-Plugins==0.17.0
58
- Requires-Dist: orjson==3.10.15
58
+ Requires-Dist: orjson==3.10.16
59
59
  Requires-Dist: pillow==11.1.0
60
60
  Requires-Dist: psutil==7.0.0
61
- Requires-Dist: psycopg[binary]==3.2.5
61
+ Requires-Dist: psycopg[binary]==3.2.6
62
62
  Requires-Dist: pyotp==2.9.0
63
63
  Requires-Dist: pysaml2==7.5.2
64
64
  Requires-Dist: python-nomad==2.1.0
65
65
  Requires-Dist: python-slugify==8.0.4
66
66
  Requires-Dist: python-socketio==5.12.1
67
- Requires-Dist: pytz==2025.1
67
+ Requires-Dist: pytz==2025.2
68
68
  Requires-Dist: redis==5.2.1
69
69
  Requires-Dist: requests==2.32.3
70
- Requires-Dist: rq==2.1.0
70
+ Requires-Dist: rq==2.2.0
71
71
  Requires-Dist: slackclient==2.9.4
72
72
  Requires-Dist: sqlalchemy_utils==0.41.2
73
- Requires-Dist: sqlalchemy==2.0.38
73
+ Requires-Dist: sqlalchemy==2.0.39
74
74
  Requires-Dist: ua-parser==1.0.1
75
75
  Requires-Dist: werkzeug==3.1.3
76
76
  Provides-Extra: prod
@@ -84,13 +84,14 @@ Requires-Dist: mixer==7.2.2; extra == "test"
84
84
  Requires-Dist: pytest-cov==6.0.0; extra == "test"
85
85
  Requires-Dist: pytest==8.3.5; extra == "test"
86
86
  Provides-Extra: monitoring
87
- Requires-Dist: prometheus-flask-exporter==0.23.1; extra == "monitoring"
87
+ Requires-Dist: prometheus-flask-exporter==0.23.2; extra == "monitoring"
88
88
  Requires-Dist: pygelf==0.4.2; extra == "monitoring"
89
- Requires-Dist: sentry-sdk==2.22.0; extra == "monitoring"
89
+ Requires-Dist: sentry-sdk==2.24.1; extra == "monitoring"
90
90
  Provides-Extra: lint
91
91
  Requires-Dist: autoflake==2.3.1; extra == "lint"
92
92
  Requires-Dist: black==25.1.0; extra == "lint"
93
- Requires-Dist: pre-commit==4.1.0; extra == "lint"
93
+ Requires-Dist: pre-commit==4.2.0; extra == "lint"
94
+ Dynamic: license-file
94
95
  Dynamic: requires-python
95
96
 
96
97
  .. figure:: https://zou.cg-wire.com/kitsu.png
@@ -1,4 +1,4 @@
1
- zou/__init__.py,sha256=uhGl1res98kiqEDpx7DwZ_agTcrQGc3X-FE3cNaE4xc,24
1
+ zou/__init__.py,sha256=lS0BgqFlmD2VCQ72vdCp-Kl8zeRZ2cwgpktzorWsby8,24
2
2
  zou/cli.py,sha256=HuYi2Ma7SP2SD7C9d9dwpZ49BHpytKIoyJP_su9JwZY,18755
3
3
  zou/debug.py,sha256=1fawPbkD4wn0Y9Gk0BiBFSa-CQe5agFi8R9uJYl2Uyk,520
4
4
  zou/event_stream.py,sha256=EpohqFJwWL0zs-Ic_W5dX5_XSDeCrqHQPL5Re39OnQ0,6382
@@ -18,7 +18,7 @@ zou/app/blueprints/breakdown/resources.py,sha256=pmGlHLiXFsPRbxf403SiVgGiaBbtK8G
18
18
  zou/app/blueprints/chats/__init__.py,sha256=YGmwGvddg3MgSYVIh-hmkX8t2em9_LblxBeJzFqFJD4,558
19
19
  zou/app/blueprints/chats/resources.py,sha256=4yLFermdwOsnBLs9nx8yxuHWLar24uQWQy0XgsUNDD0,5950
20
20
  zou/app/blueprints/comments/__init__.py,sha256=WqpJ7-_dK1cInGTFJAxQ7syZtPCotwq2oO20UEnk1h4,1532
21
- zou/app/blueprints/comments/resources.py,sha256=o_izuBb4Z2yNMpRa1rfS8Shf4PTFP5zuSbw51I-wS8g,19110
21
+ zou/app/blueprints/comments/resources.py,sha256=To2tyxh1pMkBAnlnj-0u3PGW70n4JTnNsv7BXw-Ng7I,19185
22
22
  zou/app/blueprints/concepts/__init__.py,sha256=sP_P4mfYvfMcgeE6MHZYP3eD0Lz0Lwit5-CFuVnA-Jg,894
23
23
  zou/app/blueprints/concepts/resources.py,sha256=maJNrBAWX0bKbDKtOZc3YFp4nTVtIdkkAA4H9WA9n1Y,10140
24
24
  zou/app/blueprints/crud/__init__.py,sha256=qn7xkEh2EG0mPS_RBmm0GgYr0O1jnmI8ymXZnFWZCz8,8361
@@ -87,17 +87,17 @@ zou/app/blueprints/index/resources.py,sha256=Z2N8fRffv4rkhazUe1_2x6I7-A01rCkCnBy
87
87
  zou/app/blueprints/news/__init__.py,sha256=HxBXjC15dVbotNAZ0CLf02iwUjxJr20kgf8_kT_9nwM,505
88
88
  zou/app/blueprints/news/resources.py,sha256=HdLq2NgfKyN2d3hIATBhH3dlk4c50I4dhhvEhhB_NY4,7334
89
89
  zou/app/blueprints/persons/__init__.py,sha256=0cnHHw3K_8OEMm0qOi3wKVomSAg9IJSnVjAXabMeHks,3893
90
- zou/app/blueprints/persons/resources.py,sha256=PfK6epzRn_kbqN6g9qYiH9XWStFlccTVCYyKxs72Hu8,42764
90
+ zou/app/blueprints/persons/resources.py,sha256=HpVKckUYu52qbMv-llVPqwP3dtD2Q43HxJ1zutQ7d3I,42163
91
91
  zou/app/blueprints/playlists/__init__.py,sha256=vuEk1F3hFHsmuKWhdepMoLyOzmNKDn1YrjjfcaIz0lQ,1596
92
92
  zou/app/blueprints/playlists/resources.py,sha256=alRlMHypUFErXLsEYxpFK84cdjFJ3YWwamZtW0KcwLY,17211
93
93
  zou/app/blueprints/previews/__init__.py,sha256=ihC6OQ9AUjnZ2JeMnjRh_tKGO0UmAjOwhZnOivc3BnQ,4460
94
- zou/app/blueprints/previews/resources.py,sha256=i_BwkcPLKh-ktxckwcesXddgXmA9D6JnSTZjkEnL8uE,53551
94
+ zou/app/blueprints/previews/resources.py,sha256=uyjfW3vyE2a1PPXO8MsHP8-3jhuVKHt3oi2pYsq-ZIw,53376
95
95
  zou/app/blueprints/projects/__init__.py,sha256=Pn3fA5bpNFEPBzxTKJ2foV6osZFflXXSM2l2uZh3ktM,3927
96
96
  zou/app/blueprints/projects/resources.py,sha256=1WBS2FyaY1RSA_T-BdPnc8X9myjTJ127bMDigyoAklk,31979
97
97
  zou/app/blueprints/search/__init__.py,sha256=QCjQIY_85l_orhdEiqav_GifjReuwsjZggN3V0GeUVY,356
98
98
  zou/app/blueprints/search/resources.py,sha256=_QgRlUuxCPgY-ip5r2lGFtXNcGSE579JsCSrVf8ajVU,3093
99
99
  zou/app/blueprints/shots/__init__.py,sha256=EcG9qmAchlucqg1M6-RqWGfuKpa5Kq6RgyLZNSsjUr4,4225
100
- zou/app/blueprints/shots/resources.py,sha256=WOWvYOEVxv3mu1PKTFg6lGoTfM_UQ5n-iJTUFuZKMh8,52162
100
+ zou/app/blueprints/shots/resources.py,sha256=Uv8zXKK1e23U0Sw11qjnJT7-JrirDPjS8usQKMHzix0,52366
101
101
  zou/app/blueprints/source/__init__.py,sha256=H7K-4TDs4pc5EJvcYTYMJBHesxyqsE5-xq7J8ckOS2g,6093
102
102
  zou/app/blueprints/source/kitsu.py,sha256=4lWdqxaKDzwx-5POAIHIgZ6ODbDMOOVRxaSb_FOLcCk,5012
103
103
  zou/app/blueprints/source/otio.py,sha256=nTXQEauFinPv2QBXziJW83rSrB_qzIbkFQ_qgxbJynA,13419
@@ -206,14 +206,14 @@ zou/app/services/preview_files_service.py,sha256=Yk-vwzHuKTzNkEZfl9DhQRdDuRU006u
206
206
  zou/app/services/projects_service.py,sha256=aIbYaFomy7OX2Pxvkf9w5qauDvkjuc9ummSGNYIpQMY,21249
207
207
  zou/app/services/scenes_service.py,sha256=iXN19HU4njPF5VtZXuUrVJ-W23ZQuQNPC3ADXltbWtU,992
208
208
  zou/app/services/schedule_service.py,sha256=E99HKYsXgnK2sw58fw-NNHXWBgVJiA60upztjkNSCaM,6989
209
- zou/app/services/shots_service.py,sha256=UW7QcW2Gi_OsbBuR_96FCjNKnsm3SH2R1AcBRnL9pzo,54803
209
+ zou/app/services/shots_service.py,sha256=NxIK_kluFR284jufZt76xvHxsS-BQBOG6IW5tpz4O68,54802
210
210
  zou/app/services/stats_service.py,sha256=e9h090eZWADtzXycy1WOup_jlxGwQojrr1y_PDcVatc,13156
211
211
  zou/app/services/status_automations_service.py,sha256=tVio7Sj7inhvKS4UOyRhcdpwr_KNP96hT1o0X7XcGF4,715
212
212
  zou/app/services/sync_service.py,sha256=iWxx1kOGEXympHmSBBQWtDZWNtumdxp8kppee0OefMo,41811
213
213
  zou/app/services/tasks_service.py,sha256=6ZFq4DhJ9HDgWT3CcikUWWImMNuHko1Bz_ARKPfeoEw,69775
214
214
  zou/app/services/telemetry_services.py,sha256=xQm1h1t_JxSFW59zQGf4NuNdUi1UfMa_6pQ-ytRbmGA,1029
215
215
  zou/app/services/time_spents_service.py,sha256=H9X-60s6oqtY9rtU-K2jKwUSljfkdGlf_9wMr3iVfIA,15158
216
- zou/app/services/user_service.py,sha256=SKW6n3eMRDUJljUE893cYUrg00xyUwUkxLHzQHjIZT0,51362
216
+ zou/app/services/user_service.py,sha256=-ST4zUm2rbdXgdw2xzVJaYEA-LAsZvInRjDvpCC8GJA,51353
217
217
  zou/app/stores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
218
218
  zou/app/stores/auth_tokens_store.py,sha256=-qOJPybLHvnMOq3PWk073OW9HJwOHGhFLZeOIlX1UVw,1290
219
219
  zou/app/stores/file_store.py,sha256=yLQDM6mNbj9oe0vsWdBqun7D8Dw-eSjD1yHCCftX0OI,4045
@@ -420,9 +420,9 @@ zou/remote/normalize_movie.py,sha256=zNfEY3N1UbAHZfddGONTg2Sff3ieLVWd4dfZa1dpnes
420
420
  zou/remote/playlist.py,sha256=AsDo0bgYhDcd6DfNRV6r6Jj3URWwavE2ZN3VkKRPbLU,3293
421
421
  zou/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
422
422
  zou/utils/movie.py,sha256=d67fIL9dVBKt-E_qCGXRbNNdbJaJR5sHvZeX3hf8ldE,16559
423
- zou-0.20.26.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
424
- zou-0.20.26.dist-info/METADATA,sha256=qSn_1o3aw1Dr5Se1i1Cm00c2lGZ1CupYOh50b5UrCbA,6673
425
- zou-0.20.26.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
426
- zou-0.20.26.dist-info/entry_points.txt,sha256=PelQoIx3qhQ_Tmne7wrLY-1m2izuzgpwokoURwSohy4,130
427
- zou-0.20.26.dist-info/top_level.txt,sha256=4S7G_jk4MzpToeDItHGjPhHx_fRdX52zJZWTD4SL54g,4
428
- zou-0.20.26.dist-info/RECORD,,
423
+ zou-0.20.28.dist-info/licenses/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
424
+ zou-0.20.28.dist-info/METADATA,sha256=RzMWJ1L0ABIKyXtZmadHniNlpghuRiXnlWI_pgRjjJw,6695
425
+ zou-0.20.28.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
426
+ zou-0.20.28.dist-info/entry_points.txt,sha256=PelQoIx3qhQ_Tmne7wrLY-1m2izuzgpwokoURwSohy4,130
427
+ zou-0.20.28.dist-info/top_level.txt,sha256=4S7G_jk4MzpToeDItHGjPhHx_fRdX52zJZWTD4SL54g,4
428
+ zou-0.20.28.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5