outpost-asset_host 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 Bryan Ricker
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.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Outpost::AssetHost
2
+
3
+ AssetHost integration with Outpost.
4
+
5
+ Dependencies:
6
+ * Outpost
7
+ * Backbone, >= 0.9
8
+
9
+ You should include these dependencies yourself.
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ class PostAsset < ActiveRecord::Base
15
+ belongs_to :post
16
+ end
17
+
18
+
19
+ class Post < ActiveRecord::Base
20
+ has_many :assets, class_name: "PostAsset"
21
+ accepts_json_input_for_assets
22
+ end
23
+ ```
24
+
25
+ You'll also need to define a `window.assethost` object, with "SERVER" and "TOKEN":
26
+
27
+ ```coffee
28
+ window.assethost =
29
+ SERVER: "http://assethost.yourserver.com"
30
+ TOKEN: "{your assethost key}
31
+ ```
32
+
33
+ And include the javascript and stylesheet:
34
+
35
+ ```
36
+ //= require outpost/asset_host
37
+
38
+ /*
39
+ *= require outpost/assets
40
+ */
41
+ ```
42
+
43
+ ## Contributing
44
+
45
+ 1. Fork it
46
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+ 4. Push to the branch (`git push origin my-new-feature`)
49
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
@@ -0,0 +1,143 @@
1
+ ##
2
+ # AssetManager
3
+ #
4
+ # For Managing Assets
5
+ class outpost.AssetManager
6
+ @TemplatePath = 'outpost/asset_host/templates/'
7
+
8
+ DefaultOptions:
9
+ jsonInput: "#asset_json"
10
+
11
+ #----------
12
+
13
+ constructor: (assets, el, options={}) ->
14
+ _.extend @, Backbone.Events
15
+ @options = _.defaults options, @DefaultOptions
16
+ @el = $(el)
17
+
18
+ @assets = new outpost.AssetHost.Assets(assets)
19
+ @assetsView = new outpost.AssetManager.Assets(collection: @assets)
20
+
21
+ @el.html @assetsView.el
22
+
23
+ # Register listener for AssetHost message
24
+ window.addEventListener "message", (event) =>
25
+ # If the data is an object (i.e. not "LOADED"), do things
26
+ if _.isObject(event.data)
27
+ @assets.reset(event.data)
28
+ @assets.sort()
29
+ @assetsView.render()
30
+ @updateInput()
31
+ , false
32
+
33
+ #----------
34
+
35
+ updateInput: ->
36
+ $(@options.jsonInput).val(JSON.stringify(@assets.simpleJSON()))
37
+
38
+ #----------
39
+
40
+ @Asset: Backbone.View.extend
41
+ tagName: "li"
42
+ template: JST[AssetManager.TemplatePath + 'asset']
43
+
44
+ #----------
45
+
46
+ initialize: ->
47
+ @render()
48
+ @model.bind "change", => @render()
49
+
50
+ #----------
51
+
52
+ render: ->
53
+ if @model.get('tags')
54
+ @$el.html @template(asset: @model.toJSON())
55
+
56
+ @
57
+
58
+ #----------
59
+
60
+ @Assets: Backbone.View.extend
61
+ tagName: "ul"
62
+ events: "click a.popup": "_popup"
63
+
64
+ initialize: ->
65
+ @_views = {}
66
+
67
+ @collection.bind "reset", =>
68
+ view.detach() for view in @_views
69
+ @_views = {}
70
+
71
+ @collection.bind 'add', (f) =>
72
+ @_views[f.cid] = new outpost.AssetManager.Asset
73
+ model: f
74
+
75
+ @renderCollection()
76
+
77
+ @collection.bind 'remove', (f) =>
78
+ $(@_views[f.cid].el).detach()
79
+ delete @_views[f.cid]
80
+ @renderCollection()
81
+
82
+ # attach a listener to wait for the LOADED message
83
+ window.addEventListener "message", (evt) =>
84
+ if evt.data == "LOADED" and @chooserIsAvailable()
85
+ console.log @collection.toJSON()
86
+ # dispatch our event with the asset data
87
+ window.assethostChooser.postMessage @collection.toJSON(), assethost.SERVER
88
+ , false
89
+
90
+ @render()
91
+
92
+ #----------
93
+
94
+ chooserIsAvailable: ->
95
+ window.assethostChooser and !window.assethostChooser.closed
96
+
97
+ #----------
98
+
99
+ _popup: (event) ->
100
+ event.originalEvent.stopPropagation()
101
+ event.originalEvent.preventDefault()
102
+
103
+ popup =
104
+ url: "#{assethost.SERVER}/a/chooser"
105
+ name: "chooser"
106
+ options: "height=620,width=1000,scrollbars=1"
107
+
108
+ if @chooserIsAvailable()
109
+ window.assethostChooser.focus()
110
+ else
111
+ window.assethostChooser = window.open(popup.url, popup.name, popup.options)
112
+
113
+ false
114
+
115
+ #----------
116
+ # Render the full view. This should only be called once.
117
+ render: ->
118
+ @$el.html JST[AssetManager.TemplatePath + 'asset_manager']
119
+ @collectionEl = $(".collection", @$el)
120
+ @emptyNotification = new outpost.Notification(
121
+ @collectionEl,
122
+ "info",
123
+ "There are no assets. Click the button to open AssetHost."
124
+ )
125
+
126
+ @renderCollection()
127
+ @
128
+
129
+ #----------
130
+ # Render the collection. This gets called every time AssetHost send a message.
131
+ renderCollection: ->
132
+ if @collection.isEmpty()
133
+ return @emptyNotification.render()
134
+
135
+ @collection.each (asset, index) =>
136
+ asset.set(ORDER: index)
137
+
138
+ @_views[asset.cid] ?= new outpost.AssetManager.Asset
139
+ model: asset
140
+
141
+ views = _(@_views).sortBy (a) => a.model.get("ORDER")
142
+ @collectionEl.html( _(views).map (v) -> v.el )
143
+ @
@@ -0,0 +1,51 @@
1
+ ##
2
+ # AssetHost
3
+ # Models for AssetHost API interaction
4
+ #
5
+ class outpost.AssetHost
6
+ @Asset: Backbone.Model.extend
7
+ urlRoot: "#{assethost.SERVER}/api/assets/"
8
+
9
+ #----------
10
+ # simpleJSON is an object of just the attributes
11
+ # we care about for SCPRv4. Everything else is
12
+ # pulled from the AssetHost API.
13
+ #
14
+ # This should be kept in sync with ContentAsset#simple_json
15
+ simpleJSON: ->
16
+ {
17
+ id: @get 'id'
18
+ caption: @get 'caption'
19
+ position: @get 'ORDER'
20
+ }
21
+
22
+ #--------------
23
+
24
+ url: ->
25
+ url = if @isNew() then @urlRoot else @urlRoot + encodeURIComponent(@id)
26
+
27
+ if assethost.TOKEN
28
+ token = $.param(auth_token:assethost.TOKEN)
29
+ url += "?#{token}"
30
+
31
+ url
32
+
33
+ #----------
34
+
35
+ @Assets: Backbone.Collection.extend
36
+ model: @Asset
37
+
38
+ # If we have an ORDER attribute, sort by that.
39
+ # Otherwise, sort by just the asset ID.
40
+ comparator: (asset) ->
41
+ asset.get("ORDER") || -Number(asset.get("id"))
42
+
43
+ #----------
44
+ # An array of assets turned into simpleJSON. See
45
+ # Asset#simpleJSON for more.
46
+ simpleJSON: ->
47
+ assets = []
48
+ @each (asset) -> assets.push(asset.simpleJSON())
49
+ assets
50
+
51
+ #----------
@@ -0,0 +1,8 @@
1
+ <div class="thumbnail">
2
+ <%- @asset.tags.lsquare %>
3
+
4
+ <div class="asset-info">
5
+ <h6><%= @asset.title %></h6>
6
+ <small class="muted"><%= @asset.caption %></small>
7
+ </div>
8
+ </div>
@@ -0,0 +1,2 @@
1
+ <h4>Assets <a style="margin: 0 20px;" class="btn popup" href="#">Pop Up Asset Chooser</a></h4>
2
+ <div class="collection"></div>
@@ -0,0 +1,3 @@
1
+ //= require_directory ./asset_host/templates
2
+ //= require outpost/asset_host/assets
3
+ //= require outpost/asset_host/asset_manager
@@ -0,0 +1,31 @@
1
+ #asset_bucket {
2
+ ul, li { @extend .unstyled; }
3
+
4
+ li {
5
+ @extend .span4;
6
+ margin: 0 5px 5px 0;
7
+ float: left;
8
+ height: 165px;
9
+ overflow: hidden;
10
+ }
11
+
12
+ .thumbnail {
13
+ border: 1px solid $grayLighter;
14
+ padding: 5px;
15
+ @include clearfix;
16
+
17
+ img {
18
+ float: left;
19
+ max-width: 150px;
20
+ margin-right: 5px;
21
+ }
22
+
23
+ .asset-info {
24
+ line-height: 12px;
25
+ h6 {
26
+ display: inline;
27
+ line-height: 11px;
28
+ }
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,26 @@
1
+ module Outpost
2
+ module AssetHost
3
+ module JoinModelJson
4
+ def as_json(options={})
5
+ @as_json ||= begin
6
+ # grab asset as_json, merge in our values
7
+ self.asset.as_json(options).merge!({
8
+ "post_asset_id" => self.id,
9
+ "caption" => self.caption,
10
+ "ORDER" => self.position,
11
+ "credit" => self.asset.owner
12
+ })
13
+ end
14
+ end
15
+
16
+
17
+ def simple_json
18
+ @simple_json ||= {
19
+ "id" => self.asset_id.to_i,
20
+ "caption" => self.caption.to_s,
21
+ "position" => self.position.to_i
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,79 @@
1
+ module Outpost
2
+ module AssetHost
3
+ module JsonInput
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def accepts_json_input_for_assets
8
+ include InstanceMethodsOnActivation
9
+ @assets_association_join_class = self.reflect_on_association(:assets).class_name
10
+ end
11
+
12
+ def assets_association_join_class
13
+ @assets_association_join_class
14
+ end
15
+ end
16
+
17
+
18
+ module InstanceMethodsOnActivation
19
+ #-------------------
20
+ # #asset_json is a way to pass in a string representation
21
+ # of a javascript object to the model, which will then be
22
+ # parsed and turned into ContentAsset objects in the
23
+ # #asset_json= method.
24
+ def asset_json
25
+ current_assets_json.to_json
26
+ end
27
+
28
+ #-------------------
29
+ # Parse the input from #asset_json and turn it into real
30
+ # ContentAsset objects.
31
+ def asset_json=(json)
32
+ # If this is literally an empty string (as opposed to an
33
+ # empty JSON object, which is what it would be if there were no assets),
34
+ # then we can assume something went wrong and just abort.
35
+ # This shouldn't happen since we're populating the field in the template.
36
+ return if json.empty?
37
+
38
+ json = Array(JSON.parse(json)).sort_by { |c| c["position"].to_i }
39
+ loaded_assets = []
40
+
41
+ json.each do |asset_hash|
42
+ new_asset = self.class.assets_association_join_class.constantize.new(
43
+ :asset_id => asset_hash["id"].to_i,
44
+ :caption => asset_hash["caption"].to_s,
45
+ :position => asset_hash["position"].to_i
46
+ )
47
+
48
+ loaded_assets.push new_asset
49
+ end
50
+
51
+ loaded_assets_json = assets_to_simple_json(loaded_assets)
52
+
53
+ # If the assets didn't change, there's no need to bother the database.
54
+ if current_assets_json != loaded_assets_json
55
+ if self.respond_to?(:custom_changes)
56
+ self.custom_changes['assets'] = [current_assets_json, loaded_assets_json]
57
+ end
58
+
59
+ self.changed_attributes['assets'] = current_assets_json
60
+ self.assets = loaded_assets
61
+ end
62
+
63
+ self.assets
64
+ end
65
+
66
+
67
+ private
68
+
69
+ def current_assets_json
70
+ assets_to_simple_json(self.assets)
71
+ end
72
+
73
+ def assets_to_simple_json(array)
74
+ Array(array).map(&:simple_json)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,5 @@
1
+ module Outpost
2
+ module AssetHost
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ require "outpost/asset_host/version"
2
+ require "outpost/asset_host/json_input"
3
+ require "outpost/asset_host/join_model_json"
4
+
5
+ module Outpost
6
+ module AssetHost
7
+ module Rails
8
+ class Engine < ::Rails::Engine
9
+ config.to_prepare do
10
+ ActiveSupport.on_load(:active_record) do
11
+ ActiveRecord::Base.send :include, Outpost::AssetHost::JsonInput
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'outpost/asset_host/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "outpost-asset_host"
8
+ spec.version = Outpost::AssetHost::VERSION
9
+ spec.authors = ["Bryan Ricker"]
10
+ spec.email = ["bricker88@gmail.com"]
11
+ spec.description = %q{AssetHost integration with Outpost.}
12
+ spec.summary = %q{Provides client-side hooks into AssetHost for Outpost.}
13
+ spec.homepage = "https://github.com/SCPR/outpost-asset_host"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec-rails"
24
+ spec.add_development_dependency "combustion"
25
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: outpost-asset_host
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bryan Ricker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: combustion
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: AssetHost integration with Outpost.
79
+ email:
80
+ - bricker88@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - MIT-LICENSE
88
+ - README.md
89
+ - Rakefile
90
+ - lib/assets/javascripts/outpost/asset_host.js
91
+ - lib/assets/javascripts/outpost/asset_host/asset_manager.js.coffee
92
+ - lib/assets/javascripts/outpost/asset_host/assets.js.coffee
93
+ - lib/assets/javascripts/outpost/asset_host/templates/asset.jst.eco
94
+ - lib/assets/javascripts/outpost/asset_host/templates/asset_manager.jst.eco
95
+ - lib/assets/stylesheets/outpost/assets.css.scss
96
+ - lib/outpost/asset_host.rb
97
+ - lib/outpost/asset_host/join_model_json.rb
98
+ - lib/outpost/asset_host/json_input.rb
99
+ - lib/outpost/asset_host/version.rb
100
+ - outpost-asset_host.gemspec
101
+ homepage: https://github.com/SCPR/outpost-asset_host
102
+ licenses:
103
+ - MIT
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.25
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Provides client-side hooks into AssetHost for Outpost.
126
+ test_files: []
127
+ has_rdoc: