Apakah ada menu “Places” untuk Ubuntu Unity?

11

Saya ingin tahu apakah mungkin untuk meletakkan tab "Tempat" di menu atas Ubuntu, seperti CentOS, Debian, dll.

Terima kasih

Ulises CT
sumber
Mudah, tetapi apa yang seharusnya ditampilkan?
Jacob Vlijm
folder utama (home, unduhan, dokumen, dll) dan yang memiliki bookmark seperti debian dan centos
Ulises CT
Saya tahu, akan menulis satu hari ini atau besok jika tidak ada orang lain yang melakukannya sebelum saya :), atau mungkin sudah ada (maksud Anda indikator, kan?)
Jacob Vlijm
cari "Tempat menu Debian" di Gambar Google dan Anda akan melihat apa yang saya maksud.
Ulises CT
Tidak, itu adalah menu klasik. Yang saya temukan hanyalah barang-barang usang dengan satu inci debu di atasnya. Saya dapat dengan cepat menulis yang dasar (dan akan). Saya ingin menggabungkannya dengan yang satu ini: askubuntu.com/questions/803869/… , yang akan menjadikannya proyek yang menarik. Tembakan pertama hari ini atau besok tidak akan menjadi yang terakhir. Pertanyaan yang bagus
Jacob Vlijm

Jawaban:

12

Saya mencoba beberapa yang sudah ada, tetapi tidak dapat menemukan indikator Tempat yang berfungsi . Yang saya temukan sudah ketinggalan zaman, ppa tidak lagi dipertahankan.

Menu Tempat Modular

Jadi, di bawah yang baru ditulis: Indikator Places & Files untuk Ubuntu .

masukkan deskripsi gambar di sini 2

Versi ppa adalah versi modular ; Anda dapat memilih apa yang akan ditampilkan di menu:

[ masukkan deskripsi gambar di sini]

Dalam versi lengkap:

masukkan deskripsi gambar di sini

... atau yang terkecil, hanya menampilkan yang terakhir digunakan:

masukkan deskripsi gambar di sini

Menginstal dari ppa

sudo add-apt-repository ppa:vlijm/placesfiles
sudo apt-get update
sudo apt-get install placesfiles

Versi yang disederhanakan untuk menampilkan menu tempat, bookmark, dan file yang terakhir digunakan

Keterangan & kode (awal)

Naskah

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
import os
import subprocess

