asset_host_core 2.0.0.beta

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 (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,26 @@
1
+ en:
2
+ simple_form:
3
+ "yes": 'Yes'
4
+ "no": 'No'
5
+ required:
6
+ text: 'required'
7
+ mark: '*'
8
+ # You can uncomment the line below if you need to overwrite the whole required html.
9
+ # When using html, text and mark won't be used.
10
+ # html: '<abbr title="required">*</abbr>'
11
+ error_notification:
12
+ default_message: "Please review the problems below:"
13
+ # Labels and hints examples
14
+ # labels:
15
+ # defaults:
16
+ # password: 'Password'
17
+ # user:
18
+ # new:
19
+ # email: 'E-mail to sign in.'
20
+ # edit:
21
+ # email: 'E-mail.'
22
+ # hints:
23
+ # defaults:
24
+ # username: 'User name to sign in.'
25
+ # password: 'No special characters, please.'
26
+
@@ -0,0 +1,49 @@
1
+ AssetHostCore::Engine.routes.draw do
2
+ match '/i/:aprint/:id-:style.:extension', :to => 'public#image', :as => :image, :constraints => { :id => /\d+/, :style => /[^\.]+/}
3
+
4
+
5
+ namespace :api do
6
+ resources :assets, :id => /\d+/, defaults: { format: :json } do
7
+ member do
8
+ get 'r/:context/(:scheme)', :action => :render
9
+ get 'tag/:style', :action => :tag
10
+ end
11
+ end
12
+
13
+ resources :outputs, defaults: { format: :json }
14
+ end
15
+
16
+
17
+
18
+ namespace :a, :module => "admin" do
19
+ resources :assets, :id => /\d+/ do
20
+ collection do
21
+ get '/search(/:q)', action: 'search', as: "search"
22
+ get '/p/(:page)', action: 'index'
23
+ get '/p/:page/:q', action: 'search'
24
+
25
+ post :upload
26
+ get :metadata
27
+ put :metadata, :action => "update_metadata"
28
+ end
29
+
30
+ member do
31
+ get :preview
32
+ post :replace
33
+ end
34
+ end
35
+
36
+ resources :outputs
37
+
38
+ resources :api_users do
39
+ put 'reset_token', on: :member, as: :reset_token
40
+ end
41
+
42
+ match 'chooser', :to => "home#chooser", :as => 'chooser'
43
+
44
+ root :to => "assets#index"
45
+ end
46
+
47
+
48
+ root :to => "public#home"
49
+ end
@@ -0,0 +1,38 @@
1
+ require "asset_host_core/engine"
2
+ require "asset_host_core/paperclip"
3
+ require "asset_host_core/config"
4
+ require "asset_host_core/resque_job"
5
+ require "asset_host_core/model_methods"
6
+ require 'google/api_client'
7
+ require 'open-uri'
8
+ require 'faraday_middleware'
9
+ require "asset_host_core/loaders"
10
+
11
+ module AssetHostCore
12
+ class << self
13
+ # Pass url to our loader plugins and see if anyone bites. Our first
14
+ # loader should always be the loader that handles our own API urls
15
+ # for existing assets.
16
+ def as_asset(url)
17
+ AssetHostCore::Loaders.load(url)
18
+ end
19
+
20
+ #----------------
21
+
22
+ def configure
23
+ yield config
24
+ end
25
+
26
+ #----------------
27
+
28
+ def config
29
+ @config ||= AssetHostCore::Config.new
30
+ end
31
+
32
+ def hooks(&block)
33
+ block.call(AssetHostCore::Config)
34
+ end
35
+ end
36
+ end
37
+
38
+ ActiveRecord::Base.send(:include, AssetHostCore::ModelMethods)
@@ -0,0 +1,39 @@
1
+ module AssetHostCore
2
+ class Config
3
+ class << self
4
+ def current_user_method(&blk)
5
+ @current_user = blk if blk
6
+ @current_user
7
+ end
8
+
9
+ #----------
10
+
11
+ def sign_out_path(&blk)
12
+ @sign_out = blk if blk
13
+ @sign_out
14
+ end
15
+
16
+ #----------
17
+
18
+ def authentication_method(&blk)
19
+ @authentication = blk if blk
20
+ @authentication
21
+ end
22
+
23
+ #----------
24
+
25
+ def api_authentication_method(&blk)
26
+ @api_authentication = blk if blk
27
+ @api_authentication
28
+ end
29
+ end
30
+
31
+
32
+ attr_accessor :flickr_api_key,
33
+ :brightcove_api_key,
34
+ :google_api_key,
35
+ :thumb_size,
36
+ :modal_size,
37
+ :detail_size
38
+ end
39
+ end
@@ -0,0 +1,94 @@
1
+ require 'rails'
2
+ require 'rake' # I don't know why, please don't ask
3
+ require 'resque'
4
+ require 'thinking_sphinx'
5
+ require 'paperclip'
6
+
7
+ require 'coffee-rails'
8
+ require 'sass-rails'
9
+ require 'eco'
10
+ require 'bootstrap-sass'
11
+
12
+ require 'simple_form'
13
+ require 'kaminari'
14
+
15
+
16
+ module AssetHostCore
17
+ class Engine < ::Rails::Engine
18
+ @@mpath = nil
19
+ @@redis_pubsub = nil
20
+
21
+ isolate_namespace AssetHostCore
22
+
23
+ # initialize our config hash
24
+ config.assethost = ActiveSupport::OrderedOptions.new
25
+
26
+ # -- post-initialization setup -- #
27
+
28
+ config.after_initialize do
29
+ # work around an issue where TS isn't seeing model directories if Rails hasn't appended the trailing slash
30
+ ::ThinkingSphinx::Configuration.instance.model_directories << File.expand_path("../../../app/models",__FILE__) + "/"
31
+
32
+ # set our resque job's queue
33
+ AssetHostCore::ResqueJob.instance_variable_set :@queue, Rails.application.config.assethost.resque_queue
34
+ end
35
+
36
+ initializer 'asset_host_core.register_processor' do
37
+ Paperclip.configure do |c|
38
+ # Since this isn't in the standard location that Paperclip
39
+ # looks for it (lib/paperclip_processors), we should just
40
+ # register is manually to be safe.
41
+ c.register_processor :asset_thumbnail, Paperclip::AssetThumbnail
42
+ end
43
+ end
44
+
45
+ # add resque's rake tasks
46
+ rake_tasks do
47
+ require "resque/tasks"
48
+ end
49
+
50
+ #----------
51
+
52
+ def self.mounted_path
53
+ if @@mpath
54
+ return @@mpath.spec.to_s == '/' ? '' : @@mpath.spec.to_s
55
+ end
56
+
57
+ # -- find our path -- #
58
+
59
+ route = Rails.application.routes.routes.detect do |route|
60
+ route.app == self
61
+ end
62
+
63
+ if route
64
+ @@mpath = route.path
65
+ end
66
+
67
+ return @@mpath.spec.to_s == '/' ? '' : @@mpath.spec.to_s
68
+ end
69
+
70
+ #----------
71
+
72
+ def self.redis_pubsub
73
+ if Rails.application.config.assethost.redis_pubsub && Rails.application.config.assethost.redis_pubsub.is_a?(Hash)
74
+ if @@redis_pubsub
75
+ return @@redis_pubsub
76
+ end
77
+
78
+ return @@redis_pubsub ||= Redis.new(Rails.application.config.assethost.redis_pubsub[:server])
79
+ else
80
+ return false
81
+ end
82
+ end
83
+
84
+ #----------
85
+
86
+ def self.redis_publish(data)
87
+ if r = self.redis_pubsub
88
+ return r.publish(Rails.application.config.assethost.redis_pubsub[:key]||"AssetHost",data.to_json)
89
+ else
90
+ return false
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ require "asset_host_core/loaders/base"
2
+ require "asset_host_core/loaders/asset_host"
3
+ require "asset_host_core/loaders/youtube"
4
+ require "asset_host_core/loaders/vimeo"
5
+ require "asset_host_core/loaders/flickr"
6
+ require "asset_host_core/loaders/brightcove"
7
+ require "asset_host_core/loaders/url"
8
+
9
+ module AssetHostCore
10
+ module Loaders
11
+
12
+ MODULES = [
13
+ AssetHost,
14
+ YouTube,
15
+ Vimeo,
16
+ Flickr,
17
+ Brightcove,
18
+ URL # This needs to be last, to act as a last-resort.
19
+ ]
20
+
21
+ class << self
22
+ def load(url)
23
+ loader = nil
24
+ MODULES.find { |klass| loader = klass.build_from_url(url) }
25
+ loader.try(:load)
26
+ end
27
+
28
+
29
+ def classes
30
+ puts "Classes: " + MODULES.to_s
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ module AssetHostCore
2
+ module Loaders
3
+ class AssetHost < Base
4
+ SOURCE = "AssetHost"
5
+
6
+ def self.build_from_url(url)
7
+ assethost_root = "#{Rails.application.config.assethost.server}#{AssetHostCore::Engine.mounted_path}"
8
+
9
+ matches = [
10
+ %r{#{assethost_root}\/i\/[^\/]+\/(?<id>\d+)-},
11
+ %r{#{assethost_root}\/api\/assets\/(?<id>\d+)}
12
+ ]
13
+
14
+ match = nil
15
+
16
+ if matches.find { |m| match = url.match(m) }
17
+ self.new(url: url, id: match[:id])
18
+ else
19
+ nil
20
+ end
21
+ end
22
+
23
+ #--------------
24
+
25
+ def load
26
+ AssetHostCore::Asset.find_by_id(@id)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ module AssetHostCore
2
+ module Loaders
3
+ class Base
4
+ attr_accessor :title,
5
+ :owner,
6
+ :description,
7
+ :url,
8
+ :created,
9
+ :file,
10
+ :source,
11
+ :id
12
+
13
+ #------------------
14
+
15
+ def initialize(attributes={})
16
+ @id = attributes[:id]
17
+ @url = attributes[:url]
18
+ @source = self.class::SOURCE
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,67 @@
1
+ require 'mime/types'
2
+ require 'brightcove-api'
3
+
4
+ module AssetHostCore
5
+ module Loaders
6
+ class Brightcove < Base
7
+ SOURCE = "Brightcove"
8
+
9
+ # Since brightcove videos don't have canoncial URL's,
10
+ # we have to make-up a way to import them
11
+ def self.build_from_url(url)
12
+ return nil if AssetHostCore.config.brightcove_api_key.blank?
13
+
14
+ url.match(/brightcove:(?<id>\d+)/) do |m|
15
+ self.new(url: nil, id: m[:id])
16
+ end
17
+ end
18
+
19
+ #----------
20
+
21
+ # Brightcove videos don't have URL's
22
+ def load
23
+ brightcove = ::Brightcove::API.new(AssetHostCore.config.brightcove_api_key)
24
+
25
+ # get our video info
26
+ response = brightcove.get("find_video_by_id", { video_id: @id }).parsed_response
27
+
28
+ native = AssetHostCore::BrightcoveVideo.create(
29
+ :videoid => response['id'],
30
+ :length => response['length']
31
+ )
32
+
33
+
34
+ asset = AssetHostCore::Asset.new(
35
+ :title => response["name"],
36
+ :caption => response["shortDescription"],
37
+ :owner => "KPCC",
38
+ :image_taken => DateTime.strptime(response["publishedDate"],"%Q"),
39
+ :url => nil,
40
+ :notes => "Imported from Brightcove: #{@id}",
41
+ :image => image_file(response['videoStillURL']),
42
+ :native => native
43
+ )
44
+
45
+
46
+ asset.save!
47
+ asset
48
+ end
49
+
50
+
51
+ #----------
52
+
53
+ private
54
+
55
+ def image_file(url)
56
+ @image_file ||= begin
57
+ response = open(url)
58
+
59
+ tempfile = Tempfile.new('ah-brightcove', encoding: "ascii-8bit")
60
+ tempfile.write response.read
61
+
62
+ tempfile
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,114 @@
1
+ require 'net/http'
2
+ require 'cgi'
3
+ require 'mime/types'
4
+
5
+ module AssetHostCore
6
+ module Loaders
7
+ class Flickr < Base
8
+ SOURCE = "Flickr"
9
+
10
+ def self.build_from_url(url)
11
+ return nil if AssetHostCore.config.flickr_api_key.blank?
12
+
13
+ matches = [
14
+ %r{flickr\.com/photos/[\w@]+/(?<id>\d+)},
15
+ %r{staticflickr\.com/\d+/(?<id>\d+)_[\w\d]+}
16
+ ]
17
+
18
+ match = nil
19
+
20
+ if matches.find { |m| match = url.match(m) }
21
+ self.new(url: url, id: match[:id])
22
+ else
23
+ nil
24
+ end
25
+ end
26
+
27
+ #----------
28
+
29
+ def load
30
+ return nil if AssetHostCore.config.flickr_api_key.blank?
31
+
32
+ flickr = MiniFlickr.new
33
+
34
+ # we're going to try and go get it from flickr
35
+ photo = flickr.call('flickr.photos.getInfo', photo_id: @id)["photo"]
36
+ return nil if !photo
37
+
38
+ sizes = flickr.call('flickr.photos.getSizes', photo_id: @id)["sizes"]["size"]
39
+ licenses = flickr.call('flickr.photos.licenses.getInfo')
40
+
41
+ # Load the image first so that the image EXIF data doesn't
42
+ # override the data from the Flickr API.
43
+ asset = AssetHostCore::Asset.new(
44
+ :image => image_file(sizes[-1]["source"]),
45
+ :title => photo["title"]["_content"],
46
+ :caption => photo["description"]["_content"],
47
+ :owner => photo['owner']['realname'] || photo['owner']["username"],
48
+ :image_taken => photo["dates"]["taken"],
49
+ :url => photo['urls']['url'][0]['_content']
50
+ )
51
+
52
+ # look up licenses
53
+ if license = licenses["licenses"]["license"].find { |l| l['id'] == photo['license'] }
54
+ asset.notes = [ license['name'], license['url'] ].join(" : ")
55
+ end
56
+
57
+ # save Asset
58
+ asset.save!
59
+ asset
60
+ end
61
+
62
+
63
+ #----------
64
+
65
+ private
66
+
67
+ def image_file(url)
68
+ @image_file ||= begin
69
+ response = open(url)
70
+
71
+ tempfile = Tempfile.new('ah-flickr', encoding: "ascii-8bit")
72
+ tempfile.write response.read
73
+
74
+ tempfile
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+ class MiniFlickr
81
+ attr :api_key
82
+
83
+ def user
84
+ USERID
85
+ end
86
+
87
+ def call(method, params = {})
88
+ parameters = params.dup
89
+
90
+ parameters[:api_key] = AssetHostCore.config.flickr_api_key
91
+ parameters[:method] = method
92
+ parameters[:format] = "json"
93
+ parameters[:nojsoncallback] = 1
94
+
95
+ response = http.get(path_for_params(parameters))
96
+
97
+ # return an object parsed from the JSON
98
+ ActiveSupport::JSON.decode(response.body)
99
+ end
100
+
101
+
102
+ private
103
+
104
+ def path_for_params(params)
105
+ query_string = "?" + params.inject([]) { |qs, pair| qs << "#{CGI.escape(pair[0].to_s)}=#{CGI.escape(pair[1].to_s)}"; qs }.join("&")
106
+ "/services/rest/" + query_string
107
+ end
108
+
109
+ def http
110
+ @http ||= Net::HTTP.new("api.flickr.com", 80)
111
+ end
112
+ end
113
+ end
114
+ end