0001-Added-PiSi-support-back.patch 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. From: Berk Cakar <berk2238@hotmail.com>
  2. Date: Thu, 24 Jun 2021 00:01:23 +0300
  3. Subject: [PATCH] Added PiSi support back
  4. ---
  5. backends/pisi/meson.build | 21 ++
  6. backends/pisi/pisiBackend.py | 632 ++++++++++++++++++++++++++++++++
  7. backends/pisi/pk-backend-pisi.c | 369 +++++++++++++++++++
  8. meson_options.txt | 2 +-
  9. 4 files changed, 1023 insertions(+), 1 deletion(-)
  10. create mode 100644 backends/pisi/meson.build
  11. create mode 100644 backends/pisi/pisiBackend.py
  12. create mode 100644 backends/pisi/pk-backend-pisi.c
  13. diff --git a/backends/pisi/meson.build b/backends/pisi/meson.build
  14. new file mode 100644
  15. index 000000000..71236ad11
  16. --- /dev/null
  17. +++ b/backends/pisi/meson.build
  18. @@ -0,0 +1,21 @@
  19. +shared_module(
  20. + 'pk_backend_pisi',
  21. + 'pk-backend-pisi.c',
  22. + include_directories: packagekit_src_include,
  23. + dependencies: [
  24. + packagekit_glib2_dep,
  25. + gmodule_dep,
  26. + ],
  27. + c_args: [
  28. + '-DPK_COMPILATION',
  29. + '-DG_LOG_DOMAIN="PackageKit-Pisi"',
  30. + ],
  31. + install: true,
  32. + install_dir: pk_plugin_dir,
  33. +)
  34. +
  35. +install_data(
  36. + 'pisiBackend.py',
  37. + install_dir: join_paths(get_option('datadir'), 'PackageKit', 'helpers', 'pisi'),
  38. + install_mode: 'rwxr--r--',
  39. +)
  40. diff --git a/backends/pisi/pisiBackend.py b/backends/pisi/pisiBackend.py
  41. new file mode 100644
  42. index 000000000..f9c19eeaf
  43. --- /dev/null
  44. +++ b/backends/pisi/pisiBackend.py
  45. @@ -0,0 +1,632 @@
  46. +#!/usr/bin/python
  47. +# -*- coding: utf-8 -*-
  48. +#
  49. +# Licensed under the GNU General Public License Version 2
  50. +#
  51. +# This program is free software; you can redistribute it and/or modify
  52. +# it under the terms of the GNU General Public License as published by
  53. +# the Free Software Foundation; either version 2 of the License, or
  54. +# (at your option) any later version.
  55. +#
  56. +# This program is distributed in the hope that it will be useful,
  57. +# but WITHOUT ANY WARRANTY; without even the implied warranty of
  58. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  59. +# GNU General Public License for more details.
  60. +#
  61. +# You should have received a copy of the GNU General Public License
  62. +# along with this program; if not, write to the Free Software
  63. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  64. +#
  65. +# Copyright (C) 2007 S.Çağlar Onur <caglar@pardus.org.tr>
  66. +# Copyright (C) 2013 Ikey Doherty <ikey@solusos.com>
  67. +# Copyright (C) 2021 Berk Çakar <berk2238@hotmail.com>
  68. +
  69. +# Notes to PiSi based distribution maintainers
  70. +# /etc/PackageKit/pisi.conf must contain a mapping of PiSi component to
  71. +# PackageKit groups for correct operation, i.e.
  72. +# system.utils = system
  73. +# desktop.gnome = desktop-gnome
  74. +# If you have a BTS you must also provide Bug-Regex and Bug-URI fields, i.e:
  75. +# Bug-Regex = Bug-SolusOS: T(\d+)
  76. +# Bug-URI = http://inf.solusos.com/T%s
  77. +# We use simple python string formatting to replace the %s with the first
  78. +# matched group in the regular expression. So in the example above, we expect
  79. +# to see "Bug-SolusOS: T9" for example, on its own line in a package update
  80. +# comment.
  81. +
  82. +import pisi
  83. +import pisi.ui
  84. +from packagekit.backend import *
  85. +from packagekit.package import PackagekitPackage
  86. +from packagekit import enums
  87. +import os.path
  88. +import piksemel
  89. +import re
  90. +
  91. +class SimplePisiHandler(pisi.ui.UI):
  92. +
  93. + def __init(self):
  94. + pisi.ui.UI.__init__(self, False, False)
  95. +
  96. + def display_progress(self, **ka):
  97. + self.the_callback(**ka)
  98. +
  99. +
  100. +class PackageKitPisiBackend(PackageKitBaseBackend, PackagekitPackage):
  101. +
  102. + SETTINGS_FILE = "/etc/PackageKit/pisi.conf"
  103. +
  104. + def __init__(self, args):
  105. + self.bug_regex = None
  106. + self.bug_uri = None
  107. + self._load_settings()
  108. + PackageKitBaseBackend.__init__(self, args)
  109. +
  110. + self.componentdb = pisi.db.componentdb.ComponentDB()
  111. + # self.filesdb = pisi.db.filesdb.FilesDB()
  112. + self.installdb = pisi.db.installdb.InstallDB()
  113. + self.packagedb = pisi.db.packagedb.PackageDB()
  114. + self.repodb = pisi.db.repodb.RepoDB()
  115. +
  116. + # Do not ask any question to users
  117. + self.options = pisi.config.Options()
  118. + self.options.yes_all = True
  119. +
  120. + self.saved_ui = pisi.context.ui
  121. +
  122. + def _load_settings(self):
  123. + """ Load the PK Group-> PiSi component mapping """
  124. + if os.path.exists(self.SETTINGS_FILE):
  125. + with open(self.SETTINGS_FILE, "r") as mapping:
  126. + self.groups = {}
  127. + for line in mapping.readlines():
  128. + line = line.replace("\r", "").replace("\n", "").strip()
  129. + if line.strip() == "" or "#" in line:
  130. + continue
  131. +
  132. + splits = line.split("=")
  133. + key = splits[0].strip()
  134. + value = splits[1].strip()
  135. +
  136. + # Check if this contains our bug keys
  137. + if key == "Bug-Regex":
  138. + self.bug_regex = re.compile(value)
  139. + continue
  140. + if key == "Bug-URI":
  141. + self.bug_uri = value
  142. + continue
  143. + self.groups[key] = value
  144. + else:
  145. + self.groups = {}
  146. +
  147. + def __get_package_version(self, package):
  148. + """ Returns version string of given package """
  149. + # Internal FIXME: PiSi may provide this
  150. + if package.build is not None:
  151. + version = "%s-%s-%s" % (package.version, package.release,
  152. + package.build)
  153. + else:
  154. + version = "%s-%s" % (package.version, package.release)
  155. + return version
  156. +
  157. + def __get_package(self, package, filters=None):
  158. + """ Returns package object suitable for other methods """
  159. + if self.installdb.has_package(package):
  160. + status = INFO_INSTALLED
  161. + pkg = self.installdb.get_package(package)
  162. + elif self.packagedb.has_package(package):
  163. + status = INFO_AVAILABLE
  164. + pkg = self.packagedb.get_package(package)
  165. + else:
  166. + self.error(ERROR_PACKAGE_NOT_FOUND, "Package was not found")
  167. +
  168. + if filters:
  169. + if "none" not in filters:
  170. + if FILTER_INSTALLED in filters and status != INFO_INSTALLED:
  171. + return
  172. + if FILTER_NOT_INSTALLED in filters and status == INFO_INSTALLED:
  173. + return
  174. + if FILTER_GUI in filters and "app:gui" not in pkg.isA:
  175. + return
  176. + if FILTER_NOT_GUI in filters and "app:gui" in pkg.isA:
  177. + return
  178. +
  179. + version = self.__get_package_version(pkg)
  180. +
  181. + id = self.get_package_id(pkg.name, version, pkg.architecture, "")
  182. +
  183. + return self.package(id, status, pkg.summary)
  184. +
  185. + def depends_on(self, filters, package_ids, recursive):
  186. + """ Prints a list of depends for a given package """
  187. + self.allow_cancel(True)
  188. + self.percentage(None)
  189. +
  190. + package = self.get_package_from_id(package_ids[0])[0]
  191. +
  192. + for pkg in self.packagedb.get_package(package).runtimeDependencies():
  193. + # FIXME: PiSi API has really inconsistent for return types
  194. + # and arguments!
  195. + self.__get_package(pkg.package)
  196. +
  197. + def get_details(self, package_ids):
  198. + """ Prints a detailed description for a given package """
  199. + self.allow_cancel(True)
  200. + self.percentage(None)
  201. +
  202. + package = self.get_package_from_id(package_ids[0])[0]
  203. +
  204. + if self.packagedb.has_package(package):
  205. + pkg = self.packagedb.get_package(package)
  206. + repo = self.packagedb.get_package_repo(pkg.name, None)
  207. + pkg_id = self.get_package_id(pkg.name,
  208. + self.__get_package_version(pkg),
  209. + pkg.architecture, repo[1])
  210. +
  211. + if pkg.partOf in self.groups:
  212. + group = self.groups[pkg.partOf]
  213. + else:
  214. + group = GROUP_UNKNOWN
  215. +
  216. + homepage = pkg.source.homepage if pkg.source.homepage is not None\
  217. + else ''
  218. +
  219. + self.details(pkg_id, '', ",".join(pkg.license), group, pkg.description,
  220. + homepage, pkg.packageSize)
  221. + else:
  222. + self.error(ERROR_PACKAGE_NOT_FOUND, "Package was not found")
  223. +
  224. + def get_files(self, package_ids):
  225. + """ Prints a file list for a given package """
  226. + self.allow_cancel(True)
  227. + self.percentage(None)
  228. +
  229. + package = self.get_package_from_id(package_ids[0])[0]
  230. +
  231. + if self.installdb.has_package(package):
  232. + pkg = self.packagedb.get_package(package)
  233. + repo = self.packagedb.get_package_repo(pkg.name, None)
  234. + pkg_id = self.get_package_id(pkg.name,
  235. + self.__get_package_version(pkg),
  236. + pkg.architecture, repo[1])
  237. +
  238. + pkg = self.installdb.get_files(package)
  239. +
  240. + files = map(lambda y: "/%s" % y.path, pkg.list)
  241. +
  242. + file_list = ";".join(files)
  243. + self.files(pkg_id, file_list)
  244. +
  245. + def get_repo_list(self, filters):
  246. + """ Prints available repositories """
  247. + self.allow_cancel(True)
  248. + self.percentage(None)
  249. +
  250. + for repo in pisi.api.list_repos():
  251. + # Internal FIXME: What an ugly way to get repo uri
  252. + # FIXME: Use repository enabled/disabled state
  253. + uri = self.repodb.get_repo(repo).indexuri.get_uri()
  254. + self.repo_detail(repo, uri, True)
  255. +
  256. + def required_by(self, filters, package_ids, recursive):
  257. + """ Prints a list of requires for a given package """
  258. + self.allow_cancel(True)
  259. + self.percentage(None)
  260. +
  261. + package = self.get_package_from_id(package_ids[0])[0]
  262. +
  263. + # FIXME: Handle packages which is not installed from repository
  264. + for pkg in self.packagedb.get_rev_deps(package):
  265. + self.__get_package(pkg[0])
  266. +
  267. + def get_updates(self, filter):
  268. + """ Prints available updates and types """
  269. + self.allow_cancel(True)
  270. + self.percentage(None)
  271. +
  272. + self._updates = dict()
  273. + for package in pisi.api.list_upgradable():
  274. + pkg = self.packagedb.get_package(package)
  275. + version = self.__get_package_version(pkg)
  276. + id = self.get_package_id(pkg.name, version, pkg.architecture, "")
  277. + installed_package = self.installdb.get_package(package)
  278. +
  279. + repo = self.packagedb.get_package_repo(pkg.name, None)[1]
  280. + pindex = "/var/lib/pisi/index/%s/pisi-index.xml" % repo
  281. +
  282. + self._updates[pkg.name] = \
  283. + self._extract_update_details(pindex, pkg.name)
  284. + bug_uri = self._updates[pkg.name][3]
  285. +
  286. + # FIXME: PiSi must provide this information as a single API call :(
  287. + updates = [i for i in self.packagedb.get_package(package).history
  288. + if pisi.version.Version(i.release) >
  289. + installed_package.release]
  290. + if pisi.util.any(lambda i: i.type == "security", updates):
  291. + self.package(id, INFO_SECURITY, pkg.summary)
  292. + elif bug_uri != "":
  293. + self.package(id, INFO_BUGFIX, pkg.summary)
  294. + else:
  295. + self.package(id, INFO_NORMAL, pkg.summary)
  296. +
  297. + def _extract_update_details(self, pindex, package_name):
  298. + document = piksemel.parse(pindex)
  299. + packages = document.tags("Package")
  300. + for pkg in packages:
  301. + if pkg.getTagData("Name") == package_name:
  302. + history = pkg.getTag("History")
  303. + update = history.tags("Update")
  304. + update_message = "Updated"
  305. + update_release = 0
  306. + update_date = ""
  307. + needsReboot = False
  308. + bugURI = ""
  309. + for update in update:
  310. + if int(update.getAttribute("release")) > update_release:
  311. + update_release = int(update.getAttribute("release"))
  312. + # updater = update.getTagData("Name")
  313. + update_message = update.getTagData("Comment")
  314. + update_message = update_message.replace("\n", ";")
  315. + update_date = update.getTagData("Date")
  316. + needsReboot = False
  317. + try:
  318. + requires = update.getTag("Requires")
  319. + action = requires.getTagData("Action")
  320. + if action == "systemRestart":
  321. + needsReboot = True
  322. + except Exception:
  323. + pass
  324. + # Determine if this is a bug fix
  325. + for line in update_message.split(";"):
  326. + m = self.bug_regex.match(line)
  327. + if m is not None:
  328. + bugURI = self.bug_uri % m.group(1)
  329. + break
  330. + return (update_message, update_date, needsReboot, bugURI)
  331. + pkg = pkg.nextTag("Package")
  332. + return("Log not found", "", False, "")
  333. +
  334. + def get_update_detail(self, package_ids):
  335. + for package_id in package_ids:
  336. + package = self.get_package_from_id(package_id)[0]
  337. + the_package = self.installdb.get_package(package)
  338. + updates = [package_id]
  339. + obsoletes = ""
  340. + # TODO: Add regex matching for #FIXES:ID or something similar
  341. + cve_url = ""
  342. + package_url = the_package.source.homepage
  343. + vendor_url = package_url if package_url is not None else ""
  344. + issued = ""
  345. +
  346. + changelog = ""
  347. + # TODO: Set to security_issued if security update
  348. + issued = updated = ""
  349. + update_message, security_issued, needsReboot, bugURI = \
  350. + self._updates[package]
  351. +
  352. + # TODO: Add tagging to repo's, or a mapping file
  353. + state = UPDATE_STATE_STABLE
  354. + reboot = "system" if needsReboot else "none"
  355. +
  356. + self.update_detail(package_id, updates, obsoletes, vendor_url,
  357. + bugURI, cve_url, reboot, update_message,
  358. + changelog, state, issued, updated)
  359. +
  360. + def download_packages(self, directory, package_ids):
  361. + """ Download the given packages to a directory """
  362. + self.allow_cancel(False)
  363. + self.percentage(None)
  364. + self.status(STATUS_DOWNLOAD)
  365. +
  366. + packages = list()
  367. +
  368. + def progress_cb(**kw):
  369. + self.percentage(int(kw['percent']))
  370. +
  371. + ui = SimplePisiHandler()
  372. + for package_id in package_ids:
  373. + package = self.get_package_from_id(package_id)[0]
  374. + packages.append(package)
  375. + try:
  376. + pkg = self.packagedb.get_package(package)
  377. + except:
  378. + self.error(ERROR_PACKAGE_NOT_FOUND, "Package was not found")
  379. + try:
  380. + pisi.api.set_userinterface(ui)
  381. + ui.the_callback = progress_cb
  382. + if directory is None:
  383. + directory = os.path.curdir
  384. + pisi.api.fetch(packages, directory)
  385. + # Scan for package
  386. + for package in packages:
  387. + package_obj = self.packagedb.get_package(package)
  388. + uri = package_obj.packageURI.split("/")[-1]
  389. + location = os.path.join(directory, uri)
  390. + self.files(package_id, location)
  391. + pisi.api.set_userinterface(self.saved_ui)
  392. + except Exception, e:
  393. + self.error(ERROR_PACKAGE_DOWNLOAD_FAILED,
  394. + "Could not download package: %s" % e)
  395. + self.percentage(None)
  396. +
  397. + def install_files(self, only_trusted, files):
  398. + """ Installs given package into system"""
  399. +
  400. + # FIXME: use only_trusted
  401. +
  402. + # FIXME: install progress
  403. + self.allow_cancel(False)
  404. + self.percentage(None)
  405. +
  406. + def progress_cb(**kw):
  407. + self.percentage(int(kw['percent']))
  408. +
  409. + ui = SimplePisiHandler()
  410. +
  411. + self.status(STATUS_INSTALL)
  412. + pisi.api.set_userinterface(ui)
  413. + ui.the_callback = progress_cb
  414. +
  415. + try:
  416. + self.status(STATUS_INSTALL)
  417. + pisi.api.install(files)
  418. + except pisi.Error, e:
  419. + # FIXME: Error: internal-error : Package re-install declined
  420. + # Force needed?
  421. + self.error(ERROR_PACKAGE_ALREADY_INSTALLED, e)
  422. + pisi.api.set_userinterface(self.saved_ui)
  423. +
  424. + def _report_all_for_package(self, package, remove=False):
  425. + """ Report all deps for the given package """
  426. + if not remove:
  427. + deps = self.packagedb.get_package(package).runtimeDependencies()
  428. + # TODO: Add support to report conflicting packages requiring removal
  429. + #conflicts = self.packagedb.get_package (package).conflicts
  430. + for dep in deps:
  431. + if not self.installdb.has_package(dep.name()):
  432. + dep_pkg = self.packagedb.get_package(dep.name())
  433. + repo = self.packagedb.get_package_repo(dep_pkg.name, None)
  434. + version = self.__get_package_version(dep_pkg)
  435. + pkg_id = self.get_package_id(dep_pkg.name, version,
  436. + dep_pkg.architecture, repo[1])
  437. + self.package(pkg_id, INFO_INSTALLING, dep_pkg.summary)
  438. + else:
  439. + rev_deps = self.installdb.get_rev_deps(package)
  440. + for rev_dep, depinfo in rev_deps:
  441. + if self.installdb.has_package(rev_dep):
  442. + dep_pkg = self.packagedb.get_package(rev_dep)
  443. + repo = self.packagedb.get_package_repo(dep_pkg.name, None)
  444. + version = self.__get_package_version(dep_pkg)
  445. + pkg_id = self.get_package_id(dep_pkg.name, version,
  446. + dep_pkg.architecture, repo[1])
  447. + self.package(pkg_id, INFO_REMOVING, dep_pkg.summary)
  448. +
  449. + def install_packages(self, transaction_flags, package_ids):
  450. + """ Installs given package into system"""
  451. + # FIXME: fetch/install progress
  452. + self.allow_cancel(False)
  453. + self.percentage(None)
  454. +
  455. + packages = list()
  456. +
  457. + # FIXME: use only_trusted
  458. + for package_id in package_ids:
  459. + package = self.get_package_from_id(package_id)[0]
  460. + if self.installdb.has_package(package):
  461. + self.error(ERROR_PACKAGE_NOT_INSTALLED,
  462. + "Package is already installed")
  463. + packages.append(package)
  464. +
  465. + def progress_cb(**kw):
  466. + self.percentage(int(kw['percent']))
  467. +
  468. + ui = SimplePisiHandler()
  469. +
  470. + self.status(STATUS_INSTALL)
  471. + pisi.api.set_userinterface(ui)
  472. + ui.the_callback = progress_cb
  473. +
  474. + if TRANSACTION_FLAG_SIMULATE in transaction_flags:
  475. + # Simulated, not real.
  476. + for package in packages:
  477. + self._report_all_for_package(package)
  478. + return
  479. + try:
  480. + pisi.api.install(packages)
  481. + except pisi.Error, e:
  482. + self.error(ERROR_UNKNOWN, e)
  483. + pisi.api.set_userinterface(self.saved_ui)
  484. +
  485. + def refresh_cache(self, force):
  486. + """ Updates repository indexes """
  487. + # TODO: use force ?
  488. + self.allow_cancel(False)
  489. + self.percentage(0)
  490. + self.status(STATUS_REFRESH_CACHE)
  491. +
  492. + slice = (100 / len(pisi.api.list_repos())) / 2
  493. +
  494. + percentage = 0
  495. + for repo in pisi.api.list_repos():
  496. + pisi.api.update_repo(repo)
  497. + percentage += slice
  498. + self.percentage(percentage)
  499. +
  500. + self.percentage(100)
  501. +
  502. + def remove_packages(self, transaction_flags, package_ids,
  503. + allowdeps, autoremove):
  504. + """ Removes given package from system"""
  505. + self.allow_cancel(False)
  506. + self.percentage(None)
  507. + # TODO: use autoremove
  508. + packages = list()
  509. +
  510. + for package_id in package_ids:
  511. + package = self.get_package_from_id(package_id)[0]
  512. + if not self.installdb.has_package(package):
  513. + self.error(ERROR_PACKAGE_NOT_INSTALLED,
  514. + "Package is not installed")
  515. + packages.append(package)
  516. +
  517. + def progress_cb(**kw):
  518. + self.percentage(int(kw['percent']))
  519. +
  520. + ui = SimplePisiHandler()
  521. +
  522. + package = self.get_package_from_id(package_ids[0])[0]
  523. + self.status(STATUS_REMOVE)
  524. +
  525. + if TRANSACTION_FLAG_SIMULATE in transaction_flags:
  526. + # Simulated, not real.
  527. + for package in packages:
  528. + self._report_all_for_package(package, remove=True)
  529. + return
  530. + try:
  531. + pisi.api.remove(packages)
  532. + except pisi.Error, e:
  533. + self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE, e)
  534. + pisi.api.set_userinterface(self.saved_ui)
  535. +
  536. + def repo_set_data(self, repo_id, parameter, value):
  537. + """ Sets a parameter for the repository specified """
  538. + self.allow_cancel(False)
  539. + self.percentage(None)
  540. +
  541. + if parameter == "add-repo":
  542. + try:
  543. + pisi.api.add_repo(repo_id, value, parameter)
  544. + except pisi.Error, e:
  545. + self.error(ERROR_UNKNOWN, e)
  546. +
  547. + try:
  548. + pisi.api.update_repo(repo_id)
  549. + except pisi.fetcher.FetchError:
  550. + pisi.api.remove_repo(repo_id)
  551. + err = "Could not reach the repository, removing from system"
  552. + self.error(ERROR_REPO_NOT_FOUND, err)
  553. + elif parameter == "remove-repo":
  554. + try:
  555. + pisi.api.remove_repo(repo_id)
  556. + except pisi.Error:
  557. + self.error(ERROR_REPO_NOT_FOUND, "Repository does not exist")
  558. + else:
  559. + self.error(ERROR_NOT_SUPPORTED, "Parameter not supported")
  560. +
  561. + def resolve(self, filters, package):
  562. + """ Turns a single package name into a package_id
  563. + suitable for the other methods """
  564. + self.allow_cancel(True)
  565. + self.percentage(None)
  566. +
  567. + self.__get_package(package[0], filters)
  568. +
  569. + def search_details(self, filters, values):
  570. + """ Prints a detailed list of packages contains search term """
  571. + self.allow_cancel(True)
  572. + self.percentage(None)
  573. + self.status(STATUS_INFO)
  574. +
  575. + # Internal FIXME: Use search_details instead of _package when API
  576. + # gains that ability :)
  577. + for pkg in pisi.api.search_package(values):
  578. + self.__get_package(pkg, filters)
  579. +
  580. + def search_file(self, filters, values):
  581. + """ Prints the installed package which contains the specified file """
  582. + self.allow_cancel(True)
  583. + self.percentage(None)
  584. + self.status(STATUS_INFO)
  585. +
  586. + for value in values:
  587. + # Internal FIXME: Why it is needed?
  588. + value = value.lstrip("/")
  589. +
  590. + for pkg, files in pisi.api.search_file(value):
  591. + self.__get_package(pkg)
  592. +
  593. + def search_group(self, filters, values):
  594. + """ Prints a list of packages belongs to searched group """
  595. + self.allow_cancel(True)
  596. + self.percentage(None)
  597. + self.status(STATUS_INFO)
  598. +
  599. + for value in values:
  600. + packages = list()
  601. + for item in self.groups:
  602. + if self.groups[item] == value:
  603. + try:
  604. + pkgs = self.componentdb.get_packages(item, walk=False)
  605. + packages.extend(pkgs)
  606. + except:
  607. + self.error(ERROR_GROUP_NOT_FOUND,
  608. + "Component %s was not found" % value)
  609. + for pkg in packages:
  610. + self.__get_package(pkg, filters)
  611. +
  612. + def search_name(self, filters, values):
  613. + """ Prints a list of packages contains search term in its name """
  614. + self.allow_cancel(True)
  615. + self.percentage(None)
  616. + self.status(STATUS_INFO)
  617. +
  618. + for value in values:
  619. + for pkg in pisi.api.search_package([value]):
  620. + self.__get_package(pkg, filters)
  621. +
  622. + def update_packages(self, transaction_flags, package_ids):
  623. + """ Updates given package to its latest version """
  624. +
  625. + # FIXME: use only_trusted
  626. +
  627. + # FIXME: fetch/install progress
  628. + self.allow_cancel(False)
  629. + self.percentage(None)
  630. +
  631. + packages = list()
  632. + for package_id in package_ids:
  633. + package = self.get_package_from_id(package_id)[0]
  634. + if not self.installdb.has_package(package):
  635. + self.error(ERROR_PACKAGE_NOT_INSTALLED,
  636. + "Cannot update a package that is not installed")
  637. + packages.append(package)
  638. +
  639. + def progress_cb(**kw):
  640. + self.percentage(int(kw['percent']))
  641. +
  642. + ui = SimplePisiHandler()
  643. + pisi.api.set_userinterface(ui)
  644. + ui.the_callback = progress_cb
  645. +
  646. + if TRANSACTION_FLAG_SIMULATE in transaction_flags:
  647. + for package in packages:
  648. + self._report_all_for_package(package)
  649. + return
  650. + try:
  651. + pisi.api.upgrade(packages)
  652. + except pisi.Error, e:
  653. + self.error(ERROR_UNKNOWN, e)
  654. + pisi.api.set_userinterface(self.saved_ui)
  655. +
  656. + def update_system(self, only_trusted):
  657. + """ Updates all available packages """
  658. + # FIXME: use only_trusted
  659. + # FIXME: fetch/install progress
  660. + self.allow_cancel(False)
  661. + self.percentage(None)
  662. +
  663. + if not len(pisi.api.list_upgradable()) > 0:
  664. + self.error(ERROR_NO_PACKAGES_TO_UPDATE, "System is already up2date")
  665. +
  666. + try:
  667. + pisi.api.upgrade(pisi.api.list_upgradable())
  668. + except pisi.Error, e:
  669. + self.error(ERROR_UNKNOWN, e)
  670. +
  671. +
  672. +def main():
  673. + backend = PackageKitPisiBackend('')
  674. + backend.dispatcher(sys.argv[1:])
  675. +
  676. +if __name__ == "__main__":
  677. + main()
  678. \ No newline at end of file
  679. diff --git a/backends/pisi/pk-backend-pisi.c b/backends/pisi/pk-backend-pisi.c
  680. new file mode 100644
  681. index 000000000..beb2f5836
  682. --- /dev/null
  683. +++ b/backends/pisi/pk-backend-pisi.c
  684. @@ -0,0 +1,369 @@
  685. +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  686. + *
  687. + * Copyright (C) 2007 Richard Hughes <richard@hughsie.com>
  688. + * Copyright (C) 2007 S.Çağlar Onur <caglar@pardus.org.tr>
  689. + *
  690. + * Licensed under the GNU General Public License Version 2
  691. + *
  692. + * This program is free software; you can redistribute it and/or modify
  693. + * it under the terms of the GNU General Public License as published by
  694. + * the Free Software Foundation; either version 2 of the License, or
  695. + * (at your option) any later version.
  696. + *
  697. + * This program is distributed in the hope that it will be useful,
  698. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  699. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  700. + * GNU General Public License for more details.
  701. + *
  702. + * You should have received a copy of the GNU General Public License
  703. + * along with this program; if not, write to the Free Software
  704. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  705. + */
  706. +
  707. +#include <pk-backend.h>
  708. +#include <pk-backend-spawn.h>
  709. +
  710. +static PkBackendSpawn *spawn;
  711. +
  712. +void
  713. +pk_backend_start_job (PkBackend *backend, PkBackendJob *job)
  714. +{
  715. + if (pk_backend_spawn_is_busy (spawn)) {
  716. + pk_backend_job_error_code (job,
  717. + PK_ERROR_ENUM_LOCK_REQUIRED,
  718. + "spawned backend requires lock");
  719. + return;
  720. + }
  721. +}
  722. +
  723. +void
  724. +pk_backend_initialize (GKeyFile *conf, PkBackend *backend)
  725. +{
  726. + g_debug ("backend: initialize");
  727. +
  728. + /* BACKEND MAINTAINER: feel free to remove this when you've
  729. + * added support for ONLY_DOWNLOAD and merged the simulate
  730. + * methods as specified in backends/PORTING.txt */
  731. + /*g_error ("Backend needs to be ported to 0.8.x -- "
  732. + "see backends/PORTING.txt for details"); */
  733. +
  734. + spawn = pk_backend_spawn_new (conf);
  735. + pk_backend_spawn_set_name (spawn, "pisi");
  736. +}
  737. +
  738. +void
  739. +pk_backend_destroy (PkBackend *backend)
  740. +{
  741. + g_debug ("backend: destroy");
  742. + g_object_unref (spawn);
  743. +}
  744. +
  745. +PkBitfield
  746. +pk_backend_get_groups (PkBackend *backend)
  747. +{
  748. + return pk_bitfield_from_enums (
  749. + PK_GROUP_ENUM_ACCESSORIES,
  750. + PK_GROUP_ENUM_EDUCATION,
  751. + PK_GROUP_ENUM_GAMES,
  752. + PK_GROUP_ENUM_INTERNET,
  753. + PK_GROUP_ENUM_OTHER,
  754. + PK_GROUP_ENUM_PROGRAMMING,
  755. + PK_GROUP_ENUM_MULTIMEDIA,
  756. + PK_GROUP_ENUM_SYSTEM,
  757. + PK_GROUP_ENUM_DESKTOP_GNOME,
  758. + PK_GROUP_ENUM_DESKTOP_KDE,
  759. + PK_GROUP_ENUM_DESKTOP_OTHER,
  760. + PK_GROUP_ENUM_PUBLISHING,
  761. + PK_GROUP_ENUM_SERVERS,
  762. + PK_GROUP_ENUM_FONTS,
  763. + PK_GROUP_ENUM_ADMIN_TOOLS,
  764. + PK_GROUP_ENUM_LOCALIZATION,
  765. + PK_GROUP_ENUM_VIRTUALIZATION,
  766. + PK_GROUP_ENUM_SECURITY,
  767. + PK_GROUP_ENUM_POWER_MANAGEMENT,
  768. + PK_GROUP_ENUM_UNKNOWN,
  769. + -1);
  770. +}
  771. +
  772. +PkBitfield
  773. +pk_backend_get_filters (PkBackend *backend)
  774. +{
  775. + return pk_bitfield_from_enums(
  776. + PK_FILTER_ENUM_GUI,
  777. + PK_FILTER_ENUM_INSTALLED,
  778. + -1);
  779. +}
  780. +
  781. +void
  782. +pk_backend_cancel (PkBackend *backend, PkBackendJob *job)
  783. +{
  784. + /* this feels bad... */
  785. + pk_backend_spawn_kill (spawn);
  786. +}
  787. +
  788. +void
  789. +pk_backend_download_packages (PkBackend *backend, PkBackendJob *job, gchar **package_ids, const gchar *directory)
  790. +{
  791. + gchar *package_ids_temp;
  792. +
  793. + /* send the complete list as stdin */
  794. + package_ids_temp = pk_package_ids_to_string (package_ids);
  795. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "download-packages", directory, package_ids_temp, NULL);
  796. + g_free (package_ids_temp);
  797. +}
  798. +
  799. +void
  800. +pk_backend_depends_on (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **package_ids, gboolean recursive)
  801. +{
  802. + gchar *filters_text;
  803. + gchar *package_ids_temp;
  804. + package_ids_temp = pk_package_ids_to_string (package_ids);
  805. + filters_text = pk_filter_bitfield_to_string (filters);
  806. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "depends-on", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
  807. + g_free (filters_text);
  808. + g_free (package_ids_temp);
  809. +}
  810. +
  811. +void
  812. +pk_backend_get_details (PkBackend *backend, PkBackendJob *job, gchar **package_ids)
  813. +{
  814. + gchar *package_ids_temp;
  815. + package_ids_temp = pk_package_ids_to_string (package_ids);
  816. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "get-details", package_ids_temp, NULL);
  817. + g_free (package_ids_temp);
  818. +}
  819. +
  820. +void
  821. +pk_backend_get_files (PkBackend *backend, PkBackendJob *job, gchar **package_ids)
  822. +{
  823. + gchar *package_ids_temp;
  824. + package_ids_temp = pk_package_ids_to_string (package_ids);
  825. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "get-files", package_ids_temp, NULL);
  826. + g_free (package_ids_temp);
  827. +}
  828. +
  829. +void
  830. +pk_backend_required_by (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **package_ids, gboolean recursive)
  831. +{
  832. + gchar *filters_text;
  833. + gchar *package_ids_temp;
  834. + package_ids_temp = pk_package_ids_to_string (package_ids);
  835. + filters_text = pk_filter_bitfield_to_string (filters);
  836. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "required-by", filters_text, package_ids_temp, pk_backend_bool_to_string (recursive), NULL);
  837. + g_free (filters_text);
  838. + g_free (package_ids_temp);
  839. +}
  840. +
  841. +void
  842. +pk_backend_get_updates (PkBackend *backend, PkBackendJob *job, PkBitfield filters)
  843. +{
  844. + gchar *filters_text;
  845. + filters_text = pk_filter_bitfield_to_string (filters);
  846. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "get-updates", filters_text, NULL);
  847. + g_free (filters_text);
  848. +}
  849. +
  850. +void
  851. +pk_backend_get_update_detail (PkBackend *backend, PkBackendJob *job, gchar **package_ids)
  852. +{
  853. + gchar *package_ids_temp;
  854. + package_ids_temp = pk_package_ids_to_string (package_ids);
  855. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "get-update-detail", package_ids_temp, NULL);
  856. + g_free (package_ids_temp);
  857. +}
  858. +
  859. +void
  860. +pk_backend_install_packages (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags, gchar **package_ids)
  861. +{
  862. + gchar *package_ids_temp;
  863. + gchar *transaction_flags_temp;
  864. +
  865. + /* check network state */
  866. + if (!pk_backend_is_online (backend)) {
  867. + pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
  868. + pk_backend_job_finished (job);
  869. + return;
  870. + }
  871. +
  872. + /* send the complete list as stdin */
  873. + package_ids_temp = pk_package_ids_to_string (package_ids);
  874. + transaction_flags_temp = pk_transaction_flag_bitfield_to_string (transaction_flags);
  875. +
  876. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "install-packages", transaction_flags_temp, package_ids_temp, NULL);
  877. + g_free (package_ids_temp);
  878. + g_free (transaction_flags_temp);
  879. +}
  880. +
  881. +void
  882. +pk_backend_install_files (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags, gchar **full_paths)
  883. +{
  884. + gchar *package_ids_temp;
  885. + gchar *transaction_flags_temp;
  886. +
  887. + /* send the complete list as stdin */
  888. + package_ids_temp = g_strjoinv (PK_BACKEND_SPAWN_FILENAME_DELIM, full_paths);
  889. + transaction_flags_temp = pk_transaction_flag_bitfield_to_string (transaction_flags);
  890. +
  891. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "install-files", transaction_flags_temp, package_ids_temp, NULL);
  892. + g_free (package_ids_temp);
  893. + g_free (transaction_flags_temp);
  894. +}
  895. +
  896. +void
  897. +pk_backend_refresh_cache (PkBackend *backend, PkBackendJob *job, gboolean force)
  898. +{
  899. + /* check network state */
  900. + if (!pk_backend_is_online (backend)) {
  901. + pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
  902. + pk_backend_job_finished (job);
  903. + return;
  904. + }
  905. +
  906. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "refresh-cache", pk_backend_bool_to_string (force), NULL);
  907. +}
  908. +
  909. +void
  910. +pk_backend_remove_packages (PkBackend *backend, PkBackendJob *job,
  911. + PkBitfield transaction_flags,
  912. + gchar **package_ids,
  913. + gboolean allow_deps,
  914. + gboolean autoremove)
  915. +{
  916. + gchar *package_ids_temp;
  917. + gchar *transaction_flags_temp;
  918. +
  919. + /* send the complete list as stdin */
  920. + package_ids_temp = pk_package_ids_to_string (package_ids);
  921. + transaction_flags_temp = pk_transaction_flag_bitfield_to_string (transaction_flags);
  922. + pk_backend_spawn_helper (spawn,
  923. + job, "pisiBackend.py",
  924. + "remove-packages",
  925. + transaction_flags_temp,
  926. + package_ids_temp,
  927. + pk_backend_bool_to_string (allow_deps),
  928. + pk_backend_bool_to_string (autoremove),
  929. + NULL);
  930. +
  931. + g_free (transaction_flags_temp);
  932. + g_free (package_ids_temp);
  933. +}
  934. +
  935. +void
  936. +pk_backend_search_details (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values)
  937. +{
  938. + gchar *filters_text;
  939. + gchar *search;
  940. + filters_text = pk_filter_bitfield_to_string (filters);
  941. + search = g_strjoinv ("&", values);
  942. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "search-details", filters_text, search, NULL);
  943. + g_free (search);
  944. + g_free (filters_text);
  945. +}
  946. +
  947. +void
  948. +pk_backend_search_files (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values)
  949. +{
  950. + gchar *filters_text;
  951. + gchar *search;
  952. + filters_text = pk_filter_bitfield_to_string (filters);
  953. + search = g_strjoinv ("&", values);
  954. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "search-file", filters_text, search, NULL);
  955. + g_free (search);
  956. + g_free (filters_text);
  957. +}
  958. +
  959. +void
  960. +pk_backend_search_groups (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values)
  961. +{
  962. + gchar *filters_text;
  963. + gchar *search;
  964. + filters_text = pk_filter_bitfield_to_string (filters);
  965. + search = g_strjoinv ("&", values);
  966. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "search-group", filters_text, search, NULL);
  967. + g_free (search);
  968. + g_free (filters_text);
  969. +}
  970. +
  971. +void
  972. +pk_backend_search_names (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values)
  973. +{
  974. + gchar *filters_text;
  975. + gchar *search;
  976. + filters_text = pk_filter_bitfield_to_string (filters);
  977. + search = g_strjoinv ("&", values);
  978. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "search-name", filters_text, search, NULL);
  979. + g_free (search);
  980. + g_free (filters_text);
  981. +}
  982. +
  983. +void
  984. +pk_backend_update_packages (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags, gchar **package_ids)
  985. +{
  986. + gchar *package_ids_temp;
  987. + gchar *transaction_flags_temp;
  988. +
  989. + /* check network state */
  990. + if (!pk_backend_is_online (backend)) {
  991. + pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot install when offline");
  992. + pk_backend_job_finished (job);
  993. + return;
  994. + }
  995. +
  996. + /* send the complete list as stdin */
  997. + package_ids_temp = pk_package_ids_to_string (package_ids);
  998. + transaction_flags_temp = pk_transaction_flag_bitfield_to_string (transaction_flags);
  999. +
  1000. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "update-packages", transaction_flags_temp, package_ids_temp, NULL);
  1001. + g_free (package_ids_temp);
  1002. + g_free (transaction_flags_temp);
  1003. +}
  1004. +
  1005. +void
  1006. +pk_backend_update_system (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags)
  1007. +{
  1008. + gchar *transaction_flags_temp;
  1009. + transaction_flags_temp = pk_transaction_flag_bitfield_to_string (transaction_flags);
  1010. +
  1011. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "update-system", transaction_flags_temp, NULL);
  1012. +
  1013. + g_free (transaction_flags_temp);
  1014. +}
  1015. +
  1016. +void
  1017. +pk_backend_resolve (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **package_ids)
  1018. +{
  1019. + gchar *filters_text;
  1020. + gchar *package_ids_temp;
  1021. + filters_text = pk_filter_bitfield_to_string (filters);
  1022. + package_ids_temp = pk_package_ids_to_string (package_ids);
  1023. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "resolve", filters_text, package_ids_temp, NULL);
  1024. + g_free (filters_text);
  1025. + g_free (package_ids_temp);
  1026. +}
  1027. +
  1028. +void
  1029. +pk_backend_get_repo_list (PkBackend *backend, PkBackendJob *job, PkBitfield filters)
  1030. +{
  1031. + gchar *filters_text;
  1032. + filters_text = pk_filter_bitfield_to_string (filters);
  1033. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "get-repo-list", filters_text, NULL);
  1034. + g_free (filters_text);
  1035. +}
  1036. +
  1037. +void
  1038. +pk_backend_repo_set_data (PkBackend *backend, PkBackendJob *job, const gchar *rid, const gchar *parameter, const gchar *value)
  1039. +{
  1040. + pk_backend_spawn_helper (spawn, job, "pisiBackend.py", "repo-set-data", rid, parameter, value, NULL);
  1041. +}
  1042. +
  1043. +const gchar *
  1044. +pk_backend_get_description (PkBackend *backend)
  1045. +{
  1046. + return "PiSi - Packages Installed Successfully as Intended";
  1047. +}
  1048. +
  1049. +const gchar *
  1050. +pk_backend_get_author (PkBackend *backend)
  1051. +{
  1052. + return "S.Çağlar Onur <caglar@pardus.org.tr>\nIkey Doherty <ikey@solusos.com>\nBerk Çakar <berk2238@hotmail.com>";
  1053. +}
  1054. diff --git a/meson_options.txt b/meson_options.txt
  1055. index 2f3a1dac9..7623dc9c2 100644
  1056. --- a/meson_options.txt
  1057. +++ b/meson_options.txt
  1058. @@ -1,4 +1,4 @@
  1059. -option('packaging_backend', type : 'array', choices : ['alpm', 'aptcc', 'dnf', 'dummy', 'entropy', 'poldek', 'portage', 'slack', 'zypp', 'nix'], value : ['dummy'], description : 'The name of the backend to use')
  1060. +option('packaging_backend', type : 'array', choices : ['alpm', 'aptcc', 'dnf', 'dummy', 'entropy', 'pisi', 'poldek', 'portage', 'slack', 'zypp', 'nix'], value : ['dummy'], description : 'The name of the backend to use')
  1061. option('dnf_vendor', type : 'combo', choices : ['fedora', 'mageia', 'openmandriva', 'rosa', 'opensuse'], value : 'fedora', description : 'Vendor configuration when using the dnf backend')
  1062. option('systemd', type : 'boolean', value : true, description : 'Use systemd and logind')
  1063. option('systemdsystemunitdir', type : 'string', value : '', description : 'Directory for systemd service files')
  1064. --
  1065. 2.24.3 (Apple Git-128)