Easyshare
====
DESCRIPTION
------------
**easyshare** is a client-server command line application written in Python for transfer files between network hosts.
It is highly inspired by FTP, but aim to be easier and faster to use.
For example, **easyshare** supports automatic discovery of the *sharings* of the network,
therefore, from the client you can download entire directories just by giving the name
you assigned to them from the server side.
REQUIREMENTS
------------
Requires at least Python 3.6.
INSTALLATION
------------
On Linux, you can install it with pip:
```text
sudo pip install easyshare
```
This will install both **es** (client) and **esd** (server).
WHAT IT LOOKS LIKE
-----
*A picture is worth a thousand words*
##### es (client)
![es](img/es.shrink.png)
##### esd (server)
![es](img/esd-inline.shrink.png)
## esd
#### USAGE
```text
esd [OPTION]... [SHARING [SHARING_NAME] [SHARING_OPTION]...]
```
For share stuff, you have to start an easyshare daemon (**esd**).
There are basically two ways for create *sharings*.
1. By providing the path of the file/directory to share in the command line as SHARING
2. By creating a configuration file and specifying it with the option -c config
The option 1. should be preferred for an easy one-shot sharing of a file or directory, since
doesn't need the creation a configuration file, but has the limit that only a file or folder
can be shared.
If given, SHARING must be a valid path to a local file or directory.
SHARING_NAME is an optional name to assign to the sharing, as it will be seen by clients. If
not given, the name of the file/directory is used instead.
Currently the only supported SHARING_OPTION is the read-only flag, which can be enabled with
-r, and denies any write operation on a directory sharing.
#### OPTIONS
```text
-a, --address address server address (default is primary interface)
-c, --config config_path load settings from a esd configuration file
-d, --discover-port port port used to listen to discovery messages; 1 disables discovery (default is 12021)
-e, --rexec enable rexec (remote execution)
-h, --help show this help
-n, --name name server name (default is server hostname)
--no-color don't print ANSI escape characters
-P, --password password server password, plain or hashed with es-tools
-p, --port port server port (default is 12020)
--ssl-cert cert_path path to an SSL certificate
--ssl-privkey privkey_path path to an SSL private key
-t, --trace 0_or_1 enable/disable tracing
-v, --verbose level set verbosity level
-V, --version show the easyshare version
```
#### CONFIGURATION
The server can be configured either with a configuration file (2.) or by giving **esd** the options
you need. The command line arguments have precedence over the corresponding setting of the
configuration file (i.e. if you specify an option in both the configuration file and as an argument,
the argument will be taken into account).
The configuration file is composed of two parts.
1. Global section
2. Sharings sections
Each line of a section has the form \<key\>=\<value\>.
The available \<key\> of the global section are:
```text
address
discover_port
name
no_color
password
port
rexec
ssl
ssl_cert
ssl_privkey
trace
verbose
```
The available \<key\> of the sharings sections are:
```text
path
readonly
```
The first lines of the configuration file belongs to the global section by default.
Each sharing section begins with "\[SHARING_NAME\]".
If you omit the SHARING_NAME, the name of the shared file or directory will be used instead.
See the example of the configuration file below for more details.
#### EXAMPLES
* Share a file
```text
esd /tmp/file
```
* Share a directory, assigning it a name
```text
esd /tmp/shared_directory shared
```
* Share multiples directories, using a configuration file
```text
esd -c /home/user/.easyshare/esd.conf
```
##### CONFIGURATION FILE EXAMPLE
```text
# esd.conf
# ===== SERVER SETTINGS =====
name=stefano-arch
password=aSecurePassword
port=12020
discover_port=12019
ssl=true
ssl_cert="/tmp/cert.pem"
ssl_privkey="/tmp/privkey.pem"
ssl_privkey="/tmp/privkey.pem"
rexec=false
verbose=4
trace=1
# ===== SHARINGS =====
[download]
path="/home/stefano/Downloads"
[shared]
path="/tmp/shared"
readonly=true
# Automatic sharing name
[]
path="/tmp/afile"
```
## es
#### USAGE
```text
es [OPTION]... [COMMAND [COMMAND_OPTIONS]]
```
For fetch stuff shared with **esd**, you have to start an easyshare client (**es**).
If no COMMAND is given, the interactive console is started, from which you can use any command.
If COMMAND is a valid command, it is executed and the process quits unless the command is *open*.
#### OPTIONS
```text
-d, --discover-port port port used for broadcast discovery messages
-h, --help show this help
--no-color don't print ANSI escape characters
-t, --trace 0_or_1 enable/disable tracing
-v, --verbose level set verbosity level
-V, --version show the easyshare version
-w, --discover-wait seconds time to wait for discovery responses
```
#### COMMANDS
From within the **es** console, type "help \<command\>" for the full documentation of a command.
The available commands (either from the command line or from the interactive console) are the following:
##### General commands
```text
help show this help
exit, quit, q exit from the interactive shell
trace, t enable/disable packet tracing
verbose, v change verbosity level
```
The *help* command should really be used since its quite complete.
##### Connection establishment commands
```text
scan, s scan the network for easyshare servers
connect, c connect to a remote server
disconnect disconnect from a remote server
open, o open a remote sharing (eventually discovering it)
close close the remote sharing
```
The most straightforward way to establish a connection is *open* since only requires you
to know the name assigned to the sharing.
*scan* can be used for discover the sharings of the network (for figure out the name to give to *open*).
Tipically you won't need to use *connect* explicitly since the server connection
is automatically established, if the sharing name given to *open* is valid and can be found.
Although there might be cases in which an explicit *connect* is needed, for example for
connect to a server for which the discovery cannot be performed
(i.e. a server not on the same network of the client) or if you want to connect a server without
sharings (e.g. for execute commands remotely via *rexec*).
##### Transfer commands
```text
get, g get files and directories from the remote sharing
put, p put files and directories in the remote sharing
```
*get* is used for:
* Download files or directories from a "directory sharing"
* Download a shared file ("file sharing")
*put* is used for:
* Upload files or directories to a "directory sharing"
##### Local commands
```text
pwd show the name of current local working directory
ls list local directory content
l alias for ls -la
tree list local directory contents in a tree-like format
cd change local working directory
mkdir create a local directory
cp copy files and directories locally
mv move files and directories locally
rm remove files and directories locally
exec, : execute an arbitrary command locally
shell, sh start a local shell
```
You should really be familiar with these commands since behave quite similar
to the Linux counterpart.
The command *exec* (which can be shortened with *:*) can be useful for execute arbitrary commands
without the need of open a new terminal.
##### Remote commands
```text
rpwd show the name of current remote working directory
rls list remote directory content
rl alias for rls -la
rtree list remote directory contents in a tree-like format
rcd change remote working directory
rmkdir create a remote directory
rcp copy files and directories remotely
rmv move files and directories remotely
rrm remove files and directories remotely
rexec, :: execute an arbitrary command remotely (disabled by default)
rshell, rsh start a remote shell (disabled by default)
```
These are the counterparts of the **Local commands** that work on the remote sharing
instead of the local machine (i.e. you have to establish a connection to a "directory sharing"
before use those).
The command *rexec* (which can be shortened with *::*) is a really powerful command
that basically gives you arbitrary command execution on the remote machine
(technically not a shell, but not so far).
For this reason, it is obviously disabled by default, but you can enable it with the
option **-e** if you are really confident that nobody with bad intentions will use it
(use a strong server password, by the way).
##### Server information commands
```text
info, i show information about the remote server
list list the sharings of the remote server
ping test the connection with the remote server
```
*info* can be used for fetch information of the remote server
(e.g. name, address, ports, SSL certificate, type of authentication, available sharings).
#### EXAMPLES
These are only examples, see the *help* section of each command for known exactly
what you can do.
* Start the interactive shell (from which you can use any command)
```text
es
```
* Scan the network for easyshare sharings
```text
es scan
alice-arch (192.168.1.105:12020)
DIRECTORIES
- shared
- tmp
```
* Open a sharing by name (implicit discovery and server connection) and start the interactive shell
```text
es open shared
alice-arch.shared:/ - /tmp>
...
```
* Get the content of a sharing by name
```text
es get shared
GET shared/f1 [===================] 100% 745KB/745KB
GET outcome: OK
Files 1 (745KB)
Time 1s
Avg. speed 1MB/s
```
* Open a sharing by name and put some files into it
```text
es
/tmp> open shared
alice-arch.shared:/ - /tmp> rls
f1 f2
alice-arch.shared:/ - /tmp> put /tmp/afile
PUT afile [===================] 100% 745KB/745KB
PUT outcome: OK
Files 1 (745KB)
Time 1s
Avg. speed 1MB/s
alice-arch.shared:/ - /tmp> rls
f1 f2 afile
```
* Connect to a server by specific address and port, then list the available sharings
```text
es connect 192.168.1.105:12020
alice-arch:/ - /tmp> list
DIRECTORIES
- shared
- tmp
FILES
- zshrc
```
* See content of the remote sharing, then move some files
```text
es
/tmp> open shared
alice-arch.shared:/ - /tmp> rtree
|-- dir
| |-- f3
| +-- f4
|-- f1
+-- f2
alice-arch.shared:/ - /tmp> rmv f1 f2 dir
alice-arch.shared:/ - /tmp> rtree
+-- dir
|-- f1
|-- f2
|-- f3
+-- f4
alice-arch.shared:/ - /tmp> rcd dir
alice-arch.shared:/dir - /tmp> rls
f1 f2 f3 f4
```
* Arbitrary local command execution
```text
es
/tmp> cd d
/tmp/d> ls
f0
/tmp> :touch f1
f0 f1
```
* Arbitrary remote command execution (DISABLED BY DEFAULT)
```text
es
/tmp> connect alice-arch
alice-arch:/ - /tmp> ::whoami
alice
```
## es-tools
*es-tools* is a little script that can help administrators of easyshare servers.
Currently in two ways:
1. Creating a default configuration file
2. Generating an hash of a password to use in the **esd** configuration file (preferred over a plain password)
#### USAGE
```text
es-tools [OPTION]...
```
If neither -c nor -p is given, an interactive script is started and you will be asked what to do.
#### OPTIONS
```text
-c, --generate-config generate default esd.conf file
-h, --help show this help
-p, --hash-password <password> generate an hash of the password
-V, --version show the easyshare version
```
## TESTING
Tests can be run with:
```text
tox
```
For run tests with logging enabled
```text
tox -- -s
```
Actually there are still many things to write tests for...
## TODO
* Testing on Windows
* *find* and *rfind* command that finds files by name and tag those with incremental IDs (1, 2)
which can be used in other command (something like $1, $2)
* *shell* and *rshell* which implement command execution through a pty (enhanced version of exec/rexec)
* Behind NAT section in README (open two external ports internally forwarded to 12020 and 12021)
* Add unit tests
* Handle addresses instead of numeric IPs
* Do not transfer hidden files by default (add a -a option for transfer those)
LICENSE
-------
Easyshare is [MIT licensed](LICENSE).
Raw data
{
"_id": null,
"home_page": "https://github.com/Docheinstein/easyshare",
"name": "easyshare",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "easyshare",
"author": "Stefano Dottore",
"author_email": "docheinstein@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/fb/59/c3fb5145adde74b466b8952671383490b673018482c7b3104f7ee5d9cfb8/easyshare-0.17.tar.gz",
"platform": null,
"description": "Easyshare\n====\n\nDESCRIPTION\n------------\n**easyshare** is a client-server command line application written in Python for transfer files between network hosts. \nIt is highly inspired by FTP, but aim to be easier and faster to use. \nFor example, **easyshare** supports automatic discovery of the *sharings* of the network, \ntherefore, from the client you can download entire directories just by giving the name\nyou assigned to them from the server side.\n\nREQUIREMENTS\n------------\n\nRequires at least Python 3.6.\n\nINSTALLATION\n------------\nOn Linux, you can install it with pip:\n```text\nsudo pip install easyshare\n```\n\nThis will install both **es** (client) and **esd** (server).\n\nWHAT IT LOOKS LIKE\n-----\n\n*A picture is worth a thousand words*\n\n\n##### es (client)\n\n![es](img/es.shrink.png)\n\n\n\n##### esd (server)\n\n![es](img/esd-inline.shrink.png)\n\n\n## esd\n\n#### USAGE\n```text\nesd [OPTION]... [SHARING [SHARING_NAME] [SHARING_OPTION]...]\n```\n\nFor share stuff, you have to start an easyshare daemon (**esd**).\n\nThere are basically two ways for create *sharings*.\n1. By providing the path of the file/directory to share in the command line as SHARING\n2. By creating a configuration file and specifying it with the option -c config\n\nThe option 1. should be preferred for an easy one-shot sharing of a file or directory, since \ndoesn't need the creation a configuration file, but has the limit that only a file or folder \ncan be shared.\n\nIf given, SHARING must be a valid path to a local file or directory.\nSHARING_NAME is an optional name to assign to the sharing, as it will be seen by clients. If \nnot given, the name of the file/directory is used instead.\nCurrently the only supported SHARING_OPTION is the read-only flag, which can be enabled with \n-r, and denies any write operation on a directory sharing.\n\n#### OPTIONS\n```text\n-a, --address address server address (default is primary interface)\n-c, --config config_path load settings from a esd configuration file\n-d, --discover-port port port used to listen to discovery messages; 1 disables discovery (default is 12021)\n-e, --rexec enable rexec (remote execution)\n-h, --help show this help\n-n, --name name server name (default is server hostname)\n--no-color don't print ANSI escape characters\n-P, --password password server password, plain or hashed with es-tools\n-p, --port port server port (default is 12020)\n--ssl-cert cert_path path to an SSL certificate\n--ssl-privkey privkey_path path to an SSL private key\n-t, --trace 0_or_1 enable/disable tracing\n-v, --verbose level set verbosity level\n-V, --version show the easyshare version\n```\n\n#### CONFIGURATION\n\nThe server can be configured either with a configuration file (2.) or by giving **esd** the options\nyou need. The command line arguments have precedence over the corresponding setting of the\nconfiguration file (i.e. if you specify an option in both the configuration file and as an argument, \nthe argument will be taken into account).\n\nThe configuration file is composed of two parts.\n1. Global section\n2. Sharings sections\n\nEach line of a section has the form \\<key\\>=\\<value\\>.\nThe available \\<key\\> of the global section are:\n```text\n address\n discover_port\n name\n no_color\n password\n port\n rexec\n ssl\n ssl_cert\n ssl_privkey\n trace\n verbose\n```\n\nThe available \\<key\\> of the sharings sections are:\n```text\n path\n readonly\n```\n\nThe first lines of the configuration file belongs to the global section by default.\nEach sharing section begins with \"\\[SHARING_NAME\\]\".\nIf you omit the SHARING_NAME, the name of the shared file or directory will be used instead.\n\nSee the example of the configuration file below for more details.\n\n\n#### EXAMPLES\n* Share a file\n```text\nesd /tmp/file\n```\n\n* Share a directory, assigning it a name\n```text\nesd /tmp/shared_directory shared\n```\n\n* Share multiples directories, using a configuration file \n```text\nesd -c /home/user/.easyshare/esd.conf\n```\n\n\n##### CONFIGURATION FILE EXAMPLE\n```text\n# esd.conf\n\n# ===== SERVER SETTINGS =====\n\nname=stefano-arch\npassword=aSecurePassword\n\nport=12020\ndiscover_port=12019\n\nssl=true\nssl_cert=\"/tmp/cert.pem\"\nssl_privkey=\"/tmp/privkey.pem\"\nssl_privkey=\"/tmp/privkey.pem\"\n\nrexec=false\n\nverbose=4\ntrace=1\n\n# ===== SHARINGS =====\n\n[download]\n path=\"/home/stefano/Downloads\"\n\n[shared]\n path=\"/tmp/shared\"\n readonly=true\n\n# Automatic sharing name\n[]\n path=\"/tmp/afile\"\n```\n\n\n## es\n\n\n#### USAGE\n```text\nes [OPTION]... [COMMAND [COMMAND_OPTIONS]]\n```\n\nFor fetch stuff shared with **esd**, you have to start an easyshare client (**es**).\n\nIf no COMMAND is given, the interactive console is started, from which you can use any command. \nIf COMMAND is a valid command, it is executed and the process quits unless the command is *open*.\n\n#### OPTIONS\n```text\n-d, --discover-port port port used for broadcast discovery messages\n-h, --help show this help\n--no-color don't print ANSI escape characters\n-t, --trace 0_or_1 enable/disable tracing\n-v, --verbose level set verbosity level\n-V, --version show the easyshare version\n-w, --discover-wait seconds time to wait for discovery responses\n```\n\n#### COMMANDS\n\nFrom within the **es** console, type \"help \\<command\\>\" for the full documentation of a command.\n\nThe available commands (either from the command line or from the interactive console) are the following:\n\n##### General commands\n```text\nhelp show this help\nexit, quit, q exit from the interactive shell\ntrace, t enable/disable packet tracing\nverbose, v change verbosity level\n```\n\nThe *help* command should really be used since its quite complete.\n\n##### Connection establishment commands\n```text\nscan, s scan the network for easyshare servers\nconnect, c connect to a remote server\ndisconnect disconnect from a remote server\nopen, o open a remote sharing (eventually discovering it)\nclose close the remote sharing\n```\n\nThe most straightforward way to establish a connection is *open* since only requires you\nto know the name assigned to the sharing. \n\n*scan* can be used for discover the sharings of the network (for figure out the name to give to *open*).\n\nTipically you won't need to use *connect* explicitly since the server connection\nis automatically established, if the sharing name given to *open* is valid and can be found.\nAlthough there might be cases in which an explicit *connect* is needed, for example for\nconnect to a server for which the discovery cannot be performed\n(i.e. a server not on the same network of the client) or if you want to connect a server without\nsharings (e.g. for execute commands remotely via *rexec*).\n\n\n##### Transfer commands\n```text\nget, g get files and directories from the remote sharing\nput, p put files and directories in the remote sharing\n```\n\n*get* is used for:\n* Download files or directories from a \"directory sharing\"\n* Download a shared file (\"file sharing\")\n\n*put* is used for:\n* Upload files or directories to a \"directory sharing\"\n\n##### Local commands\n```text\npwd show the name of current local working directory\nls list local directory content\nl alias for ls -la\ntree list local directory contents in a tree-like format\ncd change local working directory\nmkdir create a local directory\ncp copy files and directories locally\nmv move files and directories locally\nrm remove files and directories locally\nexec, : execute an arbitrary command locally\nshell, sh start a local shell\n```\n\nYou should really be familiar with these commands since behave quite similar \nto the Linux counterpart.\n\nThe command *exec* (which can be shortened with *:*) can be useful for execute arbitrary commands\nwithout the need of open a new terminal.\n\n##### Remote commands\n```text\nrpwd show the name of current remote working directory\nrls list remote directory content\nrl alias for rls -la\nrtree list remote directory contents in a tree-like format\nrcd change remote working directory\nrmkdir create a remote directory\nrcp copy files and directories remotely\nrmv move files and directories remotely\nrrm remove files and directories remotely\nrexec, :: execute an arbitrary command remotely (disabled by default)\nrshell, rsh start a remote shell (disabled by default)\n```\n\nThese are the counterparts of the **Local commands** that work on the remote sharing\ninstead of the local machine (i.e. you have to establish a connection to a \"directory sharing\"\nbefore use those).\n\nThe command *rexec* (which can be shortened with *::*) is a really powerful command\nthat basically gives you arbitrary command execution on the remote machine \n(technically not a shell, but not so far). \nFor this reason, it is obviously disabled by default, but you can enable it with the\noption **-e** if you are really confident that nobody with bad intentions will use it\n(use a strong server password, by the way).\n\n##### Server information commands\n```text\ninfo, i show information about the remote server\nlist list the sharings of the remote server\nping test the connection with the remote server\n```\n\n*info* can be used for fetch information of the remote server \n(e.g. name, address, ports, SSL certificate, type of authentication, available sharings).\n\n#### EXAMPLES\n\nThese are only examples, see the *help* section of each command for known exactly\nwhat you can do.\n\n* Start the interactive shell (from which you can use any command)\n```text\nes\n```\n \n* Scan the network for easyshare sharings\n```text\nes scan\n\nalice-arch (192.168.1.105:12020)\n DIRECTORIES\n - shared\n - tmp\n```\n\n\n* Open a sharing by name (implicit discovery and server connection) and start the interactive shell\n```text\nes open shared\n\nalice-arch.shared:/ - /tmp>\n...\n```\n\n* Get the content of a sharing by name\n```text\nes get shared\n\nGET shared/f1 [===================] 100% 745KB/745KB\nGET outcome: OK\nFiles 1 (745KB)\nTime 1s\nAvg. speed 1MB/s\n```\n\n* Open a sharing by name and put some files into it\n```text\nes\n\n/tmp> open shared\nalice-arch.shared:/ - /tmp> rls\nf1 f2\nalice-arch.shared:/ - /tmp> put /tmp/afile\nPUT afile [===================] 100% 745KB/745KB\nPUT outcome: OK\nFiles 1 (745KB)\nTime 1s\nAvg. speed 1MB/s\nalice-arch.shared:/ - /tmp> rls\nf1 f2 afile\n```\n\n* Connect to a server by specific address and port, then list the available sharings\n```text\nes connect 192.168.1.105:12020\n\nalice-arch:/ - /tmp> list\nDIRECTORIES\n- shared\n- tmp\nFILES\n- zshrc\n```\n\n* See content of the remote sharing, then move some files\n```text\nes \n/tmp> open shared\nalice-arch.shared:/ - /tmp> rtree\n|-- dir\n| |-- f3\n| +-- f4\n|-- f1\n+-- f2\nalice-arch.shared:/ - /tmp> rmv f1 f2 dir\nalice-arch.shared:/ - /tmp> rtree\n+-- dir\n |-- f1\n |-- f2\n |-- f3\n +-- f4\nalice-arch.shared:/ - /tmp> rcd dir\nalice-arch.shared:/dir - /tmp> rls\nf1 f2 f3 f4\n```\n\n* Arbitrary local command execution\n```text\nes \n/tmp> cd d\n/tmp/d> ls\nf0 \n/tmp> :touch f1\nf0 f1\n```\n\n* Arbitrary remote command execution (DISABLED BY DEFAULT)\n```text\nes \n/tmp> connect alice-arch\nalice-arch:/ - /tmp> ::whoami\nalice\n```\n\n## es-tools\n\n*es-tools* is a little script that can help administrators of easyshare servers. \n\nCurrently in two ways:\n1. Creating a default configuration file\n2. Generating an hash of a password to use in the **esd** configuration file (preferred over a plain password)\n\n\n#### USAGE\n```text\nes-tools [OPTION]...\n```\n\nIf neither -c nor -p is given, an interactive script is started and you will be asked what to do.\n\n#### OPTIONS\n```text\n-c, --generate-config generate default esd.conf file\n-h, --help show this help\n-p, --hash-password <password> generate an hash of the password\n-V, --version show the easyshare version\n```\n\n## TESTING\n\nTests can be run with:\n```text\ntox\n```\n\nFor run tests with logging enabled\n\n```text\ntox -- -s\n```\n\nActually there are still many things to write tests for...\n\n## TODO\n* Testing on Windows\n* *find* and *rfind* command that finds files by name and tag those with incremental IDs (1, 2)\nwhich can be used in other command (something like $1, $2)\n* *shell* and *rshell* which implement command execution through a pty (enhanced version of exec/rexec)\n* Behind NAT section in README (open two external ports internally forwarded to 12020 and 12021)\n* Add unit tests\n* Handle addresses instead of numeric IPs\n* Do not transfer hidden files by default (add a -a option for transfer those)\nLICENSE\n-------\n\nEasyshare is [MIT licensed](LICENSE).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Client-Server command line application for share files, similar to FTP but more powerful; written in Python 3.6+",
"version": "0.17",
"split_keywords": [
"easyshare"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "5f26067c9a8efd18c4693b87bf5c90bf",
"sha256": "15d01bcf345773af0f0f6eb002e265a6a18c89f18daedf62a544556d623093e2"
},
"downloads": -1,
"filename": "easyshare-0.17.tar.gz",
"has_sig": false,
"md5_digest": "5f26067c9a8efd18c4693b87bf5c90bf",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 198298,
"upload_time": "2022-12-10T22:42:20",
"upload_time_iso_8601": "2022-12-10T22:42:20.555129Z",
"url": "https://files.pythonhosted.org/packages/fb/59/c3fb5145adde74b466b8952671383490b673018482c7b3104f7ee5d9cfb8/easyshare-0.17.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-10 22:42:20",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "Docheinstein",
"github_project": "easyshare",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "easyshare"
}