Beispiel #1
0
    def on_auto_search(self, *args):

        # Wishlists supported by server?
        if self.interval == 0:
            log.add_warning(
                _("The server forbid us from doing wishlist searches."))
            return False

        searches = self.frame.np.config.sections["server"]["autosearch"]

        if not searches:
            return True

        # Search for a maximum of 1 item at each search interval
        term = searches.pop()
        searches.insert(0, term)

        for i in self.searches.searches.values():
            if i["term"] == term and i["remember"]:
                i["ignore"] = False

                self.do_wishlist_search(i["id"], term)
                break

        return True
Beispiel #2
0
    def amarok(self):
        """ Function to get amarok currently playing song """

        try:
            import dbus
            import dbus.glib
        except ImportError as error:
            log.add_warning(_("ERROR: amarok: failed to load dbus module: %(error)s"), {"error": error})
            return None

        self.bus = dbus.SessionBus()

        player = self.bus.get_object('org.mpris.amarok', '/Player')
        md = player.GetMetadata()

        for key, value in md.items():

            if key == 'mtime':
                # Convert seconds to minutes:seconds
                value = float(value) / 1000
                m, s = divmod(value, 60)
                self.title['length'] = "%d:%02d" % (m, s)
            elif key == 'audio-bitrate':
                self.title['bitrate'] = value
            elif key == "location":
                self.title['filename']
            else:
                self.title[key] = value

            self.title['nowplaying'] = self.title['artist'] + ' - ' + self.title['title']

        return True
Beispiel #3
0
def open_uri(uri, window):
    """Open a URI in an external (web) browser. The given argument has
    to be a properly formed URI including the scheme (fe. HTTP).
    As of now failures will be silently discarded."""

    # Situation 1, user defined a way of handling the protocol
    protocol = uri[:uri.find(":")]
    protocol_handlers = NICOTINE.np.config.sections["urls"]["protocols"]

    if protocol in protocol_handlers and protocol_handlers[protocol]:
        try:
            execute_command(protocol_handlers[protocol], uri)
            return
        except RuntimeError as e:
            log.add_warning("%s", e)

    if protocol == "slsk":
        on_soul_seek_uri(uri.strip())

    # Situation 2, user did not define a way of handling the protocol
    if sys.platform == "win32":
        import webbrowser
        webbrowser.open(uri)
        return

    try:
        Gtk.show_uri_on_window(window, uri, Gdk.CURRENT_TIME)
    except AttributeError:
        screen = window.get_screen()
        Gtk.show_uri(screen, uri, Gdk.CURRENT_TIME)
Beispiel #4
0
    def add_port_mapping(self, np):
        """
        This function supports creating a Port Mapping via the UPnP
        IGDv1 and IGDv2 protocol.

        Need a reference to the np object to extract the internal LAN
        local from the protothread socket.

        Any UPnP port mapping done with IGDv2 will expire after a
        maximum of 7 days (lease period), according to the protocol.
        We set the lease period to a shorter 24 hours, and regularly
        renew the port mapping (see pynicotine.py).
        """

        try:
            self._add_port_mapping(np)

        except Exception as e:
            log.add_warning(_('UPnP exception: %(error)s'), {'error': str(e)})
            log.add_warning(_('Failed to automate the creation of UPnP Port Mapping rule.'))
            return

        log.add_debug(
            _('Managed to map external WAN port %(externalwanport)s ' +
                'to your local host %(internalipaddress)s ' +
                'port %(internallanport)s.'),
            {
                'externalwanport': self.externalwanport,
                'internalipaddress': self.internalipaddress,
                'internallanport': self.internallanport
            }
        )
