optioncreator, extra options

config now has an optioncreator property that will allow another module to select how to prompt for a property
resolutions and archive options have been added to config file for sorting functionality
This commit is contained in:
ryuslash 2010-03-17 23:11:18 +01:00
parent 8e101c92f9
commit 4a9cc7e2b6
3 changed files with 158 additions and 116 deletions

189
4grab.py
View file

@ -23,6 +23,7 @@ import optparse
import sys import sys
import config import config
import download import download
import progressbar import progressbar
@ -31,15 +32,14 @@ def raw_input_with_default(default, prompt):
if inp == "": if inp == "":
return default return default
return inp return inp
config._optioncreator = raw_input_with_default
base_url = "http://boards.4chan.org/" base_url = "http://boards.4chan.org/"
parser = optparse.OptionParser() parser = optparse.OptionParser()
downloader = download.Downloader(progressbar.Progress) downloader = download.Downloader(progressbar.Progress)
conf = config.Configuration()
conf.set_optioncreator(raw_input_with_default)
def walk_with_wizard(baseurl): def walk_with_wizard(baseurl):
conf = config.Configuration()
wzrd_msg = "Pilates! *SHAZAM* Here they come!" wzrd_msg = "Pilates! *SHAZAM* Here they come!"
print "Alright, let me put on my robe and wizard hat." print "Alright, let me put on my robe and wizard hat."
@ -63,8 +63,8 @@ def walk_with_wizard(baseurl):
[thread]) [thread])
else: else:
inp = raw_input("Which category would you like to download? ") inp = raw_input("Which category would you like to download? ")
conf.set_category(inp) conf.set_categories([inp])
baseurl = "%s%s/" % (baseurl, conf.get_category()) baseurl = "%s%s/" % (baseurl, conf.get_categories()[0])
print wzrd_msg print wzrd_msg
t = downloader.get_thread_links(baseurl) t = downloader.get_thread_links(baseurl)
@ -75,102 +75,109 @@ def walk_with_wizard(baseurl):
print "Failed: ", failed print "Failed: ", failed
print "Total: ", total print "Total: ", total
parser.set_usage( def parse_commands():
"""%prog [options] conf = config.Configuration()
parser.set_usage(
"""%prog [options]
4grab Copyright (C) 2009-2010 ryuslash 4grab Copyright (C) 2009-2010 ryuslash
This program comes with ABSOLUTELY NO WARRANTY. This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions.""") under certain conditions.""")
parser.add_option("-e", parser.add_option("-e",
nargs=2, nargs=2,
dest="confval", dest="confval",
metavar="CONF VALUE", metavar="CONF VALUE",
help="Set configuration option CONF to be VALUE") help="Set configuration option CONF to be VALUE")
parser.add_option("-c", parser.add_option("-c",
"--category", "--category",
dest="tempcat", dest="tempcat",
metavar="CATEGORY", metavar="CATEGORY",
help="Set the category to CATEGORY only for this run") help="Set the category to CATEGORY only for this run")
parser.add_option("-t", parser.add_option("-t",
"--thread", "--thread",
dest="thread", dest="thread",
metavar="THREAD", metavar="THREAD",
help="Download only THREAD. If THREAD is only an ID, " help="Download only THREAD. If THREAD is only an ID, "
"CATEGORY must also be set. Otherwise, no problem :-)") "CATEGORY must also be set. Otherwise, no problem :-)")
parser.add_option("-w", parser.add_option("-w",
"--wizard", "--wizard",
action="store_true", action="store_true",
dest="wizard", dest="wizard",
help="I'll put on my robe and wizard hat and help you " help="I'll put on my robe and wizard hat and help you "
"get some of those pictures you like") "get some of those pictures you like")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if options.confval and (options.tempcat if options.confval and (options.tempcat
or options.thread or options.thread
or options.wizard): or options.wizard):
print "Can't configure something and do something else too." print "Can't configure something and do something else too."
exit(1)
if options.wizard and (options.tempcat
or options.thread
or options.confval):
print "Can't take a walk with the wizard and do something else too."
exit(1)
if options.confval:
if not conf.option_exists(options.confval[0]):
print ("%s: error: %s is not a "
"valid configuration option") % (sys.argv[0],
options.confval[0])
exit(1) exit(1)
print "Setting", options.confval[0], "to", options.confval[1]
conf.set_option(options.confval[0],
options.confval[1])
conf.save()
exit(0)
elif options.wizard: if options.wizard and (options.tempcat
try: or options.thread
walk_with_wizard(base_url) or options.confval):
except KeyboardInterrupt: print "Can't take a walk with the wizard and do something else too."
print exit(1)
print "Alright, no more wizard hat and robe then. Goodbye"
exit(0)
elif options.thread: if options.confval:
try: if not conf.option_exists(options.confval[0]):
if options.thread[:7] == "http://": print ("%s: error: %s is not a valid configuration option"
t = downloader.get_image_links("", [options.thread]) % (sys.argv[0], options.confval[0]))
elif options.tempcat:
url = "%s%s/res/" % (base_url, options.tempcat)
t = downloader.get_image_links(url, [options.thread])
else:
print ("if THREAD is not an absolute URL, "
"CATEGORY must also be specified")
exit(1) exit(1)
(skipped, failed, downloaded, total) = downloader.get_images(t) print "Setting", options.confval[0], "to", options.confval[1]
print "Downloaded: ", downloaded conf.set_option(options.confval[0],
print "Skipped: ", skipped options.confval[1])
print "Failed: ", failed conf.save()
print "Total: ", total exit(0)
except KeyboardInterrupt:
print
print "Goodbye"
exit(0)
elif options.tempcat: elif options.wizard:
conf.set_category(options.tempcat) try:
walk_with_wizard(base_url)
except KeyboardInterrupt:
print
print "Alright, no more wizard hat and robe then. Goodbye"
exit(0)
base_url = "%s%s/" % (base_url, conf.get_category()) elif options.thread:
try:
if options.thread[:7] == "http://":
t = downloader.get_image_links("", [options.thread])
elif options.tempcat:
url = "%s%s/res/" % (base_url, options.tempcat)
t = downloader.get_image_links(url, [options.thread])
else:
print ("if THREAD is not an absolute URL, "
"CATEGORY must also be specified")
exit(1)
(skipped, failed, downloaded, total) = downloader.get_images(t)
print "Downloaded: ", downloaded
print "Skipped: ", skipped
print "Failed: ", failed
print "Total: ", total
except KeyboardInterrupt:
print
print "Goodbye"
exit(0)
try: elif options.tempcat:
t = downloader.get_thread_links(base_url) conf.set_categories([options.tempcat])
t = downloader.get_image_links(base_url, t)
(skipped, failed, downloaded, total) = downloader.get_images(t) #base_url = "%s%s/" % (base_url, conf.get_categories())
print "Downloaded: ", downloaded
print "Skipped: ", skipped if __name__ == "__main__":
print "Failed: ", failed conf = config.Configuration()
print "Total: ", total parse_commands()
except KeyboardInterrupt: for category in conf.get_categories():
print base_url = "%s%s/" % (base_url, category)
print "So you don't want these images? Fine! I'll stop then." try:
t = downloader.get_thread_links(base_url)
t = downloader.get_image_links(base_url, t)
(skipped, failed, downloaded, total) = downloader.get_images(t)
print "Downloaded: ", downloaded
print "Skipped: ", skipped
print "Failed: ", failed
print "Total: ", total
except KeyboardInterrupt:
print
print "So you don't want these images? Fine! I'll stop then."

