def init_thread(self): logging.debug("RUN INIT LAST.FM") username = FCBase().lfm_login password_hash = pylast.md5(FCBase().lfm_password) self.cache = None try: self.network = pylast.get_lastfm_network(api_key=API_KEY, api_secret=API_SECRET, username=username, password_hash=password_hash) self.cache = Cache(self.network) if FC().proxy_enable and FC().proxy_url: proxy_rul = FC().proxy_url index = proxy_rul.find(":") proxy = proxy_rul[:index] port = proxy_rul[index + 1:] self.network.enable_proxy(proxy, port) logging.info("Enable proxy for last fm" + str(proxy) + str(port)) """scrobbler""" scrobbler_network = pylast.get_lastfm_network(username=username, password_hash=password_hash) self.scrobbler = scrobbler_network.get_scrobbler("fbx", "1.0") except: self.network = None self.scrobbler = None self.controls.statusbar.set_text("Error last.fm connection with %s/%s" % (username, FCBase().lfm_password)) logging.error("Invalid last fm login or password or network problems" + username + FCBase().lfm_password) """ val = show_login_password_error_dialog(_("Last.fm connection error"), _("Verify user and password"), username, FC().lfm_password) if val: FC().lfm_login = val[0] FC().lfm_password = val[1] return False """ return True
def check_for_media(self, args): dirs = [] files = [] for arg in args: if os.path.isdir(arg): dirs.append(arg) elif os.path.isfile(arg) and get_file_extension( arg) in FC().all_support_formats: files.append(arg) if dirs: self.on_add_folders(dirs) elif files: self.on_add_files(files) try: self.play_first_added(files) except: logging.error("Can't to play first added file")
def next(self): bean = self.common_single_random() if bean: return bean bean = self.get_next_bean(FC().repeat_state == const.REPEAT_ALL) if not bean: return self.set_play_icon_to_bean(bean) self.scroll_follow_play_icon() logging.debug("Next bean" + str(bean) + bean.text) return bean
def play(self, bean): self.statusbar.set_text("") if not bean: self.state_stop() return None if not bean.is_file: self.state_stop() return None if not bean.path: bean.path = get_bean_posible_paths(bean) if not bean.path: if not self.fill_bean_from_vk(bean): if self.count_errors < 4: logging.debug("Error happen [%s] %s" % (self.count_errors, FCBase().vk_login)) time.sleep(0.5) self.count_errors += 1 self.next() if bean.path and os.path.isdir(bean.path): self.state_stop() return None if bean.type == FTYPE_RADIO: self.record.show() else: self.record.hide() self.seek_bar.clear() self.count_errors = 0 self.statusbar.set_text(bean.info) self.trayicon.set_text(bean.text) self.movie_window.set_text(bean.text) self.main_window.set_title(bean.text) self.media_engine.play(bean) self.is_scrobbled = False self.start_time = False self.update_info_panel(bean) if not get_file_extension(bean.path) in FC().video_formats: self.set_visible_video_panel(False)
def draw_callback(self, w, cr, levels, s_width, interval, v_step): #levels = a number of volume levels (a number of sticks equals level-1) #s_width - width of stick #interval - interval between sticks #v_step - increase the height of the stick #all parameters must be integer type area_width = w.get_allocation().width area_height = w.get_allocation().height h_step = s_width + interval width = levels * (s_width + interval) - interval height = v_step * (levels - 1) if width < area_width: start_x = (area_width - width) / 2 else: start_x = 1 if height < area_height: start_y = area_height - (area_height - height) / 2 else: start_y = 0 x = start_x y = start_y - 1 label = FC().volume * width / 100.0 + start_x i = 0 while i < levels: color = Gdk.color_parse( "orange red") if x < label else Gdk.color_parse("white") Gdk.cairo_set_source_color(cr, color) cr.move_to(x, start_y) cr.line_to(x + s_width, start_y) cr.line_to(x + s_width, y) cr.line_to(x, y) #cr.close_path() cr.fill() i += 1 x += h_step y -= v_step return True
def on_button_press(self, w, e): if is_empty_click(w, e): w.get_selection().unselect_all() if is_middle_click(e): """to avoid unselect all selected items""" self.stop_emission('button-press-event') if is_left_click(e): # on left click expand selected folders return if is_double_left_click(e): # on middle click play selected beans self.add_to_tab() return if is_rigth_click(e): right_click_optimization_for_trees(w, e) tabhelper = self.controls.perspectives.get_perspective('fs').get_tabhelper() # on right click, show pop-up menu self.tree_menu.clear() self.tree_menu.add_item(_("Append to playlist"), "list-add", lambda: self.add_to_tab(True), None) self.tree_menu.add_item(_("Open in new playlist"), "list-add", self.add_to_tab, None) self.tree_menu.add_separator() self.tree_menu.add_item(_("Add folder here"), "folder-open", self.add_folder, None) self.tree_menu.add_separator() if FC().tabs_mode == "Multi": self.tree_menu.add_item(_("Add folder in new tab"), "folder-open", lambda: self.add_folder(True), None) self.tree_menu.add_item(_("Clear"), "edit-clear", lambda: tabhelper.clear_tree(self.scroll), None) self.tree_menu.add_item(_("Update"), "view-refresh", lambda: tabhelper.on_update_music_tree(self.scroll), None) f_model, f_t_paths = self.get_selection().get_selected_rows() if f_t_paths: model = f_model.get_model() t_paths = [f_model.convert_child_path_to_path(f_t_path) for f_t_path in f_t_paths] row = model[t_paths[0]] paths = [model[t_path][self.path[0]] for t_path in t_paths] row_refs = [Gtk.TreeRowReference.new(model, t_path) for t_path in t_paths] self.tree_menu.add_separator() self.tree_menu.add_item(_("Open in file manager"), "system-file-manager", open_in_filemanager, self.get_selected_bean().path) self.tree_menu.add_item(_("Create folder"), "folder-new", self.create_folder, (model, f_t_paths[0], row)) self.tree_menu.add_item(_("Rename file (folder)"), "edit-find-replace", self.rename_files, (row, self.path[0], self.text[0])) self.tree_menu.add_item(_("Delete file(s) / folder(s)"), "edit-delete", self.delete_files, (row_refs, paths, self.get_iter_from_row_reference)) self.tree_menu.show(e)
def notify_title(self, text): logging.debug("Notify title" + text) self.statusbar.set_text(text) text = normalize_text(text) self.seek_bar.set_text(text) t_bean = FModel(text).create_from_text(text) self.update_info_panel(t_bean) if FC().enable_radio_scrobbler: start_time = str(int(time.time())) self.net_wrapper.execute(self.lastfm_service.report_now_playing, t_bean) if "-" in text and self.chache_text != text: text = self.chache_text self.net_wrapper.execute(self.lastfm_service.report_scrobbled, t_bean, start_time, 200)
def __init__(self, controls): FControl.__init__(self, controls) Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL) self.set_title("Foobnix " + FOOBNIX_VERSION) self.set_position(Gtk.WindowPosition.CENTER) self.set_resizable(True) self.connect("window-state-event", self.on_change_state) self.connect("delete-event", self.hide_window) self.connect("key-press-event", self.on_key_press) try: self.set_icon_from_file( get_foobnix_resourse_path_by_name(const.ICON_FOOBNIX)) except TypeError as e: logging.error(str(e)) self.set_opacity(FC().window_opacity) self.iconified = False
def on_mediakey(self, comes_from, what): if not FC().media_keys_enabled: return logging.debug("Multi media key pressed" + what) """ gets called when multimedia keys are pressed down. """ if what in ['Stop', 'Play', 'Next', 'Previous']: if what == 'Stop': self.controls.state_stop() elif what == 'Play': self.controls.state_play_pause() elif what == 'Next': self.controls.next() elif what == 'Previous': self.controls.prev() else: logging.debug('Got a multimedia key:' + str(what))
def __init__(self, title=None, width=None, height=None): gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) if title: self.set_title(title) self.set_position(gtk.WIN_POS_CENTER) self.set_resizable(False) self.set_border_width(5) try: self.set_icon_from_file (self.get_fobnix_logo()) except TypeError: pass if width and height: self.set_size_request(width, height) self.connect("delete-event", self.hide_window) self.connect("key-press-event", self.on_key_press) self.hide_on_escape = True self.set_opacity(FC().window_opacity) self.is_rendered = True
def task(): tabhelper = self.controls.perspectives.get_perspective( 'fs').get_tabhelper() path = paths[0] FCache().last_music_path = path[:path.rfind("/")] tree = self number_of_tab = tabhelper.page_num(tree.scroll) if in_new_tab: tab_name = unicode(path[path.rfind("/") + 1:]) tabhelper._append_tab(tab_name) tree = tabhelper.get_current_tree() number_of_tab = tabhelper.get_current_page() FCache().music_paths.insert(0, []) FCache().tab_names.insert(0, tab_name) FCache().cache_music_tree_beans.insert(0, {}) elif tree.is_empty(): tab_name = unicode(path[path.rfind("/") + 1:]) vbox = Gtk.VBox() label = Gtk.Label(tab_name + " ") label.set_angle(90) if FC().tab_close_element: vbox.pack_start(tabhelper.button(tree.scroll), False, False) vbox.pack_end(label, False, False) event = self.controls.notetabs.to_eventbox(vbox, tree) event = tabhelper.tab_menu_creator(event, tree.scroll) event.connect("button-press-event", tabhelper.on_button_press) tabhelper.set_tab_label(tree.scroll, event) FCache().tab_names[number_of_tab] = tab_name FCache().music_paths[number_of_tab] = [] for path in paths: if path in FCache().music_paths[number_of_tab]: pass else: FCache().music_paths[number_of_tab].append(path) #self.controls.preferences.on_load() logging.info("New music paths" + str(FCache().music_paths[number_of_tab])) self.controls.update_music_tree(tree, number_of_tab)
def is_dir_with_music(path): list = None try: list = os.listdir(path) except OSError as e: logging.info("Can't get list of dir"+ str(e)) if not list: return False for file in list: full_path = os.path.join(path, file) if os.path.isdir(full_path): if is_dir_with_music(full_path): return True else: if file_extension(file) in FC().all_support_formats: return True return False
def on_button_press(self, w, e): logging.debug("on dm button press") if is_empty_click(w, e): w.get_selection().unselect_all() if is_rigth_click(e): right_click_optimization_for_trees(w, e) try: self.tree_menu.clear() if self.get_selected_bean(): self.tree_menu.add_item(_("Open in file manager"), None, open_in_filemanager, self.get_selected_bean().path) else: self.tree_menu.add_item(_("Open in file manager"), None, open_in_filemanager, FC().online_save_to_folder) self.tree_menu.show(e) except Exception, e: logging.error(e)
def next(self): bean = self.notetabs.next() if not bean: return gap = FC().gap_secs time.sleep(gap) logging.debug("play current bean is %s" % str(bean.text)) if bean.path: if os.path.isdir(bean.path): return None if bean.path.startswith("http://"): if not self.check_path(bean): path = self.net_wrapper.execute( self.vk_service.find_one_track, bean.get_display_name()).path if path: bean.path = path self.play(bean)
def notify_playing(self, pos_sec, dur_sec, bean): if not bean.type or bean.type != FTYPE_RADIO: self.seek_bar.update_seek_status(pos_sec, dur_sec) else: self.seek_bar.fill_seekbar() if pos_sec == 2 or (pos_sec > 2 and (pos_sec % 20) == 0): self.net_wrapper.execute(self.lastfm_service.report_now_playing, bean) if not self.start_time: self.start_time = str(int(time.time())) if not self.is_scrobbled and bean.type != FTYPE_RADIO: ## song should be scrobbled if 90% has been played or played greater than 5 minutes if pos_sec > (dur_sec * 0.9) or pos_sec > (60 * 5): self.is_scrobbled = True self.net_wrapper.execute(self.lastfm_service.report_scrobbled, bean, self.start_time, dur_sec) """download music""" if FC().automatic_online_save and bean.path and bean.path.startswith("http://"): self.dm.append_task(bean)
def load_music_tree(self): tabs = len(FCache().cache_music_tree_beans) tabhelper = self.perspectives.get_perspective('fs').get_tabhelper() for tab in xrange(tabs - 1, -1, -1): tabhelper._append_tab(FCache().tab_names[tab], rows=FCache().cache_music_tree_beans[tab]) if not FCache().cache_music_tree_beans[tab]: self.perspectives.get_perspective('fs').show_add_button() else: self.perspectives.get_perspective('fs').hide_add_button() logging.info("Tree loaded from cache") if FC().update_tree_on_start: def cycle(): for n in xrange(len(FCache().music_paths)): tab_child = tabhelper.get_nth_page(n) tree = tab_child.get_child() self.update_music_tree(tree, n) GLib.idle_add(cycle)
def report_now_playing(self, bean): if not FC().enable_music_scrobbler: logging.debug("Last.fm scrobbler not enabled") return None if not self.get_scrobbler(): logging.warn("no last.fm scrobbler") return None def task(bean): if bean.artist and bean.title: try: bean.artist, bean.title = bean.artist, bean.title self.get_scrobbler().report_now_playing( bean.artist, bean.title) logging.debug("notify %s %s" % (bean.artist, bean.title)) except Exception, e: logging.error( str(e) + "Error reporting now playing last.fm" + str(bean.artist) + str(bean.title)) else:
def on_save(self): if self.proxy_server.get_text(): FC().proxy_url = self.proxy_server.get_text() else: FC().proxy_url = None if self.login_text.get_text(): FC().proxy_user = self.login_text.get_text() else: FC().proxy_user = None if self.password_text.get_text(): FC().proxy_password = self.password_text.get_text() else: FC().proxy_password = None
def dirs(self): frame_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0) frame_box.set_border_width(5) frame_box.show() self.frame = FrameDecorator(_("Music dirs"), frame_box, 0.5, 0.5, border_width=0) self.frame.show() self.frame.set_no_show_all(True) self.tree_controller = SimpleListTreeControl(_("Paths"), None) """buttons""" button_box = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) button_box.show() bt_add = Gtk.Button.new_with_label(_("Add")) bt_add.connect("clicked", self.add_dir) bt_add.set_size_request(80, -1) bt_add.show() bt_remove = Gtk.Button.new_with_label(_("Remove")) bt_remove.connect("clicked", self.remove_dir) bt_remove.set_size_request(80, -1) bt_remove.show() empty = Gtk.Label.new("") empty.show() button_box.pack_start(bt_add, False, False, 0) button_box.pack_start(bt_remove, False, False, 0) button_box.pack_start(empty, True, True, 0) self.tree_controller.scroll.show_all() frame_box.pack_start(self.tree_controller.scroll, True, True, 0) frame_box.pack_start(button_box, False, False, 0) if FC().tabs_mode == "Multi": self.frame.hide() return self.frame
def dirs(self): self.frame = gtk.Frame(label=_("Music dirs")) self.frame.set_border_width(0) self.frame.show() self.frame.set_no_show_all(True) frame_box = gtk.HBox(False, 0) frame_box.set_border_width(5) frame_box.show() self.tree_controller = SimpleListTreeControl(_("Paths"), None) """buttons""" button_box = gtk.VBox(False, 0) button_box.show() bt_add = gtk.Button(_("Add")) bt_add.connect("clicked", self.add_dir) bt_add.set_size_request(80, -1) bt_add.show() bt_remove = gtk.Button(_("Remove")) bt_remove.connect("clicked", self.remove_dir) bt_remove.set_size_request(80, -1) bt_remove.show() empty = gtk.Label("") empty.show() button_box.pack_start(bt_add, False, False, 0) button_box.pack_start(bt_remove, False, False, 0) button_box.pack_start(empty, True, True, 0) self.tree_controller.scroll.show_all() frame_box.pack_start(self.tree_controller.scroll, True, True, 0) frame_box.pack_start(button_box, False, False, 0) self.frame.add(frame_box) if FC().tabs_mode == "Multi": self.frame.hide() return self.frame
def normalize_text(line): if not line: return "" line = urllib.parse.unquote(line) """find in extension""" for element in ("[", "(", "*", "#"): index = line.find(element) if index >= 0: line = line[:index] index = -1 """find in prefix""" prefix_index = re.search('^([ 0-9.-]*)', line).end() line = line[prefix_index:] line = capitalize_string(line) """remove extension""" ext = get_file_extension(line) if ext in FC().all_support_formats: line = line.replace(ext, "") return line.strip()
def update(self, bean): if bean.type == FTYPE_NOT_UPDATE_INFO_PANEL: return False self.clear() if not FC().is_view_info_panel: logging.debug("Info panel disabled") return """check connection""" if not self.controls.lastfm_service.connect(): return """update bean info form text if possible""" bean = update_bean_from_normalized_text(bean) if not bean.artist or not bean.title: logging.debug("Artist and title not defined") self.bean = bean self.update_info_panel()
def set_tab_left(self): logging.info("Set tabs Left") self.set_tab_pos(Gtk.POS_LEFT) self.default_angle = 90 self.set_show_tabs(True) for page in range(self.get_n_pages() - 1, -1, -1): tab = self.get_nth_page(page) vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0) label = tab.get_child().label label.set_angle(self.default_angle) old_box = label.get_parent() old_box.remove(label) if FC().tab_close_element: vbox.pack_start(self.button(tab), False, False, 0) vbox.pack_end(label, False, False, 0) vbox.set_child_visible(True) vbox.show_all() event = self.to_eventbox(vbox, tab) self.set_tab_label(tab, event)
def set_tab_top(self): logging.info("Set tabs top") self.set_tab_pos(Gtk.PositionType.TOP) self.default_angle = 0 self.set_show_tabs(True) for page in range(self.get_n_pages() - 1, -1, -1): tab = self.get_nth_page(page) hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0) label = tab.get_child().label label.set_angle(self.default_angle) old_box = label.get_parent() old_box.remove(label) if FC().tab_close_element: hbox.pack_end(self.button(tab), False, False, 0) hbox.pack_start(label, False, False, 0) hbox.set_child_visible(True) hbox.show_all() event = self.to_eventbox(hbox, tab) self.set_tab_label(tab, event)
def copy_to(old_paths): destinations = directory_chooser_dialog(_("Choose Folder"), FC().last_dir) if not destinations: return from foobnix.helpers.window import CopyProgressWindow pr_window = CopyProgressWindow(_("Progress"), old_paths, 300, 100) pr_window.label_to.set_text(_("To: ") + destinations[0] + "\n") if destinations: for old_path in old_paths: if not os.path.exists(old_path): logging.warning("File " + old_path + " not exists") continue pr_window.label_from.set_text(_("Copying: ") + os.path.dirname(old_path)) def task(): copy_move_with_progressbar(pr_window, old_path, destinations[0]) pr_window.response(Gtk.ResponseType.OK) t = threading.Thread(target=task) t.start() if pr_window.run() == Gtk.ResponseType.REJECT: pr_window.exit = True t.join() pr_window.destroy()
def on_load(self): self.tabs_count.set_value(FC().count_of_tabs) self.tab_len.set_value(FC().len_of_tab) if FC().tab_position == "left": self.radio_tab_left.set_active(True) elif FC().tab_position == "top": self.radio_tab_top.set_active(True) elif FC().tab_position == "no": self.radio_tab_no.set_active(True) if FC().tab_close_element == "label": self.radio_tab_label.set_active(True) elif FC().tab_close_element == "button": self.radio_tab_button.set_active(True) else: self.radio_tab_none.set_active(True)
def notify_playing(self, pos_sec, dur_sec, bean, sec): self.seek_bar.update_seek_status(pos_sec, dur_sec) sec = int(sec) if sec > 10 and sec % 11 == 0: self.net_wrapper.execute(self.lastfm_service.report_now_playing, bean) if not self.start_time: self.start_time = str(int(time.time())) if not self.is_scrobbled: if sec > dur_sec / 2 or sec > 60: self.is_scrobbled = True self.net_wrapper.execute(self.lastfm_service.report_scrobbled, bean, self.start_time, dur_sec) """download music""" if FC().automatic_online_save: self.dm.append_task(bean)
def task(): path = paths[0] list = path.split("/") FC().last_dir = path[:path.rfind("/")] name = list[len(list) - 1] parent = FModel(name) self.append_to_new_notebook(name, []) all_beans = [] all_beans.append(parent) for bean in get_all_music_by_paths(paths, self): if not bean.is_file: bean.parent(parent).add_is_file(False) all_beans.append(bean) if all_beans: self.append_to_current_notebook(all_beans) else: self.append([ self.SearchCriteriaBeen( _("Nothing found to play in the folder(s)") + paths[0]) ])
def notify_title(self, bean, raw_text): logging.debug("Notify title: " + raw_text) text = raw_text.partition("||")[0] if not self.cache_text: self.cache_text = text self.statusbar.set_text(raw_text.replace("||", "|")) text = normalize_text(text) self.seek_bar.set_text(text) t_bean = bean.create_from_text(text) self.update_info_panel(t_bean) self.set_dbus_state(STATE_PLAY, t_bean) if FC().enable_radio_scrobbler: start_time = str(int(time.time())) self.net_wrapper.execute(self.lastfm_service.report_now_playing, t_bean) if " - " in text and self.cache_text != text: c_bean = copy.copy(bean) prev_bean = c_bean.create_from_text(self.cache_text) self.net_wrapper.execute(self.lastfm_service.report_scrobbled, prev_bean, start_time, 200) self.cache_text = text
def load_music_tree(self): self.perspective.hide_add_button() if not FCache().cache_music_tree_beans[0] and len( FCache().cache_music_tree_beans) == 1: self.perspective.show_add_button() self.tree.is_empty = True if FCache().tab_names[0]: self.tabhelper.label.set_label(FCache().tab_names[0] + " ") else: tabs = len(FCache().cache_music_tree_beans) self.tree.simple_append_all(FCache().cache_music_tree_beans[tabs - 1]) self.tabhelper.label.set_label(FCache().tab_names[tabs - 1] + " ") for tab in xrange(tabs - 2, -1, -1): tree = NavigationTreeControl(self) tree.simple_append_all(FCache().cache_music_tree_beans[tab]) self.tabhelper._append_tab(FCache().tab_names[tab], navig_tree=tree) if not FCache().cache_music_tree_beans[tab]: tree.is_empty = True self.perspective.show_add_button() logging.info("Tree loaded from cache") if FC().update_tree_on_start: def cycle(): for n in xrange(len(FCache().music_paths)): tab_child = self.tabhelper.get_nth_page(n) tree = tab_child.get_child() self.update_music_tree(tree, n) gobject.idle_add(cycle)
def on_load(self): col_list = self.get_columns() col_list.sort(self.to_order_columns, reverse=True) visible_columns = [] for column in col_list: column.label.show() column.set_widget(column.label) column.set_clickable(True) if column.key != "*": column.set_reorderable(True) if FC().columns[column.key][0]: self.move_column_after(column, None) if "item" in column.__dict__: column.item.connect("button-press-event", self.on_toggle, column) self.menu.append(column.item) column.item.set_active(True) visible_columns.append(column) else: if "item" in column.__dict__: column.item.connect("button-press-event", self.on_toggle, column) self.menu.append(column.item) column.item.set_active(False) column.set_visible(False) '''if FC().columns["Track"][2] < 0: