1
#(c) 2006 Owen Williams
15
threadclass = PyLucene.PythonThread
18
threadclass = threading.Thread
20
class SynchronizeDialog:
21
def __init__(self, gladefile, app):
23
self._xml = gtk.glade.XML(gladefile, 'synchronize_window','penguintv')
24
self._dialog = self._xml.get_widget("synchronize_window")
25
self._preview_dialog = self._xml.get_widget("sync_preview_window")
26
for key in dir(self.__class__):
28
self._xml.signal_connect(key, getattr(self,key))
30
self._audio_check = self._xml.get_widget("audio_check")
31
self._delete_check = self._xml.get_widget("delete_check")
32
self._move_check = self._xml.get_widget("move_check")
33
self._destination_entry = self._xml.get_widget("dest_entry")
35
self._delete_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_delete', False))
36
self._move_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_move', False))
37
self._audio_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_audio_only', False))
38
self._dest_dir = self._app.db.get_setting(ptvDB.STRING, '/apps/penguintv/sync_dest_dir', "")
39
self._destination_entry.set_text(self._dest_dir)
47
from gnome import gconf
48
self._conf = gconf.client_get_default()
49
self._conf.add_dir('/apps/penguintv',gconf.CLIENT_PRELOAD_NONE)
50
self._conf.notify_add('/apps/penguintv/sync_delete',self.set_sync_delete)
51
self._conf.notify_add('/apps/penguintv/sync_move',self.set_sync_move)
52
self._conf.notify_add('/apps/penguintv/sync_audio_only',self.set_audio_only)
53
self._conf.notify_add('/apps/penguintv/sync_dest_dir',self.set_dest_dir)
55
self._progress_dialog = SynchronizeDialog.SyncProgress(gtk.glade.XML(gladefile, 'sync_progress_window','penguintv'), self._cancel_cb)
56
self._preview_dialog = SynchronizeDialog.SyncPreview(gtk.glade.XML(gladefile, 'sync_preview_window','penguintv'), self._cancel_cb, self._sync_cb)
62
self._destination_entry.grab_focus()
63
return self._dialog.run()
65
def _check_dest_dir(self, dir_to_check):
67
stat = os.stat(dir_to_check)
68
if not os.path.isdir(dir_to_check):
70
self._app.db.set_setting(ptvDB.STRING, '/apps/penguintv/sync_dest_dir',dir_to_check)
71
logging.debug("sync destination OK: %s" % dir_to_check)
74
logging.warning("sync destination FAIL: %s \n %s" % (dir_to_check, str(e)))
79
#hide preview just in case, but don't hide progress because we want to see that it's cancelling
80
self._preview_dialog.hide()
83
self._preview_dialog.hide()
84
self.on_sync_button_clicked(None)
86
def on_browse_button_clicked(self, event):
87
dialog = gtk.FileChooserDialog(_('Select Destination Folder...'),None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
88
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
89
dialog.set_default_response(gtk.RESPONSE_OK)
91
response = dialog.run()
92
if response == gtk.RESPONSE_OK:
93
self._destination_entry.set_text(dialog.get_filename())
96
def on_delete_check_toggled(self, event):
97
self._app.db.set_setting(ptvDB.BOOL, '/apps/penguintv/sync_delete',self._delete_check.get_active())
99
def on_move_check_toggled(self, event):
100
self._app.db.set_setting(ptvDB.BOOL, '/apps/penguintv/sync_move',self._move_check.get_active())
102
def on_audio_check_toggled(self, event):
103
self._app.db.set_setting(ptvDB.BOOL, '/apps/penguintv/sync_audio_only',self._audio_check.get_active())
105
def on_sync_button_clicked(self, event):
106
self._dest_dir = self._destination_entry.get_text()
107
if not self._check_dest_dir(self._dest_dir):
108
dialog = gtk.Dialog(title=_("Destination Error"), parent=None, flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
109
label = gtk.Label(_("The destination you have selected is not valid. \nPlease select another destination and try again."))
110
dialog.vbox.pack_start(label, True, True, 0)
112
response = dialog.run()
117
#sync = ptv_sync.ptv_sync(self._dest_dir, self._delete_check.get_active(), self._audio_check.get_active())
118
move_files = self._move_check.get_active()
119
sync = SynchronizeDialog._sync_thread(self._dest_dir,
120
self._delete_check.get_active(),
122
self._audio_check.get_active())
123
self._progress_dialog.progress_bar.set_fraction(0)
124
self._progress_dialog.progress_label.set_text("")
125
self._progress_dialog.Show()
135
for m_id in sync.pop_delete_list():
136
self._app.delete_media(m_id)
138
self._progress_dialog.progress_bar.pulse()
140
self._progress_dialog.progress_bar.set_fraction(float(p)/float(t))
141
self._progress_dialog.progress_label.set_markup("<i>"+m+"</i>")
143
sync.interrupt() #don't exit loop, just keep going
148
self._progress_dialog.hide()
150
self._progress_dialog.hide()
153
gobject.timeout_add(100,_sync_gen().next)
156
class _sync_thread(threadclass):
157
def __init__(self, dest_dir, delete=False, move=False, audio=False):
158
threadclass.__init__(self)
159
self._dest_dir = dest_dir
160
self._delete = delete
164
self._delete_list = []
173
def pop_delete_list(self):
174
retval = self._delete_list
175
self._delete_list = []
180
sync = ptv_sync.ptv_sync(self._dest_dir, delete=self._delete, move=self._move, audio=self._audio)
182
for event in sync.sync_gen():
184
self.progress = event[0]
185
self.total = event[1]
186
self.message = event[2]
187
# Append to list of media ids to delete from app
188
if event[3] is not None:
189
self._delete_list.append(event[3])
191
sync.interrupt() #don't exit loop
193
print "error copying file:",e
194
self.progress = self.total #just make sure this is done
196
def on_preview_button_clicked(self, event):
197
self._dest_dir = self._destination_entry.get_text()
198
if not self._check_dest_dir(self._dest_dir):
199
dialog = gtk.Dialog(title=_("Destination Error"), parent=None, flags=gtk.DIALOG_MODAL, buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
200
label = gtk.Label(_("The destination you have selected is not valid. Please select another destination and try again."))
201
dialog.vbox.pack_start(label, True, True, 0)
203
response = dialog.run()
207
sync = ptv_sync.ptv_sync(self._dest_dir, delete=self._delete_check.get_active(),
208
move=self._move_check.get_active(),
209
audio=self._audio_check.get_active(),
212
self._preview_dialog.buff.set_text("")
213
self._preview_dialog.Show()
219
for event in sync.sync_gen():
222
#self._preview_dialog.buff.set_text(text)
223
if last_message != event[2]:
224
self._preview_dialog.buff.insert_at_cursor(event[2]+"\n")
225
last_message = event[2]
228
#else:... just yield, let the generator run its course
231
self._preview_dialog.hide()
234
gobject.idle_add(_sync_gen().next)
236
def on_cancel_button_clicked(self, event):
239
def on_synchronize_window_delete_event(self, widget, event):
240
return self._dialog.hide_on_delete()
245
def set_sync_delete(self, client, *args, **kwargs):
246
self._delete_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_delete', False))
248
def set_sync_move(self, client, *args, **kwargs):
249
self._move_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_move', False))
251
def set_audio_only(self, client, *args, **kwargs):
252
self._audio_check.set_active(self._app.db.get_setting(ptvDB.BOOL, '/apps/penguintv/sync_audio_only', False))
254
def set_dest_dir(self, client, *args, **kwargs):
255
self._dest_dir = self._app.db.get_setting(ptvDB.STRING, '/apps/penguintv/sync_dest_dir', "")
256
self._destination_entry.set_text(self._dest_dir)
259
def __init__(self, xml, cancel_cb):
260
self._dialog = xml.get_widget('sync_progress_window')
261
self.progress_bar = xml.get_widget('sync_progressbar')
262
self.progress_bar.set_pulse_step(.05)
263
self.progress_label = xml.get_widget('progress_info_label')
264
self._cancel_cb = cancel_cb
265
for key in dir(self.__class__):
267
xml.signal_connect(key, getattr(self,key))
270
self._dialog.show_all()
275
def on_sync_progress_window_delete_event(self, widget, event):
276
return self._dialog.hide_on_delete()
278
def on_cancel_button_clicked(self, event):
280
self.progress_label.set_markup(_("<i>Cancelling...</i>"))
281
#self.hide() #stay up while the cancel completes
284
def __init__(self, xml, cancel_cb, sync_cb):
285
self._dialog = xml.get_widget('sync_preview_window')
286
self._cancel_cb = cancel_cb
287
self._sync_cb = sync_cb
288
self.buff = gtk.TextBuffer()
289
self._sync_textview = xml.get_widget('sync_textview')
290
self._sync_textview.set_buffer(self.buff)
292
for key in dir(self.__class__):
294
xml.signal_connect(key, getattr(self,key))
297
self._dialog.show_all()
302
def on_sync_preview_window_delete_event(self, widget, event):
303
return self._dialog.hide_on_delete()
305
def on_sync_button_clicked(self, event):
309
def on_cancel_button_clicked(self, event):