forked from vivien/i3blocks-contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aur-update
executable file
·128 lines (101 loc) · 3.91 KB
/
aur-update
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python3
# List available updates from the Arch User Repository (AUR)
# Copyright 2018 Johannes Lange
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty 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, see <http://www.gnu.org/licenses/>.
import json
import os
import requests
import subprocess as sp
block_button = os.environ['BLOCK_BUTTON'] if 'BLOCK_BUTTON' in os.environ else None
block_button = int(block_button) if block_button else None
class Args(object):
def add_argument(self, name, default='', arg_type=str):
val = default
if name in os.environ:
val = os.environ[name]
if arg_type == list:
val = val.split()
val = arg_type(val)
setattr(self, name.lower(), val)
return val
args = Args()
args.add_argument('UPDATE_COLOR', 'yellow')
args.add_argument('QUIET', False, bool)
args.add_argument('IGNORE', [], list)
args.add_argument('CACHE_UPDATES', False, bool)
def version_in_aur(pkg):
p = {'v': '5', 'type': 'search', 'by': 'name', 'arg': pkg}
response = requests.get('https://aur.archlinux.org/rpc/', params=p)
response = response.json()
for r in response['results']:
if r['Name'] == pkg:
return r['Version']
return "NotFound"
def vcs_version(pkg, ver):
""" Try to find a sensble version for VSC packages
If pkg looks like a VCS package according to
https://wiki.archlinux.org/index.php/VCS_package_guidelines
try to extract a sensible (= comparable) version number.
"""
suffices = ['-cvs', '-svn', '-hg', '-darcs', '-bzr', '-git']
if not any(pkg.endswith(suffix) for suffix in suffices):
# does not look like a VCS package
return ver
if '.r' in ver:
# of the form RELEASE.rREVISION: only use the release
return ver.split('.r')[0]
# no base release to compare, just return None
return None
# show the list of updates already cached
if args.cache_updates and block_button in [2, 3]:
if '_update_cache' in os.environ:
updates = os.environ['_update_cache']
else:
updates = 'no updates cached'
sp.call(['notify-send', 'AUR updates', updates or 'up to date'])
# get list of foreign packages -- assumed to be from the AUR
packages = sp.check_output(['pacman', '-Qm']).decode('utf8')
installed_version = {}
for pkg in packages.split('\n'):
if not pkg:
continue
pkg, ver = pkg.split()
installed_version[pkg] = ver
updates = []
for pkg in installed_version.keys():
if pkg in args.ignore:
continue
v_aur = version_in_aur(pkg)
v_inst = installed_version[pkg]
if vcs_version(pkg, v_aur) != vcs_version(pkg, v_inst):
updates.append(pkg + ' (%s -> %s)' % (v_inst, v_aur))
# create the message for the block
n_updates = len(updates)
if n_updates > 0:
msg = "<span color='{0}'>{1} AUR updates</span>".format(args.update_color, n_updates)
elif not args.quiet:
msg = 'AUR up to date'
# turn it into a json message
msg = {'full_text': msg}
# cache the new updates list
if args.cache_updates:
msg['_update_cache'] = '\n'.join(updates)
print(json.dumps(msg))
# if you don't use caching, show the new list of updates
if not args.cache_updates and block_button in [2, 3]:
sp.call(['notify-send', 'AUR updates', '\n'.join(updates) or 'up to date'])
if not 'BLOCK_NAME' in os.environ and n_updates > 0:
# not called by i3blocks: show the complete list
print('\n'.join(updates))