Beispiel #1
0
 def get_music_paths(self):
     paths = self.get_value('music-path')
     if not paths:
         if GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC):
             paths = [GLib.get_user_special_dir(
                 GLib.UserDirectory.DIRECTORY_MUSIC)]
         else:
             print("You need to add a music path"
                   " to org.gnome.Lollypop in dconf")
     return paths
Beispiel #2
0
    def test_xdg_dirs(self):
        d = GLib.get_user_data_dir()
        self.assertTrue('/' in d, d)
        d = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)
        self.assertTrue('/' in d, d)
        # also works with backwards compatible enum names
        self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC),
                         GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC))

        for d in GLib.get_system_config_dirs():
            self.assertTrue('/' in d, d)
        for d in GLib.get_system_data_dirs():
            self.assertTrue(isinstance(d, str), d)
Beispiel #3
0
    def __init__(self):
        self.operation = Gtk.PrintOperation()
        print_data = {'filename': os.path.abspath(__file__),
                      'font_size': 12.0,
                      'lines_per_page': 0,
                      'lines': None,
                      'num_lines': 0,
                      'num_pages': 0
                     }

        self.operation.connect('begin-print', self.begin_print, print_data)
        self.operation.connect('draw-page', self.draw_page, print_data)
        self.operation.connect('end-print', self.end_print, print_data)

        self.operation.set_use_full_page(False)
        self.operation.set_unit(Gtk.Unit.POINTS)
        self.operation.set_embed_page_setup(True)

        settings = Gtk.PrintSettings()

        dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS)
        if dir is None:
            dir = GLib.get_home_dir()
        ext = '.pdf'

        uri = "file://%s/gtk-demo%s" % (dir, ext)
        settings.set(Gtk.PRINT_SETTINGS_OUTPUT_URI, uri)
        self.operation.set_print_settings(settings)
    def _init_service(self):
        if self.props.flags & Gio.ApplicationFlags.IS_SERVICE:
            self.hold()

        # FIXME: File system encoding
        def file_changed(monitor, file_changed, other_file, event):
            if not self.settings['watch-downloads-directory']:
                return

            if event != Gio.FileMonitorEvent.CREATED:
                return

            if file_changed.get_basename().rpartition('.')[2] != 'torrent':
                return

            file_uri = file_changed.get_uri()
            logging.info('Got file created event for {}'.format(file_uri))

            self.activate()
            action = self.window.lookup_action('torrent_add')
            action.activate(GLib.Variant('s', file_uri))

        downloads_str = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        if downloads_str:
            downloads = Gio.File.new_for_path(downloads_str)
            self.download_monitor = downloads.monitor_directory(Gio.FileMonitorFlags.NONE)
            self.download_monitor.connect('changed', file_changed)

        self.client = Client(username=self.settings['username'], password=self.settings['password'],
                             hostname=self.settings['hostname'], port=self.settings['port'],
                             tls=self.settings['tls'])

        for prop in ('username', 'password', 'hostname', 'port', 'tls'):
            self.settings.bind(prop, self.client, prop, Gio.SettingsBindFlags.GET)
    def _make_share_path(self):
        config_path = self._config["shared-path"]
        default_path = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        path = None
        error = False

        if config_path == '':
            path = default_path
        elif not os.path.isdir(config_path):
            path = default_path
            error = True
            logging.warning('Invalid shared-path %s' % config_path)
        else:
            path = config_path

        if not path:
            path = os.path.expanduser("~")
            logging.warning('Failed to get Download dir from XDG')

        # We used to always store the full path which caused problems
        if config_path == default_path:
            logging.info('Reset stored path, identical to default path.')
            self._config["shared-path"] = ''

        return path, error
Beispiel #6
0
 def _set_target_default(self):
     try:
         default = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
     except:
         default = os.environ['HOME']
     folder = self.data[2] if self.data else default # liststore target
     self.target_widget.set_current_folder(folder)
Beispiel #7
0
    def on_load(self, applet):
        self._config = Config("org.blueman.transfer")

        if not self._config["shared-path"]:
            d = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            if not d:
                self._config["shared-path"] = os.path.expanduser("~")
            else:
                self._config["shared-path"] = d

        if not os.path.isdir(self._config["shared-path"]):
            logging.info("Configured share directory %s does not exist" % self._config["shared-path"])

            text = _("Configured directory for incoming files does not exist")
            secondary_text = _("Please make sure that directory \"<b>%s</b>\" exists or configure it with blueman-services")
            dlg = ErrorDialog(text, secondary_text % self._config["shared-path"])

            dlg.run()
            dlg.destroy()

        self._manager = obex.Manager()
        self._manager.connect("transfer-started", self._on_transfer_started)
        self._manager.connect("transfer-completed", self._on_transfer_completed)
        self._manager.connect('session-removed', self._on_session_removed)

        self._watch = obex.Manager.watch_name_owner(self._on_dbus_name_appeared, self._on_dbus_name_vanished)
Beispiel #8
0
	def update(self,  progress, smooth):
		self._smooth = smooth
		paths = Objects["settings"].get_value('music-path')
		if len(paths) == 0:
			if GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC):
				paths = [ GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC) ]
			else:
				print("You need to add a music path to org.gnome.Lollypop in dconf")

		if not self._in_thread:
			self._progress = progress
			progress.show()
			self._in_thread = True
			self._compilations = []
			self._mtimes = Objects["tracks"].get_mtimes()
			start_new_thread(self._scan, (paths,))
    def __init__(self, canvas):
        self.operation = Gtk.PrintOperation()
        print_data = {"canvas": canvas, "font_size": 10.0, "lines": None, "num_pages": 0}

        self.operation.connect("begin-print", self.begin_print, print_data)
        self.operation.connect("draw-page", self.draw_page, print_data)
        self.operation.connect("end-print", self.end_print, print_data)

        self.operation.set_use_full_page(False)
        self.operation.set_unit(Gtk.Unit.POINTS)
        self.operation.set_embed_page_setup(True)

        settings = Gtk.PrintSettings()

        dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS)
        if dir is None:
            dir = GLib.get_home_dir()
        if settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == "ps":
            ext = ".ps"
        elif settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == "svg":
            ext = ".svg"
        else:
            ext = ".pdf"
        # base_name = os.path.splitext(os.path.basename(out_file_path))[0]
        uri = "file://{:s}/plot{:s}".format(dir, ext)
        settings.set(Gtk.PRINT_SETTINGS_OUTPUT_URI, uri)
        self.operation.set_print_settings(settings)
Beispiel #10
0
    def download(self, widget, download, data=None):
        print("Hay una descarga")

        print(dir(download))

        DOWNLOAD_DIR = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        print(DOWNLOAD_DIR)

        name = download.get_suggested_filename()
        print(name)

        ext = op.splitext(name)
        print(ext)

        path = op.join(DOWNLOAD_DIR, name)
        print(path)

        download.set_destination_uri('file://%s' % path)
        print('file://%s' % path)

        #while download.get_status:
        #    print(download.get_status())
        #    pass

        new_dir = str.replace(path, " ", "\ ")
        os.system("evince -f %s" % new_dir)


        #download.set_destination_uri("file://home/vampirodx/hola.txt")
        #download.start(download)
        #down.webkit_download_start()
        return True
Beispiel #11
0
def create_launcher(game_slug, game_name, desktop=False, menu=False):
    """Create .desktop file."""
    desktop_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
    launcher_content = dedent(
        """
        [Desktop Entry]
        Type=Application
        Name=%s
        Icon=%s
        Exec=lutris lutris:%s
        Categories=Game
        """
        % (game_name, "lutris_" + game_slug, game_slug)
    )

    launcher_filename = "%s.desktop" % game_slug
    tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)
    tmp_launcher = open(tmp_launcher_path, "w")
    tmp_launcher.write(launcher_content)
    tmp_launcher.close()
    os.chmod(
        tmp_launcher_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
    )

    if desktop:
        shutil.copy(tmp_launcher_path, os.path.join(desktop_dir, launcher_filename))
    if menu:
        menu_path = os.path.join(GLib.get_user_data_dir(), "applications")
        shutil.copy(tmp_launcher_path, os.path.join(menu_path, launcher_filename))
    os.remove(tmp_launcher_path)
Beispiel #12
0
    def test_xdg_dirs(self):
        d = GLib.get_user_data_dir()
        self.assertTrue(os.path.sep in d, d)
        d = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
        self.assertTrue(os.path.sep in d, d)
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', PyGIDeprecationWarning)

            # also works with backwards compatible enum names
            self.assertEqual(GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC),
                             GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC))

        for d in GLib.get_system_config_dirs():
            self.assertTrue(os.path.sep in d, d)
        for d in GLib.get_system_data_dirs():
            self.assertTrue(isinstance(d, str), d)
Beispiel #13
0
    def _edit_settings_close(self, widget):
        """
            Close edit party dialog
            @param widget as Gtk.Window
        """
        # Music path
        paths = []
        main_path = self._main_chooser.get_dir()
        choosers = self._chooser_box.get_children()
        if main_path == GLib.get_user_special_dir(
            GLib.UserDirectory.DIRECTORY_MUSIC)\
           and not choosers:
            paths = []
        else:
            paths.append(main_path)
            for chooser in choosers:
                path = chooser.get_dir()
                if path is not None and path not in paths:
                    paths.append(path)

        previous = Lp.settings.get_value('music-path')
        Lp.settings.set_value('music-path', GLib.Variant('as', paths))

        # Last.fm
        try:
            self._update_lastfm_settings()
        except:
            pass

        self._settings_dialog.hide()
        self._settings_dialog.destroy()
        if set(previous) != set(paths):
            Lp.window.update_db()
Beispiel #14
0
def create_launcher(game_slug, game_id, game_name, desktop=False, menu=False):
    """Create a .desktop file."""
    desktop_dir = (
        GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
    )
    launcher_content = dedent(
        """
        [Desktop Entry]
        Type=Application
        Name={}
        Icon={}
        Exec=lutris lutris:rungameid/{}
        Categories=Game
        """.format(game_name, 'lutris_{}'.format(game_slug), game_id)
    )

    launcher_filename = get_xdg_basename(game_slug, game_id, legacy=False)
    tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)
    tmp_launcher = open(tmp_launcher_path, "w")
    tmp_launcher.write(launcher_content)
    tmp_launcher.close()
    os.chmod(tmp_launcher_path, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
             stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)

    if desktop:
        shutil.copy(tmp_launcher_path,
                    os.path.join(desktop_dir, launcher_filename))
    if menu:
        menu_path = os.path.join(GLib.get_user_data_dir(), 'applications')
        shutil.copy(tmp_launcher_path,
                    os.path.join(menu_path, launcher_filename))
    os.remove(tmp_launcher_path)
    def __init__(self, out_file_path):
        self.operation = Gtk.PrintOperation()
        print_data = {'filename': out_file_path,
                      'font_size': 10.0,
                      'lines': None,
                      'num_pages': 0
                     }

        self.operation.connect('begin-print', self.begin_print, print_data)
        self.operation.connect('draw-page', self.draw_page, print_data)
        self.operation.connect('end-print', self.end_print, print_data)

        self.operation.set_use_full_page(False)
        self.operation.set_unit(Gtk.Unit.POINTS)
        self.operation.set_embed_page_setup(True)

        settings = Gtk.PrintSettings()

        dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS)
        if dir is None:
            dir = GLib.get_home_dir()
        if settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == 'ps':
            ext = '.ps'
        elif settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == 'svg':
            ext = '.svg'
        else:
            ext = '.pdf'
        base_name = os.path.splitext(os.path.basename(out_file_path))[0]
        uri = "file://{:s}/{:s}{:s}".format(dir, base_name, ext)
        settings.set(Gtk.PRINT_SETTINGS_OUTPUT_URI, uri)
        self.operation.set_print_settings(settings)
Beispiel #16
0
    def __init__(self):
        self.operation = Gtk.PrintOperation()
        print_data = {
            "filename": os.path.abspath(__file__),
            "font_size": 12.0,
            "lines_per_page": 0,
            "lines": None,
            "num_lines": 0,
            "num_pages": 0,
        }

        self.operation.connect("begin-print", self.begin_print, print_data)
        self.operation.connect("draw-page", self.draw_page, print_data)
        self.operation.connect("end-print", self.end_print, print_data)

        self.operation.set_use_full_page(False)
        self.operation.set_unit(Gtk.Unit.POINTS)
        self.operation.set_embed_page_setup(True)

        settings = Gtk.PrintSettings()

        dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS)
        if dir is None:
            dir = GLib.get_home_dir()
        if settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == "ps":
            ext = ".ps"
        elif settings.get(Gtk.PRINT_SETTINGS_OUTPUT_FILE_FORMAT) == "svg":
            ext = ".svg"
        else:
            ext = ".pdf"

        uri = "file://%s/gtk-demo%s" % (dir, ext)
        settings.set(Gtk.PRINT_SETTINGS_OUTPUT_URI, uri)
        self.operation.set_print_settings(settings)
Beispiel #17
0
    def on_load(self, applet):
        self._config = Config("org.blueman.transfer")

        if not self._config["shared-path"]:
            d = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            if not d:
                self._config["shared-path"] = os.path.expanduser("~")
            else:
                self._config["shared-path"] = d

        if not os.path.isdir(self._config["shared-path"]):
            dprint("Configured share directory %s does not exist" % self._config["shared-path"])

            dlg = Gtk.MessageDialog(None, buttons=Gtk.ButtonsType.OK, type=Gtk.MessageType.ERROR)
            text = _("Configured directory for incoming files does not exist")
            secondary_text = _(
                'Please make sure that directory "<b>%s</b>" exists or configure it with blueman-services'
            )
            dlg.props.text = text
            dlg.format_secondary_markup(secondary_text % self._config["shared-path"])

            dlg.run()
            dlg.destroy()

        self._manager = obex.Manager()
        self._manager.connect("transfer-started", self._on_transfer_started)
        self._manager.connect("transfer-completed", self._on_transfer_completed)
        self._manager.connect("session-removed", self._on_session_removed)

        self._watch = dbus.SessionBus().watch_name_owner("org.bluez.obex", self._on_obex_owner_changed)
Beispiel #18
0
Datei: ffs.py Projekt: jku/ffs
    def get_upload_filename(self, basename):
        if not self.upload_dir:
            dl_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            dirname = os.path.join(dl_dir, "%s Uploads" % FFS_APP_NAME)

            for i in range(2, 1000):
                try:
                    os.makedirs(dirname)
                    self.upload_dir = dirname
                    break
                except os.error:
                    dirname = os.path.join(dl_dir, "%s Uploads(%d)" % (FFS_APP_NAME, i))
            if not self.upload_dir:
                raise Exception

        fn, ext = os.path.splitext(basename)
        new_fn = os.path.join(self.upload_dir, "%s" % basename)

        if not os.path.exists(new_fn):
            return new_fn

        for i in range(2, 1000):
            new_fn = os.path.join(self.upload_dir, "{}({}){}".format(fn, i, ext))
            if not os.path.exists(new_fn):
                return new_fn

        raise Exception
Beispiel #19
0
 def _get_tmpl_dir(self):
     tmpl_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_TEMPLATES)
     if tmpl_dir == os.path.expanduser("~"):
         tmpl_dir = None
     if not tmpl_dir:
         tmpl_dir = os.path.expanduser(DEFAULT_TMPL_DIR)
     pretty.print_debug(__name__, tmpl_dir)
     return tmpl_dir
Beispiel #20
0
    def update(self, smooth):
        self._smooth = smooth
        paths = Objects.settings.get_value('music-path')
        if not paths:
            if GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC):
                paths = [GLib.get_user_special_dir(
                                          GLib.UserDirectory.DIRECTORY_MUSIC)]
            else:
                print("You need to add a music path"
                      " to org.gnome.Lollypop in dconf")
                return

        if not self._in_thread:
            self._progress.show()
            self._in_thread = True
            self._compilations = []
            self._mtimes = Objects.tracks.get_mtimes()
            start_new_thread(self._scan, (paths,))
Beispiel #21
0
 def get_xdg_pictures_folder():
     try:
         pics_folder = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
         if not pics_folder:
             raise Exception("Could not get path to Pictures folder. Defaulting to ~/Pictures.")
         return pics_folder
     except:
         logger.exception(lambda: "Could not get path to Pictures folder. Defaulting to ~/Pictures.")
         return os.path.expanduser(u'~/Pictures')
 def get_default_folders(self):
     folders = {}
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)]      = 'Desktop.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)]    = 'Documents.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)]     = 'Downloads.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)]        = 'Music.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)]     = 'Pictures.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)] = 'Public.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)]    = 'Templates.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)]       = 'Videos.svg'
     return folders
 def get_default_folders(self):
     folders = {}
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP)]      = 'user-desktop.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)]    = 'folder-documents.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)]     = 'folder-download.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)]        = 'folder-music.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)]     = 'folder-pictures.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE)] = 'folder-publicshare.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES)]    = 'folder-templates.svg'
     folders[GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)]       = 'folder-video.svg'
     return folders
Beispiel #24
0
def get_launcher_path(game_slug, game_id):
    """Return the path of a XDG game launcher.
    When legacy is set, it will return the old path with only the slug,
    otherwise it will return the path with slug + id
    """
    desktop_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)

    return os.path.join(
        desktop_dir, get_xdg_basename(game_slug, game_id, base_dir=desktop_dir)
    )
Beispiel #25
0
def get_user_dir(folder):
    '''
    Get path to one of the XDG user folders.

    :param folder: folder name as str, lowercase, possible are:
    desktop, documents, downloads, music, pictures, public, templates, videos

    :returns: path to XDG user directory
    '''
    return GLib.get_user_special_dir(USER_FOLDERS[folder])
