Rubber-stamped by Brady Eidson.
[webbrowser.git] / PlanetWebKit / planet / planet.py
blob72920d735aa3296c386991e580005abb66e8a3d7
1 #!/usr/bin/env python
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
7 the latest version.
9 Requires Python 2.1, recommends 2.3.
10 """
12 __authors__ = [ "Scott James Remnant <scott@netsplit.com>",
13 "Jeff Waugh <jdub@perkypants.org>" ]
14 __license__ = "Python"
17 import os
18 import sys
19 import time
20 import locale
21 import urlparse
23 import planet
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"
33 PLANET_FEED = None
34 OWNER_NAME = "Anonymous Coward"
35 OWNER_EMAIL = ""
36 LOG_LEVEL = "WARNING"
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)
48 else:
49 return default
51 def main():
52 config_file = CONFIG_FILE
53 offline = 0
54 verbose = 0
56 for arg in sys.argv[1:]:
57 if arg == "-h" or arg == "--help":
58 print "Usage: planet [options] [CONFIGFILE]"
59 print
60 print "Options:"
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"
64 print
65 sys.exit(0)
66 elif arg == "-v" or arg == "--verbose":
67 verbose = 1
68 elif arg == "-o" or arg == "--offline":
69 offline = 1
70 elif arg.startswith("-"):
71 print >>sys.stderr, "Unknown option:", arg
72 sys.exit(1)
73 else:
74 config_file = 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."
81 sys.exit(1)
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)
89 if verbose:
90 log_level = "DEBUG"
91 else:
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
98 if not planet_feed:
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)
103 break
105 # Define locale
106 if config.has_option("Planet", "locale"):
107 # The user can specify more than one locale (separated by ":") as
108 # fallbacks.
109 locale_ok = False
110 for user_locale in config.get("Planet", "locale").split(':'):
111 user_locale = user_locale.strip()
112 try:
113 locale.setlocale(locale.LC_ALL, user_locale)
114 except locale.Error:
115 pass
116 else:
117 locale_ok = True
118 break
119 if not locale_ok:
120 print >>sys.stderr, "Unsupported locale setting."
121 sys.exit(1)
123 # Activate logging
124 planet.logging.basicConfig()
125 planet.logging.getLogger().setLevel(planet.logging.getLevelName(log_level))
126 log = planet.logging.getLogger("planet.runner")
127 try:
128 log.warning
129 except:
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.
137 if feed_timeout:
138 try:
139 feed_timeout = float(feed_timeout)
140 except:
141 log.warning("Feed timeout set to invalid value '%s', skipping", feed_timeout)
142 feed_timeout = None
144 if feed_timeout and not offline:
145 try:
146 from planet import timeoutsocket
147 timeoutsocket.setDefaultSocketTimeout(feed_timeout)
148 log.debug("Socket timeout set to %d seconds", feed_timeout)
149 except ImportError:
150 import socket
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)
155 else:
156 log.error("Unable to set timeout to %d seconds", feed_timeout)
158 # run the planet
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__":
167 main()