View file

@ -21,21 +21,19 @@ import os
import ConfigParser import ConfigParser
import sys import sys
# Get our reference point. preferably $HOME.
homedir = os.getenv("HOME") homedir = os.getenv("HOME")
if homedir is None: if homedir is None:
homedir = os.path.dirname(sys.argv[0]) homedir = os.path.dirname(sys.argv[0])
class _Configuration(object): class _Configuration(object):
def __init__(self): def __init__(self, optioncreator):
self.filename = os.path.join(os.path.join(homedir, ".4grab"), "config.cfg") self.filename = os.path.join(os.path.join(homedir, ".4grab"), "config.cfg")
self.configparser = ConfigParser.RawConfigParser() self.configparser = ConfigParser.RawConfigParser()
self.optioncreator = optioncreator
self.check()
self.configparser.read(self.filename) self.configparser.read(self.filename)
print "__init__"
def set_optioncreator(self, optioncreator):
self.optioncreator = optioncreator
def check(self): def check(self):
changed = False changed = False
@ -55,6 +53,17 @@ class _Configuration(object):
"you would like the " "you would like the "
"downloads to go: ") "downloads to go: ")
changed = True changed = True
# locations/archive
if not self.configparser.has_option("locations", "archive"):
self.create_option("locations",
"archive",
os.path.join(self.configparser.get("locations",
"download_base"),
".arch"),
"Please enter where in {download_base} you "
"would like to store archived images (used for "
"checking what to download): ")
changed = True
# settings # settings
if not self.configparser.has_section("settings"): if not self.configparser.has_section("settings"):
self.configparser.add_section("settings") self.configparser.add_section("settings")
@ -67,7 +76,15 @@ class _Configuration(object):
"category you would like " "category you would like "
"to download from: ") "to download from: ")
changed = True changed = True
# settings/resolutions
if not self.configparser.has_option("settings", "resolutions"):
self.create_option("settings",
"resolutions",
"1600x1050,1900x1200,1900x1080",
"Please enter your preferred "
"resolutions (* for all)")
changed = True
# save
if changed: if changed:
self.save() self.save()
@ -79,12 +96,23 @@ class _Configuration(object):
def get_download_location(self): def get_download_location(self):
return self.configparser.get("locations", "download_base") return self.configparser.get("locations", "download_base")
def set_download_location(self, value):
self.configparser.set("locations", "download_base", value)
def get_category(self): def get_archive_location(self):
return self.configparser.get("settings", "categories") return self.configparser.get("locations", "archive")
def set_archive_location(self, value):
self.configparser.set("locations", "archive", value)
def set_category(self, value): def get_categories(self):
self.configparser.set("settings", "category", value) return self.configparser.get("settings", "categories").split(',')
def set_categories(self, value = []):
self.configparser.set("settings", "category", ','.join(value))
def get_resolutions(self):
return self.configparser.get("settings", "resolutions").split(',')
def set_resolutions(self, value = []):
self.configparser.set("settings", "resolutions", ','.join(value))
def option_exists(self, option): def option_exists(self, option):
sections = self.configparser.sections() sections = self.configparser.sections()
@ -93,6 +121,7 @@ class _Configuration(object):
return True return True
return False return False
# Should only be used by the command-line
def set_option(self, option, value): def set_option(self, option, value):
sec = None sec = None
sections = self.configparser.sections() sections = self.configparser.sections()
@ -113,5 +142,15 @@ class _Configuration(object):
configfile = open(self.filename, "w") configfile = open(self.filename, "w")
self.configparser.write(configfile) self.configparser.write(configfile)
_configuration = _Configuration() _configuration = None
def Configuration(): return _configuration _optioncreator = None
def Configuration():
global _optioncreator
global _configuration
if _optioncreator is None:
raise ValueError("optioncreator must be set")
if _configuration is None:
_configuration = _Configuration(_optioncreator)
_configuration.check()
return _configuration

