| #!/usr/bin/env python |
| """The Planet aggregator. |
| |
| A flexible and easy-to-use aggregator for generating websites. |
| |
| Visit http://www.planetplanet.org/ for more information and to download |
| the latest version. |
| |
| Requires Python 2.1, recommends 2.3. |
| """ |
| |
| __authors__ = [ "Scott James Remnant <scott@netsplit.com>", |
| "Jeff Waugh <jdub@perkypants.org>" ] |
| __license__ = "Python" |
| |
| |
| import os |
| import sys |
| import time |
| import locale |
| import urlparse |
| |
| import planet |
| |
| from ConfigParser import ConfigParser |
| |
| # Default configuration file path |
| CONFIG_FILE = "config.ini" |
| |
| # Defaults for the [Planet] config section |
| PLANET_NAME = "Unconfigured Planet" |
| PLANET_LINK = "Unconfigured Planet" |
| PLANET_FEED = None |
| OWNER_NAME = "Anonymous Coward" |
| OWNER_EMAIL = "" |
| LOG_LEVEL = "WARNING" |
| FEED_TIMEOUT = 20 # seconds |
| |
| # Default template file list |
| TEMPLATE_FILES = "examples/basic/planet.html.tmpl" |
| |
| |
| |
| def config_get(config, section, option, default=None, raw=0, vars=None): |
| """Get a value from the configuration, with a default.""" |
| if config.has_option(section, option): |
| return config.get(section, option, raw=raw, vars=None) |
| else: |
| return default |
| |
| def main(): |
| config_file = CONFIG_FILE |
| offline = 0 |
| verbose = 0 |
| |
| for arg in sys.argv[1:]: |
| if arg == "-h" or arg == "--help": |
| print "Usage: planet [options] [CONFIGFILE]" |
| print |
| print "Options:" |
| print " -v, --verbose DEBUG level logging during update" |
| print " -o, --offline Update the Planet from the cache only" |
| print " -h, --help Display this help message and exit" |
| print |
| sys.exit(0) |
| elif arg == "-v" or arg == "--verbose": |
| verbose = 1 |
| elif arg == "-o" or arg == "--offline": |
| offline = 1 |
| elif arg.startswith("-"): |
| print >>sys.stderr, "Unknown option:", arg |
| sys.exit(1) |
| else: |
| config_file = arg |
| |
| # Read the configuration file |
| config = ConfigParser() |
| config.read(config_file) |
| if not config.has_section("Planet"): |
| print >>sys.stderr, "Configuration missing [Planet] section." |
| sys.exit(1) |
| |
| # Read the [Planet] config section |
| planet_name = config_get(config, "Planet", "name", PLANET_NAME) |
| planet_link = config_get(config, "Planet", "link", PLANET_LINK) |
| planet_feed = config_get(config, "Planet", "feed", PLANET_FEED) |
| owner_name = config_get(config, "Planet", "owner_name", OWNER_NAME) |
| owner_email = config_get(config, "Planet", "owner_email", OWNER_EMAIL) |
| if verbose: |
| log_level = "DEBUG" |
| else: |
| log_level = config_get(config, "Planet", "log_level", LOG_LEVEL) |
| feed_timeout = config_get(config, "Planet", "feed_timeout", FEED_TIMEOUT) |
| template_files = config_get(config, "Planet", "template_files", |
| TEMPLATE_FILES).split(" ") |
| |
| # Default feed to the first feed for which there is a template |
| if not planet_feed: |
| for template_file in template_files: |
| name = os.path.splitext(os.path.basename(template_file))[0] |
| if name.find('atom')>=0 or name.find('rss')>=0: |
| planet_feed = urlparse.urljoin(planet_link, name) |
| break |
| |
| # Define locale |
| if config.has_option("Planet", "locale"): |
| # The user can specify more than one locale (separated by ":") as |
| # fallbacks. |
| locale_ok = False |
| for user_locale in config.get("Planet", "locale").split(':'): |
| user_locale = user_locale.strip() |
| try: |
| locale.setlocale(locale.LC_ALL, user_locale) |
| except locale.Error: |
| pass |
| else: |
| locale_ok = True |
| break |
| if not locale_ok: |
| print >>sys.stderr, "Unsupported locale setting." |
| sys.exit(1) |
| |
| # Activate logging |
| planet.logging.basicConfig() |
| planet.logging.getLogger().setLevel(planet.logging.getLevelName(log_level)) |
| log = planet.logging.getLogger("planet.runner") |
| try: |
| log.warning |
| except: |
| log.warning = log.warn |
| |
| # timeoutsocket allows feedparser to time out rather than hang forever on |
| # ultra-slow servers. Python 2.3 now has this functionality available in |
| # the standard socket library, so under 2.3 you don't need to install |
| # anything. But you probably should anyway, because the socket module is |
| # buggy and timeoutsocket is better. |
| if feed_timeout: |
| try: |
| feed_timeout = float(feed_timeout) |
| except: |
| log.warning("Feed timeout set to invalid value '%s', skipping", feed_timeout) |
| feed_timeout = None |
| |
| if feed_timeout and not offline: |
| try: |
| from planet import timeoutsocket |
| timeoutsocket.setDefaultSocketTimeout(feed_timeout) |
| log.debug("Socket timeout set to %d seconds", feed_timeout) |
| except ImportError: |
| import socket |
| if hasattr(socket, 'setdefaulttimeout'): |
| log.debug("timeoutsocket not found, using python function") |
| socket.setdefaulttimeout(feed_timeout) |
| log.debug("Socket timeout set to %d seconds", feed_timeout) |
| else: |
| log.error("Unable to set timeout to %d seconds", feed_timeout) |
| |
| # run the planet |
| my_planet = planet.Planet(config) |
| my_planet.run(planet_name, planet_link, template_files, offline) |
| |
| my_planet.generate_all_files(template_files, planet_name, |
| planet_link, planet_feed, owner_name, owner_email) |
| |
| |
| if __name__ == "__main__": |
| main() |
| |