Skip to content

Commit

Permalink
✨ CLI and README
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Valenzuela committed Jun 13, 2021
1 parent 79d0c86 commit 4a3e77a
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 48 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
Dockerfile
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[package]
name = "sampicore"
version = "0.1.0"
version = "0.2.0"
authors = ["Daniel Valenzuela <[email protected]>"]
edition = "2018"
description = "🐶 Take a screenshot get a shareable URL"
licence = "MIT"
license-file = "LICENSE"
repository = "https://github.com/DanielVZ96/sampicore.git"
homepage = "https://github.com/DanielVZ96/sampicore"
Expand All @@ -14,7 +15,6 @@ keywords = ["screenshot", "upload", "sam"]
confy = "^0.3.1"
scrap = "0.5"
image = "^0.23.14"
egg-mode = "0.15"
directories-next = "^2.0"
futures = "^0.3"
serde = { version = "^1.0", features = ["derive"] }
Expand Down
32 changes: 32 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Dockerfile for creating a statically-linked Rust application using docker's
# multi-stage build feature. This also leverages the docker build cache to avoid
# re-downloading dependencies if they have not changed.
FROM rustlang/rust:nightly-buster AS build
WORKDIR /usr/src

RUN rustup target add x86_64-unknown-linux-gnu
RUN apt update && apt install -y libxcb-randr0-dev

# Create a dummy project and build the app's dependencies.
# If the Cargo.toml or Cargo.lock files have not changed,
# we can use the docker build cache and skip these (typically slow) steps.
RUN USER=root cargo new sampic
WORKDIR /usr/src/sampic
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release

# Copy the source and build the application.
RUN cargo install --target x86_64-unknown-linux-gnu --path .

# Copy the statically-linked binary into a scratch container.
FROM rustlang/rust:nightly-buster
WORKDIR /usr/src/sampic
RUN apt update && apt install -y libxcb-randr0-dev
RUN mkdir /.config && chown -R 1000 /.config
USER 1000
COPY --from=build /usr/local/cargo/bin/sampic /usr/src/sampic/
COPY ./entrypoint.sh /usr/src/sampic/entrypoint.sh
ENV PATH="/usr/src/sampic:${PATH}"
ENV XDG_CONFIG_HOME="/.config"
CMD ["./entrypoint.sh"]
150 changes: 150 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,152 @@
# 🐶 Sampicore

Take a screenshot, get a shareable URL

# Installation

I've only installed it on PopOS (Ubuntu/Debian based), and I needed these deps:

```sh
sudo apt update && sudo apt install libxcb-randr0-dev build-essential libssl-dev libssl-dev pkg-config libxcb1-dev libxcb-shm0-dev
```

Currently it's only published in cargo:

```sh
$ cargo install sampicore # will download and build sampic
```

# Configuration

It consists on a single `sampic.toml` file with the following contents:

```toml
$ cat ~/.config/sampic/sampic.toml
api_key = 'S3_API_KEY'
api_secret_key = 'S3_SECRET_API_KEY'
region = 'S3_REGION_'
endpoint = 'S3_ENDPOINT'
bucket = 'sampic-store'
local_path = '/tmp'
sampic_endpoint = 'https://sampic.xyz/upload'
```

Configuration will be saved locally depending on your OS in the following directories:

