Skip to content

feat: improve import file to calendar and extend capabilities #201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/config.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ VALID_FILE_EXTENSION = (".txt", ".csv", ".ics") # Can import only these files.
EVENT_VALID_YEARS = 20
EVENT_HEADER_NOT_EMPTY = 1 # 1- for not empty, 0- for empty.
EVENT_HEADER_LIMIT = 50 # Max characters for event header.
EVENT_CONTENT_LIMIT = 500 # Max characters for event characters.
EVENT_CONTENT_LIMIT = 500 # Max characters for event content.
MAX_EVENTS_START_DATE = 10 # Max Events with the same start date.
LOCATION_LIMIT = 50 # Max characters for Location.
EVENT_DURATION_LIMIT = 2 # the max duration in days for an event.

# PATHS
STATIC_ABS_PATH = os.path.abspath("static")
Expand Down
79 changes: 67 additions & 12 deletions app/internal/import_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@

from app.config import (
EVENT_CONTENT_LIMIT,
EVENT_DURATION_LIMIT,
EVENT_HEADER_LIMIT,
EVENT_HEADER_NOT_EMPTY,
EVENT_VALID_YEARS,
LOCATION_LIMIT,
MAX_EVENTS_START_DATE,
MAX_FILE_SIZE_MB,
VALID_FILE_EXTENSION
Expand All @@ -22,12 +24,22 @@


DATE_FORMAT = "%m-%d-%Y"
DATE_FORMAT2 = "%m-%d-%Y %H:%M"
DESC_EVENT = "VEVENT"
EVENT_PATTERN = re.compile(r"^(\w{" + str(EVENT_HEADER_NOT_EMPTY) + "," +
str(EVENT_HEADER_LIMIT) + r"}),\s(\w{0," +
str(EVENT_CONTENT_LIMIT) +
r"}),\s(\d{2}-\d{2}-\d{4})," +
r"\s(\d{2}-\d{2}-\d{4})$")
r"\s(\d{2}-\d{2}-\d{4})(?:,\s([\w\s-]{0," +
str(LOCATION_LIMIT) +
r"}))?$")
EVENT_PATTERN2 = re.compile(r"^(\w{" + str(EVENT_HEADER_NOT_EMPTY) + "," +
str(EVENT_HEADER_LIMIT) + r"}),\s(\w{0," +
str(EVENT_CONTENT_LIMIT) +
r"}),\s(\d{2}-\d{2}-\d{4}\s\d{2}:\d{2})," +
r"\s(\d{2}-\d{2}-\d{4}\s\d{2}:\d{2})" +
r"(?:,\s([\w\s-]{0," + str(LOCATION_LIMIT) +
r"}))?$")


def is_file_size_valid(file: str, max_size: int = MAX_FILE_SIZE_MB) -> bool:
Expand All @@ -45,26 +57,54 @@ def is_file_exist(file: str) -> bool:
return Path(file).is_file()


def change_string_to_date(date: str) -> Union[datetime.datetime, bool]:
try:
if ":" in date:
date1 = datetime.datetime.strptime(date, DATE_FORMAT2)
else:
date1 = datetime.datetime.strptime(date, DATE_FORMAT)
except ValueError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of the except here?

Copy link
Contributor Author

@Nir-P Nir-P Feb 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the string is not a valid date datetime.strptime will fail to transform the string to date and we want to catch it.

return False
return date1


def is_date_in_range(date: Union[str, datetime.datetime],
valid_dates: int = EVENT_VALID_YEARS) -> bool:
"""
check if date is valid and in the range according to the rule we have set
"""
now_year = datetime.datetime.now().year
if isinstance(date, str):
try:
check_date = datetime.datetime.strptime(date, DATE_FORMAT)
except ValueError:
check_date = change_string_to_date(date)
if not check_date:
return False
else:
check_date = date
return now_year - valid_dates < check_date.year < now_year + valid_dates


def is_start_day_before_end_date(start: Union[datetime.datetime, str],
end: Union[datetime.datetime, str]) -> bool:
if isinstance(start, str):
start = change_string_to_date(start)
end = change_string_to_date(end)
return start <= end


def is_event_valid_duration(start: Union[datetime.datetime, str],
end: Union[datetime.datetime, str],
max_duration: int = EVENT_DURATION_LIMIT) -> bool:
if isinstance(start, str):
start = change_string_to_date(start)
end = change_string_to_date(end)
return (end - start).days < max_duration


def is_event_text_valid(row: str) -> bool:
"""Check if the row contains valid data"""
get_values = EVENT_PATTERN.search(row)
return get_values is not None
get_values2 = EVENT_PATTERN2.search(row)
return get_values is not None or get_values2 is not None


def is_file_valid_to_import(file: str) -> bool:
Expand Down Expand Up @@ -100,17 +140,29 @@ def open_txt_file(txt_file: str) -> Generator[str, None, None]:

