Arguments are working :fingers_crossed:
This commit is contained in:
parent
7b8fbf672b
commit
987eddbf00
5 changed files with 172 additions and 69 deletions
|
@ -26,9 +26,7 @@ import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from version import version
|
from version import version
|
||||||
|
|
||||||
from plugins.config import Default
|
|
||||||
from plugins.config import NoDefault
|
from plugins.config import NoDefault
|
||||||
from plugins.config import Flags
|
|
||||||
|
|
||||||
class Congloggerate:
|
class Congloggerate:
|
||||||
def __init__(self, loggers):
|
def __init__(self, loggers):
|
||||||
|
@ -81,12 +79,9 @@ def main():
|
||||||
Plugin("append_type", importlib.import_module("plugins.default.append_type")),
|
Plugin("append_type", importlib.import_module("plugins.default.append_type")),
|
||||||
Plugin("ssh", importlib.import_module("plugins.default.ssh")),
|
Plugin("ssh", importlib.import_module("plugins.default.ssh")),
|
||||||
]
|
]
|
||||||
plugins = {
|
plugins = {}
|
||||||
"logger": [],
|
for type in [ "logger", "source", "name", "upload" ]:
|
||||||
"source": [],
|
plugins[type] = { "active": [], "inactive": [] }
|
||||||
"name": [],
|
|
||||||
"upload": [],
|
|
||||||
}
|
|
||||||
|
|
||||||
# Load external plugins
|
# Load external plugins
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
@ -102,6 +97,20 @@ def main():
|
||||||
sys.dont_write_bytecode = False
|
sys.dont_write_bytecode = False
|
||||||
|
|
||||||
# Set plugin configurations from config file
|
# Set plugin configurations from config file
|
||||||
|
# Load plugin arguments and detect conflicts
|
||||||
|
error = False
|
||||||
|
argument_map = {}
|
||||||
|
used_arguments = {}
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog = "SSHare",
|
||||||
|
description = "Upload files to a server via ssh",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-v",
|
||||||
|
"--version",
|
||||||
|
action="version",
|
||||||
|
version=f"%(prog)s version {version}",
|
||||||
|
)
|
||||||
if config.get("plugins") == None:
|
if config.get("plugins") == None:
|
||||||
config["plugins"] = {}
|
config["plugins"] = {}
|
||||||
for plugin in plugins_flat:
|
for plugin in plugins_flat:
|
||||||
|
@ -109,33 +118,34 @@ def main():
|
||||||
plugin_config = config["plugins"].get(plugin.name)
|
plugin_config = config["plugins"].get(plugin.name)
|
||||||
if plugin_config != None:
|
if plugin_config != None:
|
||||||
for config_entry in plugin_config.items():
|
for config_entry in plugin_config.items():
|
||||||
plugin.module.config[config_entry[0]] = Default(config_entry[1])
|
plugin.module.config[config_entry[0]] = config_entry[1]
|
||||||
|
|
||||||
# Flatten plugin configs
|
|
||||||
class PluginConfig: pass
|
|
||||||
error = False
|
|
||||||
for plugin in plugins_flat:
|
|
||||||
if hasattr(plugin.module, "config"):
|
|
||||||
config = plugin.module.config
|
|
||||||
plugin.module.config = PluginConfig()
|
|
||||||
for config_entry in config.items():
|
|
||||||
if isinstance(config_entry[1], NoDefault):
|
|
||||||
logger.error(f"{plugin.name} > Error: Value '{config_entry[0]}' has no default value and must be specified explicitly")
|
|
||||||
error = True
|
|
||||||
elif isinstance(config_entry[1], Default):
|
|
||||||
setattr(plugin.module.config, config_entry[0], config_entry[1].value)
|
|
||||||
else:
|
else:
|
||||||
setattr(plugin.module.config, config_entry[0], config_entry[1])
|
setattr(plugin.module, "config", {})
|
||||||
|
if hasattr(plugin.module, "args"):
|
||||||
|
for arg_name, arg in plugin.module.args.items():
|
||||||
|
if arg.is_valid():
|
||||||
|
arg.set_for_plugin(plugin)
|
||||||
|
def check_flag(flag):
|
||||||
|
if flag in used_arguments:
|
||||||
|
logger.error(f"Error: Argument '{arg_name}' for plugin '{plugin.name}' has conflict. Flag '{flag}' is also used by plugin '{used_arguments[arg.short]}'")
|
||||||
|
error = True
|
||||||
|
check_flag(arg.short)
|
||||||
|
check_flag(arg.long)
|
||||||
|
arg.add(parser, used_arguments)
|
||||||
|
argument_map[arg.dest] = plugin, arg_name
|
||||||
|
else:
|
||||||
|
logger.error(f"Error: Argument '{arg_name}' must set either one or both of short and long flag parameters")
|
||||||
|
error = True
|
||||||
if error:
|
if error:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Initialise plugins
|
arguments = parser.parse_args()
|
||||||
for plugin in plugins_flat:
|
for arg, (plugin, config) in list(argument_map.items()):
|
||||||
setattr(plugin.module, "logger", logger)
|
if getattr(arguments, arg):
|
||||||
if hasattr(plugin.module, "init"):
|
plugin.module.config[config] = getattr(arguments, arg)
|
||||||
plugin.module.init()
|
del argument_map[arg]
|
||||||
|
|
||||||
# Sort plugins by type
|
# Sort plugins by type and check activation criteria
|
||||||
error = False
|
error = False
|
||||||
for plugin in plugins_flat:
|
for plugin in plugins_flat:
|
||||||
if isinstance(plugin.module.plugin_type, str):
|
if isinstance(plugin.module.plugin_type, str):
|
||||||
|
@ -146,24 +156,73 @@ def main():
|
||||||
logger.error(f"Error: Plugin '{plugin.name}' has an invalid plugin type '{plugin_type}'")
|
logger.error(f"Error: Plugin '{plugin.name}' has an invalid plugin type '{plugin_type}'")
|
||||||
error = True
|
error = True
|
||||||
else:
|
else:
|
||||||
plugins_of_type.append(plugin)
|
active = True
|
||||||
|
if hasattr(plugin.module, "activate"):
|
||||||
|
criteria = plugin.module.activate
|
||||||
|
if isinstance(plugin.module.activate, dict):
|
||||||
|
criteria = plugin.module.activate.get(plugin_type)
|
||||||
|
if criteria != None:
|
||||||
|
for criterion in criteria:
|
||||||
|
active = not plugin.module.args[criterion].dest in argument_map
|
||||||
|
if not active:
|
||||||
|
break
|
||||||
|
plugins_of_type["active" if active else "inactive"].append(plugin)
|
||||||
|
for plugin_type, plugins_of_type in plugins.items():
|
||||||
|
if len(plugins_of_type["active"]) == 0 and plugin_type != "logger":
|
||||||
|
if len(plugins_of_type["inactive"]) == 0:
|
||||||
|
logger.error(f"No '{plugin_type}' plugins available. Atleast one must be provided")
|
||||||
|
else:
|
||||||
|
logger.error(f"No '{plugin_type}' plugins activated. Activate at least one of:")
|
||||||
|
for plugin in plugins_of_type["inactive"]:
|
||||||
|
logger.error(f"{plugin.name}:")
|
||||||
|
criteria = plugin.module.activate
|
||||||
|
if isinstance(plugin.module.activate, dict):
|
||||||
|
criteria = plugin.module.activate[plugin_type]
|
||||||
|
for criterion in criteria:
|
||||||
|
logger.error(f" {plugin.module.args[criterion].pretty()}")
|
||||||
|
error = True
|
||||||
if error:
|
if error:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
logger = Congloggerate([ logger.module for logger in plugins["logger"] ])
|
# Flatten plugin configs
|
||||||
|
error = False
|
||||||
|
class PluginConfig: pass
|
||||||
|
for plugin in plugins_flat:
|
||||||
|
if hasattr(plugin.module, "config"):
|
||||||
|
config = plugin.module.config
|
||||||
|
plugin.module.config = PluginConfig()
|
||||||
|
for config_entry in config.items():
|
||||||
|
if config_entry[1] == NoDefault:
|
||||||
|
logger.error(f"Error: Value 'plugins.{plugin.name}.{config_entry[0]}' has no default value and must be specified explicitly")
|
||||||
|
error = True
|
||||||
|
else:
|
||||||
|
setattr(plugin.module.config, config_entry[0], config_entry[1])
|
||||||
|
if error:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Initialise plugins
|
||||||
|
for plugin in plugins_flat:
|
||||||
|
setattr(plugin.module, "logger", logger)
|
||||||
|
if hasattr(plugin.module, "init"):
|
||||||
|
error = error or plugin.module.init()
|
||||||
|
|
||||||
|
logger = Congloggerate([ logger.module for logger in plugins["logger"]["active"] ])
|
||||||
|
|
||||||
sources = []
|
sources = []
|
||||||
for plugin in plugins["source"]:
|
for plugin in plugins["source"]["active"]:
|
||||||
sources.append(plugin.module.get())
|
sources.append(plugin.module.get())
|
||||||
|
if len(sources) == 0:
|
||||||
|
logger.error("Error: No sources provided. Must activate at least one source plugin")
|
||||||
|
log_activations(logger, plugins["source"])
|
||||||
|
|
||||||
for index, source in enumerate(sources):
|
for index, source in enumerate(sources):
|
||||||
name = ""
|
name = ""
|
||||||
for plugin in plugins["name"]:
|
for plugin in plugins["name"]["active"]:
|
||||||
name = plugin.module.name(name, source)
|
name = plugin.module.name(name, source)
|
||||||
sources[index] = name, source
|
sources[index] = name, source
|
||||||
|
|
||||||
for (name, source) in sources:
|
for (name, source) in sources:
|
||||||
for plugin in plugins["upload"]:
|
for plugin in plugins["upload"]["active"]:
|
||||||
plugin.module.upload(name, source)
|
plugin.module.upload(name, source)
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -174,12 +233,6 @@ def parse_arguments():
|
||||||
description = "Upload files to a server via ssh",
|
description = "Upload files to a server via ssh",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"-v",
|
|
||||||
"--version",
|
|
||||||
action="version",
|
|
||||||
version=f"%(prog)s version {version}",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-l",
|
"-l",
|
||||||
"--latest",
|
"--latest",
|
||||||
|
@ -206,7 +259,6 @@ def parse_arguments():
|
||||||
const=True,
|
const=True,
|
||||||
help="Copy the resultant URL to the clipboard",
|
help="Copy the resultant URL to the clipboard",
|
||||||
)
|
)
|
||||||
arguments = parser.parse_args()
|
|
||||||
|
|
||||||
return arguments
|
return arguments
|
||||||
|
|
||||||
|
|
|
@ -12,16 +12,63 @@
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# You should have received a copy of the GNU General Public License along with
|
||||||
# SSHare. If not, see <https://www.gnu.org/licenses/>.
|
# SSHare. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
class NoDefault:
|
class NoDefault: pass
|
||||||
def __init__(self, flags=None):
|
|
||||||
self.flags = flags
|
|
||||||
|
|
||||||
class Default:
|
class Argument:
|
||||||
def __init__(self, value, flags=None):
|
def __init__(self,
|
||||||
self.value = value
|
short=None,
|
||||||
self.flags = flags
|
long=None,
|
||||||
|
action='store',
|
||||||
class Flags:
|
nargs=None,
|
||||||
def __init__(self, short=None, long=None):
|
const=None,
|
||||||
|
default=None,
|
||||||
|
type=str,
|
||||||
|
choices=None,
|
||||||
|
required=False,
|
||||||
|
help=None,
|
||||||
|
metavar=None):
|
||||||
self.short = short
|
self.short = short
|
||||||
self.long = long
|
self.long = long
|
||||||
|
self.action = action
|
||||||
|
self.nargs = nargs
|
||||||
|
self.const = const
|
||||||
|
self.default = default
|
||||||
|
self.type = type
|
||||||
|
self.choices = choices
|
||||||
|
self.help = help
|
||||||
|
self.metavar = metavar or self.long or self.short
|
||||||
|
|
||||||
|
def is_valid(self):
|
||||||
|
return (self.short != None and self.short != "") or (self.long != None and self.long != "")
|
||||||
|
|
||||||
|
def pretty(self):
|
||||||
|
if self.short and self.long:
|
||||||
|
pretty = f"-{self.short}, --{self.long}"
|
||||||
|
elif self.long:
|
||||||
|
pretty = f"--{self.long}"
|
||||||
|
else:
|
||||||
|
pretty = f"-{self.short}"
|
||||||
|
return pretty + f" {self.help}"
|
||||||
|
|
||||||
|
def set_for_plugin(self, plugin):
|
||||||
|
self.plugin = plugin
|
||||||
|
self.dest = f"{plugin.name}_{self.metavar}"
|
||||||
|
|
||||||
|
def add(self, parser, used_arguments):
|
||||||
|
parser.add_argument(
|
||||||
|
f"-{self.short}",
|
||||||
|
f"--{self.long}",
|
||||||
|
action=self.action,
|
||||||
|
nargs=self.nargs,
|
||||||
|
const=self.const,
|
||||||
|
default=self.default,
|
||||||
|
type=self.type,
|
||||||
|
choices=self.choices,
|
||||||
|
help=self.help,
|
||||||
|
metavar=self.metavar,
|
||||||
|
dest=self.dest,
|
||||||
|
)
|
||||||
|
if self.short:
|
||||||
|
used_arguments["short"] = self.plugin
|
||||||
|
if self.long:
|
||||||
|
used_arguments["long"] = self.plugin
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ..config import Default
|
from ..config import Argument
|
||||||
from ..config import Flags
|
|
||||||
from ..source import File
|
from ..source import File
|
||||||
|
|
||||||
plugin_type = "name"
|
plugin_type = "name"
|
||||||
|
@ -23,6 +22,13 @@ plugin_type = "name"
|
||||||
config = {
|
config = {
|
||||||
"base": 62,
|
"base": 62,
|
||||||
}
|
}
|
||||||
|
args = {
|
||||||
|
"base": Argument(
|
||||||
|
short="b",
|
||||||
|
long="base",
|
||||||
|
help="Set the numeric base to use for the current time"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
if not isinstance(config.base, int):
|
if not isinstance(config.base, int):
|
||||||
|
|
|
@ -12,19 +12,19 @@
|
||||||
# You should have received a copy of the GNU General Public License along with
|
# You should have received a copy of the GNU General Public License along with
|
||||||
# SSHare. If not, see <https://www.gnu.org/licenses/>.
|
# SSHare. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from ..config import Argument
|
||||||
from ..config import NoDefault
|
from ..config import NoDefault
|
||||||
from ..config import Flags
|
|
||||||
from ..source import File
|
from ..source import File
|
||||||
|
|
||||||
plugin_type = "source"
|
plugin_type = "source"
|
||||||
|
|
||||||
config = {
|
activate = [ "file" ]
|
||||||
"file": NoDefault(
|
args = {
|
||||||
flags=Flags(
|
"file": Argument(
|
||||||
short="f",
|
short="f",
|
||||||
long="file"
|
long="file",
|
||||||
|
help="Upload a file"
|
||||||
)
|
)
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def get():
|
def get():
|
||||||
|
|
|
@ -15,23 +15,21 @@
|
||||||
import getpass
|
import getpass
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from ..config import Default
|
|
||||||
from ..config import NoDefault
|
from ..config import NoDefault
|
||||||
from ..config import Flags
|
|
||||||
from ..source import File
|
from ..source import File
|
||||||
from ..source import Raw
|
from ..source import Raw
|
||||||
|
|
||||||
plugin_type = "upload"
|
plugin_type = "upload"
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"host": NoDefault(),
|
"host": NoDefault,
|
||||||
"path": NoDefault(),
|
"path": NoDefault,
|
||||||
"port": 22,
|
"port": 22,
|
||||||
"user": getpass.getuser(),
|
"user": getpass.getuser(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def upload(name, source):
|
def upload(name, source):
|
||||||
logger.info(f"Uploading to {config.user}@{config.host}/{config.port}:{config.path}/{name}")
|
logger.info(f"Uploading to {config.user}@{config.host}:{config.path}/{name} on port {config.port}")
|
||||||
if isinstance(source, File):
|
if isinstance(source, File):
|
||||||
command = [
|
command = [
|
||||||
"scp",
|
"scp",
|
||||||
|
|
Loading…
Reference in a new issue