diff --git a/Dockerfile b/Dockerfile
index cc56145..a7a8771 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -108,15 +108,6 @@ RUN cd a2png && npm install
COPY a2png /app/a2png
RUN cd a2png && lein cljsbuild once main && lein cljsbuild once page
-# build uberjar
-
-COPY project.clj /app/
-RUN lein deps
-
-COPY src /app/src
-COPY resources /app/resources
-RUN lein uberjar
-
# service URLs
ENV DATABASE_URL "postgresql://postgres@postgres/postgres"
@@ -195,16 +186,11 @@ COPY docker/supervisor/asciinema.conf /etc/supervisor/conf.d/asciinema.conf
# add start script for Clojure app
ENV A2PNG_BIN_PATH "/app/a2png/a2png.sh"
-COPY docker/start.sh /app/start.sh
-RUN chmod a+x /app/start.sh
VOLUME ["/app/log", "/app/uploads", "/cache"]
CMD ["/usr/bin/supervisord"]
-# bundle exec rake db:setup
-# bundle exec sidekiq
EXPOSE 80
EXPOSE 3000
EXPOSE 4000
-EXPOSE 5000
diff --git a/dev/.env.development b/dev/.env.development
index 00f147e..99ee6c9 100644
--- a/dev/.env.development
+++ b/dev/.env.development
@@ -2,5 +2,4 @@ RAILS_ENV=development
MIX_ENV=dev
BASE_URL=http://localhost:3000
SECRET_KEY_BASE=19c70247f4034dd5ce4f3d6bd3b2b592624b63439d518367de9add564fdee9e6b8513f6cec24c2a933a84ea639136786813bb70d3dc4e84a365205a52e5bf1fa
-LEIN_ROOT=yes
BUNDLE_PATH=/bundle
\ No newline at end of file
diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml
index b88b062..9f0cecc 100644
--- a/dev/docker-compose.yml
+++ b/dev/docker-compose.yml
@@ -32,8 +32,6 @@ services:
ports:
- 3000:3000
- 4000:4000
- - 5000:5000
- - 44444:44444
volumes:
- ../uploads:/app/uploads:cached
- ../deps:/app/deps:cached
diff --git a/dev/resources/dev.edn b/dev/resources/dev.edn
deleted file mode 100644
index 6a673e9..0000000
--- a/dev/resources/dev.edn
+++ /dev/null
@@ -1,6 +0,0 @@
-{:components
- {:mem-expiring-set #var asciinema.component.mem-expiring-set/mem-expiring-set}
- :config
- {:a2png {:bin-path "a2png/a2png.sh"}}
- :dependencies
- {:asciicasts {:exp-set :mem-expiring-set}}}
diff --git a/dev/src/dev.clj b/dev/src/dev.clj
deleted file mode 100644
index b2109d1..0000000
--- a/dev/src/dev.clj
+++ /dev/null
@@ -1,33 +0,0 @@
-(ns dev
- (:refer-clojure :exclude [test])
- (:require [clojure.repl :refer :all]
- [clojure.pprint :refer [pprint]]
- [clojure.tools.namespace.repl :refer [refresh]]
- [clojure.java.io :as io]
- [com.stuartsierra.component :as component]
- [duct.generate :as gen]
- [duct.util.repl :refer [setup test cljs-repl migrate rollback]]
- [duct.util.system :refer [load-system]]
- [environ.core :refer [env]]
- [reloaded.repl :refer [system init start stop go reset]]
- [asciinema.boundary.file-store :as file-store]
- [asciinema.boundary.asciicast-database :as asciicast-database]
- [asciinema.component.local-file-store :refer [->LocalFileStore]]
- [asciinema.component.s3-file-store :refer [->S3FileStore]]))
-
-(def default-db-uri "jdbc:postgresql://localhost/asciinema_development?user=asciinema")
-
-(defn new-system []
- (let [bindings {'http-port (Integer/parseInt (:port env "4000"))
- 'db-uri (:database-url env default-db-uri)
- 's3-bucket (:s3-bucket env)
- 's3-access-key (:s3-access-key env)
- 's3-secret-key (:s3-secret-key env)}]
- (load-system (keep io/resource ["asciinema/system.edn" "dev.edn" "local.edn"]) bindings)))
-
-(when (io/resource "local.clj")
- (load "local"))
-
-(gen/set-ns-prefix 'asciinema)
-
-(reloaded.repl/set-init! new-system)
diff --git a/dev/src/user.clj b/dev/src/user.clj
deleted file mode 100644
index 9cf3c0c..0000000
--- a/dev/src/user.clj
+++ /dev/null
@@ -1,8 +0,0 @@
-(ns user)
-
-(defn dev
- "Load and switch to the 'dev' namespace."
- []
- (require 'dev)
- (in-ns 'dev)
- :loaded)
diff --git a/docker-compose.yml b/docker-compose.yml
index 69b106e..d9b45ca 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -57,7 +57,6 @@ services:
env_file: .env.production
ports:
- "3000:80"
- - "5000:5000"
volumes:
- ./uploads:/app/uploads
- ./log:/app/log
diff --git a/docker/nginx/asciinema.conf b/docker/nginx/asciinema.conf
index 49ac393..36257c1 100644
--- a/docker/nginx/asciinema.conf
+++ b/docker/nginx/asciinema.conf
@@ -6,10 +6,6 @@ upstream phoenix-server {
server 127.0.0.1:4000 fail_timeout=0;
}
-upstream clj-server {
- server 127.0.0.1:5000 fail_timeout=0;
-}
-
proxy_cache_path /cache levels=1:2 keys_zone=png_cache:10m max_size=10g
inactive=14d use_temp_path=off;
@@ -77,13 +73,4 @@ server {
proxy_pass http://phoenix-server;
proxy_redirect off;
}
-
- location @clj {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header Host $http_host;
- proxy_pass http://clj-server;
- proxy_redirect off;
- }
}
diff --git a/docker/start.sh b/docker/start.sh
deleted file mode 100644
index 6285509..0000000
--- a/docker/start.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-
-export S3_ACCESS_KEY=${AWS_ACCESS_KEY_ID}
-export S3_SECRET_KEY=${AWS_SECRET_ACCESS_KEY}
-
-exec java -server -jar /app/target/uberjar/asciinema-0.1.0-SNAPSHOT-standalone.jar
diff --git a/docker/supervisor/asciinema.conf b/docker/supervisor/asciinema.conf
index 86868bf..6cc15e8 100644
--- a/docker/supervisor/asciinema.conf
+++ b/docker/supervisor/asciinema.conf
@@ -23,13 +23,4 @@ environment=PORT=4000
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
-stderr_logfile_maxbytes=0
-
-[program:clj]
-command=/app/start.sh
-directory=/app
-environment=PORT=5000
-stdout_logfile=/dev/stdout
-stdout_logfile_maxbytes=0
-stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
\ No newline at end of file
diff --git a/project.clj b/project.clj
deleted file mode 100644
index 12d4888..0000000
--- a/project.clj
+++ /dev/null
@@ -1,48 +0,0 @@
-(defproject asciinema "0.1.0-SNAPSHOT"
- :description "FIXME: write description"
- :url "http://example.com/FIXME"
- :min-lein-version "2.0.0"
- :dependencies [[org.clojure/clojure "1.8.0"]
- [com.stuartsierra/component "0.3.1"]
- [clj-time "0.13.0"]
- [duct "0.8.2"]
- [yada "1.2.0"]
- [aleph "0.4.1"]
- [bidi "2.0.16"]
- [prismatic/schema "1.1.3"]
- [environ "1.1.0"]
- [ring "1.5.0"]
- [clj-bugsnag "0.2.9"]
- [clj-aws-s3 "0.3.10" :exclusions [joda-time]]
- [cheshire "5.7.0"]
- [pandect "0.6.1"]
- [com.taoensso/timbre "4.8.0"]
- [com.taoensso/carmine "2.15.1"]
- [org.slf4j/slf4j-nop "1.7.21"]
- [duct/hikaricp-component "0.1.0"]
- [org.postgresql/postgresql "9.4.1211"]
- [duct/ragtime-component "0.1.4"]
- [me.raynes/conch "0.8.0"]]
- :plugins [[lein-environ "1.0.3"]]
- :main ^:skip-aot asciinema.main
- :target-path "target/%s/"
- :aliases {"setup" ["run" "-m" "duct.util.repl/setup"]}
- :profiles
- {:dev [:project/dev :profiles/dev]
- :test [:project/test :profiles/test]
- :uberjar {:aot :all}
- :repl {:repl-options {:host "0.0.0.0"
- :port 44444}}
- :profiles/dev {}
- :profiles/test {}
- :project/dev {:dependencies [[duct/generate "0.8.2"]
- [reloaded.repl "0.2.3"]
- [org.clojure/tools.namespace "0.2.11"]
- [org.clojure/tools.nrepl "0.2.12"]
- [eftest "0.1.1"]
- [com.gearswithingears/shrubbery "0.4.1"]
- [kerodon "0.8.0"]]
- :source-paths ["dev/src"]
- :resource-paths ["dev/resources"]
- :repl-options {:init-ns user}}
- :project/test {}})
diff --git a/resources/asciinema/endpoint/example/example.html b/resources/asciinema/endpoint/example/example.html
deleted file mode 100644
index f808576..0000000
--- a/resources/asciinema/endpoint/example/example.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
- Example Endpoint
-
-
-
-
- This is an example endpoint
-
-
diff --git a/resources/asciinema/errors/404.html b/resources/asciinema/errors/404.html
deleted file mode 100644
index b9cab04..0000000
--- a/resources/asciinema/errors/404.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- Server Error
-
-
-
-
- Resource Not Found
- The requested page does not exist.
-
-
diff --git a/resources/asciinema/errors/500.html b/resources/asciinema/errors/500.html
deleted file mode 100644
index 985ff84..0000000
--- a/resources/asciinema/errors/500.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- Server Error
-
-
-
-
- Internal Server Error
- Sorry, something went wrong.
-
-
diff --git a/resources/asciinema/public/css/site.css b/resources/asciinema/public/css/site.css
deleted file mode 100644
index 37086ca..0000000
--- a/resources/asciinema/public/css/site.css
+++ /dev/null
@@ -1,103 +0,0 @@
-.error-page body {
- background: #eee;
-}
-
-.error-page h1 {
- margin: 15% 0 0 0;
- text-align: center;
- font-size: 42px;
- color: #900;
-}
-
-.error-page h2 {
- text-align: center;
- font-size: 32px;
- font-weight: normal;
- color: #333;
-}
-
-.welcome body {
- background: #eee;
- color: #333;
- font-family: Helvetica, Arial, sans-serif;
- max-width: 700px;
- padding: 15px;
- margin: auto;
-}
-
-.welcome p {
- line-height: 1.4em;
-}
-
-.welcome code {
- font-family: Menlo, DejaVu Sans Mono, Lucida Console, monospace;
- font-size: 12px;
- background: #ddd;
- color: #111;
-}
-
-.welcome h1 {
- text-align: center;
- font-size: 36px;
- font-weight: lighter;
- margin: 40px 0 30px 0;
-}
-
-.welcome h1 .outer {
- border: solid 4px #555;
- padding: 3px;
- display: inline-block;
-}
-
-.welcome h1 .inner {
- border: solid 2px #555;
- padding: 0 3px;
- display: inline-block;
- font-weight: normal;
- color: #444;
-}
-
-.welcome .project-name {
- font-weight: bold;
-}
-
-.welcome .profiles {
- margin-top: 30px;
-}
-
-.welcome .profiles code {
- font-size: 11px;
-}
-
-.welcome .profiles h2 {
- font-weight: normal;
- font-size: 23px;
- margin-bottom: 0;
- color: #333;
-}
-
-.welcome .profiles dl {
- margin: 0 10px;
-}
-
-.welcome .profiles dt {
- font-weight: normal;
- font-size: 19px;
- margin: 18px 0 5px 0;
-}
-
-.welcome .profiles dd {
- font-size: 14px;
- margin: 8px 0 8px 0;
-}
-
-.example body {
- background: #eee;
-}
-
-.example h1 {
- margin: 15% 0 0 0;
- text-align: center;
- font-size: 36px;
- font-weight: normal;
-}
diff --git a/resources/asciinema/public/favicon.ico b/resources/asciinema/public/favicon.ico
deleted file mode 100644
index 0e50cb2..0000000
Binary files a/resources/asciinema/public/favicon.ico and /dev/null differ
diff --git a/resources/asciinema/public/index.html b/resources/asciinema/public/index.html
deleted file mode 100644
index 36d2e30..0000000
--- a/resources/asciinema/public/index.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- Welcome to Duct
-
-
-
-
- Welcome to Duct
-
-
Congratulations! Your project asciinema is
- ready and running.
-
This is a static welcome page located at resources/asciinema/public/index.html
- in the project directory. Remove or replace it when you start developing.
- If you remove the index page entirely, be sure to change the
- :route-aliases
map in resources/asciinema/system.edn
.
-
-
-
Template profiles used:
-
- +example
- Adds an example endpoint at /example .
- +postgres
- Adds a PostgreSQL dependency and database component. The database used for
- development defaults to postgres
on localhost
.
- +ragtime
- Adds Ragtime migrations. Use (migrate)
and (rollback)
- in the REPL. Migrations are stored in resources/asciinema/migrations
.
-
- +site
- Adds middleware and configuration suited for a user-facing website.
-
-
-
-
-
diff --git a/resources/asciinema/public/robots.txt b/resources/asciinema/public/robots.txt
deleted file mode 100644
index eb05362..0000000
--- a/resources/asciinema/public/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow:
diff --git a/resources/asciinema/system.edn b/resources/asciinema/system.edn
deleted file mode 100644
index 312abc0..0000000
--- a/resources/asciinema/system.edn
+++ /dev/null
@@ -1,37 +0,0 @@
-{:components
- {:http #var asciinema.component.yada-listener/yada-listener
- :db #var asciinema.component.db/hikaricp
- :ragtime #var duct.component.ragtime/ragtime
- :auto-file-store #var asciinema.component.auto-file-store/auto-file-store
- :redis-client #var asciinema.component.redis-client/redis-client
- :a2png #var asciinema.component.a2png/a2png
- :fixed-thread-executor #var asciinema.component.fixed-thread-executor/fixed-thread-executor}
- :endpoints
- {:asciicasts #var asciinema.endpoint.asciicasts/asciicasts-endpoint}
- :dependencies
- {:http {:app :asciicasts}
- :ragtime [:db]
- :asciicasts {:db :db
- :file-store :auto-file-store
- :exp-set :redis-client
- :executor :fixed-thread-executor
- :png-gen :a2png}}
- :config
- {:http
- {:port http-port}
- :db
- {:uri db-uri}
- :ragtime
- {:resource-path "asciinema/migrations"}
- :auto-file-store
- {:path "uploads/"
- :s3-bucket s3-bucket
- :s3-cred {:access-key s3-access-key
- :secret-key s3-secret-key}}
- :redis-client
- {:uri redis-url}
- :a2png
- {:bin-path a2png-bin-path}
- :fixed-thread-executor
- {:threads 2
- :queue-length 16}}}
diff --git a/src/asciinema/boundary/asciicast_database.clj b/src/asciinema/boundary/asciicast_database.clj
deleted file mode 100644
index f06e5b5..0000000
--- a/src/asciinema/boundary/asciicast_database.clj
+++ /dev/null
@@ -1,5 +0,0 @@
-(ns asciinema.boundary.asciicast-database)
-
-(defprotocol AsciicastDatabase
- (get-asciicast-by-id [this id])
- (get-asciicast-by-token [this token]))
diff --git a/src/asciinema/boundary/executor.clj b/src/asciinema/boundary/executor.clj
deleted file mode 100644
index 51360a1..0000000
--- a/src/asciinema/boundary/executor.clj
+++ /dev/null
@@ -1,4 +0,0 @@
-(ns asciinema.boundary.executor)
-
-(defprotocol Executor
- (execute [this f]))
diff --git a/src/asciinema/boundary/expiring_set.clj b/src/asciinema/boundary/expiring_set.clj
deleted file mode 100644
index f17fdcd..0000000
--- a/src/asciinema/boundary/expiring_set.clj
+++ /dev/null
@@ -1,6 +0,0 @@
-(ns asciinema.boundary.expiring-set
- (:refer-clojure :exclude [conj! contains?]))
-
-(defprotocol ExpiringSet
- (conj! [this value expires-at])
- (contains? [this value]))
diff --git a/src/asciinema/boundary/file_store.clj b/src/asciinema/boundary/file_store.clj
deleted file mode 100644
index da2d65d..0000000
--- a/src/asciinema/boundary/file_store.clj
+++ /dev/null
@@ -1,8 +0,0 @@
-(ns asciinema.boundary.file-store)
-
-(defprotocol FileStore
- (put-file [this file path] [this file path size])
- (input-stream [this path])
- (move-file [this old-path new-path])
- (delete-file [this path])
- (serve-file [this ctx path opts]))
diff --git a/src/asciinema/boundary/png_generator.clj b/src/asciinema/boundary/png_generator.clj
deleted file mode 100644
index c975c29..0000000
--- a/src/asciinema/boundary/png_generator.clj
+++ /dev/null
@@ -1,4 +0,0 @@
-(ns asciinema.boundary.png-generator)
-
-(defprotocol PngGenerator
- (generate [this json-is png-params]))
diff --git a/src/asciinema/boundary/user_database.clj b/src/asciinema/boundary/user_database.clj
deleted file mode 100644
index abae4aa..0000000
--- a/src/asciinema/boundary/user_database.clj
+++ /dev/null
@@ -1,4 +0,0 @@
-(ns asciinema.boundary.user-database)
-
-(defprotocol UserDatabase
- (get-user-by-id [this id]))
diff --git a/src/asciinema/component/a2png.clj b/src/asciinema/component/a2png.clj
deleted file mode 100644
index 65acaf2..0000000
--- a/src/asciinema/component/a2png.clj
+++ /dev/null
@@ -1,26 +0,0 @@
-(ns asciinema.component.a2png
- (:require [asciinema.boundary.png-generator :as png-generator]
- [asciinema.util.io :refer [cleanup-input-stream create-tmp-dir]]
- [clojure.java.io :as io]
- [clojure.java
- [io :as io]
- [shell :as shell]]
- [me.raynes.conch :as conch]))
-
-(defn- exec-a2png [bin-path in-url out-path {:keys [snapshot-at theme scale]}]
- (conch/let-programs [a2png bin-path]
- (a2png in-url out-path (str snapshot-at) theme (str scale) {:timeout 30000})))
-
-(defrecord A2png [bin-path]
- png-generator/PngGenerator
- (generate [this json-is png-params]
- (let [dir (create-tmp-dir "a2png-")
- cleanup #(shell/sh "rm" "-rf" (.getPath dir))
- json-local-path (str dir "/asciicast.json")
- png-local-path (str dir "/asciicast.png")]
- (io/copy json-is (io/file json-local-path))
- (exec-a2png bin-path json-local-path png-local-path png-params)
- (cleanup-input-stream (io/input-stream png-local-path) cleanup))))
-
-(defn a2png [{:keys [bin-path]}]
- (->A2png bin-path))
diff --git a/src/asciinema/component/auto_file_store.clj b/src/asciinema/component/auto_file_store.clj
deleted file mode 100644
index e674537..0000000
--- a/src/asciinema/component/auto_file_store.clj
+++ /dev/null
@@ -1,8 +0,0 @@
-(ns asciinema.component.auto-file-store
- (:require [asciinema.component.local-file-store :refer [local-file-store]]
- [asciinema.component.s3-file-store :refer [s3-file-store]]))
-
-(defn auto-file-store [config]
- (if (:s3-bucket config)
- (s3-file-store config)
- (local-file-store config)))
diff --git a/src/asciinema/component/db.clj b/src/asciinema/component/db.clj
deleted file mode 100644
index 4008023..0000000
--- a/src/asciinema/component/db.clj
+++ /dev/null
@@ -1,62 +0,0 @@
-(ns asciinema.component.db
- (:require [asciinema.boundary.asciicast-database :refer :all]
- [asciinema.boundary.user-database :refer :all]
- [clojure.java.jdbc :as jdbc]
- [clj-time.coerce :as timec]
- [duct.component.hikaricp :as hikaricp]
- [clojure.string :as str]))
-
-(extend-protocol jdbc/ISQLValue
- org.joda.time.DateTime
- (sql-value [val]
- (timec/to-sql-time val)))
-
-(extend-protocol jdbc/IResultSetReadColumn
- java.sql.Timestamp
- (result-set-read-column [x _ _]
- (timec/from-sql-time x)))
-
-;; AsciicastDatabase
-
-(def q-get-asciicast-by-id "SELECT * FROM asciicasts WHERE id=?")
-(def q-get-asciicast-by-secret-token "SELECT * FROM asciicasts WHERE secret_token=?")
-(def q-get-public-asciicast-by-id "SELECT * FROM asciicasts WHERE id=? AND private=FALSE")
-
-(extend-protocol AsciicastDatabase
- duct.component.hikaricp.HikariCP
-
- (get-asciicast-by-id [{db :spec} id]
- (first (jdbc/query db [q-get-asciicast-by-id id])))
-
- (get-asciicast-by-token [{db :spec} token]
- (when-let [query (cond
- (re-matches #"\d+" token)
- [q-get-public-asciicast-by-id (Long/parseLong token)]
- (= (count token) 25)
- [q-get-asciicast-by-secret-token token])]
- (first (jdbc/query db query)))))
-
-;; UserDatabase
-
-(def q-get-user-by-id "SELECT * FROM users WHERE id=?")
-
-(extend-protocol UserDatabase
- duct.component.hikaricp.HikariCP
-
- (get-user-by-id [{db :spec} id]
- (first (jdbc/query db [q-get-user-by-id id]))))
-
-;; constructor
-
-(defn- fix-uri [uri]
- (when uri
- (let [[_ user _ pass] (re-find #"://([^:@]+)(:([^@]+))?@" uri)]
- (cond-> uri
- (not (str/starts-with? uri "jdbc:")) (->> (str "jdbc:"))
- (str/includes? uri "@") (str/replace #"://[^@]+@" "://")
- user (str "?user=" user)
- pass (str "&password=" pass)))))
-
-(defn hikaricp [opts]
- (let [opts (update opts :uri fix-uri)]
- (hikaricp/hikaricp opts)))
diff --git a/src/asciinema/component/fixed_thread_executor.clj b/src/asciinema/component/fixed_thread_executor.clj
deleted file mode 100644
index 7981882..0000000
--- a/src/asciinema/component/fixed_thread_executor.clj
+++ /dev/null
@@ -1,39 +0,0 @@
-(ns asciinema.component.fixed-thread-executor
- (:require [aleph.flow :as flow]
- [asciinema.boundary.executor :as executor]
- [com.stuartsierra.component :as component]
- [manifold.deferred :as d])
- (:import [java.util.concurrent
- ExecutorService
- RejectedExecutionException
- TimeUnit]))
-
-(defrecord FixedThreadExecutor [threads queue-length]
- executor/Executor
- (execute [{:keys [^ExecutorService executor]} f]
- (try
- (let [result (d/deferred)
- f (fn []
- (try
- (d/success! result (f))
- (catch Exception e
- (d/error! result e))))]
- (.execute executor f)
- result)
- (catch RejectedExecutionException _
- nil)))
-
- component/Lifecycle
- (start [{:keys [threads queue-length] :as component}]
- (let [executor (flow/fixed-thread-executor threads {:onto? false
- :initial-thread-count threads
- :queue-length queue-length})]
- (assoc component :executor executor)))
- (stop [{:keys [^ExecutorService executor] :as component}]
- (.shutdown executor)
- (when-not (.awaitTermination executor 1000 TimeUnit/MILLISECONDS)
- (.shutdownNow executor))
- (assoc component :executor nil)))
-
-(defn fixed-thread-executor [{:keys [threads queue-length]}]
- (->FixedThreadExecutor threads queue-length))
diff --git a/src/asciinema/component/local_file_store.clj b/src/asciinema/component/local_file_store.clj
deleted file mode 100644
index bf82363..0000000
--- a/src/asciinema/component/local_file_store.clj
+++ /dev/null
@@ -1,38 +0,0 @@
-(ns asciinema.component.local-file-store
- (:require [asciinema.boundary.file-store :as file-store]
- [clojure.java.io :as io]
- [ring.util.http-response :as response]))
-
-(defrecord LocalFileStore [base-path]
- file-store/FileStore
-
- (put-file [this file path]
- (let [path (str base-path path)]
- (io/make-parents path)
- (io/copy file (io/file path))))
-
- (put-file [this file path size]
- (file-store/put-file this file path))
-
- (input-stream [this path]
- (let [path (str base-path path)]
- (io/input-stream path)))
-
- (move-file [this old-path new-path]
- (let [old-path (str base-path old-path)
- new-path (str base-path new-path)]
- (.renameTo (io/file old-path) (io/file new-path))))
-
- (delete-file [this path]
- (let [path (str base-path path)]
- (io/delete-file path)))
-
- (serve-file [this ctx path {:keys [filename]}]
- (let [path (str base-path path)
- response (assoc (:response ctx) :body (io/file path))]
- (if filename
- (update response :headers assoc "content-disposition" (str "attachment; filename=" filename))
- response))))
-
-(defn local-file-store [{:keys [path]}]
- (->LocalFileStore path))
diff --git a/src/asciinema/component/mem_expiring_set.clj b/src/asciinema/component/mem_expiring_set.clj
deleted file mode 100644
index 367d549..0000000
--- a/src/asciinema/component/mem_expiring_set.clj
+++ /dev/null
@@ -1,14 +0,0 @@
-(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 #{}))))
diff --git a/src/asciinema/component/redis_client.clj b/src/asciinema/component/redis_client.clj
deleted file mode 100644
index da725a4..0000000
--- a/src/asciinema/component/redis_client.clj
+++ /dev/null
@@ -1,28 +0,0 @@
-(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 [uri]
- component/Lifecycle
- (start [component]
- (if (:listener component)
- component
- (let [conn {:pool {} :spec {:uri uri}}]
- (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 [uri]}]
- (->RedisClient uri))
diff --git a/src/asciinema/component/s3_file_store.clj b/src/asciinema/component/s3_file_store.clj
deleted file mode 100644
index c30e573..0000000
--- a/src/asciinema/component/s3_file_store.clj
+++ /dev/null
@@ -1,66 +0,0 @@
-(ns asciinema.component.s3-file-store
- (:require [asciinema.boundary.file-store :as file-store]
- [aws.sdk.s3 :as s3]
- [clj-time
- [coerce :as timec]
- [core :as time]]
- [ring.util.http-response :as response]
- [ring.util.mime-type :as mime-type])
- (:import com.amazonaws.auth.BasicAWSCredentials
- com.amazonaws.services.s3.AmazonS3Client
- [com.amazonaws.services.s3.model GeneratePresignedUrlRequest ResponseHeaderOverrides]))
-
-(defn- s3-client* [cred]
- (let [credentials (BasicAWSCredentials. (:access-key cred) (:secret-key cred))]
- (AmazonS3Client. credentials)))
-
-(def ^:private s3-client (memoize s3-client*))
-
-(defn- generate-presigned-url [cred bucket path {:keys [expires filename]
- :or {expires (-> 1 time/days time/from-now)}}]
- (let [client (s3-client cred)
- request (GeneratePresignedUrlRequest. bucket path)]
- (.setExpiration request (timec/to-date expires))
- (when filename
- (let [header-overrides (doto (ResponseHeaderOverrides.)
- (.setContentDisposition (str "attachment; filename=" filename)))]
- (.setResponseHeaders request header-overrides)))
- (.toString (.generatePresignedUrl client request))))
-
-(defrecord S3FileStore [cred bucket path-prefix]
- file-store/FileStore
-
- (put-file [this file path]
- (file-store/put-file this file path nil))
-
- (put-file [this file path size]
- (let [path (str path-prefix path)
- content-type (mime-type/ext-mime-type path)]
- (s3/put-object cred bucket path file {:content-length size
- :content-type content-type})))
-
- (input-stream [this path]
- (let [path (str path-prefix path)]
- (:content (s3/get-object cred bucket path))))
-
- (move-file [this old-path new-path]
- (let [old-path (str path-prefix old-path)
- new-path (str path-prefix new-path)]
- (s3/copy-object cred bucket old-path new-path)
- (s3/delete-object cred bucket old-path)))
-
- (delete-file [this path]
- (let [path (str path-prefix path)]
- (s3/delete-object cred bucket path)))
-
- (serve-file [this ctx path opts]
- (let [path (str path-prefix path)
- url (generate-presigned-url cred bucket path opts)]
- (-> (:response ctx)
- (assoc :status 302)
- (update :headers assoc "location" url)))))
-
-(defn s3-file-store
- [{:keys [s3-cred s3-bucket path]}]
- {:pre [(some? s3-cred) (some? s3-bucket) (some? path)]}
- (->S3FileStore s3-cred s3-bucket path))
diff --git a/src/asciinema/component/yada_listener.clj b/src/asciinema/component/yada_listener.clj
deleted file mode 100644
index 2125a3b..0000000
--- a/src/asciinema/component/yada_listener.clj
+++ /dev/null
@@ -1,22 +0,0 @@
-(ns asciinema.component.yada-listener
- (:require [bidi.vhosts :refer [vhosts-model]]
- [com.stuartsierra.component :as component]
- [yada.yada :as yada]))
-
-(defrecord YadaListener [port server app]
- component/Lifecycle
- (start [component]
- (if server
- component
- (let [handler (vhosts-model [:* (:routes app)]) ; wrap in * vhost to make path-for work
- server (yada/listener handler {:port port})]
- (assoc component :server server))))
- (stop [component]
- (if server
- (do
- ((:close server))
- (assoc component :server nil))
- component)))
-
-(defn yada-listener [{:keys [port app]}]
- (map->YadaListener {:port port :app app}))
diff --git a/src/asciinema/endpoint/asciicasts.clj b/src/asciinema/endpoint/asciicasts.clj
deleted file mode 100644
index 572643e..0000000
--- a/src/asciinema/endpoint/asciicasts.clj
+++ /dev/null
@@ -1,90 +0,0 @@
-(ns asciinema.endpoint.asciicasts
- (:require [asciinema.boundary
- [asciicast-database :as adb]
- [executor :as executor]
- [expiring-set :as exp-set]
- [file-store :as fstore]
- [png-generator :as png]
- [user-database :as udb]]
- [asciinema.model.asciicast :as asciicast]
- [asciinema.yada :refer [not-found-model resource]]
- [clj-time.core :as t]
- [schema.core :as s]
- [yada.yada :as yada]))
-
-(def Theme (apply s/enum asciicast/themes))
-
-(defn- service-unavailable-response [ctx]
- (-> (:response ctx)
- (assoc :status 503)
- (update :headers assoc "retry-after" "5")))
-
-(defn- async-response [ctx executor f]
- (or (executor/execute executor f)
- (service-unavailable-response ctx)))
-
-(defn asciicast-file-resource [db file-store]
- (resource
- {:produces "application/json"
- :parameters {:path {:token String}
- :query {(s/optional-key :dl) s/Bool}}
- :properties (fn [ctx]
- (if-let [asciicast (adb/get-asciicast-by-token db (-> ctx :parameters :path :token))]
- {::asciicast asciicast}
- {:exists? false}))
- :response (fn [ctx]
- (let [asciicast (-> ctx :properties ::asciicast)
- dl (-> ctx :parameters :query :dl)
- path (asciicast/json-store-path asciicast)
- filename (str "asciicast-" (:id asciicast) ".json")]
- (fstore/serve-file file-store ctx path (when dl {:filename filename}))))}))
-
-(def png-ttl-days 7)
-
-(defn asciicast-image-resource [db file-store exp-set executor png-gen]
- (resource
- {:produces
- "image/png"
-
- :parameters
- {:path {:token String}
- :query {(s/optional-key :time) s/Num
- (s/optional-key :theme) Theme
- (s/optional-key :scale) (s/enum "1" "2")}}
-
- :properties
- (fn [ctx]
- (if-let [asciicast (adb/get-asciicast-by-token db (-> ctx :parameters :path :token))]
- (let [user (udb/get-user-by-id db (:user_id asciicast))
- {:keys [time theme scale]} (-> ctx :parameters :query)
- png-params (cond-> (asciicast/png-params asciicast user)
- time (assoc :snapshot-at time)
- theme (assoc :theme theme)
- scale (assoc :scale (Integer/parseInt scale)))]
- {:version (asciicast/png-version asciicast png-params)
- ::asciicast asciicast
- ::png-params png-params})
- {:exists? false}))
-
- :response
- (fn [ctx]
- (let [asciicast (-> ctx :properties ::asciicast)
- png-params (-> ctx :properties ::png-params)
- png-store-path (asciicast/png-store-path asciicast png-params)
- expires (-> png-ttl-days t/days t/from-now)]
- (if (exp-set/contains? exp-set png-store-path)
- (fstore/serve-file file-store ctx png-store-path {})
- (async-response ctx
- executor
- (fn []
- (let [json-store-path (asciicast/json-store-path asciicast)]
- (with-open [json-is (fstore/input-stream file-store json-store-path)
- png-is (png/generate png-gen json-is png-params)]
- (fstore/put-file file-store png-is png-store-path)))
- (exp-set/conj! exp-set png-store-path expires)
- (fstore/serve-file file-store ctx png-store-path {}))))))}))
-
-(defn asciicasts-endpoint [{:keys [db file-store exp-set executor png-gen]}]
- ["" [["/a/" [[[:token ".json"] (asciicast-file-resource db file-store)]
- [[:token ".png"] (asciicast-image-resource db file-store exp-set executor png-gen)]]]
- [true (yada/resource not-found-model)]]])
diff --git a/src/asciinema/main.clj b/src/asciinema/main.clj
deleted file mode 100644
index a283b17..0000000
--- a/src/asciinema/main.clj
+++ /dev/null
@@ -1,41 +0,0 @@
-(ns asciinema.main
- (:gen-class)
- (:require [asciinema.yada :as y]
- [clj-bugsnag.core :as bugsnag]
- [com.stuartsierra.component :as component]
- [duct.util.runtime :refer [add-shutdown-hook]]
- [duct.util.system :refer [load-system]]
- [environ.core :refer [env]]
- [clojure.java.io :as io]))
-
-(defn- request-context [req]
- (str (-> req (get :request-method :unknown) name .toUpperCase)
- " "
- (:uri req)))
-
-(defn- create-exception-notifier []
- (when-let [key (:bugsnag-key env)]
- (let [environment (:env-name env "production")
- version (:git-sha env)]
- (fn [ex req]
- (bugsnag/notify ex {:api-key key
- :environment environment
- :project-ns "asciinema"
- :version version
- :context (request-context req)
- :meta {:request (dissoc req :body)}})))))
-
-(defn -main [& args]
- (binding [y/*exception-notifier* (create-exception-notifier)]
- (let [bindings {'http-port (Integer/parseInt (:port env "4000"))
- 'db-uri (:database-url env)
- 's3-bucket (:s3-bucket env)
- 's3-access-key (:s3-access-key env)
- 's3-secret-key (:s3-secret-key env)
- 'redis-url (:redis-url env "redis://localhost")
- 'a2png-bin-path (:a2png-bin-path env "a2png/a2png.sh")}
- system (->> (load-system [(io/resource "asciinema/system.edn")] bindings)
- (component/start))]
- (add-shutdown-hook ::stop-system #(component/stop system))
- (println "Started HTTP server on port" (-> system :http :port))))
- @(promise))
diff --git a/src/asciinema/model/asciicast.clj b/src/asciinema/model/asciicast.clj
deleted file mode 100644
index da2bbbb..0000000
--- a/src/asciinema/model/asciicast.clj
+++ /dev/null
@@ -1,38 +0,0 @@
-(ns asciinema.model.asciicast
- (:require [pandect.algo.sha1 :as sha1]
- [clojure.string :as str]))
-
-(defn json-store-path [{:keys [id file stdout_frames]}]
- (cond
- file (str "asciicast/file/" id "/" file)
- stdout_frames (str "asciicast/stdout_frames/" id "/" stdout_frames)))
-
-(def themes #{"asciinema" "tango" "solarized-dark" "solarized-light" "monokai"})
-(def default-theme "asciinema")
-
-(defn theme-name [asciicast user]
- (or (:theme_name asciicast)
- (:theme_name user)
- default-theme))
-
-(defn snapshot-at [{:keys [snapshot_at duration]}]
- (or snapshot_at (/ duration 2.0)))
-
-(def default-png-scale 2)
-
-(defn png-params [asciicast user]
- {:snapshot-at (snapshot-at asciicast)
- :theme (theme-name asciicast user)
- :scale default-png-scale})
-
-(defn png-version [asciicast params]
- (let [attrs (assoc params :id (:id asciicast))]
- (->> attrs
- (map (fn [[k v]] (str (name k) "=" v)))
- (str/join "/")
- (sha1/sha1))))
-
-(defn png-store-path [asciicast params]
- (let [ver (png-version asciicast params)
- png-filename (str ver ".png")]
- (str "png/" (:id asciicast) "/" png-filename)))
diff --git a/src/asciinema/util/io.clj b/src/asciinema/util/io.clj
deleted file mode 100644
index 6c2d1ad..0000000
--- a/src/asciinema/util/io.clj
+++ /dev/null
@@ -1,22 +0,0 @@
-(ns asciinema.util.io
- (:require [clojure.java.shell :as shell])
- (:import java.io.FilterInputStream
- java.nio.file.attribute.FileAttribute
- java.nio.file.Files))
-
-(defn create-tmp-dir [prefix]
- (let [dir (Files/createTempDirectory prefix (into-array FileAttribute []))]
- (.toFile dir)))
-
-(defmacro with-tmp-dir [[sym prefix] & body]
- `(let [~sym (create-tmp-dir ~prefix)]
- (try
- ~@body
- (finally
- (shell/sh "rm" "-rf" (.getPath ~sym))))))
-
-(defn cleanup-input-stream [is cleanup]
- (proxy [FilterInputStream] [is]
- (close []
- (proxy-super close)
- (cleanup))))
diff --git a/src/asciinema/yada.clj b/src/asciinema/yada.clj
deleted file mode 100644
index 06d7057..0000000
--- a/src/asciinema/yada.clj
+++ /dev/null
@@ -1,46 +0,0 @@
-(ns asciinema.yada
- (:require [clojure.java.io :as io]
- [taoensso.timbre :as log]
- [yada.status :as status]
- [yada.yada :as yada]))
-
-(def ^:dynamic *exception-notifier* nil)
-
-(def not-found-model
- {:produces
- #{"text/html" "text/plain"}
- :response
- (fn [ctx]
- (assoc (:response ctx)
- :status 404
- :body (case (yada/content-type ctx)
- "text/html" (io/input-stream (io/resource "asciinema/errors/404.html"))
- "Not found")))})
-
-(defn error-response [ctx]
- (let [status (-> ctx :response :status)
- status-name (get-in status/status [status :name])]
- (case (yada/content-type ctx)
- "text/html" (str "" status-name " ")
- status-name)))
-
-(defn create-logger []
- (let [notifier *exception-notifier*]
- (fn [ctx]
- (when-let [error (:error ctx)]
- (let [status (-> ctx :response :status)]
- (when (not= status 404)
- (log/error error))
- (when (and (= status 500) notifier)
- (let [ex (or (-> error ex-data :error) error)]
- (notifier ex (:request ctx))))))
- ctx)))
-
-(defn resource [model]
- (let [error-statuses (set (concat (range 400 404) (range 405 600) ))]
- (-> model
- (assoc :logger (create-logger))
- (update-in [:responses 404] #(or % not-found-model))
- (update-in [:responses error-statuses] #(or % {:produces #{"text/html" "text/plain"}
- :response error-response}))
- yada/resource)))
diff --git a/test/asciinema/boundary/file_store_test.clj b/test/asciinema/boundary/file_store_test.clj
deleted file mode 100644
index b6d3786..0000000
--- a/test/asciinema/boundary/file_store_test.clj
+++ /dev/null
@@ -1,7 +0,0 @@
-(ns asciinema.boundary.file-store-test
- (:require [clojure.test :refer :all]
- [asciinema.boundary.file-store :as file-store]))
-
-(deftest a-test
- (testing "FIXME, I fail."
- (is (= 0 1))))
diff --git a/test/asciinema/component/db_test.clj b/test/asciinema/component/db_test.clj
deleted file mode 100644
index 4a5fba7..0000000
--- a/test/asciinema/component/db_test.clj
+++ /dev/null
@@ -1,54 +0,0 @@
-(ns asciinema.component.db-test
- (:require [clojure.test :refer :all]
- [clojure.java.jdbc :as jdbc]
- [clj-time.local :as timel]
- [com.stuartsierra.component :as component]
- [asciinema.component.db :as db]
- [asciinema.boundary.asciicast-database :as adb]))
-
-(defmacro with-db-component [component-var & body]
- `(let [component# (-> (db/hikaricp {:uri "jdbc:postgresql://localhost:15432/asciinema_test?user=vagrant"})
- component/start)]
- (try
- (jdbc/with-db-transaction [db# (:spec component#)]
- (let [~component-var (assoc component# :spec db#)]
- (jdbc/db-set-rollback-only! db#)
- ~@body))
- (finally
- (component/stop component#)))))
-
-(defn insert-asciicast
- ([db] (insert-asciicast db {}))
- ([db attrs]
- (first (jdbc/insert! db :asciicasts (merge {:duration 10.0
- :terminal_columns 80
- :terminal_lines 24
- :created_at (timel/local-now)
- :updated_at (timel/local-now)
- :version 1
- :secret_token "abcdeabcdeabcdeabcdeabcde"}
- attrs)))))
-
-(deftest get-asciicast-by-id-test
- (testing "for existing asciicast"
- (with-db-component db
- (let [asciicast (insert-asciicast (:spec db))]
- (is (map? (adb/get-asciicast-by-id db (:id asciicast)))))))
- (testing "for non-existing asciicast"
- (with-db-component db
- (is (nil? (adb/get-asciicast-by-id db 1))))))
-
-(deftest get-asciicast-by-token-test
- (testing "for existing public asciicast"
- (with-db-component db
- (let [asciicast (insert-asciicast (:spec db) {:private false})]
- (is (map? (adb/get-asciicast-by-token db (:secret_token asciicast))))
- (is (map? (adb/get-asciicast-by-token db (-> asciicast :id str)))))))
- (testing "for existing private asciicast"
- (with-db-component db
- (let [asciicast (insert-asciicast (:spec db) {:private true})]
- (is (map? (adb/get-asciicast-by-token db (:secret_token asciicast))))
- (is (nil? (adb/get-asciicast-by-token db (-> asciicast :id str)))))))
- (testing "for non-existing asciicast"
- (with-db-component db
- (is (nil? (adb/get-asciicast-by-token db "1"))))))