diff options
-rw-r--r-- | tech-support/labels/README.rst | 27 | ||||
-rw-r--r-- | tech-support/labels/cables.py | 87 | ||||
-rw-r--r-- | tech-support/labels/gondul.py | 76 | ||||
-rw-r--r-- | tech-support/labels/main.py | 60 | ||||
-rw-r--r-- | tech-support/labels/old/README.txt | 29 | ||||
-rw-r--r-- | tech-support/labels/old/cable_labels.pl | 16 | ||||
-rw-r--r-- | tech-support/labels/old/switch_labels.py | 120 | ||||
-rw-r--r-- | tech-support/labels/switches.py | 43 |
8 files changed, 458 insertions, 0 deletions
diff --git a/tech-support/labels/README.rst b/tech-support/labels/README.rst new file mode 100644 index 0000000..c242d3c --- /dev/null +++ b/tech-support/labels/README.rst @@ -0,0 +1,27 @@ +TG label scripts +================ + +Scripts. + +Usage +----- + +The ``--help`` parameter is pretty helpful. + +Run the script with either ``cables`` or ``switches``, +depending if you want labels for cables or switches. +Configure the application further if needed. Consult ``--help``. + +Specify gondul credentials either using environment variables +(``GONDUL_USERNAME``, ``GONDUL_PASSWORD``) or the command line. +It's also possible to update the API root or API endpoint to use, +as well as a regex for matching switches. + +Specify the output file with the ``--outfile`` argument. + +For cables, specify the number of uplinks (``--uplinks``), +copies (``--copies``) and when to split (``--split``) +the CSV files for the label printer. Supply APs to print +labels for them to, either by identifying the switch with ``--ap`` +or by supplying a newline-separated file of switch identifiers +through ``--aps-file`` (e.g. ``33-1`` to add an AP to that switch). diff --git a/tech-support/labels/cables.py b/tech-support/labels/cables.py new file mode 100644 index 0000000..a7ff5de --- /dev/null +++ b/tech-support/labels/cables.py @@ -0,0 +1,87 @@ +from itertools import chain + +cable_label_format = "%(switch_name)s-%(switch_num)s-%(cable_name)s" +mark_twice = True +num_tabs = 1 + + +def generate_label(switch, cable_name): + data = { + "switch_name": switch.split("-")[0], + "switch_num": switch.split("-")[1], + "cable_name": cable_name, + } + label = cable_label_format % data + if not mark_twice: + return label + + return "{}{}{}".format(label, "\t" * num_tabs, label) + + +def generate_label_copies(switch, cable_name, copies=2): + return [generate_label(switch, cable_name) for _ in range(0, copies)] + + +def generate_labels(switches, aps=[], copies=2, uplinks=3): + print("Generating {} copies of each label for {} uplinks for {} switches and {} APs ({} labels)".format( + copies, uplinks, len(switches), len(aps), (len(switches) * uplinks + len(aps)) * copies)) + + labels = [] + for i in range(0, len(switches)): + switch = switches[i] + switch_name = switch[1:] + cable_labels = [generate_label_copies( + switch_name, uplink + 1, copies=copies) for uplink in range(0, uplinks)] + + # Destructure the list of copies into a flat list + labels.extend(chain.from_iterable(cable_labels)) + + if switch_name in aps: + labels.extend( + generate_label_copies(switch_name, "AP", copies=copies)) + + return labels + + +def write_to_file(data, outfile="cable_labels.csv", filenum=1): + outfile_numbered = outfile.replace(".", "-{}.".format(filenum)) + + with open(outfile_numbered, "w") as f: + f.writelines("\n".join(data)) + + +def chunk_list(li, items): + for i in range(0, len(li), items): + yield li[i:i+items] + + +def write_csv(data, outfile="cable_labels.csv", split_per_num=100): + split_data = list(chunk_list(data, split_per_num)) + + for i in range(0, len(split_data)): + write_to_file(split_data[i], filenum=i+1) + + print("Wrote cable labels to {} files, starting from {}".format( + len(split_data), outfile.replace(".", "-1."))) + + +def read_aps_file(path): + aps = [] + with open(path, "r") as f: + aps = [line.replace("\n", "").strip() for line in f.readlines()] + + return aps + + +def make_cable_labels(switches, ap_file=None, aps=[], copies=2, outfile="cable_labels.csv", split_per_num=100, uplinks=3): + print("Generating labels for cables") + + list_of_aps = aps + if ap_file: + list_of_aps.extend(read_aps_file(ap_file)) + + if len(list_of_aps): + print("Generating labels for {} APs".format(len(list_of_aps))) + + labels = generate_labels(switches, copies=copies, uplinks=uplinks, aps=aps) + write_csv(labels, outfile=outfile, split_per_num=split_per_num) diff --git a/tech-support/labels/gondul.py b/tech-support/labels/gondul.py new file mode 100644 index 0000000..74c1a23 --- /dev/null +++ b/tech-support/labels/gondul.py @@ -0,0 +1,76 @@ +import base64 +import json +import os +import re +import urllib.parse +import urllib.request + +GONDUL_USERNAME = os.getenv("GONDUL_USERNAME", "") +GONDUL_PASSWORD = os.getenv("GONDUL_PASSWORD", "") +GONDUL_API = os.getenv("GONDUL_API", "https://tg18.gondul.gathering.org/api") +GONDUL_SWITCHES_ENDPOINT = os.getenv( + "GONDUL_SWITCHES_ENDPOINT", "/public/switches") + + +def _generate_credentials(username, password): + return base64.standard_b64encode( + (username + ":" + password) + .encode("utf-8")).decode("utf-8") + + +def _do_switches_request( + api=GONDUL_API, + endpoint=GONDUL_SWITCHES_ENDPOINT, + credentials=_generate_credentials(GONDUL_USERNAME, GONDUL_PASSWORD)): + switches_url = api + endpoint + + # Build request + request = urllib.request.Request(switches_url) + request.add_header("Authorization", "Basic " + credentials) + resp = urllib.request.urlopen(request, timeout=5) + assert resp.status == 200, "HTTP return was not 200 OK" + + # Read response + body = resp.read().decode("utf-8") + data = json.loads(body) + assert "switches" in data, "Missing switches object from HTTP response" + + switches = data.get("switches") + print("Found {} switches in Gondul".format(len(switches))) + return switches + + +def _match_switches(switches, match="^e(.*)"): + pattern = re.compile(match) + + included_switches = [] + for switch in switches: + include = re.search(pattern, switch) + if include: + included_switches.append(switch) + + print("'{}' matches {} switches.".format(match, len(included_switches))) + return included_switches + + +def _sort_switches(switches): + # The lambda returns two values to compare on; + # * The switch number (e77-4) - picks out the number 77 + # * The number of the switch in relation to other switches on the same row + # E.g. "e77-4" will return 4 + return sorted(switches, key=lambda x: (int(x[1:].split("-")[0]), x.split("-")[1])) + + +def fetch_gondul_switches(api=None, endpoint=None, username=None, password=None, match="^e(.*)"): + # Use provided arg instead of environment variable if defined. + _api = api if api is not None else GONDUL_API + _endpoint = endpoint if endpoint is not None else GONDUL_SWITCHES_ENDPOINT + _username = username if username is not None else GONDUL_USERNAME + _password = password if password is not None else GONDUL_PASSWORD + credentials = _generate_credentials(_username, _password) + + return _sort_switches( + _match_switches( + _do_switches_request( + api=_api, endpoint=_endpoint, credentials=credentials), + match=match)) diff --git a/tech-support/labels/main.py b/tech-support/labels/main.py new file mode 100644 index 0000000..a8a0ed7 --- /dev/null +++ b/tech-support/labels/main.py @@ -0,0 +1,60 @@ +import argparse +import sys + +from cables import make_cable_labels +from gondul import fetch_gondul_switches +from switches import make_switch_labels + +parser = argparse.ArgumentParser( + "Label generator script 2000", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) +parser.add_argument("labler", type=str, + help="The label function to run. Either [c]ables or [s]witches.") +parser.add_argument("--gondul-user", type=str, + help="Gondul username. Overrides env GONDUL_USERNAME") +parser.add_argument("--gondul-pass", type=str, + help="Gondul password. Overrides env GONDUL_PASSWORD") +parser.add_argument("--gondul-api", type=str, + help="Gondul API base. Overrides env GONDUL_API") +parser.add_argument("--gondul-switches", type=str, + help="Gondul switches endpoint. Overrides env GONDUL_SWITCHES_ENDPOINT") +parser.add_argument("--match-switches", type=str, default="^e(.*)", + help="Regex for matching switches") +parser.add_argument("--outfile", "-o", type=str, default="cable_labels.csv", + help="Output (base) file name. Might be appended with numbers for cables.") + +cables_args = parser.add_argument_group("cables") +cables_args.add_argument("--ap", type=str, action="append", + help="Name of a switch where an AP should be connected") +cables_args.add_argument("--aps-file", type=str, + help="Path to a newline-separated file with switches where an AP should be connected") +cables_args.add_argument("--copies", "-c", type=int, default=2, + help="Number of copies per label") +cables_args.add_argument("--uplinks", "-u", type=int, default=3, + help="Number of uplinks per switch") +cables_args.add_argument("--split", "-s", type=int, default=100, + help="Split into CSV files of this size") + +if __name__ == "__main__": + args = parser.parse_args() + + switches = fetch_gondul_switches( + api=args.gondul_api, + endpoint=args.gondul_switches, + username=args.gondul_user, + password=args.gondul_pass, + match=args.match_switches, + ) + + if args.labler[0] == "c": + make_cable_labels(switches, + aps=args.ap if args.ap is not None else [], + ap_file=args.aps_file, + copies=args.copies, + outfile=args.outfile, + split_per_num=args.split) + elif args.labler[0] == "s": + make_switch_labels(switches, outfile=args.outfile) + else: + parser.print_help() + sys.exit("Invalid labler operation.") diff --git a/tech-support/labels/old/README.txt b/tech-support/labels/old/README.txt new file mode 100644 index 0000000..fa02d44 --- /dev/null +++ b/tech-support/labels/old/README.txt @@ -0,0 +1,29 @@ +Disse filene brukes for � generere merking av kabler og switcher til The Gathering (Eller andre event med lignende behov) + +############## +switch_lables.py: +############## +Brukes til � generere lapper som henges opp p� switcher/switchstativer for enkel identifisering. + + +Howto: +Endre configen i filen (Antall rader, antall switcher, filnavn + eventuell config for Creativia), og kj�r filen med python. + +Den lager en HTML fil med valgt navn, som s� kan printes i en vanlig printer. + + +############## +cable_lables.pl +############## +Brukes til � generere teksten til lappene som settes i begge ender av alle kablene i hallen. + +CSV-filen mates inn i dymo programvaren og formatteres der. Husk at alle lapper m� skrives ut i to eksemplarer. + +Howto: +Kj�r filen med perl, sett variablene og pipe ut til csv med passende navn. + +Variablene filen spiser er f�lgende: Antall rader, antall switcher per rad, antall kabler per switch. + +Eksempel: + +perl cable_lables.pl 82 4 4 > Lapper.csv diff --git a/tech-support/labels/old/cable_labels.pl b/tech-support/labels/old/cable_labels.pl new file mode 100644 index 0000000..b461d03 --- /dev/null +++ b/tech-support/labels/old/cable_labels.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my ($rows, $switches, $cables) = @ARGV; + +for my $row (1 .. $rows) { + next if (!($row & 1)); + + for my $switch (1 .. $switches) { + for my $cable (1 .. $cables) { + print join('-', ($row, $switch, $cable)) . ';' . "\n"; + } + } +} diff --git a/tech-support/labels/old/switch_labels.py b/tech-support/labels/old/switch_labels.py new file mode 100644 index 0000000..867c5ab --- /dev/null +++ b/tech-support/labels/old/switch_labels.py @@ -0,0 +1,120 @@ +#!/usr/bin/python +#coding: utf-8 +# +# @version: 0.1 +# @date: 19.04.2011 +# +# @description: A quick script to output a html page that prints +# switch labels in the format: <row>-<switch> +# i.e: 71-4. One label per page. +# +# NB! only makes odd number labels. +# +# @author: technocake +# Found at: blog.technocake.net +#-------------------------------------------- + +import sys + +###################################### +# Configuration +###################################### +rows = 84 #rows +switches = 4 #switches per row +outFile = "tg-switch-labels-print-me.html" + + +#### CREATIVIA #### +creative_rows = 12 +creative_prepend = "C" + + +output = "" + +# the top of the html page +def head(): + return """<!Doctype html> +<html> <head> +<style> + div.a4 { + font-size: 24em; + text-align: center; + @page size: A4 landscape; + + /* this is the part that makes each div print per page. */ + page-break-after: always; + } +</style> +</head> +<body> +""" + +#the bottom of the html page +def tail(): + return "</body></html>" + +#ONE switch label +def a4(s ): + return "<div class='a4'> %s </div>" % (s, ) + + +def saveToFile(data, fileName): + f = open(fileName, 'w+') + f.write( data ) + f.close() + +# In python 3, raw_input is renamed to input. In python v <3. input does something else. +# this function fixes that +def prompt(text): + try: + return raw_input(text) + except: + try: + return input(text) + + except: + exit() + + +################################################### +# This is where the actual generating takes place +################################################### + + +if __name__ == "__main__": + output += head() + + + #Generating all the labels for the switches + for row in range(1, rows+1, 2): + for SWITCH in range(1, switches+1): + output += a4("%s-%s\n" % (row, SWITCH) ) + + + # Generating all the labels for the CREATIVE area + for row in range(1, creative_rows+1): + output += a4("%s-%s\n" % (creative_prepend, row)) + + + + output += tail() + + # Taking it out to the big tg-world + + if len(sys.argv) > 1: + #Printing to stdout if second argument is passed to the script + print ( output ) + else: + saveToFile(output, outFile) + #normally, this is what happens. Saving it to a new html file + + + print ( """ + Generated labels for %d switches per row and %d rows. \n + The html file is in this folder, and is named %s \n + Pages to print: %d \n\n + """ + % (switches, rows, outFile, (switches*rows)/2 + creative_rows) + ) + + prompt( "Press any key to exit...")
\ No newline at end of file diff --git a/tech-support/labels/switches.py b/tech-support/labels/switches.py new file mode 100644 index 0000000..a218489 --- /dev/null +++ b/tech-support/labels/switches.py @@ -0,0 +1,43 @@ +switch_label_format = "%(switch_name)s-%(switch_num)s" +switch_label_layout = """<!DOCTYPE html> +<html><head> + <style> + div.a4 { + font-size: 24em; + text-align: center; + @page size: A4 landscape; + + /* this is the part that makes each div print per page. */ + page-break-after: always; + } + </style> +</head> +<body>%s</body></html> +""" +switch_label_page = '<div class="a4">%s</div>' + + +def generate_label(switch_name, switch_number): + return switch_label_page % switch_label_format % { + "switch_name": switch_name, + "switch_num": switch_number, + } + + +def generate_labels(switches): + labels = list(map(lambda switch: generate_label( + switch[1:].split("-")[0], switch.split("-")[1]), switches)) + + return switch_label_layout % "".join(labels) + + +def write_html_to_file(html, outfile="switch_labels.html"): + with open(outfile, "w") as f: + f.write(html) + print("Wrote labels to '{}'.\nOpen the file in your browser and print it.".format(outfile)) + + +def make_switch_labels(switches, outfile="switch_labels.html"): + print("Generating labels for switches") + labels = generate_labels(switches) + write_html_to_file(labels, outfile=outfile) |