asset_host_core 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +138 -0
  3. data/Rakefile +11 -0
  4. data/app/assets/images/asset_host_core/alert-overlay.png +0 -0
  5. data/app/assets/images/asset_host_core/arrow-left.gif +0 -0
  6. data/app/assets/images/asset_host_core/arrow-right.gif +0 -0
  7. data/app/assets/images/asset_host_core/fallback-img-rect.png +0 -0
  8. data/app/assets/images/asset_host_core/videoplayer-play.png +0 -0
  9. data/app/assets/images/asset_host_core/x.png +0 -0
  10. data/app/assets/javascripts/asset_host_core/admin/assets.js.coffee +221 -0
  11. data/app/assets/javascripts/asset_host_core/application.js +20 -0
  12. data/app/assets/javascripts/asset_host_core/assetadmin.js.coffee +56 -0
  13. data/app/assets/javascripts/asset_host_core/assethost.js.coffee.erb +17 -0
  14. data/app/assets/javascripts/asset_host_core/browserui.js.coffee +139 -0
  15. data/app/assets/javascripts/asset_host_core/chooserui.js.coffee +381 -0
  16. data/app/assets/javascripts/asset_host_core/client.js.coffee +29 -0
  17. data/app/assets/javascripts/asset_host_core/clients/BrightcoveVideo.js.coffee +64 -0
  18. data/app/assets/javascripts/asset_host_core/clients/templates/brightcove_embed.jst.eco +18 -0
  19. data/app/assets/javascripts/asset_host_core/clients/templates/vimeo_embed.jst.eco +1 -0
  20. data/app/assets/javascripts/asset_host_core/clients/templates/youtube_embed.jst.eco +1 -0
  21. data/app/assets/javascripts/asset_host_core/clients/vimeo_video.js.coffee +21 -0
  22. data/app/assets/javascripts/asset_host_core/clients/youtube_video.js.coffee +21 -0
  23. data/app/assets/javascripts/asset_host_core/cmsplugin.js.coffee +235 -0
  24. data/app/assets/javascripts/asset_host_core/models.js.coffee +586 -0
  25. data/app/assets/javascripts/asset_host_core/railsCMS.js.coffee +141 -0
  26. data/app/assets/javascripts/asset_host_core/slideshow.js.coffee +428 -0
  27. data/app/assets/javascripts/asset_host_core/templates/after_upload_button.jst.eco +3 -0
  28. data/app/assets/javascripts/asset_host_core/templates/asset_drop_asset.jst.eco +4 -0
  29. data/app/assets/javascripts/asset_host_core/templates/asset_modal.jst.eco +13 -0
  30. data/app/assets/javascripts/asset_host_core/templates/asset_preview.jst.eco +35 -0
  31. data/app/assets/javascripts/asset_host_core/templates/asset_search.jst.eco +2 -0
  32. data/app/assets/javascripts/asset_host_core/templates/browser_asset.jst.eco +1 -0
  33. data/app/assets/javascripts/asset_host_core/templates/browser_asset_tip.jst.eco +3 -0
  34. data/app/assets/javascripts/asset_host_core/templates/edit_modal.jst.eco +40 -0
  35. data/app/assets/javascripts/asset_host_core/templates/import_help.jst.eco +59 -0
  36. data/app/assets/javascripts/asset_host_core/templates/pagination_link.jst.eco +1 -0
  37. data/app/assets/javascripts/asset_host_core/templates/pagination_links.jst.eco +13 -0
  38. data/app/assets/javascripts/asset_host_core/templates/queued_file.jst.eco +11 -0
  39. data/app/assets/javascripts/asset_host_core/templates/save_and_close_view.jst.eco +4 -0
  40. data/app/assets/javascripts/asset_host_core/templates/upload_all_button.jst.eco +4 -0
  41. data/app/assets/javascripts/asset_host_core/templates/url_input.jst.eco +8 -0
  42. data/app/assets/stylesheets/asset_host_core/application.css.scss +384 -0
  43. data/app/assets/stylesheets/asset_host_core/jquery-ui.css +105 -0
  44. data/app/assets/stylesheets/asset_host_core/public.css.scss +204 -0
  45. data/app/assets/stylesheets/asset_host_core/slidetest.css.scss +93 -0
  46. data/app/controllers/asset_host_core/admin/api_users_controller.rb +72 -0
  47. data/app/controllers/asset_host_core/admin/assets_controller.rb +140 -0
  48. data/app/controllers/asset_host_core/admin/base_controller.rb +36 -0
  49. data/app/controllers/asset_host_core/admin/home_controller.rb +13 -0
  50. data/app/controllers/asset_host_core/admin/outputs_controller.rb +55 -0
  51. data/app/controllers/asset_host_core/api/assets_controller.rb +110 -0
  52. data/app/controllers/asset_host_core/api/base_controller.rb +43 -0
  53. data/app/controllers/asset_host_core/api/outputs_controller.rb +33 -0
  54. data/app/controllers/asset_host_core/application_controller.rb +43 -0
  55. data/app/controllers/asset_host_core/public_controller.rb +104 -0
  56. data/app/models/asset_host_core/api_user.rb +44 -0
  57. data/app/models/asset_host_core/api_user_permission.rb +6 -0
  58. data/app/models/asset_host_core/asset.rb +265 -0
  59. data/app/models/asset_host_core/asset_output.rb +69 -0
  60. data/app/models/asset_host_core/brightcove_video.rb +20 -0
  61. data/app/models/asset_host_core/output.rb +52 -0
  62. data/app/models/asset_host_core/permission.rb +19 -0
  63. data/app/models/asset_host_core/video.rb +8 -0
  64. data/app/models/asset_host_core/vimeo_video.rb +17 -0
  65. data/app/models/asset_host_core/youtube_video.rb +17 -0
  66. data/app/views/asset_host_core/admin/api_users/_form_fields.html.erb +5 -0
  67. data/app/views/asset_host_core/admin/api_users/edit.html.erb +26 -0
  68. data/app/views/asset_host_core/admin/api_users/index.html.erb +31 -0
  69. data/app/views/asset_host_core/admin/api_users/new.html.erb +17 -0
  70. data/app/views/asset_host_core/admin/api_users/show.html.erb +23 -0
  71. data/app/views/asset_host_core/admin/assets/index.html.erb +19 -0
  72. data/app/views/asset_host_core/admin/assets/metadata.html.erb +24 -0
  73. data/app/views/asset_host_core/admin/assets/show.html.erb +86 -0
  74. data/app/views/asset_host_core/admin/home/chooser.html.erb +49 -0
  75. data/app/views/asset_host_core/admin/outputs/_form_fields.html.erb +5 -0
  76. data/app/views/asset_host_core/admin/outputs/edit.html.erb +26 -0
  77. data/app/views/asset_host_core/admin/outputs/index.html.erb +27 -0
  78. data/app/views/asset_host_core/admin/outputs/new.html.erb +13 -0
  79. data/app/views/asset_host_core/admin/outputs/show.html.erb +17 -0
  80. data/app/views/asset_host_core/shared/_footerjs.html.erb +3 -0
  81. data/app/views/asset_host_core/shared/_navbar.html.erb +28 -0
  82. data/app/views/kaminari/_first_page.html.erb +3 -0
  83. data/app/views/kaminari/_gap.html.erb +3 -0
  84. data/app/views/kaminari/_last_page.html.erb +3 -0
  85. data/app/views/kaminari/_next_page.html.erb +3 -0
  86. data/app/views/kaminari/_page.html.erb +3 -0
  87. data/app/views/kaminari/_paginator.html.erb +17 -0
  88. data/app/views/kaminari/_prev_page.html.erb +3 -0
  89. data/app/views/layouts/asset_host_core/application.html.erb +54 -0
  90. data/app/views/layouts/asset_host_core/full_width.html.erb +32 -0
  91. data/app/views/layouts/asset_host_core/minimal.html.erb +45 -0
  92. data/config/initializers/simple_form.rb +142 -0
  93. data/config/initializers/simple_form_bootstrap.rb +45 -0
  94. data/config/locales/simple_form.en.yml +26 -0
  95. data/config/routes.rb +49 -0
  96. data/lib/asset_host_core.rb +38 -0
  97. data/lib/asset_host_core/config.rb +39 -0
  98. data/lib/asset_host_core/engine.rb +94 -0
  99. data/lib/asset_host_core/loaders.rb +34 -0
  100. data/lib/asset_host_core/loaders/asset_host.rb +30 -0
  101. data/lib/asset_host_core/loaders/base.rb +22 -0
  102. data/lib/asset_host_core/loaders/brightcove.rb +67 -0
  103. data/lib/asset_host_core/loaders/flickr.rb +114 -0
  104. data/lib/asset_host_core/loaders/url.rb +59 -0
  105. data/lib/asset_host_core/loaders/vimeo.rb +76 -0
  106. data/lib/asset_host_core/loaders/youtube.rb +90 -0
  107. data/lib/asset_host_core/model_methods.rb +61 -0
  108. data/lib/asset_host_core/paperclip.rb +4 -0
  109. data/lib/asset_host_core/paperclip/asset_thumbnail.rb +92 -0
  110. data/lib/asset_host_core/paperclip/attachment.rb +206 -0
  111. data/lib/asset_host_core/paperclip/trimmer.rb +33 -0
  112. data/lib/asset_host_core/resque_job.rb +13 -0
  113. data/lib/asset_host_core/version.rb +3 -0
  114. data/lib/tasks/asset_host_core_tasks.rake +4 -0
  115. data/spec/controllers/admin/api_users_controller_spec.rb +21 -0
  116. data/spec/controllers/admin/assets_controller_spec.rb +59 -0
  117. data/spec/controllers/admin/home_controller_spec.rb +4 -0
  118. data/spec/controllers/admin/outputs_controller_spec.rb +4 -0
  119. data/spec/controllers/api/assets_controller_spec.rb +133 -0
  120. data/spec/controllers/api/outputs_controller_spec.rb +51 -0
  121. data/spec/controllers/public_controller_spec.rb +4 -0
  122. data/spec/factories.rb +39 -0
  123. data/spec/features/api_users_spec.rb +78 -0
  124. data/spec/fixtures/api/brightcove/video.json +137 -0
  125. data/spec/fixtures/api/flickr/photos_getInfo.json +78 -0
  126. data/spec/fixtures/api/flickr/photos_getSizes.json +82 -0
  127. data/spec/fixtures/api/flickr/photos_licenses_getInfo.json +52 -0
  128. data/spec/fixtures/api/vimeo/video.json +28 -0
  129. data/spec/fixtures/api/youtube/discovery.json +5190 -0
  130. data/spec/fixtures/api/youtube/video.json +44 -0
  131. data/spec/fixtures/images/chipmunk.jpg +0 -0
  132. data/spec/fixtures/images/dude.jpg +0 -0
  133. data/spec/fixtures/images/ernie.jpg +0 -0
  134. data/spec/fixtures/images/fry.png +0 -0
  135. data/spec/fixtures/images/hat.jpg +0 -0
  136. data/spec/fixtures/images/spongebob.png +0 -0
  137. data/spec/fixtures/images/stars.jpg +0 -0
  138. data/spec/internal/app/controllers/application_controller.rb +16 -0
  139. data/spec/internal/app/controllers/sessions_controller.rb +24 -0
  140. data/spec/internal/app/models/user.rb +10 -0
  141. data/spec/internal/app/views/sessions/new.html.erb +14 -0
  142. data/spec/internal/config/database.yml +3 -0
  143. data/spec/internal/config/initializers/assethost_config.rb +57 -0
  144. data/spec/internal/config/routes.rb +7 -0
  145. data/spec/internal/db/combustion_test.sqlite +0 -0
  146. data/spec/internal/db/schema.rb +106 -0
  147. data/spec/internal/log/test.log +14769 -0
  148. data/spec/internal/public/favicon.ico +0 -0
  149. data/spec/internal/public/images/1_27f7745237849975ca90591c1fba5934_original. +0 -0
  150. data/spec/internal/public/images/1_7d33319deca787d5bb3f62ff06563ad2_original. +0 -0
  151. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original. +0 -0
  152. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.jpg +0 -0
  153. data/spec/internal/public/images/1_b6d48c8b1286104ce76649731e09645f_original.txt +0 -0
  154. data/spec/internal/public/images/1_e179cbd27e07cb55042d0db36cdac095_original. +0 -0
  155. data/spec/internal/public/images/1_e669edd3dfd74be66fc38416e82e3a37_original. +0 -0
  156. data/spec/lib/asset_host_core/loaders/asset_host_spec.rb +33 -0
  157. data/spec/lib/asset_host_core/loaders/brightcove_spec.rb +51 -0
  158. data/spec/lib/asset_host_core/loaders/flickr_spec.rb +72 -0
  159. data/spec/lib/asset_host_core/loaders/url_spec.rb +42 -0
  160. data/spec/lib/asset_host_core/loaders/vimeo_spec.rb +51 -0
  161. data/spec/lib/asset_host_core/loaders/youtube_spec.rb +73 -0
  162. data/spec/lib/asset_host_core/loaders_spec.rb +4 -0
  163. data/spec/lib/asset_host_core/model_methods_spec.rb +4 -0
  164. data/spec/lib/asset_host_core/paperclip/asset_thumbnail_spec.rb +4 -0
  165. data/spec/lib/asset_host_core/paperclip/attachment_spec.rb +4 -0
  166. data/spec/lib/asset_host_core/resque_job_spec.rb +4 -0
  167. data/spec/lib/asset_host_core_spec.rb +4 -0
  168. data/spec/models/api_user_spec.rb +58 -0
  169. data/spec/models/asset_output_spec.rb +4 -0
  170. data/spec/models/asset_spec.rb +4 -0
  171. data/spec/models/output_spec.rb +4 -0
  172. data/spec/models/permission_spec.rb +4 -0
  173. data/spec/spec_helper.rb +30 -0
  174. data/spec/support/fixture_loader.rb +9 -0
  175. data/spec/support/param_helper.rb +14 -0
  176. data/spec/support/permission_matcher.rb +17 -0
  177. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  178. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  179. data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  180. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  181. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  182. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  183. data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  184. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  185. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  186. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  187. data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  188. data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  189. data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  190. data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  191. data/vendor/assets/javascripts/backbone.js +1158 -0
  192. data/vendor/assets/javascripts/backbone.modelbinding.js +475 -0
  193. data/vendor/assets/javascripts/exif.js +695 -0
  194. data/vendor/assets/javascripts/jquery-ui.js +5614 -0
  195. data/vendor/assets/javascripts/simplemodal.js +698 -0
  196. data/vendor/assets/javascripts/spin.jquery.js +81 -0
  197. data/vendor/assets/javascripts/spin.min.js +1 -0
  198. data/vendor/assets/javascripts/underscore.min.js +1 -0
  199. metadata +658 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,138 @@