Beispiel #5
0
    def set_shares(self, sharestype="normal", files=None, streams=None, mtimes=None, wordindex=None, fileindex=None):

        if sharestype == "normal":
            storable_objects = [
                (files, "sharedfiles", "files.db"),
                (streams, "sharedfilesstreams", "streams.db"),
                (mtimes, "sharedmtimes", "mtimes.db"),
                (wordindex, "wordindex", "wordindex.db"),
                (fileindex, "fileindex", "fileindex.db")
            ]
        else:
            storable_objects = [
                (files, "bsharedfiles", "buddyfiles.db"),
                (streams, "bsharedfilesstreams", "buddystreams.db"),
                (mtimes, "bsharedmtimes", "buddymtimes.db"),
                (wordindex, "bwordindex", "buddywordindex.db"),
                (fileindex, "bfileindex", "buddyfileindex.db")
            ]

        for source, destination, filename in storable_objects:
            if source is not None:
                try:
                    self.config.sections["transfers"][destination].close()
                    self.config.sections["transfers"][destination] = shelve.open(os.path.join(self.config.data_dir, filename), flag='n', protocol=pickle.HIGHEST_PROTOCOL)
                    self.config.sections["transfers"][destination].update(source)

                except Exception as e:
                    log.add_warning(_("Can't save %s: %s") % (filename, e))
                    return
Beispiel #6
0
    def create_menu(self):

        try:
            self.tray_popup_menu_server = popup0 = PopupMenu(self, False)
            popup0.setup(
                ("#" + _("Connect"), self.frame.on_connect),
                ("#" + _("Disconnect"), self.frame.on_disconnect)
            )

            self.tray_popup_menu = popup = PopupMenu(self, False)
            popup.setup(
                ("#" + _("Hide / Show Nicotine+"), self.on_hide_unhide_window),
                (1, _("Server"), self.tray_popup_menu_server, None),
                ("#" + _("Downloads"), self.on_downloads),
                ("#" + _("Uploads"), self.on_uploads),
                ("#" + _("Send Message"), self.on_open_private_chat),
                ("#" + _("Lookup a User's IP"), self.on_get_a_users_ip),
                ("#" + _("Lookup a User's Info"), self.on_get_a_users_info),
                ("#" + _("Lookup a User's Shares"), self.on_get_a_users_shares),
                ("$" + _("Away"), self.frame.on_away),
                ("#" + _("Preferences"), self.frame.on_settings),
                ("#" + _("Quit"), self.frame.on_quit)
            )
        except Exception as e:
            log.add_warning(_('ERROR: tray menu, %(error)s'), {'error': e})
Beispiel #7
0
def load_ui_elements(ui_class, filename):

    try:
        builder = Gtk.Builder()
        builder.set_translation_domain('nicotine')
        builder.add_from_file(filename)

        for obj in builder.get_objects():
            try:
                obj_name = Gtk.Buildable.get_name(obj)

                if not obj_name.startswith("_"):
                    setattr(ui_class, obj_name, obj)

            except TypeError:
                pass

        builder.connect_signals(ui_class)

    except Exception as e:
        log.add_warning(_("Failed to load ui file %(file)s: %(error)s"), {
            "file": filename,
            "error": e
        })
        sys.exit()
Beispiel #8
0
def open_uri(uri, window):
    """Open a URI in an external (web) browser. The given argument has
    to be a properly formed URI including the scheme (fe. HTTP).
    As of now failures will be silently discarded."""

    # Situation 1, user defined a way of handling the protocol
    protocol = uri[:uri.find(":")]
    protocol_handlers = config.sections["urls"]["protocols"]

    if protocol in protocol_handlers and protocol_handlers[protocol]:
        try:
            execute_command(protocol_handlers[protocol], uri)
            return
        except RuntimeError as e:
            log.add_warning("%s", e)

    if protocol == "slsk":
        on_soul_seek_uri(uri.strip())
        return

    # Situation 2, user did not define a way of handling the protocol
    try:
        if sys.platform == "win32":
            os.startfile(uri)

        elif sys.platform == "darwin":
            execute_command("open $", uri)

        else:
            Gio.AppInfo.launch_default_for_uri(uri)

    except Exception as error:
        log.add_warning(_("Failed to open URL: %s"), str(error))
Beispiel #9
0
def open_uri(uri, window):
    """Open a URI in an external (web) browser. The given argument has
    to be a properly formed URI including the scheme (fe. HTTP).
    As of now failures will be silently discarded."""

    # Situation 1, user defined a way of handling the protocol
    protocol = uri[:uri.find(":")]
    if protocol in PROTOCOL_HANDLERS:
        if isinstance(PROTOCOL_HANDLERS[protocol], types.MethodType):
            PROTOCOL_HANDLERS[protocol](uri.strip())
            return
        if PROTOCOL_HANDLERS[protocol]:
            try:
                execute_command(PROTOCOL_HANDLERS[protocol], uri)
                return
            except RuntimeError as e:
                log.add_warning("%s", e)

    # Situation 2, user did not define a way of handling the protocol
    if sys.platform == "win32" and webbrowser:
        webbrowser.open(uri)
        return

    try:
        Gtk.show_uri_on_window(window, uri, Gdk.CURRENT_TIME)
    except AttributeError:
        screen = window.get_screen()
        Gtk.show_uri(screen, uri, Gdk.CURRENT_TIME)