class Indicator():
    def __init__(self):

        currpath = os.path.dirname(os.path.realpath(__file__))
        self.home = os.environ["HOME"]
        self.bmark_file = os.path.join(self.home, ".config/gtk-3.0/bookmarks")
        self.def_file = os.path.join(self.home, ".config/user-dirs.dirs")
        self.recdata = os.path.join(self.home, ".local/share/recently-used.xbel")
        self.n = 10
        self.app = 'places'
        iconpath = os.path.join(currpath, "dir_icon.png")
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
        self.indicator.set_label("Places", self.app)
        self.indicator.set_menu(self.create_menu())
        # the thread:
        self.update = Thread(target=self.check_recent)
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        # creates the (initial) menu
        self.menu = Gtk.Menu()
        # separator
        initial = Gtk.MenuItem("Fetching list...")
        menu_sep = Gtk.SeparatorMenuItem()
        self.menu.append(initial)
        self.menu.append(menu_sep)
        # item_quit.show() 
        self.menu.show_all()
        return self.menu

    def open_directory(self, *args):
        index = self.menu.get_children().index(self.menu.get_active())
        selection = self.menu_items2[index-2]
        self.execute(["xdg-open", selection])

    def open_file(self, *args):
        index = self.submenu.get_children().index(self.submenu.get_active())
        selection = self.submenu2[index] 
        self.execute(["xdg-open", selection])

    def go_special(self, button, target):
        self.execute(["xdg-open", target])

    def connect(self, button):
        self.execute("nautilus-connect-server")

    def set_new(self):
        # update the list, appearing in the menu
        for i in self.menu.get_children():
            self.menu.remove(i)
        home_mention = Gtk.MenuItem("⌂ Home")
        home_mention.connect("activate", self.go_special, self.home)
        self.menu.append(home_mention)
        # separator
        menu_sep1 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep1)
        for app in self.menu_items2:
            sub = Gtk.MenuItem("⏍ "+app.split("/")[-1])
            self.menu.append(sub)
            sub.connect('activate', self.open_directory)
        # separator
        menu_sep2 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep2)
        # network
        network = "network:///"
        network_mention = Gtk.MenuItem("⇄ Network")
        network_mention.connect("activate", self.go_special, network)
        self.menu.append(network_mention)
        connect_mention = Gtk.MenuItem("⮁ Connect to server")
        connect_mention.connect("activate", self.connect)
        self.menu.append(connect_mention)
        # separator
        menu_sep3 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep3)
        # computer
        computer = "computer:///"
        computer_mention = Gtk.MenuItem("⛁ Computer")
        computer_mention.connect("activate", self.go_special, computer)
        self.menu.append(computer_mention)
        recent_mention = Gtk.MenuItem("⁕ Recent files")
        self.menu.append(recent_mention)

        self.submenu = Gtk.Menu()
        for f in self.submenu2:
            recent = Gtk.MenuItem(f)
            recent.connect("activate", self.open_file)
            self.submenu.append(recent)
        recent_mention.set_submenu(self.submenu)
        # separator
        menu_sep6 = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep6)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        self.menu.append(item_quit)
        self.menu.show_all()

    def run_about(self, *args):
        self.execute("/opt/upfront/code/runabout")

    def check_recent(self):
        self.menu_items1 = []; self.submenu1 = []
        while True:
            time.sleep(4)
            self.menu_items2 = self.get_bookmarks()
            self.submenu2 = self.get_files()

            if any([self.menu_items2 != self.menu_items1,
                self.submenu2 != self.submenu1]):
                GObject.idle_add(
                    self.set_new, 
                    priority=GObject.PRIORITY_DEFAULT
                    )
            self.menu_items1 = self.menu_items2
            self.submenu1 = self.submenu2

    def stop(self, source):
        Gtk.main_quit()

    def get_bookmarks(self):
        loc_bookmarks = [
            l.replace("file://", "") for l in open(self.bmark_file).read().splitlines()\
            if l.startswith("file://")
            ]
        netw_bookmarks = [
            l for l in open(self.bmark_file).read().splitlines()\
            if l.startswith("smb://")
            ]
        defaults = [
            os.path.join(self.home, l.replace('"', "").split("$HOME/")[-1]) for l in \
            open(self.def_file).read().splitlines() if all\
            (["$HOME/" in l, l.startswith("XDG")])
            ]
        return [self.replace_sc(m.split(" ")[0]).rstrip("/") for m in list(
            set(loc_bookmarks+defaults+netw_bookmarks))]

    def replace_sc(self, path):
        for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
                  ("file://", ""), ("%20", " ")]:
            path = path.replace(c[0], c[1])
        return path

    def execute(self, command):
        subprocess.Popen(command)

    def get_files(self):
        # create the list of recently used files
        used = [l for l in open(self.recdata) if all([
                    '<bookmark href="file://' in l, not "/tmp" in l, "." in l])]
        relevant = [l.split('="') for l in set(used)]
        relevant = [[it[1][7:-7], it[-2][:-10]] for it in relevant]
        relevant.sort(key=lambda x: x[1])
        return [item[0].replace("%20", " ") for item in relevant[::-1][:self.n]]


Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

Cara menggunakan (jika tidak dipasang dari ppa)

  1. Salin skrip ke file kosong, simpan sebagai places_indicator.py
  2. Simpan ikon (klik kanan> simpan sebagai) yang diberi nama persis :

    dir_icon.png
    

    masukkan deskripsi gambar di sini

    ..dalam satu dan direktori yang sama dengan skrip.

  3. Tes-jalankan skrip dengan perintah:

    python3 /path/to/places_indicator.py
    
  4. Jika semua berfungsi dengan baik, tambahkan ke Aplikasi Startup: Dash> Startup Applications> Add. Tambahkan perintah:

    /bin/bash -c "sleep 10 && python3 /path/to/places_indicator.py
    

Tentang indikator

Indikator menunjukkan:

  1. Direktori rumah
  2. Semua direktori (bookmark lokal dan seseorang) di
    • ~/.config/gtk-3.0/bookmarks
    • ~/.config/user-dirs.dirs
  3. Jaringan
  4. Terhubung ke jaringan
  5. Komputer
  6. File yang baru saja digunakan (lat 10 seperti apa adanya, dapat dengan mudah diubah)

