|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: UTF-8 -*- |
| 3 | +"""Planet cache tool. |
| 4 | +
|
| 5 | +""" |
| 6 | + |
| 7 | +__authors__ = [ "Scott James Remnant <scott@netsplit.com>", |
| 8 | + "Jeff Waugh <jdub@perkypants.org>" ] |
| 9 | +__license__ = "Python" |
| 10 | + |
| 11 | + |
| 12 | +import os |
| 13 | +import sys |
| 14 | +import time |
| 15 | +import dbhash |
| 16 | +import ConfigParser |
| 17 | + |
| 18 | +import planet |
| 19 | + |
| 20 | + |
| 21 | +def usage(): |
| 22 | + print "Usage: planet-cache [options] CACHEFILE [ITEMID]..." |
| 23 | + print |
| 24 | + print "Examine and modify information in the Planet cache." |
| 25 | + print |
| 26 | + print "Channel Commands:" |
| 27 | + print " -C, --channel Display known information on the channel" |
| 28 | + print " -L, --list List items in the channel" |
| 29 | + print " -K, --keys List all keys found in channel items" |
| 30 | + print |
| 31 | + print "Item Commands (need ITEMID):" |
| 32 | + print " -I, --item Display known information about the item(s)" |
| 33 | + print " -H, --hide Mark the item(s) as hidden" |
| 34 | + print " -U, --unhide Mark the item(s) as not hidden" |
| 35 | + print |
| 36 | + print "Other Options:" |
| 37 | + print " -h, --help Display this help message and exit" |
| 38 | + sys.exit(0) |
| 39 | + |
| 40 | +def usage_error(msg, *args): |
| 41 | + print >>sys.stderr, msg, " ".join(args) |
| 42 | + print >>sys.stderr, "Perhaps you need --help ?" |
| 43 | + sys.exit(1) |
| 44 | + |
| 45 | +def print_keys(item, title): |
| 46 | + keys = item.keys() |
| 47 | + keys.sort() |
| 48 | + key_len = max([ len(k) for k in keys ]) |
| 49 | + |
| 50 | + print title + ":" |
| 51 | + for key in keys: |
| 52 | + if item.key_type(key) == item.DATE: |
| 53 | + value = time.strftime(planet.TIMEFMT_ISO, item[key]) |
| 54 | + else: |
| 55 | + value = str(item[key]) |
| 56 | + print " %-*s %s" % (key_len, key, fit_str(value, 74 - key_len)) |
| 57 | + |
| 58 | +def fit_str(string, length): |
| 59 | + if len(string) <= length: |
| 60 | + return string |
| 61 | + else: |
| 62 | + return string[:length-4] + " ..." |
| 63 | + |
| 64 | + |
| 65 | +if __name__ == "__main__": |
| 66 | + cache_file = None |
| 67 | + want_ids = 0 |
| 68 | + ids = [] |
| 69 | + |
| 70 | + command = None |
| 71 | + |
| 72 | + for arg in sys.argv[1:]: |
| 73 | + if arg == "-h" or arg == "--help": |
| 74 | + usage() |
| 75 | + elif arg == "-C" or arg == "--channel": |
| 76 | + if command is not None: |
| 77 | + usage_error("Only one command option may be supplied") |
| 78 | + command = "channel" |
| 79 | + elif arg == "-L" or arg == "--list": |
| 80 | + if command is not None: |
| 81 | + usage_error("Only one command option may be supplied") |
| 82 | + command = "list" |
| 83 | + elif arg == "-K" or arg == "--keys": |
| 84 | + if command is not None: |
| 85 | + usage_error("Only one command option may be supplied") |
| 86 | + command = "keys" |
| 87 | + elif arg == "-I" or arg == "--item": |
| 88 | + if command is not None: |
| 89 | + usage_error("Only one command option may be supplied") |
| 90 | + command = "item" |
| 91 | + want_ids = 1 |
| 92 | + elif arg == "-H" or arg == "--hide": |
| 93 | + if command is not None: |
| 94 | + usage_error("Only one command option may be supplied") |
| 95 | + command = "hide" |
| 96 | + want_ids = 1 |
| 97 | + elif arg == "-U" or arg == "--unhide": |
| 98 | + if command is not None: |
| 99 | + usage_error("Only one command option may be supplied") |
| 100 | + command = "unhide" |
| 101 | + want_ids = 1 |
| 102 | + elif arg.startswith("-"): |
| 103 | + usage_error("Unknown option:", arg) |
| 104 | + else: |
| 105 | + if cache_file is None: |
| 106 | + cache_file = arg |
| 107 | + elif want_ids: |
| 108 | + ids.append(arg) |
| 109 | + else: |
| 110 | + usage_error("Unexpected extra argument:", arg) |
| 111 | + |
| 112 | + if cache_file is None: |
| 113 | + usage_error("Missing expected cache filename") |
| 114 | + elif want_ids and not len(ids): |
| 115 | + usage_error("Missing expected entry ids") |
| 116 | + |
| 117 | + # Open the cache file directly to get the URL it represents |
| 118 | + try: |
| 119 | + db = dbhash.open(cache_file) |
| 120 | + url = db["url"] |
| 121 | + db.close() |
| 122 | + except dbhash.bsddb._db.DBError, e: |
| 123 | + print >>sys.stderr, cache_file + ":", e.args[1] |
| 124 | + sys.exit(1) |
| 125 | + except KeyError: |
| 126 | + print >>sys.stderr, cache_file + ": Probably not a cache file" |
| 127 | + sys.exit(1) |
| 128 | + |
| 129 | + # Now do it the right way :-) |
| 130 | + my_planet = planet.Planet(ConfigParser.ConfigParser()) |
| 131 | + my_planet.cache_directory = os.path.dirname(cache_file) |
| 132 | + channel = planet.Channel(my_planet, url) |
| 133 | + |
| 134 | + for item_id in ids: |
| 135 | + if not channel.has_item(item_id): |
| 136 | + print >>sys.stderr, item_id + ": Not in channel" |
| 137 | + sys.exit(1) |
| 138 | + |
| 139 | + # Do the user's bidding |
| 140 | + if command == "channel": |
| 141 | + print_keys(channel, "Channel Keys") |
| 142 | + |
| 143 | + elif command == "item": |
| 144 | + for item_id in ids: |
| 145 | + item = channel.get_item(item_id) |
| 146 | + print_keys(item, "Item Keys for %s" % item_id) |
| 147 | + |
| 148 | + elif command == "list": |
| 149 | + print "Items in Channel:" |
| 150 | + for item in channel.items(hidden=1, sorted=1): |
| 151 | + print " " + item.id |
| 152 | + print " " + time.strftime(planet.TIMEFMT_ISO, item.date) |
| 153 | + if hasattr(item, "title"): |
| 154 | + print " " + fit_str(item.title, 70) |
| 155 | + if hasattr(item, "hidden"): |
| 156 | + print " (hidden)" |
| 157 | + |
| 158 | + elif command == "keys": |
| 159 | + keys = {} |
| 160 | + for item in channel.items(): |
| 161 | + for key in item.keys(): |
| 162 | + keys[key] = 1 |
| 163 | + |
| 164 | + keys = keys.keys() |
| 165 | + keys.sort() |
| 166 | + |
| 167 | + print "Keys used in Channel:" |
| 168 | + for key in keys: |
| 169 | + print " " + key |
| 170 | + print |
| 171 | + |
| 172 | + print "Use --item to output values of particular items." |
| 173 | + |
| 174 | + elif command == "hide": |
| 175 | + for item_id in ids: |
| 176 | + item = channel.get_item(item_id) |
| 177 | + if hasattr(item, "hidden"): |
| 178 | + print item_id + ": Already hidden." |
| 179 | + else: |
| 180 | + item.hidden = "yes" |
| 181 | + |
| 182 | + channel.cache_write() |
| 183 | + print "Done." |
| 184 | + |
| 185 | + elif command == "unhide": |
| 186 | + for item_id in ids: |
| 187 | + item = channel.get_item(item_id) |
| 188 | + if hasattr(item, "hidden"): |
| 189 | + del(item.hidden) |
| 190 | + else: |
| 191 | + print item_id + ": Not hidden." |
| 192 | + |
| 193 | + channel.cache_write() |
| 194 | + print "Done." |
0 commit comments