def login(cls, username, password): """ this method takes two argument and checks if there is a match user with this information :param username: unchecked username :param password: unchecked password :return: True if username and password are match, or False otherwise """ data = file_manager.read_from_file('users_data.json') works = file_manager.read_from_file('all_users_works.json') user_has_work = True if username in works.keys() else False my_works = works[username] if user_has_work else {} password = str(password).encode() hash_password = md5(password).hexdigest() if username in data.keys(): if hash_password == data[username]['password']: current_user = cls(*(data[username].values())) if user_has_work: for _ in my_works.values(): current_user.works.append(Work(*(_.values()))) return current_user else: return False else: print(f'No user named {username}...') return False
def share(sender_user, target_work): """ this function saves a copy of chosen work by sender user to a temporary file as events file :param sender_user: logged in user :param target_work: selected work to be sent :return: """ users_from_file = file_manager.read_from_file('users_data.json') users_from_file.pop(sender_user.username) all_usernames = {i + 1: username for i, username in enumerate(users_from_file.keys())} yes_or_no = int(input(f'\n{Fore.GREEN} do you know your friend username? 1. yes 2. no{Fore.RESET}')) receiver = '' if yes_or_no == 1: receiver = input(f'{Fore.BLUE} enter friend username:{Fore.RESET}') elif yes_or_no == 2: for num, username in all_usernames.items(): print(f'{Fore.CYAN}{num}. "{username}"{Fore.RESET}') select = int(input(f'\n{Fore.MAGENTA} select a friend: ')) receiver = all_usernames[select] receiver_usr = user.User(*(users_from_file[receiver].values())) receiver_usr.events[sender_user.username] = target_work to_event_file = target_work.__dict__ to_event_file.pop("priority") to_event_file.pop("time_ntf") file_manager.write_to_file('events.json', to_event_file, receiver, sender_user.username) return f'{Fore.WHITE}"{target_work.work_name}" has been sent to "{receiver_usr.username}"{Fore.RESET}'
def change_status(usr, wrk): """ this function changes status of work from in progress to done and vice versa :param wrk: target work of user :param usr: logged in user to reminder """ change_sts = 0 while change_sts != 3: print(f'{Fore.LIGHTGREEN_EX}current status of "{wrk.work_name}" is {wrk.status}{Fore.RESET}') try: change_sts = int(input(f'do you want to change it? 1. yes{Fore.CYAN} ' f'2. {Fore.LIGHTGREEN_EX}No{Fore.MAGENTA}3. back{Fore.RESET}: ')) if change_sts == 1: new_status = wrk.change_status() print(f'{Fore.LIGHTGREEN_EX} status of "{wrk.work_name}" changed to "{wrk.status}"{Fore.RESET}') all_usr_wrk = file_manager.read_from_file('all_users_works.json', usr.username) status_ch = all_usr_wrk[wrk.work_name] status_ch['status'] = new_status print(file_manager.write_to_file('all_users_works.json', status_ch, usr.username, wrk.work_name)) reminder_logger.info(f'user finished a work', exc_info=True) break elif change_sts == 2: print(f'change status of "{wrk.work_name}" has been aborted') break else: ValueError(change_sts) continue except ValueError: print(f'invalid input, try again..') except IOError: print('something went wrong about "all_users_works.json" file')
def register(cls, user_data): """ this method takes information of a User class and makes an instance from it :return: an instance of User class or an error about wrong inputs """ new_user_data = { 'email': user_data[0], 'name': user_data[1], 'last_name': user_data[2], 'username': user_data[3], 'password': user_data[4], 'status': True, 'lock_time': '0000-00-00 00:00:00' } password = str(new_user_data['password']).encode() hashed_password = md5(password).hexdigest() new_user_data['password'] = hashed_password new_user = cls(*(new_user_data.values())) all_users_data = file_manager.read_from_file('users_data.json') if user_data[3] in all_users_data.keys(): print(f'{user_data[3]} already exists') else: file_manager.write_to_file('users_data.json', new_user_data, new_user.username) return new_user
def delete_work(logged_in_user, target_work): """ this function deletes a work from user work list and from file :param logged_in_user: current user :param target_work: selected work object to delete :return: """ logged_in_user.delete_work(target_work.work_name) for th in threads: if th.name == target_work.work_name: threads.remove(th) user_works_file = file_manager.read_from_file('all_users_works.json', logged_in_user.username) user_works_file.pop(target_work.work_name) file_manager.write_to_file('all_users_works.json', user_works_file, logged_in_user.username) return f'"{target_work.work_name}" has been deleted successfully'
def lock_user(username): """ if user enters password wrong 3 times, this function will recall and changes status attribute of user to False. :param username: target username for locking """ users = file_manager.read_from_file('users_data.json') user = users[username] print(user) if username in users.keys(): menu_manager.reminder_logger.info(f"one account locked") lock_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S") user.update({'status': False}) user.update({'lock_time': lock_time}) print(user) file_manager.write_to_file('users_data.json', user, username) print(f'{Fore.RED}your account is locked for 2 minutes. try later{Fore.RESET}') else: print('pass')
def check_lock(username): """ this function checks if user's account is lock :param username: input username to check """ try: users = file_manager.read_from_file('users_data.json') user = users[username] except KeyError: return 2 if user["status"]: return 1 else: lock_time = datetime.strptime(user["lock_time"], "%Y-%m-%d %H:%M:%S") if lock_time + timedelta(seconds=60 * 2) < datetime.now(): user["status"] = True file_manager.write_to_file('users_data.json', user, username) return 1 return 0
def postpone_work(usr, wrk): """ this function postpone a work by changing datetime attribute of work. there is four options for user. one hour, one day, one week or one month. :param wrk: target work of user :param usr: logged in user to reminder :return: a massage about changing datetime of work """ postpone = 0 while postpone != 5: print(f'{Fore.CYAN}How much do you want to postpone "{wrk.work_name}"?' f'\n{Fore.LIGHTYELLOW_EX} 1. one hour' f'\n{Fore.LIGHTGREEN_EX} 2. one day' f'\n{Fore.LIGHTYELLOW_EX} 3. one week' f'\n{Fore.LIGHTGREEN_EX} 4. one month' f'\n{Fore.LIGHTYELLOW_EX}5. back {Fore.RESET}') try: p = int(input(f'pick a number for more changes enter >5>1 to edit{wrk.work_name}')) options = {1: 'hour', 2: 'day', 3: 'week', 4: 'month'} new_datetime = wrk.postpone(1, options[p]) new_dt_file = new_datetime.strftime("%Y-%m-%d %H:%M:%S") update_work = {} try: assert path.isfile('all_users_works.json') update_work = file_manager.read_from_file('all_users_works.json', usr.username) except AssertionError: print('file not found') update_work[wrk.work_name]['work_datetime'] = new_dt_file print(file_manager.write_to_file('all_users_works.json', update_work, usr.username)) reminder_logger.info(f'"a work has been postponed', exc_info=True) return f'{Fore.GREEN}{wrk.work_name} has been postponed to {new_datetime}{Fore.RESET}' except ValueError: print(f'{Fore.LIGHTRED_EX} invalid input try again..{Fore.RESET}') except IOError: print(f'{Fore.LIGHTRED_EX}file read and write error{Fore.RESET}') reminder_logger.error('error in reading or writing "all_users_works.json"')
def tweet_data(): file_name = 'tweet' extension = '.json' print file_manager.read_from_file(file_name, extension) return file_manager.read_from_file(file_name, extension)
def social_data(): file_name = 'social' extension = '.json' return file_manager.read_from_file(file_name, extension)
def technical_data(file_name): extension = '.tsv' return file_manager.read_from_file(file_name, extension)
def main(): list_of_lines = file_manager.read_from_file("words.txt") longest_words = find_the_longest_word(list_of_lines) file_manager.write_to_file(longest_words)
def edit_work_menu(usr, wrk): """ this menu lets users edit attributes of their works :param usr: user logged in to reminder :param wrk: selected work object to edit :return: an edited work object """ items = [] attributes_dict = {} attribute_lst = list(wrk.__dict__.keys()) if ('priority' in attribute_lst) or ('time_ntf' in attribute_lst): attribute_lst.pop(attribute_lst.index('priority')) attribute_lst.pop(attribute_lst.index('time_ntf')) count = 0 R = Fore.RESET for i in range(1, len(attribute_lst) + 1): if count % 2 == 0: C = Fore.LIGHTCYAN_EX else: C = Fore.LIGHTWHITE_EX attributes_dict[i] = attribute_lst[i - 1] print(f'{i}. {C}{attribute_lst[i - 1]} of {wrk.work_name}{R}') count += 1 new_values = {} while True: try: items = list(map(lambda x: int(x), input('id of items fo editing:' '(split items with comma): ').strip().split(','))) for itm in items: assert 1 <= itm <= 10 if not isinstance(itm, int): ValueError(itm) assert len(items) <= 10 break except AssertionError: print(f"\n{Fore.RED} invalid input... just 1 - 10 are allowed." f" you don't have more than 10 option{Fore.RESET}") except ValueError: print(f'\n{Fore.LIGHTRED_EX} invalid input. input must be integer') continue edit_items = [attributes_dict[num] for num in items] old_values = {_: wrk.__dict__[_] for _ in edit_items} out_str = '' work_dict = file_manager.read_from_file('all_users_works.json', usr.username) edit_work_file = work_dict[wrk.work_name] new_val = None cnt = 0 R = Fore.RESET for itm in edit_items: if cnt % 2 == 0: C = Fore.BLUE else: C = Fore.LIGHTMAGENTA_EX if itm == 'importance' or itm == 'urgency': new_val = bool(int(input(f'{C} is {wrk.work_name} {itm}?,' f' current {itm} is {old_values[itm]} (1. yes 0. No){R}'))) edit_work_file[itm] = new_val new_values[itm] = new_val elif itm == 'work_datetime': while True: try: new_val = input(f'{C}new values of {itm}, current {itm} is {old_values[itm]}{R}') if not re.match("%Y-%m-%d %H:%M:%S", new_val): ValueError(new_val) edit_work_file[itm] = new_val new_values[itm] = new_val new_values['work_datetime'] = datetime.datetime.strptime(new_values['work_datetime'], "%Y-%m-%d %H:%M:%S") break except ValueError: print(Fore.LIGHTRED_EX, f'invalid datetime format. try this: year-month-day hour:minutes:second', R) continue else: new_val = input(f'{C}new values of {itm}, current {itm} is {old_values[itm]}{R}') edit_work_file[itm] = new_val new_values[itm] = new_val out_str += f'{C}{itm} changed from >> {old_values[itm]} to >> {new_val}\n{R}' cnt += 1 if 'work_name' in new_values.keys(): new_work_name = edit_work_file['work_name'] work_dict[new_work_name] = edit_work_file work_dict.pop(wrk.work_name) file_manager.write_to_file('all_users_works.json', work_dict, usr.username) wrk.edit_work(new_values) th_names = [th.name for th in threads] if wrk.work_name in th_names: for th in threads: if wrk.work_name == th.name: th.join(1) else: th = threading.Thread(name=wrk.work_name, target=wrk.notify, daemon=True) threads.append(th) th.start() th.join(1) reminder_logger.info('user edited a work') return out_str
def check_events(logged_in_user): """ this function checks event file of user just after log in. (work_select variable is a dict to assign number to every event work_select = {event_num:(sender, received work as Work obj)}) User should decide what to do with received work. :param logged_in_user: current user in reminder :return: a massage about user decision """ all_events = {} while True: try: all_events = file_manager.read_from_file('events.json')[logged_in_user.username] assert all_events except KeyError: print(f'{Fore.GREEN}You have no events...{Fore.RESET}') reminder_logger.info(f'user checked events and has no event so far') back = input(f'{Fore.GREEN}enter "b" to back{Fore.RESET}') if back: break except AssertionError: print(f'{Fore.BLUE}no new event...{Fore.RESET}') reminder_logger.info(f'"user checked events and has no new event this time') back = input(f'{Fore.GREEN}enter "b" to back{Fore.RESET}') if back: break sender_work = {i + 1: event for i, event in enumerate(all_events.items())} work_select = {} for i, evnt in sender_work.items(): work_select[i] = (evnt[0], (Work(*(evnt[1].values())))) options = len(work_select) while work_select: for i, evnt in work_select.items(): print(f'{i}. {evnt[0]}: "{evnt[1].work_name}"') print('0. back to main menu') select = int(input('choose a work or enter 0 to back:')) if 0 < select <= options: temp = work_select.pop(select) slct_wrk = temp[1] all_events.pop(temp[0]) print(file_manager.write_to_file('events.json', all_events, logged_in_user.username)) print(f'{Fore.GREEN}information of "{slct_wrk.work_name}": {Fore.RESET}') print(f'{slct_wrk}') act = int(input(f'{Fore.GREEN}1. accept {Fore.RED}2. reject: {Fore.RESET}')) if act == 1: print(logged_in_user.accept_a_work(slct_wrk)) wrk_to_file = slct_wrk.__dict__.copy() wrk_to_file.pop("priority") wrk_to_file.pop("time_ntf") print(slct_wrk.__dict__) print(file_manager.write_to_file('all_users_works.json', wrk_to_file, logged_in_user.username, slct_wrk.work_name)) elif act == 2: print(f'\n{Fore.LIGHTYELLOW_EX}{slct_wrk.work_name} has been rejected{Fore.RESET}') continue elif select == 0: print(f'\n{Fore.CYAN} event check has been aborted {Fore.RESET}') break if not work_select: all_events.clear() sender_work.clear() print(file_manager.write_to_file('events.json', {}, logged_in_user.username)) break