Skip to content

Commit b7debd4

Browse files
update 1.5.0 complete
Finalise Update 1.5.0
2 parents 2c31f1f + 8a7a891 commit b7debd4

File tree

6 files changed

+179
-24
lines changed

6 files changed

+179
-24
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This project is unfinished and only works on the [listed][13] sites currently. M
1414
#### Currently Supported:
1515
- [Rule34][3] (API)
1616
- [E621][4] (API)
17+
- [E6AI][22] (API)
1718
- [E926][5] (API)
1819
- [Furbooru][6] (API)
1920
- [Multporn][7]
@@ -49,6 +50,7 @@ This project is unfinished and only works on the [listed][13] sites currently. M
4950
[19]:https://rule34.art/
5051
[20]:https://2.multporn.net/
5152
[21]:https://github.com/HttpAnimation/NN-Downloader-Linux
53+
[22]:https://e6ai.net/
5254

5355
Further sites can be added. Just open a [support ticket][11] with the URL to the site.
5456

main.py

+33-7
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44
from termcolor import colored
55
from ctypes import windll
66
from time import sleep
7-
from sys import exit
7+
import sys
88
import inquirer
99

10-
version = "1.4.3"
10+
version = "1.5.0"
1111
windll.kernel32.SetConsoleTitleW(f"NN-Downloader | v{version}")
1212
proxy_list = []
1313
header = {"User-Agent":f"nn-downloader/{version} (by Official Husko on GitHub)"}
1414
needed_folders = ["db", "media"]
15-
database_list = ["e621", "furbooru", "rule34"]
15+
database_list = ["e621", "furbooru", "rule34", "e6ai"]
1616
unsafe_chars = ["/", "\\", ":", "*", "?", "\"", "<", ">", "|", "\0", "$", "#", "@", "&", "%", "!", "`", "^", "(", ")", "{", "}", "[", "]", "=", "+", "~", ",", ";"]
1717

18-
DEBUG = True
18+
if sys.gettrace() is not None:
19+
DEBUG = True
20+
else:
21+
DEBUG = False
1922

2023
if os.path.exists("outdated"):
2124
version_for_logo = colored(f"v{version}", "cyan", attrs=["blink"])
@@ -34,6 +37,17 @@
3437

3538
class Main():
3639
def main_startup():
40+
41+
print(colored("Checking for read and write permissions.", "green"))
42+
43+
# Check if the process has read and write permissions
44+
if os.access(os.getcwd(), os.R_OK | os.W_OK):
45+
pass
46+
else:
47+
print(colored("The program is missing read & write permissions! Change the directory or try run as administrator.", "red"))
48+
sleep(300)
49+
sys.exit(0)
50+
3751
os.system("cls")
3852
print(logo)
3953
print("")
@@ -53,7 +67,7 @@ def main_startup():
5367
config = Config_Manager.creator()
5468
print(colored("New Config file generated. Please configure it for your use case and add API keys for needed services.", "green"))
5569
sleep(7)
56-
exit(0)
70+
sys.exit(0)
5771

5872
if checkForUpdates == True:
5973
os.system("cls")
@@ -79,7 +93,7 @@ def main_startup():
7993
print(colored("What site do you want to download from?", "green"))
8094
questions = [
8195
inquirer.List('selection',
82-
choices=['E621', 'E926', 'Furbooru', 'Luscious', 'Multporn', 'Rule34', 'Yiffer']),
96+
choices=['E621', 'E6AI', 'E926', 'Furbooru', 'Luscious', 'Multporn', 'Rule34', 'Yiffer']),
8397
]
8498
answers = inquirer.prompt(questions)
8599
print("")
@@ -113,6 +127,18 @@ def main_startup():
113127
else:
114128
output = E621.Fetcher(user_tags=user_tags, user_blacklist=config["blacklisted_tags"], proxy_list=proxy_list, max_sites=max_sites, user_proxies=config["proxies"], apiUser=apiUser, apiKey=apiKey, header=header, db=database)
115129

