#4olderDumper v1.00
#By ~ dark.chaos.0@gmail.com
import os
import sys
import getopt
import pycurl
from StringIO import StringIO
from mimetypes import guess_type
from time import sleep
def post(server, board, thread, post="", image=None, name="", email="", subject="", password="pyegase", proxy=None):
FF_XP2 = {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.5) Gecko/20060719 Firefox/1.5.0.5)',
'Accept': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
'Accept-Language': 'en-us,en;q=0.5',
'Accept-Encoding': 'gzip,deflate',
'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'Referer' : "http://%s.4chan.org/%s/res/%s.html" % (server, board, thread),
}
curl_headers = [v is not None and '%s: %s' % (k, v) or '%s:' % k
for k, v in FF_XP2.items()]
post = [('MAX_FILE_SIZE', '3145728'),
('resto', thread),
('name', name),
('email', email),
('sub', subject),
('com', post),
('pwd', password),
('mode', 'regist'),
]
processor = {"orz":"tmp", "zip":"bin", "img":"dat", "cgi":"nov"}
curl = pycurl.Curl()
curl.setopt(pycurl.SSL_VERIFYPEER, 0)
if proxy:
curl.setopt(pycurl.PROXY, proxy)
curl.setopt(pycurl.URL, "http://%s.4chan.org/%s/imgboard.php" % (processor[server], board))
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.HTTPHEADER, curl_headers)
#curl.setopt(pycurl.POSTFIELDS, urlencode(post))
if image:
post.append(('upfile', (pycurl.FORM_CONTENTTYPE, guess_type(image)[0], pycurl.FORM_FILENAME, os.path.basename(image), pycurl.FORM_FILE, image)))
curl.setopt(pycurl.HTTPPOST, post)
body = StringIO(); header = StringIO()
curl.setopt(pycurl.WRITEFUNCTION, body.write)
curl.setopt(pycurl.HEADERFUNCTION, header.write)
for i in range(5):
try:
curl.perform()
res = body.getvalue()
except KeyboardInterrupt:
return False
except:
print sys.exc_info()[1]
continue
if not res.find("SQLFAILS_") > 0:
break
curl.close()
if (res.find("file entry detected") > 0):
print "Duplicate File Entry"
return False
elif res.find("Flood detected") > 0:
print "Flood Detected"
return False
elif res.find("404") > 0 or res.find("Thread specified does not exist") > 0:
print "404'd"
return True
elif res.find("Updating") > 0:
print "Uploaded", os.path.basename(image)
return True
else:
print "Unknown Error"
z = open("error.html", "w")
z.write(res)
z.close()
return False
def usage():
print """4olderDump - 4chan Folder Dumper
usage : %s [options]
Options and arguments:
-s,--server : Server of the board. (Ex. zip, orz, img) [Required]
-b,--board : Board. (Ex. g, b, v no slashes) [Required]
-t,--thread : Thread id. (Ex. http://zip.4chan.org/board/res/1337.html, 1337 is the Thread id. [Required]
(That means you must make the thread first).
-f,--folder : Path/to/folder. [Required]
-c, : Displays Current Image / Total Images as the comment.
--comment-enabled
-n,--name : Name/Tripcode faggotry. (Ex. Iam##afaggot)
-e,--email : Email. (Noko, Sage)
-S,--subject : Subject.
-p,--password : Password. (For Post deletion)
-h,--help : Display this help.
-w,--wait : Delay between posts. Default : 30 seconds.
-r, : Maxium retries before giving up on uploading an image. Default : 3.
--max-retries
Example:
%s -s img -b b -t 1337331 -f home/shit/CP -c -S "Am I Kewl Yet Guize?"
""" % (os.path.basename(sys.argv[0]), os.path.basename(sys.argv[0]))
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "s:b:t:f:cn:e:S:p:w:r:h", ["-server", "-board", "-thread", "-folder", "-comment-enabled", "-name", "-email", "-subject", "-password", "-wait", "-max-retries", "-help"])
except getopt.GetoptError, err:
print "Error:", str(err)
print ""
usage()
sys.exit(2)
usettings = {}
settings = {"server":"","board":"","thread":"","folder":"","comment":False,"name":"","email":"","subject":"","password":"pyegase","retry":3,"wait":30}
dhelp = False
for o, a in opts:
if o in ("-h", "--help"):
dhelp = True
elif o in ("-s", "--server"):
usettings['server'] = a
elif o in ("-b", "--board"):
usettings['board'] = a
elif o in ("-t", "--thread"):
usettings['thread'] = a
elif o in ("-f", "--folder"):
usettings['folder'] = a
elif o in ("-c", "--comment-enabled"):
usettings['comment'] = True
elif o in ("-n", "--name"):
usettings['name'] = a
elif o in ("-e", "--email"):
usettings['email'] = a
elif o in ("-S", "--subject"):
usettings['subject'] = a
elif o in ("-p", "--password"):
usettings['password'] = a
elif o in ("-r", "--max-retries"):
usettings['retry'] = int(a)
elif o in ("-w", "--wait"):
usettings['wait'] = int(a)
req = ["server", "board", "thread", "folder"]
for k in req:
if k not in settings:
print "Error: Missing required option", k
print ""
usage()
sys.exit(2)
break
settings.update(usettings)
if not os.path.isdir(settings['folder']):
print "Error: Folder",settings['folder'],"does not exist."
print ""
usage()
sys.exit(2)
print "Starting..."
files = os.listdir(settings['folder'])
images = []
for f in files:
if os.path.splitext(os.path.join(settings['folder'],f))[1].lower() in (".gif", ".jpg", ".png", ".jpeg"):
images.append(os.path.join(settings['folder'],f))
print "Dumping", len(images), "images."
i=1
for image in images:
print "Dumping image %d of %d." % (i,len(images))
comment = ("Image %d of %d." % (i,len(images))) if settings['comment'] else ""
for r in range(settings['retry']):
z = post(settings['server'], settings['board'], settings['thread'], comment, image, settings['name'], settings['email'], settings['subject'], settings['password'])
if (z): break
print "Waiting..."
sleep(settings['wait'])
i += 1
print "Done!"
if __name__ == "__main__":
main()
raw_input()