loft 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ccac65018592298f1e32ccdc370f0c0b7bb845ad
4
+ data.tar.gz: ec7a87c3cbc6b444957a82ba71a9086a613bf1a4
5
+ SHA512:
6
+ metadata.gz: ea38f740b9bc4a63612cc738e4603e539f72a59f1f93047fd684d3fa88d7385c2b6fd312e88ba533547c7a99f193799a59c5e02f526cbb10c383bb350f2cf8b9
7
+ data.tar.gz: 038275e74677eacc7818653af9f2567afe4d2eed4cf830c2827107d03059d27bc4ee96ebf2e6c29bfa09bbefa90fd41b0a366fc45dfa025b149bd882fb3b4286
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,24 @@
1
+ We love pull requests. Here’s a quick guide:
2
+
3
+ 1. Fork the repository.
4
+ 2. Make your changes in a topic branch.
5
+ 3. Squash your commits into a single one (more on that [here](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)).
6
+ 4. Rebase against `origin/master`, push to your fork and submit a pull request.
7
+ 5. If you are writing a new feature please add documentation for it by making another pull request to the `gh-pages` branch.
8
+
9
+ At this point you’re waiting on us. We like to at least comment on, if not
10
+ accept, pull requests within three business days (and, typically, one business
11
+ day). We may suggest some changes or improvements or alternatives.
12
+
13
+ Some things that will increase the chance that your pull request is accepted:
14
+
15
+ * Fix a bug, refactor code or expand an existing feature.
16
+ * Use the right syntax and naming conventions.
17
+ * Update parts of the documentation that are affected by your contribution.
18
+
19
+ **Git Commit Messages**
20
+
21
+ * Capitalize your commit messages.
22
+ * Start your message with a verb.
23
+ * Use present tense.
24
+ * Refer to the issue/PR number in your squashed commit message.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2015 [Slate Studio, LLC](http://slatestudio.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the “Software”), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # Loft
2
+
3
+ ## Character CMS media assets plugin
4
+
5
+ ### Installation
6
+
7
+ Add to ```Gemfile```:
8
+
9
+ gem 'loft'
10
+
11
+ Setup a new model for assets ```asset.rb```:
12
+
13
+ class Asset
14
+ include Mongoid::Document
15
+ include Mongoid::Timestamps
16
+ include Mongoid::SerializableId
17
+ include Mongoid::LoftAsset
18
+ end
19
+
20
+ Add controller for asset model to make it accesible via CMS, e.g. ```app/controllers/admin/assets_controller.rb```:
21
+
22
+ class Admin::AssetsController < Admin::BaseController
23
+ mongosteen
24
+ has_scope :by_type
25
+ json_config({ methods: [ :list_item_thumbnail, :created_ago ] })
26
+ end
27
+
28
+ Add admin assets controller to ```routes.rb```:
29
+
30
+ resources :assets
31
+
32
+ Add to ```admin.scss```:
33
+
34
+ @import "loft";
35
+
36
+ Add to ```admin.coffee``` character configuration object:
37
+
38
+ assets: new Loft('Library', 'asset', '/admin/assets')
39
+
40
+
41
+ ## Loft family
42
+
43
+ - [Mongosteen](https://github.com/slate-studio/mongosteen): An easy way to add restful actions for mongoid models
44
+ - [Character](https://github.com/slate-studio/chr): A simple and lightweight javascript library for building data management web apps
45
+ - [Inverter](https://github.com/slate-studio/inverter): An easy way to connect Rails templates content to CMS
46
+
47
+ ## Credits
48
+
49
+ [![Slate Studio](https://slate-git-images.s3-us-west-1.amazonaws.com/slate.png)](http://slatestudio.com)
50
+
51
+ Inverter is maintained and funded by [Slate Studio, LLC](http://slatestudio.com). Tweet your questions or suggestions to [@slatestudio](https://twitter.com/slatestudio) and while you’re at it follow us too.
52
+
53
+ ## License
54
+
55
+ Copyright © 2015 [Slate Studio, LLC](http://slatestudio.com). Character is free software, and may be redistributed under the terms specified in the [license](LICENSE.md).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+ require "rubygems"
3
+ require "bundler"
@@ -0,0 +1,67 @@
1
+ # add file icon
2
+ # add selectbox for delete
3
+ # add modal dialog mode
4
+
5
+ class @LoftAssetItem extends Item
6
+ constructor: (@module, @path, @object, @config) ->
7
+ @$el =$ "<div class='item asset' data-id='#{ @object._id }' data-title=''></div>"
8
+ @render()
9
+
10
+
11
+ render: ->
12
+ @$el.html('').removeClass('item-folder has-subtitle has-thumbnail')
13
+
14
+ @_render_title()
15
+ @_render_subtitle()
16
+
17
+ # asset icon with link
18
+ @$link =$ "<a class='asset-icon' href='#{ @object.file.url }' target='_blank'></a>"
19
+ @$el.prepend(@$link)
20
+
21
+ # checkbox for item selection
22
+ @$checkbox =$ "<input class='asset-checkbox' type='checkbox' />"
23
+ @$el.prepend(@$checkbox)
24
+
25
+ # input for assets name
26
+ name = @$el.attr('data-title')
27
+ @$nameInput =$ "<input class='asset-name' type='text' value='#{ name }' />"
28
+ @$title.before @$nameInput
29
+ @_bind_name_input()
30
+
31
+ # handler for asset name change on title click
32
+ @$title.on 'click', (e) => @_edit_name(e)
33
+
34
+
35
+ _bind_name_input: ->
36
+ @$nameInput.on 'blur', (e) => @_update_name_if_changed()
37
+ @$nameInput.on 'keyup', (e) =>
38
+ if e.keyCode == 13 then $(e.target).blur()
39
+ if e.keyCode == 27 then @_cancel_name_change()
40
+
41
+
42
+ _edit_name: (e) ->
43
+ @$el.addClass('edit-name')
44
+ @$nameInput.focus().select()
45
+
46
+
47
+ _cancel_name_change: ->
48
+ @$el.removeClass('edit-name')
49
+ name = @$title.html()
50
+ @$nameInput.val(name)
51
+
52
+
53
+ _update_name_if_changed: ->
54
+ @$el.removeClass('edit-name')
55
+ name = @$nameInput.val()
56
+
57
+ if name == @$title.html() then return
58
+ @$title.html(name)
59
+
60
+ @config.arrayStore.update @object._id, { '[name]': name },
61
+ onSuccess: (object) =>
62
+ onError: (errors) => # process errors
63
+
64
+
65
+
66
+
67
+
@@ -0,0 +1,62 @@
1
+ class @LoftGroupActions
2
+ constructor: (@list, @module) ->
3
+ @_render()
4
+ @_bind_checkboxes()
5
+
6
+
7
+ _render: ->
8
+ @$el =$ "<div class='assets-group-actions' style='display:none;'></div>"
9
+ @list.$header.append @$el
10
+
11
+ @$unselectBtn =$ "<a href='#' class='unselect'>Unselect All</a>"
12
+ @$unselectBtn.on 'click', (e) => e.preventDefault(); @_unselect_list_items()
13
+ @$el.append @$unselectBtn
14
+
15
+ @$deleteBtn =$ "<a href='#' class='delete'>Delete Selected</a>"
16
+ @$deleteBtn.on 'click', (e) => e.preventDefault(); @_delete_selected_list_items()
17
+ @$el.append @$deleteBtn
18
+
19
+
20
+ _bind_checkboxes: ->
21
+ @list.$el.on 'click', '.asset .asset-checkbox', (e) =>
22
+ selectedItems = @_selected_list_items()
23
+ if selectedItems.length > 0
24
+ @_show()
25
+ else
26
+ @_hide()
27
+
28
+
29
+ _selected_list_items: ->
30
+ @list.$el.find '.asset .asset-checkbox:checked'
31
+
32
+
33
+ _unselect_list_items: ->
34
+ @list.$el.find('.asset .asset-checkbox').prop('checked', false)
35
+ @_hide()
36
+
37
+
38
+ _delete_selected_list_items: ->
39
+ if confirm("Are you sure?")
40
+ selectedItems = @_selected_list_items()
41
+ filesToRemoveCounter = selectedItems.length
42
+
43
+ # we have on scroll pagination so after some items are removed,
44
+ # next page request might skip items that replaced removed ones
45
+ for item in selectedItems
46
+ objectId = $(item).parent().attr('data-id')
47
+ @list.config.arrayStore.remove objectId,
48
+ onSuccess: => # success notification
49
+ onError: => # error notification
50
+ @_hide()
51
+
52
+
53
+ _show: ->
54
+ @$el.show()
55
+
56
+
57
+ _hide: ->
58
+ @$el.hide()
59
+
60
+
61
+
62
+
@@ -0,0 +1,99 @@
1
+ class @Loft
2
+ constructor: (title, @resource, @resourcePath) ->
3
+ @module = {}
4
+ @store = {}
5
+
6
+ @_uploadsCounter = 0
7
+
8
+ moduleConfig =
9
+ title: title
10
+ showNestedListsAside: true
11
+ items:
12
+ assets_all: @_nested_list_config 'All'
13
+ assets_images: @_nested_list_config 'Images', 'image'
14
+ assets_text: @_nested_list_config 'Text', 'text'
15
+ assets_archives: @_nested_list_config 'Archives', 'archive'
16
+ assets_audio: @_nested_list_config 'Audio', 'audio'
17
+ assets_video: @_nested_list_config 'Video', 'video'
18
+ assets_other: @_nested_list_config 'Other', 'other'
19
+
20
+ onModuleInit: (module) =>
21
+ @_initialize_module(module)
22
+
23
+ return moduleConfig
24
+
25
+
26
+ _initialize_module: (module) ->
27
+ @module = module
28
+ @store = @module.nestedLists.assets_all.config.arrayStore
29
+
30
+
31
+ _nested_list_config: (moduleName, assetType) ->
32
+ arrayStoreConfig =
33
+ resource: @resource
34
+ path: @resourcePath
35
+ searchable: true
36
+
37
+ if assetType
38
+ $.extend(arrayStoreConfig, { urlParams: { by_type: assetType } })
39
+
40
+ config =
41
+ title: moduleName
42
+ itemTitleField: 'name'
43
+ itemSubtitleField: 'created_ago'
44
+ itemClass: LoftAssetItem
45
+ arrayStore: new MongosteenArrayStore(arrayStoreConfig)
46
+ onListInit: (list) => @_inititialize_list(list)
47
+
48
+ return config
49
+
50
+
51
+ _inititialize_list: (list) ->
52
+ # uploading spinner
53
+ list.$loading =$ "<div class='loader'></div>"
54
+ list.$el.append list.$loading
55
+
56
+ # file input button for uploading new files
57
+ list.$uploadInput =$ "<input class='asset-upload' type='file' multiple='multiple' />"
58
+ list.$search.before list.$uploadInput
59
+
60
+ # file upload handler
61
+ list.$uploadInput.on 'change', (e) =>
62
+ files = e.target.files
63
+ if files.length > 0
64
+ @_upload(file, list) for file in files
65
+
66
+ # group actions toolbar
67
+ list.$groupActions = new LoftGroupActions(list, this)
68
+
69
+
70
+ _upload: (file, list) ->
71
+ obj = {}
72
+ obj["__FILE__[file]"] = file
73
+
74
+ @_start_file_upload()
75
+ @store.push obj,
76
+ onSuccess: (object) => @_finish_file_upload(list)
77
+ onError: (errors) => @_finish_file_upload(list)
78
+ # + process validation errors, if any
79
+
80
+
81
+ _start_file_upload: ->
82
+ @_uploadsCounter += 1
83
+ @module.$el.addClass('assets-uploading')
84
+
85
+
86
+ _finish_file_upload: (list) ->
87
+ @_uploadsCounter -= 1
88
+ if @_uploadsCounter == 0
89
+ @module.$el.removeClass('assets-uploading')
90
+
91
+ # update data in list if it's not assets_all,
92
+ # in there new objects are added automatically
93
+ visibleList = @module.visibleNestedListShownWithParent()
94
+ if visibleList.name != 'assets_all'
95
+ visibleList.updateItems()
96
+
97
+
98
+
99
+
@@ -0,0 +1,3 @@
1
+ #= require chr/loft/group-actions
2
+ #= require chr/loft/asset-item
3
+ #= require chr/loft/module
@@ -0,0 +1,107 @@
1
+ //
2
+ // Styles for Loft Character CMS plugin, this should be included in
3
+ // admin.scss (default)
4
+ //
5
+ // - mobile version
6
+ //
7
+
8
+ /* Tablet Layout */
9
+ @media #{$tablet} {
10
+ .module.assets {
11
+ .list:not(:first-child) {
12
+ .items {
13
+ .item { min-height: 49px; }
14
+ .item-title { display: inline-block; }
15
+ .item-subtitle { display: inline; float: right; }
16
+ .item.has-subtitle { padding: 1em; }
17
+ }
18
+ }
19
+ }
20
+ }
21
+
22
+
23
+ // Group Actions
24
+ .assets-group-actions {
25
+ @include absolutePosition(0 0 0 0); background: $white;
26
+ .unselect { @include headerButton($stableColor); float: left; margin-left: 1em; }
27
+ .delete { @include headerButton($assertiveColor); float: right; margin-right: 1em; }
28
+ }
29
+
30
+
31
+ // Icons for Parrent List
32
+ .list.assets {
33
+ .items .item {
34
+ .item-title { margin-left: 2.05em; }
35
+ &:before {
36
+ content: '';
37
+ position: absolute;
38
+ display: block; width: 16px; height: 16px;
39
+ margin-right: 1em;
40
+ background-color: $lightColor;
41
+ }
42
+ }
43
+ }
44
+
45
+
46
+ // Upload Button
47
+ .asset-upload {
48
+ @include absolutePosition(0 0 inherit inherit);
49
+ @extend .icon-plus;
50
+ cursor: pointer;
51
+ right: -40px;
52
+ padding-left: 80px;
53
+ &:focus { outline: none; }
54
+ }
55
+
56
+ .list header {
57
+ .asset-upload + .search { @include absolutePosition(0 40px inherit inherit); }
58
+ }
59
+
60
+ .list.list-search header {
61
+ .asset-upload + .search { @include absolutePosition(0 0 inherit 0); }
62
+ }
63
+
64
+
65
+ // Loader Spinner
66
+ .module.assets.assets-uploading .list:not(:first-child) header .spinner { display: inline-block; }
67
+
68
+
69
+ // List Item
70
+ .item.asset {
71
+ .item-title {
72
+ cursor: pointer;
73
+ position: relative;
74
+ &:hover { color: $positiveColor; text-decoration: underline; }
75
+ }
76
+ .asset-name {
77
+ display: none;
78
+ width: 50%;
79
+ position: absolute;
80
+ line-height: 1;
81
+ padding: 0em .3em .3em .375em;
82
+ top: .55em; bottom: .55em; left: 4.5em;
83
+ z-index: 1;
84
+ border-radius: 3px;
85
+ &:focus {
86
+ outline: none !important;
87
+ border: 1px solid $stableColor;
88
+ box-shadow: 0 0 10px $lightColor;
89
+ }
90
+ }
91
+ .asset-checkbox {
92
+ position: relative; top: -.25em;
93
+ margin-right: 1em;
94
+ }
95
+ .asset-icon {
96
+ display: inline-block; width: 16px; height: 16px;
97
+ margin-right: 1em;
98
+ background-color: $lightColor; }
99
+
100
+ &.edit-name {
101
+ .asset-name { display: block; }
102
+ }
103
+ }
104
+
105
+
106
+
107
+
@@ -0,0 +1,7 @@
1
+ class AssetFileUploader < CarrierWave::Uploader::Base
2
+ include Loft::AssetFileUploader
3
+ end
4
+
5
+
6
+
7
+
data/lib/loft.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'carrierwave/mongoid'
2
+
3
+ module Loft
4
+ require 'loft/engine'
5
+ require 'mongoid/loft_asset'
6
+ require 'uploaders/asset_file_uploader'
7
+ end
@@ -0,0 +1,5 @@
1
+ module Loft
2
+ class Engine < Rails::Engine
3
+ # auto wire
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Loft
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,129 @@
1
+ require 'autoinc'
2
+ require 'mongoid_search'
3
+
4
+ module Mongoid
5
+ module LoftAsset
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ include Mongoid::Autoinc
11
+ include Mongoid::Search
12
+ include ActionView::Helpers::DateHelper
13
+ include ActionView::Helpers::NumberHelper
14
+
15
+ # attributes
16
+ field :name, default: ''
17
+ field :filename, default: ''
18
+ field :size, type: Integer
19
+ field :humanized_size, default: ''
20
+ field :type, default: 'other'
21
+ # - image
22
+ # - video
23
+ # - audio
24
+ # - archive
25
+ # - text
26
+
27
+ # increment value, used by uploader
28
+ field :_number, type: Integer
29
+ increments :number
30
+
31
+ # uploaders
32
+ mount_uploader :file, AssetFileUploader
33
+
34
+ # validations
35
+ validates :file, presence: true
36
+
37
+ # search
38
+ search_in :name, :filename
39
+
40
+ # scopes
41
+ default_scope -> { desc(:created_at) }
42
+ scope :by_type, -> asset_type { where(type: asset_type) }
43
+
44
+ # indexes
45
+ index({ created_at: -1 })
46
+
47
+ # callbacks
48
+ before_save :update_asset_attributes
49
+
50
+
51
+ # helpers
52
+ def created_ago
53
+ time_ago_in_words(self.created_at) + " ago"
54
+ end
55
+
56
+
57
+ def list_item_thumbnail
58
+ if is_image? and file?
59
+ file.small_150.url
60
+ else
61
+ ''
62
+ end
63
+ end
64
+
65
+
66
+ def content_type
67
+ @content_type ||= file.content_type
68
+ end
69
+
70
+
71
+ def is_image?
72
+ return false unless file?
73
+ content_type.match(/image\//) ? true : false
74
+ end
75
+
76
+ def is_text?
77
+ return false unless file?
78
+ content_type.match(/text\//) ? true : false
79
+ end
80
+
81
+ def is_archive?
82
+ return false unless file?
83
+ # need to add more archive types: rar, gz, bz2, gzip
84
+ content_type.match(/zip/) ? true : false
85
+ end
86
+
87
+ def is_audio?
88
+ return false unless file?
89
+ content_type.match(/audio\//) ? true : false
90
+ end
91
+
92
+ def is_video?
93
+ return false unless file?
94
+ content_type.match(/video\//) ? true : false
95
+ end
96
+
97
+
98
+ def update_asset_attributes
99
+ if file.present? && file_changed?
100
+
101
+ # save original file name for search
102
+ self.filename = file.file.original_filename
103
+
104
+ # save file size in plain for search
105
+ self.size = file.file.size
106
+
107
+ # save humanized file size
108
+ self.humanized_size = number_to_human_size(self.size)
109
+
110
+ # asset types
111
+ self.type = 'image' if self.is_image?
112
+ self.type = 'text' if self.is_text?
113
+ self.type = 'archive' if self.is_archive?
114
+ self.type = 'audio' if self.is_audio?
115
+ self.type = 'video' if self.is_video?
116
+ end
117
+
118
+ # use filename as an asset name if name is empty ''
119
+ self.name = self.name.empty? ? self.filename : self.name
120
+ end
121
+ private :update_asset_attributes
122
+
123
+ end
124
+ end
125
+ end
126
+
127
+
128
+
129
+
@@ -0,0 +1,23 @@
1
+ module Loft
2
+ module AssetFileUploader
3
+ extend ActiveSupport::Concern
4
+ included do
5
+
6
+ include CarrierWave::MiniMagick
7
+
8
+ def store_dir
9
+ "assets/loft/#{ model._number }"
10
+ end
11
+
12
+ version :small_150, if: :is_image? do
13
+ process :resize_to_fill => [150, 150]
14
+ end
15
+
16
+ def is_image? new_file
17
+ model.is_image?
18
+ end
19
+ private :is_image?
20
+
21
+ end
22
+ end
23
+ end
data/loft.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'loft/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'loft'
7
+ s.version = Loft::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Alexander Kravets']
10
+ s.email = 'alex@slatestudio.com'
11
+ s.license = 'MIT'
12
+ s.homepage = 'http://slatestudio.com'
13
+ s.summary = 'Character CMS media assets plugin.'
14
+ s.description = <<-DESC
15
+ This Character CMS plugin adds an assets library that provides an
16
+ easy way to upload, manage and insert files into documents.
17
+ DESC
18
+
19
+ s.rubyforge_project = 'loft'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.require_paths = ['lib']
23
+
24
+ s.add_dependency("mongoid_search", ">= 0.3.1")
25
+ s.add_dependency("mongoid-autoinc", ">= 4.0.0")
26
+ s.add_dependency("mini_magick", ">= 4.1.0")
27
+ s.add_dependency("mongoid-grid_fs", ">= 2.1.0")
28
+ s.add_dependency("carrierwave-mongoid", ">= 0.7.1")
29
+ end
30
+
31
+
32
+
33
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Kravets
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mongoid_search
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: mongoid-autoinc
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: mini_magick
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 4.1.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 4.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongoid-grid_fs
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.1.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 2.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: carrierwave-mongoid
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 0.7.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 0.7.1
83
+ description: |
84
+ This Character CMS plugin adds an assets library that provides an
85
+ easy way to upload, manage and insert files into documents.
86
+ email: alex@slatestudio.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - CONTRIBUTING.md
92
+ - Gemfile
93
+ - LICENSE.md
94
+ - README.md
95
+ - Rakefile
96
+ - app/assets/javascripts/chr/loft/asset-item.coffee
97
+ - app/assets/javascripts/chr/loft/group-actions.coffee
98
+ - app/assets/javascripts/chr/loft/module.coffee
99
+ - app/assets/javascripts/loft.coffee
100
+ - app/assets/stylesheets/_loft.scss
101
+ - app/uploaders/asset_file_uploader.rb
102
+ - lib/loft.rb
103
+ - lib/loft/engine.rb
104
+ - lib/loft/version.rb
105
+ - lib/mongoid/loft_asset.rb
106
+ - lib/uploaders/asset_file_uploader.rb
107
+ - loft.gemspec
108
+ homepage: http://slatestudio.com
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project: loft
128
+ rubygems_version: 2.4.5
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Character CMS media assets plugin.
132
+ test_files: []