├── LICENSE ├── README.md ├── assets ├── logo.png ├── screenshot1.png └── screenshot2.png ├── main.py └── modules ├── categorieEditor.py ├── pictureDownloader.py ├── shuffler.py ├── utilities.py └── videoDownloader.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 |

7 |
8 |

9 | 10 | Logo 11 | 12 | 13 |

PH-DL

14 | 15 |

16 | The PornHub Downloader is a powerfull script used to download and manage both videos and pictures 17 |
18 | Explore the docs » 19 |
20 |
21 | Report Bug 22 | · 23 | Request Feature 24 | · 25 | Join the discord 26 |

27 |

28 | 29 |
30 | Table of Contents 31 |
    32 |
  1. 33 | About The Project 34 | 37 |
  2. 38 |
  3. 39 | Getting Started 40 | 44 |
  4. 45 |
  5. Usage
  6. 46 |
  7. Roadmap
  8. 47 |
  9. Contributing
  10. 48 |
  11. License
  12. 49 |
  13. Contact
  14. 50 |
51 |
52 | 53 | ## About The Project 54 | Image of product 55 | 56 | The script will allow you to download both images and also files 57 | If you don't know what I'm talking about when I say images you can locate them [here (NSFW)](https://www.pornhub.com/albums) 58 | 59 | The script supports what I call categories, when you download a video the script will prompt you to type out a category where it will put the downloaded file there, see the image below 60 | 61 | Image of product 2 62 | 63 | The script takes the full url when downloading the files, that looks like this: 64 | `https://www.pornhub.com/view_video.php?viewkey=ph600dfff994b80` 65 | 66 | ### Built With 67 | 68 | *On inital launch the script will automatically prompt you to install them* 69 | * [Requests](https://github.com/psf/requests) 70 | * [Youtube-Dl](https://github.com/ytdl-org/youtube-dl) 71 | * [BS4](https://www.crummy.com/software/BeautifulSoup/) 72 | * [pynotifier](https://github.com/YuriyLisovskiy/pynotifier) 73 | 74 | ## Getting Started 75 | 76 | To get a local copy up and running follow these simple steps. 77 | 78 | ### Prerequisites 79 | You need to install Python, that can be done [here](https://www.python.org) 80 | 81 | ### Installation 82 | 1. Clone the repo 83 | ```sh 84 | git clone https://github.com/logicguy1/Discord-Nitro-Generator-and-Checker.git 85 | ``` 86 | 87 | 2. Run the files 88 | ```sh 89 | python main.py 90 | ``` 91 | 92 | From there simply say yes to everything the script asks you for (after reading and agreeing of course) and you're set 93 | 94 | ## Usage 95 | After running the files everything should be set-up and ready to go for you, if you want to download a video, press `1` and insert the URL, it will download the files, give you a notification and then you can choose where you want the video to be saved (what category) 96 | 97 | Downloading pictures and albums is a little different since you can either use a single image or a whole album 98 | 99 | Album urls: https://www.pornhub.com/album/70564671 100 | Picture urls: https://www.pornhub.com/photo/803965741 101 | 102 | They get downloaded at the same place in the script 103 | 104 | ## Roadmap 105 | 106 | See the [open issues](https://github.com/logicguy1/PH-DL/issues) for a list of proposed features (and known issues). 107 | 108 | ## Contributing 109 | 110 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 111 | 112 | 1. Fork the Project 113 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 114 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 115 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 116 | 5. Open a Pull Request 117 | 118 | 119 | ## Licence 120 | 121 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 122 | 123 | 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: 124 | 125 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 126 | 127 | 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. 128 | 129 | ## Contact 130 | 131 | Logicguy - [@Drillenissen#4268](https://www.discordapp.com) - logicguy.mailandcontact@gmail.com 132 | 133 | Project Link: [https://github.com/logicguy1/PH-DL](https://github.com/logicguy1/PH-DL) 134 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logicguy1/PH-DL/50b5052bf5c294e4fc13fb2868930291e91fb7be/assets/logo.png -------------------------------------------------------------------------------- /assets/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logicguy1/PH-DL/50b5052bf5c294e4fc13fb2868930291e91fb7be/assets/screenshot1.png -------------------------------------------------------------------------------- /assets/screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logicguy1/PH-DL/50b5052bf5c294e4fc13fb2868930291e91fb7be/assets/screenshot2.png -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "Cloased Beta 1.1" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import time 12 | 13 | print(LICNECE) 14 | 15 | time.sleep(1) 16 | 17 | import os # Standerd python modules 18 | import sys 19 | import traceback 20 | import modules.utilities as utilities 21 | 22 | os.system('cls' if os.name == 'nt' else 'clear') # Clear the LICNECE information to make the screen look nicer 23 | 24 | DEBUG = True 25 | # Check if the required folders are setup 26 | print(" [+] Checking requred folders") 27 | 28 | if not os.path.exists("Video Downloads/") or not os.path.exists("Videos/") or not os.path.exists("Pictures/"): 29 | inp = input(" [!] Missing folders detected, do you wish to create the requred folders? (Y/n) ") 30 | if "y" not in inp.lower() and inp != "": 31 | exit() 32 | 33 | if not os.path.exists("Video Downloads/"): 34 | os.mkdir("Video Downloads") 35 | if not os.path.exists("Videos/"): 36 | os.mkdir("Videos") 37 | if not os.path.exists("Pictures/"): 38 | os.mkdir("Pictures") 39 | 40 | else: 41 | print(" [+] Found all requred folders") 42 | 43 | # Check every module / package and ask the user to install them if they arent installed 44 | 45 | packages = { # Some packages go under a diffrent pip name than what you use to import 46 | "youtube_dl" : "youtube_dl", 47 | "requests" : "requests", 48 | "pynotifier" : "py-notifier", 49 | "bs4" : "bs4" 50 | } 51 | 52 | print("\n [+] Checking requred packages") 53 | 54 | while True: # Will run untill all the packages has been installed and imported successfully 55 | try: 56 | # import youtube_dl # Python packages that needs to be installed 57 | from pynotifier import Notification 58 | from bs4 import BeautifulSoup 59 | import requests 60 | 61 | 62 | print(" [+] All requred packages are installed") 63 | break 64 | except ImportError as e: 65 | package = str(e)[17:-1] 66 | inp = input(f" [!] Missing '{package}', do you wish to install {package}? (Y/n) ") 67 | 68 | if "y" not in inp.lower() and inp != "": 69 | exit() 70 | 71 | utilities.install(packages[package]) 72 | 73 | print("\n [+] Loading Modules") # Load the external files of the project 74 | try: 75 | import modules.videoDownloader as videoDownloader 76 | import modules.pictureDownloader as pictureDownloader 77 | import modules.shuffler as shuffler 78 | import modules.categorieEditor as categoryEditor 79 | 80 | print(" [+] All modules imported successfully") 81 | except ImportError as e: 82 | if DEBUG: 83 | exc_info = sys.exc_info() 84 | traceback.print_exception(*exc_info) 85 | del exc_info 86 | 87 | input(" [!] Falied loading modules, make sure you cloned all the files from the github, press enter to exit") 88 | exit() 89 | 90 | modules = { 91 | "1" : {"function" : videoDownloader.main, "name" : "Download Video"}, 92 | "2" : {"function" : pictureDownloader.main, "name" : "Download album or picture"}, 93 | "3" : {"function" : shuffler.main, "name" : "Shuffle / Unshuffle videos"}, 94 | "4" : {"function" : categoryEditor.main, "name" : "Manage categories"}, 95 | "5" : {"function" : exit, "name" : "Exit"} 96 | } 97 | 98 | while True: 99 | utilities.clear() # Clear the screen 100 | 101 | indx = 0 102 | for key, val in modules.items(): 103 | num = f"[{key}]" 104 | print( 105 | f" {num:<6} {val['name']:<{35 if int(key) < 10 else 34}}", 106 | end = "" if indx % 2 == 0 else "\n" 107 | ) 108 | indx += 1 109 | 110 | if indx % 2 == 1: 111 | print("") 112 | 113 | option = input("\n>>> ") 114 | 115 | modules[option]["function"]() 116 | 117 | input(f"\n [!] Done! Press enter to continue") 118 | -------------------------------------------------------------------------------- /modules/categorieEditor.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "1.0" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import modules.utilities as utilities 12 | 13 | import os 14 | import shutil 15 | 16 | def add_cat(): # Add a category 17 | name = input("\n [?] Name: ") 18 | 19 | os.mkdir(f"Videos/{name}") 20 | 21 | print(f" [+] Created category '{name}'") 22 | 23 | def del_cat(): # Delete a category 24 | name = input("\n [?] Category name: ") 25 | 26 | inp = input(f" [!] Are you sure you want to remove '{inp}', the files cannot be undone (Y/n) ") 27 | if "y" in inp.lower() or inp == "": 28 | os.rmdir(os.mkdir(f"Videos/{name}")) 29 | 30 | print(f" [!] Removed '{name}'") 31 | else: 32 | print(" [-] Canseled") 33 | 34 | def mer_cat(): # Merge category, used to combine 2 categories into 1 35 | name1 = input("\n [?] Category name 1 (The one that will be copied from): ") 36 | name2 = input(" [?] Category name 2 (The one that will be copied to): ") 37 | 38 | print(" [+] Started processing, stand by\n") 39 | 40 | ka = False 41 | sa = False 42 | 43 | path = os.walk(f"Videos/{name1}") # Get all the files in the folder 44 | for root, dirs, files in path: 45 | for i in files: 46 | path1 = f"Videos/{name1}/{i}" 47 | path2 = f"Videos/{name2}/{i}" 48 | 49 | if ka or not os.path.isfile(path2): # ka = Keep Always (BOOL) 50 | shutil.copyfile(path1, path2) 51 | elif sa and os.path.isfile(path2): # sa = Skip Always (BOOl) 52 | continue 53 | elif os.path.isfile(path2): 54 | inp = input(f" [!] Conflict, {i} already exists at destination, (K- keep, S- Skip, KA- Keep Always, SA- Skip Always) ") 55 | 56 | if inp.lower() == "s": 57 | continue 58 | elif inp.lower() == "k": 59 | shutil.copyfile(path1, path2) 60 | elif inp.lower() == "ka": 61 | ka = True 62 | elif inp.lower() == "sa": 63 | sa = True 64 | 65 | def ren_cat(): 66 | name1 = input("\n [?] Name 1 (The one that will be renamed): ") 67 | name2 = input(" [?] Name 2 (What it will be renamed to): ") 68 | 69 | path1 = f"Videos/{name1}" 70 | path2 = f"Videos/{name2}" 71 | 72 | shutil.move(path1, path2) 73 | 74 | def main(): 75 | utilities.clear() 76 | 77 | print(" [+] Current categories\n") 78 | utilities.display_categories(aditionalInfo = False) 79 | print() 80 | 81 | print(""" [1] Add category [2] Remove category 82 | [3] Merge category [4] Rename category""") 83 | 84 | inp = input("\n>>> ") 85 | 86 | if inp == "1": 87 | add_cat() 88 | elif inp == "2": 89 | del_cat() 90 | elif inp == "3": 91 | mer_cat() 92 | elif inp == "4": 93 | ren_cat() 94 | -------------------------------------------------------------------------------- /modules/pictureDownloader.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "1.0" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import modules.utilities as utilities 12 | 13 | from bs4 import BeautifulSoup 14 | import requests 15 | import shutil 16 | import os 17 | 18 | def main(): 19 | utilities.clear() 20 | 21 | URL = input(" [?] Album or picture URL: ") 22 | print("") 23 | 24 | if "album" in URL: 25 | html = requests.get(URL).text 26 | soup = BeautifulSoup(html, 'html.parser') 27 | 28 | title = soup.title.text 29 | 30 | children = [f'https://www.pornhub.com{i.find("a")["href"]}' for i in soup.find("ul", "photosAlbumsListing").children if i != "\n"] 31 | 32 | else: 33 | children = [URL,] 34 | 35 | indx = 1 36 | for i in children: 37 | html = requests.get(i).text 38 | soup = BeautifulSoup(html, 'html.parser') 39 | 40 | try: 41 | img = soup.find("div", "centerImage").find("img")["src"] 42 | except TypeError: 43 | img = soup.find("div", "centerImage").find("video").find("source")["src"] 44 | title = soup.title.text 45 | album = soup.find("div", {"id" : "thumbSlider"}).find("h2").text[8:]#.find("ul")#.children[1] 46 | 47 | if not os.path.isdir(f"Pictures/{title}"): 48 | os.mkdir(f"Pictures/{title}") 49 | 50 | r = requests.get(img, stream = True) 51 | r.raw.decode_content = True 52 | 53 | with open(f"Pictures/{title}/{album} - {i.split('/')[-1]}.{img.split('.')[-1]}".replace("\\", ""),'wb') as f: 54 | shutil.copyfileobj(r.raw, f) 55 | 56 | print(f" [+] Downloaded 'Pictures/{title}/{album} - {i.split('/')[-1]}.{img.split('.')[-1]}', {indx}/{len(children)} - {indx / len(children) * 100:.2f}% ", end = "\r") 57 | 58 | indx += 1 59 | 60 | print("") 61 | -------------------------------------------------------------------------------- /modules/shuffler.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "1.0" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import modules.utilities as utilities 12 | 13 | import os 14 | import shutil 15 | import random 16 | 17 | def shuffle(): # Shuffle all the files in the folder by adding 4 random numbers infront of the file name 18 | utilities.display_categories() 19 | category = input(' [?] Category: ') 20 | print("") # Add newline 21 | 22 | path = os.walk(f"Videos/{category}") # Get all the files in the folder 23 | for root, dirs, files in path: 24 | for i in files: 25 | shutil.move( # Rename the file 26 | f"Videos/{category}/{i}", 27 | f"Videos/{category}/{random.randint(1000, 9999)} # {i}" 28 | ) 29 | print(f" [+] Videos/{category}/{random.randint(1000, 9999)} # {i}") # Print the result for debugging and updating the user on whats going on 30 | 31 | def unshuffle(): # Used to unshuffle the whole list, will preserve file names of those who does not have the numbers in thir name 32 | utilities.display_categories() 33 | category = input(' [?] Category: ') 34 | print("") 35 | 36 | path = os.walk(f"Videos/{category}") # Get all the files in the path 37 | for root, dirs, files in path: 38 | for i in files: 39 | if "#" in i[:7]: # Check if the # is within the first 6 chareters of the filename 40 | shutil.move( # Rename the file 41 | f"Videos/{category}/{i}", 42 | f"Videos/{category}/{i[6:].strip()}" 43 | ) 44 | print(f" [+] Videos/{category}/{i[7:]}") 45 | 46 | def main(): 47 | utilities.clear() 48 | 49 | print(" [1] Shuffle [2] Unshuffle \n") 50 | 51 | inp = input(">>> ") 52 | 53 | if inp == "1": 54 | shuffle() 55 | elif inp == "2": 56 | unshuffle() 57 | else: 58 | print(" [!] Invalid option") 59 | -------------------------------------------------------------------------------- /modules/utilities.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "1.0" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import os 12 | import subprocess 13 | import sys 14 | 15 | def clear(): # Used to clear the screen 16 | os.system('cls' if os.name == 'nt' else 'clear') 17 | print(""" 18 | ██████╗ ██╗ ██╗ ██████╗ ██╗ 19 | ██╔══██╗██║ ██║ ██╔══██╗██║ 20 | ██████╔╝███████║█████╗██║ ██║██║ 21 | ██╔═══╝ ██╔══██║╚════╝██║ ██║██║ 22 | ██║ ██║ ██║ ██████╔╝███████╗ 23 | ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ 24 | """) 25 | 26 | def display_categories(aditionalInfo = True): # Displays the categories 27 | if aditionalInfo: # Usefull in the categorie editor where we dont need to additional information it pastes to the console 28 | print("\n [+] Current categories:\n") 29 | 30 | categories = [f" [-] {x[0][7:]}" for x in os.walk("Videos/")][1:] 31 | print("\n".join(categories)) 32 | 33 | if aditionalInfo: 34 | print("\n [+] Type any of the above (case insentensive) or a new category and it will be created for you") 35 | 36 | def install(package): # Used to install packages 37 | subprocess.check_call([sys.executable, "-m", "pip", "install", package]) 38 | -------------------------------------------------------------------------------- /modules/videoDownloader.py: -------------------------------------------------------------------------------- 1 | LICNECE = """ 2 | Copyright © 2021 Drillenissen#4268 - logicguy.mailandcontact@gmail.com 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | """ 7 | 8 | __version__ = "1.0" 9 | __author__ = "Drillenissen#4268" 10 | 11 | import modules.utilities as utilities 12 | from contextlib import contextmanager 13 | import subprocess 14 | import sys, os 15 | import youtube_dl 16 | import time 17 | from pynotifier import Notification 18 | import os 19 | import shutil 20 | 21 | def main(): 22 | utilities.clear() 23 | url = input(" [?] Video URL: ") 24 | 25 | print(" [+] Downloading stand by\n") 26 | 27 | 28 | ydl = youtube_dl.YoutubeDL({'outtmpl': 'Video Downloads/%(uploader)s - %(title)s - %(id)s.%(ext)s'}) # If anyone knows how to mute the output of this send help :,) 29 | 30 | with ydl: 31 | result = ydl.extract_info( 32 | url, 33 | download = True 34 | ) 35 | 36 | Notification( 37 | title='Download Complete', 38 | description='Finished downloading video', 39 | duration=5, 40 | urgency='normal' 41 | ).send() 42 | 43 | print(f"\n [!] Finished downloading '{result['title']}'") 44 | inp = input(" [?] Do you want to keep the video? (Y/n) ") 45 | 46 | if "y" in inp.lower() or inp == "": 47 | utilities.display_categories() # Show the avaliable categories to the user 48 | 49 | while True: 50 | category = input("\n [?] Category: ") 51 | 52 | if not os.path.exists(f"Videos/{category}"): 53 | inp = input(f" [?] Are you sure you want to create a new category named '{category}'? (Y/n) ") 54 | if "y" in inp.lower() or inp == "": 55 | os.mkdir(f"Videos/{category}") 56 | break 57 | 58 | else: 59 | break 60 | 61 | shutil.move( 62 | f"Video Downloads/{result['uploader']} - {result['title']} - {result['id']}.mp4", 63 | f"Videos/{category}/{result['uploader']} - {result['title']} - {result['id']}.mp4" 64 | ) 65 | 66 | else: 67 | os.remove(f"Video Downloads/{result['uploader']} - {result['title']} - {result['id']}.mp4") 68 | 69 | 70 | #https://www.pornhub.com/view_video.php?viewkey=ph5e80ec51bc6b5 71 | --------------------------------------------------------------------------------