Compare commits
No commits in common. "56d45ad311562c6474cedc6850674b907d329e27" and "2197dd0c1d4055098de1020564cf480fbc0f2e43" have entirely different histories.
56d45ad311
...
2197dd0c1d
14 changed files with 12 additions and 153 deletions
15
README.md
15
README.md
|
|
@ -1,10 +1,6 @@
|
||||||
# Code Snippets
|
# Code Snippets
|
||||||
|
|
||||||
Backend application to store my code snippets and make them available via REST API.
|
App to store my code snippets.
|
||||||
|
|
||||||
[CLI CMS Companion Project](https://git.sr.ht/~travisshears/code-snippets-cli-cms)
|
|
||||||
|
|
||||||
This project is written in [Clojure](https://clojure.org/) and data is stored in [XTDB](https://xtdb.dev/).
|
|
||||||
|
|
||||||
## Links
|
## Links
|
||||||
|
|
||||||
|
|
@ -20,12 +16,3 @@ This project is written in [Clojure](https://clojure.org/) and data is stored in
|
||||||
```
|
```
|
||||||
$ clojure -M -m snippets.infra.api
|
$ clojure -M -m snippets.infra.api
|
||||||
```
|
```
|
||||||
|
|
||||||
### How to create docker image
|
|
||||||
|
|
||||||
At this point I'm using a private AWS ECR repository for the project and deploying it in my homelab.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ export AWS_PROFILE=personal
|
|
||||||
$ docker buildx build --platform linux/amd64,linux/arm64 -t 853019563312.dkr.ecr.eu-central-1.amazonaws.com/snippets-homelabstack:latest --push .
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete {
|
delete {
|
||||||
url: {{host}}/api/snippet?id=d77d3463-c76e-4c53-a1d5-ecaf16c6c54e
|
url: {{host}}/api/snippet?id=90d00a80-78c4-4bc9-a066-01c988599d05
|
||||||
body: none
|
body: none
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
params:query {
|
params:query {
|
||||||
id: d77d3463-c76e-4c53-a1d5-ecaf16c6c54e
|
id: 90d00a80-78c4-4bc9-a066-01c988599d05
|
||||||
}
|
}
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ params:query {
|
||||||
|
|
||||||
body:json {
|
body:json {
|
||||||
{
|
{
|
||||||
"title": "quick way to push last jj commit to git",
|
"title": "Updated from Bruno",
|
||||||
"tags": ["jj", "git"]
|
"tags": ["code", "mock"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
meta {
|
|
||||||
name: get_snippet_by_slug
|
|
||||||
type: http
|
|
||||||
seq: 10
|
|
||||||
}
|
|
||||||
|
|
||||||
get {
|
|
||||||
url: {{host}}/api/snippet-by-slug?slug=netcat-over-ping
|
|
||||||
body: none
|
|
||||||
auth: none
|
|
||||||
}
|
|
||||||
|
|
||||||
params:query {
|
|
||||||
slug: netcat-over-ping
|
|
||||||
}
|
|
||||||
|
|
||||||
body:json {
|
|
||||||
{
|
|
||||||
"title": "Test Snippet",
|
|
||||||
"markdown": "## Cool Snippet\ndoes a cool thing",
|
|
||||||
"tags": ["git", "jj"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,13 +5,13 @@ meta {
|
||||||
}
|
}
|
||||||
|
|
||||||
get {
|
get {
|
||||||
url: {{host}}/api/snippets?limit=25&skip=0
|
url: {{host}}/api/snippets?limit=100&skip=0
|
||||||
body: none
|
body: none
|
||||||
auth: none
|
auth: none
|
||||||
}
|
}
|
||||||
|
|
||||||
params:query {
|
params:query {
|
||||||
limit: 25
|
limit: 100
|
||||||
skip: 0
|
skip: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
meta {
|
|
||||||
name: get_tag
|
|
||||||
type: http
|
|
||||||
seq: 9
|
|
||||||
}
|
|
||||||
|
|
||||||
get {
|
|
||||||
url: {{host}}/api/tag?tag=git
|
|
||||||
body: none
|
|
||||||
auth: none
|
|
||||||
}
|
|
||||||
|
|
||||||
params:query {
|
|
||||||
tag: git
|
|
||||||
}
|
|
||||||
|
|
||||||
body:json {
|
|
||||||
{
|
|
||||||
"title": "Test Snippet",
|
|
||||||
"markdown": "## Cool Snippet\ndoes a cool thing",
|
|
||||||
"tags": ["git", "jj"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
meta {
|
|
||||||
name: get_tags
|
|
||||||
type: http
|
|
||||||
seq: 8
|
|
||||||
}
|
|
||||||
|
|
||||||
get {
|
|
||||||
url: {{host}}/api/tags
|
|
||||||
body: none
|
|
||||||
auth: none
|
|
||||||
}
|
|
||||||
|
|
||||||
body:json {
|
|
||||||
{
|
|
||||||
"title": "Test Snippet",
|
|
||||||
"markdown": "## Cool Snippet\ndoes a cool thing",
|
|
||||||
"tags": ["git", "jj"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
16
build.sh
16
build.sh
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
export AWS_PROFILE=personal
|
|
||||||
export AWS_REGION=eu-central-1
|
|
||||||
|
|
||||||
REPO_NAME="snippets-homelabstack"
|
|
||||||
|
|
||||||
if ! aws ecr describe-repositories --repository-names "$REPO_NAME" >/dev/null 2>&1; then
|
|
||||||
aws ecr create-repository --repository-name "$REPO_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker buildx build --platform linux/amd64,linux/arm64 -t "853019563312.dkr.ecr.eu-central-1.amazonaws.com/${REPO_NAME}:latest" --push .
|
|
||||||
|
|
||||||
echo "Docker image built and pushed to AWS ECR"
|
|
||||||
4
deps.edn
4
deps.edn
|
|
@ -1,7 +1,7 @@
|
||||||
{:paths ["src"]
|
{:paths ["src"]
|
||||||
:deps {;; api
|
:deps {ring/ring-core {:mvn/version "1.13.0"}
|
||||||
ring/ring-core {:mvn/version "1.13.0"}
|
|
||||||
ring/ring-jetty-adapter {:mvn/version "1.13.0"}
|
ring/ring-jetty-adapter {:mvn/version "1.13.0"}
|
||||||
|
;; logging, required by jetty:
|
||||||
org.slf4j/slf4j-simple {:mvn/version "2.0.16"}
|
org.slf4j/slf4j-simple {:mvn/version "2.0.16"}
|
||||||
|
|
||||||
;; db
|
;; db
|
||||||
|
|
|
||||||
|
|
@ -47,26 +47,6 @@
|
||||||
{:status 200
|
{:status 200
|
||||||
:body (format "Deleted snippet with id: %s if it existed" id)}))
|
:body (format "Deleted snippet with id: %s if it existed" id)}))
|
||||||
|
|
||||||
(defn handle-view-tags [_args]
|
|
||||||
(let [tags (snippets.use-cases.view/view-tags)]
|
|
||||||
{:status 200
|
|
||||||
:body tags}))
|
|
||||||
|
|
||||||
(defn handle-view-snippets-by-tag [{params :query-params}]
|
|
||||||
(let [tag (get params "tag")]
|
|
||||||
{:status 200
|
|
||||||
:body (snippets.use-cases.view/view-snippets-by-tag tag)}))
|
|
||||||
|
|
||||||
(defn handle-view-tags [_]
|
|
||||||
(let [tags (snippets.use-cases.view/view-tags)]
|
|
||||||
{:status 200
|
|
||||||
:body tags}))
|
|
||||||
|
|
||||||
(defn handle-view-snippet-by-slug [{params :query-params}]
|
|
||||||
(let [slug (get params "slug")]
|
|
||||||
{:status 200
|
|
||||||
:body (snippets.use-cases.view/view-snippet-by-slug slug)}))
|
|
||||||
|
|
||||||
(defn wrap [handler id]
|
(defn wrap [handler id]
|
||||||
(fn [request]
|
(fn [request]
|
||||||
(update (handler request) :wrap (fnil conj '()) id)))
|
(update (handler request) :wrap (fnil conj '()) id)))
|
||||||
|
|
@ -78,9 +58,6 @@
|
||||||
mm/wrap-format
|
mm/wrap-format
|
||||||
[wrap :api]]}
|
[wrap :api]]}
|
||||||
["/ping" {:get handle-ping}]
|
["/ping" {:get handle-ping}]
|
||||||
["/tags" {:get handle-view-tags}]
|
|
||||||
["/tag" {:get handle-view-snippets-by-tag}]
|
|
||||||
["/snippet-by-slug" {:get handle-view-snippet-by-slug}]
|
|
||||||
["/snippets" {:get handle-view-snippets}]
|
["/snippets" {:get handle-view-snippets}]
|
||||||
["/snippet" {:post handle-create-snippet
|
["/snippet" {:post handle-create-snippet
|
||||||
:get handle-view-snippet
|
:get handle-view-snippet
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,7 @@
|
||||||
(format "(quote (-> (from :snippets [title pub-date tags slug markdown {:xt/id id}]) (order-by {:val pub-date, :dir :desc, :nulls :last}) (offset %s) (limit %s)))" skip limit)))))
|
(format "(quote (-> (from :snippets [title pub-date tags slug markdown {:xt/id id}]) (order-by {:val pub-date, :dir :desc, :nulls :last}) (offset %s) (limit %s)))" skip limit)))))
|
||||||
|
|
||||||
(defn get-snippet-by-id [snippet-id]
|
(defn get-snippet-by-id [snippet-id]
|
||||||
(first (xt/q client ['#(from :snippets [{:xt/id %} slug title tags {:xt/id id} markdown pub-date]) snippet-id])))
|
(first (xt/q client ['#(from :snippets [{:xt/id %} slug title {:xt/id id} markdown pub-date]) snippet-id])))
|
||||||
|
|
||||||
(defn get-snippet-by-slug [slug]
|
|
||||||
(first (xt/q client ['#(from :snippets [{:xt/id id} {:slug %} slug title tags markdown pub-date]) slug])))
|
|
||||||
|
|
||||||
(defn put-snippet [id snippet]
|
(defn put-snippet [id snippet]
|
||||||
(t/log! {:level :info, :data {:snippet snippet :id id}} "Saving new snippet to db")
|
(t/log! {:level :info, :data {:snippet snippet :id id}} "Saving new snippet to db")
|
||||||
|
|
@ -42,12 +39,3 @@
|
||||||
(defn patch-snippet [id patch]
|
(defn patch-snippet [id patch]
|
||||||
(t/log! {:level :info, :data {:patch patch :id id}} "Patching snippet")
|
(t/log! {:level :info, :data {:patch patch :id id}} "Patching snippet")
|
||||||
(xt/execute-tx client [[:patch-docs :snippets (merge {:xt/id id} patch)]]))
|
(xt/execute-tx client [[:patch-docs :snippets (merge {:xt/id id} patch)]]))
|
||||||
|
|
||||||
(defn list-tags []
|
|
||||||
;; (xt/q client '(-> (from :snippets [{:xt/id id} tags]) (unnest {:tag tags}) (without :tags) (aggregate tag {:ids (array-agg id)}))))
|
|
||||||
(xt/q client '(-> (from :snippets [{:xt/id id} tags]) (unnest {:tag tags}) (without :tags) (aggregate tag {:count (count id)}))))
|
|
||||||
|
|
||||||
(defn get-snippets-by-tag [tag]
|
|
||||||
(map #(dissoc % :tag)
|
|
||||||
(xt/q client (eval (read-string
|
|
||||||
(format "(quote (-> (from :snippets [title slug tags pub-date]) (unnest {:tag tags}) (without :tags) (where (= tag \"%s\"))))" tag))))))
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
(ns snippets.main
|
(ns snippets.main
|
||||||
(:require [snippets.infra.api :as api])
|
(:require [snippets.api :as api])
|
||||||
(:gen-class))
|
(:gen-class))
|
||||||
|
|
||||||
(defn -main []
|
(defn -main []
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[:map {:closed true}
|
[:map {:closed true}
|
||||||
[:markdown {:optional true} :string]
|
[:markdown {:optional true} :string]
|
||||||
[:title {:optional true} :string]
|
[:title {:optional true} :string]
|
||||||
[:tags {:optional true} [:seqable :string]]
|
[:tags [:seqable :string]]
|
||||||
[:slug {:optional true} :string]]))
|
[:slug {:optional true} :string]]))
|
||||||
|
|
||||||
(defn edit-snippet [id patch]
|
(defn edit-snippet [id patch]
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,3 @@
|
||||||
|
|
||||||
(defn view-snippets [& args]
|
(defn view-snippets [& args]
|
||||||
(db/list-snippets args))
|
(db/list-snippets args))
|
||||||
|
|
||||||
(defn view-tags []
|
|
||||||
(t/log! {:level :info} "Viewing tags")
|
|
||||||
(db/list-tags))
|
|
||||||
|
|
||||||
(defn view-snippets-by-tag [tag]
|
|
||||||
(t/log! {:level :info :data {:tag tag}} "Viewing snippet by tag")
|
|
||||||
(db/get-snippets-by-tag tag))
|
|
||||||
|
|
||||||
(defn view-snippet-by-slug [slug]
|
|
||||||
(t/log! {:level :info :data {:slug slug}} "Viewing snippet by slug")
|
|
||||||
(db/get-snippet-by-slug slug))
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue