2 """The Planet aggregator.
4 A flexible and easy-to-use aggregator for generating websites.
6 Visit http://www.planetplanet.org/ for more information and to download
9 Requires Python 2.1, recommends 2.3.
12 __authors__ = [ "Scott James Remnant <scott@netsplit.com>",
13 "Jeff Waugh <jdub@perkypants.org>" ]
14 __license__ = "Python"
25 from ConfigParser import ConfigParser
27 # Default configuration file path
28 CONFIG_FILE = "config.ini"
30 # Defaults for the [Planet] config section
31 PLANET_NAME = "Unconfigured Planet"
32 PLANET_LINK = "Unconfigured Planet"
34 OWNER_NAME = "Anonymous Coward"
37 FEED_TIMEOUT = 20 # seconds
39 # Default template file list
40 TEMPLATE_FILES = "examples/basic/planet.html.tmpl"
44 def config_get(config, section, option, default=None, raw=0, vars=None):
45 """Get a value from the configuration, with a default."""
46 if config.has_option(section, option):
47 return config.get(section, option, raw=raw, vars=None)
52 config_file = CONFIG_FILE
56 for arg in sys.argv[1:]:
57 if arg == "-h" or arg == "--help":
58 print "Usage: planet [options] [CONFIGFILE]"
61 print " -v, --verbose DEBUG level logging during update"
62 print " -o, --offline Update the Planet from the cache only"
63 print " -h, --help Display this help message and exit"
66 elif arg == "-v" or arg == "--verbose":
68 elif arg == "-o" or arg == "--offline":
70 elif arg.startswith("-"):
71 print >>sys.stderr, "Unknown option:", arg
76 # Read the configuration file
77 config = ConfigParser()
78 config.read(config_file)
79 if not config.has_section("Planet"):
80 print >>sys.stderr, "Configuration missing [Planet] section."
83 # Read the [Planet] config section
84 planet_name = config_get(config, "Planet", "name", PLANET_NAME)
85 planet_link = config_get(config, "Planet", "link", PLANET_LINK)
86 planet_feed = config_get(config, "Planet", "feed", PLANET_FEED)
87 owner_name = config_get(config, "Planet", "owner_name", OWNER_NAME)
88 owner_email = config_get(config, "Planet", "owner_email", OWNER_EMAIL)
92 log_level = config_get(config, "Planet", "log_level", LOG_LEVEL)
93 feed_timeout = config_get(config, "Planet", "feed_timeout", FEED_TIMEOUT)
94 template_files = config_get(config, "Planet", "template_files",
95 TEMPLATE_FILES).split(" ")
97 # Default feed to the first feed for which there is a template
99 for template_file in template_files:
100 name = os.path.splitext(os.path.basename(template_file))[0]
101 if name.find('atom')>=0 or name.find('rss')>=0:
102 planet_feed = urlparse.urljoin(planet_link, name)
106 if config.has_option("Planet", "locale"):
107 # The user can specify more than one locale (separated by ":") as
110 for user_locale in config.get("Planet", "locale").split(':'):
111 user_locale = user_locale.strip()
113 locale.setlocale(locale.LC_ALL, user_locale)
120 print >>sys.stderr, "Unsupported locale setting."
124 planet.logging.basicConfig()
125 planet.logging.getLogger().setLevel(planet.logging.getLevelName(log_level))
126 log = planet.logging.getLogger("planet.runner")
130 log.warning = log.warn
132 # timeoutsocket allows feedparser to time out rather than hang forever on
133 # ultra-slow servers. Python 2.3 now has this functionality available in
134 # the standard socket library, so under 2.3 you don't need to install
135 # anything. But you probably should anyway, because the socket module is
136 # buggy and timeoutsocket is better.
139 feed_timeout = float(feed_timeout)
141 log.warning("Feed timeout set to invalid value '%s', skipping", feed_timeout)
144 if feed_timeout and not offline:
146 from planet import timeoutsocket
147 timeoutsocket.setDefaultSocketTimeout(feed_timeout)
148 log.debug("Socket timeout set to %d seconds", feed_timeout)
151 if hasattr(socket, 'setdefaulttimeout'):
152 log.debug("timeoutsocket not found, using python function")
153 socket.setdefaulttimeout(feed_timeout)
154 log.debug("Socket timeout set to %d seconds", feed_timeout)
156 log.error("Unable to set timeout to %d seconds", feed_timeout)
159 my_planet = planet.Planet(config)
160 my_planet.run(planet_name, planet_link, template_files, offline)
162 my_planet.generate_all_files(template_files, planet_name,
163 planet_link, planet_feed, owner_name, owner_email)
166 if __name__ == "__main__":