oxen_media 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.bowerrc +3 -0
  3. data/.envrc +1 -0
  4. data/.gitignore +11 -0
  5. data/.rspec +3 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +16 -0
  8. data/Gemfile.lock +331 -0
  9. data/Guardfile +135 -0
  10. data/MIT-LICENSE +20 -0
  11. data/README.rdoc +31 -0
  12. data/Rakefile +15 -0
  13. data/app/assets/images/oxen_media/.keep +0 -0
  14. data/app/assets/javascripts/jsrender.min.js +4 -0
  15. data/app/assets/javascripts/jsrender.min.js.map +463 -0
  16. data/app/assets/javascripts/oxen_media.js +3 -0
  17. data/app/assets/javascripts/oxen_media/.keep +0 -0
  18. data/app/assets/javascripts/oxen_media/carrier_wave_cropper.js.coffee +22 -0
  19. data/app/assets/javascripts/oxen_media/media.js.coffee +469 -0
  20. data/app/assets/javascripts/oxen_media/medium_pane.js.coffee +107 -0
  21. data/app/assets/javascripts/templates/selected_files.html +35 -0
  22. data/app/assets/stylesheets/media.css +10 -0
  23. data/app/assets/stylesheets/oxen_media/.keep +0 -0
  24. data/app/assets/stylesheets/scaffold.css +56 -0
  25. data/app/controllers/.keep +0 -0
  26. data/app/controllers/media_controller.rb +106 -0
  27. data/app/helpers/.keep +0 -0
  28. data/app/helpers/media_helper.rb +2 -0
  29. data/app/mailers/.keep +0 -0
  30. data/app/models/.keep +0 -0
  31. data/app/models/concerns/roleable.rb +61 -0
  32. data/app/models/medium.rb +25 -0
  33. data/app/policies/oxen_medium_policy.rb +12 -0
  34. data/app/uploaders/medium_uploader.rb +106 -0
  35. data/app/views/.keep +0 -0
  36. data/app/views/media/_fields.html.haml +42 -0
  37. data/app/views/media/_form.html.haml +48 -0
  38. data/app/views/media/_media.html.haml +18 -0
  39. data/app/views/media/_medium.html.haml +25 -0
  40. data/app/views/media/_medium_fields.html.haml +4 -0
  41. data/app/views/media/create.js.haml +2 -0
  42. data/app/views/media/crop.html.haml +3 -0
  43. data/app/views/media/edit.html.haml +2 -0
  44. data/app/views/media/index.html.haml +29 -0
  45. data/app/views/media/index.json.jbuilder +4 -0
  46. data/app/views/media/new.html.erb +5 -0
  47. data/app/views/media/show.html.haml +21 -0
  48. data/app/views/media/show.json.jbuilder +1 -0
  49. data/app/views/media/update_crop.js.haml +1 -0
  50. data/bin/rails +12 -0
  51. data/config/initializers/backtrace_silencers.rb +9 -0
  52. data/config/initializers/carrier_wave.rb +11 -0
  53. data/config/initializers/simple_form.rb +14 -0
  54. data/config/locales/media.en.yml +20 -0
  55. data/config/routes.rb +6 -0
  56. data/db/migrate/20150629071720_create_media.rb +13 -0
  57. data/lib/generators/media/USAGE +8 -0
  58. data/lib/generators/media/media_generator.rb +48 -0
  59. data/lib/generators/media/templates/medium.rb +13 -0
  60. data/lib/oxen_media.rb +7 -0
  61. data/lib/oxen_media/engine.rb +19 -0
  62. data/lib/oxen_media/version.rb +3 -0
  63. data/lib/tasks/oxen_media_tasks.rake +4 -0
  64. data/oxen_media.gemspec +59 -0
  65. data/test/controllers/media_controller_test.rb +49 -0
  66. data/test/fixtures/media.yml +17 -0
  67. data/test/integration/oxen_media_test.rb +7 -0
  68. data/test/lib/generators/media_generator_test.rb +14 -0
  69. data/test/models/medium_test.rb +7 -0
  70. data/test/test_helper.rb +13 -0
  71. metadata +387 -0
