瀏覽代碼

initial commit for powerctl

Breandan Dezendorf 1 年之前
父節點
當前提交
5eba080751

+ 7 - 0
dezendorf/applications/powerctl/BUILD

@@ -0,0 +1,7 @@
+load("@rules_python//python:defs.bzl", "py_binary")
+
+py_binary(
+  name = "powerctl",
+  srcs = ["powerctl"],
+  visibility = ["//visibility:public"],
+)

+ 16 - 0
dezendorf/applications/powerctl/README.md

@@ -0,0 +1,16 @@
+powerctl is a utility to manage the power state in the homelab.
+Initial support will be for APC PDU's SNMP write string access
+and a mapping between ports and friendly names/dns names for
+hosts and devices on the network.
+
+TODO:
+  - implement SNMPv1 write
+  - implement Unifi PoE+ rpi4 reboots
+  - implement HomeKit for selected entries
+  - persistant datastore with backups
+  - parent/child relationships (rebooting the Switch-16 in the office also impacts <list>)
+  - failsafe to prevent turning off access to management consoles
+  - APC management card reboots
+  - Unifi device reboots
+  - blaze targets
+  - webUI

+ 0 - 0
dezendorf/applications/powerctl/data/map.ini


+ 120 - 0
dezendorf/applications/powerctl/powerctl

@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+
+import re
+from datetime import timedelta
+import argparse
+import locale
+
+import math
+
+class SubtitleEntry:
+  def __init__(self, entryNumber, text, startTime, endTime):
+    # dd:dd:dd,ddd --> dd:dd:dd,ddd
+    self.entryNumber = entryNumber
+    self.text = text
+    sH, sM, sS = startTime.replace(',', '.').split(':')
+    self.startTime = int(sH) * 3600 + int(sM) * 60 + float(sS)
+    sH, sM, sS = endTime.replace(',', '.').split(':')
+    self.endTime = int(sH) * 3600 + int(sM) * 60 + float(sS)
+
+  def formatEntry(self):
+    entry = ""
+    entry += "{}\n".format(self.entryNumber)
+    entry += self.formatTimeString() + "\n"
+    entry += "{}".format(self.text)
+    return entry
+
+  def formatTimeString(self):
+    s = self.startTime
+    startHours = s // 3600
+    s = s - (startHours * 3600)
+    startMinutes = s // 60
+    s = s - (startMinutes * 60)
+    startSeconds = s
+
+    e = self.endTime
+    endHours = e // 3600
+    e = e - (endHours * 3600)
+    endMinutes = e // 60
+    e = e - (endMinutes * 60)
+    endSeconds = e
+
+    return '{:02.0f}:{:02.0f}:{:02.0f},{:03.0f} --> {:02.0f}:{:02.0f}:{:02.0f},{:03.0f}'.format(startHours, startMinutes, math.floor(startSeconds), (startSeconds % 1) * 1000 , endHours, endMinutes, math.floor(endSeconds), (endSeconds % 1) * 1000 )
+
+  def shift(self, seconds):
+    self.startTime = self.startTime + seconds    
+    self.endTime = self.endTime + seconds
+
+def main():
+  Subtitles = []
+
+  parser = argparse.ArgumentParser()
+
+  parser.add_argument("--seconds", help="Decimal formatted seconds to adjust offsets by", type=float, required=True)
+  parser.add_argument("--file", help="Subtitle file to shift", type=str, required=True)
+  parser.add_argument("--inplace", required=False, help="Shift file in place, creating a backup", action='store_true')
+  parser.add_argument("--outfile", required=False, help="New subtitle filename", type=str)
+  parser.add_argument("--strip-first", required=False, help="Clear first subtitle entry", action='store_true')
+  parser.add_argument("--strip-last", required=False, help="Clear last subtitle entry", action='store_true')
+
+  args = parser.parse_args()
+
+  if args.inplace is True:
+      if args.outfile == None:
+        args.outfile = str(args.file + ".backup")
+      else:
+        sys.exit(1)
+
+  if args.outfile == None:
+      args.outfile = str(args.file + ".new")
+
+  print("Opening subtitle file: {}".format(args.file))
+
+  with open(args.file, "r+") as file:
+    entryNumber = 0
+    text = ""
+    timestamp = ""
+    for line in file:
+      m1 = re.match(r"^([0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3}) --> ([0-9]{2}:[0-9]{2}:[0-9]{2},[0-9]{3})", line)
+      if line == "\n":
+        if (entryNumber > 0) and (timestamp is not None):
+          s = SubtitleEntry(entryNumber, text, timestamp.groups()[0], timestamp.groups()[1])
+          Subtitles.append(s)
+          text = ""
+          timestamp = ""
+          entryNumber = 0
+      elif re.match(r"^[0-9]+$", line):
+        entryNumber = int(line.rstrip())
+      elif m1:
+        timestamp = m1
+      else:
+        text += line
+
+  if args.inplace == True:
+    args.outfile = args.file
+    args.file = args.file + ".backup"
+    with open(args.file, 'w') as o:
+      print("Writing backup to " + args.file)
+      for entry in Subtitles:
+        print(entry.formatEntry(), file=o)
+
+  print("Updating subtitle file: " + args.outfile)
+  lastEntryNumber = Subtitles[-1].entryNumber
+  with open(args.outfile, 'w') as o:
+    print("Shifting all entries by {} seconds".format(args.seconds))
+    for idx, entry in enumerate(Subtitles):
+      if idx == 0:
+        print("First subtitle line: {}".format(entry.text))
+        if args.strip_first and entry.text != "":
+          print("Stripping first line - {}".format(entry.text))
+          entry.text = ""
+      if idx == lastEntryNumber - 1:
+        print("Last subtitle line: {}".format(entry.text))
+        if args.strip_last and entry.text != "":
+          print("Stripping last line - {}".format(entry.text))
+          entry.text = ""
+      entry.shift(args.seconds)
+      print(entry.formatEntry(), file=o)
+
+if __name__ == "__main__":
+  main()