zou 0.19.59__py3-none-any.whl → 0.19.60__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 +1 -1
- zou/app/blueprints/auth/resources.py +3 -1
- zou/app/blueprints/crud/person.py +4 -1
- zou/app/blueprints/index/resources.py +7 -3
- zou/app/blueprints/persons/resources.py +4 -1
- zou/app/blueprints/previews/resources.py +5 -0
- zou/app/blueprints/user/resources.py +38 -1
- zou/app/config.py +2 -1
- zou/app/models/search_filter.py +4 -0
- zou/app/models/search_filter_group.py +3 -0
- zou/app/services/persons_service.py +3 -1
- zou/app/services/user_service.py +107 -31
- zou/app/utils/commands.py +7 -2
- zou/app/utils/emails.py +2 -2
- zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py +44 -0
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/METADATA +1 -1
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/RECORD +21 -20
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/LICENSE +0 -0
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/WHEEL +0 -0
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/entry_points.txt +0 -0
- {zou-0.19.59.dist-info → zou-0.19.60.dist-info}/top_level.txt +0 -0
zou/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.19.
|
|
1
|
+
__version__ = "0.19.60"
|
|
@@ -1369,7 +1369,9 @@ class SAMLSSOResource(Resource, ArgsMixin):
|
|
|
1369
1369
|
user = persons_service.get_person_by_email(email)
|
|
1370
1370
|
for k, v in person_info.items():
|
|
1371
1371
|
if user.get(k) != v:
|
|
1372
|
-
persons_service.update_person(
|
|
1372
|
+
persons_service.update_person(
|
|
1373
|
+
user["id"], person_info, bypass_protected_accounts=True
|
|
1374
|
+
)
|
|
1373
1375
|
break
|
|
1374
1376
|
except PersonNotFoundException:
|
|
1375
1377
|
user = persons_service.create_person(
|
|
@@ -203,7 +203,10 @@ class PersonResource(BaseModelResource, ArgsMixin):
|
|
|
203
203
|
and persons_service.is_user_limit_reached()
|
|
204
204
|
):
|
|
205
205
|
raise WrongParameterException("User limit reached.")
|
|
206
|
-
if
|
|
206
|
+
if (
|
|
207
|
+
instance_dict["email"] in config.PROTECTED_ACCOUNTS
|
|
208
|
+
and instance_dict["id"] != persons_service.get_current_user()["id"]
|
|
209
|
+
):
|
|
207
210
|
message = None
|
|
208
211
|
if data.get("active") is False:
|
|
209
212
|
message = "Can't set this person as inactive it's a protected account."
|
|
@@ -9,7 +9,7 @@ from zou import __version__
|
|
|
9
9
|
|
|
10
10
|
from zou.app import app, config
|
|
11
11
|
from zou.app.utils import permissions, shell, date_helpers
|
|
12
|
-
from zou.app.services import projects_service, stats_service
|
|
12
|
+
from zou.app.services import projects_service, stats_service, persons_service
|
|
13
13
|
|
|
14
14
|
from flask_jwt_extended import jwt_required
|
|
15
15
|
|
|
@@ -276,17 +276,21 @@ class StatsResource(Resource):
|
|
|
276
276
|
class ConfigResource(Resource):
|
|
277
277
|
def get(self):
|
|
278
278
|
"""
|
|
279
|
-
Get
|
|
279
|
+
Get basic configuration for the current instance.
|
|
280
280
|
---
|
|
281
281
|
tags:
|
|
282
282
|
- Index
|
|
283
283
|
responses:
|
|
284
284
|
200:
|
|
285
|
-
description:
|
|
285
|
+
description: Configuration object including self-hosted status,
|
|
286
|
+
Crisp token, indexer configuration, SAML status, and dark theme
|
|
287
|
+
status
|
|
286
288
|
"""
|
|
289
|
+
organisation = persons_service.get_organisation()
|
|
287
290
|
conf = {
|
|
288
291
|
"is_self_hosted": config.IS_SELF_HOSTED,
|
|
289
292
|
"crisp_token": config.CRISP_TOKEN,
|
|
293
|
+
"dark_theme_by_default": organisation["dark_theme_by_default"],
|
|
290
294
|
"indexer_configured": (
|
|
291
295
|
len(config.INDEXER["key"]) > 0
|
|
292
296
|
and config.INDEXER["key"] != "masterkey"
|
|
@@ -1255,7 +1255,10 @@ class ChangePasswordForPersonResource(Resource, ArgsMixin):
|
|
|
1255
1255
|
permissions.check_admin_permissions()
|
|
1256
1256
|
try:
|
|
1257
1257
|
person = persons_service.get_person(person_id)
|
|
1258
|
-
if
|
|
1258
|
+
if (
|
|
1259
|
+
person["email"] in config.PROTECTED_ACCOUNTS
|
|
1260
|
+
and person["id"] != persons_service.get_current_user()["id"]
|
|
1261
|
+
):
|
|
1259
1262
|
raise PersonInProtectedAccounts()
|
|
1260
1263
|
current_user = persons_service.get_current_user()
|
|
1261
1264
|
auth.validate_password(password, password_2)
|
|
@@ -1023,6 +1023,11 @@ class PersonThumbnailResource(BaseThumbnailResource):
|
|
|
1023
1023
|
if not is_current_user and not permissions.has_admin_permissions():
|
|
1024
1024
|
raise permissions.PermissionDenied
|
|
1025
1025
|
|
|
1026
|
+
def prepare_creation(self, instance_id):
|
|
1027
|
+
self.model = self.update_model_func(
|
|
1028
|
+
instance_id, {"has_avatar": True}, bypass_protected_accounts=True
|
|
1029
|
+
)
|
|
1030
|
+
|
|
1026
1031
|
|
|
1027
1032
|
class CreatePersonThumbnailResource(PersonThumbnailResource):
|
|
1028
1033
|
pass
|
|
@@ -544,6 +544,7 @@ class FiltersResource(Resource, ArgsMixin):
|
|
|
544
544
|
arguments["entity_type"],
|
|
545
545
|
arguments["is_shared"],
|
|
546
546
|
arguments["search_filter_group_id"],
|
|
547
|
+
department_id=arguments["department_id"],
|
|
547
548
|
),
|
|
548
549
|
201,
|
|
549
550
|
)
|
|
@@ -558,6 +559,7 @@ class FiltersResource(Resource, ArgsMixin):
|
|
|
558
559
|
("entity_type", None, False),
|
|
559
560
|
("is_shared", False, False, inputs.boolean),
|
|
560
561
|
("search_filter_group_id", None, False),
|
|
562
|
+
("department_id", None, False),
|
|
561
563
|
]
|
|
562
564
|
)
|
|
563
565
|
|
|
@@ -591,6 +593,7 @@ class FilterResource(Resource, ArgsMixin):
|
|
|
591
593
|
("search_filter_group_id", None, False),
|
|
592
594
|
("is_shared", None, False, inputs.boolean),
|
|
593
595
|
("project_id", None, None),
|
|
596
|
+
("department_id", None, None),
|
|
594
597
|
]
|
|
595
598
|
)
|
|
596
599
|
data = self.clear_empty_fields(
|
|
@@ -663,19 +666,27 @@ class FilterGroupsResource(Resource, ArgsMixin):
|
|
|
663
666
|
name: entity_type
|
|
664
667
|
required: False
|
|
665
668
|
type: string
|
|
669
|
+
- in: formData
|
|
670
|
+
name: is_shared
|
|
671
|
+
required: False
|
|
672
|
+
type: boolean
|
|
666
673
|
- in: formData
|
|
667
674
|
name: project_id
|
|
668
675
|
required: True
|
|
669
676
|
type: string
|
|
670
677
|
format: UUID
|
|
671
678
|
example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
679
|
+
- in: formData
|
|
680
|
+
name: department_id
|
|
681
|
+
required: False
|
|
682
|
+
format: UUID
|
|
683
|
+
example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
672
684
|
responses:
|
|
673
685
|
201:
|
|
674
686
|
description: Filter groups for the current user and only for
|
|
675
687
|
open projects created.
|
|
676
688
|
"""
|
|
677
689
|
arguments = self.get_arguments()
|
|
678
|
-
|
|
679
690
|
return (
|
|
680
691
|
user_service.create_filter_group(
|
|
681
692
|
arguments["list_type"],
|
|
@@ -684,6 +695,7 @@ class FilterGroupsResource(Resource, ArgsMixin):
|
|
|
684
695
|
arguments["project_id"],
|
|
685
696
|
arguments["entity_type"],
|
|
686
697
|
arguments["is_shared"],
|
|
698
|
+
arguments["department_id"],
|
|
687
699
|
),
|
|
688
700
|
201,
|
|
689
701
|
)
|
|
@@ -697,6 +709,7 @@ class FilterGroupsResource(Resource, ArgsMixin):
|
|
|
697
709
|
("project_id", None, False),
|
|
698
710
|
("is_shared", False, False, inputs.boolean),
|
|
699
711
|
("entity_type", None, False),
|
|
712
|
+
("department_id", None, False),
|
|
700
713
|
]
|
|
701
714
|
)
|
|
702
715
|
|
|
@@ -733,6 +746,28 @@ class FilterGroupResource(Resource, ArgsMixin):
|
|
|
733
746
|
type: string
|
|
734
747
|
format: UUID
|
|
735
748
|
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
749
|
+
- in: formData
|
|
750
|
+
name: name
|
|
751
|
+
type: string
|
|
752
|
+
x-example: Name of the filter group
|
|
753
|
+
- in: formData
|
|
754
|
+
name: color
|
|
755
|
+
type: string
|
|
756
|
+
x-example: Color of the filter group
|
|
757
|
+
- in: formData
|
|
758
|
+
name: is_shared
|
|
759
|
+
type: boolean
|
|
760
|
+
x-example: True
|
|
761
|
+
- in: formData
|
|
762
|
+
name: project_id
|
|
763
|
+
type: string
|
|
764
|
+
format: UUID
|
|
765
|
+
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
766
|
+
- in: formData
|
|
767
|
+
name: department_id
|
|
768
|
+
type: string
|
|
769
|
+
format: UUID
|
|
770
|
+
x-example: a24a6ea4-ce75-4665-a070-57453082c25
|
|
736
771
|
responses:
|
|
737
772
|
200:
|
|
738
773
|
description: Given filter group with updated data
|
|
@@ -743,10 +778,12 @@ class FilterGroupResource(Resource, ArgsMixin):
|
|
|
743
778
|
("color", None, False),
|
|
744
779
|
("is_shared", None, False, inputs.boolean),
|
|
745
780
|
("project_id", None, None),
|
|
781
|
+
("department_id", None, None),
|
|
746
782
|
]
|
|
747
783
|
)
|
|
748
784
|
|
|
749
785
|
data = self.clear_empty_fields(data)
|
|
786
|
+
print("data", data)
|
|
750
787
|
user_filter = user_service.update_filter_group(filter_group_id, data)
|
|
751
788
|
return user_filter, 200
|
|
752
789
|
|
zou/app/config.py
CHANGED
|
@@ -81,7 +81,8 @@ MAIL_SERVER = os.getenv("MAIL_SERVER", "localhost")
|
|
|
81
81
|
MAIL_PORT = os.getenv("MAIL_PORT", 25)
|
|
82
82
|
MAIL_USERNAME = os.getenv("MAIL_USERNAME", "")
|
|
83
83
|
MAIL_PASSWORD = os.getenv("MAIL_PASSWORD", "")
|
|
84
|
-
MAIL_DEBUG =
|
|
84
|
+
MAIL_DEBUG = int(os.getenv("MAIL_DEBUG", "0"))
|
|
85
|
+
MAIL_DEBUG_BODY = envtobool("MAIL_DEBUG_BODY", False)
|
|
85
86
|
MAIL_USE_TLS = envtobool("MAIL_USE_TLS", False)
|
|
86
87
|
MAIL_USE_SSL = envtobool("MAIL_USE_SSL", False)
|
|
87
88
|
MAIL_DEFAULT_SENDER = os.getenv(
|
zou/app/models/search_filter.py
CHANGED
|
@@ -23,6 +23,10 @@ class SearchFilter(db.Model, BaseMixin, SerializerMixin):
|
|
|
23
23
|
nullable=False,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
+
department_id = db.Column(
|
|
27
|
+
UUIDType(binary=False),
|
|
28
|
+
db.ForeignKey("department.id"),
|
|
29
|
+
)
|
|
26
30
|
search_filter_group_id = db.Column(
|
|
27
31
|
UUIDType(binary=False),
|
|
28
32
|
db.ForeignKey("search_filter_group.id"),
|
|
@@ -24,3 +24,6 @@ class SearchFilterGroup(db.Model, BaseMixin, SerializerMixin):
|
|
|
24
24
|
|
|
25
25
|
person_id = db.Column(UUIDType(binary=False), db.ForeignKey("person.id"))
|
|
26
26
|
project_id = db.Column(UUIDType(binary=False), db.ForeignKey("project.id"))
|
|
27
|
+
department_id = db.Column(
|
|
28
|
+
UUIDType(binary=False), db.ForeignKey("department.id")
|
|
29
|
+
)
|
|
@@ -381,7 +381,9 @@ def update_person_last_presence(person_id):
|
|
|
381
381
|
date = log.date
|
|
382
382
|
elif time_spent is not None:
|
|
383
383
|
date = time_spent.date
|
|
384
|
-
return update_person(
|
|
384
|
+
return update_person(
|
|
385
|
+
person_id, {"last_presence": date}, bypass_protected_accounts=True
|
|
386
|
+
)
|
|
385
387
|
|
|
386
388
|
|
|
387
389
|
def get_presence_logs(year, month):
|
zou/app/services/user_service.py
CHANGED
|
@@ -889,20 +889,30 @@ def get_user_filters(current_user_id):
|
|
|
889
889
|
.all()
|
|
890
890
|
)
|
|
891
891
|
|
|
892
|
+
current_user = persons_service.get_current_user(relations=True)
|
|
893
|
+
is_manager = permissions.has_manager_permissions()
|
|
894
|
+
|
|
892
895
|
for search_filter in filters:
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
+
department_id = search_filter.department_id
|
|
897
|
+
is_in_departments = (
|
|
898
|
+
department_id is not None and \
|
|
899
|
+
str(department_id) in current_user["departments"]
|
|
900
|
+
)
|
|
896
901
|
|
|
897
|
-
if
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
902
|
+
if department_id is None or is_manager or is_in_departments:
|
|
903
|
+
if search_filter.list_type not in result:
|
|
904
|
+
result[search_filter.list_type] = {}
|
|
905
|
+
subresult = result[search_filter.list_type]
|
|
906
|
+
|
|
907
|
+
if search_filter.project_id is None:
|
|
908
|
+
project_id = "all"
|
|
909
|
+
else:
|
|
910
|
+
project_id = str(search_filter.project_id)
|
|
901
911
|
|
|
902
|
-
|
|
903
|
-
|
|
912
|
+
if project_id not in subresult:
|
|
913
|
+
subresult[project_id] = []
|
|
904
914
|
|
|
905
|
-
|
|
915
|
+
subresult[project_id].append(search_filter.serialize())
|
|
906
916
|
|
|
907
917
|
return result
|
|
908
918
|
|
|
@@ -915,6 +925,7 @@ def create_filter(
|
|
|
915
925
|
entity_type=None,
|
|
916
926
|
is_shared=False,
|
|
917
927
|
search_filter_group_id=None,
|
|
928
|
+
department_id=None,
|
|
918
929
|
):
|
|
919
930
|
"""
|
|
920
931
|
Add a new search filter to the database.
|
|
@@ -937,6 +948,13 @@ def create_filter(
|
|
|
937
948
|
"A search filter should have the same value for is_shared than its search filter group."
|
|
938
949
|
)
|
|
939
950
|
|
|
951
|
+
if department_id is not None:
|
|
952
|
+
department = tasks_service.get_department(department_id)
|
|
953
|
+
if department is None:
|
|
954
|
+
raise WrongParameterException(
|
|
955
|
+
f"No department found with id: {department_id}"
|
|
956
|
+
)
|
|
957
|
+
|
|
940
958
|
search_filter = SearchFilter.create(
|
|
941
959
|
list_type=list_type,
|
|
942
960
|
name=name,
|
|
@@ -946,6 +964,7 @@ def create_filter(
|
|
|
946
964
|
entity_type=entity_type,
|
|
947
965
|
is_shared=is_shared,
|
|
948
966
|
search_filter_group_id=search_filter_group_id,
|
|
967
|
+
department_id=department_id,
|
|
949
968
|
)
|
|
950
969
|
search_filter.serialize()
|
|
951
970
|
if search_filter.is_shared:
|
|
@@ -969,10 +988,23 @@ def update_filter(search_filter_id, data):
|
|
|
969
988
|
if search_filter is None:
|
|
970
989
|
raise SearchFilterNotFoundException
|
|
971
990
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
991
|
+
department_id = data.get("department_id", None)
|
|
992
|
+
if department_id is not None:
|
|
993
|
+
department = tasks_service.get_department(department_id)
|
|
994
|
+
if department is None:
|
|
995
|
+
raise WrongParameterException(
|
|
996
|
+
f"No department found with id: {department_id}"
|
|
997
|
+
)
|
|
998
|
+
|
|
999
|
+
if data.get("is_shared", None) is not None and \
|
|
1000
|
+
search_filter.is_shared != data["is_shared"] and \
|
|
1001
|
+
(
|
|
1002
|
+
data.get("project_id", None) is None or
|
|
1003
|
+
(
|
|
1004
|
+
data["project_id"] is not None
|
|
1005
|
+
and not has_manager_project_access(data["project_id"])
|
|
1006
|
+
)
|
|
1007
|
+
):
|
|
976
1008
|
data["is_shared"] = False
|
|
977
1009
|
|
|
978
1010
|
if (
|
|
@@ -992,6 +1024,15 @@ def update_filter(search_filter_id, data):
|
|
|
992
1024
|
raise WrongParameterException(
|
|
993
1025
|
"A search filter should have the same value for is_shared than its search filter group."
|
|
994
1026
|
)
|
|
1027
|
+
|
|
1028
|
+
department_id = data.get("department_id", None)
|
|
1029
|
+
if department_id is not None:
|
|
1030
|
+
department = tasks_service.get_department(department_id)
|
|
1031
|
+
if department is None:
|
|
1032
|
+
raise WrongParameterException(
|
|
1033
|
+
f"No department found with id: {department_id}"
|
|
1034
|
+
)
|
|
1035
|
+
|
|
995
1036
|
search_filter.update(data)
|
|
996
1037
|
if search_filter.is_shared:
|
|
997
1038
|
clear_filter_cache()
|
|
@@ -1028,7 +1069,7 @@ def get_filter_groups():
|
|
|
1028
1069
|
return get_user_filter_groups(current_user["id"])
|
|
1029
1070
|
|
|
1030
1071
|
|
|
1031
|
-
@cache.memoize_function(
|
|
1072
|
+
@cache.memoize_function(10)
|
|
1032
1073
|
def get_user_filter_groups(current_user_id):
|
|
1033
1074
|
"""
|
|
1034
1075
|
Retrieve search filter groups used for given user. It groups them by
|
|
@@ -1055,26 +1096,41 @@ def get_user_filter_groups(current_user_id):
|
|
|
1055
1096
|
.all()
|
|
1056
1097
|
)
|
|
1057
1098
|
|
|
1099
|
+
current_user = persons_service.get_current_user(relations=True)
|
|
1100
|
+
is_manager = permissions.has_manager_permissions()
|
|
1101
|
+
|
|
1058
1102
|
for search_filter_group in filter_groups:
|
|
1059
1103
|
if search_filter_group.list_type not in result:
|
|
1060
1104
|
result[search_filter_group.list_type] = {}
|
|
1061
|
-
subresult = result[search_filter_group.list_type]
|
|
1062
1105
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1106
|
+
department_id = search_filter_group.department_id
|
|
1107
|
+
is_in_departments = (
|
|
1108
|
+
department_id is not None and \
|
|
1109
|
+
str(department_id) in current_user["departments"]
|
|
1110
|
+
)
|
|
1111
|
+
if department_id is None or is_manager or is_in_departments:
|
|
1112
|
+
subresult = result[search_filter_group.list_type]
|
|
1067
1113
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1114
|
+
if search_filter_group.project_id is None:
|
|
1115
|
+
project_id = "all"
|
|
1116
|
+
else:
|
|
1117
|
+
project_id = str(search_filter_group.project_id)
|
|
1070
1118
|
|
|
1071
|
-
|
|
1119
|
+
if project_id not in subresult:
|
|
1120
|
+
subresult[project_id] = []
|
|
1121
|
+
subresult[project_id].append(search_filter_group.serialize())
|
|
1072
1122
|
|
|
1073
1123
|
return result
|
|
1074
1124
|
|
|
1075
1125
|
|
|
1076
1126
|
def create_filter_group(
|
|
1077
|
-
list_type,
|
|
1127
|
+
list_type,
|
|
1128
|
+
name,
|
|
1129
|
+
color,
|
|
1130
|
+
project_id=None,
|
|
1131
|
+
entity_type=None,
|
|
1132
|
+
is_shared=False,
|
|
1133
|
+
department_id=None
|
|
1078
1134
|
):
|
|
1079
1135
|
"""
|
|
1080
1136
|
Add a new search filter group to the database.
|
|
@@ -1084,6 +1140,14 @@ def create_filter_group(
|
|
|
1084
1140
|
project_id is not None and not has_manager_project_access(project_id)
|
|
1085
1141
|
):
|
|
1086
1142
|
is_shared = False
|
|
1143
|
+
|
|
1144
|
+
if department_id is not None:
|
|
1145
|
+
department = tasks_service.get_department(department_id)
|
|
1146
|
+
if department is None:
|
|
1147
|
+
raise WrongParameterException(
|
|
1148
|
+
f"No department found with id: {department_id}"
|
|
1149
|
+
)
|
|
1150
|
+
|
|
1087
1151
|
search_filter_group = SearchFilterGroup.create(
|
|
1088
1152
|
list_type=list_type,
|
|
1089
1153
|
name=name,
|
|
@@ -1092,12 +1156,15 @@ def create_filter_group(
|
|
|
1092
1156
|
person_id=current_user["id"],
|
|
1093
1157
|
entity_type=entity_type,
|
|
1094
1158
|
is_shared=is_shared,
|
|
1159
|
+
department_id=department_id,
|
|
1095
1160
|
)
|
|
1096
1161
|
search_filter_group.serialize()
|
|
1162
|
+
|
|
1097
1163
|
if search_filter_group.is_shared:
|
|
1098
1164
|
clear_filter_group_cache()
|
|
1099
1165
|
else:
|
|
1100
1166
|
clear_filter_group_cache(current_user["id"])
|
|
1167
|
+
|
|
1101
1168
|
return search_filter_group.serialize()
|
|
1102
1169
|
|
|
1103
1170
|
|
|
@@ -1122,16 +1189,26 @@ def update_filter_group(search_filter_group_id, data):
|
|
|
1122
1189
|
search_filter_group = SearchFilterGroup.get_by(
|
|
1123
1190
|
id=search_filter_group_id, person_id=current_user["id"]
|
|
1124
1191
|
)
|
|
1192
|
+
|
|
1125
1193
|
if search_filter_group is None:
|
|
1126
1194
|
raise SearchFilterGroupNotFoundException
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1195
|
+
|
|
1196
|
+
if data.get("is_shared", None) is not None and \
|
|
1197
|
+
search_filter_group.is_shared != data["is_shared"] and \
|
|
1198
|
+
(
|
|
1199
|
+
data.get("project_id", None) is None or
|
|
1200
|
+
(
|
|
1201
|
+
data["project_id"] is not None
|
|
1202
|
+
and not has_manager_project_access(data["project_id"])
|
|
1203
|
+
)
|
|
1204
|
+
):
|
|
1205
|
+
data["is_shared"] = False
|
|
1206
|
+
|
|
1132
1207
|
search_filter_group.update(data)
|
|
1133
1208
|
|
|
1134
|
-
if data.get("is_shared", None) is not None
|
|
1209
|
+
if data.get("is_shared", None) is not None \
|
|
1210
|
+
and data.get("project_id", None) is not None \
|
|
1211
|
+
and has_manager_project_access(data["project_id"]):
|
|
1135
1212
|
if (
|
|
1136
1213
|
SearchFilter.query.filter_by(
|
|
1137
1214
|
search_filter_group_id=search_filter_group_id
|
|
@@ -1284,7 +1361,6 @@ def get_last_notifications(
|
|
|
1284
1361
|
query = query.filter(Notification.read == read)
|
|
1285
1362
|
|
|
1286
1363
|
if watching is not None:
|
|
1287
|
-
print(watching)
|
|
1288
1364
|
if watching:
|
|
1289
1365
|
query = query.filter(Subscription.id != None)
|
|
1290
1366
|
else:
|
zou/app/utils/commands.py
CHANGED
|
@@ -394,7 +394,9 @@ def sync_with_ldap_server():
|
|
|
394
394
|
)
|
|
395
395
|
.all()
|
|
396
396
|
):
|
|
397
|
-
persons_service.update_person(
|
|
397
|
+
persons_service.update_person(
|
|
398
|
+
person.id, {"active": False}, bypass_protected_accounts=True
|
|
399
|
+
)
|
|
398
400
|
print(
|
|
399
401
|
"User %s disabled (not found in LDAP)." % person.desktop_login
|
|
400
402
|
)
|
|
@@ -418,6 +420,7 @@ def sync_with_ldap_server():
|
|
|
418
420
|
"desktop_login": user["desktop_login"],
|
|
419
421
|
"ldap_uid": user["ldap_uid"],
|
|
420
422
|
},
|
|
423
|
+
bypass_protected_accounts=True,
|
|
421
424
|
)
|
|
422
425
|
print(f"User {user['desktop_login']} updated.")
|
|
423
426
|
except IsUserLimitReachedException:
|
|
@@ -470,7 +473,9 @@ def sync_with_ldap_server():
|
|
|
470
473
|
)
|
|
471
474
|
file_store.add_picture("thumbnails", person["id"], thumbnail_png_path)
|
|
472
475
|
os.remove(thumbnail_png_path)
|
|
473
|
-
persons_service.update_person(
|
|
476
|
+
persons_service.update_person(
|
|
477
|
+
person["id"], {"has_avatar": True}, bypass_protected_accounts=True
|
|
478
|
+
)
|
|
474
479
|
|
|
475
480
|
ldap_users = get_ldap_users()
|
|
476
481
|
update_person_list_with_ldap_users(ldap_users)
|
zou/app/utils/emails.py
CHANGED
|
@@ -12,9 +12,9 @@ def send_email(subject, html, recipient_email, body=None):
|
|
|
12
12
|
"""
|
|
13
13
|
if body is None:
|
|
14
14
|
body = strip_html_tags(html)
|
|
15
|
-
if app.config["
|
|
15
|
+
if app.config["MAIL_DEBUG_BODY"]:
|
|
16
16
|
print(body)
|
|
17
|
-
|
|
17
|
+
if app.config["MAIL_ENABLED"]:
|
|
18
18
|
with app.app_context():
|
|
19
19
|
try:
|
|
20
20
|
mail_default_sender = app.config["MAIL_DEFAULT_SENDER"]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""add department keys to filter models
|
|
2
|
+
|
|
3
|
+
Revision ID: 9d3bb33c6fc6
|
|
4
|
+
Revises: 8e67c183bed7
|
|
5
|
+
Create Date: 2024-10-11 15:52:29.740222
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
from alembic import op
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
import sqlalchemy_utils
|
|
11
|
+
import sqlalchemy_utils
|
|
12
|
+
import uuid
|
|
13
|
+
|
|
14
|
+
# revision identifiers, used by Alembic.
|
|
15
|
+
revision = '9d3bb33c6fc6'
|
|
16
|
+
down_revision = '8e67c183bed7'
|
|
17
|
+
branch_labels = None
|
|
18
|
+
depends_on = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def upgrade():
|
|
22
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
23
|
+
with op.batch_alter_table('search_filter', schema=None) as batch_op:
|
|
24
|
+
batch_op.add_column(sa.Column('department_id', sqlalchemy_utils.types.uuid.UUIDType(binary=False), default=uuid.uuid4, nullable=True))
|
|
25
|
+
batch_op.create_foreign_key(None, 'department', ['department_id'], ['id'])
|
|
26
|
+
|
|
27
|
+
with op.batch_alter_table('search_filter_group', schema=None) as batch_op:
|
|
28
|
+
batch_op.add_column(sa.Column('department_id', sqlalchemy_utils.types.uuid.UUIDType(binary=False), default=uuid.uuid4, nullable=True))
|
|
29
|
+
batch_op.create_foreign_key(None, 'department', ['department_id'], ['id'])
|
|
30
|
+
|
|
31
|
+
# ### end Alembic commands ###
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def downgrade():
|
|
35
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
36
|
+
with op.batch_alter_table('search_filter_group', schema=None) as batch_op:
|
|
37
|
+
batch_op.drop_constraint(None, type_='foreignkey')
|
|
38
|
+
batch_op.drop_column('department_id')
|
|
39
|
+
|
|
40
|
+
with op.batch_alter_table('search_filter', schema=None) as batch_op:
|
|
41
|
+
batch_op.drop_constraint(None, type_='foreignkey')
|
|
42
|
+
batch_op.drop_column('department_id')
|
|
43
|
+
|
|
44
|
+
# ### end Alembic commands ###
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
zou/__init__.py,sha256=
|
|
1
|
+
zou/__init__.py,sha256=Q-R4YnG0E1Dy8riIkq9R2p9ONeBkY4iPua_nw1RTmDA,24
|
|
2
2
|
zou/cli.py,sha256=DHHf4mz33Bi0gGFJ0GdRUpjrMrMSQYyVubJFppHPZlU,18914
|
|
3
3
|
zou/debug.py,sha256=1fawPbkD4wn0Y9Gk0BiBFSa-CQe5agFi8R9uJYl2Uyk,520
|
|
4
4
|
zou/event_stream.py,sha256=_tue9Ry3aqCniZpKGhWJaY1Eo_fd6zOAfnzPvh_mJzU,8489
|
|
5
5
|
zou/job_settings.py,sha256=_aqBhujt2Q8sXRWIbgbDf-LUdXRdBimdtTc-fZbiXoY,202
|
|
6
6
|
zou/app/__init__.py,sha256=AJEGrLTirr5zZmA8DVSjZedtTuDg6eg9rG4kXMimPnQ,6966
|
|
7
7
|
zou/app/api.py,sha256=JTB_IMVO8EOoyqx9KdRkiIix0chOLi0yGDY-verUJXA,5127
|
|
8
|
-
zou/app/config.py,sha256=
|
|
8
|
+
zou/app/config.py,sha256=V6kV3JzaR2yGz8F3vcsb-v4EB9VvvirEPtGeQMot9bI,6649
|
|
9
9
|
zou/app/mixin.py,sha256=eYwfS_CUFvNmldaQXrjsN5mK_gX0wYrBFykfx60uUM8,4897
|
|
10
10
|
zou/app/swagger.py,sha256=Jr7zsMqJi0V4FledODOdu-aqqVE02jMFzhqVxHK0_2c,54158
|
|
11
11
|
zou/app/blueprints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
zou/app/blueprints/assets/__init__.py,sha256=T2zhDagHjXF6jRwOQ8vqokZTkBHyY7XtTI0Rlooamjs,2931
|
|
13
13
|
zou/app/blueprints/assets/resources.py,sha256=ff7g8_FzZC6dLvMxcYYffsIOy0CqKqdkZibGm2-qgko,25599
|
|
14
14
|
zou/app/blueprints/auth/__init__.py,sha256=xP874bMWUnLIirOPSEbpe-Q2fBBQrxZGKd0tLZmNJXk,1128
|
|
15
|
-
zou/app/blueprints/auth/resources.py,sha256=
|
|
15
|
+
zou/app/blueprints/auth/resources.py,sha256=ujdYPdz-anqIjK2Iepk5Yg4dRXJcHmc8sGpo6omG73A,45214
|
|
16
16
|
zou/app/blueprints/breakdown/__init__.py,sha256=Dp6GWSGxxWIedpyzTTEKpCRUYEo8oVNVyQhwNvTMmQM,1888
|
|
17
17
|
zou/app/blueprints/breakdown/resources.py,sha256=JY3j17kv7xPKV9S-XoOxNYivpGHlfZkXI5WuGtx3_Yk,13591
|
|
18
18
|
zou/app/blueprints/chats/__init__.py,sha256=YGmwGvddg3MgSYVIh-hmkX8t2em9_LblxBeJzFqFJD4,558
|
|
@@ -43,7 +43,7 @@ zou/app/blueprints/crud/notification.py,sha256=A-KNH0IDNCXlE4AddNxvmsD_7a9HqHGo_
|
|
|
43
43
|
zou/app/blueprints/crud/organisation.py,sha256=bNGo3Dtir2o_cHk0vDPs4cJw7mRWlSwPf2oA4lDQUyU,859
|
|
44
44
|
zou/app/blueprints/crud/output_file.py,sha256=jWSagq4LxwtFQH0XL_LjXaiW9FRn8T4k0tv1EbmPfg0,3954
|
|
45
45
|
zou/app/blueprints/crud/output_type.py,sha256=eYJXLPkUCRj9-v5mc3rxqEHM3yycmf6rVAoaOfbnAcU,1998
|
|
46
|
-
zou/app/blueprints/crud/person.py,sha256=
|
|
46
|
+
zou/app/blueprints/crud/person.py,sha256=FPvMt4ChXnfH6DheQL_jagakO6ic123UkOmsIM0cG_s,9281
|
|
47
47
|
zou/app/blueprints/crud/playlist.py,sha256=ZXaz-hHPej6XYKo_RUfJ2QnGOh2W8-y9hTkPZCUp7Zk,1876
|
|
48
48
|
zou/app/blueprints/crud/preview_background_file.py,sha256=WzOfag5qhz5B3-XDObYRC8TO4X-kIo1sHOnMCV62IEo,2437
|
|
49
49
|
zou/app/blueprints/crud/preview_file.py,sha256=252EDEdF-wQaL9ZhqQv5j9z_JKK5WeYwidJfFafArjo,3831
|
|
@@ -83,15 +83,15 @@ zou/app/blueprints/export/csv/time_spents.py,sha256=yYPtilOxfQD5mBwyh9h-PbTQBpab
|
|
|
83
83
|
zou/app/blueprints/files/__init__.py,sha256=7Wty30JW2OXIn-tBFXOWWmPuHnsnxPpH3jNtHvvr9tY,3987
|
|
84
84
|
zou/app/blueprints/files/resources.py,sha256=8SIV8kaqv3dxyL8nyqG3QiZmk5ZYIvUxw6k1ic-jhBs,69786
|
|
85
85
|
zou/app/blueprints/index/__init__.py,sha256=Dh3oQiirpg8RCkfVOuk3irIjSvUvuRf0jPxE6oGubz0,828
|
|
86
|
-
zou/app/blueprints/index/resources.py,sha256=
|
|
86
|
+
zou/app/blueprints/index/resources.py,sha256=UUBHWGDIyx6xgk2Jt_uwvpSETB0xeIjQ3quYVN0uOlc,8734
|
|
87
87
|
zou/app/blueprints/news/__init__.py,sha256=HxBXjC15dVbotNAZ0CLf02iwUjxJr20kgf8_kT_9nwM,505
|
|
88
88
|
zou/app/blueprints/news/resources.py,sha256=SL0RYo-fs23GjQU1IW4kuEBg2SHdaXaonrOoOnWafdw,7183
|
|
89
89
|
zou/app/blueprints/persons/__init__.py,sha256=0cnHHw3K_8OEMm0qOi3wKVomSAg9IJSnVjAXabMeHks,3893
|
|
90
|
-
zou/app/blueprints/persons/resources.py,sha256=
|
|
90
|
+
zou/app/blueprints/persons/resources.py,sha256=0EBI6w63WhjqDSj-COYGk4NO6V1oRyAzfH4f7dXNYoE,42793
|
|
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=qGohO6LRNZKXBAegINcUXuZlrtxobJKQg84-rQ1L3AU,4202
|
|
94
|
-
zou/app/blueprints/previews/resources.py,sha256=
|
|
94
|
+
zou/app/blueprints/previews/resources.py,sha256=yuSs7-VOYdeSrTDwktx_3uyugxMN1r73FG0kNH-qNXg,48241
|
|
95
95
|
zou/app/blueprints/projects/__init__.py,sha256=Pn3fA5bpNFEPBzxTKJ2foV6osZFflXXSM2l2uZh3ktM,3927
|
|
96
96
|
zou/app/blueprints/projects/resources.py,sha256=E91Vj9EzId2pxiL50JRfrThiyif1PmzWS1oPeMThzQI,31544
|
|
97
97
|
zou/app/blueprints/search/__init__.py,sha256=QCjQIY_85l_orhdEiqav_GifjReuwsjZggN3V0GeUVY,356
|
|
@@ -129,7 +129,7 @@ zou/app/blueprints/source/shotgun/versions.py,sha256=8Mb35e5p3FLbbiu6AZb9tJErDKz
|
|
|
129
129
|
zou/app/blueprints/tasks/__init__.py,sha256=pNUqVEVX1KVu1IzRRJNsziPkhWKXqgyvQsNp7LbmIxo,4342
|
|
130
130
|
zou/app/blueprints/tasks/resources.py,sha256=b5z4OolidyKdKTP5kuZLk7tDLhgDs5W3rkH4ZWlwB0Y,56020
|
|
131
131
|
zou/app/blueprints/user/__init__.py,sha256=H9zCHcVobC6jq6dTToXKAjnZmDA0a9gChHiIP3BcZsc,4586
|
|
132
|
-
zou/app/blueprints/user/resources.py,sha256=
|
|
132
|
+
zou/app/blueprints/user/resources.py,sha256=07TXMEJG__aBRotgKnduoDf2Y59J-9VcMzUDXVUHzCI,39919
|
|
133
133
|
zou/app/file_trees/default.json,sha256=ryUrEmQYE8B_WkzCoQLgmem3N9yNwMIWx9G8p3HfG9o,2310
|
|
134
134
|
zou/app/file_trees/simple.json,sha256=VBI43Z3rjQxtTpVCq3ktUgS0UB8x-aTowKL9LXuXCFI,3149
|
|
135
135
|
zou/app/indexer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -166,8 +166,8 @@ zou/app/models/preview_file.py,sha256=Ur45Wau2X3qyKULh04EUcMbnBmaQc8y4IMs5NgELiA
|
|
|
166
166
|
zou/app/models/project.py,sha256=T2gTImmbd5O-U5GySWSwzkR0r_cY2RDr1niwSfOPqeA,8900
|
|
167
167
|
zou/app/models/project_status.py,sha256=pExaHH7x4Eu8xOqD3_mRRbMzjT2jJZ8rm-9jo7yUGXA,390
|
|
168
168
|
zou/app/models/schedule_item.py,sha256=coY5uDDuBoctaMICnfCzx4zT5om2E1uu4iq5MDWAPlY,1444
|
|
169
|
-
zou/app/models/search_filter.py,sha256=
|
|
170
|
-
zou/app/models/search_filter_group.py,sha256=
|
|
169
|
+
zou/app/models/search_filter.py,sha256=Q699mJa3GGwFEva93Y_nHiIcx3BDht9VsAe2zeQL0FA,1242
|
|
170
|
+
zou/app/models/search_filter_group.py,sha256=LGT2zn1lk3dCC-Fu7NU7VFD6MWprmBz7saQhS2ST2gA,980
|
|
171
171
|
zou/app/models/serializer.py,sha256=VKN5hHJ6M_jsvrbKe5SonnTeg5dxXSYqb_4JDVWIQwA,1477
|
|
172
172
|
zou/app/models/software.py,sha256=3y9xEOS8BBxqgTaRrCaSYHaB6uOdJ88uU5i-cACoCSk,517
|
|
173
173
|
zou/app/models/status_automation.py,sha256=95c0lmOetujyGWViLd_qsR4GWPhrmlvi9ZfkC0x1NuM,1391
|
|
@@ -200,7 +200,7 @@ zou/app/services/index_service.py,sha256=1w8rGJ7ArYC13B43hD4JOPtVhaRsbseJVVY-GnU
|
|
|
200
200
|
zou/app/services/names_service.py,sha256=TOSrintROmxcAlcFQE0i2E3PBLnw81GAztNselpTn18,2947
|
|
201
201
|
zou/app/services/news_service.py,sha256=g-QlITBbEvhvm-pLv7GtGACKX4uBPa-IKxfNOgMgaHo,8768
|
|
202
202
|
zou/app/services/notifications_service.py,sha256=7GDRio_mGaRYV5BHOAdpxBZjA_LLYUfVpbwZqy1n9pI,15685
|
|
203
|
-
zou/app/services/persons_service.py,sha256=
|
|
203
|
+
zou/app/services/persons_service.py,sha256=0CKYrmHDUq34VNNgLSWDKN37EgmD68ZqyrUmm4ABj18,16356
|
|
204
204
|
zou/app/services/playlists_service.py,sha256=pAlPHET4jNdST5jsmJrFUkf1SVhfSoML9zdNpZ_88l4,32439
|
|
205
205
|
zou/app/services/preview_files_service.py,sha256=M1kXryARUKwCDXsr0hOfUUyGn75y-qXIVIwlMOKWWHs,35609
|
|
206
206
|
zou/app/services/projects_service.py,sha256=_J8hIHy3MX5MsdEMRIKNfbyewwhxtMEcc_ymeHBsF38,21434
|
|
@@ -213,7 +213,7 @@ zou/app/services/sync_service.py,sha256=EunfXlma_IIb7011A_xLQLVQGAi-MteKgm2Y2NAx
|
|
|
213
213
|
zou/app/services/tasks_service.py,sha256=IoogHBoZhbJegnl5SYGgOaBp2YVqrL22Gccjfp8dPn8,69335
|
|
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=
|
|
216
|
+
zou/app/services/user_service.py,sha256=O6KdOVqJBGHCzRqykqnrqWgH1ijRZLtxqA6QFaNaZ5g,50471
|
|
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
|
|
@@ -225,11 +225,11 @@ zou/app/utils/auth.py,sha256=DZfZSr1Ulge0UK3hfvOWsMo3_d7RVP_llV118u9BtUI,870
|
|
|
225
225
|
zou/app/utils/cache.py,sha256=MRluTvGG67ybOkyzgD70B6PGKMdRyFdTc0AYy3dEQe8,1210
|
|
226
226
|
zou/app/utils/chats.py,sha256=ORngxQ3IQQF0QcVFJLxJ-RaU4ksQ9-0M8cmPa0pc0Ho,4302
|
|
227
227
|
zou/app/utils/colors.py,sha256=LaGV17NL_8xY0XSp8snGWz5UMwGnm0KPWXyE5BTMG6w,200
|
|
228
|
-
zou/app/utils/commands.py,sha256=
|
|
228
|
+
zou/app/utils/commands.py,sha256=z1tpCRY6wOH_uSrjPTS5kRkhYwW8SEA-pKhreaXLu0I,27472
|
|
229
229
|
zou/app/utils/csv_utils.py,sha256=difqBp9xp3nHvaOjW6B64A4X3Uyfe_vKGw10i6SJ5_E,1291
|
|
230
230
|
zou/app/utils/date_helpers.py,sha256=jFxDPCbAasg0I1gsC72AKEbGcx5c4pLqXZkSfZ4wLdQ,4724
|
|
231
231
|
zou/app/utils/dbhelpers.py,sha256=RSJuoxLexGJyME16GQCs-euFLBR0u-XAFdJ1KMSv5M8,1143
|
|
232
|
-
zou/app/utils/emails.py,sha256=
|
|
232
|
+
zou/app/utils/emails.py,sha256=hc4HWvVYsG1xoP3sR0Zig0sB0k0y7bNxuNxxBreN5Yg,1436
|
|
233
233
|
zou/app/utils/env.py,sha256=haveriMt1rDeLOosAPMm0IblF_QpMViEsjg7BJqD-rw,711
|
|
234
234
|
zou/app/utils/events.py,sha256=a_W70v0Oi4QJwJzCLVUQ8RTwjlWo-VzAT_hQZCz2HQU,3024
|
|
235
235
|
zou/app/utils/fido.py,sha256=qhUWZdDCvgWqydYS4DN1SVkNwdAQkRSV9zs0Xw9O15E,536
|
|
@@ -354,6 +354,7 @@ zou/migrations/versions/99825b9cc778_.py,sha256=vleoLh_fCLwNnCmgZkW5x1-lJ09CgjPd
|
|
|
354
354
|
zou/migrations/versions/9a09467f9b2c_.py,sha256=cjSO3cXzHHhlcaQhShF9WlxmBWIfwLYSyIb9C6B5Dwc,1246
|
|
355
355
|
zou/migrations/versions/9b85c14fa8a7_add_day_off_new_columns.py,sha256=u6n5X_hwoeH9XnkWHB4PvVvGVrkddgDamweMrlPFQ9I,2106
|
|
356
356
|
zou/migrations/versions/9bd17364fc18_.py,sha256=nruaGMczzkWkya_D11QEU3uiU1UVEUItM6svSBjOw2c,1890
|
|
357
|
+
zou/migrations/versions/9d3bb33c6fc6_add_department_keys_to_filter_models.py,sha256=iWcJUdkPThoWONEHQ64hpQYSVcax0lO7rHJ3DVZYRDs,1587
|
|
357
358
|
zou/migrations/versions/9e5b3a9b0cee_add_new_column_metadatadescriptor_data_type_.py,sha256=HT34AjM9yN1IvLrCzx4-YOiocFDnPQ-FJ05icPCBnNo,5517
|
|
358
359
|
zou/migrations/versions/9f8445f9b42c_add_man_days_fields.py,sha256=muFsM2g_m-L5Zss36roTsjCoSDdhu_e4hVQntiNHyiY,828
|
|
359
360
|
zou/migrations/versions/a23682ccc1f1_.py,sha256=dVOUWldUZyLuLc6_HrgKUI5XH5-6Vjwai6Ew9kygkHw,1663
|
|
@@ -412,9 +413,9 @@ zou/remote/normalize_movie.py,sha256=zNfEY3N1UbAHZfddGONTg2Sff3ieLVWd4dfZa1dpnes
|
|
|
412
413
|
zou/remote/playlist.py,sha256=AsDo0bgYhDcd6DfNRV6r6Jj3URWwavE2ZN3VkKRPbLU,3293
|
|
413
414
|
zou/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
414
415
|
zou/utils/movie.py,sha256=u9LCEOvmkxwm-KiZ6jKNdB9LSC6XXUDwJpVx8LkDwJg,16416
|
|
415
|
-
zou-0.19.
|
|
416
|
-
zou-0.19.
|
|
417
|
-
zou-0.19.
|
|
418
|
-
zou-0.19.
|
|
419
|
-
zou-0.19.
|
|
420
|
-
zou-0.19.
|
|
416
|
+
zou-0.19.60.dist-info/LICENSE,sha256=dql8h4yceoMhuzlcK0TT_i-NgTFNIZsgE47Q4t3dUYI,34520
|
|
417
|
+
zou-0.19.60.dist-info/METADATA,sha256=EqDZA8e8KYpG4COrPyaVuxsMAeFLd9pHuzKCtAY605Q,6676
|
|
418
|
+
zou-0.19.60.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
419
|
+
zou-0.19.60.dist-info/entry_points.txt,sha256=PelQoIx3qhQ_Tmne7wrLY-1m2izuzgpwokoURwSohy4,130
|
|
420
|
+
zou-0.19.60.dist-info/top_level.txt,sha256=4S7G_jk4MzpToeDItHGjPhHx_fRdX52zJZWTD4SL54g,4
|
|
421
|
+
zou-0.19.60.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|