card-mod-script 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/lib/javascript/decko/autosave.js.coffee +30 -0
  3. data/lib/javascript/decko/bridge.js.coffee +31 -0
  4. data/lib/javascript/decko/card_menu.js.coffee +26 -0
  5. data/lib/javascript/decko/components.js.coffee +51 -0
  6. data/lib/javascript/decko/decko.js.coffee +100 -0
  7. data/lib/javascript/decko/doubleclick.js.coffee +30 -0
  8. data/lib/javascript/decko/editor.js.coffee +55 -0
  9. data/lib/javascript/decko/filter.js.coffee +176 -0
  10. data/lib/javascript/decko/filter_items.js.coffee +128 -0
  11. data/lib/javascript/decko/filter_links.js.coffee +81 -0
  12. data/lib/javascript/decko/follow.js.coffee +22 -0
  13. data/lib/javascript/decko/layout.js.coffee +76 -0
  14. data/lib/javascript/decko/link_editor.js.coffee +61 -0
  15. data/lib/javascript/decko/mod.js.coffee +85 -0
  16. data/lib/javascript/decko/modal.js.coffee +110 -0
  17. data/lib/javascript/decko/name_editor.js.coffee +51 -0
  18. data/lib/javascript/decko/navbox.js.coffee +74 -0
  19. data/lib/javascript/decko/nest_editor.js.coffee +166 -0
  20. data/lib/javascript/decko/nest_editor_name.js.coffee +102 -0
  21. data/lib/javascript/decko/nest_editor_options.js.coffee +93 -0
  22. data/lib/javascript/decko/nest_editor_rules.js.coffee +3 -0
  23. data/lib/javascript/decko/overlay.js.coffee +57 -0
  24. data/lib/javascript/decko/recaptcha.js.coffee +19 -0
  25. data/lib/javascript/decko/selectable_filtered_content.js.coffee +12 -0
  26. data/lib/javascript/decko/slot.js.coffee +172 -0
  27. data/lib/javascript/decko/slot_ready.js.coffee +11 -0
  28. data/lib/javascript/decko/slotter.js.coffee +269 -0
  29. data/lib/javascript/decko/upload.js.coffee +57 -0
  30. data/lib/javascript/jquery-ui.js +10 -0
  31. data/lib/javascript/jquery.autosize.js +274 -0
  32. data/lib/javascript/jquery.iframe-transport.js +185 -0
  33. data/lib/javascript/script_html5shiv_printshiv.js +1 -0
  34. data/lib/javascript/script_pointer_config.js.coffee +80 -0
  35. data/lib/javascript/script_pointer_list_editor.js.coffee +67 -0
  36. data/lib/javascript/theme-textmate.js +130 -0
  37. data/set/abstract/script.rb +85 -0
  38. data/set/right/script.rb +19 -0
  39. data/set/self/01_script_libraries.rb +1 -0
  40. data/set/self/script.rb +1 -0
  41. data/set/self/script_decko.rb +12 -0
  42. data/set/self/script_editors.rb +1 -0
  43. data/set/self/script_html5shiv_printshiv.rb +11 -0
  44. data/set/self/script_jquery.rb +10 -0
  45. data/set/self/script_jquery_helper.rb +14 -0
  46. data/set/self/script_mods.rb +1 -0
  47. data/set/self/script_pointer_config.rb +9 -0
  48. data/set/type/coffee_script.rb +25 -0
  49. data/set/type/java_script.rb +9 -0
  50. data/vendor/jquery_file_upload/CONTRIBUTING.md +15 -0
  51. data/vendor/jquery_file_upload/LICENSE.txt +21 -0
  52. data/vendor/jquery_file_upload/README.md +107 -0
  53. data/vendor/jquery_file_upload/angularjs.html +211 -0
  54. data/vendor/jquery_file_upload/basic-plus.html +226 -0
  55. data/vendor/jquery_file_upload/basic.html +136 -0
  56. data/vendor/jquery_file_upload/bower-version-update.js +16 -0
  57. data/vendor/jquery_file_upload/bower.json +64 -0
  58. data/vendor/jquery_file_upload/cors/postmessage.html +75 -0
  59. data/vendor/jquery_file_upload/cors/result.html +24 -0
  60. data/vendor/jquery_file_upload/css/jquery-ui-demo-ie8.css +21 -0
  61. data/vendor/jquery_file_upload/css/jquery-ui-demo.css +67 -0
  62. data/vendor/jquery_file_upload/css/jquery.fileupload-noscript.css +22 -0
  63. data/vendor/jquery_file_upload/css/jquery.fileupload-ui-noscript.css +17 -0
  64. data/vendor/jquery_file_upload/css/jquery.fileupload-ui.css +57 -0
  65. data/vendor/jquery_file_upload/css/jquery.fileupload.css +37 -0
  66. data/vendor/jquery_file_upload/css/style.css +15 -0
  67. data/vendor/jquery_file_upload/img/loading.gif +0 -0
  68. data/vendor/jquery_file_upload/img/progressbar.gif +0 -0
  69. data/vendor/jquery_file_upload/index.html +255 -0
  70. data/vendor/jquery_file_upload/jquery-ui.html +252 -0
  71. data/vendor/jquery_file_upload/js/app.js +101 -0
  72. data/vendor/jquery_file_upload/js/cors/jquery.postmessage-transport.js +126 -0
  73. data/vendor/jquery_file_upload/js/cors/jquery.xdr-transport.js +89 -0
  74. data/vendor/jquery_file_upload/js/jquery.fileupload-angular.js +437 -0
  75. data/vendor/jquery_file_upload/js/jquery.fileupload-audio.js +113 -0
  76. data/vendor/jquery_file_upload/js/jquery.fileupload-image.js +326 -0
  77. data/vendor/jquery_file_upload/js/jquery.fileupload-jquery-ui.js +161 -0
  78. data/vendor/jquery_file_upload/js/jquery.fileupload-process.js +178 -0
  79. data/vendor/jquery_file_upload/js/jquery.fileupload-ui.js +714 -0
  80. data/vendor/jquery_file_upload/js/jquery.fileupload-validate.js +125 -0
  81. data/vendor/jquery_file_upload/js/jquery.fileupload-video.js +113 -0
  82. data/vendor/jquery_file_upload/js/jquery.fileupload.js +1486 -0
  83. data/vendor/jquery_file_upload/js/jquery.iframe-transport.js +224 -0
  84. data/vendor/jquery_file_upload/js/main.js +75 -0
  85. data/vendor/jquery_file_upload/js/vendor/jquery.ui.widget.js +748 -0
  86. data/vendor/jquery_file_upload/package.json +55 -0
  87. data/vendor/jquery_file_upload/server/gae-go/app.yaml +12 -0
  88. data/vendor/jquery_file_upload/server/gae-go/app/main.go +361 -0
  89. data/vendor/jquery_file_upload/server/gae-go/static/favicon.ico +0 -0
  90. data/vendor/jquery_file_upload/server/gae-go/static/robots.txt +2 -0
  91. data/vendor/jquery_file_upload/server/gae-python/app.yaml +17 -0
  92. data/vendor/jquery_file_upload/server/gae-python/main.py +204 -0
  93. data/vendor/jquery_file_upload/server/gae-python/static/favicon.ico +0 -0
  94. data/vendor/jquery_file_upload/server/gae-python/static/robots.txt +2 -0
  95. data/vendor/jquery_file_upload/server/php/Dockerfile +38 -0
  96. data/vendor/jquery_file_upload/server/php/UploadHandler.php +1411 -0
  97. data/vendor/jquery_file_upload/server/php/docker-compose.yml +9 -0
  98. data/vendor/jquery_file_upload/server/php/index.php +15 -0
  99. data/vendor/jquery_file_upload/test/index.html +172 -0
  100. data/vendor/jquery_file_upload/test/test.js +1292 -0
  101. data/vendor/jquery_rails/CHANGELOG.md +359 -0
  102. data/vendor/jquery_rails/CONTRIBUTING.md +132 -0
  103. data/vendor/jquery_rails/Gemfile +22 -0
  104. data/vendor/jquery_rails/MIT-LICENSE +21 -0
  105. data/vendor/jquery_rails/README.md +75 -0
  106. data/vendor/jquery_rails/Rakefile +59 -0
  107. data/vendor/jquery_rails/VERSIONS.md +62 -0
  108. data/vendor/jquery_rails/jquery-rails.gemspec +26 -0
  109. data/vendor/jquery_rails/lib/jquery-rails.rb +1 -0
  110. data/vendor/jquery_rails/lib/jquery/assert_select.rb +149 -0
  111. data/vendor/jquery_rails/lib/jquery/rails.rb +8 -0
  112. data/vendor/jquery_rails/lib/jquery/rails/engine.rb +6 -0
  113. data/vendor/jquery_rails/lib/jquery/rails/version.rb +9 -0
  114. data/vendor/jquery_rails/test/assert_select_jquery_test.rb +85 -0
  115. data/vendor/jquery_rails/test/test_helper.rb +6 -0
  116. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.js +11008 -0
  117. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.js +5 -0
  118. data/vendor/jquery_rails/vendor/assets/javascripts/jquery.min.map +1 -0
  119. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.js +9814 -0
  120. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.js +4 -0
  121. data/vendor/jquery_rails/vendor/assets/javascripts/jquery2.min.map +1 -0
  122. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.js +10364 -0
  123. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.js +2 -0
  124. data/vendor/jquery_rails/vendor/assets/javascripts/jquery3.min.map +1 -0
  125. data/vendor/jquery_rails/vendor/assets/javascripts/jquery_ujs.js +555 -0
  126. metadata +212 -0
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "blueimp-file-upload",
3
+ "version": "9.21.0",
4
+ "title": "jQuery File Upload",
5
+ "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.",
6
+ "keywords": [
7
+ "jquery",
8
+ "file",
9
+ "upload",
10
+ "widget",
11
+ "multiple",
12
+ "selection",
13
+ "drag",
14
+ "drop",
15
+ "progress",
16
+ "preview",
17
+ "cross-domain",
18
+ "cross-site",
19
+ "chunk",
20
+ "resume",
21
+ "gae",
22
+ "go",
23
+ "python",
24
+ "php",
25
+ "bootstrap"
26
+ ],
27
+ "homepage": "https://github.com/blueimp/jQuery-File-Upload",
28
+ "author": {
29
+ "name": "Sebastian Tschan",
30
+ "url": "https://blueimp.net"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git://github.com/blueimp/jQuery-File-Upload.git"
35
+ },
36
+ "license": "MIT",
37
+ "optionalDependencies": {
38
+ "blueimp-canvas-to-blob": "3.5.0",
39
+ "blueimp-load-image": "2.12.2",
40
+ "blueimp-tmpl": "3.6.0"
41
+ },
42
+ "devDependencies": {
43
+ "bower-json": "0.8.1",
44
+ "jshint": "2.9.3"
45
+ },
46
+ "scripts": {
47
+ "bower-version-update": "./bower-version-update.js",
48
+ "lint": "jshint *.js js/*.js js/cors/*.js",
49
+ "test": "npm run lint",
50
+ "preversion": "npm test",
51
+ "version": "npm run bower-version-update && git add bower.json",
52
+ "postversion": "git push --tags origin master && npm publish"
53
+ },
54
+ "main": "js/jquery.fileupload.js"
55
+ }
@@ -0,0 +1,12 @@
1
+ application: jquery-file-upload
2
+ version: 2
3
+ runtime: go
4
+ api_version: go1
5
+
6
+ handlers:
7
+ - url: /(favicon\.ico|robots\.txt)
8
+ static_files: static/\1
9
+ upload: static/(.*)
10
+ expiration: '1d'
11
+ - url: /.*
12
+ script: _go_app
@@ -0,0 +1,361 @@
1
+ /*
2
+ * jQuery File Upload Plugin GAE Go Example
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, Sebastian Tschan
6
+ * https://blueimp.net
7
+ *
8
+ * Licensed under the MIT license:
9
+ * https://opensource.org/licenses/MIT
10
+ */
11
+
12
+ package app
13
+
14
+ import (
15
+ "bufio"
16
+ "bytes"
17
+ "encoding/json"
18
+ "fmt"
19
+ "github.com/disintegration/gift"
20
+ "golang.org/x/net/context"
21
+ "google.golang.org/appengine"
22
+ "google.golang.org/appengine/memcache"
23
+ "hash/crc32"
24
+ "image"
25
+ "image/gif"
26
+ "image/jpeg"
27
+ "image/png"
28
+ "io"
29
+ "log"
30
+ "mime/multipart"
31
+ "net/http"
32
+ "net/url"
33
+ "path/filepath"
34
+ "regexp"
35
+ "strings"
36
+ )
37
+
38
+ const (
39
+ WEBSITE = "https://blueimp.github.io/jQuery-File-Upload/"
40
+ MIN_FILE_SIZE = 1 // bytes
41
+ // Max file size is memcache limit (1MB) minus key size minus overhead:
42
+ MAX_FILE_SIZE = 999000 // bytes
43
+ IMAGE_TYPES = "image/(gif|p?jpeg|(x-)?png)"
44
+ ACCEPT_FILE_TYPES = IMAGE_TYPES
45
+ THUMB_MAX_WIDTH = 80
46
+ THUMB_MAX_HEIGHT = 80
47
+ EXPIRATION_TIME = 300 // seconds
48
+ // If empty, only allow redirects to the referer protocol+host.
49
+ // Set to a regexp string for custom pattern matching:
50
+ REDIRECT_ALLOW_TARGET = ""
51
+ )
52
+
53
+ var (
54
+ imageTypes = regexp.MustCompile(IMAGE_TYPES)
55
+ acceptFileTypes = regexp.MustCompile(ACCEPT_FILE_TYPES)
56
+ thumbSuffix = "." + fmt.Sprint(THUMB_MAX_WIDTH) + "x" +
57
+ fmt.Sprint(THUMB_MAX_HEIGHT)
58
+ )
59
+
60
+ func escape(s string) string {
61
+ return strings.Replace(url.QueryEscape(s), "+", "%20", -1)
62
+ }
63
+
64
+ func extractKey(r *http.Request) string {
65
+ // Use RequestURI instead of r.URL.Path, as we need the encoded form:
66
+ path := strings.Split(r.RequestURI, "?")[0]
67
+ // Also adjust double encoded slashes:
68
+ return strings.Replace(path[1:], "%252F", "%2F", -1)
69
+ }
70
+
71
+ func check(err error) {
72
+ if err != nil {
73
+ panic(err)
74
+ }
75
+ }
76
+
77
+ type FileInfo struct {
78
+ Key string `json:"-"`
79
+ ThumbnailKey string `json:"-"`
80
+ Url string `json:"url,omitempty"`
81
+ ThumbnailUrl string `json:"thumbnailUrl,omitempty"`
82
+ Name string `json:"name"`
83
+ Type string `json:"type"`
84
+ Size int64 `json:"size"`
85
+ Error string `json:"error,omitempty"`
86
+ DeleteUrl string `json:"deleteUrl,omitempty"`
87
+ DeleteType string `json:"deleteType,omitempty"`
88
+ }
89
+
90
+ func (fi *FileInfo) ValidateType() (valid bool) {
91
+ if acceptFileTypes.MatchString(fi.Type) {
92
+ return true
93
+ }
94
+ fi.Error = "Filetype not allowed"
95
+ return false
96
+ }
97
+
98
+ func (fi *FileInfo) ValidateSize() (valid bool) {
99
+ if fi.Size < MIN_FILE_SIZE {
100
+ fi.Error = "File is too small"
101
+ } else if fi.Size > MAX_FILE_SIZE {
102
+ fi.Error = "File is too big"
103
+ } else {
104
+ return true
105
+ }
106
+ return false
107
+ }
108
+
109
+ func (fi *FileInfo) CreateUrls(r *http.Request, c context.Context) {
110
+ u := &url.URL{
111
+ Scheme: r.URL.Scheme,
112
+ Host: appengine.DefaultVersionHostname(c),
113
+ Path: "/",
114
+ }
115
+ uString := u.String()
116
+ fi.Url = uString + fi.Key
117
+ fi.DeleteUrl = fi.Url
118
+ fi.DeleteType = "DELETE"
119
+ if fi.ThumbnailKey != "" {
120
+ fi.ThumbnailUrl = uString + fi.ThumbnailKey
121
+ }
122
+ }
123
+
124
+ func (fi *FileInfo) SetKey(checksum uint32) {
125
+ fi.Key = escape(string(fi.Type)) + "/" +
126
+ escape(fmt.Sprint(checksum)) + "/" +
127
+ escape(string(fi.Name))
128
+ }
129
+
130
+ func (fi *FileInfo) createThumb(buffer *bytes.Buffer, c context.Context) {
131
+ if imageTypes.MatchString(fi.Type) {
132
+ src, _, err := image.Decode(bytes.NewReader(buffer.Bytes()))
133
+ check(err)
134
+ filter := gift.New(gift.ResizeToFit(
135
+ THUMB_MAX_WIDTH,
136
+ THUMB_MAX_HEIGHT,
137
+ gift.LanczosResampling,
138
+ ))
139
+ dst := image.NewNRGBA(filter.Bounds(src.Bounds()))
140
+ filter.Draw(dst, src)
141
+ buffer.Reset()
142
+ bWriter := bufio.NewWriter(buffer)
143
+ switch fi.Type {
144
+ case "image/jpeg", "image/pjpeg":
145
+ err = jpeg.Encode(bWriter, dst, nil)
146
+ case "image/gif":
147
+ err = gif.Encode(bWriter, dst, nil)
148
+ default:
149
+ err = png.Encode(bWriter, dst)
150
+ }
151
+ check(err)
152
+ bWriter.Flush()
153
+ thumbnailKey := fi.Key + thumbSuffix + filepath.Ext(fi.Name)
154
+ item := &memcache.Item{
155
+ Key: thumbnailKey,
156
+ Value: buffer.Bytes(),
157
+ }
158
+ err = memcache.Set(c, item)
159
+ check(err)
160
+ fi.ThumbnailKey = thumbnailKey
161
+ }
162
+ }
163
+
164
+ func handleUpload(r *http.Request, p *multipart.Part) (fi *FileInfo) {
165
+ fi = &FileInfo{
166
+ Name: p.FileName(),
167
+ Type: p.Header.Get("Content-Type"),
168
+ }
169
+ if !fi.ValidateType() {
170
+ return
171
+ }
172
+ defer func() {
173
+ if rec := recover(); rec != nil {
174
+ log.Println(rec)
175
+ fi.Error = rec.(error).Error()
176
+ }
177
+ }()
178
+ var buffer bytes.Buffer
179
+ hash := crc32.NewIEEE()
180
+ mw := io.MultiWriter(&buffer, hash)
181
+ lr := &io.LimitedReader{R: p, N: MAX_FILE_SIZE + 1}
182
+ _, err := io.Copy(mw, lr)
183
+ check(err)
184
+ fi.Size = MAX_FILE_SIZE + 1 - lr.N
185
+ if !fi.ValidateSize() {
186
+ return
187
+ }
188
+ fi.SetKey(hash.Sum32())
189
+ item := &memcache.Item{
190
+ Key: fi.Key,
191
+ Value: buffer.Bytes(),
192
+ }
193
+ context := appengine.NewContext(r)
194
+ err = memcache.Set(context, item)
195
+ check(err)
196
+ fi.createThumb(&buffer, context)
197
+ fi.CreateUrls(r, context)
198
+ return
199
+ }
200
+
201
+ func getFormValue(p *multipart.Part) string {
202
+ var b bytes.Buffer
203
+ io.CopyN(&b, p, int64(1<<20)) // Copy max: 1 MiB
204
+ return b.String()
205
+ }
206
+
207
+ func handleUploads(r *http.Request) (fileInfos []*FileInfo) {
208
+ fileInfos = make([]*FileInfo, 0)
209
+ mr, err := r.MultipartReader()
210
+ check(err)
211
+ r.Form, err = url.ParseQuery(r.URL.RawQuery)
212
+ check(err)
213
+ part, err := mr.NextPart()
214
+ for err == nil {
215
+ if name := part.FormName(); name != "" {
216
+ if part.FileName() != "" {
217
+ fileInfos = append(fileInfos, handleUpload(r, part))
218
+ } else {
219
+ r.Form[name] = append(r.Form[name], getFormValue(part))
220
+ }
221
+ }
222
+ part, err = mr.NextPart()
223
+ }
224
+ return
225
+ }
226
+
227
+ func validateRedirect(r *http.Request, redirect string) bool {
228
+ if redirect != "" {
229
+ var redirectAllowTarget *regexp.Regexp
230
+ if REDIRECT_ALLOW_TARGET != "" {
231
+ redirectAllowTarget = regexp.MustCompile(REDIRECT_ALLOW_TARGET)
232
+ } else {
233
+ referer := r.Referer()
234
+ if referer == "" {
235
+ return false
236
+ }
237
+ refererUrl, err := url.Parse(referer)
238
+ if err != nil {
239
+ return false
240
+ }
241
+ redirectAllowTarget = regexp.MustCompile("^" + regexp.QuoteMeta(
242
+ refererUrl.Scheme+"://"+refererUrl.Host+"/",
243
+ ))
244
+ }
245
+ return redirectAllowTarget.MatchString(redirect)
246
+ }
247
+ return false
248
+ }
249
+
250
+ func get(w http.ResponseWriter, r *http.Request) {
251
+ if r.URL.Path == "/" {
252
+ http.Redirect(w, r, WEBSITE, http.StatusFound)
253
+ return
254
+ }
255
+ // Use RequestURI instead of r.URL.Path, as we need the encoded form:
256
+ key := extractKey(r)
257
+ parts := strings.Split(key, "/")
258
+ if len(parts) == 3 {
259
+ context := appengine.NewContext(r)
260
+ item, err := memcache.Get(context, key)
261
+ if err == nil {
262
+ w.Header().Add("X-Content-Type-Options", "nosniff")
263
+ contentType, _ := url.QueryUnescape(parts[0])
264
+ if !imageTypes.MatchString(contentType) {
265
+ contentType = "application/octet-stream"
266
+ }
267
+ w.Header().Add("Content-Type", contentType)
268
+ w.Header().Add(
269
+ "Cache-Control",
270
+ fmt.Sprintf("public,max-age=%d", EXPIRATION_TIME),
271
+ )
272
+ w.Write(item.Value)
273
+ return
274
+ }
275
+ }
276
+ http.Error(w, "404 Not Found", http.StatusNotFound)
277
+ }
278
+
279
+ func post(w http.ResponseWriter, r *http.Request) {
280
+ result := make(map[string][]*FileInfo, 1)
281
+ result["files"] = handleUploads(r)
282
+ b, err := json.Marshal(result)
283
+ check(err)
284
+ if redirect := r.FormValue("redirect"); validateRedirect(r, redirect) {
285
+ if strings.Contains(redirect, "%s") {
286
+ redirect = fmt.Sprintf(
287
+ redirect,
288
+ escape(string(b)),
289
+ )
290
+ }
291
+ http.Redirect(w, r, redirect, http.StatusFound)
292
+ return
293
+ }
294
+ w.Header().Set("Cache-Control", "no-cache")
295
+ jsonType := "application/json"
296
+ if strings.Index(r.Header.Get("Accept"), jsonType) != -1 {
297
+ w.Header().Set("Content-Type", jsonType)
298
+ }
299
+ fmt.Fprintln(w, string(b))
300
+ }
301
+
302
+ func delete(w http.ResponseWriter, r *http.Request) {
303
+ key := extractKey(r)
304
+ parts := strings.Split(key, "/")
305
+ if len(parts) == 3 {
306
+ result := make(map[string]bool, 1)
307
+ context := appengine.NewContext(r)
308
+ err := memcache.Delete(context, key)
309
+ if err == nil {
310
+ result[key] = true
311
+ contentType, _ := url.QueryUnescape(parts[0])
312
+ if imageTypes.MatchString(contentType) {
313
+ thumbnailKey := key + thumbSuffix + filepath.Ext(parts[2])
314
+ err := memcache.Delete(context, thumbnailKey)
315
+ if err == nil {
316
+ result[thumbnailKey] = true
317
+ }
318
+ }
319
+ }
320
+ w.Header().Set("Content-Type", "application/json")
321
+ b, err := json.Marshal(result)
322
+ check(err)
323
+ fmt.Fprintln(w, string(b))
324
+ } else {
325
+ http.Error(w, "405 Method not allowed", http.StatusMethodNotAllowed)
326
+ }
327
+ }
328
+
329
+ func handle(w http.ResponseWriter, r *http.Request) {
330
+ params, err := url.ParseQuery(r.URL.RawQuery)
331
+ check(err)
332
+ w.Header().Add("Access-Control-Allow-Origin", "*")
333
+ w.Header().Add(
334
+ "Access-Control-Allow-Methods",
335
+ "OPTIONS, HEAD, GET, POST, DELETE",
336
+ )
337
+ w.Header().Add(
338
+ "Access-Control-Allow-Headers",
339
+ "Content-Type, Content-Range, Content-Disposition",
340
+ )
341
+ switch r.Method {
342
+ case "OPTIONS", "HEAD":
343
+ return
344
+ case "GET":
345
+ get(w, r)
346
+ case "POST":
347
+ if len(params["_method"]) > 0 && params["_method"][0] == "DELETE" {
348
+ delete(w, r)
349
+ } else {
350
+ post(w, r)
351
+ }
352
+ case "DELETE":
353
+ delete(w, r)
354
+ default:
355
+ http.Error(w, "501 Not Implemented", http.StatusNotImplemented)
356
+ }
357
+ }
358
+
359
+ func init() {
360
+ http.HandleFunc("/", handle)
361
+ }
@@ -0,0 +1,2 @@
1
+ User-agent: *
2
+ Disallow:
@@ -0,0 +1,17 @@
1
+ application: jquery-file-upload
2
+ version: 1
3
+ runtime: python27
4
+ api_version: 1
5
+ threadsafe: true
6
+
7
+ libraries:
8
+ - name: PIL
9
+ version: latest
10
+
11
+ handlers:
12
+ - url: /(favicon\.ico|robots\.txt)
13
+ static_files: static/\1
14
+ upload: static/(.*)
15
+ expiration: '1d'
16
+ - url: /.*
17
+ script: main.app