comparison python/html2flux.py @ 649:fbfc02ea7d8e

make our menu generator slightly less vulgar
author Jeff Hammel <k0scist@gmail.com>
date Sat, 22 Mar 2014 01:15:26 -0700
parents a43d0205f80b
children c26ec5ea9b9a
comparison
equal deleted inserted replaced
648:c6d3bfb2a21c 649:fbfc02ea7d8e
11 11
12 x-form -> internal format: 12 x-form -> internal format:
13 13
14 ('submenu name': [('program label', 'command'), 14 ('submenu name': [('program label', 'command'),
15 ('another program label', 'command2')]) 15 ('another program label', 'command2')])
16
17 - add graphterm: graphterm (should be in ~/k0s/)
18 * if a menu has a single item, that is *the* implementor to that interface! :)
19 - display fluxbox menu items by `title` attribute, if possible
20 * (see class-based usage below)
21 - something about && for joining
22 - class-based usage (class="shell|...")
23 * and is the shell persistent? small? etc.
24 * also, sudo! (or other access related thing)
25 * resolve: xmessage v gmessage v xosd_cat etc
26 * classes: shell, root, message
27 - an easier way of editing o_O
28 * add an item to a menu
29 * submenu
30 - utility to find missing commands
31 - utility to add command + (e.g. ubuntu) install
32 - python package for all of this
33 * ...which also sets up the whole html2flux thing
34 - ....and the 50 billion dollar problem is:
35 How to integrate $(this) and http://k0s.org/portfolio/ubuntu-packages.txt
36 * these should have classifiers and ultimately work in to toolbox
37 - can a workflow be mapped to a (X; and, tbf, hierarchal) menu?!?
38 * YOU'RE SEEING IT, RIGHT?
39 - that said, a hierachal menu...ain't the best; maybe something like
40 dasher....
41 - to that effect, amonst others, menu items of the same set
42 should be added multiple places. that is to say, the menu item
43 indicated as `[foo][bar]fleem` could also live under
44 `[bar][foo]fleem`
16 """ 45 """
17 46
18 import optparse 47 import argparse
19 import os 48 import os
20 import sys 49 import sys
21 from lxml import etree 50 from lxml import etree
22 from lsex import lsex # local import 51 from lsex import lsex # local import
23 52
53 string = (str, unicode)
54
24 # available executables 55 # available executables
25 executables = set([i.rsplit('/', 1)[-1] for i in lsex() ]) 56 executables = set([os.path.basename(i) for i in lsex() ])
26 57
27 # TODO: next generation 58 # TODO: next generation
28 # class HtmlMenu 59 # class HtmlMenu
29 # def _init__(self, html): 60 # def _init__(self, html):
30 # if isinstance (html, string): 61 # if isinstance (html, string):
67 if child.tag == 'dl': 98 if child.tag == 'dl':
68 menu_items.append(readmenu(child, output, top=False)) 99 menu_items.append(readmenu(child, output, top=False))
69 100
70 return (name, menu_items) 101 return (name, menu_items)
71 102
103
72 def printflux(name, menu, output, top=True): 104 def printflux(name, menu, output, top=True):
73 """ 105 """
106 print menu in fluxbox notation
107
74 - output: file-like object for writing 108 - output: file-like object for writing
75 """ 109 """
110
111 if not menu:
112 return
76 113
77 # print [submenu] tag for this menu 114 # print [submenu] tag for this menu
78 name = name or '' 115 name = name or ''
79 if not top: 116 if not top:
80 print >> output, '[submenu] (%s)' % name 117 print >> output, '[submenu] (%s)' % name
92 if not top: 129 if not top:
93 print >> output, '[end]' 130 print >> output, '[end]'
94 131
95 def printmenu(dl, output): 132 def printmenu(dl, output):
96 name, menu = readmenu(dl, output) 133 name, menu = readmenu(dl, output)
97 printflux(name, menu, output) 134 if isinstance(output, string):
135 with open(output, 'w') as f:
136 printflux(name, menu, f)
137 else:
138 # file-like object
139 printflux(name, menu, output)
98 140
99 def main(args=sys.argv[1:]): 141 def main(args=sys.argv[1:]):
100 """command line interface""" 142 """command line interface"""
101 143
102 # parse command line option 144 # parse command line
103 usage = '%prog [options] [menu.html]' 145 parser = argparse.ArgumentParser(description=__doc__)
104 parser = optparse.OptionParser(usage=usage, 146 parser.add_argument('htmlfile', metavar='programs.html', nargs='?',
105 description=__doc__) 147 type=argparse.FileType('r'), default=sys.stdin,
106 parser.add_option('--collapse', dest='collapse', 148 help='input file, or read from stdin if ommitted')
149 parser.add_argument('--collapse', dest='collapse',
107 action='store_true', default=False, 150 action='store_true', default=False,
108 help="collapse menus with a single item to that item") 151 help="collapse menus with a single item to that item")
109 parser.add_option('-o', '--output', dest='output', 152 parser.add_argument('-o', '--output', dest='output',
110 help="output file [Default: <stdout>]") 153 help="output file [Default: <stdout>]")
111 options, args = parser.parse_args(args) 154 options = parser.parse_args(args)
112 155
113 # setup input, output 156 # read input
114 if args: 157 html = options.htmlfile.read()
115 htmlfile = file(args[0])
116 else:
117 htmlfile = sys.stdin
118 html = htmlfile.read()
119 fluxout = sys.stdout
120 158
121 # get first element 159 # get first element
122 dom = etree.fromstring(html) 160 dom = etree.fromstring(html)
123 dl = dom.find('.//dl') 161 dl = dom.find('.//dl')
124 162
125 # print to stdout 163 # print to stdout
126 printmenu(dl, fluxout) 164 printmenu(dl, options.output or sys.stdout)
127 165
128 if __name__ == '__main__': 166 if __name__ == '__main__':
129 main() 167 main()