Compare commits

..

13 Commits

Author SHA1 Message Date
ge
71e1d87d32 feat: Improve and make scripts POSIX compliant 2022-09-29 10:47:48 +03:00
ge
921dd5d29d feat: Add dark theme via prefers-color-scheme 2022-09-29 10:46:51 +03:00
ge
cde343d159 update README 2022-09-29 10:44:41 +03:00
ge
cd258011be fix: Update link 2022-09-29 08:31:36 +03:00
aed21e14a3 Merge pull request #2 from gechandesu/dependabot/pip/bottle-0.12.20
build(deps): Bump bottle from 0.12.19 to 0.12.20
2022-07-27 08:40:34 +03:00
85b2664483 build(deps): Bump bottle from 0.12.19 to 0.12.20
Bumps [bottle](https://github.com/bottlepy/bottle) from 0.12.19 to 0.12.20.
- [Release notes](https://github.com/bottlepy/bottle/releases)
- [Changelog](https://github.com/bottlepy/bottle/blob/master/docs/changelog.rst)
- [Commits](https://github.com/bottlepy/bottle/compare/0.12.19...0.12.20)

---
updated-dependencies:
- dependency-name: bottle
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-03 22:50:24 +00:00
ge
dbdbf2a3d9 feat: Remove WSGI server from requirements 2022-03-17 21:42:47 +03:00
ge
3a8bef4ddc feat: Reduce image size from ~930M to ~85M 2022-03-17 21:42:06 +03:00
ge
8122de2c52 fix: Naitilus script fixed 2022-01-29 02:43:50 +03:00
ge
2eea050bf8 fix: Fix typo in README 2022-01-23 16:47:49 +03:00
gd
2f7fc76573 fix: Fix Nginx vhost example 2022-01-05 13:22:13 +03:00
gd
dd570f7f93 feat: Add Dockerfile 2022-01-05 13:12:51 +03:00
gd
312efc9047 feat: Update requirements 2022-01-05 11:18:10 +03:00
7 changed files with 209 additions and 139 deletions

9
Dockerfile Normal file
View File

@ -0,0 +1,9 @@
FROM alpine:latest
RUN apk update && apk add python3 py3-pip
ADD . /opt/imgs
RUN mkdir -p /opt/imgs/uploads
WORKDIR /opt/imgs
RUN pip install --upgrade pip && pip install --requirement requirements.txt
RUN pip install gunicorn
EXPOSE 5000
CMD gunicorn imgs:app --bind :5000

View File

@ -5,24 +5,74 @@ imgs is a minimalictic image sharing web app written with Bottle framework.
No database. No image compression. No time limits. No additional dependencies. No database. No image compression. No time limits. No additional dependencies.
Features: Features:
* Upload images via Drag&Drop * Upload images via Drag&Drop
* Easy copy share link * Easy copy share link
* MIME type detecting * MIME type detecting
See deployment options in Bottle documentation: https://bottlepy.org/docs/dev/deployment.html See deployment options in Bottle documentation: https://bottlepy.org/docs/dev/deployment.html
# Run imgs in Docker
Clone repository and edit **imgs.ini**.
Build Docker image:
```shell
docker build --tag imgs .
```
Run container from image. Replace **/path/to/your/uploads/dir** with path to directory where you want to store images:
```shell
docker run -d \
--name imgs \
--publish 127.0.0.1:5000:5000 \
--volume /path/to/your/uploads/dir:/opt/imgs/uploads \
imgs
```
imgs will launched on `127.0.0.1:5000`. Set up reverse proxy server. I recommed to use basic authentication to prevent abuses. Nginx virtual host example:
```nginx
server {
listen 80;
server_name yourdomain.tld;
root /path/to/imgs/root;
location / {
auth_basic "Authentication required";
auth_basic_user_file /path/to/.htpasswd;
proxy_pass http://127.0.0.1:5000;
}
location ~* ^/favicon.ico$ {
try_files $uri $uri/ =404;
}
location ~* \..* {
auth_basic off;
proxy_pass http://127.0.0.1:5000;
}
}
```
# Additional # Additional
## imgs client with CLI ## imgs client with CLI
imgs has a simple CLI tool based on curl. Copy **imgs** script to your PATH. imgs has a simple CLI tool based on curl. Copy **imgs** script to your PATH.
```bash ```shell
sudo cp imgs /usr/bin/imgs sudo cp imgs /usr/bin/imgs
``` ```
## Nautilus integration ## Nautilus integration
Push files to your imgs instance via GNOME Files (former name: Nautilus). Depends packages: curl, notyfy-send. Push files to your imgs instance via GNOME Files (former name: Nautilus). Depends on: curl, libnotify (notify-send utility).
Just place **Upload to imgs** script into **~/.local/share/nautilus/scripts**. Just place **Upload to imgs** script into **~/.local/share/nautilus/scripts/** directory.
```shell
DIR=~/.local/share/nautilus/scripts/; mkdir -p $DIR && cp Upload\ to\ imgs $DIR
```

View File

@ -1,36 +1,32 @@
#!/usr/bin/env bash #!/bin/sh
# This is an imgs <https://gitea.gch.icu/ge/imgs> "integration" for Nautilus. # This is an imgs https://git.nxhs.cloud/ge/imgs "integration" for Nautilus.
# Place this script into path: $HOME/.local/share/nautilus/scripts # Place this script into path: $HOME/.local/share/nautilus/scripts
# See more info at: <https://help.ubuntu.com/community/NautilusScriptsHowto> # See more info at: <https://help.ubuntu.com/community/NautilusScriptsHowto>
imgs_check_vars() { IMGSLOG="${IMGSLOG:-$HOME/imgs_debug.log}"
[ "$IMGSLOG" ] || IMGSLOG=$HOME/imgs_debug.log [ -n "$IMGSREMOTE" ] && return 0 # exit from func if variable is set
[ "$IMGSREMOTE" ] && return 0 # exit from func if variable is set
if [ -f "$HOME/.imgsremote" ]; then if [ -f "$HOME"/.imgsremote ]; then
. $HOME/.imgsremote # shellcheck source=/dev/null
. "$HOME"/.imgsremote
fi fi
if [ "$IMGSREMOTE" ]; then if [ -z "$IMGSREMOTE" ]; then
: echo "$0: Error: IMGSREMOTE variable is not set." >&2; exit 1
else
echo "$0: Error: IMGSREMOTE variable is not set." >&2
exit 1
fi fi
}
[ "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Started" >> "$IMGSLOG" [ -n "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Started" >> "$IMGSLOG"
while read -r file; do echo "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | while read -r file; do
[ "$file" ] || break [ -z "$file" ] && break
if [ "$IMGSDEBUG" ]; then if [ -n "$IMGSDEBUG" ]; then
image="$(curl -v -L -F "image=@$file" "$IMGSREMOTE" 2>&1 | tee -a "$IMGSLOG")" image="$(curl -v -L -F "image=@$file" "$IMGSREMOTE" 2>&1 | tee -a "$IMGSLOG")"
image="$(tail -n 1 <<< "$image")" image="$(echo "$image" | tail -n 1)"
else else
image="$(curl -L -F "image=@$file" "$IMGSREMOTE")" image="$(curl -L -F "image=@$file" "$IMGSREMOTE")"
fi fi
[ "$IMGSDEBUG" ] && echo "$(date +"[%d %b %Y %H:%M:%S]") $file --> $image" >> "$IMGSLOG" [ -n "$IMGSDEBUG" ] && echo "$(date +"[%d %b %Y %H:%M:%S]") $file --> $image" >> "$IMGSLOG"
notify-send "File uploaded to imgs!" "$image" notify-send "File uploaded to imgs!" "$image"
done <<< "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" done
[ "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Finished" >> "$IMGSLOG" [ -n "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Finished" >> "$IMGSLOG"

88
imgs
View File

@ -1,18 +1,16 @@
#!/usr/bin/env bash #!/bin/sh
# imgs CLI client. # imgs CLI https://git.nxhs.cloud/ge/imgs
# Home page: <https://gitea.gch.icu/ge/imgs>
imgs_usage() { imgs_usage() {
cat <<- EOF cat <<- EOF
Upload images to remote imgs server. Upload images to remote imgs server.
Usage: imgs [--version] [--help] [-r | --remote <URL>] <file>... Usage: imgs [-rvh] <file>...
Options: Options:
-r, --remote remote imgs instance URI. Example: -r, --remote remote imgs instance URI e.g. https://user:password@example.org
'https://user:password@example.org' -v, --version print version and exit.
--version print version and exit. -h, --help print this help message and exit.
--help print this help message and exit.
Environment variables: Environment variables:
IMGSREMOTE remote imgs instance URI. IMGSREMOTE remote imgs instance URI.
@ -20,55 +18,57 @@ imgs_usage() {
IMGSLOG path to logfile. Default: ~/imgs_debug.log IMGSLOG path to logfile. Default: ~/imgs_debug.log
You can set variables in ~/.imgsremote file instead of ~/.bashrc You can set variables in ~/.imgsremote file instead of ~/.bashrc
See <https://gitea.gch.icu/ge/imgs> for more info. See <https://git.nxhs.cloud/ge/imgs> for more info.
EOF EOF
exit 0
} }
imgs_check_vars() { [ "$#" -eq 0 ] && { imgs_usage; exit 1; }
[ "$IMGSLOG" ] || IMGSLOG=$HOME/imgs_debug.log
[ "$IMGSREMOTE" ] && return 0 # exit from func if variable is set
if [ -f "$HOME/.imgsremote" ]; then # Transform long options to short ones
. $HOME/.imgsremote for arg in "$@"; do
fi shift
case "$arg" in
if [ "$IMGSREMOTE" ]; then --remote) set -- "$@" "-r";;
: --help) set -- "$@" "-h";;
else --version) set -- "$@" "-v";;
echo "$0: Error: IMGSREMOTE variable is not set." >&2 *) set -- "$@" "$arg";;
exit 1
fi
}
[[ "$@" ]] || imgs_usage
while (( "$#" )); do
case "$1" in
-r|--remote) if [ "$2" ] && [ "${2:0:1}" != '-' ]; then
IMGSREMOTE="$2"; shift
else
echo "$0: missing argument for $1" >&2; exit 1
fi; shift;;
--version) echo 'imgs CLI 1.0'; exit 0;;
--help) imgs_usage;;
-*) echo "$0: $1: bad option" >&2; exit 1;;
*) [ -f "$1" ] || { echo "$0: $1: no such file" >&2; exit 1; }
_files+=("$1"); shift;;
esac esac
done done
imgs_check_vars while getopts r:vh OPT; do
case "$OPT" in
r) IMGSREMOTE="$OPTARG";;
v) echo 'imgs CLI 1.1'; exit 0;;
h) imgs_usage; exit 0;;
*) echo "$0: Unknown option: $OPT" >&2; exit 1;;
esac
done
[ "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Started" | tee -a "$IMGSLOG" shift $((OPTIND - 1)) # shift for parse positional args
for file in "${_files[@]}"; do # Check variables
IMGSLOG="${IMGSLOG:-$HOME/imgs_debug.log}"
[ -n "$IMGSREMOTE" ] && return 0 # exit from func if variable is set
if [ -f "$HOME"/.imgsremote ]; then
# shellcheck source=/dev/null
. "$HOME"/.imgsremote
fi
if [ -z "$IMGSREMOTE" ]; then
echo "$0: Error: IMGSREMOTE variable is not set." >&2; exit 1
fi
[ -n "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Started" | tee -a "$IMGSLOG"
for file in "$@"; do
filepath="$(realpath "$file")" filepath="$(realpath "$file")"
if [ "$IMGSDEBUG" ]; then if [ -n "$IMGSDEBUG" ]; then
echo "Uploading $filepath" | tee -a "$IMGSLOG" echo "Uploading $filepath ..." | tee -a "$IMGSLOG"
curl -v -L -F "image=@/$filepath" "$IMGSREMOTE" 2>&1 | tee -a "$IMGSLOG" curl -v -L -F "image=@/$filepath" "$IMGSREMOTE" 2>&1 | tee -a "$IMGSLOG"
else else
curl -L -F "image=@/$filepath" "$IMGSREMOTE" curl -L -F "image=@/$filepath" "$IMGSREMOTE"
fi fi
done done
[ "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Finished" | tee -a "$IMGSLOG" [ -n "$IMGSDEBUG" ] && date +"[%d %b %Y %H:%M:%S] Finished" | tee -a "$IMGSLOG"

View File

@ -77,7 +77,7 @@
<div class="logo"> <div class="logo">
<pre> __<br>|__| _____ ____ ______<br>| |/ \ / ___\/ ___/<br>| | Y Y / /_/ \___ \<br>|__|__|_| \___ /____ ><br> \/_____/ \/</pre> <pre> __<br>|__| _____ ____ ______<br>| |/ \ / ___\/ ___/<br>| | Y Y / /_/ \___ \<br>|__|__|_| \___ /____ ><br> \/_____/ \/</pre>
</div> </div>
<p><a href="https://gitea.gch.icu/ge/imgs" target="_blank">v1.1</a></p> <p><a href="https://git.nxhs.cloud/ge/imgs" target="_blank">v1.1</a></p>
</main> </main>
</body> </body>

View File

@ -1 +1 @@
bottle==0.12.19 bottle==0.12.20

View File

@ -1,5 +1,18 @@
:root {
--b: #000;
--w: #fff;
}
@media (prefers-color-scheme: dark) {
:root {
--b: #fff;
--w: #000;
}
}
body { body {
background-color: #fff; color: var(--b);
background-color: var(--w);
font-family: 'Ubuntu Mono', monospace; font-family: 'Ubuntu Mono', monospace;
max-width: 720px; max-width: 720px;
margin: 0 auto; margin: 0 auto;
@ -7,11 +20,14 @@ body {
} }
main { margin: 4rem 2rem; } main { margin: 4rem 2rem; }
.not-found, .bad-mime-type { margin-bottom: 2rem; } a, a:visited { color: var(--b); }
a, a:visited { color: #000; }
img { width: 100%; } img { width: 100%; }
.not-found, .bad-mime-type { margin-bottom: 2rem; }
.logo pre {
display: flex;
justify-content: center;
text-align: left;
}
/* Drag and Drop */ /* Drag and Drop */
.drop-area { .drop-area {
@ -23,9 +39,7 @@ img { width: 100%; }
padding: 25px; padding: 25px;
border: 3px dashed #e1e1e1; border: 3px dashed #e1e1e1;
} }
.drop-area.dragover { border-color: var(--b); }
.drop-area.dragover { border-color: #000; }
.file-input { .file-input {
position: absolute; position: absolute;
left: 0; left: 0;
@ -36,7 +50,6 @@ img { width: 100%; }
align-items: center; align-items: center;
opacity: 0; opacity: 0;
} }
.file-input-label { .file-input-label {
display: block; display: block;
margin-top: 1rem; margin-top: 1rem;
@ -46,17 +59,17 @@ img { width: 100%; }
.copy-to-clipboard { .copy-to-clipboard {
display: flex; display: flex;
margin: 2rem 0; margin: 2rem 0;
border: 1px solid #000000; border: 1px solid var(--b);
} }
.copy-to-clipboard input[type=text] { .copy-to-clipboard input[type=text] {
flex: 50%; flex: 50%;
width: 100%; width: 100%;
padding: 12px 20px; padding: 12px 20px;
border: none; border: none;
outline: none; outline: none;
background-color: var(--w);
color: var(--b);
} }
.copy-to-clipboard button { .copy-to-clipboard button {
padding: 12px 20px; padding: 12px 20px;
margin: 0; margin: 0;
@ -64,8 +77,8 @@ img { width: 100%; }
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
border: none; border: none;
background-color: #000000; background-color: var(--b);
color: #ffffff; color: var(--w);
} }
/* cURL command */ /* cURL command */
@ -73,13 +86,15 @@ img { width: 100%; }
text-align: left; text-align: left;
padding: 12px 20px; padding: 12px 20px;
font-size: 14px; font-size: 14px;
background: #000000; background: var(--b);
color: #ffffff; color: var(--w);
overflow-x: auto; overflow-x: auto;
} }
.logo pre { /* SVG */
display: flex; svg {
justify-content: center; color: var(--b);
text-align: left; }
svg path {
stroke: currentcolor;
} }