Skip to content

Commit

Permalink
Updated README
Browse files Browse the repository at this point in the history
  • Loading branch information
ds2600 committed Feb 7, 2024
1 parent d11f033 commit f8b98fa
Show file tree
Hide file tree
Showing 19 changed files with 1,606 additions and 1,602 deletions.
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# autobk-p

AutoBk is a backup script to automatically backup obscure devices.

**Currently Supports:**
- Arris APEX-1000
- Arris CAP-1000
- Alpha CXC-HP
- Synamedia DCM 9902
- WISI Inca 4440
- Monroe OneNet
- Sonifex PSSend
- Arris Quartet
- Vecima TC600E
- Vecima CableVista
# autobk-r

AutoBk is a backup script to automatically backup obscure devices.

AutoBk-P is the original, although it is currently being rewritten in Rust ([AutoBk-R](https://github.com/ds2600/autobk-r))

[AutoBk Controller](https://github.com/ds2600/autobk-controller) is a web interface designed to work with either AutoBk-P or AutoBk-R.

**Currently Supports:**
- Arris APEX-1000
- Arris CAP-1000
- Alpha CXC-HP
- Synamedia DCM 9902
- WISI Inca 4440
- Monroe OneNet
- Sonifex PSSend
- Arris Quartet
- Vecima TC600E
- Vecima CableVista
196 changes: 98 additions & 98 deletions lib_autobk.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,98 @@
#!/usr/local/bin/python3.8
import logging as mLog
from logging import Formatter, FileHandler
from logging.handlers import RotatingFileHandler
from configparser import RawConfigParser
from subprocess import Popen, PIPE
from datetime import timedelta, datetime, time

## Exceptions
class AutoBkError(Exception): pass

###############################
# Global Configurations and Constants
oLog = mLog.getLogger() # root logger
sAt = 'autobk:%s=%s'
sCombo = '{} @ {}'
sAuthKey = '{}:{}'
sSubPath = "{}/{}"
sSqlTimeFmt = '%Y-%m-%d %H:%M:%S'

###############################
# Loads the configuration file and logger
def LoadConfig(sMod, *, sIniFile='./autobk.ini', bRotate=False):
global oLog, sAt
# Parse Config File
oINI = RawConfigParser()
oINI.read([sIniFile])

# Load Logging config
sIni = 'Logging'
sLogFile = oINI.get(sIni, 'File', fallback='./autobk.log')
iLogSize = oINI.getint(sIni, 'MaxSize', fallback=64000)
iLogCount = oINI.getint(sIni, 'Count', fallback=3)
sLogLevel = oINI.get(sIni, 'Level', fallback=mLog.INFO)
sAt = sMod + ':%s=%s'

# Logging Components
oF = Formatter('%(asctime)s - %(message)s', sSqlTimeFmt)
oH = RotatingFileHandler(sLogFile, 'a', iLogSize, iLogCount) if bRotate else FileHandler(sLogFile)
oH.setFormatter(oF)

# Setup Loggers
oLog.setLevel(mLog.WARNING)
oLog.addHandler(oH)
oLog = mLog.getLogger('AutoBk') # Switch to local logger to avoid spam from other modules
oLog.setLevel(sLogLevel)
oLog.addHandler(oH)
oLog.propagate = False

return (oINI, oLog, sAt)

###############################
# Returns the next iWeekday@iHour from tFrom
def NextWeekday(tFrom, iWeekday, iHour, iWeeks=1):
iOffset = iWeekday - tFrom.isoweekday()
if (iOffset > 0): iWeeks -= 1
iOffset += iWeeks * 7
return datetime.combine(tFrom + timedelta(days=iOffset), time(hour=iHour), tFrom.tzinfo)

###############################
# Executes a script in a new process and waits for completion
def CallScript(sName, sScript, *, lsArg=None, iTimeout=60, bOutIsErr=True):
# Prepare arguments for process call
lsParam = ['python3.8', sScript]
if (lsArg is not None): lsParam += lsArg

# Execute script
oLog.info(sAt, sName, 'calling')
oProc = Popen(lsParam, stdout=PIPE, text=True)
sOut = None

# Wait for completion
try:
(sOut, sErr) = oProc.communicate(timeout=iTimeout)
except Exception as oErr:
oLog.error(sAt, sName, 'timeout')
oProc.kill()

if (oProc.returncode == 0):
oLog.info(sAt, sName, 'complete')
return None if (bOutIsErr) else sOut
else:
oLog.error(sAt, sName, 'failed')
return sOut if (bOutIsErr) else None

###############################
# Sends an HTTP request and returns the response
def HttpRequest(oHttpCnx, sURL, dnHdrs, *, bPost=False, bData=True, sMsg=None, sFallbackURL=None):
# Send HTTP transfer request message to get a file
oHttpCnx.request('POST' if (bPost) else 'GET', sURL, sMsg, dnHdrs)
oResponse = oHttpCnx.getresponse()
if (oResponse.status == 200 or oResponse.status == 302):
return oResponse.read() if bData else oResponse
elif (oResponse.status == 404 and sFallbackURL is not None):
oResponse.read() # Must read all data before trying fallback
return HttpRequest(oHttpCnx, sFallbackURL, dnHdrs, bPost=bPost, bData=bData, sMsg=sMsg)
else:
raise AutoBkError('Bad HTTP Response: {}'.format(oResponse.status))
#!/usr/local/bin/python3.8
import logging as mLog
from logging import Formatter, FileHandler
from logging.handlers import RotatingFileHandler
from configparser import RawConfigParser
from subprocess import Popen, PIPE
from datetime import timedelta, datetime, time

## Exceptions
class AutoBkError(Exception): pass

###############################
# Global Configurations and Constants
oLog = mLog.getLogger() # root logger
sAt = 'autobk:%s=%s'
sCombo = '{} @ {}'
sAuthKey = '{}:{}'
sSubPath = "{}/{}"
sSqlTimeFmt = '%Y-%m-%d %H:%M:%S'

###############################
# Loads the configuration file and logger
def LoadConfig(sMod, *, sIniFile='./autobk.ini', bRotate=False):
global oLog, sAt
# Parse Config File
oINI = RawConfigParser()
oINI.read([sIniFile])

# Load Logging config
sIni = 'Logging'
sLogFile = oINI.get(sIni, 'File', fallback='./autobk.log')
iLogSize = oINI.getint(sIni, 'MaxSize', fallback=64000)
iLogCount = oINI.getint(sIni, 'Count', fallback=3)
sLogLevel = oINI.get(sIni, 'Level', fallback=mLog.INFO)
sAt = sMod + ':%s=%s'

# Logging Components
oF = Formatter('%(asctime)s - %(message)s', sSqlTimeFmt)
oH = RotatingFileHandler(sLogFile, 'a', iLogSize, iLogCount) if bRotate else FileHandler(sLogFile)
oH.setFormatter(oF)

# Setup Loggers
oLog.setLevel(mLog.WARNING)
oLog.addHandler(oH)
oLog = mLog.getLogger('AutoBk') # Switch to local logger to avoid spam from other modules
oLog.setLevel(sLogLevel)
oLog.addHandler(oH)
oLog.propagate = False

return (oINI, oLog, sAt)

###############################
# Returns the next iWeekday@iHour from tFrom
def NextWeekday(tFrom, iWeekday, iHour, iWeeks=1):
iOffset = iWeekday - tFrom.isoweekday()
if (iOffset > 0): iWeeks -= 1
iOffset += iWeeks * 7
return datetime.combine(tFrom + timedelta(days=iOffset), time(hour=iHour), tFrom.tzinfo)

###############################
# Executes a script in a new process and waits for completion
def CallScript(sName, sScript, *, lsArg=None, iTimeout=60, bOutIsErr=True):
# Prepare arguments for process call
lsParam = ['python3.8', sScript]
if (lsArg is not None): lsParam += lsArg

# Execute script
oLog.info(sAt, sName, 'calling')
oProc = Popen(lsParam, stdout=PIPE, text=True)
sOut = None

# Wait for completion
try:
(sOut, sErr) = oProc.communicate(timeout=iTimeout)
except Exception as oErr:
oLog.error(sAt, sName, 'timeout')
oProc.kill()

if (oProc.returncode == 0):
oLog.info(sAt, sName, 'complete')
return None if (bOutIsErr) else sOut
else:
oLog.error(sAt, sName, 'failed')
return sOut if (bOutIsErr) else None

###############################
# Sends an HTTP request and returns the response
def HttpRequest(oHttpCnx, sURL, dnHdrs, *, bPost=False, bData=True, sMsg=None, sFallbackURL=None):
# Send HTTP transfer request message to get a file
oHttpCnx.request('POST' if (bPost) else 'GET', sURL, sMsg, dnHdrs)
oResponse = oHttpCnx.getresponse()
if (oResponse.status == 200 or oResponse.status == 302):
return oResponse.read() if bData else oResponse
elif (oResponse.status == 404 and sFallbackURL is not None):
oResponse.read() # Must read all data before trying fallback
return HttpRequest(oHttpCnx, sFallbackURL, dnHdrs, bPost=bPost, bData=bData, sMsg=sMsg)
else:
raise AutoBkError('Bad HTTP Response: {}'.format(oResponse.status))
Loading

0 comments on commit f8b98fa

Please sign in to comment.