Implemented SFTP, TMDB, and default configs.
This commit is contained in:
parent
2b7538de71
commit
542b736d6e
134
Universal/network/sftpservice.py
Normal file
134
Universal/network/sftpservice.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
class SFTPService:
|
||||||
|
def __init__(self, logger, ioservice, universal):
|
||||||
|
self.logger = logger
|
||||||
|
self.ioservice = ioservice
|
||||||
|
self.universal = universal
|
||||||
|
self.report(2, "Initializing")
|
||||||
|
try:
|
||||||
|
import paramiko
|
||||||
|
self.enabled = True
|
||||||
|
self.paramiko = paramiko
|
||||||
|
self.report(2, "API Found")
|
||||||
|
except ImportError:
|
||||||
|
self.enabled = False
|
||||||
|
self.report(3, "Module 'paramiko' was not found")
|
||||||
|
self.report(3, "Disabling SFTP features")
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
|
def connectSFTPServer(self, host, port, username, password, key_file, key_type):
|
||||||
|
self.report(2, "connectSFTPServer")
|
||||||
|
self.host = host
|
||||||
|
self.port = int(port)
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
self.key_file = key_file
|
||||||
|
self.key_type = key_type
|
||||||
|
tmp_key = None
|
||||||
|
if key_file != None:
|
||||||
|
if key_file.lower().find("dsa") != -1:
|
||||||
|
tmp_key = self.paramiko.DSAKey.from_private_key_file(key_file)
|
||||||
|
elif key_file.lower().find("rsa") != -1:
|
||||||
|
tmp_key = self.paramiko.RSAKey.from_private_key_file(key_file)
|
||||||
|
try:
|
||||||
|
tmp = self.paramiko.Transport((host, port))
|
||||||
|
tmp.connect(None, username, password, tmp_key)
|
||||||
|
except:
|
||||||
|
self.connected = False
|
||||||
|
try:
|
||||||
|
self.sftp_socket = self.paramiko.SFTPClient.from_transport(tmp)
|
||||||
|
self.connected = True
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
self.connected = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
def attemptReconnect(self, retries=1):
|
||||||
|
self.report(2, "attemptReconnect")
|
||||||
|
self.connected = False
|
||||||
|
if retries == 1:
|
||||||
|
self.report(1, "Lost connect to SFTP Server...")
|
||||||
|
if retries <= 5:
|
||||||
|
self.report(1, "Attempt #" + str(retries) + "... Attemping to reconnect in 15 seconds...")
|
||||||
|
self.closeConnection()
|
||||||
|
time.sleep(15)
|
||||||
|
if self.connectSFTPServer(self.host, self.port, self.username, self.password, self.key_file, self.key_type):
|
||||||
|
self.logger(0, "Successfully reconnected to SFTP Server")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return self.attemptReconnect(retries + 1)
|
||||||
|
else:
|
||||||
|
self.report(3, "Could not reconnect to SFTP Server...")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def closeConnection(self):
|
||||||
|
self.report(2, "closeConnection")
|
||||||
|
if self.sftp_socket is not None:
|
||||||
|
self.sftp_socket.close()
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
|
def getFileSize(self, path, retried=0):
|
||||||
|
self.report(2, "getFileSize")
|
||||||
|
try:
|
||||||
|
return str(self.sftp_socket.lstat(path)).split()[4]
|
||||||
|
except IOError:
|
||||||
|
return None
|
||||||
|
except:
|
||||||
|
if retried == 0:
|
||||||
|
if self.attemptReconnect():
|
||||||
|
return self.getFileSize(path, 1)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def doesFileExists(self, path):
|
||||||
|
self.report(2, "doesFileExists")
|
||||||
|
if self.getFileSize(path):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def createFolder(self, path):
|
||||||
|
self.report(2, "createFolder")
|
||||||
|
tmp_full_path = path.split("/")
|
||||||
|
tmp_path = tmp_full_path[0]
|
||||||
|
for current_path in tmp_full_path:
|
||||||
|
if tmp_path != current_path:
|
||||||
|
tmp_path = tmp_path + "/" + current_path
|
||||||
|
try:
|
||||||
|
self.sftp_socket.mkdir(tmp_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def deleteFile(self, path):
|
||||||
|
self.report(2, "deleteFile")
|
||||||
|
try:
|
||||||
|
self.sftp_socket.remove(path)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
self.report(3, "Failed to delete file")
|
||||||
|
|
||||||
|
def uploadFile(self, input_path, output_path, retried=0):
|
||||||
|
self.report(2, "uploadFile")
|
||||||
|
try:
|
||||||
|
self.createFolder(output_path.replace(output_path.split("/")[-1], ""))
|
||||||
|
if self.doesFileExists(output_path):
|
||||||
|
self.deleteFile(output_path)
|
||||||
|
return self.sftp_socket.put(input_path, output_path)
|
||||||
|
except:
|
||||||
|
if retried == 0:
|
||||||
|
if self.attemptReconnect():
|
||||||
|
return self.uploadFile(input_path, output_path, 1)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def report(self, level, message):
|
||||||
|
match level:
|
||||||
|
case 0:
|
||||||
|
self.logger.infoReport("[SFTP] " + message)
|
||||||
|
case 1:
|
||||||
|
self.logger.warningReport("[SFTP] " + message)
|
||||||
|
case 2:
|
||||||
|
self.logger.debugReport("[SFTP] " + message)
|
||||||
|
case 3:
|
||||||
|
self.logger.errorReport("[SFTP] " + message)
|
@ -1,18 +1,28 @@
|
|||||||
class TMDBService:
|
class TMDBService:
|
||||||
def __init__(self, loggingservice):
|
def __init__(self, loggingservice, ioservice):
|
||||||
self.logger = loggingservice
|
|
||||||
self.report(2, "Initializing")
|
self.report(2, "Initializing")
|
||||||
try:
|
try:
|
||||||
import tmdbsimple
|
import tmdbsimple
|
||||||
self.tmdb = tmdbsimple
|
self.tmdb = tmdbsimple
|
||||||
self.report(2, "API Found")
|
self.report(2, "API Found")
|
||||||
|
self.logger = loggingservice
|
||||||
|
self.ioservice = ioservice
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
self.tmdb_key = None
|
||||||
|
self.addDefaultConfiguration()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
self.report(3, "Module 'tmdbsimple' was not found")
|
self.report(3, "Module 'tmdbsimple' was not found")
|
||||||
self.report(3, "Disabling TMDB API")
|
self.report(3, "Disabling TMDB API")
|
||||||
self.enabled = False
|
self.enabled = False
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
|
||||||
|
def addDefaultConfiguration(self):
|
||||||
|
self.ioservice.addConfiguration("TMDB Service", "TMDB API Key", "NONE")
|
||||||
|
|
||||||
|
def updateConfiguration(self):
|
||||||
|
if self.tmdb_key == None:
|
||||||
|
self.tmdb_key = self.ioservice.getConfigurationStr("TMDB Service", "TMDB API Key")
|
||||||
|
|
||||||
def report(self, level, message):
|
def report(self, level, message):
|
||||||
match level:
|
match level:
|
||||||
case 0:
|
case 0:
|
||||||
@ -24,12 +34,13 @@ class TMDBService:
|
|||||||
case 3:
|
case 3:
|
||||||
self.logger.errorReport("[TMDB] " + message)
|
self.logger.errorReport("[TMDB] " + message)
|
||||||
|
|
||||||
def connectToTMDB(self, api_key):
|
def connectToTMDB(self):
|
||||||
self.report(2, "connectToTMDB")
|
self.report(2, "connectToTMDB")
|
||||||
if not self.connected:
|
if not self.connected:
|
||||||
try:
|
try:
|
||||||
self.report(2, "Attempting to Login")
|
self.report(2, "Attempting to Login")
|
||||||
self.tmdb.API_KEY = api_key
|
self.updateConfiguration()
|
||||||
|
self.tmdb.API_KEY = self.tmdb_key
|
||||||
self.connected = True
|
self.connected = True
|
||||||
self.report(2, "Connected")
|
self.report(2, "Connected")
|
||||||
except self.tmdb.APIKeyError:
|
except self.tmdb.APIKeyError:
|
||||||
|
@ -6,14 +6,13 @@ def generateConfigs():
|
|||||||
generateVideoConfig()
|
generateVideoConfig()
|
||||||
|
|
||||||
def generateProcessorConfigs():
|
def generateProcessorConfigs():
|
||||||
ioservice.addConfiguration("Video Configuration", "TMDB API Key")
|
|
||||||
ioservice.addConfiguration("Video Configuration", "FFProbe Path")
|
ioservice.addConfiguration("Video Configuration", "FFProbe Path")
|
||||||
ioservice.addConfiguration("Video Configuration", "Encoder Path")
|
ioservice.addConfiguration("Video Configuration", "Encoder Path")
|
||||||
ioservice.addConfiguration("Video Configuration", "Sleep Timer (Seconds)", "100")
|
ioservice.addConfiguration("Video Configuration", "Sleep Timer (Seconds)", "100")
|
||||||
ioservice.addConfiguration("Video Configuration", "Blacklist Words", "1080p, 720p, 480p, 360p, x265, x264")
|
ioservice.addConfiguration("Video Configuration", "Blacklist Words", "1080p, 720p, 480p, 360p, x265, x264")
|
||||||
|
|
||||||
def generateServerConfig():
|
def generateServerConfig():
|
||||||
ioservice.addConfiguration("Server 1", "Type (SFTP/NONE)", "NONE")
|
ioservice.addConfiguration("Server 1", "Type", "NONE")
|
||||||
ioservice.addConfiguration("Server 1", "Host", "127.0.0.1")
|
ioservice.addConfiguration("Server 1", "Host", "127.0.0.1")
|
||||||
ioservice.addConfiguration("Server 1", "Port", "22")
|
ioservice.addConfiguration("Server 1", "Port", "22")
|
||||||
ioservice.addConfiguration("Server 1", "Username", "NONE")
|
ioservice.addConfiguration("Server 1", "Username", "NONE")
|
||||||
@ -37,3 +36,55 @@ def generateVideoConfig():
|
|||||||
ioservice.addConfiguration("Video Library 1", "Server", "None")
|
ioservice.addConfiguration("Video Library 1", "Server", "None")
|
||||||
ioservice.addConfiguration("Video Library 1", "Server Path", "/TV Shows/${NAME}/Season ${SEASON}/${NAME} S${SEASON}E${EPISODE}.${FORMAT}")
|
ioservice.addConfiguration("Video Library 1", "Server Path", "/TV Shows/${NAME}/Season ${SEASON}/${NAME} S${SEASON}E${EPISODE}.${FORMAT}")
|
||||||
ioservice.addConfiguration("Video Library 1", "Server Overwrite", "False")
|
ioservice.addConfiguration("Video Library 1", "Server Overwrite", "False")
|
||||||
|
|
||||||
|
class VideoSettings:
|
||||||
|
def __init__(self):
|
||||||
|
self.settings = {}
|
||||||
|
self.library = {}
|
||||||
|
self.server = {}
|
||||||
|
|
||||||
|
def updateEverything(self, num):
|
||||||
|
self.updateSettings()
|
||||||
|
self.updateLibrary(num)
|
||||||
|
|
||||||
|
def updateSettings(self):
|
||||||
|
tmp_ffprobe = ioservice.getConfigurationStr("Video Configuration", "FFProbe Path")
|
||||||
|
tmp_encoder = ioservice.getConfigurationStr("Video Configuration", "Encoder Path")
|
||||||
|
tmp_timer = ioservice.getConfigurationStr("Video Configuration", "Sleep Timer (Seconds)")
|
||||||
|
tmp_blacklist = ioservice.getConfigurationStr("Video Configuration", "Blacklist Words")
|
||||||
|
self.settings = {"FFProbe": tmp_ffprobe, "Encoder": tmp_encoder, "Timer": tmp_timer,
|
||||||
|
"Blacklist": tmp_blacklist}
|
||||||
|
|
||||||
|
def updateLibrary(self, num):
|
||||||
|
tmp_section = ("Video Library " + str(num))
|
||||||
|
tmp_name = ioservice.getConfigurationStr(tmp_section, "Directory Name")
|
||||||
|
tmp_input = ioservice.getConfigurationStr(tmp_section, "Input")
|
||||||
|
tmp_output = ioservice.getConfigurationStr(tmp_section, "Output")
|
||||||
|
tmp_database = ioservice.getConfigurationStr(tmp_section, "Database Service")
|
||||||
|
tmp_type = ioservice.getConfigurationStr(tmp_section, "Media Type")
|
||||||
|
tmp_compress = ioservice.getConfigurationBool(tmp_section, "Compress Video")
|
||||||
|
tmp_out_format = ioservice.getConfigurationStr(tmp_section, "Output Format")
|
||||||
|
tmp_dir_format = ioservice.getConfigurationStr(tmp_section, "Directory Format")
|
||||||
|
tmp_command = ioservice.getConfigurationStr(tmp_section, "Command")
|
||||||
|
tmp_srt_command = ioservice.getConfigurationStr(tmp_section, "Subtitle Command")
|
||||||
|
tmp_del_input = ioservice.getConfigurationBool(tmp_section, "Delete Input")
|
||||||
|
tmp_server = ioservice.getConfigurationStr(tmp_section, "Server")
|
||||||
|
tmp_server_path = ioservice.getConfigurationStr(tmp_section, "Server Path")
|
||||||
|
tmp_server_overwrite = ioservice.getConfigurationBool(tmp_section, "Server Overwrite")
|
||||||
|
self.library = {"Name": tmp_name, "Input": tmp_input, "Output": tmp_output, "Database": tmp_database,
|
||||||
|
"Type": tmp_type, "Compress": tmp_compress, "Format": tmp_out_format, "Directory": tmp_dir_format,
|
||||||
|
"Command": tmp_command, "SRT Command": tmp_srt_command, "Delete Input": tmp_del_input,
|
||||||
|
"Server": tmp_server, "Server Path": tmp_server_path, "Server Overwrite": tmp_server_overwrite}
|
||||||
|
|
||||||
|
def updateServer(self, num):
|
||||||
|
tmp_section = ("Server " + str(num))
|
||||||
|
tmp_type = ioservice.getConfigurationStr(tmp_section, "Type")
|
||||||
|
tmp_host = ioservice.getConfigurationStr(tmp_section, "Host")
|
||||||
|
tmp_port = ioservice.getConfigurationStr(tmp_section, "Port")
|
||||||
|
tmp_username = ioservice.getConfigurationStr(tmp_section, "Username")
|
||||||
|
tmp_password = ioservice.getConfigurationStr(tmp_section, "Password")
|
||||||
|
tmp_keyfile = ioservice.getConfigurationStr(tmp_section, "Key File")
|
||||||
|
tmp_keytype = ioservice.getConfigurationStr(tmp_section, "Key Type (RSA/DSA)")
|
||||||
|
tmp_root = ioservice.getConfigurationStr(tmp_section, "Media Root")
|
||||||
|
self.server = {"Type": tmp_type, "Host": tmp_host, "Port": tmp_port, "Username": tmp_username,
|
||||||
|
"Password": tmp_password, "Key File": tmp_keyfile, "Key Type": tmp_keytype, "Root": tmp_root}
|
||||||
|
Loading…
Reference in New Issue
Block a user