import datetime, json from typing import Dict, List, Optional, Set, Union from pydantic import BaseModel, EmailStr, Field, PrivateAttr, ValidationError, validator from app.db_sql import redis_lookup_id_random, sql_delete, sql_insert, sql_select, sql_update, sql_enable_part, sql_limit_offset_part from app.lib_general import log, logging, logger_reset # from app.methods.event_abstract_tracking_methods import get_event_abstract_tracking_rec_list, load_event_abstract_tracking_obj from app.methods.event_person_methods import load_event_person_obj from app.models.common_field_schema import default_num_bytes from app.models.event_abstract_models import Event_Abstract_Ext, Event_Abstract_In # ### BEGIN ### API Event Abstract Methods ### load_event_abstract_obj() ### # Updated 2023-03-20 @logger_reset def load_event_abstract_obj( event_abstract_id: int|str, enabled: str = 'enabled', # enabled, disabled, all approved: str = 'all', # approved, not_approved, all hidden: str = 'not_hidden', # hidden, not_hidden, all review: str = 'all', # ready, not_ready, all inc_event_file_list: bool = False, inc_event_person: bool = False, inc_event_person_profile: bool = False, inc_event_presentation_list: bool = False, inc_event_presenter_list: bool = False, inc_hosted_file: bool = False, limit: int = 1500, offset: int = 0, by_alias: bool = True, exclude_unset: bool = True, model_as_dict: bool = False, ) -> Event_Abstract_Ext|dict|bool: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) # if event_abstract_id := redis_lookup_id_random(record_id_random=event_abstract_id, table_name='event_abstract'): pass # else: return False if event_abstract_rec := sql_select(table_name='v_event_abstract', record_id=event_abstract_id): pass else: return False try: event_abstract_obj = Event_Abstract_Ext(**event_abstract_rec) log.debug(event_abstract_obj) except ValidationError as e: log.error(e.json()) return False # Updated 2023-03-20 if inc_event_file_list: # log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.info('Need to include event file list...') from app.methods.event_file_methods import get_event_file_rec_list, load_event_file_obj if event_file_rec_list_result := get_event_file_rec_list( for_type = 'event_abstract', for_id = event_abstract_id, # file_purpose_id = event_file_file_purpose_id, # file_purpose = event_file_file_purpose, # priority = event_file_priority, # group = event_file_group, enabled = enabled, limit = limit, ): event_file_result_list = [] for event_file_rec in event_file_rec_list_result: if load_event_file_result := load_event_file_obj( event_file_id = event_file_rec.get('event_file_id', None), enabled = enabled, inc_hosted_file = inc_hosted_file, # model_as_dict = True, # by_alias = by_alias, # exclude_unset = False, ): event_file_result_list.append(load_event_file_result) else: event_file_result_list.append(None) log.debug(event_file_result_list) event_abstract_obj.event_file_list = event_file_result_list elif isinstance(event_file_rec_list_result, list): event_abstract_obj.event_file_list = [] else: event_abstract_obj.event_file_list = None # Updated 2023-03-20 if inc_event_person: # log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.info('Need to include event person...') if event_person_obj := load_event_person_obj( event_person_id = event_abstract_obj.event_person_id, enabled = enabled, # inc_address = inc_address, # inc_contact = inc_contact, # inc_event_abstract = inc_event_abstract, inc_event_person_profile = inc_event_person_profile, # inc_event_registration = inc_event_registration, # inc_person = inc_person, # inc_user = inc_user, ): log.debug(event_person_obj) event_abstract_obj.event_person = event_person_obj else: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(event_person_obj) event_abstract_obj.event_person = None log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL # Updated 2023-03-20 if inc_event_presenter_list: log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.info('Need to include Event Presenter List data...') if event_presenter_rec_list_result := get_event_presenter_rec_list( event_abstract_id = event_abstract_id, limit = limit, enabled = enabled, hidden = hidden, ): event_presenter_result_list = [] for event_presenter_rec in event_presenter_rec_list_result: event_presenter_result_list.append( load_event_presenter_obj( event_presenter_id = event_presenter_rec.get('event_presenter_id'), inc_event_person = inc_event_person, ) ) event_abstract_obj.event_abstract_list = event_abstract_result_list else: event_abstract_obj.event_abstract_list = [] # log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL if model_as_dict: return event_abstract_obj.dict(by_alias=by_alias, exclude_unset=exclude_unset) # pylint: disable=no-member else: return event_abstract_obj # ### END ### API Event Abstract Methods ### load_event_abstract_obj() ### # ### BEGIN ### API Event Abstract Methods ### get_event_abstract_rec_list() ### # Updated 2023-03-20 @logger_reset def get_event_abstract_rec_list( event_id: None|str = None, event_person_id: None|str = None, abstract_type_code: str = None, # not sure yet approved: str = 'all', # not_approved, approved, all enabled: str = 'enabled', # enabled, disabled, all limit: int = 250, offset: int = 0, ) -> list|bool: log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): pass elif event_id is None: pass else: return False if event_person_id := redis_lookup_id_random(record_id_random=event_person_id, table_name='event_person'): pass elif event_person_id is None: pass else: return False data = {} # data['event_id'] = event_id if event_id: data['event_id'] = event_id sql_event_id = f'`event_abstract`.event_id = :event_id' else: sql_event_id = '1=1' if event_person_id: data['event_person_id'] = event_person_id sql_event_person_id = f'AND `event_abstract`.event_person_id = :event_person_id' else: sql_event_person_id = '' if abstract_type_code: data['abstract_type_code'] = abstract_type_code sql_abstract_type_code = f'AND `event_abstract`.abstract_type_code = :abstract_type_code' else: sql_abstract_type_code = '' if approved in ['not_approved', 'approved', 'all']: log.info(f'Creating partial SQL string for "approved" check. Printed: {approved}') if approved == 'not_approved': sql_abstract_approved = f'AND (`event_abstract`.approve IS NULL OR `event_abstract`.approved = FALSE)' elif approved == 'approved': sql_abstract_approved = f'AND `event_abstract`.approve = TRUE' elif approved == 'all': sql_abstract_approved = f'AND (`event_abstract`.approve IS NULL OR `event_abstract`.approve IS NOT NULL)' log.debug(sql_abstract_approved) else: sql_abstract_approved = '' sql_enabled, data['enable'] = sql_enable_part(table_name='event_abstract', enabled=enabled) # Reasonably safe return str and bool sql_limit = sql_limit_offset_part(limit=limit, offset=offset) # Reasonably safe return str sql = f""" SELECT `event_abstract`.id AS 'event_abstract_id', `event_abstract`.id_random AS 'event_abstract_id_random' FROM `v_event_abstract` AS `event_abstract` WHERE {sql_event_id} {sql_event_person_id} {sql_abstract_type_code} {sql_abstract_approved} {sql_enabled} ORDER BY event_abstract.priority DESC, event_abstract.sort DESC, event_abstract.name ASC, `event_abstract`.created_on DESC, `event_abstract`.updated_on DESC {sql_limit}; """ log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(sql) if event_abstract_rec_li_result := sql_select(data=data, sql=sql, as_list=True): event_abstract_rec_li = event_abstract_rec_li_result else: # [] or False event_abstract_rec_li = event_abstract_rec_li_result log.debug(event_abstract_rec_li_result) return event_abstract_rec_li # ### END ### API Event Abstract Methods ### get_event_abstract_rec_list() ### # ### BEGIN ### API Event Abstract Methods ### create_update_event_abstract_obj() ### # Updated 2023-03-22 @logger_reset def create_update_event_abstract_obj( event_abstract_obj: Event_Abstract_In, event_abstract_id: int = None, event_id: int = None, event_person_id: int = None, create_sub_obj: bool = False, fail_any: bool = False, # Fail if any thing goes wrong for sub objects return_outline: bool = False, ) -> int|bool: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info('Checking requirements...') if event_abstract_id: log.info(f'Got: event_abstract_id={event_abstract_id}; Update existing Event Abstract') event_abstract_obj.id = event_abstract_id elif event_id and event_person_id: log.info(f'Got: event_id={event_id}; event_person_id={event_person_id}; Create Event Abstract') event_abstract_obj.event_id = event_id event_abstract_obj.event_person_id = event_person_id else: return False log.debug(type(event_abstract_obj)) log.debug(event_abstract_obj ) event_abstract_dict = event_abstract_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'event_file_list', 'event_person', 'event_person_list', 'event_presenter_list', 'created_on', 'updated_on'}) # log.debug(type(event_abstract_dict.get('topics_json', None))) # if 'topics_json' in event_abstract_dict and (isinstance(event_abstract_dict['topics_json'], dict) or isinstance(event_abstract_dict['topics_json'], list)): # log.debug('Need to convert to JSON string') # event_abstract_dict['topics_json'] = json.dumps(event_abstract_dict['topics_json']) # log.debug(event_abstract_dict) if event_abstract_id: if event_abstract_dict_up_result := sql_update(data=event_abstract_dict, table_name='event_abstract', rm_id_random=True): log.info(f'Event Abstract updated. event_abstract_id={event_abstract_id}') pass else: log.warning(f'Event Abstract not updated. event_abstract_id={event_abstract_id}') log.debug(event_abstract_dict_up_result) return False log.debug(event_abstract_dict_up_result) else: if event_abstract_dict_in_result := sql_insert(data=event_abstract_dict, table_name='event_abstract', rm_id_random=True, id_random_length=None): log.info(f'Event Abstract created. event_abstract_id={event_abstract_dict_in_result}') else: log.warning(f'Event Abstract not created.') log.debug(event_abstract_dict_in_result) return False log.debug(event_abstract_dict_in_result) event_abstract_id = event_abstract_dict_in_result # False, None, integer event_abstract_outline = {} event_abstract_outline['event_id'] = event_id event_abstract_outline['event_abstract_id'] = event_abstract_id event_abstract_outline['event_person_id'] = event_person_id # event_abstract_outline['event_file_count'] = event_file_count if return_outline: log.debug(f'Returning the Event Abstract Outline: {event_abstract_outline}') return event_abstract_outline else: log.debug(f'Returning the Event Abstract ID: {event_abstract_id}') return event_abstract_id # ### END ### API Event Abstract Methods ### create_update_event_abstract_obj() ### # ### BEGIN ### API Event Abstract Methods ### create_update_event_abstract_obj_old() ### # Updated 2023-03-20 @logger_reset def create_update_event_abstract_obj_old( event_abstract_dict_obj: Event_Abstract_In|dict, event_abstract_id: int|str = None, event_id: int|str = None, event_person_id: int|str = None, create_sub_obj: bool = False, fail_any: bool = False, # Fail if any thing goes wrong for sub objects return_outline: bool = False, ) -> int|bool: log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(locals()) log.info('Checking requirements...') if event_abstract_id: log.info(f'Event Abstract ID passed. Update existing Event Abstract. Event Abstract ID: {event_abstract_id}') if event_abstract_id := redis_lookup_id_random(record_id_random=event_abstract_id, table_name='event_abstract'): pass else: log.error('Event Abstract ID passed but is invalid. Failed requirement.') return False if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): log.info(f'Event ID: {event_id}') elif event_id is None: log.error('Missing Event ID. Not required. Ignoring.') log.info(f'Event ID: {event_id}') else: log.error('Invalid Event ID passed. Not required. But not ignoring since it is likely invalid.') log.info(f'Event ID: {event_id}') return False else: log.info('No Event Abstract ID passed. Create new Event Abstract. Required: Event ID') if event_id := redis_lookup_id_random(record_id_random=event_id, table_name='event'): log.info(f'Event ID: {event_id}') elif event_id is None: log.error('Missing Event ID. Failed requirement.') log.info(f'Event ID: {event_id}') return False else: log.error('Invalid Event ID passed. Failed requirement.') log.info(f'Event ID: {event_id}') return False # else: # log.error('Missing or invalid Event ID passed. Failed requirement.') # log.info(f'Event ID: {event_id}') # return False log.debug(type(event_abstract_dict_obj)) if isinstance(event_abstract_dict_obj, dict): event_abstract_dict = event_abstract_dict_obj if event_abstract_id: event_abstract_dict['event_abstract_id'] = event_abstract_id if event_id: event_abstract_dict['event_id'] = event_id if event_person_id: event_abstract_dict['event_person_id'] = event_person_id try: event_abstract_obj = Event_Abstract_In(**event_abstract_dict) log.setLevel(logging.DEBUG) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL log.debug(event_abstract_obj) except ValidationError as e: log.error(e.json()) return False else: event_abstract_obj = event_abstract_dict_obj if event_abstract_id: # NOTE: Can't update the ID alias if it was never set. event_abstract_obj.id = event_abstract_id if event_id: event_abstract_obj.event_id = event_id if event_person_id: event_abstract_obj.event_person_id = event_person_id event_abstract_dict = event_abstract_obj.dict(by_alias=False, exclude_defaults=False, exclude_unset=True, exclude={'event_person', 'event_person_list', 'created_on', 'updated_on'}) if event_abstract_id: if event_abstract_dict_up_result := sql_update(data=event_abstract_dict, table_name='event_abstract', rm_id_random=True): pass else: log.warning(f'Event Abstract not updated. Event Abstract ID: {event_abstract_id}') log.debug(event_abstract_dict_up_result) return False log.debug(event_abstract_dict_up_result) else: if event_abstract_dict_in_result := sql_insert(data=event_abstract_dict, table_name='event_abstract', rm_id_random=True, id_random_length=None): pass else: log.warning(f'Event Abstract not created.') log.debug(event_abstract_dict_in_result) return False log.debug(event_abstract_dict_in_result) event_abstract_id = event_abstract_dict_in_result event_abstract_outline = {} event_abstract_outline['event_id'] = event_id event_abstract_outline['event_abstract_id'] = event_abstract_id event_abstract_outline['event_person_id'] = event_person_id # event_abstract_outline['event_presenter_list'] = [] # if event_abstract_obj.event_presenter_list and isinstance(event_abstract_obj.event_presenter_list, list): # log.info(f'Event Presenter List was found. Loop through and create a new Event Presenter for each and link them to the new Event Abstract. Event Abstract ID: {event_abstract_id}') # for event_presenter_obj in event_abstract_obj.event_presenter_list: # # NOTE: Use object model version because of better type checking and validations # log.debug(event_presenter_obj) # if event_presenter_id := event_presenter_obj.id: pass # else: event_presenter_id = None # # event_presenter_obj.event_id = event_id # # event_presenter_obj.event_session_id = event_session_id # create_update_event_presenter_obj_result = create_update_event_presenter_obj_v4( # event_presenter_dict_obj = event_presenter_obj, # event_presenter_id = event_presenter_id, # event_id = event_id, # event_session_id = event_session_id, # event_abstract_id = event_abstract_id, # fail_any = fail_any, # return_outline = return_outline, # ) # if isinstance(create_update_event_presenter_obj_result, int): # event_presenter_id = create_update_event_presenter_obj_result # elif create_update_event_presenter_obj_result == True: pass # else: # log.warning(f'Create or Update failed while trying create_update_event_presenter_obj_v4(): {create_update_event_presenter_obj_result}') # event_presenter_id = None # event_abstract_outline['event_presenter_id'] = event_presenter_id if return_outline: log.debug(f'Returning the Event Abstract Outline: {event_abstract_outline}') return event_abstract_outline else: log.debug(f'Returning the Event Abstract ID: {event_abstract_id}') return event_abstract_id # ### END ### API Event Abstract Methods ### create_update_event_abstract_obj_old() ### # ### BEGIN ### API Event Abstract Methods ### remove_event_abstract_obj() ### # Updated 2023-03-22 @logger_reset def remove_event_abstract_obj( event_abstract_id: int, method: None|str = None, log_lvl: int = logging.DEBUG, # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL ) -> bool|None: log.setLevel(log_lvl) if method is None or method == 'disable': data = {'enable': False} if event_abstract_dict_up_result := sql_update( table_name = 'event_abstract', record_id = event_abstract_id, data = data, log_lvl = log_lvl, ): log.info(f'Event Abstract was disabled.') return True else: log.warning(f'Event Abstract not disabled.') return event_abstract_dict_up_result # False or None elif method == 'delete': if event_abstract_dict_del_result := sql_delete( table_name = 'event_abstract', record_id = event_abstract_id, log_lvl = log_lvl, ): log.info(f'Event Abstract was deleted.') return True else: log.warning(f'Event Abstract not deleted.') return event_abstract_dict_del_result # False or None elif method == 'hide': data = {'hide': True} if event_abstract_dict_up_result := sql_update( table_name = 'event_abstract', record_id = event_abstract_id, data = data, log_lvl = log_lvl, ): log.info(f'Event Abstract was hidden.') return True else: log.warning(f'Event Abstract not hidden.') return event_abstract_dict_up_result # False or None else: log.error('We should not be here. Something went wrong in remove_event_abstract_obj()!') return False # ### END ### API Event Abstract Methods ### remove_event_abstract_obj() ###