Beispiel #26
0
 def open_download_dialog(self, widget):
     dialog = Gtk.FileChooserDialog('下载', None, Gtk.FileChooserAction.SAVE, (
         '取消', Gtk.ResponseType.CANCEL,
         '确定', Gtk.ResponseType.OK))
     dialog.set_current_name(
         self.song['artist'] + ' - ' + self.song['title'] + '.mp3')
     dialog.set_current_folder(
         GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD))
     if dialog.run() == Gtk.ResponseType.OK:
         threading.Thread(target=self.download, args=(dialog.get_filename(),)).start()
     dialog.destroy()
Beispiel #27
0
 def __init__(self, header_bar, player):
     Gtk.Stack.__init__(self,
                        transition_type=Gtk.StackTransitionType.CROSSFADE)
     builder = Gtk.Builder()
     builder.add_from_resource('/org/gnome/Music/NoMusic.ui')
     music_folder_path = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
     widget = builder.get_object('container')
     label = builder.get_object('label1')
     label.set_label(_("No Music found!\n Put some files into the folder %s") % music_folder_path)
     self.add(widget)
     self.show_all()
Beispiel #28
0
	def on_download_requested(self,web_view,download):
		#dest = webkit_download_get_uri()
		#webkit_download_set_destination_uri(download, dest);
		uri = download.get_uri()
		destination_download_uri = GLib.filename_to_uri(GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD) + '/'+ download.get_suggested_filename())
		download.set_destination_uri(destination_download_uri)
		download.connect("notify::status", self.on_notify_status)
		download.connect("notify::progress", self.on_download_progress)
		download.connect("error", self.on_download_error)
		#download.start()

		return True
Beispiel #29
0
    def __init__(self):
        try:
            Query.music_folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
            assert Query.music_folder is not None
        except (TypeError, AssertionError):
            logger.warn("XDG Music dir is not set")
            return

        Query.MUSIC_URI = Tracker.sparql_escape_string(GLib.filename_to_uri(Query.music_folder))

        for folder in [Query.music_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted", folder)
def set_default_photo_source():
    save = SaveListStore()

    if not save.has_save_file():

        monitor_w, monitor_h = get_geometry_first_monitor()
        if monitor_w > 800 and monitor_h > 600:
            SETTINGS_GEOMETRY.set_int('root-x', monitor_w - 225)
            SETTINGS_GEOMETRY.set_int('root-y', 200)

        folder = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
        sources = {0: {'source': 'Flickr', 'target': _('Interestingness')},
                   1: {'source': _('Folder'), 'target': folder}}
        save.save_to_json(sources)
    def embed_albums(self, selected_albums):
        '''
        method to create the menu items for all supported plugins

        :selected_albums: `Album` - array of albums
        
        '''
        # temporarily move this import to here for v0.8
        # need to separate the two plugins correctly for v0.9
        from coverart_search_tracks import CoverArtTracks
        
        search_tracks = CoverArtTracks()
        playlist_manager = self.shell.props.playlist_manager
        playlists_entries = playlist_manager.get_playlists()

        ui = Gtk.Builder()
        ui.add_from_file(rb.find_plugin_file(self.plugin,
            'ui/coverart_exportembed.ui'))
        ui.connect_signals(self)
        embeddialog = ui.get_object('exportembeddialog')
        folderchooserbutton  = ui.get_object('folderchooserbutton')
        use_album_name_checkbutton = ui.get_object('use_album_name_checkbutton')
        open_filemanager_checkbutton = ui.get_object('open_filemanager_checkbutton')
        
        downloads_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        folderchooserbutton.set_current_folder(downloads_dir)

        response = embeddialog.run()
        
        if response != Gtk.ResponseType.OK:
            embeddialog.destroy()
            return

        #ok pressed - now fetch values from the dialog
        final_folder_store = folderchooserbutton.get_current_folder()
        use_album_name = use_album_name_checkbutton.get_active()
        open_filemanager = open_filemanager_checkbutton.get_active()
        
        embeddialog.destroy()

        albums = {}
        total = 0

        for album in selected_albums:
            albums[album] = album.get_tracks()
            total = total + len(albums[album])

        self._track_count = 1

        def complete():
            self.album_manager.progress = 1
        
            if open_filemanager:
                #code taken from http://stackoverflow.com/questions/1795111/is-there-a-cross-platform-way-to-open-a-file-browser-in-python
                if sys.platform=='win32':
                    import _winreg
                    path= r('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon')
                    for root in (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE):
                        try:
                            with _winreg.OpenKey(root, path) as k:
                                value, regtype= _winreg.QueryValueEx(k, 'Shell')
                        except WindowsError:
                            pass
                        else:
                            if regtype in (_winreg.REG_SZ, _winreg.REG_EXPAND_SZ):
                                shell= value
                            break
                    else:
                        shell= 'Explorer.exe'
                    subprocess.Popen([shell, final_folder_store])

                elif sys.platform=='darwin':
                    subprocess.Popen(['open', final_folder_store])

                else:
                    subprocess.Popen(['xdg-open', final_folder_store])

        self._albumiter = iter(albums)
        self._tracknumber = 0
        self._album = self._albumiter.next()
        
        def idle_call(data):
            exit_idle = True

            track = albums[self._album][self._tracknumber]
                
            if not process_track(self._album, track):
                exit_idle = False

            self._tracknumber = self._tracknumber + 1

            if self._tracknumber >= len(albums[self._album]):          
                try:
                    self._tracknumber = 0
                    self._album = self._albumiter.next()
                except StopIteration:
                    exit_idle = False
           
            if not exit_idle:
                complete()

            return exit_idle
        
        def process_track(album, track):
            self.album_manager.progress = self._track_count / total
            self._track_count = self._track_count + 1

            key = album.create_ext_db_key()
            finalPath = urllib.unquote(track.location)[7:]
            album_name = RB.search_fold(album.name)
            
            if use_album_name:
                folder_store = final_folder_store + '/' + album_name
            else:
                folder_store = final_folder_store
                
            try:
                if not os.path.exists(folder_store):
                    os.makedirs(folder_store)
                shutil.copy(finalPath, folder_store)
            except IOError as err:
                print err.args[0]
                return False

            dest = os.path.join(folder_store, os.path.basename(finalPath))
            desturi = 'file://' + urllib.pathname2url(dest)
            
            return search_tracks.embed(desturi, key)

        data = None
        
        Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, idle_call, data)
Beispiel #32
0
    def __init__(self):
        """
            Init dialog
        """
        self._choosers = []

        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/SettingsDialog.ui')

        self._settings_dialog = builder.get_object('settings_dialog')
        self._settings_dialog.set_transient_for(Lp.window)

        if not Lp.settings.get_value('disable-csd'):
            self._settings_dialog.set_titlebar(
                builder.get_object('header_bar'))

        switch_scan = builder.get_object('switch_scan')
        switch_scan.set_state(Lp.settings.get_value('auto-update'))

        switch_view = builder.get_object('switch_dark')
        switch_view.set_state(Lp.settings.get_value('dark-ui'))

        switch_background = builder.get_object('switch_background')
        switch_background.set_state(Lp.settings.get_value('background-mode'))

        switch_state = builder.get_object('switch_state')
        switch_state.set_state(Lp.settings.get_value('save-state'))

        switch_autoplay = builder.get_object('switch_autoplay')
        switch_autoplay.set_state(Lp.settings.get_value('auto-play'))

        switch_genres = builder.get_object('switch_genres')
        switch_genres.set_state(Lp.settings.get_value('show-genres'))

        switch_compilations = builder.get_object('switch_compilations')
        switch_compilations.set_state(
            Lp.settings.get_value('show-compilations'))

        self._settings_dialog.connect('destroy', self._edit_settings_close)

        builder.connect_signals(self)

        main_chooser_box = builder.get_object('main_chooser_box')
        self._chooser_box = builder.get_object('chooser_box')
        party_grid = builder.get_object('party_grid')

        #
        # Music tab
        #
        dirs = []
        for directory in Lp.settings.get_value('music-path'):
            dirs.append(directory)

        # Main chooser
        self._main_chooser = ChooserWidget()
        image = Gtk.Image.new_from_icon_name("list-add-symbolic",
                                             Gtk.IconSize.MENU)
        self._main_chooser.set_icon(image)
        self._main_chooser.set_action(self._add_chooser)
        main_chooser_box.pack_start(self._main_chooser, False, True, 0)
        if len(dirs) > 0:
            path = dirs.pop(0)
        else:
            path = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
        self._main_chooser.set_dir(path)

        # Others choosers
        for directory in dirs:
            self._add_chooser(directory)

        #
        # Party mode tab
        #
        genres = Lp.genres.get()
        genres.insert(0, (Type.POPULARS, _("Populars")))
        genres.insert(1, (Type.RECENTS, _("Recently added")))
        ids = Lp.player.get_party_ids()
        i = 0
        x = 0
        for genre_id, genre in genres:
            label = Gtk.Label()
            label.set_property('margin-start', 10)
            label.set_property('halign', Gtk.Align.START)
            label.set_property('hexpand', True)
            label.set_ellipsize(Pango.EllipsizeMode.END)
            label.set_text(genre)
            label.set_tooltip_text(genre)
            label.show()
            switch = Gtk.Switch()
            if genre_id in ids:
                switch.set_state(True)
            switch.connect("state-set", self._party_switch_state, genre_id)
            switch.set_property('margin-end', 50)
            switch.show()
            party_grid.attach(label, x, i, 1, 1)
            party_grid.attach(switch, x+1, i, 1, 1)
            if x == 0:
                x += 2
            else:
                i += 1
                x = 0
        #
        # Last.fm tab
        #
        if Lp.lastfm is not None and Secret is not None:
            self._test_img = builder.get_object('test_img')
            self._login = builder.get_object('login')
            self._password = builder.get_object('password')
            schema = Secret.Schema.new("org.gnome.Lollypop",
                                       Secret.SchemaFlags.NONE,
                                       SecretSchema)
            Secret.password_lookup(schema, SecretAttributes, None,
                                   self._on_password_lookup)
            builder.get_object('lastfm_grid').set_sensitive(True)
            builder.get_object('lastfm_error').hide()
            self._login.set_text(
                Lp.settings.get_value('lastfm-login').get_string())
Beispiel #33
0
 def __init__(self,
              directory='{}/Wallpapers'.format(
                  GLib.get_user_special_dir(
                      GLib.UserDirectory.DIRECTORY_PICTURES))):
     self._types = ('*.jpg', '*.jpeg', '*.png')
     self.directory = directory
def get_default_recordings_dir():
    videos = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS)
    if videos == None:
        videos = join(expanduser('~'), 'Videos')
    return join(videos, 'Recordings')
Beispiel #35
0
    def run(self, keywords, path, search_zips, regex=False, exclude_paths=[]):
        """Run the search method using keywords and path.  regex is not used
        by this search method.

        This function is a generator and will yield files as they are found or
        True if still running."""
        exclude = []
        maybe_exclude = exclude_paths
        for maybe_path in maybe_exclude:
            if not path.startswith(maybe_path):
                exclude.append(maybe_path)

        self.running = True
        if isinstance(keywords, str):
            keywords = keywords.replace(',', ' ').strip().split()

        # Enable symbolic link directories, but process once
        processed_links = []

        # Grab the special directory list to get them precedence
        xdgdirlist = [
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_TEMPLATES),
            GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS),
        ]

        for root, dirs, files in os.walk(top=path, topdown=True,
                                         onerror=None,
                                         followlinks=True):
            # Bail once the search has been canceled
            if not self.running:
                break

            # Check if we've already processed symbolic paths
            if os.path.islink(root):
                realpath = os.path.realpath(root)
                if realpath in processed_links:
                    yield True
                    continue
                processed_links.append(realpath)

            # Prioritize and drop excluded paths
            dirs[:] = self.get_dir_list(
                root, dirs, xdgdirlist, exclude, processed_links)

            paths = sorted(dirs + files)

            # Check paths in the second and deeper levels of the selected
            # directory
            for path in paths:
                fullpath = os.path.join(root, path)
                if self.search_path(path, keywords):
                    yield fullpath
                if search_zips and \
                   os.path.isfile(fullpath) and zipfile.is_zipfile(fullpath):
                    yield fullpath
            yield True
        yield False
Beispiel #36
0
import aptdaemon.client
from aptdaemon.enums import *
from aptdaemon.gtk3widgets import AptErrorDialog, AptConfirmDialog, AptProgressDialog, AptStatusIcon
import aptdaemon.errors

import setproctitle
setproctitle.setproctitle("mintbackup")

# i18n
gettext.install("mintbackup", "/usr/share/linuxmint/locale")

HOME = os.path.expanduser("~")
UI_FILE = '/usr/share/linuxmint/mintbackup/mintbackup.ui'
META_FILE = ".meta.mint"

BACKUP_DIR = os.path.join(GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS), _("Backups"))
if not os.path.exists(BACKUP_DIR):
    print("Creating backup directory in %s" % BACKUP_DIR)
    os.makedirs(BACKUP_DIR)

(TAB_START, TAB_FILE_BACKUP_1, TAB_FILE_BACKUP_2, TAB_FILE_BACKUP_3, TAB_FILE_BACKUP_4, TAB_FILE_BACKUP_5, TAB_FILE_RESTORE_1, TAB_FILE_RESTORE_3, TAB_FILE_RESTORE_4,
TAB_PKG_BACKUP_1, TAB_PKG_BACKUP_2, TAB_PKG_RESTORE_1, TAB_PKG_RESTORE_2, TAB_PKG_RESTORE_3) = range(14)

def print_timing(func):
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
        print('%s took %0.3f ms' % (func.__name__, (t2 - t1) * 1000.0))
        return res
    return wrapper
