Python3 port

This commit is contained in:
gm10 2019-01-26 06:08:00 +01:00
parent c293d485d9
commit 0df697d99d
No known key found for this signature in database
GPG Key ID: A981D4EA8CF993A9
15 changed files with 116 additions and 97 deletions

15
debian/control vendored
View File

@ -10,20 +10,19 @@ Architecture: all
Depends:
${python:Depends},
${misc:Depends},
mint-common,
python (>= 2.4), python (<< 3),
python-apt,
python-configobj,
python-setproctitle,
python-xlib,
python-xdg,
python3 (>= 3.3),
python3-apt,
python3-configobj,
python3-setproctitle,
python3-xlib,
python3-xdg,
xdg-utils,
libglib2.0-bin,
mate-menus,
python-mate-menu,
gir1.2-matepanelapplet-4.0,
gir1.2-gtk-3.0,
gir1.2-mate-desktop,
gir1.2-matemenu-2.0,
mozo
Description: Advanced MATE menu
One of the most advanced menus under Linux. MintMenu supports filtering,

2
debian/postinst vendored
View File

@ -19,7 +19,7 @@ set -e
case "$1" in
configure)
glib-compile-schemas /usr/share/glib-2.0/schemas
python -m compileall -qf /usr/lib/linuxmint/mintMenu/
python3 -m compileall -qf /usr/lib/linuxmint/mintMenu/
;;
abort-upgrade|abort-remove|abort-deconfigure)

2
debian/rules vendored
View File

@ -3,7 +3,7 @@
DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')
%:
dh ${@} --with-python2
dh ${@}
# Inject version number in the code
override_dh_installdeb:

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
# -*- coding: utf-8; -*-
# Copyright (C) 2013 Ozcan Esen <ozcanesen@gmail.com>
@ -118,7 +118,7 @@ class GlobalKeyBinding(GObject.GObject, threading.Thread):
self.grab(self.keytext)
def get_mask_combinations(self, mask):
return [x for x in xrange(mask+1) if not (x & ~mask)]
return [x for x in range(mask+1) if not (x & ~mask)]
def idle(self):
self.emit("activate")

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import gc
import gettext
@ -168,7 +168,7 @@ class MainWindow(object):
try:
X = __import__(plugin)
# If no parameter passed to plugin it is autonomous
if X.pluginclass.__init__.func_code.co_argcount == 1:
if X.pluginclass.__init__.__code__.co_argcount == 1:
MyPlugin = X.pluginclass()
else:
# pass mintMenu and togglebutton instance so that the plugin can use it
@ -540,9 +540,8 @@ class MenuWin(object):
self.do_image(self.buttonIcon, False)
self.systemlabel = Gtk.Label(label= "%s " % self.buttonText)
if os.path.isfile("/etc/linuxmint/info"):
with open("/etc/linuxmint/info") as info:
with open("/etc/linuxmint/info", encoding = "utf-8") as info:
for line in info:
line = line.decode("utf-8")
if line.startswith("DESCRIPTION="):
tooltip = line.split("=",1)[1].strip('"\n')
self.systemlabel.set_tooltip_text(tooltip)
@ -638,7 +637,7 @@ class MenuWin(object):
self.do_image(self.buttonIcon, False)
self.sizeButton()
def hotkeyChanged (self, schema, key):
def hotkeyChanged(self, schema, key):
self.hotkeyText = self.settings.get_string("hot-key")
self.keybinder.rebind(self.hotkeyText)

View File

