contact-person-profile-csv-imp-local 0.0.50__tar.gz → 0.0.52__tar.gz
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.
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/PKG-INFO +2 -2
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local/src/CSVToContactPersonProfile.py +124 -30
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local.egg-info/PKG-INFO +2 -2
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local.egg-info/requires.txt +1 -1
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/setup.py +2 -2
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/README.md +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local/src/__init__.py +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local/src/contact_person_profile_csv_imp_local_constants.py +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local.egg-info/SOURCES.txt +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local.egg-info/dependency_links.txt +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/contact_person_profile_csv_imp_local.egg-info/top_level.txt +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/pyproject.toml +0 -0
- {contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/setup.cfg +0 -0
{contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: contact-person-profile-csv-imp-local
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.52
|
|
4
4
|
Summary: PyPI Package for Circles CSVToContactPersonProfile-local Local/Remote Python
|
|
5
5
|
Home-page: https://github.com/circles-zone/contact-person-profile-csv-imp-local-python-package
|
|
6
6
|
Author: Circles
|
|
@@ -12,7 +12,7 @@ Requires-Dist: contact-local>=0.0.48
|
|
|
12
12
|
Requires-Dist: logger-local>=0.0.135
|
|
13
13
|
Requires-Dist: database-mysql-local>=0.1.1
|
|
14
14
|
Requires-Dist: user-context-remote>=0.0.77
|
|
15
|
-
Requires-Dist: contact-email-address-local>=0.0.
|
|
15
|
+
Requires-Dist: contact-email-address-local>=0.0.8
|
|
16
16
|
Requires-Dist: contact-group-local>=0.0.68
|
|
17
17
|
Requires-Dist: contact-location-local>=0.0.14
|
|
18
18
|
Requires-Dist: contact-notes-local>=0.0.33
|
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
from zoneinfo import ZoneInfo
|
|
7
7
|
import chardet
|
|
8
8
|
|
|
9
|
-
from .contact_person_profile_csv_imp_local_constants import CSVToContactPersonProfileConstants
|
|
9
|
+
from src.contact_person_profile_csv_imp_local_constants import CSVToContactPersonProfileConstants
|
|
10
10
|
from data_source_local.data_source import DataSources
|
|
11
11
|
# from user_external_local.user_externals_local import UserExternalsLocal
|
|
12
12
|
# from user_context_remote.user_context import UserContext
|
|
@@ -50,25 +50,6 @@ DEFAULT_PROFILE_ID = 0
|
|
|
50
50
|
|
|
51
51
|
# Those methods should be called from the common method for this repo (contact-person-profile-csv-imp-local-python-package and google-contact-sync ...)
|
|
52
52
|
|
|
53
|
-
# TODO def process_first_name( original_first_name: str) -> str: (move to people-local-python-package)
|
|
54
|
-
# normilized_first_name = the first word in original_first_name
|
|
55
|
-
# GroupsLocal.add_update_group_and_link_to_contact( normilized_first_name, is_group=true, contact_id) # When checking if exists, ignore the upper-case lower-case
|
|
56
|
-
# return normilized_first_name
|
|
57
|
-
|
|
58
|
-
# TODO def process_last_name( original_last_name : str) -> str: (move to people-local-python-package)
|
|
59
|
-
# normilized_last_name = Remove all the digits from the last_name
|
|
60
|
-
# GroupsLocal.add_update_group_and_link_to_contact( normilized_last_name, is_group=true, contact_id) # When checking if exists, ignore the upper-case lower-case
|
|
61
|
-
|
|
62
|
-
# TODO def process_phone( original_phone_number: str) -> str: (move to phone-local-python-package)
|
|
63
|
-
# phone_id, normalized_phone = PhonesLocal.link_phone_to_contact( normilized_phone, contact_id) # Please use method written by @akiva and return normalized_phone_number
|
|
64
|
-
|
|
65
|
-
# TODO def process_job_title( job_title: str) -> str: (move to people-local-python-package)
|
|
66
|
-
# normalized_job_title = GroupsLocal.add_update_group_and_link_to_contact( job_title, is_group=true, contact_id) # When checking if exists, ignore the upper-case lower-case, return the value with is_main == true
|
|
67
|
-
|
|
68
|
-
# TODO def process_email_address( email_address: str)
|
|
69
|
-
# """ Returned email_address_id, domain_name, organization_name """
|
|
70
|
-
# DomainsLocal.link_contact_to_domain( contact_id, domain_name )
|
|
71
|
-
|
|
72
53
|
# TODO def process_organization( organization_name: str, email_address: str) -> str: (move to people-local-python-package
|
|
73
54
|
# if organization_name == None or empty
|
|
74
55
|
# organization_name = extract_organization_from_email_address( email_address)
|
|
@@ -124,7 +105,10 @@ class CSVToContactPersonProfile(
|
|
|
124
105
|
'contact_location', 'user_externals_local',
|
|
125
106
|
'organizations_local', 'domain_local',
|
|
126
107
|
'importers_local']
|
|
127
|
-
GenericCRUD.__init__(self, default_schema_name="
|
|
108
|
+
GenericCRUD.__init__(self, default_schema_name="field",
|
|
109
|
+
default_column_name="field_id",
|
|
110
|
+
default_table_name="field_table",
|
|
111
|
+
default_view_table_name="field_view",
|
|
128
112
|
is_test_data=is_test_data)
|
|
129
113
|
self.contact_entity_type_id = \
|
|
130
114
|
self.select_one_value_by_column_and_value(
|
|
@@ -170,11 +154,32 @@ class CSVToContactPersonProfile(
|
|
|
170
154
|
# Otherwise, return the value
|
|
171
155
|
return value
|
|
172
156
|
|
|
173
|
-
|
|
174
|
-
#
|
|
157
|
+
# # TODO Does this function should be here on in https://github.com/circles-zone/variable-local-python-package/tree/dev/variable_local_python_package/variable_local/src "field/field.py"?
|
|
158
|
+
# def __get_field_name(self, field_id: int, data_source_type_id: int) -> str:
|
|
159
|
+
# """
|
|
160
|
+
# Get the field name from the database
|
|
161
|
+
# :param field_id: The field ID
|
|
162
|
+
# :param data_source_type_id: The data source ID
|
|
163
|
+
# :return: The field name
|
|
164
|
+
# """
|
|
165
|
+
#
|
|
166
|
+
# 'data_source_type_id': data_source_type_id})
|
|
167
|
+
|
|
168
|
+
# self.set_schema(schema_name="data_source_field")
|
|
169
|
+
# data_source_field_tuples = self.select_multi_tuple_by_where(view_table_name="data_source_field_view",
|
|
170
|
+
# select_clause_value="external_field_name",
|
|
171
|
+
# where="data_source_type_id = %s AND field_id = %s",
|
|
172
|
+
# params=(data_source_type_id, field_id))
|
|
173
|
+
|
|
174
|
+
# if data_source_field_tuples:
|
|
175
|
+
#
|
|
176
|
+
# return data_source_field_tuples[0][0]
|
|
177
|
+
# return
|
|
178
|
+
|
|
179
|
+
# TODO what are the diff between csv_path and directory_name?
|
|
175
180
|
# ans: csv_path is the full path to the csv file, directory_name is the directory where the csv file is located
|
|
176
181
|
|
|
177
|
-
# I think file name should be after directory_name and csv_path
|
|
182
|
+
# TODO I think file name should be after directory_name and csv_path
|
|
178
183
|
# ans: it cannot be after directory_name and csv_path because it is a required parameter
|
|
179
184
|
|
|
180
185
|
# TODO: break this function into smaller functions
|
|
@@ -203,7 +208,7 @@ class CSVToContactPersonProfile(
|
|
|
203
208
|
:return:
|
|
204
209
|
"""
|
|
205
210
|
data_source_type_name = DataSources().get_data_source_name_by_id(data_source_type_id)
|
|
206
|
-
# There can be multiple profiles with the same email, why not to query `user_external_table`.`main_profile_id`?
|
|
211
|
+
# TODO There can be multiple profiles with the same email, why not to query `user_external_table`.`main_profile_id`?
|
|
207
212
|
# Answer: first, We can't query tables with GenericCRUD, second, we may not find profile_id in user_external table
|
|
208
213
|
# and may have to insert a new record to user_external_table, in this case we need profile_id from profile_view
|
|
209
214
|
profile_id = self.select_one_value_by_column_and_value(
|
|
@@ -219,6 +224,7 @@ class CSVToContactPersonProfile(
|
|
|
219
224
|
self.logger.error("Couldn't find profile_id in profile_view by email_address.")
|
|
220
225
|
raise Exception("Couldn't find profile_id in user_external or profile_view.")
|
|
221
226
|
system_id = system_id or CONTACT_PERSON_PROFILE_CSV_SYSTEM_ID
|
|
227
|
+
self.set_schema(schema_name="field")
|
|
222
228
|
self.list_of_group_dicts = list_of_group_dicts if list_of_group_dicts else []
|
|
223
229
|
'''
|
|
224
230
|
profile_id = ProfilesLocal().select_one_value_by_column_and_value(
|
|
@@ -227,6 +233,7 @@ class CSVToContactPersonProfile(
|
|
|
227
233
|
column_value=user_external_username)
|
|
228
234
|
'''
|
|
229
235
|
self.logger.info(f"profile_id: {profile_id}")
|
|
236
|
+
# TODO Please explain
|
|
230
237
|
# if csv_path is provided then we will use the full path
|
|
231
238
|
# if csv_path is not provided then we will use the directory_name and file_name to create the full path
|
|
232
239
|
# if directory_name is not provided the assumption is that the file is in the same directory as the script and not in a folder
|
|
@@ -320,7 +327,6 @@ class CSVToContactPersonProfile(
|
|
|
320
327
|
# contact_dict['last_name'] = process_last_name(
|
|
321
328
|
# original_last_name=contact_dict['last_name'])
|
|
322
329
|
|
|
323
|
-
|
|
324
330
|
# TODO This should be executed also by Google Contact Sync (please make sure it is in
|
|
325
331
|
# people-local-python-package i.e. get_display_name(first_name, last_name, organization) -> str
|
|
326
332
|
if contact_dict.get('display_as') is None:
|
|
@@ -332,6 +338,8 @@ class CSVToContactPersonProfile(
|
|
|
332
338
|
if not contact_dict['display_as'] and contact_dict.get('organization'):
|
|
333
339
|
contact_dict['display_as'] += " " + contact_dict['organization']
|
|
334
340
|
|
|
341
|
+
# TODO if contact_dict['display_as'] still empty raise?
|
|
342
|
+
|
|
335
343
|
# TODO process_notes( contact_dict[notes] )
|
|
336
344
|
|
|
337
345
|
# TODO We should take care of situation which the contact already exists and we need to update it
|
|
@@ -351,6 +359,9 @@ class CSVToContactPersonProfile(
|
|
|
351
359
|
data_source_instance_id=data_source_instance_id,
|
|
352
360
|
data_source_type_id=data_source_type_id)
|
|
353
361
|
contact_data_by_contact_id_dict[contact_id] = contact_dict
|
|
362
|
+
# groups_linked_by_job_title = process_job_title(contact_id=contact_id, job_title=contact_dict['job_title'])
|
|
363
|
+
# if groups_linked_by_job_title is None:
|
|
364
|
+
# logger.info("No groups linked by job title to contact " + str(contact_id))
|
|
354
365
|
|
|
355
366
|
return contact_data_by_contact_id_dict
|
|
356
367
|
|
|
@@ -646,6 +657,24 @@ class CSVToContactPersonProfile(
|
|
|
646
657
|
|
|
647
658
|
return contact_phone_ids
|
|
648
659
|
|
|
660
|
+
# old, TODO, do we need it?
|
|
661
|
+
def __insert_link_contact_user_external(self, contact_dict: dict) -> int:
|
|
662
|
+
contact_id = contact_dict.get("contact_id")
|
|
663
|
+
print("Before " + __name__, file=sys.stderr, flush=True)
|
|
664
|
+
contact_user_external_id = \
|
|
665
|
+
self.contact_user_external.insert_contact_and_link_to_existing_or_new_user_external(
|
|
666
|
+
contact_dict=contact_dict,
|
|
667
|
+
contact_email_address_str=contact_dict["email1"],
|
|
668
|
+
contact_id=contact_id,
|
|
669
|
+
system_id=contact_dict.get("system_id"),
|
|
670
|
+
# TODO What happends if contact do not have email?
|
|
671
|
+
# TODO I'm not sure we should use contact_dict["email1"] for user_external_dict["username"] probably bug
|
|
672
|
+
user_external_dict={"username": contact_dict["email1"]}
|
|
673
|
+
)
|
|
674
|
+
print("After " + __name__, file=sys.stderr, flush=True)
|
|
675
|
+
return contact_user_external_id
|
|
676
|
+
|
|
677
|
+
# new
|
|
649
678
|
def __insert_link_contact_user_external_by_contact_dict_and_user_external_dict(
|
|
650
679
|
self,
|
|
651
680
|
contact_dict: dict,
|
|
@@ -672,34 +701,48 @@ class CSVToContactPersonProfile(
|
|
|
672
701
|
def __insert_link_contact_domains(self, contact_dict: dict) -> list[dict]:
|
|
673
702
|
contact_id = contact_dict.get("contact_id")
|
|
674
703
|
profiles_ids_list = contact_dict.get("profiles_ids_list")
|
|
704
|
+
organization_name = contact_dict.get("organization")
|
|
705
|
+
if organization_name:
|
|
706
|
+
organization_id = self.select_one_value_by_column_and_value(
|
|
707
|
+
schema_name="organization",
|
|
708
|
+
view_table_name="organization_view",
|
|
709
|
+
select_clause_value="organization_id",
|
|
710
|
+
column_name="name",
|
|
711
|
+
column_value=organization_name)
|
|
712
|
+
else:
|
|
713
|
+
organization_id = None
|
|
714
|
+
|
|
675
715
|
website_count = 1
|
|
676
716
|
website_url = contact_dict.get("website" + str(website_count))
|
|
677
717
|
url_insert_information_list = []
|
|
678
718
|
while website_url:
|
|
679
719
|
if DomainLocal.is_domain(website_url):
|
|
680
720
|
domain_insert_information_dict = self.domain_local.link_contact_to_domain(
|
|
681
|
-
contact_id=contact_id, url=website_url)
|
|
721
|
+
contact_id=contact_id, url=website_url, organization_id=organization_id)
|
|
682
722
|
url_insert_information_list.append(domain_insert_information_dict)
|
|
683
723
|
elif DomainLocal.is_url(website_url):
|
|
684
724
|
url_insert_information_dict = self.domain_local.link_contact_to_url(
|
|
685
725
|
contact_id=contact_id, url=website_url, profiles_ids=profiles_ids_list)
|
|
686
726
|
url_insert_information_list.append(url_insert_information_dict)
|
|
727
|
+
domain_insert_information_dict = self.domain_local.link_contact_to_domain(
|
|
728
|
+
contact_id=contact_id, url=website_url, organization_id=organization_id)
|
|
729
|
+
url_insert_information_list.append(domain_insert_information_dict)
|
|
687
730
|
else:
|
|
688
|
-
self.logger.warining(f"
|
|
731
|
+
self.logger.warining(f"insert_link_contact_domains: website_url: {website_url} is not a valid domain or url")
|
|
689
732
|
website_count += 1
|
|
690
733
|
website_url = contact_dict.get("website" + str(website_count))
|
|
691
734
|
url = contact_dict.get("url")
|
|
692
735
|
if url:
|
|
693
736
|
if DomainLocal.is_domain(url):
|
|
694
737
|
domain_insert_information_dict = self.domain_local.link_contact_to_domain(
|
|
695
|
-
contact_id=contact_id, url=url)
|
|
738
|
+
contact_id=contact_id, url=url, organization_id=organization_id)
|
|
696
739
|
url_insert_information_list.append(domain_insert_information_dict)
|
|
697
740
|
elif DomainLocal.is_url(url):
|
|
698
741
|
url_insert_information_dict = self.domain_local.link_contact_to_url(
|
|
699
742
|
contact_id=contact_id, url=url, profiles_ids=profiles_ids_list)
|
|
700
743
|
url_insert_information_list.append(url_insert_information_dict)
|
|
701
744
|
else:
|
|
702
|
-
self.logger.warining(f"
|
|
745
|
+
self.logger.warining(f"insert_link_contact_domains: url: {url} is not a valid domain or url")
|
|
703
746
|
|
|
704
747
|
return url_insert_information_list
|
|
705
748
|
|
|
@@ -958,3 +1001,54 @@ class CSVToContactPersonProfile(
|
|
|
958
1001
|
cellphone_number = '+972 ' + cellphone_number
|
|
959
1002
|
contact_dict['phone1'] = cellphone_number
|
|
960
1003
|
return contact_dict
|
|
1004
|
+
|
|
1005
|
+
def process_email_address(self, email_address: str) -> dict:
|
|
1006
|
+
"""
|
|
1007
|
+
Process email address and extract domain information
|
|
1008
|
+
:param email_address: Email adress to process
|
|
1009
|
+
:return: Dict with email_address_id, internet_domain_name, internet_domain_name_id, organization_name, organization_id
|
|
1010
|
+
"""
|
|
1011
|
+
# Example email address could be: circles@circlez.ai
|
|
1012
|
+
if '@' not in email_address:
|
|
1013
|
+
return None #Invalid email address
|
|
1014
|
+
|
|
1015
|
+
# Get domain name
|
|
1016
|
+
internet_domain_name = email_address.split('@')[1]
|
|
1017
|
+
|
|
1018
|
+
# Get internet_domain_name_id based on internet_domain_name
|
|
1019
|
+
internet_domain_name_id = self.select_one_value_by_column_and_value(
|
|
1020
|
+
schema_name="internet_domain",
|
|
1021
|
+
view_table_name="internet_domain_view",
|
|
1022
|
+
select_clause_value="internet_domain_id",
|
|
1023
|
+
column_name="domain",
|
|
1024
|
+
column_value=internet_domain_name)
|
|
1025
|
+
|
|
1026
|
+
# Get organization_id name based on internet_domain_name
|
|
1027
|
+
organization_id = self.select_one_value_by_column_and_value(
|
|
1028
|
+
schema_name="internet_domain",
|
|
1029
|
+
view_table_name="internet_domain_view",
|
|
1030
|
+
select_clause_value="organization_id",
|
|
1031
|
+
column_name="domain",
|
|
1032
|
+
column_value=internet_domain_name)
|
|
1033
|
+
|
|
1034
|
+
# Get organization_name based on organization_id
|
|
1035
|
+
organization_name = self.select_one_value_by_column_and_value(
|
|
1036
|
+
schema_name="organization",
|
|
1037
|
+
view_table_name="organization_view",
|
|
1038
|
+
select_clause_value="name",
|
|
1039
|
+
column_name="organization_id",
|
|
1040
|
+
column_value=organization_id)
|
|
1041
|
+
|
|
1042
|
+
# Get email_address_id based on email_address
|
|
1043
|
+
email_address_id = self.select_one_value_by_column_and_value(
|
|
1044
|
+
schema_name="email_address",
|
|
1045
|
+
view_table_name="email_address_view",
|
|
1046
|
+
select_clause_value="email_address_id",
|
|
1047
|
+
column_name="email_address",
|
|
1048
|
+
column_value=email_address)
|
|
1049
|
+
|
|
1050
|
+
return {"email_address_id": email_address_id,
|
|
1051
|
+
"internet_domain_name": internet_domain_name,
|
|
1052
|
+
"internet_domain_name_id": internet_domain_name_id,
|
|
1053
|
+
"organization_name": organization_name,
|
|
1054
|
+
"organization_id": organization_id}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: contact-person-profile-csv-imp-local
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.52
|
|
4
4
|
Summary: PyPI Package for Circles CSVToContactPersonProfile-local Local/Remote Python
|
|
5
5
|
Home-page: https://github.com/circles-zone/contact-person-profile-csv-imp-local-python-package
|
|
6
6
|
Author: Circles
|
|
@@ -12,7 +12,7 @@ Requires-Dist: contact-local>=0.0.48
|
|
|
12
12
|
Requires-Dist: logger-local>=0.0.135
|
|
13
13
|
Requires-Dist: database-mysql-local>=0.1.1
|
|
14
14
|
Requires-Dist: user-context-remote>=0.0.77
|
|
15
|
-
Requires-Dist: contact-email-address-local>=0.0.
|
|
15
|
+
Requires-Dist: contact-email-address-local>=0.0.8
|
|
16
16
|
Requires-Dist: contact-group-local>=0.0.68
|
|
17
17
|
Requires-Dist: contact-location-local>=0.0.14
|
|
18
18
|
Requires-Dist: contact-notes-local>=0.0.33
|
|
@@ -2,7 +2,7 @@ contact-local>=0.0.48
|
|
|
2
2
|
logger-local>=0.0.135
|
|
3
3
|
database-mysql-local>=0.1.1
|
|
4
4
|
user-context-remote>=0.0.77
|
|
5
|
-
contact-email-address-local>=0.0.
|
|
5
|
+
contact-email-address-local>=0.0.8
|
|
6
6
|
contact-group-local>=0.0.68
|
|
7
7
|
contact-location-local>=0.0.14
|
|
8
8
|
contact-notes-local>=0.0.33
|
{contact_person_profile_csv_imp_local-0.0.50 → contact_person_profile_csv_imp_local-0.0.52}/setup.py
RENAMED
|
@@ -5,7 +5,7 @@ package_dir = PACKAGE_NAME.replace("-", "_")
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name=PACKAGE_NAME,
|
|
8
|
-
version='0.0.
|
|
8
|
+
version='0.0.52', # https://pypi.org/project/contact-person-profile-csv-imp-local/
|
|
9
9
|
|
|
10
10
|
author="Circles",
|
|
11
11
|
author_email="info@circles.ai",
|
|
@@ -26,7 +26,7 @@ setuptools.setup(
|
|
|
26
26
|
'logger-local>=0.0.135',
|
|
27
27
|
'database-mysql-local>=0.1.1',
|
|
28
28
|
'user-context-remote>=0.0.77',
|
|
29
|
-
'contact-email-address-local>=0.0.
|
|
29
|
+
'contact-email-address-local>=0.0.8',
|
|
30
30
|
'contact-group-local>=0.0.68',
|
|
31
31
|
'contact-location-local>=0.0.14',
|
|
32
32
|
'contact-notes-local>=0.0.33',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|