Beispiel #10
0
    def on_tab_click(self, widget, event, child):

        if event.type == Gdk.EventType.BUTTON_PRESS:

            search_id = None
            n = self.page_num(child)
            page = self.get_nth_page(n)

            for search, data in self.searches.items():

                if data[2] is None:
                    continue
                if data[2].Main is page:
                    search_id = search
                    break

            if search_id is None:
                log.add_warning(_("Search ID was none when clicking tab"))
                return

            if event.button == 2:
                self.searches[search_id][2].on_close(widget)
                return True

            if event.button == 3:
                menu = self.tab_popup(search_id)
                menu.popup(None, None, None, None, event.button, event.time)
                return True

        return False
Beispiel #11
0
    def foobar(self):
        """ Function to get foobar currently playing song on windows """

        if sys.platform == "win32":
            try:
                from win32gui import GetWindowText, FindWindow
            except ImportError as error:
                log.add_warning(_("ERROR: foobar: failed to load win32gui module: %(error)s"), {"error": error})
                return None
        else:
            log.add_warning(_("ERROR: foobar: is only supported on windows."))
            return None

        wnd_ids = [
            '{DA7CD0DE-1602-45e6-89A1-C2CA151E008E}',
            '{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}',
            '{E7076D1C-A7BF-4f39-B771-BCBE88F2A2A8}'
        ]

        metadata = None

        for wnd_id in wnd_ids:
            wnd_txt = GetWindowText(FindWindow(wnd_id, None))
            if wnd_txt:
                m = re.match(r"(.*)\\s+\[foobar.*", wnd_txt)
                if m:
                    metadata = m.groups()[0].strip()

        if metadata:
            self.title["nowplaying"] = "now playing: " + metadata.decode('mbcs')
            return True
        else:
            return None
Beispiel #12
0
    def on_search(self):

        self.save_columns()

        text = self.frame.SearchEntry.get_text().strip()

        if not text:
            return

        users = []
        room = None
        search_mode = self.frame.SearchMethod.get_active_id()
        feedback = None

        if search_mode == "global":
            feedback = self.frame.np.pluginhandler.outgoing_global_search_event(text)

            if feedback is not None:
                text = feedback[0]

        elif search_mode == "rooms":
            name = self.frame.RoomSearchEntry.get_text()
            # Space after Joined Rooms is important, so it doesn't conflict
            # with any possible real room
            if name != _("Joined Rooms ") and not name.isspace():
                room = name

            feedback = self.frame.np.pluginhandler.outgoing_room_search_event(room, text)

            if feedback is not None:
                (room, text) = feedback

        elif search_mode == "buddies":
            feedback = self.frame.np.pluginhandler.outgoing_buddy_search_event(text)

            if feedback is not None:
                text = feedback[0]

        elif search_mode == "user":
            user = self.frame.UserSearchEntry.get_text().strip()

            if user:
                users = [user]
            else:
                return

            feedback = self.frame.np.pluginhandler.outgoing_user_search_event(users, text)

            if feedback is not None:
                (users, text) = feedback

        else:
            log.add_warning(_("Unknown search mode, not using plugin system. Fix me!"))
            feedback = True

        if feedback is not None:
            self.do_search(text, search_mode, users, room)
