From d5ccca6a8e3e085f7d8783283f98043a8f292272 Mon Sep 17 00:00:00 2001 From: Blake Haug Date: Thu, 11 Jun 2026 15:38:28 -0700 Subject: [PATCH 1/2] remove pdf-open --- bin/pdf-open | 1 - desktop/pdf-open | 20 -------------------- 2 files changed, 21 deletions(-) delete mode 120000 bin/pdf-open delete mode 100755 desktop/pdf-open diff --git a/bin/pdf-open b/bin/pdf-open deleted file mode 120000 index 638badc..0000000 --- a/bin/pdf-open +++ /dev/null @@ -1 +0,0 @@ -../desktop/pdf-open \ No newline at end of file diff --git a/desktop/pdf-open b/desktop/pdf-open deleted file mode 100755 index 1f31e4f..0000000 --- a/desktop/pdf-open +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -e -[ "$#" -ne 1 ] && { echo 'Bad arguments, trying evince...'; exec evince "$@"; } -[ -f "$1" ] || { echo 'File does not exist, trying evince...'; exec evince "$@"; } - -size=$(du "$1") || { echo 'Cannot get size, trying evince...'; exec evince "$@"; } -size=$(cut -f1 <<< "$size") -[ "$size" -lt 5120 ] || { echo 'Too large, trying evince...'; exec evince "$@"; } - -echo 'Rasterizing PDF...' -tmp=$(mktemp --suffix='.pdf') - -if ! convert -density 250 "$1" "$tmp"; then - rm "$tmp" - echo 'Convert failed, trying evince...' - exec evince "$@" -fi - -echo 'Done rasterizing, now opening with evince...' -echo "(output file: $tmp)" -exec evince "$tmp" From 0db8a85f0a2ffc15972409742642855d83dc9f8c Mon Sep 17 00:00:00 2001 From: Blake Haug Date: Thu, 11 Jun 2026 15:38:38 -0700 Subject: [PATCH 2/2] remove mod-printer --- sbin/mod-printer | 1 - staff/lab/mod-printer | 186 ------------------------------------------ 2 files changed, 187 deletions(-) delete mode 120000 sbin/mod-printer delete mode 100755 staff/lab/mod-printer diff --git a/sbin/mod-printer b/sbin/mod-printer deleted file mode 120000 index 1ffb3bb..0000000 --- a/sbin/mod-printer +++ /dev/null @@ -1 +0,0 @@ -../staff/lab/mod-printer \ No newline at end of file diff --git a/staff/lab/mod-printer b/staff/lab/mod-printer deleted file mode 100755 index 0be807f..0000000 --- a/staff/lab/mod-printer +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -"""Remove or add printers to/from CUPS classes.""" -import argparse -import re -import subprocess -import sys - - -class CUPSException(Exception): - pass - - -def modify_printer(args): - """Perform internal call to CUPS CLI to modify class(es).""" - # Get available CUPS classes - lpstat_out = do_internal_call(['lpstat', '-c']) - cups_classes = parse_cups_classes(lpstat_out, args) - - # Perform pre-call logging and input processing - printer = args.printer.lower() - if args.verbose: - print('Printer to perform action on: %s' % printer) - action_flag = '-r' if args.action == 'remove' else '-c' - if args.verbose: - print('Action to be performed (and flag): %s (%s)' % (args.action, action_flag)) - - # Call lpadmin command to perform addition/removal - for class_name, class_members in cups_classes.items(): - printer_name = printer + '-' + class_name - if args.action == 'remove' and printer_name not in class_members: - # Allow the user to continue - supports removal if only one class was modified - print('ERROR: Printer %s is not a member of class %s' % (printer_name, class_name)) - continue - action_cmd = ['lpadmin', '-p', printer_name, action_flag, class_name] - subprocess.run(action_cmd, check=True) - action_out = 'added to' if args.action == 'add' else 'removed from' - print('Printer %s was successfully %s %s' % (printer, action_out, class_name)) - - -def list_printers(args): - """Perform internal call to CUPS CLI to list printer status(es) (and potentially jobs).""" - # Get available CUPS classes - lpstat_out = do_internal_call(['lpstat', '-c']) - cups_classes = parse_cups_classes(lpstat_out, args) - - # Get all CUPS printers - lpstat_proc = subprocess.run(['lpstat', '-p'], check=True, - stdout=subprocess.PIPE, stdin=subprocess.PIPE) - lpstat_out = lpstat_proc.stdout.decode('utf-8').strip().split('\n') - - printer_arg = args.printer and args.printer.lower() - - # Parse lpstat output to find all available printers - # This includes classes and printers (i.e. shared and non-shared printers) - all_printers = [] - for printer_line in lpstat_out: - printer_name_match = re.search(r'printer (\S*)', printer_line) - if not printer_name_match: - continue - printer_name = printer_name_match.group(1) - - if printer_arg and printer_arg not in printer_name: - continue - - if args.classname and args.classname not in printer_name: - continue - - if printer_name not in cups_classes: - all_printers.append(printer_name) - - if args.verbose: - print('All printers found: %s' % all_printers) - print('CUPS class-printer mapping found: %s' % cups_classes) - - # Find differences between all printers and assigned printers - assigned_printers = [] - def matches_args(name): return (not args.printer or args.printer in name) \ - and (not args.classname or args.classname in name) - for class_name, class_members in cups_classes.items(): - class_members = [name for name in class_members if matches_args(name)] - assigned_printers.extend(class_members) - - # Print out all printers belonging to class - if len(class_members): - print('Class %s contains printers: %s' % (class_name, ', '.join(class_members))) - else: - print('Class %s contains no printers' % class_name) - diff_printers = set(all_printers) - set(assigned_printers) - - # Print out all printers not assigned to a class (i.e. out of service) - if len(diff_printers): - print('No classes contain: %s' % ', '.join(diff_printers)) - else: - print('All printers are in service') - - # Print out jobs currently queued for specified printers (default: all) - if args.jobs: - jobs_cmd = ['lpstat', '-o'] - # Specify targets to lpstat command based on classname and printer args - jobs_cmd.extend(cups_classes.keys()) - jobs_cmd.extend([printer for printer in all_printers if matches_args(printer)]) - if args.verbose: - print('Printing jobs with command %s' % jobs_cmd) - - # Perform internal jobs call and print result - jobs_out = do_internal_call(jobs_cmd) - # Remove blank lines/extraneous whitespace - jobs_out = [job for job in jobs_out if job] - if len(jobs_out): - print('\nCurrent print jobs:') - print('\n'.join(jobs_out)) - else: - print('\nNo current jobs queued') - - -def do_internal_call(cmd): - """Perform a call to the system to retrieve data.""" - # Perform internal call to get raw data - proc = subprocess.run(cmd, check=True, - stdout=subprocess.PIPE, stdin=subprocess.PIPE) - # Split data by newline, no trailing or leading whitespace - return proc.stdout.decode('utf-8').strip().split('\n') - - -def parse_cups_classes(lpstat_raw, args): - """Parse raw CUPS class data into class names and members.""" - # Data output in dict with class names as keys and class - # members as values (each stored in an array) - cups_classes = {} - curr_classname = None - for line in lpstat_raw: - match = re.search(r'members of class (\S*):', line) - if match: - curr_classname = match.group(1) - cups_classes[curr_classname] = [] - else: - cups_classes[curr_classname].append(line.strip()) - - if args.verbose: - print('Found CUPS classes: %s' % cups_classes) - - # Override with specified classname if provided and valid - if args.classname: - if args.classname in cups_classes: - cups_classes = {args.classname: cups_classes[args.classname]} - if args.verbose: - print('Overriding CUPS classes with parameter: %s' % args.classname) - else: - raise CUPSException('ERROR: Specified class %s could not be found in available classes %s' - % (args.classname, cups_classes)) - return cups_classes - - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('-v', '--verbose', '--debug', - action='store_true', - help='output more verbose logging to stdout' - ) - parser.add_argument('-c', '--classname', help='modify/list only a specific class') - - subparsers = parser.add_subparsers(dest='action', help='action to perform') - subparsers.required = True - - add_parser = subparsers.add_parser('add', help='add a printer') - add_parser.add_argument('printer', help='name of printer to add') - - remove_parser = subparsers.add_parser('remove', help='remove a printer') - remove_parser.add_argument('printer', help='name of printer to remove') - - list_parser = subparsers.add_parser('list', help='list printer statuses') - list_parser.add_argument('-p', '--printer', help='list only this named printer') - list_parser.add_argument('-j', '--jobs', - action='store_true', help='include print jobs') - - args = parser.parse_args() - if args.action == 'add' or args.action == 'remove': - return modify_printer(args) - elif args.action == 'list': - return list_printers(args) - else: - raise CUPSException('ERROR: Invalid action passed %s' % args.action) - - -if __name__ == '__main__': - sys.exit(main())