vappman 0.4__tar.gz → 0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vappman
3
- Version: 0.4
3
+ Version: 0.6
4
4
  Summary: A visual wrapper for appman
5
5
  Author-email: Joe Defen <joedef@google.com>
6
6
  License: MIT
@@ -22,20 +22,41 @@ Requires-Dist: psutil>=5.9
22
22
  * Install `vappman` using `pipx install vappman`, or however you do so.
23
23
  * Prerequisites: install [ivan-hc/AppMan: AppImage package manager to install, update (for real) and manage ALL of them locally thanks to "AM", the ever-growing AUR-inspired database listing (for now) 1900+ portable apps and programs for GNU/Linux. Manage your AppImages with the ease of APT and the power of PacMan.](https://github.com/ivan-hc/AppMan) and all of its prerequisites.
24
24
 
25
- NOTE: `vappman` is in a very preliminary state,
26
- but it implements the most needed, basic functionality:
27
- * filtering the app list
28
- * installing new apps
29
- * removing installed apps
25
+ NOTE: `vappman` covers many capabilities of appman:
26
+ * implicitly, (-f) files (or show installed), (-l) list available apps,
27
+ and (-q) search the app list
28
+ * (-i) installing uninstalled apps
29
+ * (-r) removing installed apps
30
+ * (-b) backup / (-o) overwrite of installed apps
31
+ * (-a) about (i.e., more info) for all apps
32
+ * (-c) clean to remove unneeded files and directories
33
+ * (-u) update installed apps; and `vappman` uses "U" for update
34
+ all installed apps
35
+
36
+ But it does NOT cover:
37
+ * (-d) download install script
38
+ * (-h) help or full help for appman
39
+ * (-H) home or set $HOME directory for apps
40
+ * (-t) template for custom install template
41
+ * (-v) version of appman
42
+ * --force-latest to get the most recent stable release AND
43
+ all other options and unmentioned commands.
30
44
 
31
45
  ## Usage
32
46
  * Run `vappman` from the command line.
33
47
  * It presents some keys available on the top line.
34
48
  * Use '?' to learn the navigation keys (e.g., you can use the mouse wheel,
35
49
  arrow keys, and many `vi`-like keys)
50
+ * '?' also elaborates the meaning of the available keys for operations.
51
+ * NOTE: `ENTER` acts differently based on context:
52
+ * In help, it returns to the main menu.
53
+ * On an uninstalled app, it installs it.
54
+ * On an installed app, it uninstalls it.
36
55
  * Then `vappman` presents a list of installed apps, followed by available/uninstalled apps.
56
+ * Installed apps have prefix '✔✔✔' (i.e., three checks).
57
+ * Uninstalled apps have prefix '◆' (i.e., a solid diamond).
37
58
  * Enter `/` to enter a "filter" for installed/uninstalled apps, if you wish.
38
- * If you enter plain old "words", then those words must match the beginning of words
59
+ * If you enter plain ole "words", then those words must match the beginning of words
39
60
  of the apps or descriptions (in order, but not contiguously).
40
61
  * Or you can enter an regular expression acceptable to python (e.g., `\b` means word
41
62
  boundary, etc.)
@@ -46,10 +67,12 @@ but it implements the most needed, basic functionality:
46
67
 
47
68
  ---
48
69
 
49
- NOTES:
50
- * the filter is `card` so it shows apps with words starting with `card`.
51
- * the current position is on `glabels`; thus if `i` is typed, `appman install glabels` is run.
70
+ NOTES: in this example:
71
+ * the filter is `card` so it shows app lines with words starting with `card`.
72
+ * the reverse video, current position is on `glabels`;
73
+ thus if `i` (or ENTER) is typed, `appman install glabels` is run.
52
74
  * if the horizontal line (second line show) has no decorations, then you are looking
53
75
  all the filtered apps; otherwise, the decoration suggests where you are in the
54
76
  partial view of the filtered apps.
77
+ * the matching installed app has the '✔✔✔' prefix.
55
78
 
@@ -4,20 +4,41 @@
4
4
  * Install `vappman` using `pipx install vappman`, or however you do so.
5
5
  * Prerequisites: install [ivan-hc/AppMan: AppImage package manager to install, update (for real) and manage ALL of them locally thanks to "AM", the ever-growing AUR-inspired database listing (for now) 1900+ portable apps and programs for GNU/Linux. Manage your AppImages with the ease of APT and the power of PacMan.](https://github.com/ivan-hc/AppMan) and all of its prerequisites.
6
6
 
7
- NOTE: `vappman` is in a very preliminary state,
8
- but it implements the most needed, basic functionality:
9
- * filtering the app list
10
- * installing new apps
11
- * removing installed apps
7
+ NOTE: `vappman` covers many capabilities of appman:
8
+ * implicitly, (-f) files (or show installed), (-l) list available apps,
9
+ and (-q) search the app list
10
+ * (-i) installing uninstalled apps
11
+ * (-r) removing installed apps
12
+ * (-b) backup / (-o) overwrite of installed apps
13
+ * (-a) about (i.e., more info) for all apps
14
+ * (-c) clean to remove unneeded files and directories
15
+ * (-u) update installed apps; and `vappman` uses "U" for update
16
+ all installed apps
17
+
18
+ But it does NOT cover:
19
+ * (-d) download install script
20
+ * (-h) help or full help for appman
21
+ * (-H) home or set $HOME directory for apps
22
+ * (-t) template for custom install template
23
+ * (-v) version of appman
24
+ * --force-latest to get the most recent stable release AND
25
+ all other options and unmentioned commands.
12
26
 
13
27
  ## Usage
14
28
  * Run `vappman` from the command line.
15
29
  * It presents some keys available on the top line.
16
30
  * Use '?' to learn the navigation keys (e.g., you can use the mouse wheel,
17
31
  arrow keys, and many `vi`-like keys)
32
+ * '?' also elaborates the meaning of the available keys for operations.
33
+ * NOTE: `ENTER` acts differently based on context:
34
+ * In help, it returns to the main menu.
35
+ * On an uninstalled app, it installs it.
36
+ * On an installed app, it uninstalls it.
18
37
  * Then `vappman` presents a list of installed apps, followed by available/uninstalled apps.
38
+ * Installed apps have prefix '✔✔✔' (i.e., three checks).
39
+ * Uninstalled apps have prefix '◆' (i.e., a solid diamond).
19
40
  * Enter `/` to enter a "filter" for installed/uninstalled apps, if you wish.
20
- * If you enter plain old "words", then those words must match the beginning of words
41
+ * If you enter plain ole "words", then those words must match the beginning of words
21
42
  of the apps or descriptions (in order, but not contiguously).
22
43
  * Or you can enter an regular expression acceptable to python (e.g., `\b` means word
23
44
  boundary, etc.)
@@ -28,10 +49,12 @@ but it implements the most needed, basic functionality:
28
49
 
29
50
  ---
30
51
 
31
- NOTES:
32
- * the filter is `card` so it shows apps with words starting with `card`.
33
- * the current position is on `glabels`; thus if `i` is typed, `appman install glabels` is run.
52
+ NOTES: in this example:
53
+ * the filter is `card` so it shows app lines with words starting with `card`.
54
+ * the reverse video, current position is on `glabels`;
55
+ thus if `i` (or ENTER) is typed, `appman install glabels` is run.
34
56
  * if the horizontal line (second line show) has no decorations, then you are looking
35
57
  all the filtered apps; otherwise, the decoration suggests where you are in the
36
58
  partial view of the filtered apps.
59
+ * the matching installed app has the '✔✔✔' prefix.
37
60
 
@@ -55,7 +55,7 @@ build-backend = "setuptools.build_meta"
55
55
 
56
56
  [project]
57
57
  name = "vappman"
58
- version = "0.4"
58
+ version = "0.6"
59
59
  description = "A visual wrapper for appman"
60
60
  authors = [
61
61
  { name = "Joe Defen", email = "joedef@google.com" }
@@ -14,6 +14,7 @@ Interactive, visual thin layer atop appman
14
14
  import os
15
15
  import sys
16
16
  import re
17
+ import shutil
17
18
  import subprocess
18
19
  import traceback
19
20
  import copy
@@ -32,27 +33,42 @@ class Vappman:
32
33
  assert not Vappman.singleton
33
34
  Vappman.singleton = self
34
35
 
35
- self.summary_lines = []
36
- self.new_summary_lines = True
37
-
38
36
  spin = self.spin = OptionSpinner()
39
37
  spin.add_key('help_mode', '? - toggle help screen', vals=[False, True])
40
38
 
41
- other = 'ir/q'
39
+ # EXPAND
40
+ other = 'airbou/qscU'
42
41
  other_keys = set(ord(x) for x in other)
42
+ other_keys.add(cs.KEY_ENTER)
43
+ other_keys.add(10) # another form of ENTER
43
44
  self.opts = spin.default_obj
44
45
 
45
46
  self.actions = {} # currently available actions
46
47
  self.pick_app = '' # current picked app
47
48
  self.pick_is_installed = False
48
- # self.verbs = {'i': 'install', 'r': 'remove', 'v': 'view',}
49
49
  self.prev_filter = '' # string
50
50
  self.filter = None # compiled pattern
51
+ self.check_preqreqs()
51
52
  self.apps = self.cmd_dict('appman list')
52
53
  self.installs = self.get_installed() # dict keyed by app
53
54
  self.win = Window(head_line=True, body_rows=len(self.apps)+20, head_rows=10,
54
55
  keys=spin.keys ^ other_keys, mod_pick=self.mod_pick)
55
56
 
57
+ @staticmethod
58
+ def check_preqreqs():
59
+ """ Check that needed programs are installed. """
60
+ ok = True
61
+ for prog in 'curl grep jq sed wget appman'.split():
62
+ if shutil.which(prog) is None:
63
+ ok = False
64
+ print(f'ERROR: cannot find {prog!r} on $PATH')
65
+ if prog == 'appman':
66
+ print('Install appman with:')
67
+ print("""mkdir -p ~/.local/bin && cd /tmp &&"""
68
+ """ wget https://raw.githubusercontent.com/ivan-hc/AM/main/APP-MANAGER"""
69
+ """ -O appman && chmod a+x ./appman && mv ./appman ~/.local/bin/appman""")
70
+ if not ok:
71
+ sys.exit(1)
56
72
 
57
73
  def cmd_dict(self, cmd, start='◆ '):
58
74
  """ Get lines with the given start."""
@@ -77,7 +93,7 @@ class Vappman:
77
93
 
78
94
  def get_installed(self):
79
95
  """ Get the list of lines of installed apps """
80
- rv = self.cmd_dict('appman files --by-name')
96
+ rv = self.cmd_dict('appman files --byname')
81
97
  return rv
82
98
 
83
99
  def main_loop(self):
@@ -89,13 +105,23 @@ class Vappman:
89
105
  self.win.set_pick_mode(False)
90
106
  self.spin.show_help_nav_keys(self.win)
91
107
  self.spin.show_help_body(self.win)
108
+ # EXPAND
92
109
  lines = [
93
110
  'ALWAYS AVAILABLE:',
94
- ' / - filter apps',
95
111
  ' q - quit program (CTL-C disabled)',
112
+ ' a - about (more info about app)',
113
+ ' s - sync (update appman itself)',
114
+ ' c - clean (remove unneeded files/folters)',
115
+ ' U - update ALL installed apps',
116
+ ' / - filter apps',
117
+ ' ENTER = install, remove, or return from help',
96
118
  'CONTEXT SENSITIVE:',
97
119
  ' i - install uninstalled app',
98
120
  ' r - remove installed app',
121
+ ' b - backup installed app',
122
+ ' u - update installed app',
123
+ ' o - overwrite app from its backup',
124
+
99
125
  ]
100
126
  for line in lines:
101
127
  self.win.put_body(line)
@@ -106,15 +132,15 @@ class Vappman:
106
132
  # self.win.set_pick_mode(self.opts.pick_mode, self.opts.pick_size)
107
133
  self.win.set_pick_mode(True)
108
134
  self.win.add_header(self.get_keys_line(), attr=cs.A_BOLD)
109
- for line in self.installs.values():
135
+ for app, line in self.installs.items():
136
+ if app in self.apps:
137
+ line = self.apps[app]
110
138
  if wanted(line):
139
+ line = '✔✔✔' + line[1:]
111
140
  self.win.add_body(line)
112
141
  for app, line in self.apps.items():
113
142
  if app not in self.installs and wanted(line):
114
143
  self.win.add_body(line)
115
- # if self.new_summary_lines:
116
- # self.win.pick_pos = self.win.scroll_pos = 0
117
- # self.new_summary_lines = False
118
144
  self.win.render()
119
145
 
120
146
  _ = self.do_key(self.win.prompt(seconds=300))
@@ -122,11 +148,13 @@ class Vappman:
122
148
 
123
149
  def get_keys_line(self):
124
150
  """ TBD """
151
+ # EXPAND
125
152
  filt = self.prev_filter if self.prev_filter else '{No-Filt}'
126
153
  line = 'KEYS:'
127
154
  for key, verb in self.actions.items():
128
155
  line += f' {key}:{verb}'
129
- line += f' ?:help q:quit /{filt} '
156
+ # or EXPAND
157
+ line += f' ?:help q:quit a:about s:sync c:clean U:upd /{filt} '
130
158
  # for action in self.actions:
131
159
  # line += f' {action[0]}:{action}'
132
160
  return line
@@ -139,8 +167,12 @@ class Vappman:
139
167
  line = lines[self.win.pick_pos]
140
168
  app = self.get_word1(line)
141
169
  self.pick_is_installed = bool(app in self.installs)
170
+ # EXPAND
142
171
  if self.pick_is_installed:
143
- actions['r'] = 'remove'
172
+ actions['r'] = 'rmv'
173
+ actions['b'] = 'bkup'
174
+ actions['o'] = 'overwr'
175
+ actions['u'] = 'upd'
144
176
  else:
145
177
  actions['i'] = 'install'
146
178
 
@@ -170,54 +202,59 @@ class Vappman:
170
202
  # line = line[0:-over]
171
203
 
172
204
  # return line + suffix
205
+ def run_appman(self, cmd):
206
+ Window.stop_curses()
207
+ os.system(f'clear; stty sane; {cmd};'
208
+ + ' /bin/echo -e "\n\n===== Press ENTER for menu ====> \c"; read FOO')
209
+ self.installs = self.get_installed()
210
+ Window._start_curses()
173
211
 
174
212
  def do_key(self, key):
175
213
  """ TBD """
176
- def dashes(ns, ok=True):
177
- try:
178
- # use checkmark or circle-backslash
179
- filler = ('\u2713' if ok else '\u2342') * (ns.end - ns.start)
180
- line = self.summary_lines[self.win.pick_pos]
181
- line = line[0:ns.start] + filler + line[ns.end:]
182
- self.summary_lines[self.win.pick_pos] = line
183
- self.win.draw(self.win.pick_pos, 0, line, width=self.win.get_pad_width(), header=False)
184
- self.win.fix_positions(delta=1)
185
- self.win.render()
186
- except Exception:
187
- pass
188
-
189
214
  if not key:
190
215
  return True
216
+ if key == cs.KEY_ENTER or key == 10: # Handle ENTER
217
+ if self.opts.help_mode:
218
+ self.opts.help_mode = False
219
+ return True
220
+ elif self.pick_is_installed:
221
+ key = ord('r') # removed installed app
222
+ else:
223
+ key = ord('i') # install uninstalled app
224
+
191
225
  if key in self.spin.keys:
192
226
  value = self.spin.do_key(key, self.win)
193
- if key in (ord('p'), ord('s')):
194
- self.win.set_pick_mode(on=self.opts.pick_mode, pick_size=self.opts.pick_size)
195
- elif key == ord('n'):
196
- self.win.alert(title='Info', message=f'got: {value}')
197
227
  return value
228
+
198
229
  if key == ord('q'):
199
230
  self.win.stop_curses()
200
231
  os.system('clear; stty sane')
201
232
  sys.exit(0)
202
233
 
203
234
  if key == ord('i') and not self.pick_is_installed:
204
- # pylint: disable=protected-access
205
- Window.stop_curses()
206
- os.system(f'clear; stty sane; appman install {self.pick_app};'
207
- + ' echo -e "\n\nHit ENTER to return to menu"; read FOO')
208
- self.installs = self.get_installed()
209
- Window._start_curses()
235
+ self.run_appman(f'appman install {self.pick_app}')
210
236
  return None
211
237
 
212
238
  if key == ord('r') and self.pick_is_installed:
213
- # pylint: disable=protected-access
214
- Window.stop_curses()
215
- os.system(f'clear; stty sane; appman remove {self.pick_app};'
216
- + ' echo -e "\n\nHit ENTER to return to menu"; read FOO')
217
- self.installs = self.get_installed() # dict keyed by app
218
- Window._start_curses()
239
+ self.run_appman(f'appman remove {self.pick_app}')
219
240
  return None
220
241
 
242
+ if key == ord('s'):
243
+ self.run_appman('appman sync')
244
+ if key == ord('c'):
245
+ self.run_appman('appman clean')
246
+ if key == ord('b'):
247
+ self.run_appman(f'appman backup {self.pick_app}')
248
+ if key == ord('o'):
249
+ self.run_appman(f'appman overwrite {self.pick_app}')
250
+ if key == ord('a'):
251
+ self.run_appman(f'appman about {self.pick_app}')
252
+ if key == ord('u'):
253
+ self.run_appman(f'appman update {self.pick_app}')
254
+ if key == ord('U'):
255
+ self.run_appman(f'appman update')
256
+ # EXPAND
257
+
221
258
  if key == ord('/'):
222
259
  # pylint: disable=protected-access
223
260
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vappman
3
- Version: 0.4
3
+ Version: 0.6
4
4
  Summary: A visual wrapper for appman
5
5
  Author-email: Joe Defen <joedef@google.com>
6
6
  License: MIT
@@ -22,20 +22,41 @@ Requires-Dist: psutil>=5.9
22
22
  * Install `vappman` using `pipx install vappman`, or however you do so.
23
23
  * Prerequisites: install [ivan-hc/AppMan: AppImage package manager to install, update (for real) and manage ALL of them locally thanks to "AM", the ever-growing AUR-inspired database listing (for now) 1900+ portable apps and programs for GNU/Linux. Manage your AppImages with the ease of APT and the power of PacMan.](https://github.com/ivan-hc/AppMan) and all of its prerequisites.
24
24
 
25
- NOTE: `vappman` is in a very preliminary state,
26
- but it implements the most needed, basic functionality:
27
- * filtering the app list
28
- * installing new apps
29
- * removing installed apps
25
+ NOTE: `vappman` covers many capabilities of appman:
26
+ * implicitly, (-f) files (or show installed), (-l) list available apps,
27
+ and (-q) search the app list
28
+ * (-i) installing uninstalled apps
29
+ * (-r) removing installed apps
30
+ * (-b) backup / (-o) overwrite of installed apps
31
+ * (-a) about (i.e., more info) for all apps
32
+ * (-c) clean to remove unneeded files and directories
33
+ * (-u) update installed apps; and `vappman` uses "U" for update
34
+ all installed apps
35
+
36
+ But it does NOT cover:
37
+ * (-d) download install script
38
+ * (-h) help or full help for appman
39
+ * (-H) home or set $HOME directory for apps
40
+ * (-t) template for custom install template
41
+ * (-v) version of appman
42
+ * --force-latest to get the most recent stable release AND
43
+ all other options and unmentioned commands.
30
44
 
31
45
  ## Usage
32
46
  * Run `vappman` from the command line.
33
47
  * It presents some keys available on the top line.
34
48
  * Use '?' to learn the navigation keys (e.g., you can use the mouse wheel,
35
49
  arrow keys, and many `vi`-like keys)
50
+ * '?' also elaborates the meaning of the available keys for operations.
51
+ * NOTE: `ENTER` acts differently based on context:
52
+ * In help, it returns to the main menu.
53
+ * On an uninstalled app, it installs it.
54
+ * On an installed app, it uninstalls it.
36
55
  * Then `vappman` presents a list of installed apps, followed by available/uninstalled apps.
56
+ * Installed apps have prefix '✔✔✔' (i.e., three checks).
57
+ * Uninstalled apps have prefix '◆' (i.e., a solid diamond).
37
58
  * Enter `/` to enter a "filter" for installed/uninstalled apps, if you wish.
38
- * If you enter plain old "words", then those words must match the beginning of words
59
+ * If you enter plain ole "words", then those words must match the beginning of words
39
60
  of the apps or descriptions (in order, but not contiguously).
40
61
  * Or you can enter an regular expression acceptable to python (e.g., `\b` means word
41
62
  boundary, etc.)
@@ -46,10 +67,12 @@ but it implements the most needed, basic functionality:
46
67
 
47
68
  ---
48
69
 
49
- NOTES:
50
- * the filter is `card` so it shows apps with words starting with `card`.
51
- * the current position is on `glabels`; thus if `i` is typed, `appman install glabels` is run.
70
+ NOTES: in this example:
71
+ * the filter is `card` so it shows app lines with words starting with `card`.
72
+ * the reverse video, current position is on `glabels`;
73
+ thus if `i` (or ENTER) is typed, `appman install glabels` is run.
52
74
  * if the horizontal line (second line show) has no decorations, then you are looking
53
75
  all the filtered apps; otherwise, the decoration suggests where you are in the
54
76
  partial view of the filtered apps.
77
+ * the matching installed app has the '✔✔✔' prefix.
55
78
 
File without changes
File without changes
File without changes
File without changes