aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOle Mathias Aa. Heggem <olemathias.aa.heggem@gmail.com>2019-04-02 20:20:25 +0200
committerGitHub <noreply@github.com>2019-04-02 20:20:25 +0200
commit02bb6476b443765bb673d4a0e93770698e44e8a7 (patch)
treeb7ae384ea3cc28f3550dd73b0baeb659faf43e26
parentf706bae1c3c2222a702e4121e1db8b7e9d45ab50 (diff)
parent7cd4617b362b99562e265fd9715764e4976cdf3e (diff)
Merge pull request #102 from sklirg/feat/support-label-scripts
Add label generation scripts for Tech Support
-rw-r--r--tech-support/labels/README.rst27
-rw-r--r--tech-support/labels/cables.py87
-rw-r--r--tech-support/labels/gondul.py76
-rw-r--r--tech-support/labels/main.py60
-rw-r--r--tech-support/labels/old/README.txt29
-rw-r--r--tech-support/labels/old/cable_labels.pl16
-rw-r--r--tech-support/labels/old/switch_labels.py120
-rw-r--r--tech-support/labels/switches.py43
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)