Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 4 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
View
18 clj/src/kpawebgen/config.clj
@@ -0,0 +1,18 @@
+(ns kpawebgen.config
+ "Config-file-related utilities."
+ (:require [kpawebgen.util :as u]))
+
+(defn config-dir
+ "Get the canonical dir from which all config-relative paths are resolved."
+ [conf]
+ (.getCanonicalFile (.getParentFile (u/file (:_config_path conf)))))
+
+(defn db-spec
+ "Get a DB spec from a config map."
+ [conf]
+ (let [path (u/file (config-dir conf)
+ (:kpa_dir conf)
+ (:shadow_path conf))]
+ {:classname "org.sqlite.JDBC"
+ :subprotocol "sqlite"
+ :subname (.getCanonicalPath path)}))
View
7 clj/src/kpawebgen/core.clj
@@ -4,6 +4,7 @@
(:use [clojopts.core :only (clojopts with-arg optional-arg)])
(:require kpawebgen.slurp
kpawebgen.munge
+ kpawebgen.spit
clojure.repl))
(def ^{:doc "Boolean indicating whether debug mode is on", :dynamic true}
@@ -12,11 +13,9 @@
(defn localweb
"Run the localweb task using the command line options."
[{:keys [config] :as opts}]
- (->> config
- kpawebgen.slurp/read
+ (->> (kpawebgen.slurp/read config)
(kpawebgen.munge/shadow->localweb config)
- keys
- (println "Tables:")))
+ (kpawebgen.spit/write config)))
(def ^{:doc "Map of task keywords to functions (taking command-line options)."}
tasks {:localweb localweb})
View
15 clj/src/kpawebgen/slurp.clj
@@ -4,21 +4,10 @@ function for this."
(:refer-clojure :exclude [read])
(:require [clojure.java.jdbc :as sql]
clojure.java.jdbc.internal
- [kpawebgen.util :as u])
+ kpawebgen.config)
(:use [org.timmc.handy :only (version-norm)]
[slingshot.slingshot :only [throw+]]))
-(defn db-spec
- "Get a DB spec from a config map."
- [conf]
- (let [config-parent (.getParentFile (u/file (:_config_path conf)))
- path (u/file config-parent
- (:kpa_dir conf)
- (:shadow_path conf))]
- {:classname "org.sqlite.JDBC"
- :subprotocol "sqlite"
- :subname (.getAbsolutePath path)}))
-
(def tables #{:image_id :image_int :image_ext
:categories :tags :tagstoimages :taghierarchy
:metadata :changelog})
@@ -46,7 +35,7 @@ Throws (via slingshot):
localweb can't handle"
[conf]
(binding [clojure.java.jdbc.internal/*as-key* str]
- (sql/with-connection (db-spec conf)
+ (sql/with-connection (kpawebgen.config/db-spec conf)
(sql/with-query-results r
["SELECT `version` FROM `metadata`"]
;; TODO: check for table and column existence
View
33 clj/src/kpawebgen/spit.clj
@@ -0,0 +1,33 @@
+(ns kpawebgen.spit
+ "Produce thumbnails/watermarked images and SQL database from in-memory
+data structures and photo store."
+ (:require [clojure.java.jdbc :as sql]
+ clojure.java.jdbc.internal
+ clojure.java.shell
+ kpawebgen.config
+ [kpawebgen.util :as u])
+ (:use [org.timmc.handy :only (version-norm)]
+ [slingshot.slingshot :only [throw+]]))
+
+(defn wipe-dest
+ "Wipe destination files and folders."
+ [conf]
+ (let [conf-base (u/file (kpawebgen.config/config-dir conf))
+ gal-db (u/file conf-base (:gal_db_path conf))
+ ;;TODO data-dir (u/file conf-base (:data_dir conf))
+ ]
+ ;; check if DB is there or createable
+ (when-not (u/file-type-match-any? gal-db [#"(?i)sqlite"]
+ :ok-missing? true, :ok-empty? true)
+ (throw+ {:type ::target-db-file-type-on-deletion,
+ :msg (format "Refusing to overwrite file %s, not SQLite or empty"
+ gal-db)}))
+ (.delete gal-db)))
+
+(defn write
+ "Write website data out to disk and generate all files.
+
+Does not yet optimize based on diff to last localweb generation."
+ [config db]
+ (wipe-dest config)
+ (println "Tables:" (keys db)))
View
32 clj/src/kpawebgen/util.clj
@@ -1,6 +1,7 @@
(ns kpawebgen.util
"Common utilities."
- (:require [clojure.java.io :as io])
+ (:require [clojure.java.io :as io]
+ clojure.java.shell)
(:import (java.io File)
(java.util.regex Pattern Matcher)))
@@ -12,9 +13,34 @@
(if (.isAbsolute f2) (io/file p) (io/file f p))))
(defn file
- "Concatenate one or more paths. Absolute paths are respected. Concatenating
-a/b/c with /d/e/f results in /d/e/f."
+ "Concatenate one or more paths. Absolute paths overrule all previous paths.
+Concatenating a/b/c with /d/e/f results in /d/e/f."
[path & more]
{:pre [path], :post [(cast File %)]}
(let [f (io/file path)]
(if (empty? more) (io/file f) (reduce path-cat f more))))
+
+(defn sh-file
+ "Get the shell result of calling the UNIX `file` command on a File."
+ [f]
+ {:pre [(cast File f)]}
+ (clojure.java.shell/sh "file" "-b" "-L" "--" (.getPath f)))
+
+(defn file-type-match-any?
+ "Check if a file f's type matches (via re-find) any regex supplied in
+re-list, returning logical boolean. File may be a path or java.io.File.
+Always false if error occurs when attempting to stat or read file.
+opts is a map of options:
+
+* :ok-missing? [false] Return true if file is missing
+* :ok-empty? [false] Return true if file is empty"
+ [f re-list & opts]
+ (let [f (file f)
+ {:keys [ok-missing? ok-empty?]
+ :or {ok-missing? false, ok-empty? false}} opts]
+ (if (.exists f)
+ (let [{:keys [exit out]} (sh-file f)]
+ (and (= exit 0)
+ (some #(re-find % out)
+ (if ok-empty? (cons #"^empty\n$" re-list) re-list))))
+ ok-missing?)))
View
37 clj/test/kpawebgen/test/util.clj
@@ -1,6 +1,7 @@
(ns kpawebgen.test.util
- (:use [kpawebgen.util])
- (:use [clojure.test]))
+ (:use [kpawebgen.util]
+ [clojure.test])
+ (require [clojure.java.io :as io]))
(deftest paths
(are [a e] (= (.getPath a)
@@ -13,3 +14,35 @@
(file "a/b/" "/etc/init.d" "c/d") "/etc/init.d/c/d"
(file "/a" "/b" "/c" "/d" "/e") "/e"))
+(defn mapply
+ [f & args]
+ (apply f (apply concat (butlast args) (last args))))
+
+(defn maybe-real-file
+ "Resolve a file resource if real, or just make a File somehow."
+ [path]
+ (if-let [res (io/resource path)]
+ (io/as-file res)
+ (java.io.File. path)))
+
+(deftest file-types
+ (are [f res opts exp]
+ (= (boolean (mapply file-type-match-any? (maybe-real-file f) res opts))
+ exp)
+ ;; basic explicit behavior
+ "." [#"directory"] {:ok-empty? false, :ok-missing? false} true
+ ;; some, not every
+ "." [#"xxx" #"dir"] {:ok-empty? false, :ok-missing? false} true
+ ;; default: missing is not OK
+ "/fnurble" [#"whatever"] {} false
+ "/fnurble" [#"whatever"] {:ok-missing? true} true
+ ;; default: empty is not OK
+ "kpawebgen/util/filetype/blank.txt" [#"xxx"] {} false
+ "kpawebgen/util/filetype/blank.txt" [#"empty"] {} true
+ ;; no conflation of empty with missing
+ "kpawebgen/util/filetype/blank.txt" [#"xxx"] {:ok-missing? true} false
+ "kpawebgen/util/filetype/blank.txt" [#"xxx"] {:ok-empty? true} true
+ ;; don't even need matchers
+ "kpawebgen/util/filetype/blank.txt" [] {:ok-empty? true} true
+ ;; basic matching on a normal file
+ "kpawebgen/util/filetype/img.png" [#"image"] {} true))
View
0 clj/test/kpawebgen/util/filetype/blank.txt
No changes.
View
BIN clj/test/kpawebgen/util/filetype/img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2 py/src/kpawebgen/main.py
@@ -118,7 +118,7 @@ def main(self, args):
def die_usage():
usage = ["Usage:",
"kpawebgen --help",
- "kpawebgen [options] config-file sequence"
+ "kpawebgen [options] config-file sequence",
"Options: None currently defined."] #TODO
KPAWebGen.die_top(usage, Constants.ERR_BAD_ARGS, isExc=False)

No commit comments for this range

Something went wrong with that request. Please try again.