Beispiel #37
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        accel = Gtk.AccelGroup()
        accel.connect(Gdk.keyval_from_name('q'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.on_quit_app)
        accel.connect(Gdk.keyval_from_name('h'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.on_toggle_high_quality)
        accel.connect(Gdk.keyval_from_name('a'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.on_toggle_audio)
        accel.connect(Gdk.keyval_from_name('m'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.on_toggle_mouse_record)
        accel.connect(Gdk.keyval_from_name('r'), Gdk.ModifierType.CONTROL_MASK,
                      0, self.on_toggle_record)
        self.cpus = multiprocessing.cpu_count() - 1
        self.add_accel_group(accel)
        self.connect("delete-event", self.on_delete_event)
        Notify.init(constants["APPID"])
        self.notification = None
        self.settings = Gio.Settings.new(constants["APPID"])
        self.recordSoundOn = self.settings.get_boolean('record-audio-switch')
        self.delayBeforeRecording = self.settings.get_int('delay')
        self.videoFrames = self.settings.get_int('frames')
        self.recordMouse = self.settings.get_boolean(
            'record-mouse-cursor-switch')
        self.recordFormat = self.settings.get_string('format-video')
        self._sound_on_switch.set_active(self.recordSoundOn)
        self._record_mouse_switcher.set_active(self.recordMouse)
        self._quality_video_switcher.set_active(
            self.settings.get_boolean("high-quality-switch"))
        self._delay_button.set_value(self.delayBeforeRecording)
        if self.videoFrames == 15:
            self._frames_combobox.set_active(0)
        elif self.videoFrames == 30:
            self._frames_combobox.set_active(1)
        else:
            self._frames_combobox.set_active(2)

        self.currentFolder = self.settings.get_string(
            'path-to-save-video-folder')

        if self.currentFolder == "Default":
            if GLib.get_user_special_dir(
                    GLib.UserDirectory.DIRECTORY_VIDEOS) == None:

                directory = "/RecAppVideo"
                parent_dir = Popen("xdg-user-dir", shell=True,
                                   stdout=PIPE).communicate()
                parent_dir = list(parent_dir)
                parent_dir = parent_dir[0].decode().split()[0]
                path = parent_dir + directory

                if not os.path.exists(path):
                    os.makedirs(path)
                self.settings.set_string('path-to-save-video-folder', path)
            else:
                self.settings.set_string(
                    'path-to-save-video-folder',
                    GLib.get_user_special_dir(
                        GLib.UserDirectory.DIRECTORY_VIDEOS))
            self._video_folder_button.set_current_folder_uri(
                self.settings.get_string('path-to-save-video-folder'))
        else:
            self._video_folder_button.set_current_folder_uri(
                self.currentFolder)

        self.displayServer = os.environ['XDG_SESSION_TYPE'].lower()

        if self.displayServer == "wayland":
            self._select_area_button.set_visible(False)
            self._sound_box.set_visible(False)
            self._sound_on_switch.set_active(False)
            self._audio_rowbox.set_visible(False)
            self.bus = SessionBus()
            if os.environ['XDG_CURRENT_DESKTOP'] != 'GNOME':
                self._record_button.set_sensitive(False)
                self.notification = Notify.Notification.new(
                    constants["APPNAME"],
                    _("Sorry, Wayland session is not supported yet"))
                self.notification.show()
            else:
                self.GNOMEScreencast = self.bus.get(
                    'org.gnome.Shell.Screencast',
                    '/org/gnome/Shell/Screencast')
        else:
            self.video_str = "gst-launch-1.0 --eos-on-shutdown ximagesrc use-damage=1 show-pointer={0} ! video/x-raw,framerate={1}/1 ! queue ! videoscale ! videoconvert ! {2} ! queue ! {3} name=mux ! queue ! filesink location='{4}'{5}"

        for encoder in self.encoders:
            plugin = Gst.ElementFactory.find(encoder)
            if plugin:
                if (encoder == "vp8enc"):
                    self.formats.append("webm")
                    self.formats.append("mkv")
                elif (encoder == "x264enc"):
                    self.formats.append("mp4")
            else:
                pass
        formats_store = Gtk.ListStore(str)
        for format in self.formats:
            formats_store.append([format])
        self._formats_combobox.set_model(formats_store)
        self._formats_combobox.set_active(
            self.formats.index(self.settings.get_string('format-video')))
        self.recordFormat = self._formats_combobox.get_active_text()
Beispiel #38
0
def get_user_special_dir(d_id):
    """Like g_get_user_special_dir(), but always unicode"""
    d_fs = GLib.get_user_special_dir(d_id)
    return filename_to_unicode(d_fs)
Beispiel #39
0
    def configure_minidlna(self):

        if not os.path.exists(MINIDLNA_CONFIG_DIR):
            self.logger.debug(u"Creating config dir: {config_dir}...".format(cache_dir=MINIDLNA_CONFIG_DIR))
            os.mkdir(MINIDLNA_CONFIG_DIR)

        if not os.path.exists(MINIDLNA_CACHE_DIR):
            self.logger.debug(u"Creating cache dir: {cache_dir}...".format(cache_dir=MINIDLNA_CACHE_DIR))
            os.mkdir(MINIDLNA_CACHE_DIR)

        if not os.path.exists(MINIDLNA_CONFIG_FILE):

            self.logger.debug(u"Creating initial config file...")
            with codecs.open(MINIDLNA_CONFIG_FILE, "w", "utf-8") as f:
                home_dir = os.path.expanduser("~")
                f.write(u"db_dir={db_dir}\n".format(db_dir=MINIDLNA_CACHE_DIR))
                self.minidlna_logdir = MINIDLNA_LOG_DIR
                f.write(u"log_dir={log_dir}\n".format(log_dir=self.minidlna_logdir))
                self.minidlna_port = 8200+random.randint(1, 99)
                self.logger.debug(u"Setting port to {port}".format(port=self.minidlna_port))
                f.write(u"port={port}\n".format(port=self.minidlna_port))
                f.write(u"uuid={uuid}\n".format(uuid=str(uuid.uuid4())))
                f.write(u"friendly_name=" + _(u"Multimedia for {user}").format(user=getpass.getuser()) + "\n")

                download_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
                if download_dir:
                    if download_dir != home_dir:
                        download_dir = download_dir.decode('utf-8')
                        self.logger.debug(u"Adding folder {folder} as downloads...".format(folder=download_dir))
                        f.write(u"media_dir={media_dir}\n".format(media_dir=download_dir))
                        self.minidlna_dirs.append({"path": download_dir, "type": "mixed"})
                    else:
                        self.logger.debug(u"Detected download folder {folder} is the same as the home folder; ignoring.".format(folder=download_dir))
                else:
                    self.logger.debug(u"Couldn't detect download folder; ignoring.")

                pictures_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
                if pictures_dir:
                    if pictures_dir != home_dir:
                        pictures_dir = pictures_dir.decode('utf-8')
                        self.logger.debug(u"Adding folder {folder} as pictures...".format(folder=pictures_dir))
                        f.write(u"media_dir=P,{media_dir}\n".format(media_dir=pictures_dir))
                        self.minidlna_dirs.append({"path": pictures_dir, "type": "pictures"})
                    else:
                        self.logger.debug(u"Detected pictures folder {folder} is the same as the home folder; ignoring.".format(folder=pictures_dir))
                else:
                    self.logger.debug(u"Couldn't detect pictures folder; ignoring.")

                music_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
                if music_dir:
                    if music_dir != home_dir:
                        music_dir = music_dir.decode('utf-8')
                        self.logger.debug(u"Adding folder {folder} as music...".format(folder=music_dir))
                        f.write(u"media_dir=A,{media_dir}\n".format(media_dir=music_dir))
                        self.minidlna_dirs.append({"path": music_dir, "type": "audio"})
                    else:
                        self.logger.debug(u"Detected music folder {folder} is the same as the home folder; ignoring.".format(folder=music_dir))
                else:
                    self.logger.debug(u"Couldn't detect music folder; ignoring.")

                videos_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS)
                if videos_dir:
                    if videos_dir != home_dir:
                        videos_dir = videos_dir.decode('utf-8')
                        self.logger.debug(u"Adding folder {folder} as videos...".format(folder=videos_dir))
                        f.write(u"media_dir=V,{media_dir}\n".format(media_dir=videos_dir))
                        self.minidlna_dirs.append({"path": videos_dir, "type": "video"})
                    else:
                        self.logger.debug(u"Detected videos folder {folder} is the same as the home folder; ignoring.".format(folder=videos_dir))
                else:
                    self.logger.debug(u"Couldn't detect videos folder; ignoring.")

        else:

            # Obtener los datos actuales del archivo de configuración
            self.logger.debug(u"Reading existing config file {config_file}...".format(config_file=MINIDLNA_CONFIG_FILE))
            with codecs.open(MINIDLNA_CONFIG_FILE, "a+", "utf-8") as fp:
                uuid_file = None
                friendly_name = None
                for line in fp:
                    line = line.strip()
                    if line.startswith("port="):
                        self.minidlna_port = int(re.sub(r'^port=', "", line))
                        self.logger.debug(u"Setting port to {port}...".format(port=self.minidlna_port))
                    elif line.startswith("log_dir="):
                        self.minidlna_logdir = re.sub(r'^log_dir=', "", line)
                        self.logger.debug(u"Setting log_dir to {log_dir}...".format(log_dir=self.minidlna_logdir))
                    elif line.startswith("uuid="):
                        uuid_file = re.sub(r'^uuid=', "", line)
                        self.logger.debug(u"Setting uuid to {uuid}...".format(uuid=uuid_file))
                    elif line.startswith("friendly_name="):
                        friendly_name = re.sub(r'^friendly_name=', "", line)
                        self.logger.debug(u"Setting friendly_name to {friendly_name}...".format(friendly_name=friendly_name))
                    elif line.startswith("media_dir="):
                        line = re.sub(r'^media_dir=', '', line)
                        if line.startswith("A,"):
                            line = re.sub(r'^A,', '', line)
                            self.logger.debug(u"Adding audio folder {folder}...".format(folder=line))
                            self.minidlna_dirs.append({"path": line, "type": "audio"})
                        elif line.startswith("P,"):
                            line = re.sub(r'^P,', '', line)
                            self.logger.debug(u"Adding pictures folder {folder}...".format(folder=line))
                            self.minidlna_dirs.append({"path": line, "type": "pictures"})
                        elif line.startswith("V,"):
                            line = re.sub(r'^V,', '', line)
                            self.logger.debug(u"Adding video folder {folder}...".format(folder=line))
                            self.minidlna_dirs.append({"path": line, "type": "video"})
                        elif line.startswith("PV,"):
                            line = re.sub(r'^PV,', '', line)
                            self.logger.debug(u"Adding pictures/video folder {folder}...".format(folder=line))
                            self.minidlna_dirs.append({"path": line, "type": "picturesvideo"})
                        else:
                            self.logger.debug(u"Adding mixed (no-type specified) folder {folder}...".format(folder=line))
                            self.minidlna_dirs.append({"path": line, "type": "mixed"})

                if not uuid_file or not friendly_name or not self.minidlna_port:
                    fp.write("\n")
                    if not uuid_file:
                        self.logger.info(u"No UUID specified in configuration file; generating one and saving to file...")
                        generated_uuid_file = str(uuid.uuid4())
                        self.logger.debug(u"UUID generated: {uuid}".format(uuid=generated_uuid_file))
                        fp.write(u"uuid={uuid}\n".format(uuid=generated_uuid_file))
                    if not friendly_name:
                        self.logger.info(u"No friendly_name specified in configuration file; generating one and saving to file...")
                        generated_friendly_name = _(u"Multimedia for {user}").format(user=getpass.getuser())
                        self.logger.debug(u"friendly_name generated: {friendly_name}".format(friendly_name=generated_friendly_name))
                        fp.write(u"friendly_name={friendly_name}\n".format(friendly_name=generated_friendly_name))
                    if not self.minidlna_port:
                        self.logger.info(u"No port specified in configuration file; generating one and saving to file...")
                        self.minidlna_port = 8200 + random.randint(1, 99)
                        self.logger.debug(u"Port generated: {port}".format(port=self.minidlna_port))
                        fp.write(u"port={port}\n".format(port=self.minidlna_port))
Beispiel #40
0
setproctitle.setproctitle("mintbackup")

# i18n
APP = 'mintbackup'
LOCALE_DIR = "/usr/share/linuxmint/locale"
locale.bindtextdomain(APP, LOCALE_DIR)
gettext.bindtextdomain(APP, LOCALE_DIR)
gettext.textdomain(APP)
_ = gettext.gettext

HOME = os.path.expanduser("~")
UI_FILE = '/usr/share/linuxmint/mintbackup/mintbackup.ui'
META_FILE = ".meta.mint"

BACKUP_DIR = os.path.join(
    GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS), _("Backups"))
if not os.path.exists(BACKUP_DIR):
    print("Creating backup directory in %s" % BACKUP_DIR)
    os.makedirs(BACKUP_DIR)

(TAB_START, TAB_FILE_BACKUP_1, TAB_FILE_BACKUP_2, TAB_FILE_BACKUP_3,
 TAB_FILE_BACKUP_4, TAB_FILE_BACKUP_5, TAB_FILE_RESTORE_1, TAB_FILE_RESTORE_3,
 TAB_FILE_RESTORE_4, TAB_PKG_BACKUP_1, TAB_PKG_BACKUP_2, TAB_PKG_RESTORE_1,
 TAB_PKG_RESTORE_2, TAB_PKG_RESTORE_3) = range(14)


def print_timing(func):
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
Beispiel #41
0
class Theme(object):
    KNOWN_DIRECTORIES = {
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_DESKTOP):
        'user-desktop.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS):
        'folder-documents.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD):
        'folder-download.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC):
        'folder-music.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES):
        'folder-pictures.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_PUBLIC_SHARE):
        'folder-publicshare.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_TEMPLATES):
        'folder-templates.svg',
        GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS):
        'folder-video.svg',
        GLib.get_home_dir(): 'folder-home.svg',
    }
    logger.debug("Known directories are: %s" % KNOWN_DIRECTORIES)

    KNOWN_THEMES = {
        'Mint-X': 'Green',
        'Mint-X-Dark': 'Green',
        'Rave-X-CX': 'Beige',
        'Faience': 'Beige',
        'gnome': 'Beige',
        'Matrinileare': 'Beige',
        'menta': 'Green',
        'mate': 'Beige',
        'oxygen': 'Blue'
    }
    logger.debug("Known themes are: %s" % KNOWN_THEMES)

    def __init__(self, base_name, color_variant):
        self.base_name = base_name
        self.color_variant = color_variant

    def __str__(self):
        if self.color_variant:
            return "%s-%s" % (self.base_name, self.color_variant)
        else:
            return "%s" % self.base_name

    @staticmethod
    def parse(theme_str):
        base_name = theme_str
        color_variant = None
        for color in COLORS:
            if theme_str.endswith("-%s" % color):
                base_name = theme_str[:-len("-%s" % color)]
                color_variant = color
        return base_name, color_variant

    @staticmethod
    def from_theme_name(theme_str):
        base_name, color_variant = Theme.parse(theme_str)
        return Theme(base_name, color_variant)

    @property
    def base_path(self):
        return "/usr/share/icons/%s/" % self

    def get_folder_icon_path(self, directory=None):
        icon_name = Theme.KNOWN_DIRECTORIES.get(directory, 'folder.svg')
        return os.path.join(self.base_path, "places/48/", icon_name)

    def get_index_theme_path(self):
        return os.path.join(self.base_path, "index.theme")

    def has_svg_for_folder(self, directory=None):
        path = self.get_folder_icon_path(directory)
        return os.path.isfile(path)

    def inherited_themes(self):
        logger.debug('Importing config parser...')
        import ConfigParser
        parser = ConfigParser.RawConfigParser()
        index_theme_path = self.get_index_theme_path()
        try:
            logger.debug('Trying to read index.theme at %s' % index_theme_path)
            parser.read(index_theme_path)
            inherits_str = parser.get('Icon Theme', 'Inherits')
            logger.debug('Theme %s inherits %s' % (self, inherits_str))
            result = []
            for parent in inherits_str.split(","):
                result.append(Theme.from_theme_name(parent))
            return result
        except:
            logger.info('Could not read index.theme for theme %s' % self)
            return []

    def get_ancestor_defining_folder_svg(self, directory=None):
        if self.has_svg_for_folder(directory):
            return self
        for theme in self.inherited_themes():
            ancestor = theme.get_ancestor_defining_folder_svg(directory)
            if ancestor:
                return ancestor
        return None

    def sibling(self, color):
        if color == self.color:
            # This theme implements the desired color
            return self
        elif color == Theme.KNOWN_THEMES.get(self.base_name):
            # The base version of this theme implements the desired color
            return Theme(self.base_name, None)
        else:
            # The color belongs to a color variant
            return Theme(self.base_name, color)

    def find_folder_icon(self, color, directory=None):
        logger.debug(
            "Trying to find icon for directory %s in %s for theme %s" %
            (directory, color, self))
        relevant_ancestor = self.get_ancestor_defining_folder_svg(directory)
        if not relevant_ancestor:
            logger.warning("Could not find ancestor defining SVG")
            return None
        logger.debug("Ancestor defining SVG is %s" % relevant_ancestor)
        colored_theme = relevant_ancestor.sibling(color)
        icon_path = colored_theme.get_folder_icon_path(directory)
        logger.debug("Checking for icon in %s" % icon_path)
        if os.path.isfile(icon_path):
            logger.debug("Icon found")
            return icon_path
        else:
            logger.debug("No suitable icon found")
            return None

    def get_supported_colors(self, paths):
        supported_colors = []

        for color in COLORS:
            color_supported = True
            for directory in paths:
                icon_path = self.find_folder_icon(color, directory)
                if not icon_path:
                    color_supported = False
                    break
            if color_supported:
                supported_colors.append(color)
        return supported_colors

    @property
    def color(self):
        if self.color_variant:
            return self.color_variant
        else:
            return Theme.KNOWN_THEMES.get(self.base_name)