Beispiel #13
0
    def on_search(self):
        self.save_columns()
        text = self.frame.search_entry.get_text().strip()

        if not text:
            return

        users = []
        room = None
        search_mode = self.frame.SearchMethod.get_model().get(self.frame.SearchMethod.get_active_iter(), 0)[0]

        if search_mode == _("Global"):
            mode = 0
        elif search_mode == _("Rooms"):
            mode = 1
            name = self.frame.RoomSearchCombo.get_child().get_text()
            # Space after Joined Rooms is important, so it doesn't conflict
            # with any possible real room
            if name != _("Joined Rooms ") and not name.isspace():
                room = name
        elif search_mode == _("Buddies"):
            mode = 2
        elif search_mode == _("User"):
            mode = 3
            user = self.frame.UserSearchCombo.get_child().get_text().strip()
            if user != "" and not user.isspace():
                users = [user]
            else:
                return
        else:
            mode = 0

        feedback = None

        if mode == 0:
            feedback = self.frame.np.pluginhandler.outgoing_global_search_event(text)
            if feedback is not None:
                text = feedback[0]
        elif mode == 1:
            feedback = self.frame.np.pluginhandler.outgoing_room_search_event(room, text)
            if feedback is not None:
                (room, text) = feedback
        elif mode == 2:
            feedback = self.frame.np.pluginhandler.outgoing_buddy_search_event(text)
            if feedback is not None:
                text = feedback[0]
        elif mode == 3:
            feedback = self.frame.np.pluginhandler.outgoing_user_search_event(users)
            if feedback is not None:
                users = feedback[0]
        else:
            log.add_warning(_("Unknown search mode, not using plugin system. Fix me!"))
            feedback = True

        if feedback is not None:
            self.do_search(text, mode, users, room)
            self.frame.search_entry.set_text("")
Beispiel #14
0
    def create_data_folder(self):
        """ Create the folder for storing data in (aliases, shared files etc.),
        if the folder doesn't exist """

        try:
            if not os.path.isdir(self.data_dir):
                os.makedirs(self.data_dir)

        except OSError as msg:
            log.add_warning(_("Can't create directory '%(path)s', reported error: %(error)s"), {'path': self.data_dir, 'error': msg})
Beispiel #15
0
    def create_config_folder(self):
        """ Create the folder for storing the config file in, if the folder
        doesn't exist """

        path, fn = os.path.split(self.filename)
        try:
            if not os.path.isdir(path):
                os.makedirs(path)

        except OSError as msg:
            log.add_warning(_("Can't create directory '%(path)s', reported error: %(error)s"), {'path': path, 'error': msg})
Beispiel #16
0
    def on_tab_popup(self, widget, child):

        search_id = self.get_search_id(child)

        if search_id is None:
            log.add_warning(_("Search ID was none when clicking tab"))
            return False

        menu = self.searches[search_id]["tab"].tab_menu
        menu.popup()
        return True
Beispiel #17
0
def open_file_path(file_path, command=None):
    """ Currently used to either open a folder or play an audio file
    Tries to run a user-specified command first, and falls back to
    the system default. """

    if command and "$" in command:
        execute_command(command, file_path)
    else:
        try:
            Gio.AppInfo.launch_default_for_uri("file:///" + file_path)
        except GLib.Error as error:
            log.add_warning(_("Failed to open folder: %s"), str(error))
Beispiel #18
0
    def other(self):
        try:
            othercommand = self.NPCommand.get_text()
            if othercommand == "":
                return None

            output = execute_command(othercommand, returnoutput=True)
            self.title["nowplaying"] = output
            return True
        except Exception as error:
            log.add_warning(_("ERROR: Executing '%(command)s' failed: %(error)s"), {"command": othercommand, "error": error})
            return None
Beispiel #19
0
    def tts_player(self, message):

        self.tts_playing = True

        try:
            execute_command(config.sections["ui"]["speechcommand"],
                            message,
                            background=False)

        except Exception as error:
            log.add_warning(_("Text-to-speech for message failed: %s"),
                            str(error))
