Includes: - Odoo 19 framework (odoo/) - 27 custom EnCoach addons (new_project/custom_addons/) - encoach_core, encoach_api, encoach_lms_api, encoach_adaptive_api - encoach_exam, encoach_taxonomy, encoach_adaptive, encoach_assignment - encoach_ai, encoach_ai_grading, encoach_ai_generation, encoach_ai_media - encoach_courseware, encoach_communication, encoach_subscription - encoach_notification, encoach_approval, encoach_branding - encoach_classroom, encoach_registration, encoach_stats - encoach_faq, encoach_ticket, encoach_training, encoach_resources - encoach_adaptive_ai, encoach_sis - 21 OpenEduCat Enterprise modules (new_project/enterprise-19/) - 14 OpenEduCat Community modules (new_project/openeducat_erp-19.0/) - Configuration: odoo.conf, requirements.txt, scripts - 200+ REST API endpoints with JWT authentication - SRS and test documentation Made-with: Cursor
79 lines
2.1 KiB
Python
79 lines
2.1 KiB
Python
import re
|
|
from datetime import datetime, timedelta
|
|
|
|
import pytz
|
|
|
|
strftime_to_spreadsheet_time_format_table = {
|
|
"%H": "hh",
|
|
"%I": "hh",
|
|
"%M": "mm",
|
|
"%S": "ss",
|
|
}
|
|
|
|
strftime_to_spreadsheet_dateformat_table = {
|
|
"%Y": "yyyy",
|
|
"%y": "yy",
|
|
"%m": "mm",
|
|
"%b": "mmm",
|
|
"%B": "mmmm",
|
|
"%d": "dd",
|
|
"%a": "ddd",
|
|
"%A": "dddd",
|
|
}
|
|
|
|
|
|
def strftime_format_to_spreadsheet_time_format(strf_format):
|
|
"""Convert a strftime format to a spreadsheet time format.
|
|
"""
|
|
|
|
twelve_hour_system = False
|
|
parts = []
|
|
for part in re.finditer(r"(%.)", strf_format):
|
|
symbol = part.group(1)
|
|
spreadsheet_symbol = strftime_to_spreadsheet_time_format_table.get(symbol)
|
|
if spreadsheet_symbol:
|
|
parts.append(spreadsheet_symbol)
|
|
if symbol == "%I" or symbol == "%p":
|
|
twelve_hour_system = True
|
|
|
|
separator = re.search(r"(:| )", strf_format)
|
|
separator = separator.group(1) if separator else ":"
|
|
|
|
return separator.join(parts) + (" a" if twelve_hour_system else "")
|
|
|
|
|
|
def strftime_format_to_spreadsheet_date_format(strf_format):
|
|
"""Convert a strftime format to a spreadsheet date format.
|
|
"""
|
|
parts = []
|
|
for part in re.finditer(r"(%.)", strf_format):
|
|
symbol = part.group(1)
|
|
spreadsheet_symbol = strftime_to_spreadsheet_dateformat_table.get(symbol)
|
|
if spreadsheet_symbol:
|
|
parts.append(spreadsheet_symbol)
|
|
|
|
separator = re.search(r"(/|-| )", strf_format)
|
|
separator = separator.group(1) if separator else "/"
|
|
|
|
return separator.join(parts)
|
|
|
|
|
|
INITIAL_1900_DAY = datetime(1899, 12, 30)
|
|
SECONDS_PER_DAY = 24 * 60 * 60
|
|
|
|
|
|
def datetime_to_spreadsheet_date_number(dt, tz_name):
|
|
context_tz = pytz.timezone(tz_name)
|
|
localized_datetime = dt.astimezone(context_tz)
|
|
offset = localized_datetime.utcoffset() / timedelta(seconds=1)
|
|
timestamp = dt.timestamp() + offset
|
|
|
|
delta = timestamp - INITIAL_1900_DAY.timestamp()
|
|
return delta / SECONDS_PER_DAY
|
|
|
|
|
|
def date_to_spreadsheet_date_number(d):
|
|
dt = datetime.combine(d, datetime.min.time())
|
|
delta = dt.timestamp() - INITIAL_1900_DAY.timestamp()
|
|
return delta / SECONDS_PER_DAY
|