Beispiel #42
0
class Query():
    music_folder = None
    MUSIC_URI = None
    download_folder = None
    DOWNLOAD_URI = None
    try:
        music_folder = GLib.get_user_special_dir(
            GLib.UserDirectory.DIRECTORY_MUSIC)
        MUSIC_URI = Tracker.sparql_escape_string(
            GLib.filename_to_uri(music_folder))
        download_folder = GLib.get_user_special_dir(
            GLib.UserDirectory.DIRECTORY_DOWNLOAD)
        DOWNLOAD_URI = Tracker.sparql_escape_string(
            GLib.filename_to_uri(download_folder))

        for folder in [music_folder, download_folder]:
            if os.path.islink(folder):
                logger.warn("%s is a symlink, this folder will be omitted" %
                            folder)
            else:
                i = len(next(os.walk(folder))[2])
                logger.debug("Found %d files in %s" % (i, folder))
    except TypeError:
        logger.warn("XDG user dirs are not set")

    @staticmethod
    def order_by_statement(attr):
        """Returns a SPARQL ORDER BY statement sorting by the given attribute, ignoring
            articles as defined in _("the"). 'Attr' should be given without parentheses,
            e.g., "attr='?author'"."""
        return_statement = "fn:lower-case(%(attribute)s)" % {'attribute': attr}
        # TRANSLATORS: _("the") should be a space-separated list of all-lowercase articles
        # (such as 'the') that should be ignored when alphabetizing artists/albums. This
        # list should include 'the' regardless of language. If some articles occur more
        # frequently than others, most common should appear first, least common last.
        for article in reversed(_("the a an").split(" ")):
            return_statement = '''IF(fn:starts-with(fn:lower-case(%(attribute)s), "%(article)s"),
            fn:substring(fn:lower-case(%(attribute)s), %(substr_start)s),
            %(nested_if)s)''' % {
                'attribute': attr,
                'article': article + " ",
                'substr_start': str(len(article) + 2),
                'nested_if': return_statement
            }
        return return_statement

    @staticmethod
    def all_albums():
        return Query.albums('?album a nmm:MusicAlbum .')

    @staticmethod
    def all_artists():
        return Query.artists('?album a nmm:MusicAlbum .')

    @staticmethod
    def all_songs():
        return Query.songs('?song a nmm:MusicPiece ; a nfo:FileDataObject .')

    @staticmethod
    def all_playlists():
        return Query.playlists('?playlist a nmm:Playlist .')

    @staticmethod
    def all_songs_count():
        query = '''
    SELECT
        COUNT(?song) AS childcount
    WHERE {
        ?song a nmm:MusicPiece ;
              a nfo:FileDataObject
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    '''.replace('\n', ' ').strip() % {
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def albums(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
        tracker:coalesce(
            (
                SELECT
                    GROUP_CONCAT(
                        nmm:artistName(?artist),
                        ','
                    )
                WHERE {
                    ?album nmm:albumArtist ?artist
                }
            ),
            (
                SELECT
                    GROUP_CONCAT(
                        (
                            SELECT
                                nmm:artistName(nmm:performer(?_12)) AS perf
                            WHERE {
                                ?_12 nmm:musicAlbum ?album
                            }
                            GROUP BY ?perf
                        ),
                        ','
                    ) AS album_performer
                WHERE {
                }
            )
        ) AS author
        xsd:integer(
            tracker:coalesce(
                nmm:albumTrackCount(?album),
                (
                    SELECT
                        COUNT(?_1)
                    WHERE {
                        ?_1 nmm:musicAlbum ?album ;
                            tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?_1)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?_1)
                            )
                        )
                        FILTER (
                            NOT EXISTS {
                                ?_1 a nmm:Video
                            } &&
                            NOT EXISTS {
                                ?_1 a nmm:Playlist
                            }
                        )
                    }
                )
            )
        ) AS childcount
        (
            SELECT
                fn:year-from-dateTime(?c)
            WHERE {
                ?_2 nmm:musicAlbum ?album ;
                    nie:contentCreated ?c ;
                    tracker:available 'true'
                FILTER (
                    tracker:uri-is-descendant(
                        '%(music_dir)s', nie:url(?_2)
                    ) ||
                    tracker:uri-is-descendant(
                        '%(download_dir)s', nie:url(?_2)
                    )
                )
                FILTER (
                    NOT EXISTS {
                        ?_2 a nmm:Video
                    } &&
                    NOT EXISTS {
                        ?_2 a nmm:Playlist
                    }
                )
            }
            LIMIT 1
        ) AS creation-date
        {
            %(where_clause)s
            FILTER (
                EXISTS {
                    ?_3 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                    FILTER (
                        tracker:uri-is-descendant(
                            '%(music_dir)s', nie:url(?_3)
                        ) ||
                        tracker:uri-is-descendant(
                            '%(download_dir)s', nie:url(?_3)
                        )
                    )
                    FILTER (
                        NOT EXISTS {
                            ?_3 a nmm:Video
                        } &&
                        NOT EXISTS {
                            ?_3 a nmm:Playlist
                        }
                    )
                }
            )
        }
    ORDER BY %(album_order)s
        %(artist_order)s
        ?albumyear
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI,
            'album_order': Query.order_by_statement("?title"),
            'artist_order': Query.order_by_statement("?author")
        }

        return query

    @staticmethod
    def artists(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
        tracker:coalesce(
            (
                SELECT
                    GROUP_CONCAT(
                        nmm:artistName(?artist),
                        ','
                    )
                WHERE {
                    ?album nmm:albumArtist ?artist
                }
            ),
            (
                SELECT
                    GROUP_CONCAT(
                        (
                            SELECT
                                nmm:artistName(nmm:performer(?_12)) AS perf
                            WHERE {
                                ?_12 nmm:musicAlbum ?album
                                FILTER (
                                    tracker:uri-is-descendant(
                                        '%(music_dir)s', nie:url(?_12)
                                    ) ||
                                    tracker:uri-is-descendant(
                                        '%(download_dir)s', nie:url(?_12)
                                    )
                                )
                                FILTER (
                                    NOT EXISTS {
                                        ?_12 a nmm:Video
                                    } &&
                                    NOT EXISTS {
                                        ?_12 a nmm:Playlist
                                    }
                                )
                            }
                            GROUP BY ?perf
                        ),
                        ','
                    ) AS album_performer
                WHERE {
                }
            )
        ) AS author
        xsd:integer(
            tracker:coalesce(
                nmm:albumTrackCount(?album),
                (
                    SELECT
                        COUNT(?_1)
                    WHERE {
                        ?_1 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?_1)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?_1)
                            )
                        )
                        FILTER (
                            NOT EXISTS {
                                ?_1 a nmm:Video
                            } &&
                            NOT EXISTS {
                                ?_1 a nmm:Playlist
                            }
                        )
                    }
                )
            )
        ) AS childcount
        (
            SELECT
                fn:year-from-dateTime(?c)
            WHERE {
                ?_2 nmm:musicAlbum ?album ;
                    nie:contentCreated ?c ;
                    tracker:available 'true'
                FILTER (
                    tracker:uri-is-descendant(
                        '%(music_dir)s', nie:url(?_2)
                    ) ||
                    tracker:uri-is-descendant(
                        '%(download_dir)s', nie:url(?_2)
                    )
                )
                FILTER (
                    NOT EXISTS {
                        ?_2 a nmm:Video
                    } &&
                    NOT EXISTS {
                        ?_2 a nmm:Playlist
                    }
                )
            }
            LIMIT 1
        ) AS creation-date
        {
            %(where_clause)s
            FILTER (
                EXISTS {
                    ?_3 nmm:musicAlbum ?album ;
                        tracker:available 'true'
                    FILTER (
                        tracker:uri-is-descendant(
                            '%(music_dir)s', nie:url(?_3)
                        ) ||
                        tracker:uri-is-descendant(
                            '%(download_dir)s', nie:url(?_3)
                        )
                    )
                    FILTER (
                        NOT EXISTS {
                            ?_3 a nmm:Video
                        } &&
                        NOT EXISTS {
                            ?_3 a nmm:Playlist
                        }
                    )
                }
            )
        }
    ORDER BY %(artist_order)s
        ?albumyear
        %(album_order)s
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI,
            'artist_order': Query.order_by_statement("?author"),
            'album_order': Query.order_by_statement("nie:title(?album)")
        }

        return query

    @staticmethod
    def songs(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?song)
        tracker:id(?song) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
        {
            %(where_clause)s
            OPTIONAL {
                ?song nao:hasTag ?tag .
                FILTER( ?tag = nao:predefined-tag-favorite )
            }
            FILTER (
                tracker:uri-is-descendant(
                    '%(music_dir)s', nie:url(?song)
                ) ||
                tracker:uri-is-descendant(
                    '%(download_dir)s', nie:url(?song)
                )
            )
            FILTER (
                NOT EXISTS {
                    ?song a nmm:Video
                } &&
                NOT EXISTS {
                    ?song a nmm:Playlist
                }
            )
        }
    ORDER BY tracker:added(?song)
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def playlists(where_clause):
        query = '''
    SELECT DISTINCT
        rdf:type(?playlist)
        tracker:id(?playlist) AS id
        nie:title(?playlist) AS title
        nfo:entryCounter(?playlist) AS childcount
        {
            %(where_clause)s
            OPTIONAL {
                ?playlist a nfo:FileDataObject .
                FILTER (
                    EXISTS {
                        ?playlist tracker:available 'true'
                        FILTER (
                            tracker:uri-is-descendant(
                                '%(music_dir)s', nie:url(?playlist)
                            ) ||
                            tracker:uri-is-descendant(
                                '%(download_dir)s', nie:url(?playlist)
                            )
                        )
                    }
                )
            }
        }
    ORDER BY fn:lower-case(?title)
    '''.replace('\n', ' ').strip() % {
            'where_clause': where_clause.replace('\n', ' ').strip(),
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def album_songs(album_id):
        query = '''
    SELECT DISTINCT
        rdf:type(?song)
        tracker:id(?song) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
    WHERE {
        ?song a nmm:MusicPiece ;
              a nfo:FileDataObject ;
              nmm:musicAlbum ?album .
        OPTIONAL {
            ?song nao:hasTag ?tag .
            FILTER( ?tag = nao:predefined-tag-favorite )
        }
        FILTER (
            tracker:id(?album) = %(album_id)s
        )
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    ORDER BY
         nmm:setNumber(nmm:musicAlbumDisc(?song))
         nmm:trackNumber(?song)
         tracker:added(?song)
    '''.replace('\n', ' ').strip() % {
            'album_id': album_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def playlist_songs(playlist_id, filter_clause=None):
        query = '''
    SELECT
        rdf:type(?song)
        tracker:id(?entry) AS id
        nie:url(?song) AS url
        nie:title(?song) AS title
        nmm:artistName(nmm:performer(?song)) AS artist
        nie:title(nmm:musicAlbum(?song)) AS album
        nfo:duration(?song) AS duration
        IF(bound(?tag), 'truth!', '') AS lyrics
    WHERE {
        ?playlist a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        ?entry a nfo:MediaFileListEntry ;
            nfo:entryUrl ?url .
        ?song a nmm:MusicPiece ;
             a nfo:FileDataObject ;
             nie:url ?url .
        OPTIONAL {
            ?song nao:hasTag ?tag .
            FILTER( ?tag = nao:predefined-tag-favorite )
        }
        FILTER (
            %(filter_clause)s
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    ORDER BY
         nfo:listPosition(?entry)
    '''.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id,
            'filter_clause': filter_clause
            or 'tracker:id(?playlist) = ' + playlist_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }

        return query

    @staticmethod
    def get_album_for_album_id(album_id):
        query = """
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
    WHERE {
        ?album a nmm:MusicAlbum  .
        FILTER (
            tracker:id(?album) = %(album_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'album_id': album_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }
        return query

    @staticmethod
    def get_album_for_song_id(song_id):
        query = """
    SELECT DISTINCT
        rdf:type(?album)
        tracker:id(?album) AS id
        (
            SELECT
                nmm:artistName(?artist)
            WHERE {
                ?album nmm:albumArtist ?artist
            }
            LIMIT 1
        ) AS artist
        nie:title(?album) AS title
        nie:title(?album) AS album
    WHERE {
        ?song a nmm:MusicPiece ;
              nmm:musicAlbum ?album .
        FILTER (
            tracker:id(?song) = %(song_id)s
        )
        FILTER (
            tracker:uri-is-descendant(
                '%(music_dir)s', nie:url(?song)
            ) ||
            tracker:uri-is-descendant(
                '%(download_dir)s', nie:url(?song)
            )
        )
        FILTER (
            NOT EXISTS {
                ?song a nmm:Video
            } &&
            NOT EXISTS {
                ?song a nmm:Playlist
            }
        )
    }
    """.replace("\n", " ").strip() % {
            'song_id': song_id,
            'music_dir': Query.MUSIC_URI,
            'download_dir': Query.DOWNLOAD_URI
        }
        return query

    @staticmethod
    def update_playcount(song_url):
        query = """
    INSERT OR REPLACE { ?song nie:usageCounter ?playcount . }
    WHERE {
        SELECT
            IF(bound(?usage), (?usage + 1), 1) AS playcount
            ?song
            WHERE {
                ?song a nmm:MusicPiece .
                OPTIONAL { ?song nie:usageCounter ?usage . }
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        }
    """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query

    @staticmethod
    def update_last_played(song_url, time):
        query = """
    INSERT OR REPLACE { ?song nfo:fileLastAccessed '%(time)s' . }
    WHERE {
        SELECT
            ?song
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        }
    """.replace("\n", " ").strip() % {
            'song_url': song_url,
            'time': time
        }

        return query

    @staticmethod
    def create_playlist(title):
        query = """
    INSERT {
        _:playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nie:title "%(title)s" ;
            nfo:entryCounter 0 .
    }
    """.replace("\n", " ").strip() % {
            'title': title
        }
        return query

    @staticmethod
    def create_tag(tag_text):
        query = """
    INSERT OR REPLACE {
        _:tag
            a nao:Tag ;
            rdfs:comment '%(tag_text)s'.
    }
    """.replace("\n", " ").strip() % {
            'tag_text': tag_text
        }
        return query

    @staticmethod
    def create_playlist_with_tag(title, tag_text):
        # TODO: make this an extension of 'create playlist' rather than its own func.?
        # TODO: CREATE TAG IF IT DOESN'T EXIST!
        query = """
    INSERT {
        _:playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nie:title "%(title)s" ;
            nfo:entryCounter 0 ;
            nao:hasTag ?tag.
    }
    WHERE {
        SELECT ?tag
        WHERE {
            ?tag a nao:Tag ;
                rdfs:comment '%(tag_text)s'.
        }
    }
    """.replace("\n", " ").strip() % {
            'title': title,
            'tag_text': tag_text
        }
        return query

    @staticmethod
    def delete_playlist(playlist_id):
        query = """
    DELETE {
        ?playlist
            a rdfs:Resource .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList .
        OPTIONAL {
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
        }
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id
        }
        return query

    @staticmethod
    def add_song_to_playlist(playlist_id, song_uri):
        query = """
    INSERT OR REPLACE {
        _:entry
            a nfo:MediaFileListEntry ;
            nfo:entryUrl "%(song_uri)s" ;
            nfo:listPosition ?position .
        ?playlist
            nfo:entryCounter ?position ;
            nfo:hasMediaFileListEntry _:entry .
    }
    WHERE {
        SELECT
            ?playlist
            (?counter + 1) AS position
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:entryCounter ?counter .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id,
            'song_uri': song_uri
        }
        return query

    @staticmethod
    def remove_song_from_playlist(playlist_id, song_id):
        query = """
    INSERT OR REPLACE {
        ?entry
            nfo:listPosition ?position .
    }
    WHERE {
        SELECT
            ?entry
            (?old_position - 1) AS position
        WHERE {
            ?entry
                a nfo:MediaFileListEntry ;
                nfo:listPosition ?old_position .
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
            FILTER (?old_position > ?removed_position)
            {
                SELECT
                    ?playlist
                    ?removed_position
                WHERE {
                    ?playlist
                        a nmm:Playlist ;
                        a nfo:MediaList ;
                        nfo:hasMediaFileListEntry ?removed_entry .
                    ?removed_entry
                        nfo:listPosition ?removed_position .
                    FILTER (
                        tracker:id(?playlist) = %(playlist_id)s &&
                        tracker:id(?removed_entry) = %(song_id)s
                    )
                }
            }
        }
    }
    INSERT OR REPLACE {
        ?playlist
            nfo:entryCounter ?new_counter .
    }
    WHERE {
        SELECT
            ?playlist
            (?counter - 1) AS new_counter
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:entryCounter ?counter .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
    }
    DELETE {
        ?playlist
            nfo:hasMediaFileListEntry ?entry .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s &&
            tracker:id(?entry) = %(song_id)s
        )
    }
    """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id,
            'song_id': song_id
        }
        return query

    @staticmethod
    def get_playlist_with_id(playlist_id):
        query = """
    ?playlist a nmm:Playlist .
    FILTER (
        tracker:id(?playlist) = %(playlist_id)s
    )
    """.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id
        }

        return Query.playlists(query)

    @staticmethod
    def get_playlist_with_tag(playlist_tag):
        query = """
    ?playlist
        a nmm:Playlist ;
        nao:hasTag ?tag .
    ?tag rdfs:comment ?tag_text .
    FILTER ( ?tag_text = '%(playlist_tag)s' )
    """.replace('\n', ' ').strip() % {
            'playlist_tag': playlist_tag
        }

        return Query.playlists(query)

    @staticmethod
    def get_playlist_with_urn(playlist_urn):
        query = """
    SELECT DISTINCT
        tracker:id(<%(playlist_urn)s>) AS id
    WHERE {
        <%(playlist_urn)s> a nmm:Playlist
    }
    """.replace('\n', ' ').strip() % {
            'playlist_urn': playlist_urn
        }
        return query

    @staticmethod
    def get_playlist_song_with_id(playlist_id, entry_id):
        return Query.playlist_songs(playlist_id,
                                    'tracker:id(?entry) = ' + str(entry_id))

    @staticmethod
    def get_playlist_song_with_urn(entry_urn):
        query = """
    SELECT DISTINCT
        tracker:id(<%(entry_urn)s>) AS id
    WHERE {
        <%(entry_urn)s> a nfo:MediaFileListEntry
    }
    """.replace('\n', ' ').strip() % {
            'entry_urn': entry_urn
        }
        return query

    @staticmethod
    def clear_playlist_with_id(playlist_id):
        query = """
        DELETE {
            ?playlist
                nfo:hasMediaFileListEntry ?entry .
            ?entry
                a rdfs:Resource .
        }
        WHERE {
            ?playlist
                a nmm:Playlist ;
                a nfo:MediaList ;
                nfo:hasMediaFileListEntry ?entry .
            FILTER (
                tracker:id(?playlist) = %(playlist_id)s
            )
        }
        """.replace('\n', ' ').strip() % {
            'playlist_id': playlist_id
        }

        return query

    @staticmethod
    def get_most_played_songs():
        # TODO: set playlist size somewhere? Currently default is 50.
        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:usageCounter ?count ;
                nie:isStoredAs ?as .
          ?as nie:url ?url .
        } ORDER BY DESC(?count) LIMIT 50
        """.replace('\n', ' ').strip()

        return query

    @staticmethod
    def get_never_played_songs():
        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:isStoredAs ?as .
            ?as nie:url ?url .
            FILTER ( NOT EXISTS { ?song nie:usageCounter ?count .} )
        } ORDER BY nfo:fileLastAccessed(?song)
        """.replace('\n', ' ').strip()

        return query

    def get_recently_played_songs():
        #TODO: or this could take comparison date as an argument so we don't need to make a date string in query.py...
        #TODO: set time interval somewhere? A settings file? (Default is maybe 2 weeks...?)

        days_difference = 7  # currently hardcoding time interval of 7 days
        seconds_difference = days_difference * SECONDS_PER_DAY
        compare_date = time.strftime(
            sparql_midnight_dateTime_format,
            time.gmtime(time.time() - seconds_difference))

        query = """
            SELECT ?url
            WHERE {
                ?song a nmm:MusicPiece ;
                    nie:isStoredAs ?as ;
                    nfo:fileLastAccessed ?last_played .
                ?as nie:url ?url .
                FILTER ( ?last_played > '%(compare_date)s'^^xsd:dateTime )
                FILTER ( EXISTS { ?song nie:usageCounter ?count .} )
            } ORDER BY DESC(?last_played)
            """.replace('\n', ' ').strip() % {
            'compare_date': compare_date
        }

        return query

    def get_recently_added_songs():
        #TODO: or this could take comparison date as an argument so we don't need to make a date string in query.py...
        #TODO: set time interval somewhere? A settings file? (Default is maybe 2 weeks...?)

        days_difference = 7  # currently hardcoding time interval of 7 days
        seconds_difference = days_difference * SECONDS_PER_DAY
        compare_date = time.strftime(
            sparql_midnight_dateTime_format,
            time.gmtime(time.time() - seconds_difference))

        query = """
        SELECT ?url
        WHERE {
            ?song a nmm:MusicPiece ;
                nie:isStoredAs ?as ;
                tracker:added ?added .
            ?as nie:url ?url .
            FILTER ( ?added > '%(compare_date)s'^^xsd:dateTime )
        } ORDER BY DESC(?added)
        """.replace('\n', ' ').strip() % {
            'compare_date': compare_date
        }

        return query

    def get_favorite_songs():
        query = """
    SELECT ?url
    WHERE {
        ?song a nmm:MusicPiece ;
            nie:isStoredAs ?as ;
            nao:hasTag nao:predefined-tag-favorite .
        ?as nie:url ?url .
    } ORDER BY DESC(tracker:added(?song))
    """.replace('\n', ' ').strip()

        return query

    # Functions for search
    # TODO: make those queries actually return something
    @staticmethod
    def get_albums_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum ;
                        nmm:albumArtist ?artist .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(?artist)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_albums_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.albums(query)

    @staticmethod
    def get_artists_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum ;
                        nmm:albumArtist ?artist .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(?artist)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?album
                WHERE {
                    ?album a nmm:MusicAlbum .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?album)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_artists_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    nmm:musicAlbum(?song) AS album
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.artists(query)

    @staticmethod
    def get_songs_with_any_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s") ||
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s") ||
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_artist_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nmm:artistName(nmm:performer(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_album_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(nmm:musicAlbum(?song))), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def get_songs_with_track_match(name):
        name = Tracker.sparql_escape_string(GLib.utf8_casefold(name, -1))
        query = '''
            {
                SELECT DISTINCT
                    ?song
                WHERE {
                    ?song a nmm:MusicPiece .
                    FILTER (
                        fn:contains(tracker:case-fold(nie:title(?song)), "%(name)s")
                    )
                }
            }
            '''.replace('\n', ' ').strip() % {
            'name': name
        }

        return Query.songs(query)

    @staticmethod
    def clear_playlist(playlist_id):
        # TODO is there a way to do this with only one FILTER statement?

        query = """
    DELETE {
        ?playlist
            nfo:hasMediaFileListEntry ?entry .
        ?entry
            a rdfs:Resource .
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList ;
            nfo:hasMediaFileListEntry ?entry .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
    INSERT OR REPLACE {
        ?playlist nfo:entryCounter '0'
    }
    WHERE {
        ?playlist
            a nmm:Playlist ;
            a nfo:MediaList .
        FILTER (
            tracker:id(?playlist) = %(playlist_id)s
        )
    }
        """.replace("\n", " ").strip() % {
            'playlist_id': playlist_id
        }

        return query

    def add_favorite(song_url):
        query = """
            INSERT {
                ?song nao:hasTag nao:predefined-tag-favorite
            }
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query

    def remove_favorite(song_url):
        query = """
            DELETE {
                ?song nao:hasTag nao:predefined-tag-favorite
            }
            WHERE {
                ?song a nmm:MusicPiece .
                FILTER ( nie:url(?song) = "%(song_url)s" )
            }
        """.replace("\n", " ").strip() % {
            'song_url': song_url
        }

        return query
Beispiel #43
0
import subprocess
import sys
import termios
import traceback

from datetime import datetime
from gi.types import GObjectMeta

gi.require_version("Gtk", "3.0")
gi.require_version('Notify', '0.7')

from gi.repository import GObject, GLib, Gtk, Gio, Notify

BOLD = lambda x: "\033[1m" + x + "\033[0m"

SHARED_PATH = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
if SHARED_PATH is None or not os.path.exists(SHARED_PATH):
    SHARED_PATH = os.path.expanduser("~")

# i18n
gettext.install("blueberry", "/usr/share/locale")

setproctitle.setproctitle("blueberry-obex-agent")

Notify.init("Blueberry")

try:
    in_fg = os.getpgrp() == struct.unpack(
        str('h'), fcntl.ioctl(0, termios.TIOCGPGRP, "  "))[0]
except IOError:
    in_fg = 'DEBUG' in os.environ
Beispiel #44
0
class Application(object):
    """Main application singleton.

    This class serves as a global container for everything that needs
    to be shared in the GUI. Its constructor is the last part of the
    initialization, called by main.py or by the testing scripts.

    Access via `gui.application.get_app()`.

    """

    #: Singleton instance
    _INSTANCE = None

    def __init__(self,
                 filenames,
                 app_datapath,
                 app_extradatapath,
                 user_datapath,
                 user_confpath,
                 version,
                 fullscreen=False):
        """Construct, but do not run.

        :params filenames: The list of files to load.
          Note: only the first is used.
        :param app_datapath: App-specific read-only data area.
          Path used for UI definition XML, and the default sets of backgrounds,
          palettes, and brush defintions. Often $PREFIX/share/.
        :param app_extradatapath: Extra search path for themeable UI icons.
          This will be used in addition to $XDG_DATA_DIRS for the purposes of
          icon lookup. Normally it's $PREFIX/share, to support unusual
          installations outside the usual locations. It should contain an
          icons/ subdirectory.
        :param user_datapath: Location of the user's app-specific data.
          For MyPaint, this means the user's brushes, backgrounds, and
          scratchpads. Commonly $XDG_DATA_HOME/mypaint, i.e.
          ~/.local/share/mypaint
        :param user_confpath: Location of the user's app-specific config area.
          This is where MyPaint will save user preferences data and the
          keyboard accelerator map. Commonly $XDG_CONFIG_HOME/mypaint, i.e.
          ~/.config/mypaint
        :param version: Version string for the about dialog.
        :param fullscreen: Go fullscreen after starting.

        """
        assert Application._INSTANCE is None
        super(Application, self).__init__()
        Application._INSTANCE = self

        self.user_confpath = user_confpath  #: User configs (see __init__)
        self.user_datapath = user_datapath  #: User data (see __init__)

        self.datapath = app_datapath

        self.version = version  #: version string for the app.

        # create config directory, and subdirs where the user might drop files
        for basedir in [self.user_confpath, self.user_datapath]:
            if not os.path.isdir(basedir):
                os.mkdir(basedir)
                logger.info('Created basedir %r', basedir)
        for datasubdir in ['backgrounds', 'brushes', 'scratchpads']:
            datadir = os.path.join(self.user_datapath, datasubdir)
            if not os.path.isdir(datadir):
                os.mkdir(datadir)
                logger.info('Created data subdir %r', datadir)

        _init_icons(join(app_extradatapath, "icons"))

        # Core actions and menu structure
        resources_xml = join(self.datapath, "gui", "resources.xml")
        self.builder = Gtk.Builder()
        self.builder.set_translation_domain("mypaint")
        self.builder.add_from_file(resources_xml)

        self.ui_manager = self.builder.get_object("app_ui_manager")
        signal_callback_objs = [self]

        Gdk.set_program_class('MyPaint')

        self.pixmaps = PixbufDirectory(join(self.datapath, 'pixmaps'))
        self.cursor_color_picker = Gdk.Cursor.new_from_pixbuf(
            Gdk.Display.get_default(), self.pixmaps.cursor_color_picker, 1, 30)
        self.cursors = gui.cursor.CustomCursorMaker(self)

        # unmanaged main brush; always the same instance (we can attach settings_observers)
        # this brush is where temporary changes (color, size...) happen
        self.brush = brush.BrushInfo()
        self.brush.load_defaults()

        # Global pressure mapping function, ignored unless set
        self.pressure_mapping = None

        self.preferences = {}
        self.load_settings()

        # Keyboard manager
        self.kbm = keyboard.KeyboardManager(self)

        # File I/O
        self.filehandler = filehandling.FileHandler(self)

        # Load the main interface
        mypaint_main_xml = join(self.datapath, "gui", "mypaint.glade")
        self.builder.add_from_file(mypaint_main_xml)

        # Main drawing window
        self.drawWindow = self.builder.get_object("drawwindow")
        signal_callback_objs.append(self.drawWindow)

        # Workspace widget. Manages layout of toolwindows, and autohide in
        # fullscreen.
        workspace = self.builder.get_object("app_workspace")
        workspace.build_from_layout(self.preferences["workspace.layout"])
        workspace.floating_window_created += self._floating_window_created_cb
        fs_autohide_action = self.builder.get_object("FullscreenAutohide")
        fs_autohide_action.set_active(workspace.autohide_enabled)
        self.workspace = workspace

        # Working document: viewer widget
        app_canvas = self.builder.get_object("app_canvas")

        # Working document: model and controller
        model = lib.document.Document(self.brush)
        self.doc = document.Document(self, app_canvas, model)
        app_canvas.set_model(model)

        signal_callback_objs.append(self.doc)
        signal_callback_objs.append(self.doc.modes)

        self.scratchpad_filename = ""
        scratchpad_model = lib.document.Document(self.brush,
                                                 painting_only=True)
        scratchpad_tdw = tileddrawwidget.TiledDrawWidget()
        scratchpad_tdw.set_model(scratchpad_model)
        self.scratchpad_doc = document.Document(self,
                                                scratchpad_tdw,
                                                scratchpad_model,
                                                leader=self.doc)
        self.brushmanager = brushmanager.BrushManager(
            join(app_datapath, 'brushes'), join(user_datapath, 'brushes'),
            self)
        signal_callback_objs.append(self.filehandler)
        self.brushmodifier = brushmodifier.BrushModifier(self)
        signal_callback_objs.append(self.brushmodifier)
        self.line_mode_settings = linemode.LineModeSettings(self)

        # Button press mapping
        self.button_mapping = ButtonMapping()

        # Monitors pluggings and uses of input device, configures them,
        # and switches between device-specific brushes.
        self.device_monitor = gui.device.Monitor(self)

        if not self.preferences.get("scratchpad.last_opened_scratchpad", None):
            self.preferences[
                "scratchpad.last_opened_scratchpad"] = self.filehandler.get_scratchpad_autosave(
                )
        self.scratchpad_filename = self.preferences[
            "scratchpad.last_opened_scratchpad"]

        self.brush_color_manager = BrushColorManager(self)
        self.brush_color_manager.set_picker_cursor(self.cursor_color_picker)
        self.brush_color_manager.set_data_path(self.datapath)

        #: Mapping of setting cname to a GtkAdjustment which controls the base
        #: value of that setting for the app's current brush.
        self.brush_adjustment = {}
        self.init_brush_adjustments()

        # Connect signals defined in mypaint.xml
        callback_finder = CallbackFinder(signal_callback_objs)
        self.builder.connect_signals(callback_finder)

        self.kbm.start_listening()
        self.filehandler.doc = self.doc
        self.filehandler.filename = None
        Gtk.AccelMap.load(join(self.user_confpath, 'accelmap.conf'))

        # Load the default background image if one exists
        layer_stack = self.doc.model.layer_stack
        inited_background = False
        for datapath in [self.user_datapath, self.datapath]:
            bg_path = join(datapath, backgroundwindow.BACKGROUNDS_SUBDIR,
                           backgroundwindow.DEFAULT_BACKGROUND)
            if not os.path.exists(bg_path):
                continue
            bg, errors = backgroundwindow.load_background(bg_path)
            if bg:
                layer_stack.set_background(bg, make_default=True)
                inited_background = True
                logger.info("Initialized background from %r", bg_path)
                break
            else:
                logger.warning(
                    "Failed to load user's default background image %r",
                    bg_path,
                )
                if errors:
                    for error in errors:
                        logger.warning("warning: %r", error)

        # Otherwise, try to use a sensible fallback background image.
        if not inited_background:
            bg_path = join(self.datapath, backgroundwindow.BACKGROUNDS_SUBDIR,
                           backgroundwindow.FALLBACK_BACKGROUND)
            bg, errors = backgroundwindow.load_background(bg_path)
            if bg:
                layer_stack.set_background(bg, make_default=True)
                inited_background = True
                logger.info("Initialized background from %r", bg_path)
            else:
                logger.warning(
                    "Failed to load fallback background image %r",
                    bg_path,
                )
                if errors:
                    for error in errors:
                        logger.warning("warning: %r", error)

        # Double fallback. Just use a color.
        if not inited_background:
            bg_color = (0xa8, 0xa4, 0x98)
            layer_stack.set_background(bg_color, make_default=True)
            logger.info("Initialized background to %r", bg_color)
            inited_background = True

        # Non-dockable subwindows
        # Loading is deferred as late as possible
        self._subwindow_classes = {
            # action-name: action-class
            "BackgroundWindow": backgroundwindow.BackgroundWindow,
            "BrushEditorWindow": brusheditor.BrushEditorWindow,
            "PreferencesWindow": preferenceswindow.PreferencesWindow,
            "InputTestWindow": inputtestwindow.InputTestWindow,
            "BrushIconEditorWindow": brushiconeditor.BrushIconEditorWindow,
        }
        self._subwindows = {}

        # Statusbar init
        statusbar = self.builder.get_object("app_statusbar")
        self.statusbar = statusbar
        context_id = statusbar.get_context_id("transient-message")
        self._transient_msg_context_id = context_id
        self._transient_msg_remove_timeout_id = None

        # Show main UI.
        self.drawWindow.show_all()
        GObject.idle_add(self._at_application_start, filenames, fullscreen)

    def _at_application_start(self, filenames, fullscreen):
        col = self.brush_color_manager.get_color()
        self.brushmanager.select_initial_brush()
        self.brush_color_manager.set_color(col)
        if filenames:
            # Open only the first file, no matter how many has been specified
            # If the file does not exist just set it as the file to save to
            fn = filenames[0]
            if not os.path.exists(fn):
                self.filehandler.filename = fn
            else:
                self.filehandler.open_file(fn)

        # Load last scratchpad
        sp_autosave_key = "scratchpad.last_opened_scratchpad"
        autosave_name = self.preferences[sp_autosave_key]
        if not autosave_name:
            autosave_name = self.filehandler.get_scratchpad_autosave()
            self.preferences[sp_autosave_key] = autosave_name
            self.scratchpad_filename = autosave_name
        if os.path.isfile(autosave_name):
            try:
                self.filehandler.open_scratchpad(autosave_name)
            except AttributeError:
                pass

        self.apply_settings()
        self.drawWindow.present()

        # Handle fullscreen command line option
        if fullscreen:
            self.drawWindow.fullscreen_cb()

        if not filenames:
            autosave_recovery = gui.autorecover.Presenter(self)
            autosave_recovery.run()

    def save_settings(self):
        """Saves the current settings to persistent storage."""
        self.brushmanager.save_brushes_for_devices()
        self.brushmanager.save_brush_history()
        self.filehandler.save_scratchpad(self.scratchpad_filename)
        settingspath = join(self.user_confpath, 'settings.json')
        jsonstr = helpers.json_dumps(self.preferences)
        f = open(settingspath, 'w')
        f.write(jsonstr)
        f.close()

    def apply_settings(self):
        """Applies the current settings.

        Called at startup and from the prefs dialog.
        """
        self._apply_pressure_mapping_settings()
        self._apply_button_mapping_settings()
        self._apply_autosave_settings()
        self.preferences_window.update_ui()

    def load_settings(self):
        """Loads the settings from persistent storage.

        Uses defaults if not explicitly configured.

        """
        def get_json_config():
            settingspath = join(self.user_confpath, 'settings.json')
            jsonstr = open(settingspath).read()
            try:
                return helpers.json_loads(jsonstr)
            except Exception, e:
                logger.warning("settings.json: %s", str(e))
                logger.warning("Failed to load settings: using defaults")
                return {}

        if sys.platform == 'win32':
            scrappre = os.path.join(
                GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS),
                'MyPaint', 'scrap')
            if not isinstance(scrappre, unicode):
                scrappre = scrappre.decode(sys.getfilesystemencoding())
        else:
            scrappre = u'~/MyPaint/scrap'
        DEFAULT_CONFIG = {
            'saving.scrap_prefix':
            scrappre,
            'input.device_mode':
            'screen',
            'input.global_pressure_mapping': [(0.0, 1.0), (1.0, 0.0)],
            'view.default_zoom':
            1.0,
            'view.high_quality_zoom':
            True,
            'view.real_alpha_checks':
            True,
            'ui.hide_menubar_in_fullscreen':
            True,
            'ui.hide_toolbar_in_fullscreen':
            True,
            'ui.hide_subwindows_in_fullscreen':
            True,
            'ui.parts':
            dict(main_toolbar=True, menubar=True),
            'ui.feedback.scale':
            False,
            'ui.feedback.last_pos':
            False,
            'ui.toolbar_items':
            dict(
                toolbar1_file=True,
                toolbar1_scrap=False,
                toolbar1_edit=True,
                toolbar1_blendmodes=False,
                toolbar1_linemodes=True,
                toolbar1_view_modes=True,
                toolbar1_view_manips=False,
                toolbar1_view_resets=True,
            ),
            'ui.toolbar_icon_size':
            'large',
            'ui.dark_theme_variant':
            True,
            'saving.default_format':
            'openraster',
            'brushmanager.selected_brush':
            None,
            'brushmanager.selected_groups': [],
            'frame.color_rgba': (0.12, 0.12, 0.12, 0.92),
            'misc.context_restores_color':
            True,
            'document.autosave_backups':
            True,
            'document.autosave_interval':
            10,
            'display.colorspace':
            "srgb",
            # sRGB is a good default even for OS X since v10.6 / Snow
            # Leopard: http://support.apple.com/en-us/HT3712.
            # Version 10.6 was released in September 2009.
            "scratchpad.last_opened_scratchpad":
            "",

            # Initial main window positions
            "workspace.layout": {
                "position": dict(x=50, y=32, w=-50, h=-100),
                "autohide": True,
            },

            # Linux defaults.
            # Alt is the normal window resizing/moving key these days,
            # so provide a Ctrl-based equivalent for all alt actions.
            'input.button_mapping': {
                # Note that space is treated as a fake Button2
                '<Shift>Button1': 'StraightMode',
                '<Control>Button1': 'ColorPickMode',
                '<Alt>Button1': 'ColorPickMode',
                'Button2': 'PanViewMode',
                '<Shift>Button2': 'RotateViewMode',
                '<Control>Button2': 'ZoomViewMode',
                '<Alt>Button2': 'ZoomViewMode',
                '<Control><Shift>Button2': 'FrameEditMode',
                '<Alt><Shift>Button2': 'FrameEditMode',
                'Button3': 'ShowPopupMenu',
            },
        }
        if sys.platform == 'win32':
            # The Linux wacom driver inverts the button numbers of the
            # pen flip button, because middle-click is the more useful
            # action on Linux. However one of the two buttons is often
            # accidentally hit with the thumb while painting. We want
            # to assign panning to this button by default.
            linux_mapping = DEFAULT_CONFIG["input.button_mapping"]
            DEFAULT_CONFIG["input.button_mapping"] = {}
            for bp, actname in linux_mapping.iteritems():
                bp = bp.replace("Button2", "ButtonTMP")
                bp = bp.replace("Button3", "Button2")
                bp = bp.replace("ButtonTMP", "Button3")
                DEFAULT_CONFIG["input.button_mapping"][bp] = actname

        self.preferences = DEFAULT_CONFIG.copy()
        try:
            user_config = get_json_config()
        except IOError:
            user_config = {}
        self.preferences.update(user_config)
        if 'ColorPickerPopup' in self.preferences[
                "input.button_mapping"].values():
            # old config file; users who never assigned any buttons would
            # end up with Ctrl-Click color picker broken after upgrade
            self.preferences["input.button_mapping"] = DEFAULT_CONFIG[
                "input.button_mapping"]