def save_calendar_content_txt(event: str, calendar_content: List) -> bool:
"""populate calendar with event content"""
head, content, start_date, end_date = event.split(", ")
if len(event.split(", ")) == 5:
head, content, start_date, end_date, location = event.split(", ")
location = location.replace("\n", "")
else:
head, content, start_date, end_date = event.split(", ")
end_date = end_date.replace("\n", "")
location = None
if (not is_date_in_range(start_date) or
not is_date_in_range(end_date.replace("\n", ""))):
not is_date_in_range(end_date) or
not is_start_day_before_end_date(start_date, end_date) or
not is_event_valid_duration(start_date, end_date)):
return False
start_date = datetime.datetime.strptime(start_date, DATE_FORMAT)
end_date = datetime.datetime.strptime(end_date.replace("\n", ""),
DATE_FORMAT)
if re.search(r":", start_date) and re.search(r":", start_date):
start_date = datetime.datetime.strptime(start_date, DATE_FORMAT2)
end_date = datetime.datetime.strptime(end_date, DATE_FORMAT2)
else:
start_date = datetime.datetime.strptime(start_date, DATE_FORMAT)
end_date = datetime.datetime.strptime(end_date, DATE_FORMAT)
calendar_content.append({"Head": head,
"Content": content,
"S_Date": start_date,
"E_Date": end_date})
"E_Date": end_date,
"Location": location})
return True


Expand Down Expand Up @@ -149,7 +201,8 @@ def save_calendar_content_ics(component, calendar_content) -> None:
"S_Date": component.get('dtstart').dt
.replace(tzinfo=None),
"E_Date": component.get('dtend').dt
.replace(tzinfo=None)
.replace(tzinfo=None),
"Location": str(component.get('location'))
})


Expand All @@ -175,12 +228,14 @@ def save_events_to_database(events: List[Dict[str, Union[str, Any]]],
content = event["Content"]
start = event["S_Date"]
end = event["E_Date"]
location = event["Location"]
owner_id = user_id
create_event(db=session,
title=title,
content=content,
start=start,
end=end,
location=location,
owner_id=owner_id)


Expand Down
4 changes: 2 additions & 2 deletions tests/files_for_import_file_tests/sample.ics
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ BEGIN:VEVENT
SUMMARY:HeadA
DTSTART;TZID=America/New_York:20190802T103400
DTEND;TZID=America/New_York:20190802T110400
LOCATION:1000 Broadway Ave.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content1
STATUS:CONFIRMED
SEQUENCE:3
Expand All @@ -19,7 +19,7 @@ BEGIN:VEVENT
SUMMARY:HeadB
DTSTART;TZID=America/New_York:20190802T200000
DTEND;TZID=America/New_York:20190802T203000
LOCATION:900 Jay St.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content2
STATUS:CONFIRMED
SEQUENCE:3
Expand Down
4 changes: 2 additions & 2 deletions tests/files_for_import_file_tests/sample2.ics
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CALSCALE:GREGORIAN
SUMMARY:HeadA
DTSTART;TZID=America/New_York:20190802T103400
DTEND;TZID=America/New_York:20190802T110400
LOCATION:1000 Broadway Ave.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content1
STATUS:CONFIRMED
SEQUENCE:3
Expand All @@ -19,7 +19,7 @@ BEGIN:VEVENT
SUMMARY:HeadB
DTSTART;TZID=America/New_York:20190802T200000
DTEND;TZID=America/New_York:20190802T203000
LOCATION:900 Jay St.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content2
STATUS:CONFIRMED
SEQUENCE:3
Expand Down
4 changes: 2 additions & 2 deletions tests/files_for_import_file_tests/sample3.ics
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ BEGIN:VEVENT



LOCATION:1000 Broadway Ave.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content1
STATUS:CONFIRMED
SEQUENCE:3
Expand All @@ -19,7 +19,7 @@ BEGIN:VEVENT
SUMMARY:HeadB
DTSTART;TZID=America/New_York:20190802T200000
DTEND;TZID=America/New_York:20190802T203000
LOCATION:900 Jay St.\, Brooklyn
LOCATION:Tel-Aviv
DESCRIPTION:Content2
STATUS:CONFIRMED
SEQUENCE:3
Expand Down
3 changes: 3 additions & 0 deletions tests/files_for_import_file_tests/sample_date2_ver.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Option1, Content1, 05-21-2019 10:30, 05-21-2019 11:30
Option2, Content2, 01-11-2010 11:30, 01-11-2010 12:30
Option3, Content3, 02-02-2022 13:00, 02-02-2022 13:05
3 changes: 3 additions & 0 deletions tests/files_for_import_file_tests/sample_date_mix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Option1, Content1, 05-21-2019, 05-21-2019 11:30
Option2, Content2, 01-11-2010 11:30, 01-11-2010 12:30
Option3, Content3, 02-02-2022 13:00, 02-02-2022 13:05
3 changes: 3 additions & 0 deletions tests/files_for_import_file_tests/‏‏sample_loc_ver.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Option1, Content1, 05-21-2019 10:30, 05-21-2019 11:30, aaa
Option2, Content2, 01-11-2010 11:30, 01-11-2010 12:30, bbb
Option3, Content3, 02-02-2022 13:00, 02-02-2022 13:05, ccc
Loading