View file

@ -25,10 +25,12 @@ import htmlparser
#import progressbar #import progressbar
import config import config
conf = config.Configuration() def get_savedir():
savedir = conf.get_download_location() conf = config.Configuration()
if not os.path.exists(savedir): savedir = conf.get_download_location()
os.makedirs(savedir) if not os.path.exists(savedir):
os.makedirs(savedir)
return savedir
class Downloader(object): class Downloader(object):
def __init__(self, progress_reporter): def __init__(self, progress_reporter):
@ -106,7 +108,7 @@ class Downloader(object):
i = 1 i = 1
for link in t: for link in t:
progress.show_progress(i) progress.show_progress(i)
filename = os.path.join(savedir, os.path.split(link)[1]) filename = os.path.join(get_savedir(), os.path.split(link)[1])
if not os.path.exists(filename): if not os.path.exists(filename):
tries = 10 tries = 10
while tries > 0: while tries > 0:
@ -127,10 +129,4 @@ class Downloader(object):
return (skipped, failed, downloaded, total) return (skipped, failed, downloaded, total)
if __name__ == "__main__": if __name__ == "__main__":
# Get a file-like object for the 4chan.org w/imgboard print "Don't run me, run 4grab.py"
base_url = "http://boards.4chan.org/" + conf.get_category() + "/"
# Get the hyperlinks.
t = get_thread_links(base_url)
t = get_image_links(base_url, t)
get_images(t)