Beispiel #45
0
 def get_special_dir(opt):
     if opt.startswith("USER_"):
         _, opt = opt.split("USER_", 1)
         if opt in specialdirs:
             return GLib.get_user_special_dir(specialdirs[opt])
Beispiel #46
0
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

import time
import sys
import os
from subprocess import run
from urllib.parse import urljoin

file_name = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES)
file_name = os.path.join(file_name,
                         time.strftime('screenshot_%Y-%m-%d-%H%M%S_grim.png'))

if len(sys.argv) < 2:
    run(["grim", file_name], check=True)
else:
    if sys.argv[1] in ('-h', '--help'):
        print("Usage: {} [-h|--help|--region|--window]".format(sys.argv[0]))
        sys.exit(0)
    elif sys.argv[1] == '--region':
        region = run('slurp', check=True, capture_output=True)
        run(["grim", '-g', '-', file_name], check=True, input=region.stdout)
    elif sys.argv[1] == '--window':
        tree = run(['swaymsg', '-t', 'get_tree'],
                   check=True,
                   capture_output=True)
        regions = run([
            'jq', '-r',
            '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"'
Beispiel #47
0
def get_desktop_dir():
    """ Returns path to desktop dir. """
    return GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
Beispiel #48
0
    def __init__(self):
        """
            Init dialog
        """
        self.__choosers = []
        self.__cover_tid = None
        self.__mix_tid = None
        self.__popover = None

        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Lollypop/SettingsDialog.ui")
        self.__progress = builder.get_object("progress")
        self.__infobar = builder.get_object("infobar")
        self.__reset_button = builder.get_object("reset_button")
        if Lp().lastfm is None or Lp().lastfm.is_goa:
            builder.get_object("lastfm_grid").hide()
        if Lp().scanner.is_locked():
            builder.get_object("reset_button").set_sensitive(False)
        artists = Lp().artists.count()
        albums = Lp().albums.count()
        tracks = Lp().tracks.count()
        builder.get_object("artists").set_text(
            ngettext("%d artist", "%d artists", artists) % artists)
        builder.get_object("albums").set_text(
            ngettext("%d album", "%d albums", albums) % albums)
        builder.get_object("tracks").set_text(
            ngettext("%d track", "%d tracks", tracks) % tracks)

        self.__popover_content = builder.get_object("popover")
        duration = builder.get_object("duration")
        duration.set_range(1, 20)
        duration.set_value(Lp().settings.get_value("mix-duration").get_int32())

        self.__settings_dialog = builder.get_object("settings_dialog")
        self.__settings_dialog.set_transient_for(Lp().window)

        if Lp().settings.get_value("disable-csd"):
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object("header_bar")
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        switch_scan = builder.get_object("switch_scan")
        switch_scan.set_state(Lp().settings.get_value("auto-update"))

        switch_view = builder.get_object("switch_dark")
        if Lp().gtk_application_prefer_dark_theme:
            switch_view.set_sensitive(False)
        else:
            switch_view.set_state(Lp().settings.get_value("dark-ui"))

        switch_background = builder.get_object("switch_background")
        switch_background.set_state(Lp().settings.get_value("background-mode"))

        switch_state = builder.get_object("switch_state")
        switch_state.set_state(Lp().settings.get_value("save-state"))

        switch_mix = builder.get_object("switch_mix")
        switch_mix.set_state(Lp().settings.get_value("mix"))

        self._switch_song_notifications = builder.get_object(
            "switch_song_notifications", )

        self._switch_song_notifications.set_state(
            not Lp().settings.get_value("disable-song-notifications"), )

        self._switch_song_notifications.set_sensitive(
            not Lp().settings.get_value("disable-notifications"), )

        Lp().settings.connect(
            "changed::disable-notifications",
            self._on_notifications_setting_changed,
        )

        self.__helper = TouchHelper(switch_mix, None, None)
        self.__helper.set_long_func(self.__mix_long_func, switch_mix)
        self.__helper.set_short_func(self.__mix_short_func, switch_mix)

        switch_mix_party = builder.get_object("switch_mix_party")
        switch_mix_party.set_state(Lp().settings.get_value("party-mix"))

        switch_librefm = builder.get_object("switch_librefm")
        switch_librefm.set_state(Lp().settings.get_value("use-librefm"))

        switch_artwork_tags = builder.get_object("switch_artwork_tags")
        grid_behaviour = builder.get_object("grid_behaviour")
        # Check portal for kid3-cli
        dbus_helper = DBusHelper()
        dbus_helper.call("CanSetCover", None, self.__on_can_set_cover,
                         (switch_artwork_tags, grid_behaviour))

        if GLib.find_program_in_path("youtube-dl") is None or\
                not Lp().settings.get_value("network-access"):
            builder.get_object("charts_grid").hide()
        else:
            switch_charts = builder.get_object("switch_charts")
            switch_charts.set_state(Lp().settings.get_value("show-charts"))

        switch_genres = builder.get_object("switch_genres")
        switch_genres.set_state(Lp().settings.get_value("show-genres"))

        switch_compilations = builder.get_object("switch_compilations")
        switch_compilations.set_state(
            Lp().settings.get_value("show-compilations"))

        switch_artwork = builder.get_object("switch_artwork")
        switch_artwork.set_state(Lp().settings.get_value("artist-artwork"))

        switch_spotify = builder.get_object("switch_spotify")
        switch_spotify.set_state(Lp().settings.get_value("search-spotify"))

        switch_itunes = builder.get_object("switch_itunes")
        switch_itunes.set_state(Lp().settings.get_value("search-itunes"))

        if GLib.find_program_in_path("youtube-dl") is None:
            builder.get_object("yt-dl").show()

        combo_orderby = builder.get_object("combo_orderby")
        combo_orderby.set_active(Lp().settings.get_enum(("orderby")))

        combo_preview = builder.get_object("combo_preview")

        scale_coversize = builder.get_object("scale_coversize")
        scale_coversize.set_range(150, 300)
        scale_coversize.set_value(
            Lp().settings.get_value("cover-size").get_int32())
        self.__settings_dialog.connect("destroy", self.__edit_settings_close)

        builder.connect_signals(self)

        main_chooser_box = builder.get_object("main_chooser_box")
        self.__chooser_box = builder.get_object("chooser_box")

        self.__set_outputs(combo_preview)

        #
        # Music tab
        #
        dirs = []
        for directory in Lp().settings.get_value("music-uris"):
            dirs.append(directory)

        # Main chooser
        self.__main_chooser = ChooserWidget()
        image = Gtk.Image.new_from_icon_name("list-add-symbolic",
                                             Gtk.IconSize.MENU)
        self.__main_chooser.set_icon(image)
        self.__main_chooser.set_action(self.__add_chooser)
        main_chooser_box.pack_start(self.__main_chooser, False, True, 0)
        if len(dirs) > 0:
            uri = dirs.pop(0)
        else:
            filename = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
            if filename:
                uri = GLib.filename_to_uri(filename)
            else:
                uri = ""

        self.__main_chooser.set_dir(uri)

        # Others choosers
        for directory in dirs:
            self.__add_chooser(directory)

        #
        # Google tab
        #
        key = Lp().settings.get_value("cs-api-key").get_string() or\
            Lp().settings.get_default_value("cs-api-key").get_string()
        builder.get_object("cs-entry").set_text(key)
        #
        # Last.fm tab
        #
        if Lp().lastfm is not None and Secret is not None:
            self.__test_img = builder.get_object("test_img")
            self.__login = builder.get_object("login")
            self.__password = builder.get_object("password")
            schema = Secret.Schema.new("org.gnome.Lollypop",
                                       Secret.SchemaFlags.NONE, SecretSchema)
            Secret.password_lookup(schema, SecretAttributes, None,
                                   self.__on_password_lookup)
            builder.get_object("lastfm_grid").set_sensitive(True)
            builder.get_object("lastfm_error").hide()
            self.__login.set_text(
                Lp().settings.get_value("lastfm-login").get_string())
Beispiel #49
0
    def __init__(self):
        """
            Init dialog
        """
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Eolie/SettingsDialog.ui')
        builder.connect_signals(self)

        self.__settings_dialog = builder.get_object('settings_dialog')
        self.__settings_dialog.set_transient_for(El().active_window)
        # self.__settings_dialog.connect('destroy', self.__on_destroy)

        if False:
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object('header_bar')
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        download_chooser = builder.get_object('download_chooser')
        dir_uri = El().settings.get_value('download-uri').get_string()
        if not dir_uri:
            directory = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            dir_uri = GLib.filename_to_uri(directory, None)
        download_chooser.set_uri(dir_uri)

        autostart_downloads = builder.get_object('auto_download_check')
        autostart_downloads.set_active(
            El().settings.get_value('autostart-downloads'))

        combo_engine = builder.get_object('combo_engine')
        combo_engine.set_active_id(
            El().settings.get_value('search-engine').get_string())

        remember_session = builder.get_object('remember_session_check')
        remember_session.set_active(
            El().settings.get_value('remember-session'))

        enable_plugins = builder.get_object('plugins_check')
        enable_plugins.set_active(El().settings.get_value('enable-plugins'))

        self.__fonts_grid = builder.get_object('fonts_grid')
        use_system_fonts = builder.get_object('system_fonts_check')
        use_system_fonts.set_active(
            El().settings.get_value('use-system-fonts'))

        sans_serif_button = builder.get_object('sans_serif_button')
        sans_serif_button.set_font_name(
            El().settings.get_value('font-sans-serif').get_string())
        serif_button = builder.get_object('serif_button')
        serif_button.set_font_name(
            El().settings.get_value('font-serif').get_string())
        monospace_button = builder.get_object('monospace_button')
        monospace_button.set_font_name(
            El().settings.get_value('font-monospace').get_string())

        min_font_size_spin = builder.get_object('min_font_size_spin')
        min_font_size_spin.set_value(
            El().settings.get_value('min-font-size').get_int32())

        cookies_combo = builder.get_object('cookies_combo')
        storage = El().settings.get_enum('cookie-storage')
        cookies_combo.set_active_id(str(storage))

        tracking_check = builder.get_object('tracking_check')
        tracking_check.set_active(El().settings.get_value('do-not-track'))
Beispiel #50
0
def add_music(entry):
    musics.append(entry.path)
    title = get_title(entry)
    music_label = Gtk.Label(label=title)
    listbox.add(music_label)


def add_music_from(directory):
    for entry in os.scandir(directory):
        if entry.is_dir():
            add_music_from(entry.path)
        elif entry.is_file() and entry.path.endswith('.mp3'):
            add_music(entry)


music_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC)
add_music_from(music_dir)

grid = Gtk.Grid()
grid.set_row_spacing(5)
grid.set_column_spacing(5)
win.add(grid)
grid.attach(scrolledwin, 0, 0, 100, 100)
scrolledwin.add(listbox)
grid.attach(playbutton, 50, 101, 1, 1)
grid.attach(nextbutton, 51, 101, 1, 1)
grid.attach(pervbutton, 49, 101, 1, 1)


def li(listbox, listboxrow):
    global musics, i, c, a, g
Beispiel #51
0
    # Python 2
    from urllib import unquote

# Configuration
confDir = os.path.join(GLib.get_user_config_dir(), 'green-recorder/')
confFile = os.path.join(confDir + "config.ini")
config = ConfigParser()

from timeit import default_timer as timer

recording_time_start = None

if not os.path.exists(confDir):
    os.makedirs(confDir)

VideosFolder = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)
if VideosFolder is None:
    VideosFolder = os.environ['HOME']