@@ -0,0 +1,107 @@
1
+ class MediumPaneClass
2
+
3
+ constructor: (@list, @loader='span.medium-loader') ->
4
+ @media = []
5
+
6
+ listFile: (template,data,selector) ->
7
+ $.tmpl(template, data).prependTo(selector)
8
+
9
+ #
10
+ # set Buttons
11
+ #
12
+ setButtons: (c) ->
13
+ @setNewLink(c)
14
+ @setLinks(c)
15
+
16
+
17
+ #
18
+ # set links for Uri, and current Contact
19
+ #
20
+ setFormLinks: (self) ->
21
+ @setCancel(self)
22
+ @setSave(self)
23
+
24
+
25
+ setCancel: (self) ->
26
+ me=self
27
+ $('.cancel_medium').on 'click', () ->
28
+ $(me.list + ' .medium-form').remove()
29
+
30
+ setNewLink: (self) ->
31
+ me=self
32
+ try
33
+ me=self
34
+ $('a.new_medium').on 'click', (e) ->
35
+ e.preventDefault()
36
+ e.stopPropagation()
37
+ setLoader $(me.loader)
38
+ url = $(this).attr('href') + '?scope=' + me.list.replace('#','')
39
+
40
+ $.ajax
41
+ url: url,
42
+ type: 'GET'
43
+ success: (data, textStatus, jqXHR) ->
44
+ releaseLoader $(me.loader)
45
+ $(me.list).prepend(data)
46
+ error: (jqXHR, textStatus, errorThrown) ->
47
+ releaseLoader $(me.loader)
48
+ swal 'Fejl!!', textStatus, 'error'
49
+ catch e
50
+ console.log e
51
+
52
+
53
+ setLinks: (self) ->
54
+ try
55
+ me=self
56
+ $(".medium.collection-item i.circle").on 'click', (e) ->
57
+ setLoader $(me.loader)
58
+ elem = $(this).closest('li')
59
+ _id = elem.data('id')
60
+ $.ajax
61
+ url: '/uris/' + _id + '/edit?scope='+me.list.replace('#',''),
62
+ type: 'GET'
63
+ success: (data, textStatus, jqXHR) ->
64
+ releaseLoader $(me.loader)
65
+ $(me.list).prepend(data)
66
+ error: (jqXHR, textStatus, errorThrown) ->
67
+ releaseLoader $(me.loader)
68
+ swal 'Fejl!!',textStatus, 'error'
69
+ catch e
70
+ console.log e
71
+
72
+ setSave: (self) ->
73
+ me=self
74
+ $('.save_medium').on 'click', () ->
75
+ setLoader $(me.loader)
76
+ elem = $(this).closest('form')
77
+ type = elem.attr('method')
78
+ url = elem.attr('action')
79
+ if elem.attr('id')=='new_medium'
80
+ elem= $(me.list + ' ul.collection')
81
+ else
82
+ elem=$('#' + url.replace('/media/','medium-'))
83
+ url = url + '.js'
84
+ #type = "#{params[:action]=='edit' ? 'PUT' : 'POST'}"
85
+ $inputs = $(this).closest('form').find "input, select, button, textarea"
86
+ serializedData = $inputs.serialize()
87
+
88
+ $.ajax
89
+ url: url
90
+ type: type
91
+ data: serializedData
92
+ statusCode:
93
+ 200: (response,textStatus,jqXHR) ->
94
+ releaseLoader $(me.loader)
95
+ console.log elem
96
+ console.log me.list
97
+ if $(me.list + ' form').attr('id')=='new_medium'
98
+ elem.prepend(response.responseText)
99
+ else
100
+ elem.replaceWith(response.responseText)
101
+ $(me.list + ' .uri-form').remove()
102
+ me.setLinks(me)
103
+ 301: (response,textStatus,jqXHR) ->
104
+ $('body').append "301 response to AJAX call: #{response}"
105
+
106
+
107
+ @MediumPane = MediumPaneClass
@@ -0,0 +1,35 @@
1
+ <div class="col s4">
2
+ <div class="card small new_upload" id="" data="" >
3
+ <div class="card-image new_upload waves-effect waves-block waves-light">
4
+ <img id="{{:id}}" src="" class="activator">
5
+ <input name="media[{{:id}}][file]" type="file" style="display:none" />
6
+ </div>
7
+ <div class="card-action">
8
+ <div class="progress fileupload-progress fade" style="display:none"><div class="determinate" style:"width:0%;"></div></div>
9
+ <div class="row">
10
+ <div class="col s12">
11
+ <!-- <i class="material-icons activator right" style="margin-top: 6px; margin-top: 5px">mort_vert</i> -->
12
+ <!-- <strong class="error text-danger"></strong> -->
13
+ <!-- <a class="edit_link file-upload" href="#!">
14
+ <i class="material-icons edit green-text">mode_edit</i>
15
+ </a> -->
16
+ <a class="start file-upload" href="#!">
17
+ <i class="material-icons file_upload green-text">file_upload</i>
18
+ </a>
19
+ <!-- <a class="cancel file-upload" href="#!">
20
+ <i class="material-icons cancel orange-text">cancel</i>
21
+ </a> -->
22
+ <a class="delete file-upload" href="#!">
23
+ <i class="material-icons delete red-text">delete</i>
24
+ </a>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ <div class="card-reveal">
29
+ <span class="card-title grey-text text-darken-4">Billed egenskaber<i class="material-icons right">close</i></span>
30
+ <p><span class="card-title grey-text text-darken-4">{{:name}}</span></p>
31
+ <p><input class="string optional" name="media[{{:id}}][name]" placeholder="Titel" /></p>
32
+ <p><textarea class="text optional materialize-textarea" name="media[{{:id}}][description]" placeholder="Beskrivelse" /></p>
33
+ </div>
34
+ </div>
35
+ </div>
@@ -0,0 +1,10 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
5
+ *= require jquery.jcrop
6
+ /*
7
+ @media only screen (min-width : 971px) and (max-width : 600px) {
8
+ .card.small { height: 180px}
9
+ span.card-title { display:none}
10
+ }*/
File without changes
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
File without changes
@@ -0,0 +1,106 @@
1
+ class MediaController < AbstractResourcesController
2
+
3
+ def update_crop
4
+ authorize resource
5
+ result = resource.new_record? ? resource.save(resource_params) : resource.update_attributes(resource_params)
6
+ render layout: false
7
+ end
8
+
9
+ def crop
10
+ authorize resource
11
+ render layout: false
12
+ end
13
+ #
14
+ # def index
15
+ # authorize Medium
16
+ # render :json => resources.collect { |p| p.to_jq_upload }.to_json
17
+ # end
18
+ #
19
+ # def create
20
+ # authorize Medium
21
+ # p_attr = resource_params #params[:media]
22
+ # p_attr[:media] = p_attr[:media].first if p_attr[:media].class == Array
23
+ #
24
+ # @resource = Medium.new(p_attr)
25
+ # if @resource.save
26
+ # respond_to do |format|
27
+ # format.html {
28
+ # render :json => [@resource.to_jq_upload].to_json,
29
+ # :content_type => 'text/html',
30
+ # :layout => false
31
+ # }
32
+ # format.json {
33
+ # render :json => { :files => [@resource.to_jq_upload] }
34
+ # }
35
+ # end
36
+ # else
37
+ # render :json => [{:error => "custom_failure"}], :status => 304
38
+ # end
39
+ # end
40
+ #
41
+ # def destroy
42
+ # authorize Medium
43
+ # @resource = Medium.find(params[:id])
44
+ # @resource.destroy
45
+ # render :json => true
46
+ # end
47
+ #
48
+ #
49
+
50
+ # before_action :set_medium, only: [:show, :edit, :update, :destroy]
51
+ #
52
+ # # GET /media
53
+ # def index
54
+ # @media = Medium.all
55
+ # end
56
+ #
57
+ # # GET /media/1
58
+ # def show
59
+ # end
60
+ #
61
+ # # GET /media/new
62
+ # def new
63
+ # @medium = Medium.new
64
+ # end
65
+ #
66
+ # # GET /media/1/edit
67
+ # def edit
68
+ # end
69
+ #
70
+ # # POST /media
71
+ # def create
72
+ # @medium = Medium.new(medium_params)
73
+ #
74
+ # if @medium.save
75
+ # redirect_to @medium, notice: 'Medium was successfully created.'
76
+ # else
77
+ # render :new
78
+ # end
79
+ # end
80
+ #
81
+ # # PATCH/PUT /media/1
82
+ # def update
83
+ # if @medium.update(medium_params)
84
+ # redirect_to @medium, notice: 'Medium was successfully updated.'
85
+ # else
86
+ # render :edit
87
+ # end
88
+ # end
89
+ #
90
+ # # DELETE /media/1
91
+ # def destroy
92
+ # @medium.destroy
93
+ # redirect_to media_url, notice: 'Medium was successfully destroyed.'
94
+ # end
95
+
96
+ private
97
+ # Use callbacks to share common setup or constraints between actions.
98
+ # def set_medium
99
+ # @medium = Medium.find(params[:id])
100
+ # end
101
+
102
+ # Only allow a trusted parameter "white list" through.
103
+ def resource_params
104
+ params.require(:medium).permit(:title, :imageable_id, :imageable_type, :medium, :medium_crop_w, :medium_crop_h, :medium_crop_y, :medium_crop_x, :lng_lat, :description)
105
+ end
106
+ end
data/app/helpers/.keep ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ module MediaHelper
2
+ end
data/app/mailers/.keep ADDED
File without changes
data/app/models/.keep ADDED
File without changes
@@ -0,0 +1,61 @@
1
+ require 'active_support/concern'
2
+
3
+ # TODO 05-05-2015 make Roleable work with other resource_class too
4
+
5
+ module Roleable
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ # has_many :somthing
10
+ enum role: [:user, :vip, :account_admin, :admin]
11
+ attr_accessor :max_role
12
+ after_initialize :set_default_role, :if => :new_record?
13
+
14
+ validates_with RoleValidator
15
+
16
+ end
17
+
18
+ module ClassMethods
19
+ def policed_roles user
20
+ User.roles.keys.map {|role| [role.titleize,role] if User.roles[role] <= User.roles[user.role] }.compact
21
+ end
22
+ end
23
+
24
+ # role management
25
+ # ---------------
26
+ # enum listing possible roles
27
+ # max_role setting the model max role to that of the current user - you never can promote anyone above your own level
28
+ # set_default_role sets the role of a new user
29
+ #
30
+
31
+ class RoleValidator < ActiveModel::Validator
32
+ attr_accessor :user
33
+ def validate(record)
34
+ @user = record
35
+ Rails.logger.info ("roles: old %s new %s" % [ User.roles[record.previous_version.role], User.roles[record.role] ] ) rescue "no previous role"
36
+ if max_role_exhausted and old_role_less_than_new
37
+ record.errors[:role] << I18n.t('.assigned_role_not_allowed')
38
+ end
39
+ end
40
+
41
+ def old_role_less_than_new
42
+ User.roles[user.previous_version.role] < User.roles[user.role]
43
+ rescue
44
+ false
45
+ end
46
+
47
+ def max_role_exhausted
48
+ User.roles[user.role] > User.roles[user.max_role]
49
+ rescue
50
+ false
51
+ end
52
+ end
53
+
54
+
55
+
56
+ def set_default_role
57
+ self.role ||= :user
58
+ end
59
+
60
+
61
+ end
@@ -0,0 +1,25 @@
1
+ class Medium < AbstractResource
2
+ belongs_to :imageable, polymorphic: true
3
+ belongs_to :account
4
+
5
+ mount_uploader :medium, MediumUploader
6
+ crop_uploaded :medium
7
+ #
8
+ # # attr_accessible :upload
9
+ # # has_attached_file :upload
10
+ # #
11
+ include Rails.application.routes.url_helpers
12
+
13
+ def to_jq_upload
14
+ {
15
+ "name" => self.medium.filename,
16
+ "size" => self.medium.size,
17
+ "url" => self.medium.url,
18
+ "thumbnailUrl" => self.medium.url,
19
+ "deleteUrl" => media_url(self, host: 'localhost:3000').gsub( '.','/'),
20
+ "deleteType" => "DELETE"
21
+ # "error": "Filetype not allowed"
22
+ }
23
+ end
24
+
25
+ end
@@ -0,0 +1,12 @@
1
+ class OxenMediumPolicy < AbstractResourcePolicy
2
+
3
+ def crop?
4
+ # @current_user.admin?
5
+ true
6
+ end
7
+
8
+ def update_crop?
9
+ true
10
+ end
11
+
12
+ end
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+ require 'carrierwave/processing/mime_types'
3
+ require 'carrierwave/crop'
4
+ require 'carrierwave'
5
+
6
+ class MediumUploader < CarrierWave::Uploader::Base
7
+
8
+ # Include RMagick or MiniMagick support:
9
+ # include CarrierWave::RMagick
10
+ # include CarrierWave::MiniMagick
11
+ include CarrierWave::MiniMagick
12
+ include CarrierWave::MimeTypes
13
+ include CarrierWave::Crop::Uploader
14
+ # include CarrierWave::Processing::MiniMagick
15
+
16
+ process :set_content_type
17
+ process crop: :medium, if: :is_image?
18
+
19
+ version :thumb do
20
+ process resize_to_fill: [200, 150], if: :is_image?
21
+
22
+ # if self.is_pdf?
23
+ # asset_path "2.jpg"
24
+ # elsif is_doc?
25
+ # asset_path "2.jpg"
26
+ # else
27
+ # asset_path "1.JPG"
28
+ # end
29
+ end
30
+
31
+ # process resize_to_limit: [400, 400]
32
+ # process :strip # strip image of all profiles and comments
33
+ # process :resize_to_fill => [200, 200]
34
+ # process :quality => 90 # Set JPEG/MIFF/PNG compression level (0-100)
35
+ # # process :convert => 'png'
36
+ # process :colorspace => :rgb # Set colorspace to rgb or cmyk
37
+ # process :blur => [0, 8] #reduce image noise and reduce detail levels [radius,sigma]
38
+
39
+ def _url version
40
+ case content_type
41
+ when /docx?|document$/; "1.JPG"
42
+ when /pdf$/; "2.jpg"
43
+ when /^image/; url
44
+ else default_url
45
+ end
46
+ end
47
+
48
+
49
+ # if Rails.env.production?
50
+ # storage :fog
51
+ # else
52
+ storage :file
53
+ # end
54
+
55
+ # Override the directory where uploaded files will be stored.
56
+ # This is a sensible default for uploaders that are meant to be mounted:
57
+ def store_dir
58
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
59
+ end
60
+
61
+ # Provide a default URL as a default if there hasn't been a file uploaded:
62
+ def default_url
63
+ # For Rails 3.1+ asset pipeline compatibility:
64
+ ActionController::Base.helpers.asset_path("" + [version_name, "default.jpg"].compact.join('_'))
65
+
66
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
67
+ end
68
+
69
+
70
+ # Process files as they are uploaded:
71
+ # process :scale => [200, 300]
72
+ #
73
+ # def scale(width, height)
74
+ # # do something
75
+ # end
76
+
77
+ # Create different versions of your uploaded files:
78
+ # version :thumb do
79
+ # process :resize_to_fit => [50, 50]
80
+ # end
81
+
82
+ # Add a white list of extensions which are allowed to be uploaded.
83
+ # For images you might use something like this:
84
+ # def extension_white_list
85
+ # %w(jpg jpeg gif png pdf zip mp4 docx xlsx)
86
+ # end
87
+
88
+ # Override the filename of the uploaded files:
89
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
90
+ # def filename
91
+ # "something.jpg" if original_filename
92
+ # end
93
+
94
+ def is_image? picture
95
+ picture.content_type =~ /jpg|png|gif/
96
+ end
97
+
98
+ def is_pdf? picture
99
+ picture.content_type =~ /pdf/
100
+ end
101
+
102
+ def is_doc? picture
103
+ picture.content_type =~ /docx?$/
104
+ end
105
+
106
+ end