Skip to content

Commit

Permalink
Merge pull request #53 from TingPing/archlinux
Browse files Browse the repository at this point in the history
Add initial support for Archlinux
  • Loading branch information
FrostyX committed Feb 13, 2016
2 parents cf5619a + c9cddac commit 7c672e3
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Tracer determines which applications use outdated files and prints them. For spe
Please see [User Guide](http://docs.tracer-package.com/en/latest/user-guide/)

## Requirements
- Supported linux distribution - There are currently supported [Fedora](http://fedoraproject.org/), [Gentoo](http://www.gentoo.org/) and [Debian](https://www.debian.org/)
- Supported linux distribution - There are currently supported [Fedora](http://fedoraproject.org/), [Gentoo](http://www.gentoo.org/), [Debian](https://www.debian.org/), and [Arch](https://archlinux.org)
- Python interpreter
- Python [psutil](https://code.google.com/p/psutil/) module. Available [here](https://admin.fedoraproject.org/pkgdb/acls/name/python-psutil) and [here](https://packages.gentoo.org/package/dev-python/psutil).
- Python [beautifulsoup](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) module. Available [here](https://admin.fedoraproject.org/pkgdb/acls/name/python-beautifulsoup4) and [here](https://packages.gentoo.org/package/dev-python/beautifulsoup)
Expand Down
7 changes: 7 additions & 0 deletions doc/source/get-tracer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ So far I have ``tracer.ebuild`` in my `personal overlay`_. Please take note that
layman -a frostyx
emerge tracer


ArchLinux
---------

An unofficial tracer package can be found in the `AUR`_: https://aur.archlinux.org/packages/tracer

Git
---

Expand Down Expand Up @@ -73,3 +79,4 @@ Previous paragraph can be done by running
.. _F20: https://copr.fedoraproject.org/coprs/frostyx/tracer/repo/fedora-20-i386/frostyx-tracer-fedora-20-i386.repo
.. _personal overlay: https://github.com/frostyx/gentoo-overlay
.. _requirements: https://github.com/FrostyX/tracer#requirements
.. _AUR: https://wiki.archlinux.org/index.php/Arch_User_Repository
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
'tracer.packageManagers',
'tracer.resources',
'tracer.views',
'tracer.views.resource',
'data',
],

Expand Down
37 changes: 37 additions & 0 deletions tests/test_alpm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from .__meta__ import *
try:
from tracer.packageManagers.ipackageManager import IPackageManager
from tracer.packageManagers.alpm import Alpm
except ImportError: pass

@unittest.skipIf(DISTRO != "arch", "Skipping tests because they are distro-specific")
class TestAlpm(unittest.TestCase):
def setUp(self):
self.manager = Alpm()

def test_implements_package_manager_interface(self):
self.assertIsInstance(self.manager, IPackageManager, "Every package manager should inherit from IPackageManager")

def test_package_newer_than_implemented(self):
try: self.manager.packages_newer_than(0)
except NotImplementedError: self.fail("packages_newer_than() is not implemented!")
except Exception: pass

def test_load_package_info(self):
try: self.manager.load_package_info("")
except NotImplementedError: self.fail("load_package_info() is not implemented!")
except Exception: pass

def test_package_files_implemented(self):
try: self.manager.package_files("")
except NotImplementedError: self.fail("packages_files() is not implemented!")
except Exception: pass

def test_provided_by(self):
try: self.manager.provided_by("")
except NotImplementedError: self.fail("provided_by() is not implemented!")
except Exception: pass


if __name__ == '__main__':
unittest.main()
5 changes: 4 additions & 1 deletion tracer/controllers/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ def render_system(self):
uptime = datetime.now() - datetime.fromtimestamp(System.boot_time())
uptime = str(uptime).split('.')[0]

users = set([user.name for user in psutil.get_users()])
try:
users = set([user.name for user in psutil.get_users()])
except AttributeError:
users = set([user.name for user in psutil.users()])
package_managers = System.package_manager().names()

view = SystemView()
Expand Down
103 changes: 103 additions & 0 deletions tracer/packageManagers/alpm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#-*- coding: utf-8 -*-
# alpm.py
#
# Copyright (C) 2016 Patrick Griffis <tingping@tingping.se>
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details. You should have received a copy of the
# GNU General Public License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#

from __future__ import absolute_import

from tracer.resources.system import System
if System.distribution() in ["arch"]:

import bisect
from .ipackageManager import IPackageManager
from tracer.resources.package import Package
from tracer.resources.collections import PackagesCollection
from tracer.resources.applications import Applications
import pyalpm

class Alpm(IPackageManager):

def __init__(self, *args, **kwargs):
self.opts = kwargs
self.handle = pyalpm.Handle('/', '/var/lib/pacman')
self.db = self.handle.get_localdb()

def packages_newer_than(self, unix_time):
"""
Returns list of packages which were modified between unix_time and present
"""
new_pkgs = PackagesCollection()
for pkg in self.db.pkgcache:
if pkg.installdate > unix_time:
new_pkgs.append(Package(pkg.name, pkg.installdate))

return new_pkgs

def package_files(self, pkg_name):
"""
Returns list of files provided by package
"""
pkg = self.db.get_pkg(pkg_name)
if not pkg:
return []

return ['/' + f[0] for f in pkg.files]

def load_package_info(self, package):
"""
From database load informations about given package and set them to it
"""
if not package:
return

pkg = self.db.get_pkg(package.name)
if not pkg:
return

package.description = pkg.desc
package.modified = pkg.installdate
# Don't have categories

def provided_by(self, app_name):
"""
Returns name of package which provides given application
"""
# We need a full path to the binary
process = Applications.find(app_name).instances[0]
return self._file_provided_by(process.exe)

@staticmethod
def _bsearch_list(l, item):
"""
Searches a sorted list, returns True if found
"""
i = bisect.bisect_left(l, item)
if i != len(l) and l[i] == item:
return True
else:
return False

def _file_provided_by(self, file_name):
"""
Returns name of package which provides given file
"""
# This is a bit slow
for pkg in self.db.pkgcache:
files = [f[0] for f in pkg.files]
if self._bsearch_list(files, file_name[1:]):
return Package(pkg.name, pkg.installdate)
else:
return None

5 changes: 4 additions & 1 deletion tracer/resources/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ def _append_application(default_attrs, specific_attrs={}):
@staticmethod
def _helper(app):
if app.type == Applications.TYPES["DAEMON"]:
return "service {0} restart".format(app.name)
if System.init_system() == "systemd" and System.distribution() == "arch":
return "systemctl restart {0}".format(app.name)
else:
return "service {0} restart".format(app.name)

elif app.type == Applications.TYPES["STATIC"]:
return _("You will have to reboot your computer")
Expand Down
12 changes: 8 additions & 4 deletions tracer/resources/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ def distribution():
if os.path.isfile("/etc/os-release"):
with open("/etc/os-release") as os_release_file:
os_release_data = {}
for line in os_release_file:
os_release_key, os_release_value = line.rstrip().split("=")
os_release_data[os_release_key] = os_release_value.strip('"')

# Remove empty lines and trailing spaces
lines = [line.rstrip() for line in os_release_file if line.rstrip()]
for line in lines:
os_release_key, os_release_value = line.split("=")
os_release_data[os_release_key] = os_release_value.strip('"')
return os_release_data["ID"]
else:
return platform.linux_distribution(full_distribution_name=False)[0]
Expand All @@ -63,6 +66,7 @@ def get_instance(pair):
"debian": [("tracer.packageManagers.dpkg", "Dpkg")],
"centos": [("tracer.packageManagers.yum", "Yum")],
"mageia": [("tracer.packageManagers.dnf", "Dnf")],
"arch": [("tracer.packageManagers.alpm", "Alpm")],
"fedora": [
("tracer.packageManagers.dnf", "Dnf"),
("tracer.packageManagers.yum", "Yum"),
Expand All @@ -73,7 +77,7 @@ def get_instance(pair):
if distro not in managers:
return None

return PackageManager(*map(get_instance, managers[distro]))
return PackageManager(*list(map(get_instance, managers[distro])))

@staticmethod
def init_system():
Expand Down
2 changes: 1 addition & 1 deletion tracer/views/resource/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ def render(self):
print(line.format("Application", "Type", "Ignore", "Helper"))
print(120 * "-")
for application in self.args.applications:
print(line.format(application.name, application.type, application.ignore, application.helper))
print(line.format(application.name, application.type, application.ignore, application.helper or ""))

0 comments on commit 7c672e3

Please sign in to comment.