sofa_gallery 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/.document +5 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +106 -0
  4. data/LICENSE +20 -0
  5. data/README.md +30 -0
  6. data/Rakefile +21 -0
  7. data/VERSION +1 -0
  8. data/app/assets/images/sofa_gallery/jcrop.gif +0 -0
  9. data/app/assets/javascripts/sofa_gallery/application.js +15 -0
  10. data/app/assets/javascripts/sofa_gallery/jquery.jcrop.js +246 -0
  11. data/app/assets/javascripts/sofa_gallery/jquery.js +18 -0
  12. data/app/assets/javascripts/sofa_gallery/jquery_ui.js +248 -0
  13. data/app/assets/javascripts/sofa_gallery/rails.js +315 -0
  14. data/app/assets/stylesheets/sofa_gallery/application.css +68 -0
  15. data/app/assets/stylesheets/sofa_gallery/jquery.jcrop.css +32 -0
  16. data/app/assets/stylesheets/sofa_gallery/reset.css +1 -0
  17. data/app/controllers/application_controller.rb +6 -0
  18. data/app/controllers/gallery_admin/base_controller.rb +3 -0
  19. data/app/controllers/gallery_admin/galleries_controller.rb +59 -0
  20. data/app/controllers/gallery_admin/photos_controller.rb +76 -0
  21. data/app/helpers/sofa_gallery_helper.rb +11 -0
  22. data/app/models/sofa/gallery.rb +17 -0
  23. data/app/models/sofa/photo.rb +64 -0
  24. data/app/views/gallery_admin/_navigation.html.erb +1 -0
  25. data/app/views/gallery_admin/galleries/_form.html.erb +11 -0
  26. data/app/views/gallery_admin/galleries/edit.html.erb +5 -0
  27. data/app/views/gallery_admin/galleries/index.html.erb +28 -0
  28. data/app/views/gallery_admin/galleries/new.html.erb +5 -0
  29. data/app/views/gallery_admin/photos/_form.html.erb +13 -0
  30. data/app/views/gallery_admin/photos/crop.html.erb +32 -0
  31. data/app/views/gallery_admin/photos/edit.html.erb +5 -0
  32. data/app/views/gallery_admin/photos/index.html.erb +24 -0
  33. data/app/views/gallery_admin/photos/new.html.erb +5 -0
  34. data/app/views/layouts/gallery_admin/application.html.erb +16 -0
  35. data/config.ru +4 -0
  36. data/config/application.rb +51 -0
  37. data/config/boot.rb +13 -0
  38. data/config/database.yml +16 -0
  39. data/config/environment.rb +5 -0
  40. data/config/environments/development.rb +25 -0
  41. data/config/environments/production.rb +52 -0
  42. data/config/environments/test.rb +39 -0
  43. data/config/initializers/paperclip.rb +3 -0
  44. data/config/initializers/sofa_gallery.rb +15 -0
  45. data/config/routes.rb +12 -0
  46. data/db/migrate/01_create_sofa_gallery.rb +35 -0
  47. data/lib/generators/README +10 -0
  48. data/lib/generators/sofa_gallery_generator.rb +33 -0
  49. data/lib/paperclip_processors/cropper.rb +18 -0
  50. data/lib/sofa_gallery.rb +23 -0
  51. data/lib/sofa_gallery/configuration.rb +26 -0
  52. data/lib/sofa_gallery/engine.rb +21 -0
  53. data/lib/sofa_gallery/form_builder.rb +50 -0
  54. data/script/rails +6 -0
  55. data/sofa_gallery.gemspec +113 -0
  56. data/test/fixtures/files/default.jpg +0 -0
  57. data/test/fixtures/files/default.txt +1 -0
  58. data/test/fixtures/sofa/galleries.yml +10 -0
  59. data/test/fixtures/sofa/photos.yml +9 -0
  60. data/test/functional/galleries_controller_test.rb +87 -0
  61. data/test/functional/photos_controller_test.rb +123 -0
  62. data/test/test_helper.rb +36 -0
  63. data/test/unit/configuration_test.rb +18 -0
  64. data/test/unit/gallery_test.rb +33 -0
  65. data/test/unit/photo_test.rb +29 -0
  66. metadata +167 -0