Mengubah / menambah / menghapus bookmark diperbarui secara dinamis

Yakub Vlijm
sumber
lumayan bagus, saya sudah mencoba ini di Unity dan berhasil terima kasih! Tapi saya memutuskan untuk menggunakan Gnome karena itu terlihat lebih indah tetapi saya akan menggunakan yang ini untuk fitur filess terbaru juga! terima kasih
Ulises CT
@UlisesCT Ah, terima kasih telah mencoba Unity, terlepas dari kenyataan bahwa Anda telah beralih!
Jacob Vlijm
ya! masalahnya adalah saya datang dari Windows untuk PC desktop, dan tidak pernah menggunakan hal-hal grafis di Linux, hanya terminal pada CentOS untuk server dan semacamnya, dan ketika saya menginstal ubuntu dari ubuntu.es saya pikir GUI-nya hanya yang satu dan tidak tahu ada Gnome dan Unity yang dapat Anda pilih (saya merindukan tab Places karena pada CentOS yang saya coba coba sebagai desktop tetapi agak menyebalkan). Bagus untuk terus belajar
Ulises CT
Wow, komitmen itu - menulis program baru untuk memenuhi kebutuhan ini! Sangat terkesan, @JacobVlijm dilakukan dengan baik! Mengapa ini versi 0.5.1-1 jika Anda baru saja menulisnya?
Ads20000
@ Ads20000 Terima kasih! Beberapa perbaikan; (kembali) file yang dipindahkan atau diganti namanya sekarang ditandai, pemberitahuan ditampilkan jika Anda (mencoba) untuk membukanya, ikon-baru yang berbeda, sekarang juga berfungsi pada 14,04, optimasi minor kode (memfilter karakter khusus dalam nama file) dll.
Jacob Vlijm
8

Perbarui Feb / 24/2017 : indikator sekarang memiliki opsi untuk menyematkan tautan web

pengantar

CATATAN: Versi sebelumnya dari jawaban ini dapat ditemukan di bawah riwayat edit, meskipun tidak lagi relevan.

Indikator yang disajikan di bawah ini dimaksudkan untuk pertanyaan yang berbeda, tetapi karena kesempatan muncul dengan sendirinya, saya memutuskan untuk merilisnya di sini. Indikator File adalah indikator sederhana untuk mengakses file dan folder pengguna. Ini memungkinkan memeriksa file yang terakhir digunakan, mem-bookmark file dan direktori. Secara khusus, menu Places secara khusus relevan dengan pertanyaan ini.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Seperti yang dapat Anda lihat dari tangkapan layar, indikator ini juga mendukung lokal selain bahasa Inggris, jadi jika sistem Anda menggunakan sesuatu selain bahasa Inggris, itu akan berfungsi.

Perbarui : indikator sekarang juga mendukung meluncurkan file .desktop yang telah disematkan. Sebagai contoh jika Anda memiliki pin firefox.desktop, itu akan meluncurkan firefox. Dengan demikian, indikator dapat digunakan sebagai peluncur cepat untuk program. Fitur sedang dalam perjalanan ke PPA pada saat penulisan (19 Nov, 19:53 GMT, harus memakan waktu sekitar 24 jam untuk diproses), tetapi sudah ada di github dan juga di sini, dalam kode sumber yang diperbarui.

masukkan deskripsi gambar di sini

Memperoleh indikator

Indikator tersedia dari PPA pribadi saya dan juga GitHub . Gunakan langkah-langkah berikut untuk mendapatkannya:

sudo add-apt-repository ppa:1047481448-2/sergkolo
sudo apt-get update
sudo apt-get install files-indicator

Kode sumber

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#
# Author: Serg Kolo , contact: [email protected]
# Date: November 19 , 2016
# Purpose: appindicator for accessing files and folders
# Tested on: Ubuntu 16.04 LTS
#
#
# Licensed under The MIT License (MIT).
# See included LICENSE file or the notice below.
#
# Copyright © 2016 Sergiy Kolodyazhnyy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import gi
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Notify', '0.7')
from gi.repository import GLib as glib
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Gtk as gtk
from gi.repository import Gio
from gi.repository import Notify
from collections import OrderedDict
# from collections import OrderedDict
import urllib.parse
import subprocess
import copy
import shutil
import dbus
import math
import json
import os