Beispiel #20
0
    def add_row_to_model(self, row):
        counter, user, flag, immediatedl, h_speed, h_queue, directory, filename, h_size, h_bitrate, length, bitrate, fullpath, country, size, speed, queue = row

        if self.ResultGrouping.get_active_id() != "ungrouped":
            # Group by folder or user

            if user not in self.usersiters:
                self.usersiters[user] = self.resultsmodel.append(
                    None, [
                        0, user,
                        self.get_flag(
                            user, country), immediatedl, h_speed, h_queue, "",
                        "", "", "", "", 0, "", country, 0, speed, queue
                    ])

            parent = self.usersiters[user]

            if self.ResultGrouping.get_active_id() == "folder_grouping":
                # Group by folder

                if directory not in self.directoryiters:
                    self.directoryiters[directory] = self.resultsmodel.append(
                        self.usersiters[user], [
                            0, user,
                            self.get_flag(user, country), immediatedl, h_speed,
                            h_queue, directory, "", "", "", "", 0,
                            fullpath.rsplit('\\', 1)[0] + '\\', country, 0,
                            speed, queue
                        ])

                row = row[:]
                row[6] = ""  # Directory not visible for file row if "group by folder" is enabled

                parent = self.directoryiters[directory]
        else:
            parent = None

        try:
            iterator = self.resultsmodel.append(parent, row)

            self.numvisibleresults += 1
        except Exception as e:
            types = []
            for i in row:
                types.append(type(i))
            log.add_warning(_("Search row error: %(exception)s %(row)s"), {
                'exception': e,
                'row': row
            })
            iterator = None

        return iterator
Beispiel #21
0
    def write_aliases(self):

        self.create_config_folder()

        try:
            with open(self.filename + ".alias", "wb") as f:
                pickle.dump(self.aliases, f, protocol=pickle.HIGHEST_PROTOCOL)

        except IOError as e:
            log.add_warning(_("Something went wrong while opening your alias file: %s"), e)

        except Exception as e:
            log.add_warning(_("Something went wrong while saving your alias file: %s"), e)
Beispiel #22
0
    def on_tab_click(self, widget, event, child):

        search_id = self.get_search_id(child)

        if search_id is None:
            log.add_warning(_("Search ID was none when clicking tab"))
            return False

        if triggers_context_menu(event):
            return self.on_tab_popup(widget, child)

        if event.button == 2:
            self.searches[search_id]["tab"].on_close(widget)
            return True

        return False
Beispiel #23
0
    def load_shares(self, dbs):

        errors = []

        for destination, shelvefile in dbs:
            try:
                self.config.sections["transfers"][destination] = shelve.open(shelvefile, protocol=pickle.HIGHEST_PROTOCOL)
            except Exception:
                errors.append(shelvefile)

        if errors:
            log.add_warning(_("Failed to process the following databases: %(names)s") % {'names': '\n'.join(errors)})

            self.clear_shares()

            log.add_warning(_("Shared files database seems to be corrupted, rescan your shares"))
Beispiel #24
0
    def compress_shares(self, sharestype):

        if sharestype == "normal":
            streams = self.config.sections["transfers"]["sharedfilesstreams"]
        elif sharestype == "buddy":
            streams = self.config.sections["transfers"]["bsharedfilesstreams"]

        if streams is None:
            log.add_warning(_("ERROR: No %(type)s shares database available") % {"type": sharestype})
            return

        m = slskmessages.SharedFileList(None, streams)
        _thread.start_new_thread(m.make_network_message, (0, True))

        if sharestype == "normal":
            self.compressed_shares_normal = m
        elif sharestype == "buddy":
            self.compressed_shares_buddy = m
Beispiel #25
0
    def on_tab_popup(self, widget, child):

        search_id = self.get_search_id(child)

        if search_id is None:
            log.add_warning(_("Search ID was none when clicking tab"))
            return False

        menu = PopupMenu(self.frame)
        menu.setup(
            ("#" + _("Copy Search Term"),
             self.searches[search_id]["tab"].on_copy_search_term), ("", None),
            ("#" + _("Clear All Results"),
             self.searches[search_id]["tab"].on_clear),
            ("#" + _("Close All Tabs"), menu.on_close_all_tabs, self),
            ("#" + _("_Close Tab"), self.searches[search_id]["tab"].on_close))

        menu.popup()
        return True
Beispiel #26
0
    def write_aliases(self):

        try:
            f = open(self.filename + ".alias", "wb")
        except Exception as e:
            log.add_warning(
                _("Something went wrong while opening your alias file: %s"), e)
        else:
            try:
                pickle.dump(self.aliases, f, protocol=pickle.HIGHEST_PROTOCOL)
                f.close()
            except Exception as e:
                log.add_warning(
                    _("Something went wrong while saving your alias file: %s"),
                    e)
        finally:
            try:
                f.close()
            except Exception:
                pass