(According to the [directories](https://docs.rs/directories/0.10.0/src/directories/lib.rs.html#10) rust package)

> - the [XDG base directory](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) and the [XDG user directory](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/) specifications on Linux,
> - the [Known Folder](<https://msdn.microsoft.com/en-us/library/windows/desktop/bb776911(v=vs.85).aspx>) system on Windows, and
> - the [Standard Directories](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6) on macOS.
# Usage

```text
$ sampic
sampic 0.1.0
Takes pictures and generates links
USAGE:
sampic <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
config Manage sampic configuration.
help Prints this message or the help of the given subcommand(s)
local Takes a screenshot, saves it locally and returns it's path.
s3 Takes a screenshot, saves it in s3 and returns it's link.
server Runs a sampic server.
upload Takes a screenshot, sends it to sampic and returns it's link.
```

## upload

The easiest way to use sampic. It takes a screenshot, sends it to my own sampic server, and copies it's URL to your clipboard.

```text
$ sampic upload -h
sampic-upload
Takes a screenshot, sends it to sampic and returns it's link.
USAGE:
sampic upload
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
```

## local

Similar to upload, but instead saves the screenshot to a local path and copies that to your clipboard.

```text
$ sampic local -h
sampic-local
Takes a screenshot, saves it locally and returns it's path.
USAGE:
sampic local
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
```

## s3

If you have an s3-compatible bucket available, you can use this subcommand to send your screenshots there. You'll have to configure it in the sampic.toml file.

```text
$ sampic s3 -h
sampic-s3
Takes a screenshot, saves it in s3 and returns it's link.
USAGE:
sampic s3
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
```

## config (may leave a mess in your config file)

CLI interface to change configurations. Generally works ok, but it sometimes messes with my sampic.toml.

```text
$ sampic config -h
sampic-config
Manage sampic configuration.
USAGE:
sampic config <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
list List current sampic configuration values.
set Set sampic configuration.
```

# Future

There are some things I'd like to do in order to make sampic feature complete for my use-case:

- [ ] Crossplatform region selection. Could be done in linux with the [hacksaw](https://crates.io/crates/hacksaw) crate.
- [ ] Make sure it's secure.
- [ ] Rate limit everything with the option to register and maybe even pay to relax rate limits.
- [ ] Separate code with [feature flags](https://doc.rust-lang.org/cargo/reference/features.html).
- [ ] Tests.
- [ ] A logo.
- [ ] A homepage.

I'd love to do them all, but I'm currently working full-time, so I just work sporadically on sampic when I can during my free time.
16 changes: 16 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
mkdir -p $XDG_CONFIG_HOME/sampic
CONFIG_LOCATION="$XDG_CONFIG_HOME/sampic/sampic.toml"

cat >$CONFIG_LOCATION <<EOF
storage = 'Local'
api_key = '$API_KEY'
api_secret_key = '$SECRET_KEY'
region = 'fr-par'
endpoint = 'https://s3.fr-par.scw.cloud'
bucket = 'sampic-store'
local_path = '/tmp/'
sampic_endpoint = 'example.com'
EOF
cat $CONFIG_LOCATION
./sampic server
1 change: 1 addition & 0 deletions rust-toolchain
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nightly
42 changes: 38 additions & 4 deletions src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ mod lib;
extern crate clap;

fn main() {
let matches = clap_app!(myapp =>
(version: "1.0")
(author: "Daniel V. <[email protected]>")
let matches = clap_app!(sampic =>
(version: "0.2.0")
(about: "Takes pictures and generates links")
(@setting SubcommandRequiredElseHelp)
(@setting ColoredHelp)
(@subcommand local =>
(about: "Takes a screenshot, saves it locally and returns it's path.")
)
Expand All @@ -25,16 +25,50 @@ fn main() {
(@subcommand server =>
(about: "Runs a sampic server.")
)
(@subcommand config =>
(about: "Manage sampic configuration.")
(@setting SubcommandRequiredElseHelp)
(@setting ColoredHelp)
(@subcommand set =>
(about: "Set sampic configuration.")
(@setting ArgRequiredElseHelp)
(@arg NAME: +required "Name of configuration to set.")
(@arg VALUE: +required "Value to set.")
)
(@subcommand list =>
(about: "List current sampic configuration values.")
)
)
)
.get_matches();
match matches.subcommand_name() {
let message: String = match matches.subcommand_name() {
Some("local") => lib::local_screenshot(),
Some("s3") => lib::s3_screenshot(),
Some("upload") => lib::upload_screenshot(),
Some("server") => rocket::ignite()
.mount("/", routes![lib::server::upload])
.launch()
.to_string(),
Some("config") => {
let subcommand = matches.subcommand_matches("config").unwrap();
match subcommand.subcommand_name() {
Some("set") => {
let set_matches = subcommand.subcommand_matches("set").unwrap();
let name = set_matches.value_of("NAME").unwrap().to_string();
let value = set_matches.value_of("VALUE").unwrap().to_string();
lib::config::set(name, value).unwrap();
return ();
}
Some("list") => {
let list: String = lib::config::list().unwrap();
println!("{}", list);
return ();
}
Some(_) | None => "Ok".to_string(),
};
return ();
}
Some(_) | None => "Do something!".to_string(),
};
println!("{}", message);
}
Loading

0 comments on commit 4a3e77a

Please sign in to comment.