def process_arxiv_url(url: str) -> Tuple[str]: def get_paper_id_from_url(url) -> str: while "/" in url: slash_idx = url.find("/") url = url[slash_idx + 1:] if url.endswith(".pdf"): return url[:-4] else: return url if "arxiv.org/abs" in url: ## abstract page paper_id = get_paper_id_from_url(url) paper_url = url pdf_url = f"https://arxiv.org/pdf/{paper_id}.pdf" return paper_id, paper_url, pdf_url elif "arxiv.org/pdf" in url: ## pdf page paper_id = get_paper_id_from_url(url) paper_url = f"https://arxiv.org/abs/{paper_id}" pdf_url = url return paper_id, paper_url, pdf_url else: logger.error("Unexpected URL Error by arxiv URL Handler.") raise Exception("Unexpected URL Error by arxiv URL Handler.")
async def get_all_student_info( username=Depends(auth_handler.auth_wrapper), num: int = 30): """ Get all student info Require: Admin-read """ logger.debug(f"User({username}) trying fetching all students info.") permission_ok: bool = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) student_info_list = [] count = 0 try: for student_info in students_collection.find(): count += 1 clean_dict(student_info) student_info_list.append(student_info) if count >= num: break except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return student_info_list
async def get_an_application_period(uid: str, username=Depends( auth_handler.auth_wrapper)): """ Get an Application Period Require: Admin-read """ logger.debug( f"User({username}) requested to get ApplicationPeriod({uid}).") permission_ok = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: ap_info = application_periods_collection.find_one(filter={"uid": uid}) clean_dict(ap_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if ap_info: ap_info["applicable_periods"] = convert_to_applicable_periods( ap_info["applicable_periods"]) return ap_info else: raise HTTPException(status_code=404, detail=MSG.ITEM_NOT_FOUND)
async def create_an_event(new_event: Event, username=Depends(auth_handler.auth_wrapper)): """ Create an Event Require: Student-HG or Admin-write """ logger.debug(f"User({username}) trying creating new Event.") # Check access permission_ok = Access.at_least_student_hg_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) new_event.created_by = str(username) event_dict = dict(new_event.dict()) try: _inserted_id = events_collection.insert_one(event_dict).inserted_id logger.debug( f"New Event inserted to DB with inserted_id: {_inserted_id}") _event = events_collection.find_one({"_id": _inserted_id}) clean_dict(_event) logger.debug(f"New Event info: {_event}") return _event except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR)
async def get_a_student_info(student_id: str, username=Depends(auth_handler.auth_wrapper)): """ Set a particular Student info Require: Student-self or Admin-read """ logger.debug( f"User({username}) trying fetching student({student_id}) info.") permission_ok = False if student_id == username or Access.is_admin(username): permission_ok = True if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: student_info = students_collection.find_one({"student_id": student_id}) clean_dict(student_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if student_info: logger.debug(f"student_info: {student_info}") return student_info else: raise HTTPException(status_code=404, detail=MSG.ITEM_NOT_FOUND)
async def login(auth_details: User): try: user = users_collection.find_one({"username": auth_details.username}) except Exception as e: logger.error("Failed to query user from database.") logger.error(e) raise HTTPException(status_code=500, detail="Databse Error.") if not user or not auth_handler.verify_password(auth_details.password, user["password"]): raise HTTPException(status_code=401, detail="Invalid username and/or password") token = auth_handler.encode_token(auth_details.username) logger.debug( f"New JWT token generated for user: '******'") is_student = Access.is_student(auth_details.username) is_student_hg = Access.is_student_hg(auth_details.username) is_admin = Access.is_admin(auth_details.username) is_admin_write = Access.is_admin_write(auth_details.username) return { "token": token, "is_student": is_student, "is_student_hg": is_student_hg, "is_admin": is_admin, "is_admin_write": is_admin_write, }
def url_MsgHandler(update, context): # context.bot.send_message(chat_id=update.effective_chat.id, text=update.message.text) try: url_received = update.message.text if "arxiv" in url_received: logger.debug("URL identified: arXiv") paper = get_paper(url_received) msg = "*Paper*: {}\n\n*Author*: {}\n\n*PDF*: {}".format( paper.title, paper.first_author, paper.pdf_url) user = get_current_telegram_user(update) add_paper_to_user(paper, user) elif "openaccess.thecvf.com" in url_received: logger.debug("URL identified: CVPR Open Access") msg = "CVPR Open Access (in development)" else: msg = "Currently only arxiv paper url is supported." except Exception as err: logger.error(err) msg = "Internal Server Error" # msg = telegram.utils.helpers.escape_markdown(msg) # respond to user update.message.reply_text(msg, parse_mode=telegram.ParseMode.MARKDOWN) user_log(update, remarks="respond_paper_info_from_url")
def student_update_application_form_status( AF_uid: str, username: str, new_status: str, pre_status: List[str] ) -> dict: # Check access 1 permission_ok = False if Access.is_student(username) or Access.is_admin_write(username): permission_ok = True if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) # Check access 2: check if the application belongs to student if Access.is_student(username): try: student_info = students_collection.find_one({"student_id": username}) clean_dict(student_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) student_application_uids = student_info.get("application_uids", []) if AF_uid not in student_application_uids: raise HTTPException(status_code=400, detail=MSG.NOT_YOUR_AF) _updated = update_application_form_both_status(AF_uid, new_status, pre_status) return _updated
async def get_an_application_info( uid: str, username=Depends(auth_handler.auth_wrapper) ): """ Get an ApplicationForm info Require: Student-self or Admin-read """ # Special case, check permission after getting item from DB logger.debug(f"User({username}) fetching record({uid}) info") try: application_dict: dict = applications_collection.find_one({"uid": uid}) clean_dict(application_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if not application_dict: raise HTTPException(status_code=404, detail=MSG.ITEM_NOT_FOUND) # Student-self can access DisciplinaryRecord issued to himself/herself. application_owner = application_dict.get("student_id", "") permission_ok = Access.is_admin(username) permission_ok = True if username == application_owner else permission_ok if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) return application_dict
async def create_new_application_period(ap: ApplicationPeriod, username=Depends( auth_handler.auth_wrapper)): """ Create an ApplicationPeriod Require: Admin-write """ permission_ok = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) ap.created_by = str(username) ap_dict = dict(ap.dict()) ap_dict["applicable_periods"] = convert_from_applicable_periods( ap.applicable_periods) try: _inserted_id = application_periods_collection.insert_one( ap_dict).inserted_id logger.debug( f"New ApplicationPeriod inserted to DB with inserted_id: {_inserted_id}" ) logger.debug(f"New ApplicationPeriod info: {ap_dict}") return ap_dict except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR)
async def get_active_application_periods(username=Depends( auth_handler.auth_wrapper)): """ Get Active (currently open) Application Periods Require: Any authenticated user """ logger.debug(f"User({username}) fetching active ApplicationPeriods") ap_list = [] _now = datetime.now() try: for ap_dict in application_periods_collection.find({ "application_window_open": { "$lt": _now }, "application_window_close": { "$gte": _now }, }).sort("application_window_open"): clean_dict(ap_dict) ap_dict["applicable_periods"] = convert_to_applicable_periods( ap_dict["applicable_periods"]) ap_list.append(ap_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return ap_list
async def get_all_application_periods(username=Depends( auth_handler.auth_wrapper)): """ Get ALL Application Periods Require: Admin-read """ logger.debug(f"User({username}) fetching ALL ApplicationPeriods.") permission_ok = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) ap_list = [] try: for ap_dict in application_periods_collection.find().sort( "created_by", DESCENDING): clean_dict(ap_dict) ap_dict["applicable_periods"] = convert_to_applicable_periods( ap_dict["applicable_periods"]) ap_list.append(ap_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return ap_list
async def get_all_disciplinary_record(username=Depends( auth_handler.auth_wrapper)): """ Get all Disciplinary Records Require: Admin-read """ logger.debug(f"User({username}) fetching all records info") permission_ok: bool = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) records_list = [] try: for record in records_collection.find(): clean_dict(record) records_list.append(record) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return records_list
async def update_disciplinary_record( uid: str, record_edit: RecordEditable, username=Depends(auth_handler.auth_wrapper), ): """ Update a DisciplinaryRecord Require: Admin-write """ logger.debug(f"{username} trying to update a DisciplinaryRecord({uid})") permission_ok = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) record_dict = dict(record_edit.dict()) remove_none_value_keys(record_dict) try: updated = records_collection.find_one_and_update( filter={"uid": uid}, update={"$set": record_dict}, return_document=ReturnDocument.AFTER, ) clean_dict(updated) except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) if updated: logger.debug(f"Updated: {updated}") return updated else: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND)
def get_event_list(ics_path: str) -> List[List[str]]: ics_path = Path(ics_path) if not ics_path.is_file(): logger.error("File does not exist.") with ics_path.open() as f: lines = f.readlines() reading_event: bool = False event_list: List[List[str]] = [] current_event_lines: List[str] = [] for line in lines: line: str = line.strip() if line.startswith("BEGIN:VEVENT"): reading_event = True if reading_event: current_event_lines.append(line) if line.startswith("END:VEVENT"): reading_event = False event_list.append(fix_broken_lines(current_event_lines)) # reset current_event_lines = [] return event_list
async def revoke_a_student_as_hg(student_id: str, username=Depends(auth_handler.auth_wrapper)): """ Revoke a Student as House Guardian Require: Admin-write """ permission_ok = False if Access.is_admin_write(username): permission_ok = True if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: updated = students_collection.find_one_and_update( filter={"student_id": student_id}, update={"$set": { "is_house_guardian": False }}, return_document=ReturnDocument.AFTER, ) logger.debug(f"{str(updated)}") clean_dict(updated) except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) if updated: logger.debug(f"Updated: {updated}") return updated else: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND)
def generate_video_list(video_folder: str): """ get metadata of all videos inside a video_folder, and write to `video_metadata_lst.json` and save it to the video_folder existing `video_metadata_lst.json` inside the target folder will be overwritten """ video_folder = Path(video_folder) if not video_folder.is_dir(): raise ValueError(f"'{dir}' is not a valid path to a folder.") video_list: list = [] for file in os.listdir(video_folder): logger.debug(file) video_filepath = os.path.join(video_folder, file) if os.path.isfile(video_filepath): try: video_metadata: dict = get_video_metadata(video_filepath) video_list.append(video_metadata) except Exception as err: logger.error(f"Error for {video_filepath}: {err}") continue # sort video list by video name alphabetically video_list = sorted(video_list, key=lambda x: x["filename"]) print(f"\nTotal number of videos: {len(video_list)}\n") export_filepath = video_folder / "video_metadata_lst.json" with export_filepath.open(mode="w") as f: f.write(json.dumps(video_list, indent=4))
async def update_a_student_identity( student_id: str, student_identity_profile: StudentIdentityProfile, username=Depends(auth_handler.auth_wrapper), ): logger.debug( f"User({username}) trying to update Student({student_id})'s identity profile." ) permission_ok = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) identity_dict = dict(student_identity_profile.dict()) remove_none_value_keys(identity_dict) try: updated = students_collection.find_one_and_update( filter={"student_id": student_id}, update={"$set": identity_dict}, return_document=ReturnDocument.AFTER, ) clean_dict(updated) except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) if updated: logger.debug(f"Updated: {updated}") return updated else: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND)
def get_video_metadata(video_path: str) -> dict: # check if the file exist video_path = Path(video_path) if not video_path.is_file(): logger.error(f"Invalid video_path: `{video_path}` does not exist.") raise Exception("Invalid video_path: file does not exist.") # check if it is a video file known_video_formats = (".mp4", ".flv", ".mov", ".avi", ".wmv", ".mkv") video_path_obs = video_path.resolve() head, tail = os.path.split(video_path_obs) name, ext = os.path.splitext(tail) if ext not in known_video_formats: logger.warning( f"Invalid video_path: `{tail}` is not a known video format.") raise Exception( f"Invalid video_path: `{tail}` is not a known video format.") command_template = "ffprobe -v error -select_streams v:0 -show_entries stream=width,height,avg_frame_rate,duration -of json" args = shlex.split(command_template) args.append(str(video_path)) proc = subprocess.Popen(args, stdout=subprocess.PIPE) out: bytes = proc.communicate()[0] json_string: str = out.decode("utf-8").strip() # logger.debug(json_string) json_obj: dict = json.loads(json_string) streams: list = json_obj.get("streams", []) if len(streams) == 1: _data = streams[0] elif len(streams) == 0: raise Exception() else: _data: dict = streams[0] logger.info(f"More than one stream is found at {video_path}") width: int = _data.get("width") height: int = _data.get("height") ratio = width / height avg_frame_rate: str = _data.get("avg_frame_rate") frame_rate: int = round(eval(avg_frame_rate)) if avg_frame_rate else None duration: float = round(float(_data.get("duration")), 2) video_metadata: dict = { "filepath": str(video_path_obs), "filename": name, "ext": ext, "width": width, "height": height, "ratio": ratio, # width / height "duration": duration, # in number of seconds "fps": frame_rate, # frame per seconds "avg_frame_rate": avg_frame_rate, } # logger.debug(json.dumps(video_metadata, indent=4)) return video_metadata
async def get_list_of_events(event_uids: List[str], username=Depends(auth_handler.auth_wrapper)): """ Get a list of Events for a given list of Event UIDs. If one or more provided uid(s) do not exist, it will be ignored. Require: Any authenticated user """ logger.debug(f"User({username}) fetching a list of events info") event_info_list: List[dict] = [] event_uids = list(set(event_uids)) try: for uid in event_uids: if isinstance(uid, str): event_dict: dict = events_collection.find_one({"uid": uid}) if event_dict: clean_dict(event_dict) event_info_list.append(event_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return event_info_list
async def add_room(new_room: Room, username=Depends(auth_handler.auth_wrapper)): """ Add a new Room to database Require: Admin-write """ logger.debug(f"User({username}) trying add new Room.") permission_ok: bool = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) room_dict = dict(new_room.dict()) try: _inserted_id = rooms_collection.insert_one(room_dict).inserted_id logger.debug(f"New Room inserted to DB with inserted_id: {_inserted_id}") except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) clean_dict(room_dict) logger.debug(f"New Room info: {room_dict}") return room_dict
def parse_single_event(event_lines: List[str]) -> Dict[str, str]: if event_lines[0] == "BEGIN:VEVENT" and event_lines[-1] == "END:VEVENT": event_lines = event_lines[1:-1] else: logger.error("Invalid Event") return event = OrderedDict({ "SUMMARY": None, "DESCRIPTION": None, "LOCATION": None, "DTSTART": None, "DTEND": None, "UID": None, "RRULE": None, "EXDATE": None, }) for line in event_lines: colon_index = line.find(":") key = line[:colon_index] if key not in event: continue line_value = line[colon_index + 1:] # timezone fix if key == "DTSTART" or key == "DTEND" or key == "EXDATE": event[key + ";TZID=Asia/Singapore"] = line_value elif key == "RRULE": # TODO: convert UNTIL field to GMT (add Z ad the back as well) # see: https://www.kanzaki.com/docs/ical/recur.html event[key] = line_value else: event[key] = line_value # correct summary original_summary = event.get("SUMMARY") logger.info(original_summary) if original_summary: room_index = original_summary.find("ROOM:") if room_index != -1: location_value = original_summary[room_index + 5:] event["LOCATION"] = location_value.strip() original_summary = original_summary[:room_index] chop_index = original_summary.find(":") if chop_index != -1: chopped = original_summary[:chop_index - 2] event["SUMMARY"] = chopped.strip() if event.get("SUMMARY") == event.get("DESCRIPTION"): event.pop("DESCRIPTION") unused = [] for key in event.keys(): if not event.get(key): unused.append(key) for key in unused: event.pop(key) return event
def is_admin_write(username: str) -> bool: try: admin_info: dict = admins_collection.find_one( {"username": username}) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if admin_info and admin_info.get("read_only", True) == False: return True return False
def is_student_hg(username: str) -> bool: """ Check if the given username is an existing Student House Guardian """ try: student_info: dict = students_collection.find_one( {"username": username}) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if student_info and student_info.get("is_house_guardian", False): return True return False
def is_student(username: str) -> bool: """ Check if the given username is an existing Student in the database """ try: student_info: dict = students_collection.find_one( {"username": username}) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if student_info: return True return False
def ics(update, context): # get file type file_type = update.message.document.mime_type # proceed only if the file is an ics if file_type == "text/calendar": # update.message.reply_text("Received!", parse_mode=telegram.ParseMode.MARKDOWN) logger.debug("New file (text/calendar) received.") ts: str = timestamp_now() file_id = update.message.document.file_id tg_file_ref = context.bot.get_file(file_id) download_filepath: Path = usr_data_path / f"{ts}.ics" tg_file_ref.download(download_filepath) # format the ics file try: new_file, number_of_events = calendarFixer.fix(download_filepath) user_log(update, ts=ts, remarks="ics") except Exception as e: logger.error("re-formatting of calendar ics file has failed.") logger.error(str(e)) update.message.reply_text( "Sorry, I failed to parse your file, please report the issue from here: /source", parse_mode=telegram.ParseMode.MARKDOWN, ) return # reply back update.message.reply_text( f"{number_of_events} events successfully re-formatted!", parse_mode=telegram.ParseMode.MARKDOWN, ) context.bot.send_document(chat_id=update.effective_chat.id, document=open(new_file, "rb")) update.message.reply_text( """*Fantastic, you can now import this `xxx_new.ics` into your Google/ Apple Calendar App, but you need to do this on your computer.* Instructions for Google Calendar: 1. Open [Google Calendar](https://calendar.google.com/) on Web. 2. At the top right, click gear-like icon and then *Settings*. 3. At the left, click *Import & Export*. 4. Click *Select file from your computer* and select the `.ics` file you get from me. 5. Choose which calendar to add the imported events to. By default, events will be imported into your primary calendar. 6. Click *Import*. """, parse_mode=telegram.ParseMode.MARKDOWN, ) else: update.message.reply_text( "I can only digest `.ics` file for now.", parse_mode=telegram.ParseMode.MARKDOWN, )
def tearDown(self): if self.ignore: return request_url = ( self.url_local_root + f"/api/application_periods/{self.test_use_uid}" ) response = requests.delete(url=request_url, headers=self.headers) if response.status_code == 200: logger.debug("Successfully removed test-generated data from database.") elif response.status_code == 404: logger.debug("No test-generated data found in database.") else: logger.error("Failed to remove test-generated data from database.")
def main(): """Start the bot""" logger.info("Getting bot_token from environment") bot_token = os.environ.get("BOT_TOKEN", None) if bot_token == "REPLACE_ME" or bot_token is None: logger.info("Getting bot_token from src/config.conf") config_fp = curr_folder / "config.conf" if not config_fp.is_file(): logger.error("bot_token not found: No Config File is Found.") return with config_fp.open() as f: config = json.load(f) bot_token = config.get("bot_token", None) if bot_token == "REPLACE_ME" or bot_token is None: logger.error( "bot_token not found: Failed getting bot token from environment and 'config.conf'" ) return load_stats() # Create the Updater and pass it your bot's token. # Make sure to set use_context=True to use the new context based callbacks # Post version 12 this will no longer be necessary updater = Updater(bot_token, use_context=True) # Get the dispatcher to register handlers dispatcher = updater.dispatcher # Command Handlers dispatcher.add_handler(CommandHandler("start", start)) dispatcher.add_handler(CommandHandler("help", help)) dispatcher.add_handler(CommandHandler("stats", stats)) dispatcher.add_handler(CommandHandler("friends", friends)) dispatcher.add_handler(CommandHandler("source", source)) # Message Handlers dispatcher.add_handler(MessageHandler(Filters.text, echo)) dispatcher.add_handler(MessageHandler(Filters.document, ics)) # log all errors dispatcher.add_error_handler(error) # Start the Bot updater.start_polling() updater.idle()
def process_openreview_url(url: str) -> Tuple[str]: """ Open Review url can be splitted into 5 parts: start: 'https://openreview.net/' pg_type: 'forum' or 'pdf' mid: '?id=' paper_id: 'nlAxjsniDzg' ==> url = start + pg_type + mid + paper_id """ # url validation if "openreview.net" not in url: logger.error("Unexpected URL Error by openreview URL Handler.") raise Exception("Unexpected URL Error by openreview URL Handler.") def get_paper_id(url) -> str: while "/" in url: slash_idx = url.find("/") url = url[slash_idx + 1:] idx = url.find("=") paper_id = url[idx + 1:] return paper_id def get_pg_from_paper_id(paper_id: str, parse_mode="abs") -> str: start = "https://openreview.net/" mid = "?id=" if parse_mode == "abs": pg_type = "forum" elif parse_mode == "pdf": pg_type = "pdf" else: raise Exception("parse_mode error") url = start + pg_type + mid + paper_id return url paper_id = get_paper_id(url) if "forum" in url: ## abstract page paper_url = url pdf_url = get_pg_from_paper_id(paper_id, parse_mode="pdf") return paper_id, paper_url, pdf_url elif "pdf" in url: ## pdf page paper_url = get_pg_from_paper_id(paper_id, parse_mode="abs") pdf_url = url return paper_id, paper_url, pdf_url else: logger.error("Unexpected URL Error by openreview URL Handler.") raise Exception("Unexpected URL Error by openreview URL Handler.")
def create_new_user_db(user: TelegramUser): db_ref = db.collection(ALL_USER_PARENT).document(user.username) doc = db_ref.get() if doc.exists: logger.error("User already exists") return False else: profile = { "username": user.username, "first_name": user.first_name, "last_name": user.last_name, "user_createdAt": timestamp_seconds(), "papers": {}, } db_ref.set(profile) return True