diff --git a/Website Blocker/README.md b/Website Blocker/README.md new file mode 100644 index 00000000..b1dca558 --- /dev/null +++ b/Website Blocker/README.md @@ -0,0 +1,110 @@ +# Website Blocker + + +## Overview + +This project is a Python-based website blocker that restricts access to selected websites during specified working hours. It modifies the system's hosts file to redirect targeted domains to the local machine, effectively preventing access. + +The script supports both Unix-based systems and Windows by dynamically detecting the operating system and selecting the appropriate hosts file. + + + +## Features +* Cross-platform support (Linux, macOS, Windows) +* Time-based website blocking +* Interactive selection of popular websites +* Support for custom user-defined domains +* Automatic cleanup of hosts file on exit +* Error handling for insufficient permissions +* Modular, object-oriented design + + + +## How It Works + +The program modifies the system's hosts file by adding entries that redirect selected domains (e.g., facebook.com) to 127.0.0.1. This prevents the browser from reaching the actual website. + +During non-working hours, the script restores the hosts file by removing those entries. + +This could be very useful for system administrators, parents, or anyone looking to improve productivity by limiting access to distracting websites during certain hours. + + +![simple-diagram](pictures/class-diagram.png) + + + +## Requirements + +Python 3.x +Administrator/root privileges (required to modify the hosts file) + + +## Usage + + +1. Run the script + +On Linux/macOS: +```bash +sudo python3 web_blocker.py +``` + +On Windows (run terminal as Administrator): +```bash +python web_blocker.py +``` + + +2. Select websites +You will be prompted to: +* Choose from a list of common websites +* Or enter custom domains + + +3. Set working hours +Enter: +* Start hour (0โ€“23) +* End hour (0โ€“23) + +If invalid input is provided, default values (8โ€“16) will be used. + + + +## Example + +If you select: +* facebook.com +* youtube.com + +The script will add entries like to the hosts file: +```bash +127.0.0.1 facebook.com +127.0.0.1 www.facebook.com +``` + +## Important Notes +* The script must be run with administrator/root privileges. +* Modifying the hosts file affects system-wide network behavior. +* The program automatically restores the hosts file when it is stopped using Ctrl+C. + + +## Improvements Over Original Implementation +* Refactored into an object-oriented design +* Added cross-platform compatibility +* Introduced interactive user input +* Improved timing responsiveness +* Added safe cleanup on exit +* Improved error handling and reliability + + + +## Future Improvements +* Command-line arguments support +* Configuration file for persistent settings +* Logging system +* Unit testing + + +## License + +This project is part of a public repository intended for educational and practical use. diff --git a/Website Blocker/cross-platform-web_blocker.py b/Website Blocker/cross-platform-web_blocker.py new file mode 100644 index 00000000..4dee0317 --- /dev/null +++ b/Website Blocker/cross-platform-web_blocker.py @@ -0,0 +1,169 @@ +import time +import platform +import signal +import sys +from datetime import datetime + +# Flake8 and mypy check - clean code, type hints, and comments for clarity + + +class WebsiteBlocker: + def __init__(self, + websites: list, + start_hour: int = 8, + end_hour: int = 16) -> None: + self.websites = websites + self.start_hour = start_hour + self.end_hour = end_hour + self.redirect = "127.0.0.1" + self.hosts_path = self.get_hosts_path() + + # ---------------------------- + # OS handling + # ---------------------------- + def get_hosts_path(self) -> str: + if platform.system() == "Windows": + return r"C:\Windows\System32\drivers\etc\hosts" + return "/etc/hosts" + + # ---------------------------- + # Time logic + # ---------------------------- + def is_working_hours(self) -> bool: + now = datetime.now() + return self.start_hour <= now.hour < self.end_hour + + # ---------------------------- + # Blocking logic + # ---------------------------- + def block_websites(self) -> None: + try: + with open(self.hosts_path, "r+") as file: + content = file.read() + + for site in self.websites: + entry = f"{self.redirect} {site}" + if entry not in content: + file.write(entry + "\n") + + except PermissionError: + print("โŒ Please run the script as administrator/root") + sys.exit(1) + + # ---------------------------- + # Unblocking logic + # ---------------------------- + def unblock_websites(self) -> None: + with open(self.hosts_path, "r+") as file: + lines = file.readlines() + file.seek(0) + + for line in lines: + if not any(site in line for site in self.websites): + file.write(line) + + file.truncate() + + # ---------------------------- + # Cleanup on exit + # ---------------------------- + def cleanup(self, signum=None, frame=None) -> None: + print("\n๐Ÿงน Cleaning up hosts file...") + self.unblock_websites() + sys.exit(0) + + # ---------------------------- + # Main loop + # ---------------------------- + def run(self) -> None: + print("๐Ÿš€ Website Blocker running...") + + # Handle Ctrl + C safely -> Delete /etc/hosts or + # "C:\Windows\System32\drivers\etc\hosts" entries after + + signal.signal(signal.SIGINT, self.cleanup) + + while True: + if self.is_working_hours(): + print("๐Ÿ”’ Blocking websites...") + self.block_websites() + else: + print("๐Ÿ”“ Unblocking websites...") + print("โฐ Outside of working hours. Websites are accessible.") + self.unblock_websites() + + time.sleep(5) # responsive check + + +# ---------------------------- +# User input for websites +# ---------------------------- +def get_user_websites() -> list: + options = { + "1": "facebook.com", + "2": "youtube.com", + "3": "instagram.com", + "4": "twitter.com", + "5": "gmail.com", + "6": "\033[33mCustom: Enter your own domains\033[0m", + } + + print("- Select websites to block (comma separated):") + for key, value in options.items(): + print(f"{key}) {value}") + + print() + selected = [] + choices = input("Your choice: ").split(",") + # Process selected options + for choice in choices: + choice = choice.strip() + if choice in options and choice != "6": + selected.append(options[choice]) + selected.append("www." + options[choice]) + elif choice == "6": + custom_sites = input("Enter custom domains (comma separated): ") + for site in custom_sites.split(","): + site = site.strip() + if site: + selected.append(site) + selected.append("www." + site) + else: + print( + f"\n\033[91mInvalid option: {choice}\n\ +Please select from the list.\033[0m" + ) + return [] + + return selected + + return selected + + +# ---------------------------- +# Entry point +# ---------------------------- +if __name__ == "__main__": + + print("\n\033[33mRun this script as administrator/root for \ +it to work properly.\033[0m\n") + + websites: list = [] + while len(websites) == 0: + websites = get_user_websites() + + if not websites: + print("No websites selected. Exiting.") + sys.exit(0) + + try: + start = int(input("Enter the starting hour (0-23) for blocking \ +(default 8): ")) + end = int(input("Enter the ending hour (0-23) for blocking \ +(default 16): ")) + except ValueError: + print("Invalid input for hours. Using default values (8-16).") + start, end = 8, 16 + + blocker = WebsiteBlocker(websites, start, end) + blocker.run() diff --git a/Website Blocker/description.txt b/Website Blocker/description.txt new file mode 100644 index 00000000..98ca909b --- /dev/null +++ b/Website Blocker/description.txt @@ -0,0 +1,22 @@ +* I implemented my contribution by refactoring the original website blocker script into a modular, object-oriented design that improves structure, reliability, and usability. + +* First, I introduced a WebsiteBlocker class to encapsulate the core functionality of the application. This class separates responsibilities into clear methods: + + * is_working_hours() determines whether blocking should be active based on the current time + * block_websites() adds entries to the hosts file + * unblock_websites() safely restores the hosts file + * run() manages the main execution loop + * cleanup() ensures that any changes to the hosts file are reverted when the program is interrupted + +To support multiple operating systems, I implemented a helper method get_hosts_path() that dynamically selects the correct hosts file path depending on whether the script is running on Windows or a Unix-based system. This builds on the cross-platform idea introduced in PR #563, but integrates it into a cleaner and more structured design. + +I improved reliability by adding proper error handling when accessing the hosts file. Specifically, I handle PermissionError to prevent the program from crashing and instead provide a clear message to the user about running the script with administrator or root privileges. + +I also enhanced the usability of the script by adding an interactive interface that allows users to select commonly blocked websites or input custom domains without modifying the source code. This makes the tool more practical for real-world usage. + +Additionally, I improved the responsiveness of the script by replacing long fixed delays with shorter intervals (time.sleep(5)), allowing the program to react more quickly to changes in working hours. + +Finally, I implemented a cleanup mechanism using signal handling (SIGINT) so that when the user stops the program (e.g., using Ctrl+C), any modifications made to the hosts file are automatically reverted. This addresses a key limitation in the original implementation, where stopping the script could leave the system in a blocked state. + +Overall, my contribution significantly enhances the structure, reliability, and usability of the website blocker while maintaining the core functionality of blocking distracting websites during working hours. + diff --git a/Website Blocker/mac/Website_Blocker.py b/Website Blocker/mac/Website_Blocker.py deleted file mode 100644 index 17af6f09..00000000 --- a/Website Blocker/mac/Website_Blocker.py +++ /dev/null @@ -1,61 +0,0 @@ - Run this script as root - -import time -from datetime import datetime as dt - -# change hosts path according to your OS -hosts_path = " -/etc/hosts & quot -# localhost's IP -redirect = " -127.0.0.1 & quot - -# websites That you want to block -website_list = -[ & quot - www.facebook.com & quot, & quot - facebook.com" - , - & quot - dub119.mail.live.com" - , & quot - www.dub119.mail.live.com" - , - & quot - www.gmail.com" - , & quot - gmail.com" - ] - -while True: - - # time of your work - if dt(dt.now().year, dt.now().month, dt.now().day, 8) - < - dt.now() & lt - dt(dt.now().year, dt.now().month, dt.now().day, 16): - print( & quot - Working hours... & quot - ) - with open(hosts_path, 'r+') as file: - content = file.read() - for website in website_list: - if website in content: - pass - else: - # mapping hostnames to your localhost IP address - file.write(redirect + " - & quot - + website + " - \n & quot - ) - else: - with open(hosts_path, 'r+') as file: - content = file.readlines() - file.seek(0) - for line in content: - if not any(website in line for website in website_list): - file.write(line) - - # removing hostnmes from host file - file.truncate() diff --git a/Website Blocker/pictures/class-diagram.png b/Website Blocker/pictures/class-diagram.png new file mode 100644 index 00000000..8ca378d5 Binary files /dev/null and b/Website Blocker/pictures/class-diagram.png differ diff --git a/Website Blocker/read.me b/Website Blocker/read.me deleted file mode 100644 index a782bcc1..00000000 --- a/Website Blocker/read.me +++ /dev/null @@ -1,12 +0,0 @@ -This is real world program which blocks certain distracting website like Facebook, -Youtube etc during your work hours. About the program : What we are going to in this -program is that we will pass the link of websites which you think is distracting and the -time that you are working on your computer and program will block those website. -Program Architecture: - for mac:- -1. Every system have host file whether it is Mac, Windows or Linux. -Host file in Mac and Linux : "/etc/hosts"\ - - -for windows:- -C:\Windows\System32\drivers\etc