@ -1 +1 @@
#!/usr/bin/python2
#!/usr/bin/python3

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import cgi
import filecmp
@ -10,9 +10,9 @@ import urllib
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, GdkPixbuf, Gio, GLib
gi.require_version('MateMenu', '2.0')
from gi.repository import Gtk, Gdk, GdkPixbuf, Gio, GLib, MateMenu
import matemenu
import plugins.recentHelper as RecentHelper
from plugins.easybuttons import (ApplicationLauncher, CategoryButton,
FavApplicationLauncher,
@ -79,10 +79,33 @@ def rel_path(target, base=os.curdir):
rel_list = [os.pardir] * (len(base_list) - i) + target_list[i:]
return os.path.join(*rel_list)
def get_contents(item):
contents = []
item_iter = item.iter()
item_type = item_iter.next()
while item_type != MateMenu.TreeItemType.INVALID:
item = None
if item_type == MateMenu.TreeItemType.DIRECTORY:
item = item_iter.get_directory()
elif item_type == MateMenu.TreeItemType.ENTRY:
item = item_iter.get_entry()
elif item_type == MateMenu.TreeItemType.HEADER:
item = item_iter.get_header()
elif item_type == MateMenu.TreeItemType.ALIAS:
item = item_iter.get_alias()
elif item_type == MateMenu.TreeItemType.SEPARATOR:
item = item_iter.get_separator()
if item:
contents.append(item)
item_type = item_iter.next()
return contents
class Menu:
def __init__(self, MenuToLookup):
self.tree = matemenu.lookup_tree(MenuToLookup)
self.tree = MateMenu.Tree.new(MenuToLookup, MateMenu.TreeFlags.SORT_DISPLAY_NAME)
self.tree.load_sync()
self.directory = self.tree.get_root_directory()
def getMenus(self, parent=None):
@ -90,21 +113,21 @@ class Menu:
#gives top-level "Applications" item
yield self.tree.root
else:
for menu in parent.get_contents():
if menu.get_type() == matemenu.TYPE_DIRECTORY and self.__isVisible(menu):
for menu in get_contents(parent):
if isinstance(menu, MateMenu.TreeDirectory) and self.__isVisible(menu):
yield menu
def getItems(self, menu):
for item in menu.get_contents():
if item.get_type() == matemenu.TYPE_ENTRY and \
item.get_desktop_file_id()[-19:] != '-usercustom.desktop' and \
self.__isVisible(item):
for item in get_contents(menu):
if isinstance(item, MateMenu.TreeEntry) and \
item.get_desktop_file_id()[-19:] != '-usercustom.desktop' and \
self.__isVisible(item):
yield item
def __isVisible(self, item):
if item.get_type() == matemenu.TYPE_ENTRY:
if isinstance(item, MateMenu.TreeEntry):
return not(item.get_is_excluded() or item.get_is_nodisplay())
if item.get_type() == matemenu.TYPE_DIRECTORY and len(item.get_contents()):
if isinstance(item, MateMenu.TreeDirectory) and len(get_contents(item)):
return True
class SuggestionButton(Gtk.Button):
@ -159,6 +182,7 @@ class pluginclass(object):
RecentHelper.mintMenuWin = mintMenuWin
self.mainMenus = []
self.toggleButton = toggleButton
self.menuFiles = []
self.de = de
# Detect the locale (this is used for the Wikipedia search)
@ -266,7 +290,8 @@ class pluginclass(object):
for mainitems in ["mate-applications.menu", "mate-settings.menu"]:
mymenu = Menu(mainitems)
mymenu.tree.add_monitor(self.menuChanged, None)
mymenu.tree.connect("changed", self.menuChanged, None)
self.menuFiles.append(mymenu)
self.refresh_apt_cache()
self.suggestions = []
@ -972,17 +997,17 @@ class pluginclass(object):
self.focusSearchEntry(clear = False)
def search_ddg(self, widget):
text = urllib.quote_plus(self.searchEntry.get_text().strip())
text = urllib.parse.quote_plus(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://duckduckgo.com/?q=%s" % text])
self.mintMenuWin.hide()
def search_google(self, widget):
text = urllib.quote_plus(self.searchEntry.get_text().strip())
text = urllib.parse.quote_plus(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://www.google.com/search?q=%s" % text])
self.mintMenuWin.hide()
def search_wikipedia(self, widget):
text = urllib.quote_plus(self.searchEntry.get_text().strip())
text = urllib.parse.quote_plus(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://en.wikipedia.org/wiki/Special:Search?search=%s" % text])
self.mintMenuWin.hide()
@ -992,27 +1017,27 @@ class pluginclass(object):
self.mintMenuWin.hide()
def search_mint_tutorials(self, widget):
text = urllib.quote(self.searchEntry.get_text().strip())
text = urllib.parse.quote(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://community.linuxmint.com/index.php/tutorial/search/0/%s" % text])
self.mintMenuWin.hide()
def search_mint_ideas(self, widget):
text = urllib.quote(self.searchEntry.get_text().strip())
text = urllib.parse.quote(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://community.linuxmint.com/index.php/idea/search/0/%s" % text])
self.mintMenuWin.hide()
def search_mint_users(self, widget):
text = urllib.quote(self.searchEntry.get_text().strip())
text = urllib.parse.quote(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://community.linuxmint.com/index.php/user/search/0/%s" % text])
self.mintMenuWin.hide()
def search_mint_hardware(self, widget):
text = urllib.quote(self.searchEntry.get_text().strip())
text = urllib.parse.quote(self.searchEntry.get_text().strip())
subprocess.Popen(["xdg-open", "https://community.linuxmint.com/index.php/hardware/search/0/%s" % text])
self.mintMenuWin.hide()
def search_mint_software(self, widget):
text = urllib.quote(self.searchEntry.get_text())
text = urllib.parse.quote(self.searchEntry.get_text())
subprocess.Popen(["xdg-open", "https://community.linuxmint.com/index.php/software/search/0/%s" % text])
self.mintMenuWin.hide()
@ -1190,7 +1215,7 @@ class pluginclass(object):
def favoritesBuildLauncher(self, location):
try:
# For Folders and Network Shares
location = "".join(location.split("%20"))
location = location.replace("%20", " ")
# TODO: Do we still need this?
#For Special locations
@ -1234,7 +1259,7 @@ class pluginclass(object):
os.system("mkdir -p " + path)
os.system("cp /usr/lib/linuxmint/mintMenu/applications.list " + path)
applicationsList = open(path).readlines()
applicationsList = open(path, encoding="UTF-8").readlines()
self.favorites = []
@ -1381,8 +1406,7 @@ class pluginclass(object):
def on_drag_data_get(self, widget, context, selection, info, time):
if info == self.TARGET_TYPE_FAV:
self.drag_origin = widget.position
# FIXME: This fails in python3:
selection.set(selection.get_target(), 8, str(widget.position))
selection.set(selection.get_target(), 8, str(widget.position).encode())
def on_drag_data_received(self, widget, context, x, y, selection, info, time):
if info == self.TARGET_TYPE_FAV:
@ -1579,9 +1603,14 @@ class pluginclass(object):
# Reload the menufiles from the filesystem
def loadMenuFiles(self):
self.menuFiles = []
if len(self.menuFiles) > 0:
for menu in self.menuFiles:
menu.tree.disconnect_by_func(self.menuChanged)
self.menuFiles = []
for mainitems in ["mate-applications.menu", "mate-settings.menu"]:
self.menuFiles.append(Menu(mainitems))
mymenu = Menu( mainitems )
mymenu.tree.connect("changed", self.menuChanged, None)
self.menuFiles.append(mymenu)
# Build a list of all categories in the menu ([{"name", "icon", tooltip"}]
def buildCategoryList(self):
@ -1591,16 +1620,14 @@ class pluginclass(object):
"filter":"", "index": 0}]
num = 1
for menu in self.menuFiles:
for child in menu.directory.get_contents():
if child.get_type() == matemenu.TYPE_DIRECTORY:
icon = str(child.icon)
#if (icon == "preferences-system"):
# self.adminMenu = child.name
#if (icon != "applications-system" and icon != "applications-other"):
newCategoryList.append({"name": child.name,
"icon": child.icon,
"tooltip": child.name,
"filter": child.name,
for child in get_contents(menu.directory):
if isinstance(child, MateMenu.TreeDirectory):
name = child.get_name()
icon = child.get_icon().to_string()
newCategoryList.append({"name": name,
"icon": icon,
"tooltip": name,
"filter": name,
"index": num})
num += 1
return newCategoryList
@ -1610,29 +1637,30 @@ class pluginclass(object):
newApplicationsList = []
def find_applications_recursively(app_list, directory, catName):
for item in directory.get_contents():
if item.get_type() == matemenu.TYPE_ENTRY:
for item in get_contents(directory):
if isinstance(item, MateMenu.TreeEntry):
#print("=======>>> " + str(item.get_name()) + " = " + str(catName))
app_list.append({"entry": item, "category": catName})
elif item.get_type() == matemenu.TYPE_DIRECTORY:
elif isinstance(item, MateMenu.TreeDirectory):
find_applications_recursively(app_list, item, catName)
for menu in self.menuFiles:
directory = menu.directory
for entry in directory.get_contents():
if entry.get_type() == matemenu.TYPE_DIRECTORY and len(entry.get_contents()):
for entry in get_contents(directory):
if isinstance(entry, MateMenu.TreeDirectory) and len(get_contents(entry)):
#Entry is a top-level category
#catName = entry.name
#icon = str(entry.icon)
#catName = entry.get_name()
#icon = entry.get_icon().to_string()
#if (icon == "applications-system" or icon == "applications-other"):
# catName = self.adminMenu
for item in entry.get_contents():
if item.get_type() == matemenu.TYPE_DIRECTORY:
find_applications_recursively(newApplicationsList, item, entry.name)
elif item.get_type() == matemenu.TYPE_ENTRY:
newApplicationsList.append({"entry": item, "category": entry.name})
#elif entry.get_type() == matemenu.TYPE_ENTRY:
for item in get_contents(entry):
if isinstance(item, MateMenu.TreeDirectory):
find_applications_recursively(newApplicationsList, item, entry.get_name())
elif isinstance(item, MateMenu.TreeEntry):
newApplicationsList.append( { "entry": item, "category": entry.get_name() } )
#elif isinstance(entry, MateMenu.TreeEntry):
# if not (entry.get_is_excluded() or entry.get_is_nodisplay()):
# print "=======>>> " + item.name + " = top level"
# newApplicationsList.append({"entry": item, "category": ""})
# print("=======>>> " + item.get_name() + " = top level")
# newApplicationsList.append({"entry": item, "category": ""})
return newApplicationsList

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import os.path
import shutil
@ -89,7 +89,6 @@ class IconManager(GObject.GObject):
image = Gtk.Image.new_from_icon_name(realIconName, Gtk.IconSize.DND)
image.set_pixel_size(iconSize)
return image
except Exception as e:
print("Exception %s: %s" % (e.__class__.__name__, e))
return None
@ -127,7 +126,7 @@ class easyButton(Gtk.Button):
if labels:
for label in labels:
if isinstance(label, basestring):
if isinstance(label, str):
self.addLabel(label)
elif isinstance(label, list):
self.addLabel(label[0], label[1])
@ -315,13 +314,7 @@ class ApplicationLauncher(easyButton):
return True
def strip_accents(self, string):
value = string
if isinstance(string, unicode):
try:
value = string.encode('UTF8', 'ignore')
except:
pass
return value
return string
def getTooltip(self):
tooltip = self.appName

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
from gi.repository import Gio

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import os
from gi.repository import Gio

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import os
import os.path

View File

@ -1,10 +1,9 @@
#!/usr/bin/python2
#!/usr/bin/python3
import gettext
import os
import string
from glob import glob
from urllib import unquote
import shutil
from urllib.parse import unquote
import gi
gi.require_version("Gtk", "3.0")
@ -62,11 +61,14 @@ class pluginclass(object):
self.settings.notifyAdd("show-gtk-bookmarks", self.RegenPlugin)
self.settings.notifyAdd("height", self.changePluginSize)
self.settings.notifyAdd("width", self.changePluginSize)
self.loadSettings()
self.content_holder.set_size_request(self.width, self.height)
# Variables
self.trash_info = os.path.join(home, ".local/share/Trash/info")
self.trash_files = os.path.join(home, ".local/share/Trash/files")
def wake(self):
if self.showtrash:
self.refreshTrash()
@ -186,7 +188,6 @@ class pluginclass(object):
self.trashButton.connect("clicked", self.ButtonClicked, "xdg-open trash:")
self.trashButton.show()
self.trashButton.connect("button-release-event", self.trashPopup)
self.trash_path = os.path.join(home, ".local/share/Trash/info")
self.refreshTrash()
self.placesBtnHolder.pack_start(self.trashButton, False, False, 0)
self.mintMenuWin.setTooltip(self.trashButton, _("Browse deleted files"))
@ -247,8 +248,8 @@ class pluginclass(object):
trashMenu.popup(None, None, None, None, 3, 0)
def emptyTrash(self, menu, widget):
os.system("rm -rf " + home + "/.local/share/Trash/info/*")
os.system("rm -rf " + home + "/.local/share/Trash/files/*")
shutil.rmtree(self.trash_info)
shutil.rmtree(self.trash_files)
self.trashButton.setIcon("user-trash")
def ButtonClicked(self, widget, Exec):
@ -262,7 +263,7 @@ class pluginclass(object):
self.do_gtk_bookmarks()
def refreshTrash(self):
if os.path.exists(self.trash_path) and glob(os.path.join(self.trash_path, "*")):
if os.path.isdir(self.trash_info) and os.listdir(self.trash_info):
iconName = "user-trash-full"
else:
iconName = "user-trash"

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import os
import subprocess
@ -173,7 +173,7 @@ class pluginclass:
self.Win.hide()
try:
subprocess.check_call(["xdg-open", filename])
subprocess.run(["xdg-open", filename], check=True)
except subprocess.CalledProcessError:
dialog = Gtk.MessageDialog(self.window, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("The file or location could not be opened."))

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import os

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
import threading
@ -56,7 +56,6 @@ class PointerMonitor(GObject.GObject, threading.Thread):
pdevice = Gdk.Display.get_default().get_device_manager().get_client_pointer()
p = self.get_window().get_device_position(pdevice)
g = self.get_size()
if p.x >= 0 and p.y >= 0 and p.x <= g.width and p.y <= g.height:
break
else: