File indexing completed on 2024-05-12 04:58:40

0001 # ============================================================
0002 # RunAction plugin for Falkon
0003 # Copyright (C) 2018 David Rosca <nowrep@gmail.com>
0004 #
0005 # This program is free software: you can redistribute it and/or modify
0006 # it under the terms of the GNU General Public License as published by
0007 # the Free Software Foundation, either version 3 of the License, or
0008 # (at your option) any later version.
0009 #
0010 # This program is distributed in the hope that it will be useful,
0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 # GNU General Public License for more details.
0014 #
0015 # You should have received a copy of the GNU General Public License
0016 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 # ============================================================
0018 import Falkon
0019 import os
0020 import re
0021 import enum
0022 import shlex
0023 from PySide6 import QtCore, QtGui
0024 
0025 
0026 class Action():
0027     class Type(enum.Enum):
0028         Invalid, Url, Command = range(3)
0029 
0030     class TypeCondition(enum.Enum):
0031         Page, Link, Image, Media, Text = range(5)
0032 
0033     id = ""
0034     title = ""
0035     menuTitle = ""
0036     icon = QtGui.QIcon()
0037     actionType = Type.Invalid
0038     typeCondition = [ TypeCondition.Page, TypeCondition.Link, TypeCondition.Image, TypeCondition.Media ]
0039     urlCondition = ".*"
0040     submenu = ""
0041     normalExec = ""
0042     textExec = ""
0043     supported = False
0044 
0045     def __init__(self, fileName):
0046         data = Falkon.DesktopFile(fileName)
0047         self.id = os.path.splitext(os.path.basename(fileName))[0]
0048         self.title = data.name()
0049         self.menuTitle = data.comment()
0050         self.icon = QtGui.QIcon.fromTheme(data.icon(), QtGui.QIcon(os.path.join(os.path.dirname(fileName), data.icon())))
0051         self.actionType = Action.Type[data.value("X-RunAction-Type")]
0052         self.typeCondition = list(map(lambda s: Action.TypeCondition[s], data.value("X-RunAction-TypeCondition").split(";")))
0053         self.urlCondition = data.value("X-RunAction-UrlCondition") or self.urlCondition
0054         self.submenu = data.value("X-RunAction-Submenu") or self.submenu
0055         self.normalExec = data.value("X-RunAction-Exec") or self.normalExec
0056         self.textExec = data.value("X-RunAction-TextExec") or self.normalExec
0057         self.supported = data.tryExec()
0058 
0059     def testAction(self, condition, url):
0060         if not self.supported:
0061             return False
0062         if condition not in self.typeCondition:
0063             return False
0064         if not re.match(self.urlCondition, url.toString()):
0065             return False
0066         return True
0067 
0068     def execAction(self, url, text=""):
0069         url = str(url.toEncoded(), "utf-8")
0070         if self.actionType == Action.Type.Command:
0071             url = shlex.quote(url)
0072             text = shlex.quote(text)
0073         elif self.actionType == Action.Type.Url:
0074             url = str(QtCore.QUrl.toPercentEncoding(url), "utf-8")
0075             text = str(QtCore.QUrl.toPercentEncoding(text), "utf-8")
0076         command = self.normalExec if text == "" else self.textExec
0077         command = command.replace("{url}", url)
0078         command = command.replace("{text}", text)
0079         command = command.replace("{lang}", QtCore.QLocale.system().name()[:2])
0080         return command