@@ -0,0 +1,68 @@
1
+ /*
2
+ = require sofa_gallery/reset.css
3
+ */
4
+
5
+ body {
6
+ padding: 25px;
7
+ font: 13px/18px Arial, sans-serif;
8
+ }
9
+ h1 {
10
+ font: bold 26px/34px Arial, sans-serif;
11
+ margin-bottom: 15px;
12
+ }
13
+ a {
14
+ color: #3875D7;
15
+ text-decoration: none;
16
+ }
17
+ a:hover {
18
+ text-decoration: underline;
19
+ }
20
+ table.formatted td,
21
+ table.formatted th {
22
+ padding: 2px 5px;
23
+ border-bottom: 1px dotted #ccc;
24
+ }
25
+ table.formatted th {
26
+ background-color: #666;
27
+ color: #fff;
28
+ }
29
+ table.formatted td img {
30
+ float: left;
31
+ border: 1px solid #ccc;
32
+ padding: 2px;
33
+ margin-right: 2px;
34
+ }
35
+ table.formatted td .sublabel {
36
+ font-size: 11px;
37
+ line-height: 11px;
38
+ color: #888;
39
+ }
40
+
41
+ .form_element {
42
+ overflow: hidden;
43
+ margin-bottom: 5px;
44
+ }
45
+ .form_element .label {
46
+ width: 125px;
47
+ float: left;
48
+ text-align: right;
49
+ }
50
+ .form_element .value,
51
+ .form_element .errors {
52
+ margin-left: 135px;
53
+ }
54
+ .form_element .value input[type='text'],
55
+ .form_element .value textarea {
56
+ width: 400px;
57
+ }
58
+
59
+ .jcrop-holder {
60
+ margin-bottom: 15px;
61
+ }
62
+
63
+ .flash{
64
+ border: 2px solid #ccc;
65
+ padding: 10px;
66
+ margin-bottom: 15px;
67
+ text-align: center;
68
+ }
@@ -0,0 +1,32 @@
1
+ /* Fixes issue here http://code.google.com/p/jcrop/issues/detail?id=1 */
2
+ .jcrop-holder { text-align: left; }
3
+
4
+ .jcrop-vline, .jcrop-hline {
5
+ font-size: 0px;
6
+ position: absolute;
7
+ background: white url('/assets/sofa_gallery/jcrop.gif') top left repeat;
8
+ }
9
+ .jcrop-vline { height: 100%; width: 1px !important; }
10
+ .jcrop-hline { width: 100%; height: 1px !important; }
11
+ .jcrop-vline.right { right: 0px; }
12
+ .jcrop-hline.bottom { bottom: 0px; }
13
+ .jcrop-handle {
14
+ font-size: 1px;
15
+ width: 7px !important;
16
+ height: 7px !important;
17
+ border: 1px #eee solid;
18
+ background-color: #333;
19
+ }
20
+
21
+ .jcrop-tracker { width: 100%; height: 100%; }
22
+
23
+ .custom .jcrop-vline,
24
+ .custom .jcrop-hline {
25
+ background: yellow;
26
+ }
27
+ .custom .jcrop-handle {
28
+ border-color: black;
29
+ background-color: #C7BB00;
30
+ -moz-border-radius: 3px;
31
+ -webkit-border-radius: 3px;
32
+ }
@@ -0,0 +1 @@
1
+ html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}
@@ -0,0 +1,6 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+
4
+ layout 'gallery_admin/application'
5
+
6
+ end
@@ -0,0 +1,3 @@
1
+ class GalleryAdmin::BaseController < SofaGallery.config.admin_controller.to_s.constantize
2
+ # ...
3
+ end
@@ -0,0 +1,59 @@
1
+ class GalleryAdmin::GalleriesController < GalleryAdmin::BaseController
2
+
3
+ before_filter :load_gallery, :except => [:index, :new, :create]
4
+ before_filter :build_gallery, :only => [:new, :create]
5
+
6
+ def index
7
+ @galleries = Sofa::Gallery.all
8
+ end
9
+
10
+ def new
11
+ render
12
+ end
13
+
14
+ def create
15
+ @gallery.save!
16
+ flash[:notice] = 'Gallery created'
17
+ redirect_to :action => :index
18
+ rescue ActiveRecord::RecordInvalid
19
+ flash.now[:error] = 'Failed to create Gallery'
20
+ render :action => :new
21
+ end
22
+
23
+ def show
24
+ render
25
+ end
26
+
27
+ def edit
28
+ render
29
+ end
30
+
31
+ def update
32
+ @gallery.update_attributes!(params[:gallery])
33
+ flash[:notice] = 'Gallery updated'
34
+ redirect_to :action => :index
35
+ rescue ActiveRecord::RecordInvalid
36
+ flash.now[:error] = 'Failed to update Gallery'
37
+ render :action => :edit
38
+ end
39
+
40
+ def destroy
41
+ @gallery.destroy
42
+ flash[:notice] = 'Gallery deleted'
43
+ redirect_to :action => :index
44
+ end
45
+
46
+ protected
47
+
48
+ def load_gallery
49
+ @gallery = Sofa::Gallery.find(params[:id])
50
+ rescue ActiveRecord::RecordNotFound
51
+ flash[:error] = 'Gallery not found'
52
+ redirect_to :action => :index
53
+ end
54
+
55
+ def build_gallery
56
+ @gallery = Sofa::Gallery.new(params[:gallery])
57
+ end
58
+
59
+ end
@@ -0,0 +1,76 @@
1
+ class GalleryAdmin::PhotosController < GalleryAdmin::BaseController
2
+
3
+ before_filter :load_gallery
4
+ before_filter :load_photo, :only => [:edit, :update, :destroy, :crop]
5
+ before_filter :build_photo, :only => [:new, :create]
6
+
7
+ def index
8
+ @photos = @gallery.photos
9
+ end
10
+
11
+ def new
12
+ render
13
+ end
14
+
15
+ def create
16
+ @photo.save!
17
+ flash[:notice] = 'Photo created'
18
+ redirect_to :action => :index
19
+ rescue ActiveRecord::RecordInvalid
20
+ flash[:error] = 'Failed to create Photo'
21
+ render :action => :new
22
+ end
23
+
24
+ def edit
25
+ render
26
+ end
27
+
28
+ def update
29
+ @photo.update_attributes!(params[:photo])
30
+ flash[:notice] = 'Photo updated'
31
+ redirect_to :action => :index
32
+ rescue ActiveRecord::RecordInvalid
33
+ flash.now[:error] = 'Failed to updated Photo'
34
+ render :action => :edit
35
+ end
36
+
37
+ def destroy
38
+ @photo.destroy
39
+ flash[:notice] = 'Photo deleted'
40
+ redirect_to :action => :index
41
+ end
42
+
43
+ def reorder
44
+ (params[:sofa_photo] || []).each_with_index do |id, index|
45
+ if (photo = Sofa::Photo.find_by_id(id))
46
+ photo.update_attribute(:position, index)
47
+ end
48
+ end
49
+ render :nothing => true
50
+ end
51
+
52
+ def crop
53
+ render
54
+ end
55
+
56
+ protected
57
+
58
+ def load_gallery
59
+ @gallery = Sofa::Gallery.find(params[:gallery_id])
60
+ rescue ActiveRecord::RecordNotFound
61
+ flash[:error] = 'Gallery not found'
62
+ redirect_to gallery_admin_galleries_path
63
+ end
64
+
65
+ def load_photo
66
+ @photo = @gallery.photos.find(params[:id])
67
+ rescue ActiveRecord::RecordNotFound
68
+ flash[:error] = 'Photo not found'
69
+ redirect_to :action => :index
70
+ end
71
+
72
+ def build_photo
73
+ @photo = Sofa::Photo.new({:gallery => @gallery}.merge(params[:photo] || {}))
74
+ end
75
+
76
+ end
@@ -0,0 +1,11 @@
1
+ module SofaGalleryHelper
2
+
3
+ def gallery_form_for(record_or_name_or_array, *args, &proc)
4
+ options = args.extract_options!
5
+ form_for(
6
+ record_or_name_or_array,
7
+ *(args << options.merge(:builder => SofaGallery.config.form_builder.to_s.constantize)),
8
+ &proc
9
+ )
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ class Sofa::Gallery < ActiveRecord::Base
2
+
3
+ set_table_name :sofa_galleries
4
+
5
+ # -- Relationships --------------------------------------------------------
6
+ has_many :photos, :dependent => :destroy
7
+
8
+ # -- Validations ----------------------------------------------------------
9
+ validates :title,
10
+ :presence => true
11
+
12
+ validates :slug,
13
+ :presence => true,
14
+ :uniqueness => true,
15
+ :format => { :with => /^\w[a-z0-9_-]*$/i }
16
+
17
+ end
@@ -0,0 +1,64 @@
1
+ class Sofa::Photo < ActiveRecord::Base
2
+
3
+ set_table_name :sofa_photos
4
+
5
+ upload_options = (SofaGallery.config.upload_options || {}).merge(
6
+ :styles => lambda { |image|
7
+ g = image.instance.gallery
8
+ f_settings = "#{g.full_width}x#{g.full_height}#{g.force_ratio?? '#' : '>'}"
9
+ t_settings = "#{g.thumb_width}x#{g.thumb_height}#{g.force_ratio?? '#' : '>'}"
10
+ {
11
+ :full => { :geometry => f_settings, :processors => [:cropper] },
12
+ :thumb => { :geometry => t_settings, :processors => [:cropper] },
13
+ :admin_full => '800x600>',
14
+ :admin_thumb => '40x30#'
15
+ }
16
+ }
17
+ )
18
+ has_attached_file :image, upload_options
19
+
20
+ attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
21
+
22
+ # -- Relationships --------------------------------------------------------
23
+ belongs_to :gallery
24
+
25
+ # -- Callbacks ------------------------------------------------------------
26
+ before_create :assign_position
27
+ after_update :reprocess_image, :if => :cropping?
28
+
29
+ # -- Validations ----------------------------------------------------------
30
+ validates :gallery_id,
31
+ :presence => true
32
+ validates_attachment_presence :image,
33
+ :message => 'There was no file uploaded!'
34
+ validates_attachment_content_type :image,
35
+ :content_type => %w(image/jpeg image/pjpeg image/gif image/png image/x-png),
36
+ :message => 'Please only upload .jpg, .jpeg, .gif or .png files.'
37
+ validates_attachment_size :image,
38
+ :less_than => 5.megabytes
39
+
40
+ # -- Scopes ---------------------------------------------------------------
41
+ default_scope order(:position)
42
+
43
+ # -- Instance Methods -----------------------------------------------------
44
+ def image_geometry(style = :original)
45
+ @geometry ||= {}
46
+ @geometry[style] ||= Paperclip::Geometry.from_file(image.path(style))
47
+ end
48
+
49
+ def cropping?
50
+ !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
51
+ end
52
+
53
+ private
54
+
55
+ def assign_position
56
+ max = self.gallery.photos.maximum(:position)
57
+ self.position = max ? max + 1 : 0
58
+ end
59
+
60
+ def reprocess_image
61
+ image.reprocess!
62
+ end
63
+
64
+ end
@@ -0,0 +1 @@
1
+ <li><%= active_link_to 'Galleries', gallery_admin_galleries_path %></li>
@@ -0,0 +1,11 @@
1
+ <%= form.text_field :title, :id => (@gallery.new_record?? 'slugify' : nil)%>
2
+ <%= form.text_field :slug, :id => 'slug' %>
3
+ <%= form.text_area :description%>
4
+
5
+ <%= form.text_field :full_width %>
6
+ <%= form.text_field :full_height %>
7
+ <%= form.text_field :thumb_width %>
8
+ <%= form.text_field :thumb_height %>
9
+ <%= form.check_box :force_ratio %>
10
+
11
+ <%= form.submit 'Save'%>
@@ -0,0 +1,5 @@
1
+ <h1>Editing <%= @gallery.title %></h1>
2
+
3
+ <%= gallery_form_for @gallery, :as => :gallery, :url => { :action => :update } do |form|%>
4
+ <%= render :partial => form %>
5
+ <% end %>
@@ -0,0 +1,28 @@
1
+ <%= link_to 'Add new gallery', new_gallery_admin_gallery_path, :class => 'big button' %>
2
+
3
+ <h1>Galleries</h1>
4
+
5
+ <table class='formatted'>
6
+ <% @galleries.each do |gallery| %>
7
+ <tr>
8
+ <td>
9
+ <div class='title'>
10
+ <%= link_to gallery.title, gallery_admin_gallery_photos_path(gallery) %>
11
+ </div>
12
+ <div class='sublabel'>
13
+ <%= gallery.slug %>
14
+ </div>
15
+ </td>
16
+ <td class='main'>
17
+ <% gallery.photos.limit(5).each do |photo| %>
18
+ <%= image_tag(photo.image.url(:admin_thumb)) %>
19
+ <% end %>
20
+ </td>
21
+ <td class='action_links'>
22
+ <%= link_to 'Show Photos', gallery_admin_gallery_photos_path(gallery) %>
23
+ <%= link_to 'Edit', edit_gallery_admin_gallery_path(gallery) %>
24
+ <%= link_to 'Delete', gallery_admin_gallery_path(gallery), :method => :delete, :confirm => 'Are you sure?' %>
25
+ </td>
26
+ </tr>
27
+ <% end %>
28
+ </table>
@@ -0,0 +1,5 @@
1
+ <h1>New Gallery</h1>
2
+
3
+ <%= gallery_form_for @gallery, :as => :gallery, :url => { :action => :create } do |form| %>
4
+ <%= render :partial => form %>
5
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <%= form.text_field :title, :id => (@photo.new_record?? 'slugify' : nil) %>
2
+ <%= form.text_field :slug, :id => 'slug' %>
3
+ <% if @photo.image? %>
4
+ <%= form.simple_field 'Current Image' do %>
5
+ <%= image_tag(@photo.image.url(:thumb)) %>
6
+ <br/>
7
+ <%= link_to 'Crop Image', crop_gallery_admin_gallery_photo_path(@gallery, @photo) %>
8
+ <% end %>
9
+ <% end %>
10
+ <%= form.file_field :image %>
11
+ <%= form.text_area :description %>
12
+
13
+ <%= form.submit 'Save'%>
@@ -0,0 +1,32 @@
1
+ <% content_for :head do %>
2
+ <%= stylesheet_link_tag 'sofa_gallery/jquery.jcrop.css' %>
3
+ <%= javascript_include_tag 'sofa_gallery/jquery.jcrop.js' %>
4
+ <script type="text/javascript" charset="utf-8">
5
+ $(function(){
6
+ $('#cropbox').Jcrop({
7
+ onChange: update_crop,
8
+ onSelect: update_crop,
9
+ aspectRatio: <%= @photo.gallery.force_ratio?? (@photo.gallery.full_width.to_f / @photo.gallery.full_height) : 'null' %>
10
+ });
11
+ });
12
+
13
+ function update_crop(coords) {
14
+ var ratio = <%= @photo.image_geometry(:original).width %> / <%= @photo.image_geometry(:admin_full).width %>;
15
+ $('#crop_x').val(coords.x * ratio);
16
+ $('#crop_y').val(coords.y * ratio);
17
+ $('#crop_w').val(coords.w * ratio);
18
+ $('#crop_h').val(coords.h * ratio);
19
+ }
20
+ </script>
21
+ <% end %>
22
+
23
+ <h1> Crop Photo </h1>
24
+
25
+ <%= image_tag @photo.image.url(:admin_full), :id => 'cropbox' %>
26
+
27
+ <%= gallery_form_for @photo, :as => :photo, :url => { :action => :update } do |form| %>
28
+ <% [:crop_x, :crop_y, :crop_w, :crop_h].each do |attr| %>
29
+ <%= form.hidden_field attr, :id => attr %>
30
+ <% end %>
31
+ <%= form.submit 'Crop' %>
32
+ <% end %>