Auto-expire png files after 7 days
This commit is contained in:
parent
f184616432
commit
368d0787cf
@ -1,5 +1,6 @@
|
|||||||
{:components
|
{:components
|
||||||
{:file-store #var asciinema.component.local-file-store/local-file-store}
|
{:file-store #var asciinema.component.local-file-store/local-file-store
|
||||||
|
:exp-set #var asciinema.component.mem-expiring-set/mem-expiring-set}
|
||||||
:config
|
:config
|
||||||
{:app
|
{:app
|
||||||
{:middleware
|
{:middleware
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
[clj-aws-s3 "0.3.10" :exclusions [joda-time com.fasterxml.jackson.core/jackson-core com.fasterxml.jackson.core/jackson-annotations]]
|
[clj-aws-s3 "0.3.10" :exclusions [joda-time com.fasterxml.jackson.core/jackson-core com.fasterxml.jackson.core/jackson-annotations]]
|
||||||
[aleph "0.4.1"]
|
[aleph "0.4.1"]
|
||||||
[pandect "0.6.1"]
|
[pandect "0.6.1"]
|
||||||
|
[com.taoensso/carmine "2.15.1"]
|
||||||
[org.slf4j/slf4j-nop "1.7.21"]
|
[org.slf4j/slf4j-nop "1.7.21"]
|
||||||
[org.webjars/normalize.css "3.0.2"]
|
[org.webjars/normalize.css "3.0.2"]
|
||||||
[duct/hikaricp-component "0.1.0"]
|
[duct/hikaricp-component "0.1.0"]
|
||||||
|
@ -3,14 +3,15 @@
|
|||||||
:http #var asciinema.component.aleph/aleph-server
|
:http #var asciinema.component.aleph/aleph-server
|
||||||
:db #var asciinema.component.db/hikaricp
|
:db #var asciinema.component.db/hikaricp
|
||||||
:ragtime #var duct.component.ragtime/ragtime
|
:ragtime #var duct.component.ragtime/ragtime
|
||||||
:file-store #var asciinema.component.s3-file-store/s3-file-store}
|
:file-store #var asciinema.component.s3-file-store/s3-file-store
|
||||||
|
:exp-set #var asciinema.component.redis-client/redis-client}
|
||||||
:endpoints
|
:endpoints
|
||||||
{:asciicasts #var asciinema.endpoint.asciicasts/asciicasts-endpoint}
|
{:asciicasts #var asciinema.endpoint.asciicasts/asciicasts-endpoint}
|
||||||
:dependencies
|
:dependencies
|
||||||
{:http [:app]
|
{:http [:app]
|
||||||
:app [:asciicasts]
|
:app [:asciicasts]
|
||||||
:ragtime [:db]
|
:ragtime [:db]
|
||||||
:asciicasts [:db :file-store]}
|
:asciicasts [:db :file-store :exp-set]}
|
||||||
:config
|
:config
|
||||||
{:app
|
{:app
|
||||||
{:middleware
|
{:middleware
|
||||||
@ -60,4 +61,7 @@
|
|||||||
{:cred {:access-key s3-access-key
|
{:cred {:access-key s3-access-key
|
||||||
:secret-key s3-secret-key}
|
:secret-key s3-secret-key}
|
||||||
:bucket s3-bucket
|
:bucket s3-bucket
|
||||||
:path-prefix "uploads/"}}}
|
:path-prefix "uploads/"}
|
||||||
|
:exp-set
|
||||||
|
{:host redis-host
|
||||||
|
:port redis-port}}}
|
||||||
|
6
src/asciinema/boundary/expiring_set.clj
Normal file
6
src/asciinema/boundary/expiring_set.clj
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(ns asciinema.boundary.expiring-set
|
||||||
|
(:refer-clojure :exclude [conj! contains?]))
|
||||||
|
|
||||||
|
(defprotocol ExpiringSet
|
||||||
|
(conj! [this value expires-at])
|
||||||
|
(contains? [this value]))
|
14
src/asciinema/component/mem_expiring_set.clj
Normal file
14
src/asciinema/component/mem_expiring_set.clj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
(ns asciinema.component.mem-expiring-set
|
||||||
|
(:require [asciinema.boundary.expiring-set :as exp-set]))
|
||||||
|
|
||||||
|
(defrecord MemExpiringSet [store]
|
||||||
|
exp-set/ExpiringSet
|
||||||
|
|
||||||
|
(conj! [this value _expires-at]
|
||||||
|
(swap! store conj value))
|
||||||
|
|
||||||
|
(contains? [this value]
|
||||||
|
(contains? @store value)))
|
||||||
|
|
||||||
|
(defn mem-expiring-set [{:keys [store]}]
|
||||||
|
(->MemExpiringSet (or store (atom #{}))))
|
28
src/asciinema/component/redis_client.clj
Normal file
28
src/asciinema/component/redis_client.clj
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
(ns asciinema.component.redis-client
|
||||||
|
(:require [asciinema.boundary.expiring-set :as exp-set]
|
||||||
|
[clj-time.core :as t]
|
||||||
|
[clj-time.local :as tl]
|
||||||
|
[com.stuartsierra.component :as component]
|
||||||
|
[taoensso.carmine :as car]))
|
||||||
|
|
||||||
|
(defrecord RedisClient [host port]
|
||||||
|
component/Lifecycle
|
||||||
|
(start [component]
|
||||||
|
(if (:listener component)
|
||||||
|
component
|
||||||
|
(let [conn {:pool {} :spec {:host host :port port}}]
|
||||||
|
(assoc component :conn conn))))
|
||||||
|
(stop [component]
|
||||||
|
(if (:conn component)
|
||||||
|
(dissoc component :conn)
|
||||||
|
component))
|
||||||
|
|
||||||
|
exp-set/ExpiringSet
|
||||||
|
(conj! [this value expires-at]
|
||||||
|
(let [seconds (t/in-seconds (t/interval (tl/local-now) expires-at))]
|
||||||
|
(car/wcar (:conn this) (car/setex value seconds true))))
|
||||||
|
(contains? [this value]
|
||||||
|
(car/as-bool (car/wcar (:conn this) (car/exists value)))))
|
||||||
|
|
||||||
|
(defn redis-client [{:keys [host port]}]
|
||||||
|
(->RedisClient host port))
|
@ -1,17 +1,19 @@
|
|||||||
(ns asciinema.endpoint.asciicasts
|
(ns asciinema.endpoint.asciicasts
|
||||||
(:require [asciinema.boundary
|
(:require [asciinema.boundary
|
||||||
[asciicast-database :as adb]
|
[asciicast-database :as adb]
|
||||||
|
[expiring-set :as exp-set]
|
||||||
[file-store :as fstore]
|
[file-store :as fstore]
|
||||||
[user-database :as udb]]
|
[user-database :as udb]]
|
||||||
[asciinema.model.asciicast :as asciicast]
|
[asciinema.model.asciicast :as asciicast]
|
||||||
[asciinema.util.io :refer [with-tmp-dir]]
|
[asciinema.util.io :refer [with-tmp-dir]]
|
||||||
|
[clj-time.core :as t]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[clojure.java.shell :as shell]
|
[clojure.java.shell :as shell]
|
||||||
|
[clojure.string :as str]
|
||||||
[compojure.api.sweet :refer :all]
|
[compojure.api.sweet :refer :all]
|
||||||
[environ.core :refer [env]]
|
[environ.core :refer [env]]
|
||||||
[ring.util.http-response :as response]
|
[ring.util.http-response :as response]
|
||||||
[schema.core :as s]
|
[schema.core :as s]))
|
||||||
[clojure.string :as str]))
|
|
||||||
|
|
||||||
(defn exception-handler [^Exception e data request]
|
(defn exception-handler [^Exception e data request]
|
||||||
(throw e))
|
(throw e))
|
||||||
@ -33,7 +35,9 @@
|
|||||||
|
|
||||||
(def Theme (apply s/enum asciicast/themes))
|
(def Theme (apply s/enum asciicast/themes))
|
||||||
|
|
||||||
(defn asciicasts-endpoint [{:keys [db file-store]}]
|
(def png-ttl-days 7)
|
||||||
|
|
||||||
|
(defn asciicasts-endpoint [{:keys [db file-store exp-set]}]
|
||||||
(api
|
(api
|
||||||
{:exceptions {:handlers {:compojure.api.exception/default exception-handler}}}
|
{:exceptions {:handlers {:compojure.api.exception/default exception-handler}}}
|
||||||
(context
|
(context
|
||||||
@ -58,15 +62,18 @@
|
|||||||
time (assoc :snapshot-at time)
|
time (assoc :snapshot-at time)
|
||||||
theme (assoc :theme theme)
|
theme (assoc :theme theme)
|
||||||
scale (assoc :scale (Integer/parseInt scale)))
|
scale (assoc :scale (Integer/parseInt scale)))
|
||||||
json-store-path (asciicast/json-store-path asciicast)
|
|
||||||
png-store-path (asciicast/png-store-path asciicast png-params)]
|
png-store-path (asciicast/png-store-path asciicast png-params)]
|
||||||
(with-tmp-dir [dir "asciinema-png-"]
|
(when-not (exp-set/contains? exp-set png-store-path)
|
||||||
(let [json-local-path (str dir "/asciicast.json")
|
(with-tmp-dir [dir "asciinema-png-"]
|
||||||
png-local-path (str dir "/asciicast.png")]
|
(let [json-store-path (asciicast/json-store-path asciicast)
|
||||||
(with-open [in (fstore/input-stream file-store json-store-path)]
|
json-local-path (str dir "/asciicast.json")
|
||||||
(let [out (io/file json-local-path)]
|
png-local-path (str dir "/asciicast.png")
|
||||||
(io/copy in out)))
|
expires (-> png-ttl-days t/days t/from-now)]
|
||||||
(a2png json-local-path png-local-path png-params)
|
(with-open [in (fstore/input-stream file-store json-store-path)]
|
||||||
(fstore/put-file file-store (io/file png-local-path) png-store-path)))
|
(let [out (io/file json-local-path)]
|
||||||
|
(io/copy in out)))
|
||||||
|
(a2png json-local-path png-local-path png-params)
|
||||||
|
(fstore/put-file file-store (io/file png-local-path) png-store-path)
|
||||||
|
(exp-set/conj! exp-set png-store-path expires))))
|
||||||
(fstore/serve-file file-store png-store-path {}))
|
(fstore/serve-file file-store png-store-path {}))
|
||||||
(response/not-found))))))
|
(response/not-found))))))
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
'bugsnag-key (:bugsnag-key env)
|
'bugsnag-key (:bugsnag-key env)
|
||||||
's3-bucket (:s3-bucket env)
|
's3-bucket (:s3-bucket env)
|
||||||
's3-access-key (:s3-access-key env)
|
's3-access-key (:s3-access-key env)
|
||||||
's3-secret-key (:s3-secret-key env)}
|
's3-secret-key (:s3-secret-key env)
|
||||||
|
'redis-host (:redis-host env "localhost")
|
||||||
|
'redis-port (Integer/parseInt (:redis-port env "6379"))}
|
||||||
system (->> (load-system [(io/resource "asciinema/system.edn")] bindings)
|
system (->> (load-system [(io/resource "asciinema/system.edn")] bindings)
|
||||||
(component/start))]
|
(component/start))]
|
||||||
(add-shutdown-hook ::stop-system #(component/stop system))
|
(add-shutdown-hook ::stop-system #(component/stop system))
|
||||||
|
Loading…
Reference in New Issue
Block a user