Beispiel #27
0
    def set_image(self, status=None):

        if not self.is_visible():
            return

        try:
            if status is not None:
                self.tray_status["status"] = status

            # Check for hilites, and display hilite icon if there is a room or private hilite
            if self.frame.hilites["rooms"] or self.frame.hilites["private"]:
                icon_name = "msg"
            else:
                # If there is no hilite, display the status
                icon_name = self.tray_status["status"]

            if icon_name != self.tray_status["last"]:
                self.tray_status["last"] = icon_name

            if self.appindicator is not None:
                if self.custom_icons:
                    icon_name = "trayicon_" + icon_name
                else:
                    icon_name = GLib.get_prgname() + "-" + icon_name

                self.trayicon.set_icon_full(icon_name,
                                            GLib.get_application_name())

            else:
                # GtkStatusIcon fallback
                if self.custom_icons or self.local_icons:
                    self.trayicon.set_from_pixbuf(
                        self.frame.images["trayicon_" + icon_name])

                else:
                    self.trayicon.set_from_icon_name(GLib.get_prgname() + "-" +
                                                     icon_name)

        except Exception as e:
            log.add_warning(_("ERROR: cannot set trayicon image: %(error)s"),
                            {'error': e})
Beispiel #28
0
    def on_leave(self, *args):

        if self.leaving:
            return

        self.leaving = True

        if self.room in config.sections["columns"]["chat_room"]:
            del config.sections["columns"]["chat_room"][self.room]

        if not self.meta:
            self.frame.np.queue.append(slskmessages.LeaveRoom(self.room))
        else:
            if self.room == 'Public ':
                self.frame.np.queue.append(slskmessages.LeavePublicRoom())
                self.chatrooms.leave_room(slskmessages.LeaveRoom(
                    self.room))  # Faking protocol msg
            else:
                log.add_warning(_("Unknown meta chatroom closed"))

        self.frame.np.pluginhandler.leave_chatroom_notification(self.room)
Beispiel #29
0
    def load_shares(cls, shares, dbs, reset_shares=False):

        errors = []

        for destination, shelvefile in dbs:
            try:
                if not reset_shares:
                    shares[destination] = shelve.open(
                        shelvefile, protocol=pickle.HIGHEST_PROTOCOL)
                else:
                    shares[destination] = shelve.open(
                        shelvefile, flag='n', protocol=pickle.HIGHEST_PROTOCOL)

            except Exception:
                from traceback import format_exc

                shares[destination] = None
                errors.append(shelvefile)
                exception = format_exc()

        if errors:
            log.add_warning(
                _("Failed to process the following databases: %(names)s"),
                {'names': '\n'.join(errors)})
            log.add_warning(exception)
            log.add_warning(
                _("Shared files database seems to be corrupted, rescan your shares"
                  ))

            if not reset_shares:
                cls.load_shares(shares, dbs, reset_shares=True)
Beispiel #30
0
    def lastfm(self):
        """ Function to get the last song played via lastfm api """

        import http.client
        import json

        try:
            conn = http.client.HTTPSConnection("ws.audioscrobbler.com")
        except Exception as error:
            log.add_warning(_("ERROR: lastfm: Could not connect to audioscrobbler: %(error)s"), {"error": error})
            return None

        try:
            (user, apikey) = self.NPCommand.get_text().split(';')
        except ValueError:
            log.add_warning(_("ERROR: lastfm: Please provide both your lastfm username and API key"))
            return None

        conn.request("GET", "/2.0/?method=user.getrecenttracks&user="******"&api_key=" + apikey + "&format=json", headers={"User-Agent": "Nicotine+"})
        resp = conn.getresponse()
        data = resp.read().decode("utf-8")

        if resp.status != 200 or resp.reason != "OK":
            log.add_warning(_("ERROR: lastfm: Could not get recent track from audioscrobbler: %(error)s"), {"error": str(data)})
            return None

        json_api = json.loads(data)
        lastplayed = json_api["recenttracks"]["track"][0]

        self.title["artist"] = lastplayed["artist"]["#text"]
        self.title["title"] = lastplayed["name"]
        self.title["album"] = lastplayed["album"]["#text"]
        self.title["nowplaying"] = "%s: %s - %s - %s" % (_("Last played"), self.title["artist"], self.title["album"], self.title["title"])

        return True