if os.path.isfile(confFile):
    config.read(confFile)
if not config.has_section('Options'):
    config.add_section('Options')

# Localization.
locale.setlocale(locale.LC_ALL, '')
extra_locale_dirs = [
    os.path.join(os.getcwd(), "locale"),
]

# this binds system translation
Beispiel #52
0
def special_dirs_icon_filenames():
    """Return a dict of {special_dir_path: special_dir_icon_filename}."""
    return {
        GLib.get_user_special_dir(g_user_dir_id): icon_filename
        for g_user_dir_id, icon_filename in SPECIAL_DIRS.items()
    }
Beispiel #53
0
    def __init__(self):
        """
            Init dialog
        """
        self.__choosers = []
        self.__cover_tid = None
        self.__mix_tid = None
        self.__popover = None

        cs_api_key = Lp().settings.get_value('cs-api-key').get_string()
        default_cs_api_key = Lp().settings.get_default_value(
            'cs-api-key').get_string()
        if (not cs_api_key or
            cs_api_key == default_cs_api_key) and\
                get_network_available() and\
                Lp().notify is not None:
            Lp().notify.send(
                _("Google Web Services need a custom API key"),
                _("Lollypop needs this to search artwork and music."))

        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/SettingsDialog.ui')
        self.__progress = builder.get_object('progress')
        self.__infobar = builder.get_object('infobar')
        self.__reset_button = builder.get_object('reset_button')
        if Lp().lastfm is None or Lp().lastfm.is_goa:
            builder.get_object('lastfm_grid').hide()
        if Lp().scanner.is_locked():
            builder.get_object('reset_button').set_sensitive(False)
        artists = Lp().artists.count()
        albums = Lp().albums.count()
        tracks = Lp().tracks.count()
        builder.get_object('artists').set_text(
            ngettext("%d artist", "%d artists", artists) % artists)
        builder.get_object('albums').set_text(
            ngettext("%d album", "%d albums", albums) % albums)
        builder.get_object('tracks').set_text(
            ngettext("%d track", "%d tracks", tracks) % tracks)

        self.__popover_content = builder.get_object('popover')
        duration = builder.get_object('duration')
        duration.set_range(1, 20)
        duration.set_value(Lp().settings.get_value('mix-duration').get_int32())

        self.__settings_dialog = builder.get_object('settings_dialog')
        self.__settings_dialog.set_transient_for(Lp().window)

        if Lp().settings.get_value('disable-csd'):
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object('header_bar')
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        switch_scan = builder.get_object('switch_scan')
        switch_scan.set_state(Lp().settings.get_value('auto-update'))

        switch_view = builder.get_object('switch_dark')
        switch_view.set_state(Lp().settings.get_value('dark-ui'))

        switch_background = builder.get_object('switch_background')
        switch_background.set_state(Lp().settings.get_value('background-mode'))

        switch_state = builder.get_object('switch_state')
        switch_state.set_state(Lp().settings.get_value('save-state'))

        switch_mix = builder.get_object('switch_mix')
        switch_mix.set_state(Lp().settings.get_value('mix'))
        self.__helper = TouchHelper(switch_mix, None, None)
        self.__helper.set_long_func(self.__mix_long_func, switch_mix)
        self.__helper.set_short_func(self.__mix_short_func, switch_mix)

        switch_mix_party = builder.get_object('switch_mix_party')
        switch_mix_party.set_state(Lp().settings.get_value('party-mix'))

        switch_librefm = builder.get_object('switch_librefm')
        switch_librefm.set_state(Lp().settings.get_value('use-librefm'))

        switch_artwork_tags = builder.get_object('switch_artwork_tags')
        # Check portal for kid3-cli
        can_set_cover = False
        try:
            bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
            proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
                                           'org.gnome.Lollypop.Portal',
                                           '/org/gnome/LollypopPortal',
                                           'org.gnome.Lollypop.Portal', None)
            can_set_cover = proxy.call_sync('CanSetCover', None,
                                            Gio.DBusCallFlags.NO_AUTO_START,
                                            500, None)[0]
        except Exception as e:
            print(
                "You are missing lollypop-portal: "
                "https://github.com/gnumdk/lollypop-portal", e)
        if not can_set_cover:
            grid = builder.get_object('grid_behaviour')
            h = grid.child_get_property(switch_artwork_tags, 'height')
            w = grid.child_get_property(switch_artwork_tags, 'width')
            l = grid.child_get_property(switch_artwork_tags, 'left-attach')
            t = grid.child_get_property(switch_artwork_tags, 'top-attach')
            switch_artwork_tags.destroy()
            label = Gtk.Label.new(_("You need to install kid3-cli"))
            label.get_style_context().add_class('dim-label')
            label.set_property('halign', Gtk.Align.END)
            label.show()
            grid.attach(label, l, t, w, h)
        else:
            switch_artwork_tags.set_state(
                Lp().settings.get_value('save-to-tags'))

        if GLib.find_program_in_path("youtube-dl") is None:
            builder.get_object('charts_grid').hide()
        else:
            switch_charts = builder.get_object('switch_charts')
            switch_charts.set_state(Lp().settings.get_value('show-charts'))

        switch_genres = builder.get_object('switch_genres')
        switch_genres.set_state(Lp().settings.get_value('show-genres'))

        switch_compilations = builder.get_object('switch_compilations')
        switch_compilations.set_state(
            Lp().settings.get_value('show-compilations'))

        switch_artwork = builder.get_object('switch_artwork')
        switch_artwork.set_state(Lp().settings.get_value('artist-artwork'))

        switch_spotify = builder.get_object('switch_spotify')
        switch_spotify.set_state(Lp().settings.get_value('search-spotify'))

        switch_itunes = builder.get_object('switch_itunes')
        switch_itunes.set_state(Lp().settings.get_value('search-itunes'))

        if GLib.find_program_in_path("youtube-dl") is None:
            builder.get_object('yt-dl').show()

        combo_orderby = builder.get_object('combo_orderby')
        combo_orderby.set_active(Lp().settings.get_enum(('orderby')))

        combo_preview = builder.get_object('combo_preview')

        scale_coversize = builder.get_object('scale_coversize')
        scale_coversize.set_range(150, 300)
        scale_coversize.set_value(
            Lp().settings.get_value('cover-size').get_int32())
        self.__settings_dialog.connect('destroy', self.__edit_settings_close)

        builder.connect_signals(self)

        main_chooser_box = builder.get_object('main_chooser_box')
        self.__chooser_box = builder.get_object('chooser_box')

        self.__set_outputs(combo_preview)

        #
        # Music tab
        #
        dirs = []
        for directory in Lp().settings.get_value('music-uris'):
            dirs.append(directory)

        # Main chooser
        self.__main_chooser = ChooserWidget()
        image = Gtk.Image.new_from_icon_name("list-add-symbolic",
                                             Gtk.IconSize.MENU)
        self.__main_chooser.set_icon(image)
        self.__main_chooser.set_action(self.__add_chooser)
        main_chooser_box.pack_start(self.__main_chooser, False, True, 0)
        if len(dirs) > 0:
            uri = dirs.pop(0)
        else:
            filename = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
            if filename:
                uri = GLib.filename_to_uri(filename)
            else:
                uri = ""

        self.__main_chooser.set_dir(uri)

        # Others choosers
        for directory in dirs:
            self.__add_chooser(directory)

        #
        # Google tab
        #
        builder.get_object('cs-entry').set_text(
            Lp().settings.get_value('cs-api-key').get_string())
        #
        # Last.fm tab
        #
        if Lp().lastfm is not None and Secret is not None:
            self.__test_img = builder.get_object('test_img')
            self.__login = builder.get_object('login')
            self.__password = builder.get_object('password')
            schema = Secret.Schema.new("org.gnome.Lollypop",
                                       Secret.SchemaFlags.NONE, SecretSchema)
            Secret.password_lookup(schema, SecretAttributes, None,
                                   self.__on_password_lookup)
            builder.get_object('lastfm_grid').set_sensitive(True)
            builder.get_object('lastfm_error').hide()
            self.__login.set_text(
                Lp().settings.get_value('lastfm-login').get_string())