130+
if site == "e6ai":
131+
apiUser = config["user_credentials"]["e6ai"]["apiUser"]
132+
apiKey = config["user_credentials"]["e6ai"]["apiKey"]
133+
if oneTimeDownload == True:
134+
with open("db/e6ai.db", "r") as db_reader:
135+
database = db_reader.read().splitlines()
136+
if apiKey == "" or apiUser == "":
137+
print(colored("Please add your Api Key into the config.json", "red"))
138+
sleep(5)
139+
else:
140+
output = E6AI.Fetcher(user_tags=user_tags, user_blacklist=config["blacklisted_tags"], proxy_list=proxy_list, max_sites=max_sites, user_proxies=config["proxies"], apiUser=apiUser, apiKey=apiKey, header=header, db=database)
141+
116142
elif site == "e926":
117143
apiUser = config["user_credentials"]["e926"]["apiUser"]
118144
apiKey = config["user_credentials"]["e926"]["apiKey"]
@@ -203,4 +229,4 @@ def main_startup():
203229
except KeyboardInterrupt:
204230
print("User Cancelled")
205231
sleep(3)
206-
exit(0)
232+
sys.exit(0)

modules/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
# Here are all modules for the sites that are supported
99
from .e621 import E621
10+
from .e6ai import E6AI
1011
from .e926 import E926
1112
from .rule34 import RULE34
1213
from .furbooru import FURBOORU

modules/configManager.py

+19-17
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from termcolor import colored
44
import os
55

6-
def_config_version = 1.4
6+
def_config_version = 1.5
77

88
class Config_Manager():
99

