tinycc-grabber/URLs.py

108 lines
4.9 KiB
Python

import subprocess, json, random, sys, time
class DownloadError(RuntimeError):
"""
Provides the output from Popen.communicate(), the entire tuple, each byte as a bytes string along with the exception (you will probably need to decode it with .decode("utf-8")).
To access it, use something like "except URLs.DownloadError as output:" and then it will be saved as variable output
"""
class NonexistentUrl(BaseException):
"""
Provides the URL that was tried along with the exception.
To access it, use something like "except URLs.NonexistentUrl as url:" and then it will be saved as variable url
"""
class URL:
"""
You CAN change variables inside this!
For example, to archive a specific url, instead of calling GetURL just change instance.url = "id"
NOTE: The url variable DOES NOT contain the tiny.cc/, or the https, or http, or anything! For example, id 62hd would turn into https://tiny.cc/62hd.
"""
def __init__(self, provider="http://tiny.cc", filename="file.json"):
self.pos = 0
self.filename = filename
self.GetConfig()
self.provider = provider
self.url = ""
self.chars = []
temp_str = "abcdefghijklmnopqrstuvwxyz" + "abcdefghijklmnopqrstuvwxyz".upper() + "1234567890"
for character in temp_str:
self.chars.append(character)
del temp_str
#self.incremental = incremental
def GetURL(self, urlRange=(1,10), provider="http://tiny.cc", forceSet=None):
if forceSet is not None:
self.url = forceSet
return self.url
# if self.incremental:
# incrementData = self.GetIncremental()
# self.url = incrementData[0]
# if incrementData[1] == 1:
# return self.url
# for i in range(0,incrementData[1] - 1):
# self.url += self.GetIncremental()[0]
while self.url in list(self.urls) or self.url == "":
self.url = ""
for i in range(0,random.randint(*urlRange)):
self.url += chr(random.choice((random.randint(65,90), random.randint(97,122), random.randint(48,57)))) #first one is uppercase; 2nd is lowercase; 3rd: numbers
return self.url
def GetConfig(self, retconfig=False):
"""
param retconfig (deprecated): Returns the dictionary. **This may use a LOT of ram, and will substantially slow things down**
"""
try:
with open("file.json") as file:
self.urls = json.load(file)
except Exception:
self.urls = {}
if retconfig: return self.urls
def GetDownload(self):
self.j = subprocess.Popen(["""curl -w "%%{redirect_url}" -ILsS %s/%s -o /dev/null --max-redirs 1"""%(self.provider,self.url)], shell=True, executable="/bin/bash", stdout=subprocess.PIPE, stderr=subprocess.PIPE) #https://unix.stackexchange.com/a/515645/401349 and https://unix.stackexchange.com/a/157219/401349
self.output = self.j.communicate()
if self.j.returncode != 0:
if self.j.returncode != 47:
raise DownloadError(self.output)
return self.output, self.url, self.j.returncode
GetResult = GetDownload
def WriteFile(self):
self.urls[self.url] = self.output[0].decode("utf-8").split('\n')[0].replace("\n","")
if self.urls[self.url] == f"tiny.cc/{self.url}" or self.urls[self.url] == f"https://tiny.cc/{self.url}" or self.urls[self.url] == f"http://tiny.cc/{self.url}" or self.urls[self.url] == "":
raise NonexistentUrl(self.url)
with open(self.filename,"w+") as file:
file.write(json.dumps(self.urls))
# def GetIncremental(self):
# raise NotImplementedError
# try:
# self.pos += 1
# if self.char[self.pos] == "0":
# self.lengthpos += 1
# self.pos = 0
# return (self.char[self.pos], self.length[self.lengthpos])
# except (NameError, AttributeError) as ename:
# import traceback
# traceback.print_exc()
# self.char = []
# for item in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890":
# self.char.append(item)
# self.length = (1,2,3,4,5,6,7,8,9,10)
# self.pos = 0
# self.lengthpos = 0
# return (self.char[self.pos],self.length[self.lengthpos])
def wrapper():
"""
Example wrapper
"""
try:
with open("provider") as file:
prov = file.read()
except Exception:
prov = "tiny.cc"
datums = URL(provider=prov) #create instance
datums.GetURL((1,25)) #get a random url with a length from 1 to 6
print(f"Pinging URL {datums.url}") #you can also modify datums.url, you can use that for tracker stuff (just make a wrapper that changes this variable as necessary instead of running GetURL())
datums.GetDownload() #download the url
datums.WriteFile() #write to json file
main = wrapper
if __name__ == "__main__":
main()