class FilesIndicator(object):

    def __init__(self):
        self.app = appindicator.Indicator.new(
            'files-indicator', "document-open-recent",
            appindicator.IndicatorCategory.HARDWARE
        )
        self.user_home = os.path.expanduser('~')
        filename = '.pinned_files.json'
        self.pinned_list = os.path.join(self.user_home,filename)

        self.config = os.path.join(self.user_home,'.files_indicator.json')
        self.max_items = 15
        self.name_length = 20
        self.read_config()

        self.app.set_status(appindicator.IndicatorStatus.ACTIVE)

        self.cached_files = self.get_recent_files()
        self.make_menu()
        self.update()

    def read_config(self,*args):
        config = {}
        try:
            with open(self.config) as f:
                 config = json.load(f)

        except FileNotFoundError:
            print('>>> ',self.config,' not found.Creating one')
            f = open(self.config,'w')
            config = {'max_items':self.max_items,
                      'name_length':self.name_length
            }
            json.dump(config,f,indent=4)
            f.close()
        except json.JSONDecodeError:
            print(">>> Can't read ",self.pinned_list,',may be corrupt')
            return None
        else:
            self.max_items = config['max_items']
            self.name_length = config['name_length']

    def add_menu_item(self, menu_obj, item_type, image, label, action, args):
        """ dynamic function that can add menu items depending on
            the item type and other arguments"""
        menu_item, icon = None, None
        if item_type is gtk.ImageMenuItem and label:
            menu_item = gtk.ImageMenuItem.new_with_label(label)
            menu_item.set_always_show_image(True)
            if '/' in image:
                icon = gtk.Image.new_from_file(image)
            else:
                icon = gtk.Image.new_from_icon_name(image, 48)
            menu_item.set_image(icon)
        elif item_type is gtk.ImageMenuItem and not label:
            menu_item = gtk.ImageMenuItem()
            menu_item.set_always_show_image(True)
            if '/' in image:
                icon = gtk.Image.new_from_file(image)
            else:
                icon = gtk.Image.new_from_icon_name(image, 16)
            menu_item.set_image(icon)
        elif item_type is gtk.MenuItem:
            menu_item = gtk.MenuItem(label)
        elif item_type is gtk.SeparatorMenuItem:
            menu_item = gtk.SeparatorMenuItem()
        if action:
            menu_item.connect('activate', action, *args)

        menu_obj.append(menu_item)
        menu_item.show()

    def get_user_dirs(self,*args):
        user_dirs = []
        for index,val in glib.UserDirectory.__enum_values__.items():
            if index == 8: continue
            dir = glib.get_user_special_dir(index)
            if dir: user_dirs.append(dir)
        return user_dirs

    def get_file_icon(self,*args):
        if args[-1].endswith('.desktop'):
            desk_file = Gio.DesktopAppInfo.new_from_filename(args[-1])
            icon = desk_file.get_icon()
            if type(icon) == Gio.ThemedIcon:
                themed_name = icon.get_names()[0]
                theme = gtk.IconTheme.get_default()
                name = theme.lookup_icon(themed_name, 48, 0).get_filename()
            if type(icon) == Gio.FileIcon:
                name = icon.get_file().get_uri()

            icon_url= urllib.parse.unquote(name).replace('file://','') 
            return icon_url

        file = Gio.File.new_for_path(args[-1])
        file_info = file.query_info("standard::*",0)
        icon_string = file_info.get_icon().to_string()
        if 'folder-' in icon_string:
            return icon_string.split()[-2]
        return icon_string.split()[-1]

    def get_recent_files(self,*args):
        manager = gtk.RecentManager.get_default()
        try:
            files = OrderedDict()
            for index,item in enumerate(manager.get_items(),1):
                    uri = item.get_uri()
                    uri_decoded = urllib.parse.unquote(uri)
                    filepath = uri_decoded.replace('file://','')
                    if not os.path.exists(filepath): continue
                    basename = os.path.basename(uri_decoded)
                    files[basename] = filepath
                    if index == self.max_items:
                        break
        except Exception as e:
            print(e)
            return None
        finally:  return files

    def callback(self,*args):
        self.update()

    def update(self,*args):
        current_files = self.get_recent_files()
        if current_files != self.cached_files:
             self.make_menu()
             self.cached_files = current_files
        glib.timeout_add_seconds(3,self.callback)

    def add_submenu(self,top_menu,label):
        menuitem = gtk.MenuItem(label)
        submenu = gtk.Menu()
        menuitem.set_submenu(submenu)
        top_menu.append(menuitem)
        menuitem.show()
        return submenu

    def make_menu(self):
        if hasattr(self, 'app_menu'):
            for item in self.app_menu.get_children():
                    self.app_menu.remove(item)
        else:
            self.app_menu = gtk.Menu()
        recent = self.add_submenu(self.app_menu,'Recent Files')
        recent_dict = self.get_recent_files()

        content = [recent,gtk.ImageMenuItem,'gtk-add',
                   'Add to Recent Files',self.add_recent,[None]
        ]      
        self.add_menu_item(*content) 

        content = [recent,gtk.ImageMenuItem,'user-trash',
                   'Clear recent files list',self.clear_recent,[None]
        ]      
        self.add_menu_item(*content)

        content = [recent,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        self.add_menu_item(*content) 
        if not recent_dict:
            content = [recent,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in recent.get_children():
                last = i
            last.set_sensitive(False)
        else:
            for name,data in recent_dict.items():
                icon = self.get_file_icon(data)
                content = [recent, gtk.ImageMenuItem,
                           icon, name[:self.name_length],
                           self.open_item, [data]
                ]
                self.add_menu_item(*content)

        # Pinned files
        bookmarks = self.add_submenu(self.app_menu,'Pinned Files')
        content = [bookmarks,gtk.ImageMenuItem,
                   'bookmark_add','Pin a file',
                   self.pin_file,[bookmarks,None]
        ]
        self.add_menu_item(*content)

        content = [bookmarks,gtk.ImageMenuItem,
                   'remove','Remove item',
                   self.remove_pinned,['files']
        ]
        self.add_menu_item(*content)

        content = [bookmarks,gtk.ImageMenuItem,
                   'user-trash','Remove All',
                   self.remove_all_pinned,[None]
        ]
        self.add_menu_item(*content)
        content = [bookmarks,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        self.add_menu_item(*content) 

        pinned_files = self.get_pinned()

        if (pinned_files and 
            'files' in pinned_files.keys() and
            pinned_files['files']):
            for filepath in pinned_files['files']:
                icon = self.get_file_icon(filepath) 
                content = [bookmarks,gtk.ImageMenuItem,
                           icon,os.path.basename(filepath),
                           self.open_item,[filepath]
                ]
                self.add_menu_item(*content)
        else:
            content = [bookmarks,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in bookmarks.get_children():
                last = i
            last.set_sensitive(False)

        places = self.add_submenu(self.app_menu,'Places')
        content = [places,gtk.ImageMenuItem,'add',
                   'Pin Directory',self.pin_dir,[None]
        ]

        self.add_menu_item(*content)

        content = [places,gtk.ImageMenuItem,
                   'remove','Remove Pinned',
                   self.remove_pinned,['dirs']
        ]
        self.add_menu_item(*content)

        content = [places,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)

        content = [places,gtk.MenuItem,None,
                   'Standard Dirs',None,None
        ]
        self.add_menu_item(*content)
        last = None
        for i in places.get_children():
            last = i
        last.set_sensitive(False)
        for dir in self.get_user_dirs():
            icon = self.get_file_icon(dir)
            content = [places,gtk.ImageMenuItem,icon,
                       os.path.basename(dir),self.open_item,[dir]

            ]
            self.add_menu_item(*content)

        content = [places,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)

        content = [places,gtk.MenuItem,None,
                   'Pinned Dirs',None,None
        ]
        self.add_menu_item(*content)
        last = None
        for i in places.get_children():
            last = i
        last.set_sensitive(False)

        if (pinned_files and 
           'dirs' in pinned_files.keys() and
           pinned_files['dirs']):
            for dir in pinned_files['dirs']:
                icon = self.get_file_icon(dir)
                print(icon)
                content = [places,gtk.ImageMenuItem,icon,
                           os.path.basename(dir),self.open_item,[dir]

                ]
                self.add_menu_item(*content)
        else:
            content = [places,gtk.MenuItem,None,
                       'No items',None,None
            ]
            self.add_menu_item(*content)
            last = None
            for i in places.get_children():
                last = i
            last.set_sensitive(False)

        content = [self.app_menu,gtk.SeparatorMenuItem,
                   None,None,
                   None,[None]
        ]
        self.add_menu_item(*content)
        content = [self.app_menu,gtk.ImageMenuItem,'exit',
                   'quit',self.quit,[None]
        ]
        self.add_menu_item(*content)
        self.app.set_menu(self.app_menu)

    def check_directory(self,*args):
        current_set = set(os.listdir(args[-1]))
        return current_set - self.cached_set


    def get_pinned(self,*args):
        try:
            with open(self.pinned_list) as f:
                 return json.load(f,object_pairs_hook=OrderedDict)

        except FileNotFoundError:
            print('>>> ',self.pinned_list,' not found')
            return None
        except json.JSONDecodeError:
            print(">>> Can't read ",self.pinned_list,',may be corrupt')
            return None

    def pin_dir(self,*args):
        # TODO
        current_list = self.get_pinned()
        if not current_list:
                current_list = OrderedDict()
                current_list['dirs'] = []
                f = open(self.pinned_list,'w')
                f.write("")
                f.close()

        if not args[-1]:
                cmd = "zenity --file-selection --directory --separator || --multiple"
                dirs = self.run_cmd(cmd.split())
        else:
                dirs = args[-1]

        dir_list = []
        if not dirs: return None
        dir_list = dirs.decode().strip().split("||")
        if not 'dirs' in current_list.keys():
             current_list['dirs'] = []
        for f in dir_list:
                #icon = self.get_file_icon(f)
                current_list['dirs'].append(f)

        with open(self.pinned_list,'w') as f:
                json.dump(current_list,f,indent=4)
        self.make_menu()

    def pin_file(self,*args):
        current_list = self.get_pinned()
        if not current_list:
                current_list = OrderedDict()
                current_list['files'] = []
                f = open(self.pinned_list,'w')
                f.write("")
                f.close()
        if not args[-1]:
                cmd = "zenity --file-selection --separator || --multiple "
                files = self.run_cmd(cmd.split())
        else:
                files = args[-1]

        file_list = []
        if not files: return None
        file_list = files.decode().strip().split("||")
        if not 'files' in current_list.keys():
            current_list['files'] = []
        for f in file_list:
                #icon = self.get_file_icon(f)
                current_list['files'].append(f)

        with open(self.pinned_list,'w') as f:
                json.dump(current_list,f,indent=4)
        self.make_menu()

    def remove_all_pinned(self,*args):
        try:
            #os.unlink(self.pinned_list)

            with open(self.pinned_list) as f:
                pinned = json.load(f)
            pinned.pop('files')       
            with open(self.pinned_list,'w') as f:
                    json.dump(pinned,f,indent=4)
        except:
            pass
        finally:
            self.make_menu()

    def remove_pinned(self,*args):
        key = args[-1]
        pinned = self.get_pinned() 
        if not pinned: return
        cmd_str = "zenity --forms --add-combo Remove --combo-values"
        vals = "|".join(pinned[key])
        cmd = cmd_str.split() + [vals]
        item = self.run_cmd(cmd)
        if item: 
            path = item.decode().strip()
            index = pinned[key].index(path)
            pinned[key].pop(index)
            with open(self.pinned_list,'w') as f:
                json.dump(pinned,f,indent=4)
            self.make_menu()

    def add_recent(self,*args):
        cmd = "zenity --file-selection --separator || --multiple "
        files = self.run_cmd(cmd.split())
        file_list = []
        if not files: return
        file_list = files.decode().strip().split("||")
        items = ['file://' + f for f in file_list]
        for f in items: gtk.RecentManager().get_default().add_item(f)

    def clear_recent(self,*args):
        try:
            gtk.RecentManager.get_default().purge_items()
            self.make_menu()
        except:
            pass

    def open_item(self,*args):
        #self.run_cmd(['xdg-open',args[-1]]) 
        if args[-1].endswith('.desktop'):
            desk_file = Gio.DesktopAppInfo.new_from_filename(args[-1])
            return desk_file.launch_uris()
        return subprocess.Popen(['xdg-open',args[-1]])

    def quit(self,*args):
        gtk.main_quit()

    def run_cmd(self, cmdlist):
        """ utility: reusable function for running external commands """
        #new_env = dict(os.environ)
        #new_env['LC_ALL'] = 'C'
        try:
            stdout = subprocess.check_output(cmdlist) #env=new_env)
        except subprocess.CalledProcessError:
            pass
        else:
            if stdout:
                return stdout

    def run(self):
        """ Launches the indicator """
        try:
            gtk.main()
        except KeyboardInterrupt:
            pass

    def quit(self, *args):
        """ closes indicator """
        gtk.main_quit()


def main():
    """ defines program entry point """
    indicator = FilesIndicator()
    indicator.run()

if __name__ == '__main__':
  try:
    main()
  except  KeyboardInterrupt:
    gtk.main_quit()

Konfigurasi

Indikator dikonfigurasikan melalui dua file json yang disimpan dalam direktori home pengguna.

~/.files_indicator.json mengontrol antarmuka pengguna, panjang entri menu dan jumlah maksimum di Menu File Terbaru.

{
    "name_length": 30,
    "max_items": 10
}

The ~/.pinned_files.jsonmengontrol daftar file dan folder disematkan. Setiap item adalah daftar / larik.

{
    "dirs": [
        "/home/xieerqi/\u56fe\u7247/Wallpapers"
    ],
    "files": [
        "/home/xieerqi/work_in_progress/videonauth_code.py",
        "/home/xieerqi/work_in_progress/spin_button.py"
    ]
}
Sergiy Kolodyazhnyy
sumber
Wow, terkesan bahwa Anda juga menciptakan solusi untuk masalah ini! : D
Ads20000
@ Ads20000 Terima kasih :) Indikator ini semula dimaksudkan hanya untuk file terbaru. Ketika saya melihat pertanyaan saya pikir fitur akan lebih baik untuk ditambahkan ke indikator, juga, sangat sederhana untuk diterapkan - membawa saya cukup banyak suatu pagi dan 2 cangkir kopi :)
Sergiy Kolodyazhnyy
Pekerjaan Anda juga membuatnya menjadi OMG! Ubuntu! artikel ! : D
Ads20000
Yap, saya melihat itu :)
Sergiy Kolodyazhnyy
0

Oke guys yang saya lakukan hanyalah menginstal Ubuntu-Gnome dan mengaktifkan ekstensi 'Places' di alat Tweak dan mendapatkannya. Harus mengatakan Ubuntu Gnome terlihat jauh lebih baik daripada Unity

Lihat tab "Lugares"

Ulises CT
sumber
Pilihan yang bijak. Itu sudah jelas dari awal Anda condong ke arah menggunakan GNOME, karena itu lebih akrab bagi Anda dari CentOS. Ngomong-ngomong, apa yang mereka gunakan di CentOS adalah Flashback GNOME. Ini dimaksudkan untuk secara visual mirip dengan versi sebelumnya namun menggunakan teknologi yang lebih baru. Sedangkan untuk Unity, mungkin tidak untuk semua orang, meskipun saya pribadi sangat tidak menyukai GNOME karena mereka terus-menerus menghapus fitur dan membuat pengembangan kompleks.
Sergiy Kolodyazhnyy
Ya persis, saya agak "noob" ke Linux atau "ketinggalan zaman" karena Anda lebih suka mengatakannya. Maksud saya, saya selalu menggunakan terminal untuk server pada CentOS, dan tidak banyak hal-hal grafis, saya tidak tahu ada opsi grafis yang berbeda seperti Unity dan Gnome, saya hanya berpikir Ubuntu hanya bisa melihat cara kerjanya dari paket unduhan ubuntu.com, CentOS cara kerjanya dari halaman web resmi, dll. Tidak tahu ada banyak pilihan grafis yang bisa Anda miliki. Bagus untuk terus belajar. @Serg
Ulises CT
Izinkan saya mengajukan pertanyaan ini: Jika Anda benar-benar harus menggunakan desktop Unity, hal-hal lain apa yang Anda inginkan? (Jelas, saya mencoba untuk meneliti ide-ide untuk keperluan masa depan :)
Sergiy Kolodyazhnyy
satu-satunya hal yang dapat saya pikirkan adalah tab "Tempat" atau "Aplikasi" (yang saya tidak benar-benar gunakan) sisanya tersedia di Unity juga saya kira, apa yang saya tidak suka dari gnome adalah bahwa untuk menu aplikasi Anda harus mengklik tombol di sebagian besar program (file khas, edit, menu dll)
Ulises CT