diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4ece495 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,33 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We, the members, contributors, and maintainers of this project, pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to a positive environment include: +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy toward other community members + +Examples of unacceptable behavior by participants include: +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +## Reporting + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [nayanchandradas@hotmail.com]. All complaints will be reviewed and investigated, and will result in a response that is deemed necessary and appropriate to the circumstances. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..906bc6e --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,29 @@ +# Contributing to Auto Website Visitor + +Thank you for your interest in contributing to **Auto Website Visitor**! + +## How to Contribute + +### Reporting Issues + +If you find a bug or have an issue, please report it via GitHub Issues. Make sure to include a detailed description and steps to reproduce the issue. For feature requests, please use the Feature Request template. + +### Submitting Code + +1. Fork the repository and create a new branch (`git checkout -b feature-branch`). +2. Make your changes in this branch. +3. Commit your changes (`git commit -am 'Add new feature'`). +4. Push your branch to your fork (`git push origin feature-branch`). +5. Open a Pull Request to the `main` branch of the original repository. + +### Code Style + +- Follow the [PEP 8](https://www.python.org/dev/peps/pep-0008/) coding style for Python code. +- Ensure that your code is clean and well-documented. +- Write tests for your code (if applicable). + +## Code of Conduct + +Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md). + +We welcome contributions and look forward to seeing your improvements to the project! diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2aebdec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +## Bug Report + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To Reproduce** + +Steps to reproduce the behavior: +1. Step 1 +2. Step 2 +3. Step 3 +4. See error + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Environment:** +- OS: [e.g., Windows 10, Ubuntu 20.04] +- Python version: [e.g., 3.9] +- Version of Auto Website Visitor: [e.g., v0.0.1] + +**Logs** +- Please provide any relevant logs or screenshots that can help us understand the issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..a948b0d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +## Feature Request + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when... + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..360d015 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +## Description + +**Please describe the changes made and why they are necessary.** + +## Related Issue + +**Please link any related issues (e.g., Fixes #123).** + +## Type of Change + +- [ ] Bug fix +- [ ] New feature +- [ ] Documentation update +- [ ] Other (please describe) + +## Checklist + +- [ ] I have followed the project's code of conduct. +- [ ] I have written tests for my changes. +- [ ] My code is clean and well-commented. +- [ ] I have updated the documentation (if needed). +- [ ] I have tested my changes and they work as expected. + +## Additional Information + +**Is there any other context you'd like to provide?** diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..2f37443 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,76 @@ +# ๐Ÿ”’ **SECURITY POLICY** ๐Ÿ›ก๏ธ + +Hey there, awesome devs! ๐Ÿ‘‹ Weโ€™re super hyped that youโ€™re vibing with **Auto Website Visitor** ๐Ÿš€. Letโ€™s keep this party secure for everyone! Below are the deets you need to know about reporting security issues and playing it safe. ๐Ÿ’ปโœจ + +--- + +## ๐Ÿ” **Supported Versions** + +We only drop security updates for the **latest version** of the project. +If youโ€™re chillinโ€™ with an old version, itโ€™s time to glow up! โฌ†๏ธโœจ + +| Version | Supported? ๐Ÿ“ข | +|---------|---------------| +| 0.0.2 | โœ… Yessir! | +| 0.0.1 | โŒ Nah, time to upgrade! | + +--- + +## ๐Ÿ†˜ **Found a Bug or Vulnerability?** ๐Ÿ‘€๐Ÿ› + +Uh-oh! If youโ€™ve stumbled upon a security issue, donโ€™t panic ๐Ÿ˜…โ€”weโ€™ve got your back: + +1. **Slide into our inbox**: + ๐Ÿ“ฉ Email us at **nayanchandradas@hotmail.com** ASAP. + (Pro tip: Keep it secret, keep it safe. No public posting! ๐Ÿ”) + +2. **Spill the tea โ˜•**: + - Whatโ€™s the issue? + - Steps to reproduce it (bonus points for screenshots or logs ๐Ÿ“ธ). + - Why do you think itโ€™s a security threat? ๐Ÿ‘€ + +3. **Hold tight, fam**: + Weโ€™ll hit you back within **48 hours**โ€”max. Pinky promise! ๐Ÿคž + +--- + +## โš ๏ธ **Big Fat Disclaimer** + +๐Ÿšจ **Listen up, fam!** ๐Ÿšจ +This tool is strictly for **personal use ONLY**. Weโ€™re all about ethical vibes here, so: + +- ๐Ÿšซ **Donโ€™t misuse** this project for anything illegal, shady, or spammy. +- ๐Ÿง  **Think responsibly**: Use it to test your own stuff, learn, or vibe with analyticsโ€”**not** to cause chaos. + +If you break these rules and something goes sideways, itโ€™s all on you. **We are NOT liable** for any trouble you get into, fam. Be chill, keep it legal, and donโ€™t summon the internet police. ๐Ÿš” + +--- + +## ๐Ÿ‘‘ **Our Commitment to Security** โœจ + +We take security **mad seriously** ๐Ÿซก. Hereโ€™s how we roll: +- Fixing vulnerabilities FAST AF. ๐Ÿ› ๏ธ +- Keeping you updated ๐Ÿ—ž๏ธ if things go south. + +Weโ€™re here to vibe with you to keep this project **safe and sound** for everyone. ๐Ÿ’™ + +--- + +## ๐Ÿ› ๏ธ **Security Besties** + +We โค๏ธ these tools to keep it tight: +- **Dependabot**: Spotting those sus dependencies. ๐Ÿ•ต๏ธโ€โ™‚๏ธ +- **Bandit** and **PyUp**: Regular audits to stay on point. + +Got a better tool idea? HMU! ๐Ÿ’Œ + +--- + +## ๐Ÿ–ค **Thanks for Being a Security Superhero!** ๐Ÿ™Œ + +You = the real MVP ๐Ÿฆธโ€โ™‚๏ธ๐Ÿฆธโ€โ™€๏ธ for helping make this project better and safer. + +Letโ€™s build something amazing **together** and keep the internet safe for all the homies! ๐Ÿ’ช๐Ÿ”ฅ + +Stay secure, +**Team Auto Website Visitor** โœจ diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f8e019a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: + # Python dependencies updates + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" # Check for updates weekly (can be "daily", "weekly", or "monthly") + day: "sunday" # Specify the day updates are checked + ignore: + - dependency-name: "selenium" # Ignore specific package updates + versions: ["<4.0.0"] # Ignore versions below specified + # GitHub Actions updates + - package-ecosystem: "github-actions" + directory: "/" # Check for updates in the root directory + schedule: + interval: "weekly" # Check for updates weekly + day: "monday" # Day updates are checked (optional) + ignore: + - dependency-name: "actions/checkout" # Ignore specific Actions updates + versions: ["<3.0.0"] # Ignore versions below specified diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000..0504948 --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,51 @@ +name: Python Package CI and Publish + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build-and-publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install build tools + run: python -m pip install --upgrade pip setuptools wheel twine requests + + - name: Build the package + run: | + python setup.py sdist bdist_wheel + + - name: Check if version exists on PyPI + id: check-version + run: | + PACKAGE_NAME="auto-website-visitor" + VERSION=$(python setup.py --version) + STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}" https://pypi.org/project/$PACKAGE_NAME/$VERSION/) + if [ "$STATUS_CODE" -eq 200 ]; then + echo "The version $VERSION already exists on PyPI. Skipping upload." + echo "upload_required=false" >> $GITHUB_ENV + else + echo "Version $VERSION is not published on PyPI. Proceeding with upload." + echo "upload_required=true" >> $GITHUB_ENV + fi + + - name: Publish to PyPI + if: env.upload_required == 'true' + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python -m twine upload dist/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8dbed5a --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Python bytecode files +*.pyc +*.pyo +*.pyd +__pycache__/ + +# Virtual environment directories +.venv/ + +# Windows system files +Thumbs.db + +# Logs +*.log + +# Distribution / packaging +*.egg +*.egg-info/ +dist/ +build/ +*.tar.gz +*.zip + +# PyInstaller files +*.spec + +# Test-related files +nosetests.xml +coverage.xml +*.cover +*.hypothesis/ + +# Jupyter Notebook checkpoints +.ipynb_checkpoints/ + +# Environment variable files +.env + +# Other +*.bak +*.tmp diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..38dabeb --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,50 @@ +# ๐Ÿ“ **Change Log** โœจ + +> **Keep up with the glo-ups, bug fixes, and fresh vibes in every version!** ๐Ÿ”ฅ + +--- + +## **[0.0.2]** โ€“ *2025-01-14* + +### ๐ŸŽ‰ **Major Glow-Up Alert!** ๐Ÿš€ +Hereโ€™s whatโ€™s popping in version **0.0.2**: + +### ๐ŸŒŸ **New Features:** +- **โ™พ๏ธ Unlimited Visits Mode**: Want endless visits? Now you can set `visit count = 0` and chill while it keeps going. +- **Proxy Validator**: No more headaches! We double-check your proxy before startingโ€”just clean vibes only. ๐Ÿงน๐Ÿ”’ +- **Driver Cache Rework**: Tidy gang approved! Driver files now live in `~/.browser_driver_cache` to reduce mess. ๐Ÿ—„๏ธ + +### โšก **Improved Realness:** +- **Auto-Reconnect**: Got disconnected? Donโ€™t stressโ€”this update reboots like a champ when youโ€™re back online. ๐Ÿ”„๐Ÿ’ป +- **Better Logs:** Say hello to polished, easy-to-read logs that give off real organized energy. ๐Ÿ“โœจ +- **Minimum Interval Timer:** Spamming? Nah. We made sure your intervals are set to at least **5 seconds**โ€”go responsibly. โณ๐Ÿ›‘ + +### ๐Ÿ› **Bugs That Got Yeeted:** +- Proxy setup for **Firefox**? Fixed. No more clunky configs. ๐ŸฆŠ +- Tweaked **headless mode** for smoother operation. Now crash-free. ๐Ÿ‘ป +- Squashed interval bugs to stop accidental chaos. ๐Ÿ’ฅ + +--- + +## **[0.0.1]** โ€“ *2025-01-12* ๐ŸŽ‰ + +### ๐ŸŒŸ **OG Vibes โ€“ First Release Ever!** ๐ŸŽŠ +Where it all started! Hereโ€™s what we shipped on **Day One**: + +### ๐Ÿ’Ž **Core Features:** +- Multi-browser support for **Chrome** and **Firefox**. +- Headless mode to keep things lowkey. ๐Ÿคซ +- Manual visit count and interval setupsโ€”youโ€™re in full control. ๐ŸŽ›๏ธ +- Logging system to keep tabs on what went down. ๐Ÿ“ +- Fully interactive CLI for an easy-peasy user experience. ๐Ÿ™Œ + +--- + +## **Stay Tuned for More Magic** โœจ + +Weโ€™re hyped to keep improving this tool, squashing bugs, and adding rad new features. Got feedback or a bug report? HMU anytimeโ€”weโ€™re all ears! ๐Ÿ’Œ + +--- + +**Peace and Good Vibes,** +๐Ÿ’– **Team Auto Website Visitor** diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..87e2d87 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 nayandas69 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..902f817 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +# ๐ŸŒ Auto Website Visitor + +Welcome to **Auto Website Visitor**! ๐Ÿš€ This is your go-to tool to automate website visits effortlessly. Whether you're testing your siteโ€™s performance, checking analytics, or just having some fun, this tool has got you covered. Built for Windows (.exe) users and available via `pip` for Python enthusiasts. Let's dive in! ๐ŸŒŸ + +![GitHub Stars](https://img.shields.io/github/stars/nayandas69/auto-website-visitor?style=flat-square&color=yellow&logo=github&logoColor=white) +![GitHub Forks](https://img.shields.io/github/forks/nayandas69/auto-website-visitor?style=flat-square&color=brightgreen&logo=github&logoColor=white) +![GitHub Issues](https://img.shields.io/github/issues/nayandas69/auto-website-visitor?style=flat-square&color=red&logo=github&logoColor=white) +![Discussions](https://img.shields.io/github/discussions/nayandas69/auto-website-visitor?style=flat-square&color=cyan&logo=discourse&logoColor=white) +![Workflow Status](https://img.shields.io/github/actions/workflow/status/nayandas69/auto-website-visitor/python-ci.yml?style=flat-square&color=4DB6AC&logo=github) +![Open Source](https://badges.frapsoft.com/os/v1/open-source.svg?v=103) +![PyPI Version](https://img.shields.io/pypi/v/auto-website-visitor?style=flat-square&color=00C853&logo=pypi) +![Python Version](https://img.shields.io/pypi/pyversions/auto-website-visitor?style=flat-square&color=42A5F5&logo=python) +![PyPI Downloads](https://static.pepy.tech/badge/auto-website-visitor/month?style=flat-square&color=5C6BC0) +![Total Downloads](https://static.pepy.tech/badge/auto-website-visitor?style=flat-square&color=8E24AA) + +## ๐Ÿ”ฅ Features + +- ๐Ÿ’ป **Cross-Browser Support**: Works seamlessly with Chrome and Firefox. +- ๐Ÿ•ถ๏ธ **Headless Mode**: Run it in stealth mode without opening the browser. +- ๐Ÿ•’ **Scheduling**: Automate visits at custom intervals. +- ๐ŸŒ **Proxy Support**: Browse like a ninja with proxy setup. +- ๐Ÿ“ˆ **Logs**: Keep track of every visit with detailed logs. +- ๐Ÿš€ **Frequent Updates**: Stay updated with the latest features. + +--- + +## ๐ŸŽฏ How to Use + +### For Windows (.exe): +1. **Download the .exe** file from the [latest release](https://github.com/nayandas69/auto-website-visitor/releases/latest). +2. Run the file and follow the CLI prompts. +3. Sit back and let the tool handle everything! ๐Ÿ’ผ + +### For Python Users (via pip): +1. Install the package: + ```bash + pip install auto-website-visitor + ``` +2. Run it directly in Python: + ```bash + python -m auto-website-visitor + ``` +3. Enter the details, and boom โ€“ it's running! ๐Ÿš€ + +--- + +## ๐Ÿ› ๏ธ Installation + +**Windows Users:** +- Download the `.exe` file from the [Releases Page](https://github.com/nayandas69/auto-website-visitor/releases). + +**Python Users:** +- Install via pip: + ```bash + pip install auto-website-visitor + ``` + +--- + +## ๐Ÿ”ง Requirements + +- Python 3.7+ +- Google Chrome or Firefox (latest versions). + +--- + +## ๐Ÿ›ก๏ธ How It Works + +1. Launch the app. +2. Enter: + - Website URL ๐ŸŒ + - Number of visits ๐Ÿ“Š + - Interval time (in seconds) โณ + - Browser preference (Chrome/Firefox) ๐Ÿ” + - Proxy settings (optional) ๐Ÿ•ต๏ธโ€โ™‚๏ธ +3. Hit enter and let the magic begin! ๐Ÿช„ + +--- + +## ๐Ÿค Contribute +Pull requests, issues, and feature suggestions are always welcome. Letโ€™s make this tool even cooler together! โœจ + +1. Fork the repo. +2. Create your feature branch: `git checkout -b feature/my-feature`. +3. Commit your changes: `git commit -m 'Add some feature'`. +4. Push to the branch: `git push origin feature/my-feature`. +5. Open a pull request. ๐Ÿ’Œ + +--- + +## ๐Ÿ“œ License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. + +--- + +## ๐Ÿง‘โ€๐Ÿ’ป Author +**Nayan Das** +- ๐ŸŒ [Website](https://socialportal.nayanchandradas.com) +- ๐Ÿ“ง [Email](mailto:nayanchandradas@hotmail.com) + +--- + +## ๐Ÿคฉ Show Some Love +If you found this project helpful, donโ€™t forget to: + +- โญ Star the repo! +- ๐Ÿ—จ๏ธ Join the [discussions](https://github.com/nayandas69/auto-website-visitor/discussions)! +- ๐Ÿ› ๏ธ Contribute your ideas! + +Letโ€™s make browsing automation easy and aesthetic for everyone! ๐Ÿ’– diff --git a/assets/icon.ico b/assets/icon.ico new file mode 100644 index 0000000..fbc4a84 Binary files /dev/null and b/assets/icon.ico differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..a6a007a --- /dev/null +++ b/main.py @@ -0,0 +1,285 @@ +import os +import time +import logging +import threading +import requests +from colorama import Fore, Style, init +from selenium import webdriver +from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.firefox.service import Service as FirefoxService +from webdriver_manager.chrome import ChromeDriverManager +from webdriver_manager.firefox import GeckoDriverManager +from selenium.webdriver.chrome.options import Options as ChromeOptions +from selenium.webdriver.firefox.options import Options as FirefoxOptions +import sys + +# Initialize colorama +init(autoreset=True) + +# Constants +REPO_URL = "https://github.com/nayandas69/auto-website-visitor" +LATEST_RELEASE_API = "https://api.github.com/repos/nayandas69/auto-website-visitor/releases/latest" +CURRENT_VERSION = "0.0.2" +CACHE_DIR = os.path.expanduser("~/.browser_driver_cache") +MIN_INTERVAL_SECONDS = 5 + +# Author Information with color +AUTHOR_INFO = f""" +{Fore.CYAN}Author: {Fore.GREEN}Nayan Das +{Fore.CYAN}Version: {Fore.GREEN}{CURRENT_VERSION} +{Fore.CYAN}Website: {Fore.BLUE}https://socialportal.nayanchandradas.com +{Fore.CYAN}Email: {Fore.RED}nayanchandradas@hotmail.com +""" + +# Setup logging +log_file = 'logs/visit_log.log' +if not os.path.exists('logs'): + os.makedirs('logs') + +logging.basicConfig( + filename=log_file, + level=logging.INFO, + format='%(asctime)s [%(levelname)s] %(message)s' +) + +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.INFO) +console_handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')) +logging.getLogger('').addHandler(console_handler) + +def ensure_log_file(): + """Ensure the log file exists.""" + if not os.path.exists(log_file): + with open(log_file, 'w'): + pass + +ensure_log_file() + +def retry_on_disconnect(func): + """Decorator to retry a function if the internet is disconnected.""" + def wrapper(*args, **kwargs): + while True: + try: + return func(*args, **kwargs) + except requests.ConnectionError: + logging.warning("No internet connection detected. Retrying in 1 minute...") + time.sleep(60) + print(f"{Fore.RED}No internet. Ensure a connection and retry in a minute.") + return + return wrapper + +def validate_proxy(proxy): + """Validate the format of the proxy.""" + try: + if not proxy.startswith(('http://', 'https://')): + raise ValueError("Proxy must start with 'http://' or 'https://'!") + protocol, address = proxy.split('://') + host, port = address.split(':') + int(port) # Ensure port is numeric + return True + except (ValueError, AttributeError): + return False + +def resource_path(relative_path): + """Get the absolute path to a resource, works for dev and PyInstaller.""" + try: + base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) + except Exception: + base_path = os.path.dirname(os.path.abspath(__file__)) + return os.path.join(base_path, relative_path) + +def get_user_input(): + """Prompt user for all necessary details.""" + website_url = input(f"{Fore.CYAN}Enter the website URL: {Fore.WHITE}") + + # Validate URL + while not website_url.startswith("http"): + print(f"{Fore.RED}Invalid URL. Please enter a valid URL starting with http:// or https://.") + website_url = input(f"{Fore.CYAN}Enter the website URL: {Fore.WHITE}") + + visit_count = input(f"{Fore.CYAN}Enter the number of visits (enter 0 for unlimited visits): {Fore.WHITE}") + while not visit_count.isdigit(): + print(f"{Fore.RED}Invalid input for visit count. Please enter a number.") + visit_count = input(f"{Fore.CYAN}Enter the number of visits (enter 0 for unlimited visits): {Fore.WHITE}") + visit_count = int(visit_count) if visit_count.isdigit() else 0 + + visit_interval_seconds = input(f"{Fore.CYAN}Enter the visit interval in seconds (minimum {MIN_INTERVAL_SECONDS} seconds): {Fore.WHITE}") + while not visit_interval_seconds.isdigit() or int(visit_interval_seconds) < MIN_INTERVAL_SECONDS: + print(f"{Fore.RED}Invalid input. Interval must be at least {MIN_INTERVAL_SECONDS} seconds.") + visit_interval_seconds = input(f"{Fore.CYAN}Enter the visit interval in seconds (minimum {MIN_INTERVAL_SECONDS} seconds): {Fore.WHITE}") + visit_interval_seconds = int(visit_interval_seconds) + + browser = input(f"{Fore.CYAN}Choose browser (chrome/firefox): {Fore.WHITE}").lower() + while browser not in ["chrome", "firefox"]: + print(f"{Fore.RED}Invalid browser choice. Please choose 'chrome' or 'firefox'.") + browser = input(f"{Fore.CYAN}Choose browser (chrome/firefox): {Fore.WHITE}").lower() + + headless = input(f"{Fore.CYAN}Run in headless mode? (y/n): {Fore.WHITE}").strip().lower() == 'y' + + use_proxy = input(f"{Fore.CYAN}Do you want to use a proxy? (y/n): {Fore.WHITE}").strip().lower() == 'y' + proxy = None + if use_proxy: + proxy = input(f"{Fore.CYAN}Enter your proxy URL (e.g., http://123.45.67.89:8080): {Fore.WHITE}") + while not validate_proxy(proxy): + print(f"{Fore.RED}Invalid proxy format. Please use the format http://host:port.") + proxy = input(f"{Fore.CYAN}Enter your proxy URL (e.g., http://123.45.67.89:8080): {Fore.WHITE}") + + return website_url, visit_count, visit_interval_seconds, browser, headless, proxy + +def create_driver(browser, headless, proxy=None): + """Create a web driver based on the user's choice of browser, headless mode, and proxy.""" + os.environ['WDM_CACHE'] = CACHE_DIR + + options = None + driver = None + + if browser == "chrome": + options = ChromeOptions() + if headless: + options.add_argument("--headless") + if proxy: + options.add_argument(f"--proxy-server={proxy}") + + driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options) + + elif browser == "firefox": + options = FirefoxOptions() + if headless: + options.add_argument("--headless") + if proxy: + options.set_preference("network.proxy.type", 1) + protocol, address = proxy.split('://') + host, port = address.split(':') + options.set_preference("network.proxy.http", host) + options.set_preference("network.proxy.http_port", int(port)) + options.set_preference("network.proxy.ssl", host) + options.set_preference("network.proxy.ssl_port", int(port)) + + driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()), options=options) + else: + raise ValueError(f"Unsupported browser: {browser}") + + return driver + +def visit_website(driver, url, visit_number): + """Perform a website visit and log the result.""" + try: + logging.info(f"Initiating visit {visit_number} to {url}.") + driver.get(url) + logging.info(f"Visit {visit_number}: Successfully visited {url}.") + print(f"{Fore.GREEN}Visit {visit_number}: Successfully visited {url}.") + except Exception as e: + logging.error(f"Visit {visit_number} failed: {str(e)}") + print(f"{Fore.RED}Visit {visit_number} failed: {str(e)}") + +def visit_task(website_url, visit_count, visit_interval_seconds, browser, headless, proxy): + """Execute the website visit task based on user inputs.""" + driver = create_driver(browser, headless, proxy) + + visit_number = 1 + while visit_count == 0 or visit_number <= visit_count: + visit_website(driver, website_url, visit_number) + if visit_count != 0 and visit_number >= visit_count: + break + visit_number += 1 + print(f"{Fore.YELLOW}Waiting for {visit_interval_seconds} seconds before the next visit...\n") + time.sleep(visit_interval_seconds) + + print(f"{Fore.GREEN}Visit task completed successfully!") + driver.quit() + +@retry_on_disconnect +def check_for_update(): + """Check the GitHub API for the latest release and compare it with the user's current version.""" + print(f"{Fore.CYAN}Checking for updates...") + try: + response = requests.get(LATEST_RELEASE_API) + response.raise_for_status() + latest_release = response.json() + latest_version = latest_release.get("tag_name", "Unknown") + whats_new = latest_release.get("body", "No information provided.") + + print(f"{Fore.GREEN}Your Current Version: {CURRENT_VERSION}") + + if latest_version != CURRENT_VERSION: + print(f"{Fore.YELLOW}Latest Version Available: {latest_version}") + print(f"{Fore.BLUE}What's New:\n{Style.BRIGHT}{whats_new}\n") + + choice = input(f"{Fore.YELLOW}Would you like to update to the latest version? (y/n): ").strip().lower() + if choice == 'y': + print(f"{Fore.CYAN}Download the latest .exe file here: {REPO_URL}/releases/latest") + print(f"{Fore.CYAN}If using via pip, run: {Fore.GREEN}pip install --upgrade auto-website-visitor") + elif choice == 'n': + print(f"{Fore.YELLOW}New version {latest_version} is waiting for you!") + else: + print(f"{Fore.RED}Invalid choice. Please select 'y' or 'n'.") + else: + print(f"{Fore.GREEN}You are already using the latest version: {CURRENT_VERSION}") + except requests.RequestException as e: + print(f"{Fore.RED}Error while checking for updates: {e}") + +def show_help(): + """Display help information about the app.""" + print(f"{Fore.YELLOW}How to use this CLI Auto Website Visitor:") + print("1. Start - Initiates website visits based on your input.") + print("2. Check Update - Checks for the latest version from the repository.") + print("3. Help - Shows instructions for using the application.") + print("4. Exit - Exits the application with a goodbye message.") + print("Logs are maintained for your convenience.") + print("For issues or suggestions, please contact the author:") + +def exit_app(): + """Exit the program with a goodbye message.""" + print("Thank you for using Auto Website Visitor!") + print("For more information, visit the author's website.") + print("Goodbye!") + sys.exit(0) + +def start(): + """Start the visit task after gathering user inputs.""" + website_url, visit_count, visit_interval_seconds, browser, headless, proxy = get_user_input() + + print(f"\n{Fore.CYAN}You have entered the following details:") + print(f"Website URL: {Fore.GREEN}{website_url}") + print(f"Visit Count: {Fore.GREEN}{visit_count if visit_count != 0 else 'Unlimited'}") + print(f"Visit Interval: {Fore.GREEN}{visit_interval_seconds} seconds") + print(f"Browser: {Fore.GREEN}{browser}") + print(f"Headless Mode: {Fore.GREEN}{headless}") + if proxy: + print(f"Using Proxy: {Fore.GREEN}{proxy}") + else: + print(f"Not using any proxy.") + + confirmation = input(f"{Fore.YELLOW}Do you want to start with these details? (y/n): {Fore.WHITE}").strip().lower() + + if confirmation == "y": + print(f"{Fore.GREEN}Starting the visits...\n") + visit_task(website_url, visit_count, visit_interval_seconds, browser, headless, proxy) + else: + print(f"{Fore.RED}Operation aborted by user.") + +def main(): + """Main CLI menu for user to select options.""" + while True: + print(AUTHOR_INFO) + print(f"{Fore.CYAN}Please choose an option:") + print(f"{Fore.YELLOW}1. Start") + print(f"{Fore.YELLOW}2. Check Update") + print(f"{Fore.YELLOW}3. Help") + print(f"{Fore.YELLOW}4. Exit") + choice = input(f"{Fore.CYAN}Enter your choice (1/2/3/4): ") + + if choice == "1": + start() + elif choice == "2": + check_for_update() + elif choice == "3": + show_help() + elif choice == "4": + exit_app() + break + else: + print(f"{Fore.RED}Invalid choice, please try again.") + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ba98b03 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +selenium>=4.0.0 +colorama>=0.4.4 +webdriver-manager>=3.8.0 +requests>=2.25.1 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c4f816e --- /dev/null +++ b/setup.py @@ -0,0 +1,52 @@ +from setuptools import setup, find_packages + +# Read the README.md for a long description +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + +setup( + name="auto-website-visitor", + version="0.0.2", + author="Nayan Das", + author_email="nayanchandradas@hotmail.com", + author_website="https://nayanchandradas.com", + description=("A CLI tool to automate website visits using Selenium and Python."), + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/nayandas69/auto-website-visitor", + project_urls={ + "Bug Tracker": "https://github.com/nayandas69/auto-website-visitor/issues", + "Documentation": "https://github.com/nayandas69/auto-website-visitor#readme", + "Source Code": "https://github.com/nayandas69/auto-website-visitor", + }, + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + ], + keywords=[ + "auto website visitor", "website visitor", "automation", "selenium", + "selenium python", "cli tool", "website traffic", "website automation", + ], + packages=find_packages(include=["*"], exclude=["tests*", "docs*"]), # Automatically finds packages in the root + py_modules=["main"], # Single file module + python_requires=">=3.6", # Python version requirement + install_requires=[ + "selenium>=4.0.0", + "colorama>=0.4.4", + "webdriver-manager>=3.8.0", + "requests>=2.25.1", + ], + entry_points={ + "console_scripts": [ + "auto-website-visitor=main:main", # Command to run the script + ], + }, + include_package_data=True, + zip_safe=False, + license="MIT", +) +# The setup() function is the core of the setup.py script. It takes a lot of arguments, but most of them are optional. +# Here's a breakdown of the arguments used in this script: +# name: The name of the package. This is what users will use to install the package using pip. +# version: The version of the package. This is used by pip to check for updates and dependencies. \ No newline at end of file diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..5dc56ca --- /dev/null +++ b/version.txt @@ -0,0 +1,2 @@ +0.0.1 +0.0.2 diff --git a/whats_new.txt b/whats_new.txt new file mode 100644 index 0000000..0e30b03 --- /dev/null +++ b/whats_new.txt @@ -0,0 +1,20 @@ +# ๐Ÿš€ **What's New in Auto Website Visitor v0.0.2** + +๐ŸŒŸ **New Features:** +- **Infinite Visits Mode:** Hit those websites endlessly with a slick new "unlimited visits" option. No limits, no problems! โ™พ๏ธ +- **Proxy Validation:** Enter your proxy like a pro! We check for valid formats so you're not out here debugging typos. ๐Ÿ”’ +- **Custom Cache Directory:** Your drivers now have a cool hangout spot in `~/.browser_driver_cache`โ€”less clutter, more style. ๐Ÿ—„๏ธ + +๐Ÿ› ๏ธ **Improvements:** +- **Auto-Reconnect on Internet Drops:** Got bad Wi-Fi? No stressโ€”we've got a retry loop waiting to reconnect when youโ€™re back online. ๐Ÿ”„โšก +- **Logs Glow-Up:** Cleaner logs and fancy console output so youโ€™re always in the know about what's popping in the background. ๐Ÿ“โœจ +- **Better CLI UX:** Minimum intervals enforced (5 seconds), tighter validation, and crisp feedback keep everything user-friendly. โœ… + +๐Ÿ› **Fixes:** +- Squashed the bug where intervals could be *too short*โ€”keeping it chill with a solid minimum now. ๐Ÿšซโฑ๏ธ +- **Proxy Setup for Firefox:** Fixed flaky configsโ€”it's a seamless setup now! ๐ŸฆŠ๐Ÿ”— +- Cleared out weird edge case crashes when launching headless in certain scenarios. ๐Ÿ˜Œ๐Ÿ”ง + +--- + +**Ready to level up your automation game?** ๐Ÿ’ฅ Head over to the main menu and give it a whirl. Your vibe is set to power user now! ๐Ÿ™Œ