Beispiel #54
0

ULAUNCHER_FILE_ICON_DB = [
    '3g2', '3gp', 'ai', 'air', 'asf', 'avi', 'bib', 'cls', 'csv', 'deb',
    'djvu', 'dmg', 'doc', 'docx', 'dwf', 'dwg', 'eps', 'epub', 'exe', 'f77',
    'f90', 'f', 'flac', 'flv', 'gif', 'gz', 'ico', 'indd', 'iso', 'jpeg',
    'jpg', 'log', 'm4a', 'm4v', 'midi', 'mkv', 'mov', 'mp3', 'mp4', 'mpeg',
    'mpg', 'msi', 'odp', 'ods', 'odt', 'oga', 'ogg', 'ogv', 'pdf', 'png',
    'pps', 'ppsx', 'ppt', 'pptx', 'psd', 'pub', 'py', 'qt', 'ra', 'ram', 'rar',
    'rm', 'rpm', 'rtf', 'rv', 'skp', 'spx', 'sql', 'sty', 'tar', 'tex', 'tgz',
    'tiff', 'ttf', 'txt', 'vob', 'wav', 'wmv', 'xls', 'xlsx', 'xml', 'xpi',
    'zip'
]

SPECIAL_DIRS = {
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD):
    'folder-download',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOCUMENTS):
    'folder-documents',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC):
    'folder-music',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PICTURES):
    'folder-pictures',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_PUBLIC_SHARE):
    'folder-publicshare',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_TEMPLATES):
    'folder-templates',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS):
    'folder-videos',
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP):
    'user-desktop',
    def embed_albums(self, selected_albums):
        '''
        method to export and embed coverart to chosen albums

        :selected_albums: `Album` - array of albums
        '''

        self._initialise_gstreamer()

        from coverart_search_tracks import CoverArtTracks

        search_tracks = CoverArtTracks()
        playlist_manager = self.shell.props.playlist_manager
        playlists_entries = playlist_manager.get_playlists()

        ui = Gtk.Builder()
        ui.add_from_file(rb.find_plugin_file(self.plugin,
                                             'ui/coverart_exportembed.ui'))
        ui.connect_signals(self)
        embeddialog = ui.get_object('exportembeddialog')
        embeddialog.set_transient_for(self.shell.props.window)
        folderchooserbutton = ui.get_object('folderchooserbutton')
        use_album_name_checkbutton = ui.get_object('use_album_name_checkbutton')
        open_filemanager_checkbutton = ui.get_object('open_filemanager_checkbutton')
        convert_checkbutton = ui.get_object('convert_checkbutton')
        bitrate_spinbutton = ui.get_object('bitrate_spinbutton')
        resize_checkbutton = ui.get_object('resize_checkbutton')
        resize_spinbutton = ui.get_object('resize_spinbutton')

        # predefine values if not previously opened the dialog
        if self.has_opened_previously:
            print (self._values)
            if not self._values['toresize']:
                resize_spinbutton.set_value(128)
            else:
                resize_spinbutton.set_value(self._values['resize'])

            if not self._values['convert']:
                bitrate_spinbutton.set_value(self.TARGET_BITRATE)
            else:
                bitrate_spinbutton.set_value(self._values['bitrate'])

            folderchooserbutton.set_current_folder(self._values['final_folder_store'])
            use_album_name_checkbutton.set_active(self._values['use_album_name'])
            open_filemanager_checkbutton.set_active(self._values['open_filemanager'])
            convert_checkbutton.set_active(self._values['convert'])
            resize_checkbutton.set_active(self._values['toresize'])

        else:
            bitrate_spinbutton.set_value(self.TARGET_BITRATE)
            resize_spinbutton.set_value(128)

            downloads_dir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DOWNLOAD)
            folderchooserbutton.set_current_folder(downloads_dir)

        response = embeddialog.run()

        if response != Gtk.ResponseType.OK:
            embeddialog.destroy()
            return

        self.has_opened_previously = True
        # ok pressed - now fetch values from the dialog
        final_folder_store = folderchooserbutton.get_current_folder()
        use_album_name = use_album_name_checkbutton.get_active()
        open_filemanager = open_filemanager_checkbutton.get_active()
        convert = convert_checkbutton.get_active()
        bitrate = bitrate_spinbutton.get_value()
        toresize = resize_checkbutton.get_active()
        if toresize:
            resize = int(resize_spinbutton.get_value())
        else:
            resize = -1

        self._values['bitrate'] = bitrate
        self._values['resize'] = resize
        self._values['final_folder_store'] = final_folder_store
        self._values['use_album_name'] = use_album_name
        self._values['open_filemanager'] = open_filemanager
        self._values['convert'] = convert
        self._values['toresize'] = toresize

        print (self._values)
        embeddialog.destroy()

        albums = {}
        total = 0

        for album in selected_albums:
            albums[album] = album.get_tracks()
            total = total + len(albums[album])

        self._track_count = 1

        def complete():
            self.album_manager.progress = 1

            if open_filemanager:
                #code taken from http://stackoverflow.com/questions/1795111/is-there-a-cross-platform-way-to-open-a-file-browser-in-python
                if sys.platform == 'win32':
                    import winreg

                    path = r('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon')
                    for root in (winreg.HKEY_CURRENT_USER, winreg.HKEY_LOCAL_MACHINE):
                        try:
                            with winreg.OpenKey(root, path) as k:
                                value, regtype = winreg.QueryValueEx(k, 'Shell')
                        except WindowsError:
                            pass
                        else:
                            if regtype in (winreg.REG_SZ, winreg.REG_EXPAND_SZ):
                                shell = value
                            break
                    else:
                        shell = 'Explorer.exe'
                    subprocess.Popen([shell, final_folder_store])

                elif sys.platform == 'darwin':
                    subprocess.Popen(['open', final_folder_store])

                else:
                    subprocess.Popen(['xdg-open', final_folder_store])

        self._albumiter = iter(albums)
        self._tracknumber = 0
        self._album = next(self._albumiter)

        def idle_call(data):
            exit_idle = True

            track = albums[self._album][self._tracknumber]

            if not process_track(self._album, track):
                exit_idle = False

            self._tracknumber = self._tracknumber + 1

            if self._tracknumber >= len(albums[self._album]):
                try:
                    self._tracknumber = 0
                    self._album = next(self._albumiter)
                except StopIteration:
                    exit_idle = False

            if not exit_idle:
                complete()

            return exit_idle

        def process_track(album, track):
            self.album_manager.progress = self._track_count / total
            self._track_count = self._track_count + 1

            key = album.create_ext_db_key()
            finalPath = rb3compat.unquote(track.location)[7:]
            album_name = RB.search_fold(album.name)

            if use_album_name:
                folder_store = final_folder_store + '/' + album_name
            else:
                folder_store = final_folder_store

            try:
                if not os.path.exists(folder_store):
                    os.makedirs(folder_store)

                if convert:
                    self.convert_to_mp3(finalPath, folder_store, bitrate)
                    finalPath = self._calc_mp3_filename(finalPath, folder_store)
                    print(finalPath)
                else:
                    shutil.copy(finalPath, folder_store)
            except IOError as err:
                print(err.args[0])
                return False

            dest = os.path.join(folder_store, os.path.basename(finalPath))
            desturi = 'file://' + rb3compat.pathname2url(dest)

            return search_tracks.embed(desturi, key, resize)

        data = None

        Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, idle_call, data)
Beispiel #56
0
    def __init__(self, backend, img=None, allow_system_internal=False):

        self.allow_system_internal = allow_system_internal

        self.all_widgets = set()

        self.builder = Gtk.Builder()
        self.builder.set_translation_domain('usbcreator')
        self.builder.add_from_file(ui_path)
        # A cache of the icon names and display names for the individual
        # devices.
        self.icons = {}
        self.names = {}
        self.pretty_names = {}

        for widget in self.builder.get_objects():
            # Taken from ubiquity:
            # We generally want labels to be selectable so that people can
            # easily report problems in them
            # (https://launchpad.net/bugs/41618), but GTK+ likes to put
            # selectable labels in the focus chain, and I can't seem to turn
            # this off in glade and have it stick. Accordingly, make sure
            # labels are unfocusable here.
            if isinstance(widget, Gtk.Label):
                widget.set_property('can-focus', False)
            if issubclass(type(widget), Gtk.Widget):
                self.all_widgets.add(widget)
                widget.set_name(Gtk.Buildable.get_name(widget))
                setattr(self, Gtk.Widget.get_name(widget), widget)

        Gtk.Window.set_default_icon_name('usb-creator-gtk')

        # Connect signals to widgets
        self.builder.connect_signals(self)
        self.cancelbutton.connect('clicked',
                                  lambda x: self.warning_dialog.hide())
        self.finished_exit.connect('clicked',
                                   lambda x: self.finished_dialog.hide())
        self.failed_exit.connect('clicked', lambda x: self.failed_exit.hide())
        self.progress_cancel_button.connect(
            'clicked', lambda x: self.warning_dialog.show())

        # Set warning dialog transient window
        self.warning_dialog.set_transient_for(self.install_window)

        def format_value(scale, value):
            return misc.format_mb_size(value)

        # TODO: remove format button
        self.format_dest.hide()

        # Connect to backend signals.
        self.backend = backend
        self.backend.source_added_cb = self.add_source
        self.backend.target_added_cb = self.add_target
        self.backend.source_removed_cb = self.remove_source
        self.backend.target_removed_cb = self.remove_target
        self.backend.failure_cb = self.failure
        self.backend.success_cb = self.success
        self.backend.install_progress_cb = self.progress
        self.backend.install_progress_message_cb = self.progress_message
        self.backend.install_progress_pulse_cb = self.progress_pulse
        self.backend.install_progress_pulse_stop_cb = self.progress_pulse_stop
        self.backend.retry_cb = self.retry
        self.backend.target_changed_cb = self.update_target

        # Pulse state.
        self.pulsing = False

        # we currently do not have help
        self.button_help.hide()
        #self.button_help.connect('clicked', lambda x: Gtk.show_uri(self.button_help.get_screen(),
        #                                                           'ghelp:usb-creator',
        #                                                           Gtk.get_current_event_time()))

        self.setup_sources_treeview()
        self.setup_targets_treeview()

        # Pre-populate the source view.
        if img is not None:
            self.backend.add_image(img)
            self.source_vbox.hide()

        for search_dir_id in [
                GLib.UserDirectory.DIRECTORY_DOWNLOAD,
                GLib.UserDirectory.DIRECTORY_DESKTOP
        ]:
            search_dir = GLib.get_user_special_dir(search_dir_id)
            if search_dir and os.path.isdir(search_dir):
                # TODO evand 2009-10-22: File type detection based on file(1).
                for fname in os.listdir(search_dir):
                    if fname.endswith('.iso') or fname.endswith('.img'):
                        self.backend.add_image(os.path.join(search_dir, fname))

        # Sets first pre-populated image as current in the backend
        self.selection_changed_source(self.source_treeview.get_selection())

        self.window.show()
        selection = self.source_treeview.get_selection()
        selection.connect('changed', self.selection_changed_source)
        selection = self.dest_treeview.get_selection()
        selection.connect('changed', self.selection_changed_target)

        self.backend.detect_devices()
        # FIXME: instead of passing parent we really should just send signals
        self.unity = UnitySupport(parent=self)
        self.update_loop = self.add_timeout(2000, self.backend.update_free)
        Gdk.threads_enter()
        try:
            Gtk.main()
        except KeyboardInterrupt:
            self.quit()
        Gdk.threads_leave()
Beispiel #57
0
from os import path
from gi.repository import GLib
from IconRequests.modules.settings import Settings
from IconRequests.modules.repos import Repositories

SUPPORTED_ICONS = []

settings = Settings.new()
repositories = Repositories()
ICONS_IGNORE_LIST = [""]

# This is only needed for verifing if the issue already exists!
# Which means that the application will fetch the latest 400 open issues.
ISSUES_PER_PAGE = 100
NB_PAGES = 4

DESKTOP_FILE_DIRS = [
    "/usr/share/applications/", "/usr/share/applications/kde4/",
    "/usr/share/applications/wine/", "/usr/local/share/applications/",
    "/usr/local/share/applications/kde4/",
    "/usr/local/share/applications/wine/",
    "%s/.local/share/applications/" % GLib.get_home_dir(),
    "%s/.local/share/applications/kde4/" % GLib.get_home_dir(),
    "%s/.local/share/applications/wine/" % GLib.get_home_dir(),
    GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP)
]
Beispiel #58
0
    def __init__(self):
        """
            Init dialog
        """
        self.__choosers = []
        self.__cover_tid = None
        self.__mix_tid = None
        self.__popover = None

        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/SettingsDialog.ui')
        if Lp().lastfm is None or Lp().lastfm.is_goa:
            builder.get_object('lastfm_grid').hide()
        if Lp().scanner.is_locked():
            builder.get_object('button').set_sensitive(False)
        builder.get_object('button').connect('clicked',
                                             self.__on_reset_clicked,
                                             builder.get_object('progress'))
        artists = Lp().artists.count()
        albums = Lp().albums.count()
        tracks = Lp().tracks.count()
        builder.get_object('artists').set_text(
                        ngettext("%d artist", "%d artists", artists) % artists)
        builder.get_object('albums').set_text(
                            ngettext("%d album", "%d albums", albums) % albums)
        builder.get_object('tracks').set_text(
                            ngettext("%d track", "%d tracks", tracks) % tracks)

        self.__popover_content = builder.get_object('popover')
        duration = builder.get_object('duration')
        duration.set_range(1, 20)
        duration.set_value(Lp().settings.get_value('mix-duration').get_int32())

        self.__settings_dialog = builder.get_object('settings_dialog')
        self.__settings_dialog.set_transient_for(Lp().window)

        if Lp().settings.get_value('disable-csd'):
            self.__settings_dialog.set_title(_("Preferences"))
        else:
            headerbar = builder.get_object('header_bar')
            headerbar.set_title(_("Preferences"))
            self.__settings_dialog.set_titlebar(headerbar)

        switch_scan = builder.get_object('switch_scan')
        switch_scan.set_state(Lp().settings.get_value('auto-update'))

        switch_view = builder.get_object('switch_dark')
        switch_view.set_state(Lp().settings.get_value('dark-ui'))

        switch_background = builder.get_object('switch_background')
        switch_background.set_state(Lp().settings.get_value('background-mode'))

        switch_state = builder.get_object('switch_state')
        switch_state.set_state(Lp().settings.get_value('save-state'))

        switch_mix = builder.get_object('switch_mix')
        switch_mix.set_state(Lp().settings.get_value('mix'))

        switch_mix_party = builder.get_object('switch_mix_party')
        switch_mix_party.set_state(Lp().settings.get_value('party-mix'))

        switch_librefm = builder.get_object('switch_librefm')
        switch_librefm.set_state(Lp().settings.get_value('use-librefm'))

        switch_artwork_tags = builder.get_object('switch_artwork_tags')
        if which("kid3-cli") is None:
            grid = builder.get_object('grid_behaviour')
            h = grid.child_get_property(switch_artwork_tags, 'height')
            w = grid.child_get_property(switch_artwork_tags, 'width')
            l = grid.child_get_property(switch_artwork_tags, 'left-attach')
            t = grid.child_get_property(switch_artwork_tags, 'top-attach')
            switch_artwork_tags.destroy()
            label = Gtk.Label.new(_("You need to install kid3-cli"))
            label.get_style_context().add_class('dim-label')
            label.set_property('halign', Gtk.Align.END)
            label.show()
            grid.attach(label, l, t, w, h)
        else:
            switch_artwork_tags.set_state(
                                      Lp().settings.get_value('save-to-tags'))

        switch_genres = builder.get_object('switch_genres')
        switch_genres.set_state(Lp().settings.get_value('show-genres'))

        switch_compilations = builder.get_object('switch_compilations')
        switch_compilations.set_state(
            Lp().settings.get_value('show-compilations'))

        switch_artwork = builder.get_object('switch_artwork')
        switch_artwork.set_state(Lp().settings.get_value('artist-artwork'))

        switch_repeat = builder.get_object('switch_repeat')
        switch_repeat.set_state(not Lp().settings.get_value('repeat'))

        combo_orderby = builder.get_object('combo_orderby')
        combo_orderby.set_active(Lp().settings.get_enum(('orderby')))

        combo_preview = builder.get_object('combo_preview')

        scale_coversize = builder.get_object('scale_coversize')
        scale_coversize.set_range(150, 300)
        scale_coversize.set_value(
                            Lp().settings.get_value('cover-size').get_int32())
        self.__settings_dialog.connect('destroy', self.__edit_settings_close)

        builder.connect_signals(self)

        main_chooser_box = builder.get_object('main_chooser_box')
        self.__chooser_box = builder.get_object('chooser_box')

        self.__set_outputs(combo_preview)

        #
        # Music tab
        #
        dirs = []
        for directory in Lp().settings.get_value('music-path'):
            dirs.append(directory)

        # Main chooser
        self.__main_chooser = ChooserWidget()
        image = Gtk.Image.new_from_icon_name("list-add-symbolic",
                                             Gtk.IconSize.MENU)
        self.__main_chooser.set_icon(image)
        self.__main_chooser.set_action(self.__add_chooser)
        main_chooser_box.pack_start(self.__main_chooser, False, True, 0)
        if len(dirs) > 0:
            path = dirs.pop(0)
        else:
            path = GLib.get_user_special_dir(
                GLib.UserDirectory.DIRECTORY_MUSIC)
        self.__main_chooser.set_dir(path)

        # Others choosers
        for directory in dirs:
            self.__add_chooser(directory)

        #
        # Google tab
        #
        builder.get_object('cs-entry').set_text(
                            Lp().settings.get_value('cs-api-key').get_string())
        #
        # Last.fm tab
        #
        if Lp().lastfm is not None and Secret is not None:
            self.__test_img = builder.get_object('test_img')
            self.__login = builder.get_object('login')
            self.__password = builder.get_object('password')
            schema = Secret.Schema.new("org.gnome.Lollypop",
                                       Secret.SchemaFlags.NONE,
                                       SecretSchema)
            Secret.password_lookup(schema, SecretAttributes, None,
                                   self.__on_password_lookup)
            builder.get_object('lastfm_grid').set_sensitive(True)
            builder.get_object('lastfm_error').hide()
            self.__login.set_text(
                Lp().settings.get_value('lastfm-login').get_string())
