def _init_database(self): """Connect to database and set up database if this is the first start of the application.""" self.logger.info('Connecting to global database file...') data_file = save_data_file(self._DATA_FILE) engine = create_engine('sqlite:///' + data_file) SQLSession.configure(bind=engine) if not os.path.exists(data_file): self.logger.info('Initializing database for first start...') SQLBase.metadata.create_all(engine) pool = Pool(name=_('My Computer'), host='localhost', is_local=True) docs_dir = os.environ.get('XDG_DOCUMENTS_DIR', os.path.expanduser('~')) Category(name=_('Documents'), directory=docs_dir, pool=pool) videos_dir = os.environ.get('XDG_VIDEOS_DIR', os.path.expanduser('~')) Category(name=_('Videos'), directory=videos_dir, pool=pool) music_dir = os.environ.get('XDG_MUSIC_DIR', os.path.expanduser('~')) Category(name=_('Music'), directory=music_dir, pool=pool) self.logger.info('Database initialized.') # Auto commit to database GLib.timeout_add_seconds(self._SYNC_INTERVAL, SQLSession.commit) self.logger.info('Global database file connected.')
def _on_pool_bar_response(self, info_bar, response_id): """When pool bar responsed, create or edit pool.""" if response_id != Gtk.ResponseType.OK: info_bar.hide() return pool = info_bar.pool widgets = info_bar.widgets props = {} for (prop, widget) in widgets.items(): props[prop] = widget.get_text().strip() for prop in ('name', 'host', 'port'): if not props[prop]: widgets[prop].set_placeholder_text(_('Required')) return if pool is None: pool = Pool(**props) self._pool_model.add_pool(pool) self._pool_view.expand_all() else: pool.name = props['name'] pool.host = props['host'] pool.port = props['port'] pool.user = props['user'] pool.passwd = props['passwd'] SQLSession.commit() info_bar.hide()
def _on_category_bar_response(self, info_bar, response_id): """When category_bar responsed, create or edit category.""" if response_id != Gtk.ResponseType.OK: info_bar.hide() return category = info_bar.category pool = info_bar.pool widgets = info_bar.widgets name = widgets['name'].get_text().strip() directory = widgets['directory'].get_text().strip() if not name: widgets['name'].set_placeholder_text(_('Required')) return if not directory: widgets['directory'].set_placeholder_text(_('Required')) return if category is None: category = Category(name=name, directory=directory, pool=pool) self._pool_model.add_presentable(category, insert=True) else: category.name = name category.directory = directory SQLSession.commit() info_bar.hide()
def _on_pool_remove(self, action, data): """Remove pool.""" queuing = self._pool_view.selected_presentable pool = queuing.pool if pool.is_local: dialog = Gtk.MessageDialog( self, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, _('The local server should not be removed.'), ) else: dialog = Gtk.MessageDialog( self, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _('Are you sure to remove the server "{}"?\nAll tasks ' 'in the server will be <b>removed!</b>').format(pool.name), use_markup=True) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: # Select the local pool, in order to remove the selected pool local_pool = SQLSession.query(Pool).filter( Pool.is_local == True)[0] iter_ = self._pool_model.get_iter_for_presentable( local_pool.queuing) self._pool_view.selection.select_iter(iter_) # Remove the category iter self._pool_model.remove_pool(pool) SQLSession.delete(pool) SQLSession.commit()
def __init__(self, name, category, options, uris=[], torrent=None, metafile=None): self.name = name self.status = Task._DEFAULT_STATUS self.uris = uris self.torrent = torrent self.metafile = metafile self.options = options self.category = category LoggingMixin.__init__(self) self.logger.info('Adding new task: {}...'.format(self)) self.logger.debug('Task options: {}'.format(options)) SQLSession.add(self) SQLSession.commit() self._init()
def _on_category_remove(self, action, data): """Remove category.""" category = self._pool_view.selected_presentable pool = category.pool if category is pool.default_category: dialog = Gtk.MessageDialog( self, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, _('The default category should not be removed.'), ) else: dialog = Gtk.MessageDialog( self, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _('Are you sure to remove the category "{}"?\nAll tasks ' 'in the category will be moved to the default category.'). format(category.name), ) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: # Move all tasks to default category for task in category.tasks: task.category = pool.default_category pool.default_category.add_task(task) # Remove the category iter self._pool_model.remove_presentable(category) SQLSession.delete(category) SQLSession.commit()
def state(self, state): """Always sync when task state changes.""" if hash(self) and self.state != state: self.status['status'] = state SQLSession.commit() self.emit('changed') else: self.status['status'] = state
def __init__(self, name, directory, pool): self.name = name self.directory = directory self.pool = pool SQLSession.add(self) SQLSession.commit() self._init()
def do_shutdown(self): """When shutdown, finalize database and logging systems.""" self.logger.info('Shutting down database...') SQLSession.commit() SQLSession.close() self._daemon.terminate() self.logger.info('Application quit normally.') logging.shutdown() Gtk.Application.do_shutdown(self)
def __init__(self, name, host, user='', passwd='', port='6800', is_local=False): self.name = name self.user = user self.passwd = passwd self.host = host self.port = port self.is_local = is_local SQLSession.add(self) SQLSession.commit() self._init()
def ui_manager(self): """Get the UI Manager of L{yaner}.""" if self._ui_manager is None: self.logger.info('Initializing UI Manager...') ui_manager = Gtk.UIManager() ui_manager.insert_action_group(self.action_group) try: ui_manager.add_ui_from_file(self._UI_FILE) except GObject.GError: self.logger.exception("Failed to add ui file to UIManager.") SQLSession.close() logging.shutdown() sys.exit(1) else: self.logger.info('UI Manager initialized.') self._ui_manager = ui_manager return self._ui_manager
def _on_task_pause_all(self, action, data): """Pause all the tasks in the selected pool.""" presentable = self._pool_view.selected_presentable if presentable is None or presentable.TYPE != Presentable.TYPES.QUEUING: pools = SQLSession.query(Pool) else: pools = [presentable.pool] for pool in pools: for task in pool.queuing.tasks: task.pause()
def _init(self): GObject.GObject.__init__(self) LoggingMixin.__init__(self) self._queuing = None self._categories = [] self._dustbin = None self._connected = False self._proxy = None if self.default_category is None: self.logger.info('Creating default category for {}.'.format(self)) down_dir = os.environ.get('XDG_DOWNLOAD_DIR', os.path.expanduser('~')) self.default_category = Category(name=_('My Downloads'), directory= down_dir, pool=self) SQLSession.commit() self.do_disconnected() self._keep_connection()
def remove(self): """Remove task.""" if self.is_trashed: self.pool.dustbin.remove_task(self) SQLSession.delete(self) SQLSession.commit()
def __init__(self): """ Create toplevel window of L{yaner}. The window structure is like this: - vbox - toolbar - hpaned - scrolled_window - _pool_view - task_vbox - _task_list_view """ Gtk.Window.__init__(self, title=_('Yaner')) LoggingMixin.__init__(self) self.logger.info('Initializing toplevel window...') self._settings = None self._popups = None # UIManager: Toolbar and menus self._action_group = None self._ui_manager = None self.set_default_size(self.settings.get_uint('width'), self.settings.get_uint('height')) if self.settings.get_boolean('maximized'): self.maximize() self.set_default_icon_name('yaner') # The toplevel vbox vbox = Box(VERTICAL, 0) self.add(vbox) # Toolbar toolbar = self.ui_manager.get_widget('/toolbar') vbox.pack_start(toolbar, expand=False) # HPaned: PoolView as left, TaskVBox as right hpaned = Gtk.HPaned() vbox.pack_start(hpaned) # Right pane vbox = Box(VERTICAL) hpaned.pack2(vbox, True, False) self.task_box = vbox self._task_list_model = TaskListModel() scrolled_window = Gtk.ScrolledWindow() scrolled_window.set_shadow_type(Gtk.ShadowType.IN) scrolled_window.set_size_request(400, -1) vbox.pack_end(scrolled_window) task_list_view = TaskListView(self._task_list_model) task_list_view.set_show_expanders(False) task_list_view.set_level_indentation(16) task_list_view.expand_all() task_list_view.selection.set_mode(Gtk.SelectionMode.MULTIPLE) task_list_view.connect('key-press-event', self._on_task_list_view_key_pressed) task_list_view.connect('button-press-event', self._on_task_list_view_button_pressed) task_list_view.connect('row-activated', self._on_task_list_view_row_activated) scrolled_window.add(task_list_view) self._task_list_view = task_list_view # Left pane scrolled_window = Gtk.ScrolledWindow() scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER) scrolled_window.set_shadow_type(Gtk.ShadowType.IN) scrolled_window.set_size_request(180, -1) hpaned.pack1(scrolled_window, False, False) self._pool_model = PoolModel() pool_view = PoolView(self._pool_model) pool_view.set_headers_visible(False) pool_view.set_show_expanders(False) pool_view.set_level_indentation(16) pool_view.connect('button-press-event', self._on_pool_view_button_pressed) scrolled_window.add(pool_view) self._pool_view = pool_view pool_view.selection.set_mode(Gtk.SelectionMode.SINGLE) pool_view.selection.connect("changed", self._on_pool_view_selection_changed) # Add Pools to the PoolModel for pool in SQLSession.query(Pool): self._pool_model.add_pool(pool) pool_view.expand_all() # Select first iter pool_view.selection.select_iter(self._pool_model.get_iter_first()) # Dialogs self._task_new_dialog = None self._preferences_dialog = None self._about_dialog = None self._category_bar = None self._pool_bar = None # Status icon status_icon = Gtk.StatusIcon(icon_name='yaner') status_icon.connect('activate', self._on_status_icon_activated) status_icon.connect('popup-menu', self._on_status_icon_popup) self.connect('delete-event', self._on_delete_event, status_icon) self.logger.info('Toplevel window initialized.')
def on_got_session_info(deferred): """Set session id the task belongs to.""" self.session_id = deferred.result['sessionId'] SQLSession.commit()