-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathapp.rkt
152 lines (125 loc) · 4.49 KB
/
app.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#lang racket
(require web-server/servlet
web-server/servlet-env
web-server/templates
srfi/43
net/uri-codec
racket/runtime-path
mzlib/defmacro)
(require "bayes.rkt"
"crc32.rkt"
"utils.rkt")
(define *app-version* 10)
(define *app-date* "November 2010")
(load-data!)
; Hash with crc32 mappings to author names
(define *authors-hash*
(for/hash ([author *categories*])
(values (string->crc32/hex author) author)))
(define-values (app-dispatch req)
(dispatch-rules
[("") show-index]
[("") #:method "post" process-submission]
[("b" (string-arg)) show-badge]
[("s" (string-arg)) show-shared]
[("w" (string-arg)) show-writer]
[("api") #:method "post" api]
[("newsletter") show-newsletter]
[("newsletter" (string-arg)) (lambda (r a) (redirect-to "/newsletter"))]
[else not-found]))
(define (base-template title menu body)
(include-template "templates/base.html"))
(define (get-author text)
(and (> (string-length text) 30)
(get-category (safe-substring text 0 3000))))
(define (index-template short?)
(response/full
200 #"Okay"
(current-seconds) TEXT/HTML-MIME-TYPE
empty
(list (string->bytes/utf-8 (base-template "" "analyzer"
(include-template "templates/index.html"))))))
(define (badge-url author)
(string-append "/b/" (string->crc32/hex author)))
(define (show-index req)
(index-template #f))
(define (process-submission req)
(aif (dict-ref (request-bindings req) 'text #f)
(aif (get-author it)
(redirect-to (badge-url it))
(index-template #t))
(index-template #f)))
(define (json-out s)
(response/full
200 #"Okay"
(current-seconds) #"application/json; charset=utf-8"
empty
(list (string->bytes/utf-8 s))))
(define (json-error desc)
(json-out (format "{\"error\": \"~a\"}" desc)))
(define (json-result wrapper author)
(let ([crc (string->crc32/hex author)])
(json-out (format "{\"share_link\": \"http://iwl.me/s/~a\",
\"writer_link\": \"http://iwl.me/w/~a\",
\"writer\": \"~a\",
\"id\": \"~a\",
\"badge_link\": \"http://iwl.me/b/~a\"}"
crc crc author crc crc))))
(define (api req)
(let* ([bindings (request-bindings req)]
[text (dict-ref bindings 'text #f)]
[wrapper (dict-ref bindings 'function "")]
[client-id (dict-ref bindings 'client_id #f)] ; unused, but required
[permalink (dict-ref bindings 'permalink #f)]) ; -"-
(if (and text client-id permalink)
(aif (get-author text)
(json-result wrapper it)
(json-error "text is too short or doesn't have words"))
(json-error "not enough arguments"))))
(define (not-found req)
(response/full 404 #"Not Found" (current-seconds)
TEXT/HTML-MIME-TYPE empty (list #"not found")))
(define (crc->author crc)
(hash-ref *authors-hash* crc #f))
(define-macro (badge-template req crc tpl)
`(let ([writer (crc->author ,crc)])
(if writer
(response/full
200 #"Okay"
(current-seconds) TEXT/HTML-MIME-TYPE
empty
(list (string->bytes/utf-8
(base-template writer "" (include-template ,tpl)))))
(not-found ,req))))
(define (show-badge req crc)
(badge-template req crc "templates/show-badge.html"))
(define (show-shared req crc)
(badge-template req crc "templates/show-shared.html"))
(define (show-writer req crc)
(aif (crc->author crc)
(redirect-to
(format (string-append
"http://www.amazon.com/gp/search?ie=UTF8&keywords=~a"
"&tag=blogjetblog-20&index=books&linkCode=ur2"
"&camp=1789&creative=9325") it))
(not-found req)))
(define (show-newsletter req)
(response/full
200 #"Okay"
(current-seconds) TEXT/HTML-MIME-TYPE
empty
(list (string->bytes/utf-8
(base-template "Newsletter" "newsletter"
(include-template "templates/show-newsletter.html"))))))
(define (start req)
(app-dispatch req))
(define-runtime-path srvpath ".")
(define (get-port-from-env)
(string->number (or (getenv "PORT") "8080")))
(serve/servlet start
#:servlet-path ""
#:port (get-port-from-env)
#:servlet-regexp #rx"^((?!/static/).)*$"
#:extra-files-paths (list srvpath)
#:launch-browser? #f
#:stateless? #t)