diff --git a/main_console_follow_unfollow.py b/main_console_follow_unfollow.py index f93ab69..02c8d29 100644 --- a/main_console_follow_unfollow.py +++ b/main_console_follow_unfollow.py @@ -10,7 +10,8 @@ def main_console_follow_unfollow(): print("\nChoose an action:") print("1. Follow people") print("2. Unfollow people") - print("3. Exit") + print("3. Follow back people") + print("4. Exit") choice = input("Enter your choice: ") @@ -19,10 +20,12 @@ def main_console_follow_unfollow(): elif choice == '2': main_app.unfollow_people() elif choice == '3': + main_app.follow_back() + elif choice == '4': print("Exiting the program.") break else: - print("Invalid choice. Please enter 1, 2, or 3.") + print("Invalid choice. Please enter 1, 2, 3 or 4.") if __name__ == "__main__": diff --git a/src/follow_back.py b/src/follow_back.py new file mode 100644 index 0000000..69bbcb5 --- /dev/null +++ b/src/follow_back.py @@ -0,0 +1,86 @@ +import time +import requests + + +class GitHubClientFollowBack: + def __init__(self, config): + self.token = config.get_api_key() + self.headers = { + 'Authorization': f'token {self.token}', + 'Accept': 'application/vnd.github.v3+json' + } + + def get_followers(self, username): + return self._get_paginated_data(f'https://api.github.com/users/{username}/followers') + + def get_following(self, username): + return self._get_paginated_data(f'https://api.github.com/users/{username}/following') + + def follow_user(self, username): + url = f'https://api.github.com/user/following/{username}' + response = self._make_request('PUT', url) + return response.status_code == 204 + + def _get_paginated_data(self, url): + page = 1 + data = [] + while True: + paginated_url = f'{url}?page={page}' + response = self._make_request('GET', paginated_url) + + if response.status_code != 200: + raise Exception(f"Error fetching data from {paginated_url}. Status code: {response.status_code}") + + page_data = response.json() + if not page_data: + break # No more data to fetch + + data.extend(page_data) + page += 1 + + return data + + def _make_request(self, method, url): + max_retries = 3 + for attempt in range(max_retries): + try: + if method == 'GET': + response = requests.get(url, headers=self.headers) + elif method == 'PUT': + response = requests.put(url, headers=self.headers) + else: + raise ValueError("Unsupported HTTP method") + + if response.status_code == 500: + print(f"Server error (500) at {url}, retrying...") + time.sleep(2) # Wait before retrying + continue # Retry the request + + return response + except requests.RequestException as e: + print(f"Request to {url} failed: {e}") + if attempt < max_retries - 1: + time.sleep(2) # Wait before retrying + continue # Retry the request + else: + raise + + +class FollowBackFollowers: + def __init__(self, client, username): + self.client = client + self.username = username + + def follow_back(self): + followers = self.client.get_followers(self.username) + following = self.client.get_following(self.username) + + following_set = {user['login'] for user in following} + + for user in followers: + if user['login'] not in following_set: + success = self.client.follow_user(user['login']) + if success: + print(f"Successfully followed back {user['login']}") + else: + print(f"Failed to follow back {user['login']}") diff --git a/src/manager_follow_unfollow.py b/src/manager_follow_unfollow.py index 8f43f75..c0b5e8e 100644 --- a/src/manager_follow_unfollow.py +++ b/src/manager_follow_unfollow.py @@ -1,6 +1,7 @@ import json from src.follow import GitHubClientFollow, FollowerManager, extract_username_from_url +from src.follow_back import GitHubClientFollowBack, FollowBackFollowers from src.get_following import GitHubClientGetFollowings from src.unfollow import UnfollowNonFollowers, GitHubClientUnfollow @@ -10,6 +11,7 @@ def __init__(self, config): self.github_client_follow = GitHubClientFollow(config) self.github_client_unfollow = GitHubClientUnfollow(config) self.github_client_get_following = GitHubClientGetFollowings(config) + self.github_client_follow_back = GitHubClientFollowBack(config) def follow_people(self): profile_url = input("Enter the GitHub profile URL: ") @@ -58,3 +60,9 @@ def unfollow_people(self): unfollow_manager.unfollow_non_followers() print("Process complete.") + + def follow_back(self): + username = input("Enter your GitHub username: ") + + follow_back_bot = FollowBackFollowers(self.github_client_follow_back, username) + follow_back_bot.follow_back()