diff --git a/hello.txt b/hello.txt
deleted file mode 100644
index 980a0d5..0000000
--- a/hello.txt
+++ /dev/null
@@ -1 +0,0 @@
-Hello World!
diff --git a/pyproject.toml b/pyproject.toml
index c937898..b9b4472 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "sshare"
-version = "2.0.0"
+version = "1.1.0"
authors = [
{ name = "Gnarwhal", email = "git.aspect893@passmail.net" },
]
@@ -22,9 +22,9 @@ dependencies = [
[project.urls]
Homepage = "https://forge.monodon.me/Gnarwhal/sshare"
-Documentation = "https://forge.monodon.me/Gnarwhal/sshare/README.md#Usage"
+Documentation= "https://forge.monodon.me/Gnarwhal/sshare/README.md#Usage"
Repository = "https://forge.monodon.me/Gnarwhal/sshare"
Issues = "https://forge.monodon.me/Gnarwhal/sshare/issues"
[project.scripts]
-sshare = "sshare.main:main"
+sshare = "sshare.cli:main"
diff --git a/src/sshare/__main__.py b/src/sshare/__main__.py
index 2ae67cd..6545e2b 100644
--- a/src/sshare/__main__.py
+++ b/src/sshare/__main__.py
@@ -12,6 +12,6 @@
# You should have received a copy of the GNU General Public License along with
# SSHare. If not, see .
-from main import main
+from cli import main
main()
diff --git a/src/sshare/cli.py b/src/sshare/cli.py
new file mode 100644
index 0000000..87af8be
--- /dev/null
+++ b/src/sshare/cli.py
@@ -0,0 +1,200 @@
+# This file is part of SSHare.
+#
+# SSHare is free software: you can redistribute it and/or modify it under the terms of
+# the GNU General Public License as published by the Free Software Foundation,
+# either version 3 of the License, or (at your option) any later version.
+#
+# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# SSHare. If not, see .
+
+import argparse
+import getpass
+import os
+import os.path
+import pyclip
+import time
+import tomllib
+import subprocess
+import sys
+from sshare.version import version
+
+class Config:
+ def __init__(self):
+ config_directory = os.environ.get("XDG_CONFIG_DIR")
+ if config_directory == None:
+ config_directory = f"{os.environ["HOME"]}/.config"
+ _config = self._load_from_file(f"{config_directory}/sshare/config.toml")
+
+ self.source_directory = _config.get("source_directory")
+
+ host = _config.get("host")
+ if host == None:
+ print("Error: 'host' cannot be 'None'")
+ sys.exit(1)
+ self.host_protocol = host.get("protocol")
+ self.host_name = host.get("name")
+ self.host_port = host.get("port")
+ self.host_path = host.get("path")
+ if self.host_protocol == None:
+ self.host_protocol = "https"
+ if self.host_name == None:
+ print("Error: 'host.name' cannot be 'None'")
+ sys.exit(1)
+ if self.host_port == None:
+ self.host_port = ""
+ else:
+ self.host_port = f":{self.host_port}"
+ if self.host_path == None:
+ self.host_path = ""
+
+ ssh = _config.get("ssh")
+ if ssh == None:
+ print("Error: 'ssh' cannot be 'None'")
+ sys.exit(1)
+ self.ssh_port = ssh.get("port")
+ self.ssh_user = ssh.get("user")
+ self.ssh_path = ssh.get("path")
+ if self.ssh_port == None:
+ self.ssh_port = 22
+ if self.ssh_user == None:
+ self.ssh_user = getpass.getuser()
+ if self.ssh_path == None:
+ print("Error: 'ssh.path' cannot be 'None'")
+ sys.exit(1)
+
+ def _load_from_file(self, config_path):
+ with open(config_path, mode="rb") as file:
+ return tomllib.load(file)
+
+
+def rebase(number):
+ if number == 0:
+ return "0"
+ rebased = ""
+ while number != 0:
+ digit = number % 62
+ if digit < 10:
+ rebased = chr(digit + 48) + rebased
+ elif digit < 36:
+ rebased = chr(digit + 87) + rebased
+ else:
+ rebased = chr(digit + 29) + rebased
+ number = int(number / 62)
+ return rebased
+
+
+def main():
+ arguments = parse_arguments()
+
+ config = Config()
+
+ contents = b''
+ target_file_extension = ""
+ if arguments.latest or arguments.file != None:
+ file_path = ""
+ if arguments.latest:
+ if config.source_directory == "":
+ print("Option 'latest' requires source directory to be specified")
+ sys.exit(1)
+ file_path = _latest(config.source_directory)
+ else:
+ file_path = arguments.file
+ print(f"Uploading file '{file_path}'")
+
+ with open(file_path, mode="rb") as file:
+ contents = file.read()
+
+ (_, target_file_extension) = os.path.splitext(file_path)
+ elif arguments.paste:
+ print("Uploading contents of clipboard")
+ contents = pyclip.paste()
+ target_file_extension = ".txt"
+ else:
+ print("Error: must specify one of -f FILE, -l, -p")
+ sys.exit(1)
+
+ target_id = rebase(time.time_ns())
+ target_file_name = f"{target_id}{target_file_extension}"
+ target_file = f"{config.ssh_path}/{target_file_name}"
+ target_destination = f"{config.ssh_user}@{config.host_name}"
+ print(f"Uploading to host: {target_destination}, port: {config.ssh_port}, file: {target_file}")
+ process = subprocess.run([
+ "ssh",
+ f"-p {config.ssh_port}",
+ target_destination,
+ "-T",
+ f"cat - > {target_file}"
+ ],
+ input = contents,
+ )
+ if process.returncode != 0:
+ print("Error: failed to upload file")
+ sys.exit(1)
+
+ target_url = f"{config.host_protocol}://{config.host_name}{config.host_port}{config.host_path}/{target_file_name}"
+ print(f"File available at '{target_url}'")
+ if arguments.copy:
+ pyclip.copy(target_url)
+ print("URL copied to clipboard")
+
+ sys.exit(0)
+
+
+def parse_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}",
+ )
+ parser.add_argument(
+ "-l",
+ "--latest",
+ action="store_const",
+ const=True,
+ help="Upload the latest image from the source directory",
+ )
+ parser.add_argument(
+ "-p",
+ "--paste",
+ action="store_const",
+ const=True,
+ help="Upload the contents of the clipboard as a .txt file",
+ )
+ parser.add_argument(
+ "-f",
+ "--file",
+ help="Upload a file",
+ )
+ parser.add_argument(
+ "-c",
+ "--copy",
+ action="store_const",
+ const=True,
+ help="Copy the resultant URL to the clipboard",
+ )
+ arguments = parser.parse_args()
+
+ return arguments
+
+
+def _latest(directory, key=os.path.getmtime):
+ files = map(lambda file: f"{directory}/{file}", os.listdir(directory))
+ selection = next(files)
+ selection_key = key(selection)
+ for file in files:
+ new_key = key(file)
+ if new_key > selection_key:
+ selection = file
+ selection_key = key
+ return selection
diff --git a/src/sshare/main.py b/src/sshare/main.py
deleted file mode 100644
index 86e97b3..0000000
--- a/src/sshare/main.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-import argparse
-import getpass
-import importlib
-import importlib.util
-import os
-import os.path
-import pyclip
-import time
-import tomllib
-import subprocess
-import sys
-from pathlib import Path
-from version import version
-
-from plugins.config import NoDefault
-
-class Congloggerate:
- def __init__(self, loggers):
- def info(message):
- for logger in loggers:
- logger.info(message)
-
- def warn(message):
- for logger in loggers:
- logger.warn(message)
-
- def error(message):
- for logger in loggers:
- logger.error(message)
-
- self.info = info
- self.warn = warn
- self.error = error
-
- fatalicize(self)
-
-def fatalicize(logger):
- def fatal(message):
- logger.error(message)
- sys.exit(1)
- setattr(logger, "fatal", fatal)
-
-class Plugin:
- def __init__(self, name, module):
- self.name = name
- self.module = module
-
-def main():
- config_directory = Path(os.environ.get("XDG_CONFIG_DIR") or f"{os.environ["HOME"]}/.config") / "sshare"
- with open(config_directory / "config.toml", mode="rb") as file:
- config = tomllib.load(file)
-
- # Load command line early and set it as the active logger
- # so that it can be used to report errors while loading and
- # configuring plugins
- # i.e. before other logging plugins have had a chance to be initialised
- logger = importlib.import_module("plugins.default.command_line")
- fatalicize(logger)
-
- # Load inbuilt plugins
- plugins_flat = [
- Plugin("command_line", logger),
- Plugin("file", importlib.import_module("plugins.default.file")),
- Plugin("current_time", importlib.import_module("plugins.default.current_time")),
- Plugin("append_type", importlib.import_module("plugins.default.append_type")),
- Plugin("ssh", importlib.import_module("plugins.default.ssh")),
- ]
- plugins = {}
- for type in [ "logger", "source", "name", "upload" ]:
- plugins[type] = { "active": [], "inactive": [] }
-
- # Load external plugins
- sys.dont_write_bytecode = True
- for plugin in (config_directory / "plugins").iterdir():
- if plugin.is_file():
- module_spec = importlib.util.spec_from_file_location(
- plugin.stem,
- plugin.as_posix(),
- )
- module = importlib.util.module_from_spec(module_spec)
- module_spec.loader.exec_module(module)
- plugins_flat.append(Plugin(plugin.stem, module))
- sys.dont_write_bytecode = False
-
- # 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:
- config["plugins"] = {}
- for plugin in plugins_flat:
- if hasattr(plugin.module, "config"):
- plugin_config = config["plugins"].get(plugin.name)
- if plugin_config != None:
- for config_entry in plugin_config.items():
- plugin.module.config[config_entry[0]] = config_entry[1]
- else:
- 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:
- sys.exit(1)
-
- arguments = parser.parse_args()
- for arg, (plugin, config) in list(argument_map.items()):
- if getattr(arguments, arg):
- plugin.module.config[config] = getattr(arguments, arg)
- del argument_map[arg]
-
- # Sort plugins by type and check activation criteria
- error = False
- for plugin in plugins_flat:
- if isinstance(plugin.module.plugin_type, str):
- plugin.module.plugin_type = [ plugin.module.plugin_type ]
- for plugin_type in plugin.module.plugin_type:
- plugins_of_type = plugins.get(plugin_type)
- if plugins_of_type == None:
- logger.error(f"Error: Plugin '{plugin.name}' has an invalid plugin type '{plugin_type}'")
- error = True
- else:
- 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:
- sys.exit(1)
-
- # 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 = []
- for plugin in plugins["source"]["active"]:
- 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):
- name = ""
- for plugin in plugins["name"]["active"]:
- name = plugin.module.name(name, source)
- sources[index] = name, source
-
- for (name, source) in sources:
- for plugin in plugins["upload"]["active"]:
- plugin.module.upload(name, source)
-
- sys.exit(0)
-
-def parse_arguments():
- parser = argparse.ArgumentParser(
- prog = "SSHare",
- description = "Upload files to a server via ssh",
- )
-
- parser.add_argument(
- "-l",
- "--latest",
- action="store_const",
- const=True,
- help="Upload the latest image from the source directory",
- )
- parser.add_argument(
- "-p",
- "--paste",
- action="store_const",
- const=True,
- help="Upload the contents of the clipboard as a .txt file",
- )
- parser.add_argument(
- "-f",
- "--file",
- help="Upload a file",
- )
- parser.add_argument(
- "-c",
- "--copy",
- action="store_const",
- const=True,
- help="Copy the resultant URL to the clipboard",
- )
-
- return arguments
-
-
-def _latest(directory, key=os.path.getmtime):
- files = map(lambda file: f"{directory}/{file}", os.listdir(directory))
- selection = next(files)
- selection_key = key(selection)
- for file in files:
- new_key = key(file)
- if new_key > selection_key:
- selection = file
- selection_key = key
- return selection
diff --git a/src/sshare/plugins/config.py b/src/sshare/plugins/config.py
deleted file mode 100644
index 446bca2..0000000
--- a/src/sshare/plugins/config.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-class NoDefault: pass
-
-class Argument:
- def __init__(self,
- short=None,
- long=None,
- action='store',
- nargs=None,
- const=None,
- default=None,
- type=str,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- self.short = short
- 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
diff --git a/src/sshare/plugins/default/append_type.py b/src/sshare/plugins/default/append_type.py
deleted file mode 100644
index 8d65e3e..0000000
--- a/src/sshare/plugins/default/append_type.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-from ..source import File
-from ..source import Raw
-
-plugin_type = "name"
-
-def name(name, source):
- if isinstance(source, File):
- if source.path.is_dir():
- return name
- else:
- start = 1
- components = source.path.name.split(".")
- if components[0] == "":
- start += 1
- if start > len(components):
- return name
- else:
- return name + "." + ".".join(components[start:])
- elif isinstance(source, Raw):
- return name + f".{source.type}"
diff --git a/src/sshare/plugins/default/command_line.py b/src/sshare/plugins/default/command_line.py
deleted file mode 100644
index 6b86cce..0000000
--- a/src/sshare/plugins/default/command_line.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-plugin_type = "logger"
-
-def _print_with_color(color, message):
- print(f"\033[{color}m{message}\033[0m")
-
-def info(message):
- _print_with_color(0, message)
-
-def warn(message):
- _print_with_color(93, message)
-
-def error(message):
- _print_with_color(91, message)
diff --git a/src/sshare/plugins/default/current_time.py b/src/sshare/plugins/default/current_time.py
deleted file mode 100644
index 72b5ffe..0000000
--- a/src/sshare/plugins/default/current_time.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-import time
-
-from ..config import Argument
-from ..source import File
-
-plugin_type = "name"
-
-config = {
- "base": 62,
-}
-args = {
- "base": Argument(
- short="b",
- long="base",
- help="Set the numeric base to use for the current time"
- )
-}
-
-def init():
- if not isinstance(config.base, int):
- logger.fatal("Error: 'base' must be an integer")
- elif config.base < 2:
- logger.fatal("Error: 'base' cannot be less than 2")
- elif config.base > 62:
- logger.fatal("Error: 'base' cannot be greater than 62")
-
-def name(name, source):
- return name + _rebase(config.base, time.time_ns())
-
-def _rebase(base, number):
- if number == 0:
- return "0"
- if base == 10:
- return f"{number}"
- rebased = ""
- while number != 0:
- rebased = _number_to_char(number % base) + rebased
- number = int(number / base)
- return rebased
-
-def _number_to_char(number):
- if number < 10:
- return chr(number + 48)
- elif number < 36:
- return chr(number + 87)
- else:
- return chr(number + 29)
diff --git a/src/sshare/plugins/default/file.py b/src/sshare/plugins/default/file.py
deleted file mode 100644
index 9676bef..0000000
--- a/src/sshare/plugins/default/file.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-from ..config import Argument
-from ..config import NoDefault
-from ..source import File
-
-plugin_type = "source"
-
-activate = [ "file" ]
-args = {
- "file": Argument(
- short="f",
- long="file",
- help="Upload a file"
- )
-}
-
-def get():
- file = File(config.file)
- if file.path.is_dir():
- logger.info(f"Uploading directory '{config.file}'")
- else:
- logger.info(f"Uploading file '{config.file}'")
- return file
diff --git a/src/sshare/plugins/default/ssh.py b/src/sshare/plugins/default/ssh.py
deleted file mode 100644
index b06325d..0000000
--- a/src/sshare/plugins/default/ssh.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-import getpass
-import subprocess
-
-from ..config import NoDefault
-from ..source import File
-from ..source import Raw
-
-plugin_type = "upload"
-
-config = {
- "host": NoDefault,
- "path": NoDefault,
- "port": 22,
- "user": getpass.getuser(),
-}
-
-def upload(name, source):
- logger.info(f"Uploading to {config.user}@{config.host}:{config.path}/{name} on port {config.port}")
- if isinstance(source, File):
- command = [
- "scp",
- ] + ([
- "-r",
- ] if source.path.is_dir() else []) + [
- "-P", f"{config.port}",
- source.path,
- f"{config.user}@{config.host}:{config.path}/{name}",
- ]
- process = subprocess.run(command)
- if process.returncode != 0:
- if source.path.is_dir():
- logger.fatal("Error: failed to upload directory")
- else:
- logger.fatal("Error: failed to upload file")
- elif isinstance(source, Raw):
- command = [
- "ssh",
- f"-p {config.port}",
- f"{config.user}@{config.host}",
- "-T",
- f"cat - > {config.path}/{name}"
- ]
- process = subprocess.run(
- command,
- input = source.data,
- )
- if process.returncode != 0:
- logger.fatal("Error: failed to upload data")
diff --git a/src/sshare/plugins/source.py b/src/sshare/plugins/source.py
deleted file mode 100644
index fcfc6a6..0000000
--- a/src/sshare/plugins/source.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file is part of SSHare.
-#
-# SSHare is free software: you can redistribute it and/or modify it under the terms of
-# the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# SSHare is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# SSHare. If not, see .
-
-from pathlib import Path
-
-class Raw:
- def __init__(self, type, data):
- self.type = type
- self.data = data
-
-class File:
- def __init__(self, path):
- self.path = Path(path)
diff --git a/src/sshare/version.py b/src/sshare/version.py
index 1b23640..b2b60a5 100644
--- a/src/sshare/version.py
+++ b/src/sshare/version.py
@@ -1 +1 @@
-version = "2.0.0"
+version = "1.1.0"