def get_new_profile_data(profile_data: dict, attributes: dict, new_profile_data: dict, genders: list) -> None: """ The user is asked for the new values for the personal data of the profile, and the values are stored in the new_profile_data dictionary Arguments: profile_data (dict) : All personal account data attributes (dict) : Stores all available fields that can be changed new_profile_data (dict) : Empty dictionary that will store the new values genders (list) : List of available genres """ for key, attribute in attributes.items(): print_account_warnings(attribute) change_attribute = input_user_chat( f"Do you want to change {key}? yes/no: ") if user_answer_is_yes(change_attribute): new_value = input_user_chat(f"Enter the new value for {key}: ") secure = input_user_chat(f"\nAre you sure to change {key} " f"to '{new_value}'? yes/no: ") if user_answer_is_yes(secure): if attribute == 'is_private': new_value = get_new_account_privacy(new_value) elif attribute == 'gender': new_value = get_new_user_gender(new_value, genders) new_profile_data[attribute] = new_value else: print_write_chatbot(f"No changes have been made to the {key}") else: new_profile_data[attribute] = profile_data[attribute]
def upload_to_albums(facebook_api: facebook.GraphAPI) -> None: """ Uploads a picture from the user to the album the user must select Arguments: facebook_api (object) : facebook api graph """ path = input_user_chat("Please enter the path of your picture: ") if path: albums_id = [] show_albums(facebook_api, albums_id) select = int(input_user_chat("Select the album: ")) - 1 select = validate_number(select, albums_id) caption = input_user_chat("Caption: ") try: facebook_api.put_photo(image = open(path, 'rb'), album_path = albums_id[select - 1] + "/photos", message = caption) print_write_chatbot("The photo has been uploaded successfully!", color = "green", attrs_color = ["bold"]) except Exception as error: write_log(STATUS_FILE, f"There was a problem opening the file, error: {error}", "Exception") print_write_chatbot(f"There was a problem opening the file, error: {error}", color = "red", attrs_color = ["bold"])
def connection_instagram_api() -> object: """ The user is asked if he has an instagram account to connect, if he does not have, the Crux account will be used Returns: object (instagram.Client()) - instagram.Client object """ response = input_user_chat("Would you like to connect to Instagram? (yes/no): ") credentials = {} if user_answer_is_yes(response.lower()): username = input_user_chat("Please enter your username: "******"Please enter your password: "******"By not using the instagram tool with your personal page," " we will provide the service with our Instagram account crux.bot", color = 'blue', attrs_color = ['bold']) instagram_api = instagram.connection_instagram(user_credentials = credentials) return instagram_api
def get_new_user_gender(new_value: str, genders: list) -> int: """ Returns the new value that determines the account gender. Possible numbers: 1 - Male 2 - Female 3 - Unspecified Arguments: new_value (str) : The new value that determines the gender of the account genders (list) : Possible genders list Returns: int - Number of possible gender """ if new_value in genders: gender = int(genders.index(new_value)) + 1 else: while new_value not in genders: new_value = input_user_chat( "The gender you have selected does not correspond" " to those available (male / female / unspecified), please enter a valid one: " ) else: gender = int(genders.index(new_value)) + 1 return gender
def ask_name() -> True: """ Ask the user for his/her name """ name = input_user_chat("What's your name? ", first_time = True) print_write_chatbot(f"Hi {name}!") save_username(name)
def prepare_comment(api: Client, feed: dict, text: str) -> dict: """ The user is asked for the number of the post and the comment and the data is validated to be correct Arguments: api (Client) : object instagram Client feed (dict) : Feed of the user text (str) : It's a personalized string which contains a different questions depending by the current user want to do Returns: dict - dict which contains the id of the post and the id of the comment """ position_comment = input_user_chat( f"{text} enter the post number and comment number. Ej: 1, 2 : ").split( ',') position_comment = [int(x.strip()) for x in position_comment] position_comment = validate_post_comment_number(api, feed, position_comment) post_id = str(feed[position_comment[0] - 1]['pk']) comments = api.media_comments(post_id)['comments'] comment_id = str(comments[position_comment[1] - 1]['pk']) return {'post_id': post_id, 'comment_id': comment_id}
def run_bot(bot: ChatBot) -> None: """ The user interacts with the bot. The bot can answer the user or execute the functions requested by the user Arguments: bot (ChatBot) """ print_welcome_message() running = True is_taken_name = False read = False while not read: print_write_chatbot("PLEASE READ ALL THE MESSAGE", color = 'blue', attrs_color = ['bold', 'underline', 'blink']) is_read = input_user_chat("Did you read all the message? (yes/no) ", first_time = True) read = user_answer_is_yes(is_read) while running: try: if not is_taken_name: ask_name() is_taken_name = True facebook_api = connection_facebook_api() instagram_api = connection_instagram_api() user_input = input_user_chat("\nYou: ") bot_response = str(bot.get_response(user_input)) if "_" in bot_response: exec(bot_response) else: print_write_chatbot(bot_response) keep_running = input_user_chat("Do you want to continue chatting with me?? (yes/no): ") if not user_answer_is_yes(keep_running): running = False except (KeyboardInterrupt, EOFError, SystemExit): running = False else: print_write_chatbot("It's the end", color = 'blue', attrs_color = ['bold']) animation("May the Force be with you\n") print_write_chatbot("May the Force be with you", print_text = False)
def connection_facebook_api() -> object: """ The user is asked if he has an facebook page to connect, if he does not have, the Crux account will be used Returns: object (facebook.GraphAPI()) - facebook.GraphAPI object """ response = input_user_chat("Would you like to connect to Facebook? (yes/no): ") credentials = {} if user_answer_is_yes(response.lower()): page_token = input_user_chat("Please enter your page access token: ") credentials = {'token': page_token} else: print_write_chatbot("By not using the facebook tool with your personal page, " "we will provide the service with our" "Facebook page Crux.cruz", color = 'blue', attrs_color = ['bold']) facebook_api = facebook.connection_api(user_credentials = credentials) return facebook_api
def get_post_number(text: str, max_cant_posts: int) -> int: """ Returns the post number chosen by te current user Arguments: text (str) : It's a personalized string which contains a different questions depending by the current user want to do max_cant_posts (str) : The maximum number of posts """ post_number = int(input_user_chat(f"{text} enter the Nº: ")) - 1 return validate_number_post(post_number, max_cant_posts)
def edit_post(api: Client, feed: dict, post_id: str, number_post: int) -> None: """ Edit a post chosen by the current user Arguments: api (Client) : Object instagram Client feed (dict) : the user feed post_id (str) : Id of the post number_post (int) : Position of the post in the items feed """ print_write_chatbot("You can only edit the caption!\n", color='blue', attrs_color=['bold', 'blink']) old_caption = feed['items'][number_post]['caption']['text'] new_caption = input_user_chat("Enter the new caption: ") secure = input_user_chat( f"\nAre you sure to change '{old_caption}' to '{new_caption}'? (yes/no): " ) if user_answer_is_yes(secure): result = api.edit_media(media_id=post_id, caption=new_caption) if result['status'] == 'ok': print_write_chatbot("It has been edited successfully!\n", color='green', attrs_color=['bold']) else: print_write_chatbot( message= "An error occurred while changing it, please try again later\n", color='red', attrs_color=['bold']) else: print_write_chatbot("The post has not been modified\n", color='blue', attrs_color=['bold'])
def comment(facebook_api: facebook.GraphAPI, selection: int) -> None: """ Ask what would you like to comment, comments your response and prints the success of the action Arguments: facebook_api (object) : facebook api graph selection (int) : The number of the post the user selected Returns: object - (facebook_api) """ text = input_user_chat("What would you like to comment: ").capitalize() facebook_api.put_comment(object_id = selection, message = text) print_write_chatbot("It has been successfully commented!\n", color = 'green', attrs_color = ["bold"])
def validate_number(number: int, list_: list) -> int: """ Validates the input put by the user Arguments: number (int): Number of the list selected list_ (list): Contains the list of the user Returns: int - The value of the input given by the user """ while number not in range(len(list_)): number = int(input_user_chat("re select: ")) return number
def want_unlike_target(target_type: str) -> bool: """ The user is asked if he wants to leave a dislike in a comment or post Arguments: target_type (str) : String that can be post or comment Returns: bool - If the user wants to leave a dislike in the target """ do_unlike = input_user_chat( f"The {target_type} is already" f" liked by you, you want to unliked? (yes/no): ".lower()) return user_answer_is_yes(do_unlike)
def post_related(facebook_api: facebook.GraphAPI, action: str, selected: str) -> None: """ The posts of the page are shown and depending on the action, it will be edited / liked/ deleted / commented Arguments: facebook_api (object) : facebook api graph action (str) : The action the user wants to do selected (str) : The connection name the user selected """ posts_id = [] selection = 0 posts = get_posts(facebook_api, selected) info_list = posts['data'] print_write_chatbot("The posts are: ") for count, info in enumerate(info_list, start = 1): if_text_in_info(info, posts_id, count) if action != "read": option = int(input_user_chat("Select one: ")) - 1 option = validate_number(option, posts_id) selection = posts_id[option] try: if action == "like": like(facebook_api, selection) elif action == "comment": comment(facebook_api, selection) elif action == "delete": delete_post(facebook_api, selection) elif action == "edit": text = input_user_chat("Enter the new caption: ").capitalize() edit_post(facebook_api, selection, message = text) except Exception as error: write_log(STATUS_FILE, str(error), 'Exception') print_write_chatbot(f"Error {error}", color = "red", attrs_color = ["bold"])
def validate_message() -> str: """ Validate that the message you want to send to a user is not empty Returns: str - Validated message """ validated = False message = '' while not validated: message = input_user_chat("Message: ") if message: validated = True return message
def upload_post(facebook_api: facebook.GraphAPI) -> None: """ Uploads the post written by the user and prints the success of the action if there are no errors Arguments: facebook_api (object) : facebook api graph """ user_message = input_user_chat("What would you like to write?: ") try: facebook_api.put_object(parent_object = 'me', connection_name = 'feed', message = user_message) print_write_chatbot("Posting has been updated successfully!\n", color = 'green', attrs_color = ["bold"]) except Exception as err: write_log(STATUS_FILE, str(err), 'Exception') print_write_chatbot(f"Error to upload a post {err}", color = "red", attrs_color = ['bold'])
def validate_number_post(post_number: int, max_number: int) -> int: """ Validates if the position of the post entered by the user is in a range of 0 and the number of posts - 1 Arguments: post_number (int) : Post number max_number (int) : The number of posts - 1 Returns: int - The position of the post """ while post_number < 0 or post_number >= max_number: print_write_chatbot(message="Number post incorrect", color='red', attrs_color=['bold']) post_number = int(input_user_chat("Enter a valid posting number: ")) return post_number
def search_file() -> str: """ A file is searched and validated based on an absolute path Returns: str - Absoulte path of file """ found_file = False path = '' while not found_file: path = os.path.abspath(input_user_chat("Enter the file path, the file must be .jpg: ")) if os.path.exists(path): found_file = True else: print_write_chatbot(f"The path doesnt exists, please enter a correct path \n", color = "red", attrs_color = ["bold"]) return path
def upload_photo(facebook_api: facebook.GraphAPI) -> None: """ Asks the user the path of the photo and the caption the user wants to upload, and uploads the photo and the caption Arguments: facebook_api (object) : facebook api graphThe facebook api """ path = search_file() caption = input_user_chat("Caption: ") try: facebook_api.put_photo(image = open(path, 'rb'), message = caption) print_write_chatbot("The photo has been uploaded successfully!", color = 'green', attrs_color = ["bold"]) except Exception as error: write_log(STATUS_FILE, f"There was a problem uploading the file, error: {error}", 'Exception') print_write_chatbot(f"There was a problem uploading the file, error: {error}", color = "red", attrs_color = ["bold"])
def validate_comment_number(comments, comment_number) -> int: """ Validates if the position of the comment entered by the user is in dict with all comments Arguments: comments (dict) : Dict with all comments comment_number (int) : Position of the comment Returns: int - The position of the comment """ while not comments['comments'][comment_number]: print_write_chatbot( message= "The comment doesnt exist, please enter a correct comment number", color='red', attrs_color=['bold']) comment_number = int(input_user_chat("Number comment: ")) return comment_number
def delete_comment(api: Client, feed: dict) -> None: """ Delete a comment chosen by the current user Arguments: api (Client) : Object instagram Client feed (dict) : the user feed """ print_write_chatbot("You cannot edit a comment, only delete it\n", color='blue', attrs_color=['bold', 'underline']) secure_delete = input_user_chat( "Do you want to delete a comment from a post? (yes/no):") if user_answer_is_yes(secure_delete): text = "Which comment would you delete?" comment_data = prepare_comment(api=api, feed=feed['items'], text=text) delete(api, target_id=comment_data['comment_id'], target_type='comment', parent_id=comment_data['post_id'])
def follow(api: Client) -> None: """ A specific user was searched and that user will be followed by the current user Arguments: api (Client) : Object instagram Client """ search_users(api) username = input_user_chat(f"Who do you want to follow? ") user = api.username_info(username)['user'] user_id = user['pk'] try: api.friendships_create(user_id=user_id) text = f"{username} has a private account, we have sent him a request with success!" if user[ 'is_private'] else f"{username} has been followed with success!" print_write_chatbot(message=text, color='green', attrs_color=['bold']) except Exception as error: write_log(STATUS_FILE, str(error), 'Exception') print_write_chatbot(f"There was an error:{error}", color="red", attrs_color=['bold'])
def search_users(api, text: str = 'Who do you want to search?') -> bool: """ The user is prompted for a username to find an account with that username, and 50 similar users with that username are printed Arguments: api (Client) : Object instagram Client text (str) : It's a personalized string which contains a different questions depending by the current user want to do Returns: bool - If users with that username were found """ query = input_user_chat(text) results = api.search_users(query=query) if results['num_results'] > 0: print_write_chatbot( "The maximum number of users to display is 50\n The users found are \n" ) for user in results['users']: full_data = '' full_data += f"{user['username']} {'Its a private profile' if user['is_private'] else 'Its a public profile'}" if 'social_context' in user.keys(): full_data += f" Someone you know follows this account: {user['social_context']}" if user['friendship_status']['following']: full_data += colored(f" You are currently following it", 'green') print_write_chatbot(full_data + "\n") are_users = True else: are_users = False print_write_chatbot("No user with that name was found", color="red", attrs_color=['bold']) return are_users
def edit_actions(api: Client, edit_type: str, target_type: str = 'post') -> None: """ Depending on the type of target and type of like, a post or a comment will be edit or delete Arguments: api (Client) : Object instagram Client edit_type (str) : Can be delete or edit target_type (str) : Can be post or comment """ feed = api.self_feed() is_feed_empty = feed['items'][0] if is_feed_empty: show_user_feed(api, feed['items'], True) if target_type == 'post': text = f"Which post would you {edit_type}?" post_id, number_post = get_post_id(feed, text=text) if edit_type == 'edit': edit_post(api, feed=feed, post_id=post_id, number_post=number_post) else: secure = input_user_chat( f"Are you sure to {edit_type} the post? (yes/no): \n") if user_answer_is_yes(secure): delete(api, target_id=str(post_id), target_type='post') else: if edit_type == 'delete': delete_comment(api, feed) else: print_write_chatbot("Your feed is empty", color='red', attrs_color=['bold'])
def get_username(api: Client, text: str) -> str: """ Search and return a valid username searched by the current user Arguments: api (Client) : object instagram Client text (str) : It's a personalized string which contains a different questions depending by the current user want to do Returns: str - The username of the searched user """ are_users = search_users(api, text) while not are_users: are_users = search_users( api, "No users with that name were found, please enter a correct name: " ) print_write_chatbot( "No users with that name were found, please enter a correct name: " ) username = input_user_chat("Enter username: ") return username
def unfollow(api: Client) -> None: """ Users who are followed by the current user are obtained and one of them chosen by the current user is unfollowed Arguments: api (Client) : Object instagram Client """ results = get_follows(api) username = input_user_chat(f"Who do you want to unfollow? ") for user in results['users']: try: if user['username'] == username and api.friendships_destroy( user['pk']): text = f"{username} has been successfully unfollowed!" print_write_chatbot(message=text, color='green', attrs_color=['bold']) except Exception as error: write_log(STATUS_FILE, str(error), 'Exception') print_write_chatbot(f"Error to unfollow: {error}", color="red", attrs_color=['bold'])
def post_comment(api: Client) -> None: """ Post a comment on a post from a user chosen by the current user Arguments: api (Client) : object instagram Client Returns: None """ username = get_username( api, "Who do you want to find to post a comment on his post?") can_get_feed, own_feed = is_following_user(api=api, username=username, client_username=api.username) if can_get_feed: feed, is_feed_empty = get_user_feed(api, username, own_feed=own_feed) if not is_feed_empty: comment_block = True text = "Which post would you like to comment on?" post_id, number_post = get_post_id(feed, text) want_put_comment = True while comment_block and want_put_comment: if 'comments_disabled' not in feed['items'][number_post]: comment_block = False else: print_write_chatbot( message= "The post has the comments blocked, please choose another post\n", color='red', attrs_color=['bold']) another_try = input_user_chat( "Do you want to try another comment? (yes/no) ") if user_answer_is_yes(another_try): post_id, number_post = get_post_id( feed, text), get_post_number(text=text, max_cant_posts=len( feed['items'])) else: want_put_comment = False if want_put_comment: message = input_user_chat("Message: ") result = api.post_comment(media_id=post_id, comment_text=message) try: if result['status'] == 'ok': print_write_chatbot( message="The comment has been posted correctly!\n", color='green', attrs_color=['bold']) except Exception as error: write_log(STATUS_FILE, str(error), 'Exception') print_write_chatbot(f"There was an error: {error}", color='red', attrs_color=['bold']) else: print_write_chatbot( message="It's okay if you couldn't leave a comment," " there are many posts in the sea, go get them tiger!\n", color='blue', attrs_color=['bold', 'underline']) else: print_write_chatbot(message="You cant get the feed", color='red', attrs_color=['bold'])