@@ -13,21 +13,23 @@ def creator():
1313
"proxies": True,
1414
"checkForUpdates": True,
1515
"oneTimeDownload": True,
16+
"advancedMode": False,
1617
"user_credentials": {
1718
"e621": {
1819
"apiUser": "",
1920
"apiKey": ""
2021
},
21-
"e926": {
22+
"e6ai": {
2223
"apiUser": "",
2324
"apiKey": ""
2425
},
25-
"furbooru": {
26+
"e926": {
27+
"apiUser": "",
2628
"apiKey": ""
2729
},
28-
"github": {
30+
"furbooru": {
2931
"apiKey": ""
30-
},
32+
}
3133
},
3234
"blacklisted_tags": [
3335
"example1",
@@ -46,10 +48,18 @@ def creator():
4648
def reader():
4749
if os.path.exists("config.json"):
4850
with open("config.json", "r") as cf:
49-
config = json.load(cf)
50-
config_version = config["version"]
51-
52-
if config_version < def_config_version:
51+
try:
52+
config = json.load(cf)
53+
config_version = config["version"]
54+
advanced_mode = config["advancedMode"]
55+
except:
56+
config_version = 0
57+
advanced_mode = False
58+
59+
if advanced_mode == True:
60+
return config
61+
62+
elif config_version < def_config_version and advanced_mode != True:
5363
print(colored("You are using an outdated config version! Old one is backed up. Please reconfigure the new one.", "green"))
5464
if os.path.exists("old_config.json"):
5565
os.remove("old_config.json")
@@ -63,12 +73,4 @@ def reader():
6373
else:
6474
return 0
6575
# 0 means unsuccessful
66-
67-
def compare():
68-
# TODO: Add working config compare method instead of simple config version number
69-
print("how in the hell did you even manage to get this printed?")
70-
71-
def updater():
72-
# TODO: Add working config updater
73-
print("how in the hell did you even manage to get this printed?")
7476

modules/e6ai.py

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from requests.auth import HTTPBasicAuth
2+
import requests
3+
import random
4+
from termcolor import colored
5+
from alive_progress import alive_bar
6+
from time import sleep
7+
from datetime import datetime
8+
import os
9+
10+
from main import unsafe_chars
11+
now = datetime.now()
12+
dt_now = now.strftime("%d-%m-%Y_%H-%M-%S")
13+
14+
class E6AI():
15+
def Fetcher(user_tags, user_blacklist, proxy_list, max_sites, user_proxies, apiUser ,apiKey, header, db):
16+
try:
17+
approved_list = []
18+
page = 1
19+
while True:
20+
URL = f"https://e6ai.net/posts.json?tags={user_tags}&limit=320&page={page}"
21+
if user_proxies == True:
22+
proxy = random.choice(proxy_list)
23+
raw_req = requests.get(URL, headers=header, proxies=proxy, auth=HTTPBasicAuth(apiUser, apiKey))
24+
else:
25+
raw_req = requests.get(URL, headers=header, auth=HTTPBasicAuth(apiUser, apiKey))
26+
27+
req = raw_req.json()
28+
29+
try:
30+
if req["message"] == "You cannot go beyond page 750. Please narrow your search terms.":
31+
print(colored(req["message"] + " (API limit)", "red"))
32+
sleep(5)
33+
break
34+
except:
35+
pass
36+
37+
if req["posts"] == []:
38+
print(colored("No images found or all downloaded! Try different tags.", "yellow"))
39+
sleep(5)
40+
break
41+
42+
elif page == max_sites:
43+
print(colored(f"Finished Downloading {max_sites} of {max_sites} pages.", "yellow"))
44+
sleep(5)
45+
break
46+
47+
else:
48+
for item in req["posts"]:
49+
image_id = item["id"]
50+
image_address = item["file"]["url"]
51+
post_tags1 = item["tags"]["general"]
52+
post_tags2 = item["tags"]["species"]
53+
post_tags3 = item["tags"]["character"]
54+
post_tags4 = item["tags"]["director"]
55+
post_tags5 = item["tags"]["meta"]
56+
post_tags = post_tags1 + post_tags2 + post_tags3 + post_tags4 + post_tags5
57+
image_format = item["file"]["ext"]
58+
user_blacklist_lenght = len(user_blacklist)
59+
passed = 0
60+
61+
for blacklisted_tag in user_blacklist:
62+
if blacklisted_tag in post_tags:
63+
break
64+
else:
65+
passed += 1
66+
if passed == user_blacklist_lenght and str(image_id) not in db and image_address != None:
67+
image_data = {"image_address": image_address, "image_format": image_format, "image_id": image_id}
68+
approved_list.append(image_data)
69+
else:
70+
pass
71+
72+
# Download Each file
73+
with alive_bar(len(approved_list), calibrate=1, dual_line=True, title='Downloading') as bar:
74+
for data in approved_list:
75+
image_address = data["image_address"]
76+
image_format = data["image_format"]
77+
image_id = data["image_id"]
78+
bar.text = f'-> Downloading: {image_id}, please wait...'
79+
if user_proxies == True:
80+
proxy = random.choice(proxy_list)
81+
img_data = requests.get(image_address, proxies=proxy).content
82+
else:
83+
sleep(1)
84+
img_data = requests.get(image_address).content
85+
86+
safe_user_tags = user_tags.replace(" ", "_")
87+
for char in unsafe_chars:
88+
safe_user_tags = safe_user_tags.replace(char, "")
89+
90+
if not os.path.exists(f"media/{dt_now}_{safe_user_tags}"):
91+
os.mkdir(f"media/{dt_now}_{safe_user_tags}")
92+
with open(f"media/{dt_now}_{safe_user_tags}/{str(image_id)}.{image_format}", 'wb') as handler:
93+
handler.write(img_data)
94+
with open("db/e6ai.db", "a") as db_writer:
95+
db_writer.write(f"{str(image_id)}\n")
96+
bar()
97+
98+
print(colored(f"Page {page} Completed", "green"))
99+
approved_list.clear()
100+
page += 1
101+
sleep(5)
102+
103+
return {"status": "ok"}
104+
105+
except Exception as e:
106+
return {"status": "error", "uinput": user_tags, "exception": str(e), "extra": raw_req.content}

requirements.txt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
about-time==4.2.1
2+
alive-progress==3.1.4
3+
ansicon==1.89.0
4+
blessed==1.20.0
5+
certifi==2023.7.22
6+
charset-normalizer==3.3.0
7+
grapheme==0.6.0
8+
idna==3.4
9+
inquirer==3.1.3
10+
jinxed==1.2.0
11+
python-editor==1.0.4
12+
readchar==4.0.5
13+
requests==2.31.0
14+
six==1.16.0
15+
termcolor==2.3.0
16+
urllib3==2.0.6
17+
wcwidth==0.2.8
18+
xmltodict==0.13.0

0 commit comments

Comments
 (0)