event-local 0.0.1__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.
- event_local-0.0.1/PKG-INFO +16 -0
- event_local-0.0.1/event_local/src/__init__.py +0 -0
- event_local-0.0.1/event_local/src/constants_event_local.py +15 -0
- event_local-0.0.1/event_local/src/event_local.py +159 -0
- event_local-0.0.1/event_local/src/handler.py +101 -0
- event_local-0.0.1/event_local/src/holiday_local.py +78 -0
- event_local-0.0.1/event_local/src/validate_inputs.py +73 -0
- event_local-0.0.1/event_local.egg-info/PKG-INFO +16 -0
- event_local-0.0.1/event_local.egg-info/SOURCES.txt +13 -0
- event_local-0.0.1/event_local.egg-info/dependency_links.txt +1 -0
- event_local-0.0.1/event_local.egg-info/requires.txt +3 -0
- event_local-0.0.1/event_local.egg-info/top_level.txt +1 -0
- event_local-0.0.1/pyproject.toml +21 -0
- event_local-0.0.1/setup.cfg +4 -0
- event_local-0.0.1/setup.py +42 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: event-local
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: PyPI Package for Circles event-local Python
|
|
5
|
+
Home-page: https://github.com/circles-zone/event-local-python-package
|
|
6
|
+
Author: Circles
|
|
7
|
+
Author-email: info@circlez.ai
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: Other/Proprietary License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: logger-local
|
|
13
|
+
Requires-Dist: database-sql-local
|
|
14
|
+
Requires-Dist: python-sdk-remote
|
|
15
|
+
|
|
16
|
+
PyPI Package for Circles event-local Python
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from logger_local.LoggerComponentEnum import LoggerComponentEnum
|
|
2
|
+
|
|
3
|
+
# TODO We should bring this value from entity_type_view
|
|
4
|
+
EVENT_ENTITY_TYPE_ID = 14
|
|
5
|
+
|
|
6
|
+
EVENT_LOCAL_PYTHON_COMPONENT_ID = 247
|
|
7
|
+
EVENT_LOCAL_PYTHON_COMPONENT_NAME = 'event-local-restapi-python-serverless'
|
|
8
|
+
DEVELOPER_EMAIL = 'akiva.s@circ.zone'
|
|
9
|
+
|
|
10
|
+
EVENTS_LOCAL_CODE_LOGGER_OBJECT = {
|
|
11
|
+
'component_id': EVENT_LOCAL_PYTHON_COMPONENT_ID,
|
|
12
|
+
'component_name': EVENT_LOCAL_PYTHON_COMPONENT_NAME,
|
|
13
|
+
'component_category': LoggerComponentEnum.ComponentCategory.Code.value,
|
|
14
|
+
'developer_email': DEVELOPER_EMAIL
|
|
15
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
from database_mysql_local.generic_crud import GenericCRUD, DEFAULT_SQL_SELECT_LIMIT
|
|
2
|
+
from location_local.locations_local_crud import LocationsLocal
|
|
3
|
+
from logger_local.MetaLogger import MetaLogger
|
|
4
|
+
from .constants_event_local import EVENTS_LOCAL_CODE_LOGGER_OBJECT, EVENT_ENTITY_TYPE_ID
|
|
5
|
+
from .validate_inputs import ValidateInputs
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EventsLocal(GenericCRUD, metaclass=MetaLogger, object=EVENTS_LOCAL_CODE_LOGGER_OBJECT):
|
|
11
|
+
def __init__(self, is_test_data: bool = False) -> None:
|
|
12
|
+
super().__init__(default_schema_name="event", default_column_name="event_id",
|
|
13
|
+
default_table_name="event_table", default_view_table_name="event_view",
|
|
14
|
+
is_test_data=is_test_data)
|
|
15
|
+
self.validate_inputs = ValidateInputs(is_test_data=is_test_data)
|
|
16
|
+
|
|
17
|
+
# TODO: test
|
|
18
|
+
def select_all_events(self, lang_code_str: str, limit: int = None) -> list:
|
|
19
|
+
"""Returns all the rows in the event_table"""
|
|
20
|
+
limit = limit or DEFAULT_SQL_SELECT_LIMIT
|
|
21
|
+
# TODO If we don't have result int the profile preferred language, we should bring the English version
|
|
22
|
+
# TODO If event has multiple names we should bring the one which is_main = TRUE
|
|
23
|
+
sql_query = f"""
|
|
24
|
+
SELECT event.event_id AS 'event_id',
|
|
25
|
+
{EVENT_ENTITY_TYPE_ID} AS 'item_type_id',
|
|
26
|
+
event.location_id,
|
|
27
|
+
event.organizers_profile_id,
|
|
28
|
+
event.website_url,
|
|
29
|
+
event.facebook_event_url,
|
|
30
|
+
event.meetup_event_url,
|
|
31
|
+
event_ml.title
|
|
32
|
+
FROM event.event_view AS event
|
|
33
|
+
LEFT JOIN event.event_ml_view AS event_ml ON event.event_id = event_ml.event_id
|
|
34
|
+
AND event_ml.lang_code = %s
|
|
35
|
+
LIMIT {limit}"""
|
|
36
|
+
self.cursor.execute(sql_query, (lang_code_str,))
|
|
37
|
+
columns = ("event_id, item_type_id, location_id, organizers_profile_id, website_url, "
|
|
38
|
+
"facebook_event_url, meetup_event_url, title")
|
|
39
|
+
events_dict = self.convert_multi_to_dict(self.cursor.fetchall(), columns)
|
|
40
|
+
return events_dict
|
|
41
|
+
|
|
42
|
+
def select_events_by_title(self, title: str, limit: int = None) -> list:
|
|
43
|
+
"""Returns all the events that have the given title"""
|
|
44
|
+
limit = limit or DEFAULT_SQL_SELECT_LIMIT
|
|
45
|
+
events_list = self.select_multi_dict_by_column_and_value(
|
|
46
|
+
view_table_name="event_ml_view", column_name="title", column_value=title, limit=limit)
|
|
47
|
+
return events_list
|
|
48
|
+
|
|
49
|
+
# TODO: test
|
|
50
|
+
def select_events_by_profile_id(self, profile_id: int, limit: int = None) -> list:
|
|
51
|
+
"""Returns all the events that are related to the given profile_id"""
|
|
52
|
+
self.validate_inputs.validate_id(profile_id, schema="profile")
|
|
53
|
+
limit = limit or DEFAULT_SQL_SELECT_LIMIT
|
|
54
|
+
# TODO: should we move this to a view?
|
|
55
|
+
sql_query = f"""
|
|
56
|
+
WITH EventCommonGroups AS (
|
|
57
|
+
SELECT event.event_id,
|
|
58
|
+
event_ml.title,
|
|
59
|
+
{EVENT_ENTITY_TYPE_ID} AS item_type,
|
|
60
|
+
COUNT(group_profile.group_id) AS common_group_count
|
|
61
|
+
FROM event.event_view AS event
|
|
62
|
+
LEFT JOIN
|
|
63
|
+
event.event_ml_view AS event_ml ON event.event_id = event_ml.event_id
|
|
64
|
+
LEFT JOIN
|
|
65
|
+
event_group.event_group_view AS event_group ON event.event_id = event_group.event_id
|
|
66
|
+
LEFT JOIN
|
|
67
|
+
group_profile.group_profile_view AS group_profile
|
|
68
|
+
ON event_group.group_id = group_profile.group_id AND
|
|
69
|
+
group_profile.profile_id = %s
|
|
70
|
+
GROUP BY event.event_id, event_ml.title
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
SELECT event.event_id,
|
|
74
|
+
event.location_id,
|
|
75
|
+
event.organizers_profile_id,
|
|
76
|
+
event.website_url,
|
|
77
|
+
event.facebook_event_url,
|
|
78
|
+
event.meetup_event_url,
|
|
79
|
+
event.registration_url,
|
|
80
|
+
EventCommonGroups.title,
|
|
81
|
+
EventCommonGroups.item_type,
|
|
82
|
+
EventCommonGroups.common_group_count,
|
|
83
|
+
event_location.location_id AS event_location_id,
|
|
84
|
+
(COALESCE(1 / ST_Distance(
|
|
85
|
+
event_location.coordinate, COALESCE(location_profile.coordinate, event_location.coordinate)), 0)) AS distance_rank,
|
|
86
|
+
(COALESCE(1 / ST_Distance(
|
|
87
|
+
event_location.coordinate, COALESCE(location_profile.coordinate, event_location.coordinate)), 0)) +
|
|
88
|
+
COALESCE(EventCommonGroups.common_group_count / 5, 0) AS final_rank
|
|
89
|
+
FROM EventCommonGroups
|
|
90
|
+
LEFT JOIN
|
|
91
|
+
event.event_view AS event ON EventCommonGroups.event_id = event.event_id
|
|
92
|
+
LEFT JOIN
|
|
93
|
+
(SELECT event_location.event_id,
|
|
94
|
+
event_location.location_id,
|
|
95
|
+
location.coordinate
|
|
96
|
+
FROM event_location.event_location_view AS event_location
|
|
97
|
+
LEFT JOIN location.location_view AS location ON event_location.location_id = location.location_id) AS event_location
|
|
98
|
+
ON event.event_id = event_location.event_id
|
|
99
|
+
LEFT JOIN
|
|
100
|
+
(SELECT location_profile.location_id,
|
|
101
|
+
location.coordinate,
|
|
102
|
+
location_profile.profile_id
|
|
103
|
+
FROM location_profile.location_profile_view AS location_profile
|
|
104
|
+
LEFT JOIN location.location_view AS location ON location_profile.location_id = location.location_id
|
|
105
|
+
ORDER BY location_profile.start_timestamp DESC
|
|
106
|
+
LIMIT 1) AS location_profile ON location_profile.profile_id = %s
|
|
107
|
+
LEFT JOIN
|
|
108
|
+
location.location_view AS location ON location.location_id = location_profile.location_id
|
|
109
|
+
ORDER BY final_rank DESC
|
|
110
|
+
LIMIT {limit};
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
self.cursor.execute(sql_query, (profile_id, profile_id))
|
|
114
|
+
columns = ("event.event_id, eventlocation_id, eventorganizers_profile_id, eventwebsite_url, "
|
|
115
|
+
"eventfacebook_event_url, eventmeetup_event_url, eventregistration_url, title, item_type, "
|
|
116
|
+
"common_group_count, event_location_id, distance_rank, final_rank")
|
|
117
|
+
events_dict = self.convert_multi_to_dict(self.cursor.fetchall(), columns)
|
|
118
|
+
|
|
119
|
+
return events_dict
|
|
120
|
+
|
|
121
|
+
def select_by_event_id(self, event_id: int) -> dict:
|
|
122
|
+
"""Returns the event row with the given event_id"""
|
|
123
|
+
self.validate_inputs.validate_id(event_id)
|
|
124
|
+
# TODO add support to event-external
|
|
125
|
+
select_clause = "event_id, location_id, organizers_profile_id, website_url, facebook_event_url, meetup_event_url, registration_url"
|
|
126
|
+
event = self.select_one_dict_by_column_and_value(column_value=event_id, select_clause_value=select_clause)
|
|
127
|
+
return event
|
|
128
|
+
|
|
129
|
+
def insert_event_data(self, event_data: dict) -> int:
|
|
130
|
+
"""Inserts a row into the event_table and returns the id of the inserted row"""
|
|
131
|
+
self.validate_inputs.validate_input_dict(input_dict=event_data)
|
|
132
|
+
event_id = self.insert(data_dict=event_data)
|
|
133
|
+
return event_id
|
|
134
|
+
|
|
135
|
+
def update_by_event_id(self, event_id: int, event_data: dict) -> int:
|
|
136
|
+
"""Updates the event row with the given event_id"""
|
|
137
|
+
self.validate_inputs.validate_id(event_id)
|
|
138
|
+
self.validate_inputs.validate_input_dict(input_dict=event_data)
|
|
139
|
+
amount_of_events_updated = self.update_by_column_and_value(column_value=event_id, data_dict=event_data)
|
|
140
|
+
return amount_of_events_updated
|
|
141
|
+
|
|
142
|
+
def delete_by_event_id(self, event_id: int) -> int:
|
|
143
|
+
"""Deletes the event row with the given event_id"""
|
|
144
|
+
self.validate_inputs.validate_id(event_id)
|
|
145
|
+
amount_of_events_deleted = self.delete_by_column_and_value(column_value=event_id)
|
|
146
|
+
return amount_of_events_deleted
|
|
147
|
+
|
|
148
|
+
def get_test_event_id(self) -> int:
|
|
149
|
+
location_id = LocationsLocal().get_test_location_id()
|
|
150
|
+
test_event_id = super().get_test_entity_id(
|
|
151
|
+
entity_name="event", insert_function=self.insert,
|
|
152
|
+
view_name="event_view", insert_kwargs={'location_id': location_id})
|
|
153
|
+
return test_event_id
|
|
154
|
+
|
|
155
|
+
def get_number_of_events(self) -> int:
|
|
156
|
+
sql_statement = "SELECT COUNT(*) FROM event.event_view"
|
|
157
|
+
self.cursor.execute(sql_statement=sql_statement)
|
|
158
|
+
number_of_events = self.cursor.fetchone()[0]
|
|
159
|
+
return number_of_events
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from logger_local.LoggerLocal import Logger
|
|
2
|
+
from python_sdk_local.http_response import handler_decorator
|
|
3
|
+
from python_sdk_local.utilities import DEFAULT_LANG_CODE_STR
|
|
4
|
+
|
|
5
|
+
from .constants_event_local import EVENTS_LOCAL_CODE_LOGGER_OBJECT
|
|
6
|
+
from .event_local import EventsLocal
|
|
7
|
+
|
|
8
|
+
logger = Logger.create_logger(object=EVENTS_LOCAL_CODE_LOGGER_OBJECT)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@handler_decorator(logger)
|
|
12
|
+
def createHandler(request_parameters: dict) -> dict:
|
|
13
|
+
# In all serverless-com handlers' logger.start()- Add optional parameter
|
|
14
|
+
# to logger.start() which called api_call, so logger.start will call
|
|
15
|
+
# api_management to insert into api_call_table all fields including
|
|
16
|
+
# session_id.
|
|
17
|
+
"""Read parameters from the payload and insert them"""
|
|
18
|
+
|
|
19
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
20
|
+
event_id = EventsLocal(is_test_data=is_test_data).insert_event_data(request_parameters)
|
|
21
|
+
message = {"message": "Event created successfully", "event_id": event_id}
|
|
22
|
+
return message
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# TODO: except ValueError as exception, BAD_REQUEST / INTERNAL_SERVER_ERROR...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@handler_decorator(logger)
|
|
29
|
+
def deleteHandler(request_parameters: dict) -> dict:
|
|
30
|
+
"""url/5 (5 is the eventId)"""
|
|
31
|
+
|
|
32
|
+
event_id = request_parameters.get('eventId')
|
|
33
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
34
|
+
EventsLocal(is_test_data=is_test_data).delete_by_event_id(event_id=event_id)
|
|
35
|
+
message = {"message": "Event deleted successfully"}
|
|
36
|
+
return message
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# TODO This should be imported from entity-type-python-package (this file will be generated by Sql2Code)
|
|
40
|
+
@handler_decorator(logger)
|
|
41
|
+
def getAllHandler(request_parameters: dict) -> list:
|
|
42
|
+
"""url?langCode=en&limit=10"""
|
|
43
|
+
|
|
44
|
+
lang_code_str = request_parameters.get("langCode") or DEFAULT_LANG_CODE_STR
|
|
45
|
+
limit = request_parameters.get("limit")
|
|
46
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
47
|
+
events_list = EventsLocal(is_test_data=is_test_data).select_all_events(lang_code_str, limit=limit)
|
|
48
|
+
return events_list
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@handler_decorator(logger)
|
|
52
|
+
def getEventByProfileIdHandler(request_parameters: dict) -> list:
|
|
53
|
+
"""url/5?limit=10 (5 is the profileId)"""
|
|
54
|
+
|
|
55
|
+
request_parameters = request_parameters
|
|
56
|
+
profile_id = request_parameters.get("profileId")
|
|
57
|
+
limit = request_parameters.get("limit")
|
|
58
|
+
|
|
59
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
60
|
+
events_list = EventsLocal(is_test_data=is_test_data).select_events_by_profile_id(profile_id, limit=limit)
|
|
61
|
+
return events_list
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@handler_decorator(logger)
|
|
65
|
+
def getEventByEventIdHandler(request_parameters: dict) -> dict:
|
|
66
|
+
"""url/5?isTestData=true (eventId)"""
|
|
67
|
+
|
|
68
|
+
event_id = request_parameters.get("eventId")
|
|
69
|
+
|
|
70
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
71
|
+
event = EventsLocal(is_test_data=is_test_data).select_by_event_id(event_id)
|
|
72
|
+
if not event:
|
|
73
|
+
raise Exception(f"Event not found with event_id: {event_id}")
|
|
74
|
+
return event
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@handler_decorator(logger)
|
|
78
|
+
def updateHandler(request_parameters: dict) -> dict:
|
|
79
|
+
"""url/5 (eventId)
|
|
80
|
+
Read parameters from the payload and update them"""
|
|
81
|
+
|
|
82
|
+
event_id = request_parameters.get('eventId')
|
|
83
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
84
|
+
if not event_id:
|
|
85
|
+
raise Exception("event_id is required")
|
|
86
|
+
|
|
87
|
+
EventsLocal(is_test_data=is_test_data).update_by_event_id(event_id, request_parameters)
|
|
88
|
+
message = {"message": "Event updated successfully"}
|
|
89
|
+
return message
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@handler_decorator(logger)
|
|
93
|
+
def getEventByEventTitleHandler(request_parameters: dict) -> list: # TODO: test
|
|
94
|
+
"""url/SomeTitle?limit=10"""
|
|
95
|
+
|
|
96
|
+
title = request_parameters.get("title")
|
|
97
|
+
|
|
98
|
+
limit = request_parameters.get("limit")
|
|
99
|
+
is_test_data = request_parameters.get("isTestData", False)
|
|
100
|
+
events_list = EventsLocal(is_test_data=is_test_data).select_events_by_title(title, limit=limit)
|
|
101
|
+
return events_list
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
import holidays
|
|
4
|
+
from database_mysql_local.generic_crud import GenericCRUD
|
|
5
|
+
from logger_local.MetaLogger import MetaLogger
|
|
6
|
+
|
|
7
|
+
# from location_local.locations_local_crud import LocationsLocal
|
|
8
|
+
from .constants_event_local import EVENT_CODE_LOGGER_OBJECT
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# TODO: test
|
|
12
|
+
class HolidayLocal(GenericCRUD, metaclass=MetaLogger, object=EVENT_CODE_LOGGER_OBJECT):
|
|
13
|
+
"""HolidayLocal"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, is_test_data: bool = False) -> None:
|
|
16
|
+
super().__init__(default_schema_name="event",
|
|
17
|
+
default_table_name="event_table",
|
|
18
|
+
default_view_table_name="event_view",
|
|
19
|
+
default_column_name="event_id",
|
|
20
|
+
is_test_data=is_test_data)
|
|
21
|
+
|
|
22
|
+
def insert_holiday(self, *, date: str, holiday: str,
|
|
23
|
+
country: str, state: str = None) -> int:
|
|
24
|
+
"""Inserts a new holiday and returns the new holiday_id"""
|
|
25
|
+
|
|
26
|
+
# location_obj = LocationsLocal()
|
|
27
|
+
# lang_code = "en"
|
|
28
|
+
# all_details = {"coordinate": {"latitude": None, "longitude": None}, "address_local_language": None,
|
|
29
|
+
# "address_english": None, "neighborhood": None, "county": None, "region": None, "state": state,
|
|
30
|
+
# "country": country, "postal_code": None, "plus_code": None, "is_approved": False}
|
|
31
|
+
# location_id = location_obj.get_location_ids(all_details, lang_code, True)
|
|
32
|
+
location_id = 3 # TODO
|
|
33
|
+
if self.holiday_exists(date=date, holiday=holiday, country=country, state=state):
|
|
34
|
+
event_table_data = {
|
|
35
|
+
"start_timestamp": date,
|
|
36
|
+
"location_id": location_id,
|
|
37
|
+
"website_url": "test for holiday"
|
|
38
|
+
}
|
|
39
|
+
holiday_id = super().insert(data_dict=event_table_data)
|
|
40
|
+
return holiday_id
|
|
41
|
+
|
|
42
|
+
def update_holiday(self, *, holiday_id: int, holiday_data: Dict[str, any]) -> None:
|
|
43
|
+
"""Updates an existing holiday"""
|
|
44
|
+
event_table_data = {
|
|
45
|
+
"date": holiday_data.get('date'),
|
|
46
|
+
"holiday": holiday_data.get('holiday'),
|
|
47
|
+
"country": holiday_data.get('country'),
|
|
48
|
+
"state": holiday_data.get('state')
|
|
49
|
+
}
|
|
50
|
+
super().update_by_column_and_value(column_value=holiday_id, data_dict=event_table_data)
|
|
51
|
+
|
|
52
|
+
def get_holiday_by_id(self, holiday_id: int) -> Dict[str, any]:
|
|
53
|
+
"""Gets holiday information by holiday_id"""
|
|
54
|
+
holiday_dict = self.select_one_dict_by_column_and_value(column_value=holiday_id)
|
|
55
|
+
return holiday_dict
|
|
56
|
+
|
|
57
|
+
def delete_holiday_by_id(self, holiday_id: int) -> None:
|
|
58
|
+
"""Deletes a holiday by holiday_id"""
|
|
59
|
+
self.delete_by_column_and_value(column_value=holiday_id)
|
|
60
|
+
|
|
61
|
+
def holiday_exists(self, *, date: str, holiday: str, country: str, state: str = None) -> bool:
|
|
62
|
+
"""Checks if a holiday with the given details already exists in the database"""
|
|
63
|
+
# TODO: fix
|
|
64
|
+
# conditions = {
|
|
65
|
+
# "date": date,
|
|
66
|
+
# "holiday": holiday,
|
|
67
|
+
# "country": country,
|
|
68
|
+
# "state": state
|
|
69
|
+
# }
|
|
70
|
+
existing_holiday = self.select_one_dict_by_column_and_value(
|
|
71
|
+
view_table_name="event_view", column_name="event_id", column_value="2")
|
|
72
|
+
return existing_holiday is not None
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def fetch_holidays(country: str, year: int) -> list:
|
|
76
|
+
"""fetch us holidays"""
|
|
77
|
+
holidays_list = sorted(holidays.country_holidays(country, years=year).keys())
|
|
78
|
+
return holidays_list
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from database_mysql_local.generic_crud import GenericCRUD
|
|
2
|
+
from database_mysql_local.table_columns import table_columns
|
|
3
|
+
from python_sdk_remote.utilities import validate_url
|
|
4
|
+
|
|
5
|
+
event_table_columns = table_columns["event_table"]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Note: if you shange those messages, update the tests accordingly
|
|
9
|
+
class ValidateInputs(GenericCRUD):
|
|
10
|
+
def __init__(self, is_test_data: bool = False) -> None:
|
|
11
|
+
super().__init__(default_schema_name="event", default_column_name="event_id",
|
|
12
|
+
default_table_name="event_table", default_view_table_name="event_view",
|
|
13
|
+
is_test_data=is_test_data)
|
|
14
|
+
|
|
15
|
+
def validate_location_id(self, location_id: int) -> None:
|
|
16
|
+
if location_id is None or not isinstance(location_id, int) or location_id < 0:
|
|
17
|
+
raise ValueError(f"Invalid location_id: {location_id} (type: {type(location_id)})")
|
|
18
|
+
_location_id = self.select_one_value_by_column_and_value(
|
|
19
|
+
schema_name="location", view_table_name="location_view", select_clause_value="location_id",
|
|
20
|
+
column_name="location_id", column_value=location_id)
|
|
21
|
+
if _location_id is None:
|
|
22
|
+
raise ValueError(f"Invalid location_id: {location_id} (not found in location.location_view)")
|
|
23
|
+
|
|
24
|
+
def validate_organizers_profile_id(self, organizers_profile_id: int) -> None:
|
|
25
|
+
if not organizers_profile_id or not isinstance(organizers_profile_id, int) or organizers_profile_id <= 0:
|
|
26
|
+
raise ValueError(
|
|
27
|
+
f"Invalid organizers_profile_id: {organizers_profile_id} (type: {type(organizers_profile_id)})")
|
|
28
|
+
_organizers_profile_id = self.select_one_value_by_column_and_value(
|
|
29
|
+
schema_name="profile", view_table_name="profile_view", select_clause_value="profile_id",
|
|
30
|
+
column_name="profile_id", column_value=organizers_profile_id)
|
|
31
|
+
if _organizers_profile_id is None:
|
|
32
|
+
raise ValueError(
|
|
33
|
+
f"Invalid organizers_profile_id: {organizers_profile_id} (not found in profile.profile_view)")
|
|
34
|
+
|
|
35
|
+
def validate_input_dict(self, input_dict: dict) -> None:
|
|
36
|
+
location_id = input_dict.get('location_id')
|
|
37
|
+
organizers_profile_id = input_dict.get('organizers_profile_id')
|
|
38
|
+
website_url = input_dict.get('website_url')
|
|
39
|
+
facebook_event_url = input_dict.get('facebook_event_url')
|
|
40
|
+
meetup_event_url = input_dict.get('meetup_event_url')
|
|
41
|
+
registration_url = input_dict.get('registration_url')
|
|
42
|
+
# TODO: allowed_keys = [...] and set(input_dict.keys()) == set(allowed_keys)
|
|
43
|
+
self.validate_location_id(location_id)
|
|
44
|
+
self.validate_organizers_profile_id(organizers_profile_id)
|
|
45
|
+
|
|
46
|
+
if website_url and not validate_url(website_url):
|
|
47
|
+
raise ValueError(f"Invalid input: website_url - {website_url}")
|
|
48
|
+
if facebook_event_url and not validate_url(facebook_event_url):
|
|
49
|
+
raise ValueError(f"Invalid input: facebook_event_url - {facebook_event_url}")
|
|
50
|
+
if meetup_event_url and not validate_url(meetup_event_url):
|
|
51
|
+
raise ValueError(f"Invalid input: meetup_event_url - {meetup_event_url}")
|
|
52
|
+
if registration_url and not validate_url(registration_url):
|
|
53
|
+
raise ValueError(f"Invalid input: registration_url - {registration_url}")
|
|
54
|
+
|
|
55
|
+
for key in list(input_dict):
|
|
56
|
+
if key not in event_table_columns:
|
|
57
|
+
input_dict.pop(key)
|
|
58
|
+
|
|
59
|
+
# TODO Move this function to database-mysql-python-package and make it generic for all tables using Entity enum
|
|
60
|
+
def validate_id(self, entity_id: int, schema: str = "event") -> None:
|
|
61
|
+
try:
|
|
62
|
+
entity_id = int(entity_id)
|
|
63
|
+
if entity_id < 0:
|
|
64
|
+
raise ValueError
|
|
65
|
+
except ValueError:
|
|
66
|
+
raise ValueError(f"Invalid {schema}_id: {entity_id}")
|
|
67
|
+
assert ";" not in schema # Prevent SQL Injection
|
|
68
|
+
value = self.select_one_value_by_column_and_value(schema_name=schema, view_table_name=schema + "_view",
|
|
69
|
+
select_clause_value=schema + "_id",
|
|
70
|
+
column_name=schema + "_id",
|
|
71
|
+
column_value=entity_id)
|
|
72
|
+
if value is None:
|
|
73
|
+
raise ValueError(f"Invalid {schema}_id: {entity_id} (not found in {schema}.{schema}_view)")
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: event-local
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: PyPI Package for Circles event-local Python
|
|
5
|
+
Home-page: https://github.com/circles-zone/event-local-python-package
|
|
6
|
+
Author: Circles
|
|
7
|
+
Author-email: info@circlez.ai
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: Other/Proprietary License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
Requires-Dist: logger-local
|
|
13
|
+
Requires-Dist: database-sql-local
|
|
14
|
+
Requires-Dist: python-sdk-remote
|
|
15
|
+
|
|
16
|
+
PyPI Package for Circles event-local Python
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
setup.py
|
|
3
|
+
event_local.egg-info/PKG-INFO
|
|
4
|
+
event_local.egg-info/SOURCES.txt
|
|
5
|
+
event_local.egg-info/dependency_links.txt
|
|
6
|
+
event_local.egg-info/requires.txt
|
|
7
|
+
event_local.egg-info/top_level.txt
|
|
8
|
+
event_local/src/__init__.py
|
|
9
|
+
event_local/src/constants_event_local.py
|
|
10
|
+
event_local/src/event_local.py
|
|
11
|
+
event_local/src/handler.py
|
|
12
|
+
event_local/src/holiday_local.py
|
|
13
|
+
event_local/src/validate_inputs.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
event_local
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# This file should be in the future instead of setup.py
|
|
2
|
+
# https://python-poetry.org/docs/pyproject
|
|
3
|
+
|
|
4
|
+
# This file is mandatory for the `poetry version patch`
|
|
5
|
+
|
|
6
|
+
# It seems we need to copy this file also to serverless-com repo, as required by dialog-workflow-python-package
|
|
7
|
+
|
|
8
|
+
[build-system]
|
|
9
|
+
requires = ["setuptools>=61.0"]
|
|
10
|
+
build-backend = "setuptools.build_meta"
|
|
11
|
+
|
|
12
|
+
[tool.poetry]
|
|
13
|
+
# TODO: Please update the name, similar to storage-local (suffix -local)
|
|
14
|
+
name = "event-local"
|
|
15
|
+
# I believe we are still using the version from setup.py and not from here until Potery will work
|
|
16
|
+
version = "0.0.2" # https://pypi.org/project/<project-name> i.e. https://pypi.org/project/storage-local/
|
|
17
|
+
description = "Event Local Python Package"
|
|
18
|
+
readme = "README.md"
|
|
19
|
+
authors = [
|
|
20
|
+
"Circlez.ai <info@circlez.ai>",
|
|
21
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Trying to create a package from a repo that includes both local and serverless.com
|
|
2
|
+
|
|
3
|
+
import setuptools
|
|
4
|
+
|
|
5
|
+
# TODO: Change the PACKAGE_NAME to the package's name - Either xxx-local or xxx-remote (without the -python-package suffix). Only lowercase, no underlines.
|
|
6
|
+
# Used by pypa/gh-action-pypi-publish
|
|
7
|
+
# Package Name should be identical to the inner directory name
|
|
8
|
+
# Changing the package name here, will cause changing the package directory name as well
|
|
9
|
+
# PACKAGE_NAME should be singular if handling only one instance
|
|
10
|
+
# PACKAGE_NAME should not include the word "main"
|
|
11
|
+
PACKAGE_NAME = "event-local" # e.g.: queue-local, without python-package suffix
|
|
12
|
+
|
|
13
|
+
package_dir = PACKAGE_NAME.replace("-", "_")
|
|
14
|
+
# If we need backward-compatible:
|
|
15
|
+
# old_package_dir = "old_package_name"
|
|
16
|
+
|
|
17
|
+
setuptools.setup(
|
|
18
|
+
name=PACKAGE_NAME,
|
|
19
|
+
version='0.0.1', # increase this number every time you make a change you want to publish. After 0.0.9 switch to 0.0.10 and not 0.1.0
|
|
20
|
+
author="Circles",
|
|
21
|
+
author_email="info@circlez.ai",
|
|
22
|
+
description=f"PyPI Package for Circles {PACKAGE_NAME} Python",
|
|
23
|
+
long_description=f"PyPI Package for Circles {PACKAGE_NAME} Python",
|
|
24
|
+
long_description_content_type='text/markdown',
|
|
25
|
+
url=f"https://github.com/circles-zone/{PACKAGE_NAME}-python-package",
|
|
26
|
+
packages=[package_dir],
|
|
27
|
+
# packages=[package_dir, old_package_dir],
|
|
28
|
+
package_dir={package_dir: f'{package_dir}/src'},
|
|
29
|
+
# package_dir={package_dir: f'{package_dir}/src', old_package_dir: f'{package_dir}/src'},
|
|
30
|
+
package_data={package_dir: ['*.py']},
|
|
31
|
+
classifiers=[
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"License :: Other/Proprietary License",
|
|
34
|
+
"Operating System :: OS Independent",
|
|
35
|
+
],
|
|
36
|
+
# TODO: Update which packages to include with this package in production (dependencies) - Not for development/testing
|
|
37
|
+
install_requires=[
|
|
38
|
+
'logger-local', # TODO: in -remote package please use logger-remote instead.
|
|
39
|
+
'database-sql-local', # TODO: In -remote package please delete this line.
|
|
40
|
+
'python-sdk-remote'
|
|
41
|
+
]
|
|
42
|
+
)
|