Compare commits
2 commits
mia
...
wrap_comma
Author | SHA1 | Date | |
---|---|---|---|
82b4d8de7c | |||
865f66b79d |
24 changed files with 116 additions and 397 deletions
252
README.md
252
README.md
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
Upload files to a server via ssh
|
Upload files to a server via ssh
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- **End User**: coming soon...
|
||||||
|
- **Plugin Developer**: coming soon...
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
SSHare is not available on [PyPI](https://pypi.org).
|
SSHare is not available on [PyPI](https://pypi.org).
|
||||||
|
@ -18,250 +23,7 @@ Beyond that it only utilises the python standard library.
|
||||||
### Additional Functionality
|
### Additional Functionality
|
||||||
|
|
||||||
The base install is fairly bare bones in terms of functionality.
|
The base install is fairly bare bones in terms of functionality.
|
||||||
Included in the [`examples/`](https://forge.monodon.me/Gnarwhal/sshare_plugins) submodule, there is a sampling of
|
Included in the [`examples/`](https://forge.monodon.me/Gnarwhal/sshare_plugins) submodule, there are included some
|
||||||
plugins which provide some additional conveniences
|
plugins which provide some additional conveniences
|
||||||
|
|
||||||
Refer to the above documentation for information on installing plugins
|
Refer to \[coming soon...\] for information on installing plugins
|
||||||
|
|
||||||
## Documentation - End User
|
|
||||||
|
|
||||||
Getting started with SSHare is about getting familiar with configuring SSHare.
|
|
||||||
SSHare configuration is all done in the `${XDG_CONFIG_DIR}/sshare` if set, or in `~/.config/sshare` otherwise.
|
|
||||||
In this directory are two important items: the `config.toml` file and the `plugins/` directory.
|
|
||||||
|
|
||||||
### `plugins/`
|
|
||||||
|
|
||||||
The `plugins/` directory is home to all external plugins. Installing a plugin is as simple as saving the
|
|
||||||
the plugin's `.py` file to the `plugins/`.
|
|
||||||
|
|
||||||
### `config.toml`
|
|
||||||
|
|
||||||
The configuration file can be broken down into three major components: `spec`, `config`, and `flags`.
|
|
||||||
|
|
||||||
#### `spec`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
|
|
||||||
[spec.default]
|
|
||||||
name = [ "time", "extension" ]
|
|
||||||
|
|
||||||
[spec.example]
|
|
||||||
flag = { short = "e", long = "example" }
|
|
||||||
name = [ "preserve", "extension" ]
|
|
||||||
|
|
||||||
[spec.noshort]
|
|
||||||
flag = { long = "only" }
|
|
||||||
name = [ "time" ]
|
|
||||||
help = "No short flag, only long flag >:("
|
|
||||||
```
|
|
||||||
|
|
||||||
The `spec` section is a collection of different runtime specifications. The name of a specification is
|
|
||||||
unimportant with the exception of `default`, which is run when no other spec is activated. In each specification
|
|
||||||
that isn't `default`, there is a `flag` attribute that sets which command line arguments activate the
|
|
||||||
specification. The `flag` attribute must have one or both of `short` or `long`, where `short` will be set the flag
|
|
||||||
`-{short}` and `long` will set the flag `--{long}`. The `name` attribute of a specification is an array of name type
|
|
||||||
plugins which controls the order in which said plugins are executed. Specifications can also provide a brief description
|
|
||||||
in the `help` attribute, which will be displayed when `sshare --help` is run. In the example above,
|
|
||||||
running `sshare --help` would give
|
|
||||||
```
|
|
||||||
options:
|
|
||||||
-e, --example Use example spec
|
|
||||||
--only No short flag, only long flag >:(
|
|
||||||
```
|
|
||||||
#### `config`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[config.ssh]
|
|
||||||
host = "example.com"
|
|
||||||
path = "/directory/to/store/files/in"
|
|
||||||
port = 22
|
|
||||||
```
|
|
||||||
|
|
||||||
The `config` section is used to set configuration options for plugins. Refer to documentation for a plugin to see
|
|
||||||
what options can be set here. Documentation for default plugins is included [below](#Default-Plugins).
|
|
||||||
|
|
||||||
#### `flags`
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[flags.file]
|
|
||||||
file = { short = "f" }
|
|
||||||
|
|
||||||
[flags.stdin]
|
|
||||||
stdin = { short = "" }
|
|
||||||
|
|
||||||
[flags.example]
|
|
||||||
option = { short = "o", long = "ooooption" }
|
|
||||||
```
|
|
||||||
|
|
||||||
The `flags` section is used to bind plugin arguments to a command line argument. They are specified in the same way
|
|
||||||
as the `flag` option for `spec`s. If `long` is left unspecified, the long flag will be set to the default provided by
|
|
||||||
the plugin. In the example above, running `sshare --help` would give:
|
|
||||||
```
|
|
||||||
options:
|
|
||||||
-f file, --file file Upload a file
|
|
||||||
-, --stdin Upload from stdin
|
|
||||||
-o xmpl, --ooooption xmpl
|
|
||||||
This is not a real plugin that exists
|
|
||||||
```
|
|
||||||
|
|
||||||
### Default Plugins
|
|
||||||
|
|
||||||
#### `command_line`
|
|
||||||
|
|
||||||
A `logger` plugin which prints to the command line. No configuration needed.
|
|
||||||
|
|
||||||
#### `extension`
|
|
||||||
|
|
||||||
A `name` plugin which appends the source type to the end of the file name (i.e. `txt`, `png`, etc...). No configuration needed.
|
|
||||||
|
|
||||||
#### `file`
|
|
||||||
|
|
||||||
A `source` plugin which provides a file to be uploaded. File is specified with the `--file {file_path}` argument. No configuration needed.
|
|
||||||
|
|
||||||
#### `preserve`
|
|
||||||
|
|
||||||
A `name` plugin which preserves the name of the source in the uploaded file. No configuration needed.
|
|
||||||
|
|
||||||
#### `print_location`
|
|
||||||
|
|
||||||
A `feedback` plugin which prints the location that sources can be accessed from. No configuration needed.
|
|
||||||
|
|
||||||
#### `ssh`
|
|
||||||
|
|
||||||
An `upload` plugin which uploads the sources to the server using `ssh`.
|
|
||||||
|
|
||||||
##### Configuration
|
|
||||||
| Attribute | Type | Default | Description |
|
|
||||||
|-----------|--------|---------|------------------------------------------------------|
|
|
||||||
| host | string | None | The hostname to ssh into |
|
|
||||||
| path | string | None | The path of the directory to upload the sources into |
|
|
||||||
| port | int | 22 | The port to ssh into |
|
|
||||||
| user | string | $USER | The user to ssh as |
|
|
||||||
|
|
||||||
#### `stdin`
|
|
||||||
|
|
||||||
A `source` plugin which reads from stdin. No configuration needed.
|
|
||||||
|
|
||||||
#### `time`
|
|
||||||
|
|
||||||
A `name` plugin which adds the current unix time to the name of the of the uploaded file.
|
|
||||||
|
|
||||||
##### Configuration
|
|
||||||
| Attribute | Type | Default | Description |
|
|
||||||
|-----------|--------|---------|------------------------------------------------------|
|
|
||||||
| format | int | 62 | The base between 2 and 62 to represent the number in |
|
|
||||||
|
|
||||||
##### `uri`
|
|
||||||
|
|
||||||
A `location` plugin which constructs the resulting URI that the uploaded file can be accessed from.
|
|
||||||
|
|
||||||
##### Configuration
|
|
||||||
| Attribute | Type | Default | Description |
|
|
||||||
|-----------|--------|---------|------------------------------------------------------|
|
|
||||||
| protocol | string | https | The protocol of the URI |
|
|
||||||
| host | string | None | The hostname the file can be accessed from |
|
|
||||||
| port | int | 22 | The port the file can be accessed at |
|
|
||||||
| path | string | None | The path the file can be accessed at |
|
|
||||||
|
|
||||||
## Documentation - Plugin Development
|
|
||||||
|
|
||||||
A plugin for SSHare is just a python file (`*.py`). There are currently 6 types of plugins:
|
|
||||||
- `logger`
|
|
||||||
- `source`
|
|
||||||
- `name`
|
|
||||||
- `upload`
|
|
||||||
- `location`
|
|
||||||
- `feedback`
|
|
||||||
A plugin can specify be any combination of the above types. For examples of plugins see [here](src/sshare/plugins)
|
|
||||||
and [here](https://forge.monodon.me/Gnarwhal/sshare_plugins)
|
|
||||||
|
|
||||||
### General Attributes
|
|
||||||
|
|
||||||
Every plugin regardless of type specifies or is provided with these attributes.
|
|
||||||
|
|
||||||
#### `plugin_type`
|
|
||||||
|
|
||||||
This mandatory paramater specifies what type(s) this plugin is.
|
|
||||||
It can be either a:
|
|
||||||
- `string` - Promotes to `{ string }`
|
|
||||||
- `set` - A set containing each of the plugin's types.
|
|
||||||
|
|
||||||
#### `activate`
|
|
||||||
|
|
||||||
This optional parameter specifies what flag(s) or argument(s) must be passed for this plugin to be activated.
|
|
||||||
It can be either a:
|
|
||||||
- `string` - Promotes to `{ string }`
|
|
||||||
- `set` - Promotes to `{ plugin_type: { string, ... }, plugin_type2: { string, ... }, ... }`
|
|
||||||
- `dict` - A dictionary that maps each type the plugin is, to the flags or arguments that activate the plugin for that type
|
|
||||||
All arguments specified in `activate` must be provided by the user for the plugin to activate.
|
|
||||||
|
|
||||||
#### `config`
|
|
||||||
|
|
||||||
This optional parameter specifies configuration options for the plugin. These values are what a user is allowed to change
|
|
||||||
through `config.toml`. It is a map containing `{ option: default_value, ... }`. If there is no default value (i.e. it is mandatory
|
|
||||||
that the user set it explicitly) for the option, it can be set to `NoDefault` provided by
|
|
||||||
`from sshare.plugin.config import NoDefault`.
|
|
||||||
|
|
||||||
While `config` is initially specified as a `dict`, when the plugin is loaded it will be converted to an object with attributes.
|
|
||||||
For example, if a config is specified as
|
|
||||||
```python
|
|
||||||
config = {
|
|
||||||
"example0": 42,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
it would then be accessed by `config.example` not `config["example"]`.
|
|
||||||
|
|
||||||
#### `args`
|
|
||||||
|
|
||||||
This optional parameter specifies arguments for the plugin. These values are also accessed from the `config` object,
|
|
||||||
however they are provided via program arguments as opposed to being specified in `config.toml`. An option specified
|
|
||||||
in both `config` and `args` will be loaded from the config file first and overriden by the program argument if
|
|
||||||
provided. Arguments are of type `Argument` provided by `from sshare.plugin.config import Argument`.
|
|
||||||
`Argument` takes `name` (optionally) and a list of `kwargs` equivalent to the option document [here](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument). As a convenience there is also `Flag` provided by
|
|
||||||
`from sshare.plugin.config import Flag`, which is for boolean arguments which take no parameters.
|
|
||||||
`Flag` only takes a `help=...` paramater.
|
|
||||||
|
|
||||||
#### `init`
|
|
||||||
|
|
||||||
If a plugin needs to do any initialisation, it can be done in the `init` method. The `init` method takes no parameters
|
|
||||||
and returns no values.
|
|
||||||
|
|
||||||
#### `logger`
|
|
||||||
|
|
||||||
Logger is not specified by the plugin developer, but is available inside the plugin if needed. The logger
|
|
||||||
has three levels: `info`, `warn` and `error`.
|
|
||||||
|
|
||||||
### Type Specific Attributes
|
|
||||||
|
|
||||||
#### `logger`
|
|
||||||
- `info(str)`
|
|
||||||
- `warn(str)`
|
|
||||||
- `error(str)`
|
|
||||||
|
|
||||||
#### `source` -> `get_source()`
|
|
||||||
|
|
||||||
The `get_source` function takes no arguments and returns a source. There are currently two types of sources provided by
|
|
||||||
`from sshare.plugin.source import (Raw | File)`.
|
|
||||||
- `Raw` - A raw data source. It has a type, a source name, and a byte array providing the data.
|
|
||||||
- `File` - A file or directory source. It has only the path to the file.
|
|
||||||
|
|
||||||
#### `name` -> `get_name(current_name, source)`
|
|
||||||
|
|
||||||
`name` plugins are chained one after the other. The first `name` plugin is provided an empty string for `current_name`.
|
|
||||||
Each subsequent `name` plugin is provided the output of the previous `name` plugin's `get_name` function. The `source`
|
|
||||||
parameter is the either `Raw` or `File` data source.
|
|
||||||
|
|
||||||
#### `upload` -> `upload(name, source)`
|
|
||||||
|
|
||||||
`upload` plugins are responsible for getting the source to the destination.
|
|
||||||
|
|
||||||
#### `location` -> `get_location(name)`
|
|
||||||
|
|
||||||
The `get_location` function takes in the name of a source and returns a location that the source can now be accessed from
|
|
||||||
(e.g. a URL).
|
|
||||||
|
|
||||||
#### `feedback` -> `give_feedback(location)`
|
|
||||||
|
|
||||||
The `give_feedback` function takes output from `location` plugins and presents it to the user (e.g. printing to console,
|
|
||||||
desktop notification. etc...).
|
|
||||||
|
|
||||||
|
|
5
_test_in.py
Executable file
5
_test_in.py
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("=> " + sys.stdin.read())
|
5
_test_out.py
Executable file
5
_test_out.py
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
for i in range(0, 10000):
|
||||||
|
print(f"\033[{(i % 7) + 30}mHello World!")
|
||||||
|
print(f"\033[{(i % 7) + 90}mHello World!")
|
2
examples
2
examples
|
@ -1 +1 @@
|
||||||
Subproject commit 99f2e9c3d2fbab02b0582dc8dcf9ed05df7789a6
|
Subproject commit 3273aa4e4c1898c484e989340a8525edb343cebe
|
|
@ -19,7 +19,7 @@ requires-python = ">=3.11"
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Homepage = "https://forge.monodon.me/Gnarwhal/sshare"
|
Homepage = "https://forge.monodon.me/Gnarwhal/sshare"
|
||||||
Documentation = "https://forge.monodon.me/Gnarwhal/sshare/README.md"
|
Documentation = "https://forge.monodon.me/Gnarwhal/sshare/README.md#Usage"
|
||||||
Repository = "https://forge.monodon.me/Gnarwhal/sshare"
|
Repository = "https://forge.monodon.me/Gnarwhal/sshare"
|
||||||
Issues = "https://forge.monodon.me/Gnarwhal/sshare/issues"
|
Issues = "https://forge.monodon.me/Gnarwhal/sshare/issues"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -25,12 +22,9 @@ def default_config():
|
||||||
return _LOCATION / "config.toml"
|
return _LOCATION / "config.toml"
|
||||||
|
|
||||||
def plugins():
|
def plugins():
|
||||||
if (_LOCATION / "plugins").is_dir():
|
return [
|
||||||
return [
|
path for
|
||||||
path for
|
path in
|
||||||
path in
|
(_LOCATION / "plugins").iterdir()
|
||||||
(_LOCATION / "plugins").iterdir()
|
if path.is_file() and path.suffix == ".py"
|
||||||
if path.is_file() and path.suffix == ".py"
|
]
|
||||||
]
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -43,31 +40,6 @@ def main():
|
||||||
arguments, _ = arg_parser.parse_known_args()
|
arguments, _ = arg_parser.parse_known_args()
|
||||||
with open(arguments.config or config_directory.default_config(), mode="rb") as file:
|
with open(arguments.config or config_directory.default_config(), mode="rb") as file:
|
||||||
config = tomllib.load(file)
|
config = tomllib.load(file)
|
||||||
|
|
||||||
config["spec"] = config.get("spec", {})
|
|
||||||
for spec_name, spec in config["spec"].items():
|
|
||||||
if spec_name != "default":
|
|
||||||
flags = []
|
|
||||||
if spec.get("flag", {}).get("short") != None:
|
|
||||||
flags = flags + [ f"-{spec["flag"]["short"]}" ]
|
|
||||||
if spec.get("flag", {}).get("long") != None:
|
|
||||||
flags = flags + [ f"--{spec["flag"]["long"]}" ]
|
|
||||||
arg_parser.add_argument(
|
|
||||||
*flags,
|
|
||||||
action="store_const",
|
|
||||||
const=True,
|
|
||||||
default=False,
|
|
||||||
help=spec.get(help, f"Use {spec_name} spec"),
|
|
||||||
dest=spec_name,
|
|
||||||
)
|
|
||||||
|
|
||||||
use_spec = config["spec"].get("default", {})
|
|
||||||
arguments, _ = arg_parser.parse_known_args()
|
|
||||||
for spec_name, spec in config["spec"].items():
|
|
||||||
if spec_name != "default":
|
|
||||||
if getattr(arguments, spec_name):
|
|
||||||
use_spec = spec
|
|
||||||
|
|
||||||
config["config"] = config.get("config", {})
|
config["config"] = config.get("config", {})
|
||||||
config["flags" ] = config.get("flags", {})
|
config["flags" ] = config.get("flags", {})
|
||||||
|
|
||||||
|
@ -97,9 +69,8 @@ def main():
|
||||||
logger.add(command_line)
|
logger.add(command_line)
|
||||||
plugins = PluginManager(
|
plugins = PluginManager(
|
||||||
logger,
|
logger,
|
||||||
use_spec,
|
|
||||||
config["config"],
|
config["config"],
|
||||||
config["flags" ],
|
config["flags"],
|
||||||
arg_parser,
|
arg_parser,
|
||||||
)
|
)
|
||||||
plugins.activate("logger")
|
plugins.activate("logger")
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -15,6 +12,8 @@
|
||||||
# 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/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
class NoDefault: pass
|
class NoDefault: pass
|
||||||
|
|
||||||
def Flag(name=None, help=None):
|
def Flag(name=None, help=None):
|
||||||
|
@ -36,6 +35,8 @@ class Argument:
|
||||||
self._short = None
|
self._short = None
|
||||||
self._long = name
|
self._long = name
|
||||||
|
|
||||||
|
self._is_remainder = kwargs.get("nargs", None) == argparse.REMAINDER
|
||||||
|
|
||||||
if not "default" in kwargs:
|
if not "default" in kwargs:
|
||||||
kwargs["default"] = NoDefault
|
kwargs["default"] = NoDefault
|
||||||
kwargs["default"] = _None(kwargs["default"])
|
kwargs["default"] = _None(kwargs["default"])
|
||||||
|
@ -46,6 +47,8 @@ class Argument:
|
||||||
if self._long == None:
|
if self._long == None:
|
||||||
self._long = argument
|
self._long = argument
|
||||||
self._kwargs["metavar"] = argument
|
self._kwargs["metavar"] = argument
|
||||||
|
if self._is_remainder:
|
||||||
|
self._long = self.dest()
|
||||||
|
|
||||||
def set_flags(self, short, long):
|
def set_flags(self, short, long):
|
||||||
if short != None:
|
if short != None:
|
||||||
|
@ -78,11 +81,13 @@ class Argument:
|
||||||
|
|
||||||
def add(self, arg_parser):
|
def add(self, arg_parser):
|
||||||
flags = []
|
flags = []
|
||||||
if self._short != None: flags.append(f"-{self._short}")
|
kwargs = self._kwargs
|
||||||
if self._long != None: flags.append(f"--{self._long}")
|
if self._is_remainder:
|
||||||
kwargs = self._kwargs | {
|
flags.append(self._long)
|
||||||
"dest": self.dest()
|
else:
|
||||||
}
|
if self._short != None: flags.append(f"-{self._short}")
|
||||||
|
if self._long != None: flags.append(f"--{self._long}")
|
||||||
|
kwargs["dest"] = self.dest()
|
||||||
arg_parser.add_argument(
|
arg_parser.add_argument(
|
||||||
*flags,
|
*flags,
|
||||||
**kwargs
|
**kwargs
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -38,9 +35,9 @@ class PluginLoader:
|
||||||
in ([ "command_line" ] if command_line else []) + [
|
in ([ "command_line" ] if command_line else []) + [
|
||||||
"file",
|
"file",
|
||||||
"stdin",
|
"stdin",
|
||||||
"preserve",
|
"wrap_command",
|
||||||
"time",
|
"current_time",
|
||||||
"extension",
|
"append_type",
|
||||||
"ssh",
|
"ssh",
|
||||||
"uri",
|
"uri",
|
||||||
"print_location",
|
"print_location",
|
||||||
|
@ -64,7 +61,7 @@ class PluginLoader:
|
||||||
]
|
]
|
||||||
|
|
||||||
class PluginManager:
|
class PluginManager:
|
||||||
def __init__(self, logger, spec, config, flags, arg_parser):
|
def __init__(self, logger, config, flags, arg_parser):
|
||||||
self._logger = logger
|
self._logger = logger
|
||||||
self._arg_parser = arg_parser
|
self._arg_parser = arg_parser
|
||||||
|
|
||||||
|
@ -75,22 +72,14 @@ class PluginManager:
|
||||||
for type in Plugin.types():
|
for type in Plugin.types():
|
||||||
setattr(self, type, PluginState())
|
setattr(self, type, PluginState())
|
||||||
|
|
||||||
self._uninitialized = []
|
self._uninitialized = PluginLoader.all(
|
||||||
uninitialized = PluginLoader.all(
|
|
||||||
command_line=False,
|
command_line=False,
|
||||||
logger=logger,
|
logger=logger,
|
||||||
config=config,
|
config=config,
|
||||||
flags=flags,
|
flags=flags,
|
||||||
)
|
)
|
||||||
for plugin in uninitialized:
|
for plugin in self._uninitialized:
|
||||||
plugin.add_args(arg_parser)
|
plugin.add_args(arg_parser)
|
||||||
if not "name" in plugin.plugin_type:
|
|
||||||
self._uninitialized.append(plugin)
|
|
||||||
|
|
||||||
for name in spec.get("name", []):
|
|
||||||
for plugin in uninitialized:
|
|
||||||
if plugin.name == name:
|
|
||||||
self._uninitialized.append(plugin)
|
|
||||||
|
|
||||||
def activate(self, activate_type=None):
|
def activate(self, activate_type=None):
|
||||||
args = self._arg_parser.parse_args()
|
args = self._arg_parser.parse_args()
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -18,8 +15,7 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
class Raw:
|
class Raw:
|
||||||
def __init__(self, name, type, data):
|
def __init__(self, type, data):
|
||||||
self.name = name
|
|
||||||
self.type = type
|
self.type = type
|
||||||
self.data = data
|
self.data = data
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -23,13 +20,19 @@ from sshare.plugin.source import File
|
||||||
plugin_type = "name"
|
plugin_type = "name"
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"format": 62,
|
"base": 62,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 get_name(name, source):
|
def get_name(name, source):
|
||||||
if name != "":
|
return name + _rebase(config.base, time.time_ns())
|
||||||
name = name + "_"
|
|
||||||
return name + _rebase(config.format, time.time_ns())
|
|
||||||
|
|
||||||
def _rebase(base, number):
|
def _rebase(base, number):
|
||||||
if number == 0:
|
if number == 0:
|
||||||
|
@ -44,8 +47,8 @@ def _rebase(base, number):
|
||||||
|
|
||||||
def _number_to_char(number):
|
def _number_to_char(number):
|
||||||
if number < 10:
|
if number < 10:
|
||||||
return chr(number + 48) # 0-9
|
return chr(number + 48)
|
||||||
elif number < 36:
|
elif number < 36:
|
||||||
return chr(number + 87) # a-z
|
return chr(number + 87)
|
||||||
else:
|
else:
|
||||||
return chr(number + 29) # A-Z
|
return chr(number + 29)
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# 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 <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
from sshare.plugin.source import File
|
|
||||||
from sshare.plugin.source import Raw
|
|
||||||
|
|
||||||
plugin_type = "name"
|
|
||||||
|
|
||||||
def get_name(name, source):
|
|
||||||
if name != "":
|
|
||||||
name = name + "_"
|
|
||||||
else:
|
|
||||||
name = ""
|
|
||||||
if isinstance(source, File):
|
|
||||||
components = source.path.name.split(".")
|
|
||||||
if components[0] == "":
|
|
||||||
return name + "." + components[1]
|
|
||||||
else:
|
|
||||||
return name + components[0]
|
|
||||||
else:
|
|
||||||
return name + source.name
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
@ -24,11 +21,11 @@ plugin_type = "source"
|
||||||
|
|
||||||
activate = { "stdin" }
|
activate = { "stdin" }
|
||||||
config = {
|
config = {
|
||||||
"suffix": "txt"
|
"suffix": "txt",
|
||||||
}
|
}
|
||||||
args = {
|
args = {
|
||||||
"stdin": Flag(help="Upload from stdin")
|
"stdin": Flag(help="Upload from stdin")
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_source():
|
def get_source():
|
||||||
return Raw("stdin", config.suffix, sys.stdin.buffer.read())
|
return Raw(config.suffix, sys.stdin.buffer.read())
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
50
src/sshare/plugins/wrap_command.py
Normal file
50
src/sshare/plugins/wrap_command.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import locale
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from sshare.plugin.config import Argument
|
||||||
|
from sshare.plugin.source import Raw
|
||||||
|
|
||||||
|
plugin_type = "source"
|
||||||
|
|
||||||
|
activate = { "command" }
|
||||||
|
config = {
|
||||||
|
"suffix": "txt",
|
||||||
|
}
|
||||||
|
args = {
|
||||||
|
"command": Argument(
|
||||||
|
nargs=argparse.REMAINDER,
|
||||||
|
help="Upload the contents of the wrapped command",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def init():
|
||||||
|
config.command = config.command[1:]
|
||||||
|
|
||||||
|
def get_source():
|
||||||
|
output = b""
|
||||||
|
with subprocess.Popen(
|
||||||
|
config.command,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=0,
|
||||||
|
) as process:
|
||||||
|
for line in process.stdout:
|
||||||
|
print(line.decode(locale.getpreferredencoding()), end="")
|
||||||
|
output += line
|
||||||
|
|
||||||
|
return Raw(config.suffix, output)
|
|
@ -1,6 +1,3 @@
|
||||||
# SSHare - upload files to a server
|
|
||||||
# Copyright (c) 2024 Gnarwhal
|
|
||||||
#
|
|
||||||
# This file is part of SSHare.
|
# This file is part of SSHare.
|
||||||
#
|
#
|
||||||
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
# SSHare is free software: you can redistribute it and/or modify it under the terms of
|
||||||
|
|
4
tests/test_test.py
Normal file
4
tests/test_test.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from src.sshare.plugin.config import Argument
|
||||||
|
|
||||||
|
def test_foo():
|
||||||
|
assert True
|
Loading…
Add table
Reference in a new issue