import locale, os from urlparse import urljoin import RSS ns = RSS.ns def _load_extractors(names): l = [] for s in names: m = __import__(s, globals(), locals(), []) l.append(getattr(m, s)()) return l file_extractors = _load_extractors(("FileStatExtractor", "FileMimeExtractor", "StaticRDFExtractor", "PngCommentExtractor", "JpegCommentExtractor", "JpegExifExtractor", "ThumbnailFileExtractor")) dir_extractors = _load_extractors(("DirTitleExtractor", "DirRDFExtractor")) IMAGE_TYPES = (".png", ".jpg", ".jpeg") sortingmap = { # TODO: extend to contain function? i.e. ((ns.rss10, 'title'), locale.strcoll) "date": (ns.dc, 'date'), "title": (ns.rss10, 'title') } def generate_rss(path, baseurl, verbose=False): # Bit of a hack for os.path.basename to work if path[-1:] == '/': path = path[:-1] rss = RSS.TrackingChannel() channel = {} channel[(ns.rss10, "link")] = baseurl channel[(ns.dc, "title")] = os.path.basename(path) for extractor in dir_extractors: extractor.extract(path, channel) rss.setMD((ns.rss10, "channel"), channel) # TODO: remove the crappy thumbnail check files = [f for f in os.listdir(path) if not f.startswith("thumb-")] ; files.sort() for f in [os.path.join(path, f) for f in files]: if not os.path.isfile(f): continue if not os.path.splitext(f)[1] in IMAGE_TYPES: continue if verbose: import sys; sys.stderr.write("Scanning %s\n" % f) item = {} item[(ns.rss10, 'link')] = urljoin(baseurl, os.path.basename(f)) item[(ns.rss10, 'title')] = os.path.splitext(os.path.basename(f))[0] item[(ns.dc, 'type')] = "image" for extractor in file_extractors: try: extractor.extract(f, item) except Exception,e: import sys; sys.stderr.write("Exception %s for %s\n" % (e, f)) rss.addItem(item, -1) # Set rss:title from dc:title if not channel.has_key((ns.rss10, "title")): channel[(ns.rss10, "title")] = channel[(ns.dc, "title")] # Set rss:description from the optional dc:description if not channel.has_key((ns.rss10, "description")) and channel.has_key((ns.dc, "description")): channel[(ns.rss10, "description")] = channel[(ns.dc, "description")] # If there is not a channel-wide dc:date, set one now if not channel.has_key((ns.dc, "date")): from W3CDate import W3CDate latest = W3CDate("1970-01-01") # Dummy date, would like an epoch variable for item in [rss.getItem(i) for i in rss.listItems()]: thisdate = W3CDate(item[(ns.dc, "date")]) if thisdate > latest: latest = thisdate channel[(ns.dc, "date")] = latest.getISO8601() # Possibly sort the RSS sortkey = channel.get((ns.rawk, "sort-key"), None) if (sortkey): sortorder = channel.get((ns.rawk, "sort-order"), None) def sorter(a, b): aa = rss.getItem(a)[key] ; bb = rss.getItem(b)[key] if sortorder == "up": return locale.strcoll(aa, bb) else: return locale.strcoll(bb, aa) key = sortingmap[sortkey] rss.listItems().sort(sorter) return rss