1
+ # AssetHost
2
+
3
+ [![Build Status](https://travis-ci.org/SCPR/AssetHost.png)](https://travis-ci.org/SCPR/AssetHost)
4
+
5
+ AssetHost is an attempt to create a one-stop-shop for hosting and linking
6
+ to media assets that are intended for inclusion in news stories. The goal is
7
+ to create a hub that multiple frontend CMS systems can hook into, querying
8
+ images, videos and documents from one source and enabling the easier
9
+ interchange of data.
10
+
11
+ # Philosophy
12
+
13
+ AssetHost is built around the idea that all web media assets need to
14
+ have a static visual fallback, either to support limited-functionality
15
+ devices or to support rendering of rich media assets in contexts where
16
+ a rich implementation isn't desired.
17
+
18
+ AssetHost is intended to run as two pieces: a backend asset server and
19
+ lightweight frontend plugins that attach to the CMS system. The pieces
20
+ should speak to each other using a secure API.
21
+
22
+
23
+ ### Backend Engine
24
+
25
+ This repository provides the AssetHostCore engine, which can be run either
26
+ on the root of a standalone application (perhaps powering multiple frontend
27
+ applications) or at a namespace in an existing application.
28
+
29
+ The backend server provides the primary UI for uploading, managing, and
30
+ serving assets. It also provides an API endpoint that can be accessed either
31
+ by the local application (this is how much of the admin works) or by other
32
+ applications or plugins.
33
+
34
+ A sample host application can be found at <http://github.com/SCPR/AssetHostApp>
35
+
36
+
37
+ ### Plugins for Other Applications
38
+
39
+ AssetHost provides an API and a Chooser UI that can be integrated into
40
+ your application, allowing you to integrate the system in a minimal amount
41
+ of code.
42
+
43
+ _TODO: More documentation on CMS interaction. External Rails example. Django example._
44
+
45
+ ### Integrating with the AssetHost engine
46
+
47
+ To integrate with a locally-installed AssetHostCore engine, simply make your
48
+ mapping data model belong to AssetHostCore::Asset.
49
+
50
+ _TODO: More documentation on creating content/asset models._
51
+
52
+
53
+ ### Workflow
54
+
55
+ 1. Photographer / Author / Editor goes to AssetHost and uploads or imports
56
+ a media asset.
57
+
58
+ 2. Author / Editor goes to their frontend CMS and uses the plugin UI to
59
+ select the asset they want to attach to their content (which might be a
60
+ story, a blog post, etc).
61
+
62
+ 3. CMS plugin uses API to query AssetHost and retrieve presentation code
63
+ for the asset.
64
+
65
+ 4. The CMS should call new AssetHost.Client() to put in place the handler
66
+ for rich assets.
67
+
68
+ 4. The CMS should display the image asset. If it contains tags for a
69
+ rich asset, the Client library will catch it and put in place the
70
+ appropriate handling.
71
+
72
+ 5. AssetHost will return a 302 Found to the rendered image asset if it
73
+ exists, or render it on-the-fly if it does not yet exist.
74
+
75
+ # Rich Media Support
76
+
77
+ Rich media assets are delivered as specially-tagged img tags, and are
78
+ replaced on the client-side via an AssetHost.Client plugin.
79
+
80
+
81
+ ### Brightcove Video
82
+
83
+ Brightcove videos can be imported as assets and used to place videos into
84
+ image display contexts. The video is delivered as an img tag, and the
85
+ AssetHost.Client library will see the tag and call the
86
+ AssetHost.Client.Brightcove plugin. The plugin will replace the asset with
87
+ the video.
88
+
89
+ Brightcove assets can be imported via a key in the URL Input field. See
90
+ Importing Help for more.
91
+
92
+
93
+ # Setup
94
+
95
+ TODO: Setup generators for migrations
96
+
97
+ See `spec/internal/db/schema.rb` for the tables you'll need to setup:
98
+
99
+ * asset_host_core_outputs
100
+
101
+
102
+ # Image Storage
103
+
104
+ AssetHost intends to support any image storage supported by
105
+ [Paperclip](https://github.com/thoughtbot/paperclip), the underlying gem
106
+ responsible for adding image file functionality to our Asset model.
107
+
108
+ Currently, Paperclip supports local filesystem storage and storage on
109
+ Amazon's S3.
110
+
111
+
112
+ # External Requirements
113
+
114
+ ### Async Workers via Redis
115
+
116
+ The AssetHost server uses Redis (via the Resque gem) to coordinate async
117
+ processing of images. Configure for your Redis setup in config/resque.yml.
118
+
119
+ ### Image Processing via ImageMagick
120
+
121
+ AssetHost, via Paperclip, does image processing using ImageMagick. If
122
+ needed, make sure to specify Paperclip.options[:command_path] in your config.
123
+
124
+ ### Text Search via Sphinx
125
+
126
+ Searches are done via Sphinx, using the Thinking Sphinx gem. Set up your
127
+ configuration in config/sphinx.yml, and make sure you have an external trigger
128
+ for indexing (cron, etc).
129
+
130
+
131
+ # Credits
132
+
133
+ AssetHost is being developed to serve the media asset needs of [KPCC](http://kpcc.org)
134
+ and Southern California Public Radio, a member-supported public radio network that
135
+ serves Los Angeles and Orange County on 89.3, the Inland Empire on 89.1, and the
136
+ Coachella Valley on 90.3.
137
+
138
+ AssetHost development is led by Eric Richardson (erichardson@kpcc.org).
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ RAKED = true
3
+
4
+ require 'bundler/setup'
5
+ require 'resque/tasks'
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ task :default => :spec
10
+
11
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,221 @@
1
+ class window.AssetHostUpload
2
+ DefaultOptions:
3
+ {
4
+ dropEl: "#filedrop",
5
+ url: "",
6
+ posturl: "",
7
+ readyClass: "ready",
8
+ uploadClass: "uploading",
9
+ errorClass: "error",
10
+ pendingClass: "pending",
11
+ completeClass: "complete",
12
+ token: '',
13
+ emptyText: "Drop File(s) Here",
14
+ afterText: "Go to Metadata Entry",
15
+ allowMultiple: true
16
+ }
17
+
18
+ #----------
19
+
20
+ constructor: (options={}) ->
21
+ @options = _.defaults options, @DefaultOptions
22
+
23
+ @drop = $(@options.dropEl)
24
+
25
+ @files = []
26
+ @_ids = []
27
+ @_uploading = []
28
+
29
+ @fileUL = $ "<ul/>"
30
+ $(@drop).append @fileUL
31
+
32
+ @_emptyEl = $ "<li/>", { class: "help", text: this.options.emptyText }
33
+ $(@fileUL).append @_emptyEl
34
+
35
+ @uploadButton = $ "<p/>", { class: "ahUp_upbutton", text: "Upload File(s)" }
36
+ $(@drop).append @uploadButton
37
+ $(@uploadButton).hide()
38
+ $(@uploadButton).click (evt) => this._uploadFiles(evt)
39
+
40
+ $(@drop).bind "dragenter", (evt) => @_dragenter(evt)
41
+ $(@drop).bind "dragover", (evt) => @_dragover(evt)
42
+ $(@drop).bind "drop", (evt) => @_drop(evt)
43
+
44
+ #----------
45
+
46
+ _dragenter: (evt) ->
47
+ evt.stopPropagation()
48
+ evt.preventDefault()
49
+
50
+ false
51
+
52
+ #----------
53
+
54
+ _dragover: (evt) ->
55
+ evt.stopPropagation()
56
+ evt.preventDefault()
57
+ false
58
+
59
+ #----------
60
+
61
+ _drop: (evt) ->
62
+ evt = evt.originalEvent
63
+
64
+ evt.stopPropagation()
65
+ evt.preventDefault()
66
+
67
+ # do something with this info
68
+ for f in evt.dataTransfer.files
69
+ @_addFileToList(f)
70
+
71
+ false
72
+
73
+ #----------
74
+
75
+ _addFileToList: (f) ->
76
+ if !this.options.allowMultiple && this.files.length
77
+ return false
78
+
79
+ if this._uploading.length
80
+ return false
81
+
82
+
83
+ li = $ "<li/>", { text: "#{f.name} (#{@readableFileSize f.size})" }
84
+
85
+ obj = {f:f,li:li,x:null}
86
+
87
+ x = $("<span/>", { text: "x" })
88
+ .bind "click", `_.bind(this._removeFile, this, obj, li)`
89
+ li.append x
90
+
91
+ obj.x = x
92
+
93
+ $(@fileUL).append li
94
+
95
+ @files.push obj
96
+
97
+ @_setFileState obj, this.options.readyClass
98
+
99
+ @_updateUploadButton()
100
+
101
+ true
102
+
103
+ #----------
104
+
105
+ _removeFile: (obj,li,evt) ->
106
+ if @_uploading.length
107
+ return false
108
+
109
+ $(li).detach()
110
+
111
+ @files = _(@files).without obj
112
+
113
+ @_updateUploadButton()
114
+
115
+ #----------
116
+
117
+ _updateUploadButton: ->
118
+ if @files.length then $(@uploadButton).show() else $(@uploadButton).hide()
119
+
120
+ #----------
121
+
122
+ _uploadFiles: (evt) ->
123
+ # disable drag/drop UI
124
+ @uploadButton.hide()
125
+
126
+ # upload files
127
+ for obj in @files
128
+ @_uploading.push(obj)
129
+
130
+ xhr = new XMLHttpRequest();
131
+
132
+ upload = xhr.upload;
133
+
134
+ $(upload).bind "progress", `_.bind(this._onUploadProgress,this,obj)`
135
+ $(upload).bind "load", `_.bind(this._onUploadComplete,this,obj)`
136
+ $(upload).bind "error", `_.bind(this._onUploadError,this,obj)`
137
+
138
+ xhr.onreadystatechange = `_.bind(this._onUploadState,this,xhr,obj)`
139
+
140
+ xhr.open('POST',this.options.url, true);
141
+ xhr.setRequestHeader('X_FILE_NAME', obj.f.fileName)
142
+ xhr.setRequestHeader('CONTENT_TYPE', obj.f.type)
143
+ xhr.setRequestHeader('HTTP_X_FILE_UPLOAD','true')
144
+ xhr.send(obj.f);
145
+
146
+ @_setFileState obj, this.options.uploadClass
147
+
148
+ #----------
149
+
150
+ _onUploadProgress: (obj,evt) ->
151
+ evt = evt.originalEvent
152
+
153
+ if evt.lengthComputable
154
+ percent = Math.floor( evt.loaded / evt.total * 100 )
155
+ $(obj.x).text "(#{percent}%)"
156
+ else
157
+ $(obj.x).text "(#{evt.loaded}%)"
158
+
159
+ #----------
160
+
161
+ _onUploadComplete: (obj,evt) ->
162
+ # turn our li green or something
163
+ @_setFileState obj, @options.pendingClass
164
+
165
+ #----------
166
+
167
+ _onUploadError: (obj,evt) ->
168
+ # turn our li red?
169
+ @_uploading = _(@_uploading).without obj
170
+ @_setFileState obj, this.options.errorClass
171
+
172
+ #----------
173
+
174
+ _onUploadState: (req,obj,evt) ->
175
+ # look for a response asset ID
176
+ if req.readyState == 4
177
+ if req.status == 200
178
+ @_setFileState obj, @options.completeClass
179
+ $(obj.li).addClass @options.completeClass
180
+
181
+ if req.responseText != "ERROR"
182
+ json = $.parseJSON req.responseText
183
+ @_ids.push json
184
+
185
+ @_uploading = _(@_uploading).without obj
186
+
187
+ if !@_uploading.length
188
+ @_uploadingComplete()
189
+ else
190
+ # error
191
+
192
+ #----------
193
+
194
+ _uploadingComplete: ->
195
+ link = $("<li/>").append(
196
+ $ "<a/>", { href: @options.posturl+"?ids="+_(@_ids).map( (k) -> k.id ).join(","), text: @options.afterText }
197
+ )
198
+
199
+ $(@drop).append link
200
+
201
+ #----------
202
+
203
+ _setFileState: (obj,classname) ->
204
+ # remove existing class(es)
205
+
206
+ for c in (obj.li.className || "").split(" ")
207
+ $(obj.li).removeClass(c)
208
+
209
+ $(obj.li).addClass classname
210
+
211
+ #----------
212
+
213
+ readableFileSize: (size) ->
214
+ units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
215
+ i = 0;
216
+
217
+ while size >= 1024
218
+ size /= 1024
219
+ ++i
220
+
221
+ size.toFixed(1) + ' ' + units[i];
@@ -0,0 +1,20 @@
1
+ //= require ./assethost
2
+ //= require jquery
3
+ //= require jquery_ujs
4
+ //= require jquery-ui
5
+ //= require underscore.min
6
+ //= require backbone
7
+ //= require exif
8
+
9
+ //= require backbone.modelbinding
10
+
11
+ //= require spin.min
12
+ //= require spin.jquery
13
+
14
+ //= require bootstrap-transition
15
+ //= require bootstrap-tooltip
16
+ //= require bootstrap-modal
17
+
18
+ //= require_tree ./templates
19
+
20
+ //= require_tree .
@@ -0,0 +1,56 @@
1
+ class AssetHost.AssetAdmin
2
+ DefaultOptions:
3
+ el: ""
4
+ replace: ''
5
+ replacePath: ''
6
+
7
+ constructor: (asset,options = {}) ->
8
+ @options = _.defaults options, @DefaultOptions
9
+
10
+ @asset = new AssetHost.Models.Asset asset
11
+ @preview = new AssetAdmin.PreviewView model: @asset
12
+ @form = new AssetAdmin.FormView model: @asset
13
+
14
+ $( @options.el ).html @preview.el
15
+
16
+ if @options.replace
17
+ # set up replace image uploader
18
+ @chooser = new AssetHost.ChooserUI
19
+ dropEl: @options.replace
20
+ assets: false
21
+ uploads: true
22
+ limit: 1
23
+ uploadPath: @options.replacePath
24
+ saveButton: false
25
+ afterUploadText: "Refresh",
26
+ afterUploadURL: window.location
27
+
28
+ #----------
29
+
30
+ class @FormView extends Backbone.View
31
+ el: "#editform"
32
+
33
+ #----------
34
+
35
+ class @PreviewView extends Backbone.View
36
+ template: JST['asset_host_core/templates/asset_preview']
37
+ events:
38
+ 'click .asset_sizes li': '_sizeClick'
39
+
40
+ initialize: ->
41
+ @size = AssetHost.SIZES.detail
42
+ @render()
43
+
44
+ _sizeClick: (evt) ->
45
+ size = $(evt.currentTarget).attr("data-size")
46
+
47
+ if size != @size
48
+ @size = size
49
+ @render()
50
+
51
+ render: ->
52
+ $(@el).html @template
53
+ asset: @model.toJSON()
54
+ tag: @size
55
+
56
+ @