Make substitutions for most invalid characters rather than stripping them.
[pyTivo/wmcbrine.git] / pyTivoConfigurator.pyw
blob6ea6c2dd1f79afaddb3e7873a83d5c59637c9737
1 from Tkinter import *
2 import tkSimpleDialog, tkFileDialog
3 import os, sys, ConfigParser
5 class EditShare(tkSimpleDialog.Dialog):
7     def __init__(self, parent, title=None, name='', path='', plugin=''):
8         self.name = name
9         self.path = path
10         self.plugin = StringVar()
11         self.plugin.set(plugin)
12         tkSimpleDialog.Dialog.__init__(self, parent, title)
14     def get_dir(self):
15         self.e2.delete(0, END)
16         self.e2.insert(0, os.path.normpath(tkFileDialog.askdirectory()))
18     def body(self, master):
19         Label(master, text="Name:").grid(row=0)
20         Label(master, text="Path:").grid(row=1)
22         self.e1 = Entry(master)
23         self.e2 = Entry(master)
25         if self.name:
26             self.e1.insert(0, self.name)
27         if self.path:
28             self.e2.insert(0, self.path)
30         browse = Button(master, text="Browse", command=self.get_dir)
32         self.e1.grid(row=0, column=1, columnspan=2, sticky=W+E)
33         self.e2.grid(row=1, column=1, sticky=W+E)
34         browse.grid(row=1, column=2)
36         if not self.plugin.get():
37             self.plugin.set('video')
39         for i, name in zip(xrange(3), ('video', 'music', 'photo')):
40             b = Radiobutton(master, text=name, variable=self.plugin, 
41                 value=name).grid(row=i, column=3)
43         return self.e1 # initial focus
45     def apply(self):
46         name = self.e1.get()
47         path = self.e2.get()
48         self.result = name, path, self.plugin.get()
50 class pyTivoConfigurator(Frame):
52     section = None
53         
54     def buildContainerList(self):
55         header = Frame(self)
56         header.pack(fill=X)
57         Label(header, text='Shares').pack(side=LEFT)
58         frame = Frame(self)
59         frame.pack(fill=BOTH, expand=1)
60         scrollbar = Scrollbar(frame, orient=VERTICAL)
61         self.container_list = Listbox(frame, yscrollcommand=scrollbar.set)
62         scrollbar.config(command=self.container_list.yview)
63         scrollbar.pack(side=RIGHT, fill=Y)
64         self.container_list.pack(side=LEFT, fill=BOTH, expand=1)
65         self.container_list.bind("<Double-Button-1>", self.selected)
67     def selected(self, e):
68         if not self.container_list.curselection(): 
69             return
70         index = self.container_list.curselection()[0]
71         self.section = self.container_list.get(index)
73         self.edit()
75     def buildButtons(self):
76         frame = Frame(self)
77         frame.pack(fill=X)
79         quit_button = Button(frame, text="Quit", command=self.quit)
80         quit_button.pack(side=RIGHT)
82         del_button = Button(frame, text='Del', command=self.delete)
83         del_button.pack(side=RIGHT)
85         add_button = Button(frame, text="Add", command=self.add)
86         add_button.pack(side=RIGHT)
88         if sys.platform == 'win32':
89             restart_button = Button(frame, text="Restart pyTivo",
90                                     command=self.restart)
91             restart_button.pack(side=RIGHT)
93     def add(self):
94         share = EditShare(self, title='New Share')
95         if share.result:
96             sharename, path, plugin = share.result
97             self.config.add_section(sharename)
98             self.config.set(sharename, 'type', plugin)
99             self.config.set(sharename, 'path', path)
100             self.updateContainerList()
102     def delete(self):
103         if not self.container_list.curselection(): 
104             return
105         index = self.container_list.curselection()[0]
106         section = self.container_list.get(index)
107         self.config.remove_section(section)
108         self.updateContainerList()
110     def restart(self):
111         import win32serviceutil
112         self.writeConfig()
113         win32serviceutil.RestartService('pyTivo')
115     def edit(self):
116         if not self.section:
117             return
119         name = self.section
120         path = self.config.get(name, 'path')
121         plugin = self.config.get(name, 'type')
123         share = EditShare(self, title='Edit Share', name=name, path=path,
124                           plugin=plugin)
125         if share.result:
126             name, path, plugin = share.result
127             if name != self.section:
128                 self.config.remove_section(self.section)
129                 self.config.add_section(name)
130                 self.section = name
131             self.config.set(name, 'type', plugin)
132             self.config.set(name, 'path', path)
133             self.updateContainerList()
135     def updateContainerList(self):
136         self.writeConfig()
137         self.container_list.delete(0, END)
138         for section in self.config.sections():
139             if not section == 'Server':
140                 self.container_list.insert(END, section)
142     def readConfig(self):
143         self.config = ConfigParser.ConfigParser()
144         self.config.read(self.config_file)
146     def writeConfig(self):
147         self.config.write(open(self.config_file, 'w'))
149     def __init__(self, master=None):
150         Frame.__init__(self, master)
151         self.master.title('pyTivoConfigurator')
152         self.pack(fill=BOTH, expand=1)
154         p = os.path.dirname(__file__)
155         self.config_file = os.path.join(p, 'pyTivo.conf')
157         self.readConfig()
159         self.buildContainerList()
160         self.buildButtons()
162         self.updateContainerList()
164 if __name__ == '__main__':
165     root = Tk()
166     app = pyTivoConfigurator(master=root)
167     app.mainloop()