summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Ostler <scottbot9000@gmail.com>2010-10-24 20:46:30 -0400
committerScott Ostler <scottbot9000@gmail.com>2010-10-24 20:46:30 -0400
commit33955c93ae8050778c75c18756585a59103ea86f (patch)
tree3d59aded387fa0782e9eb8e59ea31bc699671148
parent02a0597e39ed337ba4dc0cccddebb4c98c63b5ee (diff)
Add initial event logic and merge
-rwxr-xr-xbin/repl.bat2
-rwxr-xr-xbin/repl.sh2
-rw-r--r--db/0-create.psql7
-rw-r--r--src/events.clj64
-rw-r--r--src/site.clj33
-rwxr-xr-xsrc/utils.clj44
-rw-r--r--static/js/pichat.js83
7 files changed, 206 insertions, 29 deletions
diff --git a/bin/repl.bat b/bin/repl.bat
index f178a91..92c650c 100755
--- a/bin/repl.bat
+++ b/bin/repl.bat
@@ -1,3 +1,3 @@
REM Windows REPL script
SHIFT
-java -Xmx320m -server -cp lib/commons-io-1.4.jar;lib/commons-fileupload-1.2.1.jar;lib/commons-codec-1.3.jar;lib/clojure.jar;lib/clojure-contrib.jar;lib/compojure-3.2v3.jar;lib/jetty-6.1.24.jar;lib/jetty-util-6.1.24.jar;lib/servlet-api-2.5-6.1.14.jar;lib/jline-0.9.94.jar;lib/postgresql-8.4-701.jdbc4.jar;lib/stringtemplate-3.2.1.jar;lib/antlr-2.7.7.jar;lib/mail-1.4.4.jar;lib/jdom-1.1.jar;lib/rome-1.0.jar;lib/htmlcleaner-2.1.jar;lib/redis-clojure-1.0.4.jar;src/ jline.ConsoleRunner clojure.main -i %0 -r %*
+java -Xmx320m -server -cp lib/commons-io-1.4.jar;lib/commons-fileupload-1.2.1.jar;lib/commons-codec-1.3.jar;lib/clojure.jar;lib/clojure-contrib.jar;lib/compojure-3.2v3.jar;lib/jetty-6.1.24.jar;lib/jetty-util-6.1.24.jar;lib/servlet-api-2.5-6.1.14.jar;lib/jline-0.9.94.jar;lib/postgresql-8.4-701.jdbc4.jar;lib/stringtemplate-3.2.1.jar;lib/antlr-2.7.7.jar;lib/mail-1.4.4.jar;lib/jdom-1.1.jar;lib/rome-1.0.jar;lib/htmlcleaner-2.1.jar;lib/redis-clojure-1.0.4.jar;src/ jline.ConsoleRunner clojure.main -i %0 -r %* \ No newline at end of file
diff --git a/bin/repl.sh b/bin/repl.sh
index 8e32d98..1b5bca1 100755
--- a/bin/repl.sh
+++ b/bin/repl.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-java -Xmx320m -server -cp .:lib/commons-io-1.4.jar:lib/commons-fileupload-1.2.1.jar:lib/commons-codec-1.3.jar:lib/jline-0.9.94.jar:lib/clojure.jar:lib/clojure-contrib.jar:lib/compojure-3.2v3.jar:lib/jetty-6.1.24.jar:lib/jetty-util-6.1.24.jar:lib/servlet-api-2.5-6.1.14.jar:lib/postgresql-8.4-701.jdbc4.jar:lib/stringtemplate-3.2.1.jar:lib/antlr-2.7.7.jar:lib/mail-1.4.4.jar:lib/jdom-1.1.jar:lib/rome-1.0.jar:lib/htmlcleaner-2.1.jar:lib/redis-clojure-1.0.4.jar:src/ jline.ConsoleRunner clojure.main -i $1 -r $@
+java -Xmx320m -server -cp .:lib/commons-io-1.4.jar:lib/commons-fileupload-1.2.1.jar:lib/commons-codec-1.3.jar:lib/jline-0.9.94.jar:lib/clojure.jar:lib/clojure-contrib.jar:lib/compojure-3.2v3.jar:lib/jetty-6.1.24.jar:lib/jetty-util-6.1.24.jar:lib/servlet-api-2.5-6.1.14.jar:lib/postgresql-8.4-701.jdbc4.jar:lib/stringtemplate-3.2.1.jar:lib/antlr-2.7.7.jar:lib/mail-1.4.4.jar:lib/jdom-1.1.jar:lib/rome-1.0.jar:lib/htmlcleaner-2.1.jar:lib/redis-clojure-1.0.4.jar:src/ jline.ConsoleRunner clojure.main -i $1 -r $@ \ No newline at end of file
diff --git a/db/0-create.psql b/db/0-create.psql
index d2d4bfc..4fa8536 100644
--- a/db/0-create.psql
+++ b/db/0-create.psql
@@ -137,6 +137,13 @@ CREATE TABLE invalid_feed_images (
CREATE INDEX invalid_feed_images_idx ON invalid_feed_images (image_url);
+CREATE TABLE events (
+ event_id SERIAL PRIMARY KEY,
+ name text NOT NULL,
+ author integer NOT NULL REFERENCES,
+ created_on timestamp NOT NULL DEFAULT now()
+);
+
-- dont add this yet
CREATE TABLE avatars (
avatar_id SERIAL PRIMARY KEY,
diff --git a/src/events.clj b/src/events.clj
index 6660518..501c231 100644
--- a/src/events.clj
+++ b/src/events.clj
@@ -1,13 +1,69 @@
(ns events
- (use utils))
+ (:import java.util.Date
+ java.net.URL
+ java.io.ByteArrayInputStream
+ java.io.ByteArrayOutputStream
+ javax.imageio.ImageIO)
+ (:use clojure.contrib.duck-streams
+ compojure
+ rooms
+ utils))
+
+; 256bit b64 key
+(def event-secret (b64dec "zLSBf28jZ3Q89MLx7u3P/w==\r\n"))
+
+(def encoder (aes-encoder event-secret))
+(def decoder (aes-decoder event-secret))
(def sample-event {:name "TMZ Maker!"
:key "tmz"
- :template "http://dump.fm/images/20100629/1277836809689-dumpfm-ryder-tmz_template.png"
+ :template "/event/proxy?url=http://dump.fm/images/20100629/1277836809689-dumpfm-ryder-tmz_template.png"
:author {:nick "ryder" }})
-(defn current-event [session]
+(defn event-page [session]
(let [st (fetch-template "event" session)
event sample-event]
(.setAttribute st "event" (stringify-and-escape sample-event))
- (.toString st))) \ No newline at end of file
+ (.toString st)))
+
+(defn image-proxy [session params request]
+ (println "image-proxy for" (:url params))
+ [200 (.openStream (URL. (:url params)))])
+
+(defn fetch-event [key]
+ sample-event)
+
+(defn image-already-submitted? [event img-src]
+ false)
+
+(def event-submission-room "dumpfm")
+
+
+(defn build-event-msg [nick evnet url]
+ {:nick nick
+ :content url
+ :created_on (new Date)
+ :msg-id 1})
+
+(defn submit! [session params request]
+ (let [nick (:nick session)
+ bytes (b64dec (:image params))
+ src (:src params)
+ event (and nick bytes src (fetch-event (:event params)))]
+ (cond (not nick) (resp-error "NO_USER")
+ (not bytes) (resp-error "NO_IMG")
+ (not event) (resp-error "NO_EVENT")
+ (not (is-image? src)) (resp-error "BAD_SRC")
+ (image-already-submitted?
+ (:key event) src) (resp-error "IMG_SUBMITTED")
+ :else (let [ts (System/currentTimeMillis)
+ room (lookup-room event-submission-room)
+ fname (format "%s-%s.png" ts nick)
+ dest (open-file ["events" (:key event)] fname)
+ url (format "/events/%s/%s" (:key event) fname)]
+ (println "copying" dest)
+ (copy (ByteArrayInputStream. bytes) dest)
+ (dosync
+ (add-message (build-event-msg nick (:key event) url) room))
+ (println "copied")
+ (resp-success "OK"))))) \ No newline at end of file
diff --git a/src/site.clj b/src/site.clj
index 98fde79..1523c6f 100644
--- a/src/site.clj
+++ b/src/site.clj
@@ -19,7 +19,6 @@
admin
compojure
email
- events
fame
utils
cookie-login
@@ -473,7 +472,7 @@ ORDER BY cnt DESC
(defn generic-profile-handler [session nick date msg-id
func redirecter unknown]
(if-let [user-info (fetch-nick nick)]
- ;; If a valid msg-id is provided, the date is ignored.
+ ;; If a valid msg-id is provided, the date is ignored.
;; This makes urls such as /user/bogus/5 valid.
(cond msg-id (if-let [msg-id (maybe-parse-int msg-id)]
(func session user-info nil msg-id)
@@ -489,12 +488,12 @@ ORDER BY cnt DESC
(defn build-mini-profile [user-info]
(let [st (fetch-template-fragment "mini_profile")
- nick (user-info :nick)
- score (lookup-score nick)]
+ nick (user-info :nick)
+ score (lookup-score nick)]
(doseq [a [:nick :avatar :contact :bio]]
(let [v (user-info a)]
- (.setAttribute st (name a)
- (if (non-empty-string? v) (escape-html v)))))
+ (.setAttribute st (name a)
+ (if (non-empty-string? v) (escape-html v)))))
(doto st
(.setAttribute "score" (comma-format score))
(.setAttribute "score_ent" (score-to-entity score))
@@ -1150,14 +1149,14 @@ WHERE u.user_id = ANY(?)"
(str "FILE_TOO_BIG " limit)))
(defn invalid-image-dimensions? [f [max-width max-height]]
- (try
- (let [i (ImageIO/read f)
- height (.getHeight i)
- width (.getWidth i)]
- (if (or (> width max-width)
- (> height max-height))
- (str "INVALID_RESOLUTION " max-width " " max-height)))
- (catch Exception _ "INVALID_IMAGE")))
+ (try
+ (let [i (ImageIO/read f)
+ height (.getHeight i)
+ width (.getWidth i)]
+ (if (or (> width max-width)
+ (> height max-height))
+ (str "INVALID_RESOLUTION " max-width " " max-height)))
+ (catch Exception _ "INVALID_IMAGE")))
(defn format-filename [s nick]
(let [spaceless (.replace s \space \-)
@@ -1165,7 +1164,7 @@ WHERE u.user_id = ANY(?)"
subbed (re-gsub #"[^\w.-]" "" spaceless)]
(str-join "-" [(System/currentTimeMillis) "dumpfm" nick-clean subbed])))
-(defn image-url-from-file [dir date file]
+(defn image-url-from-file [dir date file]
(str-join "/" [*server-url* dir date (.getName file)]))
(defn validate-upload-file [f room]
@@ -1339,7 +1338,9 @@ WHERE u.user_id = ANY(?)"
;; Events
- (GET "/event" (current-event session))
+; (GET "/event" (event-page session))
+; (GET "/event/proxy" (image-proxy session params request))
+; (POST "/event/submit" (submit! session params request))
;; Fullscreen
(GET "/fullscreen" (serve-meme session "fullscreen"))
diff --git a/src/utils.clj b/src/utils.clj
index 9460bbc..08b06ab 100755
--- a/src/utils.clj
+++ b/src/utils.clj
@@ -6,7 +6,12 @@
java.io.File
java.net.URLDecoder
javax.sql.DataSource
+ javax.crypto.Cipher
+ javax.crypto.spec.SecretKeySpec
+ javax.crypto.KeyGenerator
+ javax.crypto.Mac
org.postgresql.ds.PGPoolingDataSource
+ org.apache.commons.codec.binary.Base64
org.apache.commons.codec.digest.DigestUtils
org.antlr.stringtemplate.StringTemplateGroup)
(:use clojure.contrib.json.write
@@ -297,7 +302,44 @@
(doseq [[i o] (map vector (iterate inc 1) objects)]
(.setObject stmt i o))
(.executeQuery stmt))))
-
+
+;; Crypto
+
+(def b64codec (Base64.))
+
+(defn b64enc [bytes]
+ (.encodeToString b64codec bytes))
+
+(defn b64dec [s]
+ (.decode b64codec s))
+
+(defn generate-aes-key [bits]
+ (let [kgen (doto (KeyGenerator/getInstance "AES")
+ (.init bits))
+ skey (.generateKey kgen)]
+ (.getEncoded skey)))
+
+(defn aes-encoder [secret]
+ (let [spec (SecretKeySpec. secret "AES")
+ cipher (Cipher/getInstance "AES")]
+ (.init cipher Cipher/ENCRYPT_MODE spec)
+ (fn [input]
+ (.doFinal cipher input))))
+
+(defn aes-decoder [secret]
+ (let [spec (SecretKeySpec. secret "AES")
+ cipher (Cipher/getInstance "AES")]
+ (.init cipher Cipher/DECRYPT_MODE spec)
+ (fn [input]
+ (.doFinal cipher input))))
+
+
+(defn make-signer [secret]
+ (let [algo "HmacSHA1"
+ spec (SecretKeySpec. (.getBytes secret) algo)
+ mac (Mac/getInstance algo)]
+ (.init mac spec)
+ (fn [input] (.doFinal mac (.getBytes input)))))
;; Parsing
diff --git a/static/js/pichat.js b/static/js/pichat.js
index b02167b..5713531 100644
--- a/static/js/pichat.js
+++ b/static/js/pichat.js
@@ -373,12 +373,11 @@ function removeFavAndHideBox() {
function showFav(f) {
$('#favbox').show();
buildFav(f).appendTo('#favbox').animate(
- {"opacity": 0},
- {"duration": 9000,
- "easing": "easeInExpo",
- "complete": removeFavAndHideBox
- })
-
+ {"opacity": 0},
+ {"duration": 9000,
+ "easing": "easeInExpo",
+ "complete": removeFavAndHideBox
+ });
}
@@ -1699,6 +1698,78 @@ function initChatMsgs() {
});
}
+var Event = {
+ "init": function(eventKey, templateSrc, urlInput, urlSubmit,
+ canvas, submitButton,
+ entryList, proxyToken) {
+ var canvas = $(canvas).get(0);
+ var ctx = canvas.getContext('2d');
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ var UrlEntered = false;
+
+ var url;
+
+ var UserLoaded = false;
+ var UserImg = new Image();
+
+ var TemplateLoaded = false;
+ var TemplateImg = new Image();
+
+ TemplateImg.onload = function() {
+ TemplateLoaded = true;
+ ctx.drawImage(TemplateImg, 0, 0, cn.width, cn.height);
+ };
+ TemplateImg.src = templateSrc;
+
+ $(urlSubmit).click(function() {
+ url = $(urlInput).val();
+ var urlSrc = '/event/proxy?url=' + url;
+ if (!urlSrc || urlSrc.length == 0) {
+ alert('Please enter an image url!');
+ $(urlInput).focus();
+ return;
+ }
+
+ UrlEntered = true;
+
+ UserImg.src = urlSrc;
+ UserImg.onload = function () {
+ ctx.drawImage(UserImg, 0, 0, cn.width, cn.height);
+ ctx.drawImage(TemplateImg, 0, 0, cn.width, cn.height);
+ return false;
+ };
+ UserImg.onerror = function() {
+ console.log("Unable to retrieve image for " + url);
+ return false;
+ };
+ });
+
+ $(submitButton).click(function() {
+ if (!UrlEntered) {
+ alert('Please enter a url!');
+ $(urlInput).focus();
+ return;
+ }
+ var data = canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, "");
+ var success = function() {
+ console.log('success');
+ };
+ var error = function() {
+ console.log('error');
+ };
+ $.ajax({ type: 'POST',
+ url: '/event/dump',
+ data: { 'event': eventKey, 'image': data, 'src': url },
+ success: success,
+ error: error,
+ cache: false
+ });
+ });
+ }
+};
+
+// sha1.js
/* SHA1.js (timb: compressed this)
* Version 2.2 Copyright Paul Johnston 2000 - 2009.