diff --git a/README.md b/README.md index 7a2e336..77f26b4 100644 --- a/README.md +++ b/README.md @@ -11,42 +11,41 @@ pip install facebook-downloader ``` ### Note -> You will need to have the FireFox browser installed on your pc (for the PyPI Package) ->> The program is dependent on selenium, so in order to run it, you will have to download and properly setup geckodriver (setup instructions available below) +> You will need to have the FireFox browser installed on your pc. # Docker -## Pull the image +## Build the container ``` -docker pull rly0nheart/facebook-downloader:facebook-downloader +docker build -t my-facebook-downloader . ``` + # Geckodriver setup +> This assumes you've cloned the repository with `git clone https://github.com/bellingcat/facebook-downloader` ## Linux -**1. Go to the geckodriver [releases page](https://github.com/mozilla/geckodriver/releases/). Find the latest version of the driver for your platform and download it** - -**2. Extract the downloaded file** +**1.** Navigate to the facebook-downloader directory ``` -tar -xvzf geckodriver* -``` -**3. Add geckodriver to your system path** -``` -export PATH=$PATH:/path/to/downloaded/geckodriver +cd facebook-downloader ``` -### Note -> If you encounter issues with the above commands, then you should run them as root +**2.** Find the `install.sh` script and run it +``` +./install.sh +``` +> This assumes the script was already made executable with the `chmod +x uninstall.sh` command. + ## Windows -**1. Go to the geckodriver [releases page](https://github.com/mozilla/geckodriver/releases/). Find the geckodriver.exe binary for your platform and download it** - -**2. Move the downloaded executable to** *C:\Users\yourusername\AppData\Local\Programs\Python\Python310* - -### Note -> The numbers on the directory 'Python310' will depend on the version of Python you have - -## Mac OS -* [Set up Selenium & GeckoDriver (Mac)](https://medium.com/dropout-analytics/selenium-and-geckodriver-on-mac-b411dbfe61bc) +**1.** Navigate to the facebook-downloader directory +``` +cd facebook-downloader +``` +**2.** Find the `install.ps1` script and run it +``` +.\install.ps1 +``` +> The installation scripts will download and setup geckodriver, then install **facebook-downloader**. # Usage ``` @@ -55,7 +54,7 @@ facebook_downloader # Docker ``` - docker run -it -v $PWD/downloads:/app/downloads facebook-downloader + docker run --tty --volume $PWD/downloads:/app/downloads my-facebook-downloader ``` @@ -68,6 +67,6 @@ facebook_downloader # Donations If you would like to donate, you could Buy A Coffee for the developer using the button below -Buy Me A Coffee + Your support will be much appreciated! diff --git a/facebook_downloader/__init__.py b/facebook_downloader/__init__.py index e69de29..401aedc 100644 --- a/facebook_downloader/__init__.py +++ b/facebook_downloader/__init__.py @@ -0,0 +1,2 @@ +__author__ = "Richard Mwewa" +__version__ = "1.4.0" \ No newline at end of file diff --git a/facebook_downloader/downloader.py b/facebook_downloader/downloader.py index 01af498..90e8852 100644 --- a/facebook_downloader/downloader.py +++ b/facebook_downloader/downloader.py @@ -8,10 +8,11 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions +from . import __version__, __author__ + class FacebookDownloader: def __init__(self): - self.__program_version_number = "1.4.0" self.__base_url = "https://getfvid.com" self.__update_check_endpoint = "https://api.github.com/repos/rly0nheart/facebook-downloader/releases/latest" self.__home_directory = os.path.expanduser("~") @@ -21,12 +22,12 @@ class FacebookDownloader: __option.add_argument('--headless') self.__driver = webdriver.Firefox(options=__option) - parser = argparse.ArgumentParser(description='facebook-downloader — by Richard Mwewa', + parser = argparse.ArgumentParser(description=f'facebook-downloader — by {__author__}', epilog='Facebook video downloader.') parser.add_argument('url', help='facebook video url') parser.add_argument('-a', '--audio', help='download file as audio', action='store_true') parser.add_argument('-o', '--output', help='output filename', default="") - parser.add_argument('-v', '--version', action='version', version=self.__program_version_number) + parser.add_argument('-v', '--version', action='version', version=__version__) self.__args = parser.parse_args() @staticmethod @@ -55,36 +56,34 @@ class FacebookDownloader: :rtype: str """ return f""" - facebook-downloader v{self.__program_version_number} Copyright (C) 2023 Richard Mwewa + facebook-downloader v{__version__} Copyright (C) 2022-2023 Richard Mwewa This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. """ - def check_updates(self) -> None: + def check_updates(self): """ Checks if the program's version tag matches the tag of the latest release on GitHub. If the tags match, assume the program is up-to-date. - - :return: None """ with requests.get(self.__update_check_endpoint) as response: - if response.json()['tag_name'] != self.__program_version_number: - print(f"* A new release is available -> facebook-downloader v{response.json()['tag_name']}.\n" + remote_version = response.json().get('tag_name') + if remote_version != __version__: + print(f"* A new release is available -> facebook-downloader v{remote_version}.\n" f"* Run 'pip install --upgrade facebook-downloader' to get the updates.\n") - else: - pass def __get_download_type_element(self) -> str: """ Gets the web element according to the specified command-line arguments. + - HD: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[1]/a - - SD: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[2]/a - - Audio: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[3]/a + ELements + -------- + - HD: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[1]/a + - SD: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[2]/a + - Audio: /html/body/div[2]/div/div/div[1]/div/div[2]/div/div[3]/p[3]/a :return: Web element """ @@ -102,13 +101,11 @@ class FacebookDownloader: :return: None """ # Construct and create the directory if it doesn't already exist - os.makedirs(os.path.join(self.__home_directory, "facebook-videos"), exist_ok=True) + os.makedirs(os.path.join(self.__home_directory, "facebook-downloader"), exist_ok=True) def download_video(self): """ Opens https://getfvid.com with selenium and uses the specified facebook video link as a query. - - :return: """ # Open the base url. self.__driver.get(self.__base_url) diff --git a/facebook_downloader/main.py b/facebook_downloader/main.py index 645d67b..dddb5a0 100644 --- a/facebook_downloader/main.py +++ b/facebook_downloader/main.py @@ -1,7 +1,7 @@ from facebook_downloader.downloader import FacebookDownloader -def run(): +def start_downloader(): try: # Initialise the FaceBookDownloader instance. program = FacebookDownloader() diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 0000000..893b107 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,27 @@ +# Define URL for GeckoDriver +$geckoURL = "https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-win64.zip" + +# Define target directories for installation +$geckoDir = "$env:USERPROFILE\facebook-downloader\GeckoDriver" + +# Function to download a file +function DownloadFile([string]$url, [string]$path) { + Invoke-WebRequest -Uri $url -OutFile $path +} + +# Check if GeckoDriver directory exists, if not create and download +if (-Not (Test-Path $geckoDir)) { + New-Item -Path $geckoDir -ItemType Directory + Write-Host "Downloading GeckoDriver..." + DownloadFile $geckoURL "$geckoDir\geckodriver.zip" + + # Unzipping the GeckoDriver + Expand-Archive -Path "$geckoDir\geckodriver.zip" -DestinationPath $geckoDir + Remove-Item "$geckoDir\geckodriver.zip" +} + +# Add the geckodriver directory to PATH +[Environment]::SetEnvironmentVariable("PATH", [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User) + ";$geckoDir", [EnvironmentVariableTarget]::User) + +pip install . +Write-Host "Setup complete." diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..6034c46 --- /dev/null +++ b/install.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Download geckodriver .tar.gz file and pipe it to 'tar' to extract the geckodriver binary directly into /usr/bin. +curl -L https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz | \ + tar xz -C /usr/bin + +# Install Python packages defined in the current directory's setup.py/pyproject.toml file. (pyproject.toml in this case) +pip3 install . +echo "Setup complete." \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 5e495f6..9adf642 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,9 +25,9 @@ classifiers = [ packages = ["facebook_downloader"] [project.urls] -homepage = "https://www.bellingcat.com" +homepage = "https://pypi.org/project/facebook-downloader" documentation = "https://github.com/bellingcat/facebook-downloader/wiki" repository = "https://github.com/bellingcat/facebook-downloader" [project.scripts] -facebook_downloader = "facebook_downloader.main:run" +facebook_downloader = "facebook_downloader.main:start_downloader" diff --git a/uninstall.ps1 b/uninstall.ps1 new file mode 100644 index 0000000..6bf1e9f --- /dev/null +++ b/uninstall.ps1 @@ -0,0 +1,26 @@ +# Define target directory for removal +$geckoDir = "$env:USERPROFILE\facebook-downloader\GeckoDriver" + +# Function to remove directory +function RemoveDir([string]$dirPath) { + if (Test-Path $dirPath) { + Remove-Item -Path $dirPath -Recurse -Force + Write-Host "Removed directory: $dirPath" + } else { + Write-Host "Directory $dirPath does not exist." + } +} + +# Remove GeckoDriver directory +RemoveDir $geckoDir + +# Remove the geckodriver directory from PATH +$pathEnv = [Environment]::GetEnvironmentVariable("PATH", [EnvironmentVariableTarget]::User) +$newPath = ($pathEnv -split ";" | Where-Object { $_ -ne $geckoDir }) -join ";" +[Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::User) +Write-Host "Removed GeckoDriver directory from PATH." + +# Uninstall facebook-downloader Python package +pip uninstall facebook-downloader -y + +Write-Host "Cleanup complete." diff --git a/uninstall.sh b/uninstall.sh new file mode 100644 index 0000000..f917a16 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Remove the geckodriver binary from /usr/bin +sudo rm /usr/bin/geckodriver -v + +# Uninstall tor2tor +pip3 uninstall facebook-downloader -y -v +echo "Cleanup complete." \ No newline at end of file