Beispiel #59
0
class PortfolioPlaces(Gtk.Stack):
    __gtype_name__ = "PortfolioPlaces"

    __gsignals__ = {
        "updated": (GObject.SignalFlags.RUN_LAST, None, (str,)),
        "removed": (GObject.SignalFlags.RUN_LAST, None, (str,)),
    }

    FLATPAK_INFO = os.path.join(os.path.abspath(os.sep), ".flatpak-info")
    PORTFOLIO_SYSTEM_DIR = os.path.abspath(os.sep)
    PORTFOLIO_HOME_DIR = os.environ.get("PORTFOLIO_HOME_DIR", os.path.expanduser("~"))

    XDG_DOWNLOAD = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
    XDG_DOCUMENTS = GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOCUMENTS)
    XDG_PICTURES = GLib.get_user_special_dir(GLib.USER_DIRECTORY_PICTURES)
    XDG_MUSIC = GLib.get_user_special_dir(GLib.USER_DIRECTORY_MUSIC)
    XDG_VIDEOS = GLib.get_user_special_dir(GLib.USER_DIRECTORY_VIDEOS)

    HOST_PERMISSION = ["host"]
    HOME_PERMISSION = ["host", "home"]
    DOWNLOAD_PERMISSION = ["host", "home", "xdg-download"]
    DOCUMENTS_PERMISSION = ["host", "home", "xdg-documents"]
    PICTURES_PERMISSION = ["host", "home", "xdg-pictures"]
    MUSIC_PERMISSION = ["host", "home", "xdg-music"]
    VIDEOS_PERMISSION = ["host", "home", "xdg-videos"]

    def __init__(self, **kargs):
        super().__init__(**kargs)
        self._setup()

    def _setup(self):
        self.props.visible = True
        self.props.transition_type = Gtk.StackTransitionType.CROSSFADE

        self._permissions = None

        self._manager = Gio.VolumeMonitor.get()
        self._manager.connect("mount-added", self._on_mount_added)
        self._manager.connect("mount-removed", self._on_mount_removed)

        # begin UI structure

        self._groups_box = Gtk.Box()
        self._groups_box.props.expand = True
        self._groups_box.props.visible = True
        self._groups_box.props.orientation = Gtk.Orientation.VERTICAL

        self._message_box = Gtk.Box()
        self._message_box.props.expand = True
        self._message_box.props.visible = True
        self._message_box.props.orientation = Gtk.Orientation.VERTICAL

        self._places_group = Handy.PreferencesGroup()
        self._places_group.props.title = _("Places")
        self._places_group.props.visible = True

        self._devices_group = Handy.PreferencesGroup()
        self._devices_group.props.title = _("Devices")
        self._devices_group.props.visible = True
        self._devices_group.get_style_context().add_class("devices-group")

        # places

        if self._has_permission_for(self.HOME_PERMISSION):
            self._add_place(
                self._places_group,
                "user-home-symbolic",
                _("Home"),
                self.PORTFOLIO_HOME_DIR,
            )
        if self._has_permission_for(self.DOWNLOAD_PERMISSION):
            self._add_place(
                self._places_group,
                "folder-download-symbolic",
                os.path.basename(self.XDG_DOWNLOAD),
                self.XDG_DOWNLOAD,
            )
        if self._has_permission_for(self.DOCUMENTS_PERMISSION):
            self._add_place(
                self._places_group,
                "folder-documents-symbolic",
                os.path.basename(self.XDG_DOCUMENTS),
                self.XDG_DOCUMENTS,
            )
        if self._has_permission_for(self.PICTURES_PERMISSION):
            self._add_place(
                self._places_group,
                "folder-pictures-symbolic",
                os.path.basename(self.XDG_PICTURES),
                self.XDG_PICTURES,
            )
        if self._has_permission_for(self.MUSIC_PERMISSION):
            self._add_place(
                self._places_group,
                "folder-music-symbolic",
                os.path.basename(self.XDG_MUSIC),
                self.XDG_MUSIC,
            )
        if self._has_permission_for(self.VIDEOS_PERMISSION):
            self._add_place(
                self._places_group,
                "folder-videos-symbolic",
                os.path.basename(self.XDG_VIDEOS),
                self.XDG_VIDEOS,
            )

        # devices

        if self._has_permission_for(self.HOST_PERMISSION):
            self._add_place(
                self._devices_group,
                "drive-harddisk-ieee1394-symbolic",
                _("System"),
                self.PORTFOLIO_SYSTEM_DIR,
            )

        for mount in self._manager.get_mounts():
            if mount.get_root().get_path() not in [
                self.PORTFOLIO_SYSTEM_DIR,
                self.PORTFOLIO_HOME_DIR,
            ]:
                self._add_place(
                    self._devices_group,
                    "drive-removable-media-symbolic",
                    mount.get_name(),
                    mount.get_root().get_path(),
                    mount,
                )

        self._groups_box.add(self._places_group)
        self._groups_box.add(self._devices_group)

        # no places message

        message = Gtk.Label()
        message.props.expand = True
        message.props.visible = True
        message.props.label = _("No places found")
        message.get_style_context().add_class("no-places")

        self._message_box.add(message)

        # finalize UI structure

        self.add_named(self._groups_box, "groups")
        self.add_named(self._message_box, "message")

        # update visibility

        self._update_stack_visibility()
        self._update_places_group_visibility()
        self._update_device_group_visibility()

    def _update_stack_visibility(self):
        groups = len(self._places_group.get_children())
        devices = len(self._devices_group.get_children())

        if not groups and not devices:
            self.set_visible_child_name("message")
        else:
            self.set_visible_child_name("groups")

    def _update_places_group_visibility(self):
        visible = len(self._places_group.get_children()) >= 1
        self._places_group.props.visible = visible

    def _update_device_group_visibility(self):
        visible = len(self._devices_group.get_children()) >= 1
        self._devices_group.props.visible = visible

    def _get_permissions(self):
        if self._permissions is not None:
            return self._permissions

        info = GLib.KeyFile()
        info.load_from_file(self.FLATPAK_INFO, GLib.KeyFileFlags.NONE)
        permissions = info.get_value("Context", "filesystems")

        if permissions is not None:
            self._permissions = set(permissions.split(";"))
        else:
            self._permissions = set()

        return self._permissions

    def _has_permission_for(self, required):
        # not using flatpak, so access to all
        if not os.path.exists(self.FLATPAK_INFO):
            return True

        permissions = self._get_permissions()
        required = set(required)
        negated = set([f"!{r}" for r in required])

        if required.intersection(permissions):
            return True
        if negated.intersection(permissions):
            return False

        return False

    def _add_place(self, group, icon, name, path, mount=None):
        place = PortfolioPlace()
        place.set_icon_name(icon)
        place.set_title(name)
        place.set_subtitle(path)
        place.path = path
        place.mount = mount
        place.eject.props.visible = mount is not None
        place.eject.connect("clicked", self._on_eject, place)
        place.connect("activated", self._on_place_activated)

        group.add(place)

    def _remove_place(self, group, mount):
        for place in group.get_children():
            if place.path == mount.get_root().get_path():
                self.emit("removed", place.path)
                place.destroy()

    def _on_place_activated(self, place):
        self.emit("updated", place.path)

    def _on_mount_added(self, monitor, mount):
        self._add_place(
            self._devices_group,
            "drive-removable-media-symbolic",
            mount.get_name(),
            mount.get_root().get_path(),
            mount,
        )
        self._update_stack_visibility()
        self._update_device_group_visibility()

    def _on_mount_removed(self, monitor, mount):
        self._remove_place(self._devices_group, mount)
        self._update_stack_visibility()
        self._update_device_group_visibility()

    def _on_eject(self, button, place):
        mount = place.mount

        if mount.can_eject():
            method = mount.eject
            finish = mount.eject_finish
        elif mount.can_unmount():
            method = mount.unmount
            finish = mount.unmount_finish

        method(Gio.MountUnmountFlags.NONE, None, self._on_eject_finished, finish)
        place.props.sensitive = False

    def _on_eject_finished(self, mount, task, finish):
        try:
            finish(task)
        except Exception as e:
            logger.debug(e)
Beispiel #60
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.connect("delete-event",self.on_delete_event)
        self.set_border_width(10)
        self.set_size_request(500, 300)
        self.set_resizable(False)
        
        self.mainvbox             = Gtk.VBox()
        self.mainvbox.props.spacing = 30
        
        self.mainhbox_label_combo = Gtk.HBox()
        self.mainhbox_label_combo.props.spacing = 10
        
        
        self.mainvbox_label       = Gtk.VBox()
        self.mainvbox_combo       = Gtk.VBox()
        self.mainvbox_label.props.homogeneous = True
        self.mainvbox_combo.props.homogeneous = True
        
        
        self.mainvbox.pack_start(self.mainhbox_label_combo,False,False,0)
        self.mainhbox_label_combo.pack_start(self.mainvbox_label,False,False,0)
        self.mainhbox_label_combo.pack_start(self.mainvbox_combo,False,False,0)
        

        ########################################################################
        self.audio_source_combo       = Gtk.ComboBoxText()
        self.audio_source_combo_label = Gtk.Label()
        self.audio_source_combo_label.props.label = "Audio Source"
        
        all_audio_sources = pulse_get_audio_source()
        alsa_audio_source = alsa_get_audio_sources()
        all_audio_sources.update(alsa_audio_source)
        for k,v in all_audio_sources.items():
            self.audio_source_combo.append(v,k[:-1]+" ({})".format(v.split("=",1)[-1])[:50])
        self.audio_source_combo.set_active(0)

        self.mainvbox_label.pack_start(self.audio_source_combo_label,False,True,0)
        self.mainvbox_combo.pack_start(self.audio_source_combo,True,True,0)
        ##########################################################################
        
        
        ##########################################################################
        self.video_source_combo       = Gtk.ComboBoxText()
        self.video_source_combo_label = Gtk.Label()
        self.video_source_combo_label.props.label = "Video Source"
        


        self.video_source_combo.append("0","Current Monitor")
        self.video_source_combo.append("-1","Select Area")
        for i in get_all_window_xid():
            self.video_source_combo.append("{}".format(i[0]),i[1][:30]+" "+i[2][:30])
        self.video_source_combo.set_active(0)

        self.mainvbox_label.pack_start(self.video_source_combo_label,False,True,0)
        self.mainvbox_combo.pack_start(self.video_source_combo,True,True,0)
        ##########################################################################
        
        
        self.mainhbox_label_button = Gtk.HBox()
        self.mainhbox_label_button.props.spacing = 10
        
        
        self.mainvbox_label       = Gtk.VBox()
        self.mainvbox_button      = Gtk.VBox()
        self.mainvbox_label.props.homogeneous = True
        self.mainvbox_button.props.homogeneous = True
        
        
        self.mainvbox.pack_start(self.mainhbox_label_button,False,False,0)
        self.mainhbox_label_button.pack_start(self.mainvbox_label,False,False,0)
        self.mainhbox_label_button.pack_start(self.mainvbox_button,False,False,0)
        ##########################################################################
        
        
        
        ##########################################################################
        self.frame_label = Gtk.Label()
        self.frame_label.props.label = "Framerate"
        adjustment = Gtk.Adjustment(value=30,lower=10,upper=61,page_size=1,step_increment=1, page_increment=0)
        self.frame = Gtk.SpinButton(max_width_chars=2,value=30,adjustment=adjustment)

        self.mainvbox_label.pack_start(self.frame_label,True,False,0)
        self.mainvbox_button.pack_start(self.frame,False,False,0)
        ##########################################################################
        
        
        
        
        ##########################################################################
        self.audio_label = Gtk.Label()
        self.audio_label.props.label = "Record Audio"
        self.audiocheckbutton = Gtk.CheckButton()
        self.audiocheckbutton.set_active(True)

        self.mainvbox_label.pack_start(self.audio_label,True,False,0)
        self.mainvbox_button.pack_start(self.audiocheckbutton,False,False,0)



        
        ##########################################################################
        
        

        ##########################################################################
        self.mouse_label = Gtk.Label()
        self.mouse_label.props.label = "Show Mouse"
        self.mousecheckbutton = Gtk.CheckButton()
        self.mousecheckbutton.set_active(True)
        
        self.mainvbox_label.pack_start(self.mouse_label,True,False,0)
        self.mainvbox_button.pack_start(self.mousecheckbutton,False,False,0)
        ##########################################################################
        
        
        ##########################################################################
        self.minimize_label = Gtk.Label()
        self.minimize_label.props.label = "Minimize Before Record"
        self.minimizecheckbutton = Gtk.CheckButton()
        self.minimizecheckbutton.set_active(False)
        self.mainvbox_label.pack_start(self.minimize_label,True,False,0)
        self.mainvbox_button.pack_start(self.minimizecheckbutton,False,False,0)
        #########################################################################
        
        ##########################################################################
        self.open_location_label = Gtk.Label()
        self.open_location_label.props.label = "Open Location After Stop"
        self.openlocationecheckbutton = Gtk.CheckButton()
        self.openlocationecheckbutton.set_active(True)
        self.mainvbox_label.pack_start(self.open_location_label,True,False,0)
        self.mainvbox_button.pack_start(self.openlocationecheckbutton,False,False,0)
        #########################################################################
        
        
        ##########################################################################
        self.play_label = Gtk.Label()
        self.play_label.props.label = "Play Video After Stop"
        self.playcheckbutton = Gtk.CheckButton()
        self.playcheckbutton.set_active(False)
        self.mainvbox_label.pack_start(self.play_label,True,False,0)
        self.mainvbox_button.pack_start(self.playcheckbutton,False,False,0)
        #########################################################################
        
        #########################################################################
        
        self.filevbox = Gtk.VBox()
        self.filevbox.props.spacing = 10
        self.mainvbox.pack_start(self.filevbox,False,False,0)
        self.filenameentry = Gtk.Entry()
        self.filenameentry.set_placeholder_text("Enter File Name...")
        self.filenameentry.set_max_length(20)


        self.folder = "file://"+GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_VIDEOS)
        self.choicefolder = Gtk.FileChooserButton()
        self.choicefolder.props.action = Gtk.FileChooserAction(2)
        self.choicefolder.set_uri(self.folder)
        
        self.filevbox.pack_start(self.filenameentry,False,False,0)
        self.filevbox.pack_start(self.choicefolder,False,False,0)
        ############################################################################
        
        
        
        
        ############################################################################
        
        self.time_label = Gtk.Label()
        self.time_label.props.use_markup = True


        self.mainvbox.pack_start(self.time_label,False,False,0)
        #############################################################################
        
        

        ############################################################################
        self.is_record_active = False
        self.play_image = Gtk.Image.new_from_icon_name(
                "gtk-media-play",
                Gtk.IconSize.MENU
            )
        self.pause_image = Gtk.Image.new_from_icon_name(
                "gtk-media-pause",
                Gtk.IconSize.MENU
            )
        self.stop_image = Gtk.Image.new_from_icon_name(
                "gtk-media-stop",
                Gtk.IconSize.MENU
            )
        self.start_stop_hbox = Gtk.HBox()
        self.mainvbox.pack_start(self.start_stop_hbox,False,False,0)
        self.start_button = Gtk.Button()
        self.stop_button  = Gtk.Button()
        self.start_button.set_image(self.play_image)
        self.stop_button.set_image(self.stop_image)
        self.stop_button.set_sensitive(False)
        
        self.start_stop_hbox.pack_start(self.start_button,True,True,0)
        self.start_stop_hbox.pack_start(self.stop_button,True,True,0)
        
        self.start_button.connect("clicked",self.on_start_clicked)
        self.stop_button.connect("clicked",self.on_stop_clicked)
        
        ###############################################################################
        self.add(self.mainvbox)
        self.show_all()