spud_media 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/Readme.markdown CHANGED
@@ -1,6 +1,6 @@
1
1
  # Spud Media
2
2
 
3
- Spud Media is an engine for managing documents and other media miscellaneous files, designed for use with [Spud][1].
3
+ Spud Media is an engine for managing documents and other miscellaneous media files, designed for use with [Spud][1].
4
4
 
5
5
  ## Installation/Usage
6
6
 
@@ -20,17 +20,17 @@ Spud Media is an engine for managing documents and other media miscellaneous fil
20
20
 
21
21
  Spud Photos accepts the following configuration options:
22
22
 
23
- Spud::Media.configure do |config|
23
+ Spud::Media.configure do |config|
24
24
 
25
- # s3 storage requires the 'aws-sdk' gem. defaults to filesystem
26
- config.paperclip_storage = :s3
27
- config.s3_credentials = "#{Rails.root}/config/s3.yml"
25
+ # s3 storage requires the 'aws-sdk' gem. defaults to filesystem
26
+ config.paperclip_storage = :s3
27
+ config.s3_credentials = "#{Rails.root}/config/s3.yml"
28
28
 
29
29
  # see below for notes on 'storage_path_protected'
30
- config.storage_path = "public/system/spud_media/:id/:style/:basename.:extension"
31
- config.storage_path_protected = "public/system/spud_media_protected/:id/:style/:basename.:extension"
32
- config.storage_url = "/system/spud_media/:id/:style/:basename.:extension"
33
- end
30
+ config.storage_path = "public/system/spud_media/:id/:style/:basename.:extension"
31
+ config.storage_path_protected = "public/system/spud_media_protected/:id/:style/:basename.:extension"
32
+ config.storage_url = "/system/spud_media/:id/:style/:basename.:extension"
33
+ end
34
34
 
35
35
  ## File Protection
36
36
 
@@ -42,7 +42,7 @@ Unprotected files are stored under `/public/system/spud_media` and are accessed
42
42
 
43
43
  Protected files are moved to `public/system/spud_media_protected`. Note that the public-facing download URL should __not__ reflect the `protected` storage path. Instead the user will hit the same URL as before, but this time their request will hit the `show` action of the `ProtectedMedia` controller.
44
44
 
45
- It is up to the individual developer to make sure that the protected storage path is not accessible by the public. You may choose to protect this folder via server configurations, or you can move the folder out of the document root using `config.storage_path_protected`.
45
+ __It is up to the individual developer to make sure that the protected storage path is not accessible by the public.__ You may choose to protect this folder via server configurations, or you can move the folder out of the document root using `config.storage_path_protected`.
46
46
 
47
47
  ### Amazon S3
48
48
 
@@ -0,0 +1,176 @@
1
+ //= require jcrop/js/jquery.Jcrop
2
+ //= require_self
3
+
4
+ Spud = (typeof(Spud) == 'undefined') ? {} : Spud;
5
+ Spud.Admin = (typeof(Spud.Admin) == 'undefined') ? {} : Spud.Admin;
6
+
7
+ Spud.Admin.Media = new function(){
8
+
9
+ var self = this;
10
+ var cropimage;
11
+ var cropcontainer;
12
+ var croptarget;
13
+ var cropscale;
14
+ var maxcropscale;
15
+ var cropscaleincrement;
16
+ var originalWidth;
17
+ var originalHeight;
18
+ var cropartbox;
19
+ var jcrop;
20
+
21
+ this.edit = function(){
22
+ cropimage = $('#spud_media_cropper_image');
23
+ // IE8 isn't handling the image load event properly, so...
24
+ setTimeout(function(){
25
+ if(cropimage[0].complete){
26
+ self.initializeEditor();
27
+ }
28
+ else{
29
+ self.edit();
30
+ }
31
+ }, 50);
32
+ };
33
+
34
+ this.initializeEditor = function(){
35
+
36
+ // cache some selectors
37
+ cropcontainer = $('#spud_media_cropper_jcrop_container');
38
+ cropartbox = $('#spud_media_cropper');
39
+
40
+ // get the original dimensions before scaling the image down
41
+ originalWidth = cropimage.width();
42
+ originalHeight = cropimage.height();
43
+
44
+ // the max width is 900px (at least until the UI can handle more than that)
45
+ if(originalWidth > 900){
46
+ maxcropscale = Math.floor(900 / originalWidth * 100);
47
+ }
48
+ else{
49
+ maxcropscale = 100;
50
+ }
51
+ cropscaleincrement = Math.ceil(3.0 * (maxcropscale / 100));
52
+
53
+ // scale down the original if necessary
54
+ cropscale = parseInt($('#spud_media_crop_s').val());
55
+ if(cropscale > maxcropscale){
56
+ $('#spud_media_crop_s').val(maxcropscale);
57
+ cropscale = maxcropscale;
58
+ }
59
+
60
+ // if this is a new image, width and hight will be null. set some starter values.
61
+ if(!$('#spud_media_crop_w').val()){
62
+ $('#spud_media_crop_w').val(originalWidth * (maxcropscale / 100));
63
+ $('#spud_media_crop_h').val(originalHeight * (maxcropscale / 100));
64
+ }
65
+
66
+ // update height of artbox to match height of scaled image
67
+ cropartbox.height(originalHeight * (maxcropscale / 100));
68
+
69
+ self.resizeAndCenter(cropscale);
70
+
71
+ $('body').on('change', '#spud_media_crop_s', self.changedMediaCropScale);
72
+ $('body').on('click', '#spud_media_cropper_resize_up, #spud_media_cropper_resize_down', self.incrementMediaCropScale);
73
+ $('body').on('change', '#spud_media_crop_x, #spud_media_crop_y, #spud_media_crop_w, #spud_media_crop_h', self.changedMediaCropDimensions);
74
+ $('body').on('keypress', 'form input[type=text]', self.preventSubmitOnEnterKey);
75
+ };
76
+
77
+ this.resizeAndCenter = function(percent){
78
+
79
+ // destroy the jcrop object if it exists already
80
+ if(jcrop){
81
+ jcrop.destroy();
82
+ }
83
+
84
+ // initialize jcrop. snap to pre-existing selection if one exists.
85
+ var _width = Math.min(900, (originalWidth * (percent / 100)));
86
+ var _height = originalHeight * (_width / originalWidth);
87
+ cropimage.Jcrop({
88
+ boxWidth:_width,
89
+ boxHeight:_height,
90
+ onChange:self.updateCropCoordinates,
91
+ onSelect:self.updateCropCoordinates,
92
+ setSelect:self.getSelectFields()
93
+ },
94
+ function(){
95
+ jcrop = this;
96
+ }
97
+ );
98
+
99
+ // using the outer container, center the jcrop object in the artboard
100
+ var _left = (900 - _width) / 2;
101
+ var _top = (cropartbox.height() - _height) / 6;
102
+ cropcontainer.css({
103
+ left:_left,
104
+ top:_top
105
+ });
106
+ };
107
+
108
+ this.updateCropCoordinates = function(c){
109
+ $('#spud_media_crop_x').val(Math.floor(c.x * (cropscale / 100)));
110
+ $('#spud_media_crop_y').val(Math.floor(c.y * (cropscale / 100)));
111
+ $('#spud_media_crop_w').val(Math.floor(c.w * (cropscale / 100)));
112
+ $('#spud_media_crop_h').val(Math.floor(c.h * (cropscale / 100)));
113
+ };
114
+
115
+ this.changedMediaCropScale = function(e){
116
+ var val = $(this).val();
117
+ var percent = parseInt(val);
118
+ if(!percent || percent > maxcropscale){
119
+ $(this).val(maxcropscale);
120
+ }
121
+ else{
122
+ $(this).val(percent);
123
+ cropscale = percent;
124
+ self.resizeAndCenter(percent);
125
+ }
126
+ };
127
+
128
+ this.incrementMediaCropScale = function(e){
129
+ var id = $(this).attr('id');
130
+ if(id == 'spud_media_cropper_resize_up'){
131
+ cropscale = Math.min(maxcropscale, cropscale+cropscaleincrement);
132
+ }
133
+ else{
134
+ cropscale = Math.max(0, cropscale-cropscaleincrement);
135
+ }
136
+ $('#spud_media_crop_s').val(cropscale);
137
+ self.resizeAndCenter(cropscale);
138
+ return false;
139
+ }
140
+
141
+ this.changedMediaCropDimensions = function(e){
142
+ var selection = self.getSelectFields();
143
+ if(selection){
144
+ jcrop.setSelect(selection);
145
+ }
146
+ };
147
+
148
+ this.getSelectFields = function(){
149
+ var x = parseInt($('#spud_media_crop_x').val());
150
+ var y = parseInt($('#spud_media_crop_y').val());
151
+ var w = parseInt($('#spud_media_crop_w').val());
152
+ var h = parseInt($('#spud_media_crop_h').val());
153
+ var x2 = x + w;
154
+ var y2 = y + h;
155
+ if(isNaN(x) || isNaN(w) || isNaN(x2) || isNaN(y2)){
156
+ return false;
157
+ }
158
+ else{
159
+ return [x * (100 / cropscale), y * (100 / cropscale), x2 * (100 / cropscale), y2 * (100 / cropscale)];
160
+ }
161
+ }
162
+
163
+ this.preventSubmitOnEnterKey = function(e){
164
+ if(e.keyCode == 13) {
165
+ e.preventDefault();
166
+ // need to prevent the form submit, but still fire the value change events
167
+ if($(this).attr('id') == 'spud_media_crop_s'){
168
+ self.changedMediaCropScale.apply(this, [e]);
169
+ }
170
+ else{
171
+ self.changedMediaCropDimensions(e);
172
+ }
173
+ return false;
174
+ }
175
+ };
176
+ };
Binary file
@@ -0,0 +1,86 @@
1
+ /* jquery.Jcrop.css v0.9.10 - MIT License */
2
+
3
+ /*
4
+ The outer-most container in a typical Jcrop instance
5
+ If you are having difficulty with formatting related to styles
6
+ on a parent element, place any fixes here or in a like selector
7
+
8
+ You can also style this element if you want to add a border, etc
9
+ A better method for styling can be seen below with .jcrop-light
10
+ (Add a class to the holder and style elements for that extended class)
11
+ */
12
+ .jcrop-holder {
13
+ direction: ltr;
14
+ text-align: left;
15
+ }
16
+
17
+ /* These styles define the border lines */
18
+ .jcrop-vline,.jcrop-hline{background:#FFF url(/assets/jcrop/css/Jcrop.gif) top left repeat;font-size:0;position:absolute;}
19
+ .jcrop-vline{height:100%;width:1px!important;}
20
+ .jcrop-hline{height:1px!important;width:100%;}
21
+ .jcrop-vline.right{right:0;}
22
+ .jcrop-hline.bottom{bottom:0;}
23
+
24
+ /* Handle style - size is set by Jcrop handleSize option (currently) */
25
+ .jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
26
+
27
+ /* This style is used for invisible click targets */
28
+ .jcrop-tracker
29
+ {
30
+ height: 100%;
31
+ width: 100%;
32
+ -webkit-tap-highlight-color: transparent; /* "turn off" link highlight */
33
+ -webkit-touch-callout: none; /* disable callout, image save panel */
34
+ -webkit-user-select: none; /* disable cut copy paste */
35
+ }
36
+
37
+ /* Positioning of handles and drag bars */
38
+ .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
39
+ .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
40
+ .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
41
+ .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
42
+ .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
43
+ .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
44
+ .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
45
+ .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
46
+ .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
47
+ .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
48
+ .jcrop-dragbar.ord-n{margin-top:-4px;}
49
+ .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
50
+ .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
51
+ .jcrop-dragbar.ord-w{margin-left:-4px;}
52
+
53
+ /* The "jcrop-light" class/extension */
54
+ .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline
55
+ {
56
+ background:#FFF;
57
+ filter:Alpha(opacity=70)!important;
58
+ opacity:.70!important;
59
+ }
60
+ .jcrop-light .jcrop-handle
61
+ {
62
+ -moz-border-radius:3px;
63
+ -webkit-border-radius:3px;
64
+ background-color:#000;
65
+ border-color:#FFF;
66
+ border-radius:3px;
67
+ }
68
+
69
+ /* The "jcrop-dark" class/extension */
70
+ .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline
71
+ {
72
+ background:#000;
73
+ filter:Alpha(opacity=70)!important;
74
+ opacity:.7!important;
75
+ }
76
+ .jcrop-dark .jcrop-handle
77
+ {
78
+ -moz-border-radius:3px;
79
+ -webkit-border-radius:3px;
80
+ background-color:#FFF;
81
+ border-color:#000;
82
+ border-radius:3px;
83
+ }
84
+
85
+ /* Fix for twitter bootstrap et al. */
86
+ .jcrop-holder img,img.jcrop-preview{ max-width: none; }
@@ -0,0 +1,28 @@
1
+ /* jquery.Jcrop.min.css v0.9.10 (build:20120429) */
2
+ .jcrop-holder{direction:ltr;text-align:left;}
3
+ .jcrop-vline,.jcrop-hline{background:#FFF url(/assets/jcrop/css/Jcrop.gif) top left repeat;font-size:0;position:absolute;}
4
+ .jcrop-vline{height:100%;width:1px!important;}
5
+ .jcrop-hline{height:1px!important;width:100%;}
6
+ .jcrop-vline.right{right:0;}
7
+ .jcrop-hline.bottom{bottom:0;}
8
+ .jcrop-handle{background-color:#333;border:1px #eee solid;font-size:1px;}
9
+ .jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;}
10
+ .jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;}
11
+ .jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;}
12
+ .jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;}
13
+ .jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;}
14
+ .jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;}
15
+ .jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;}
16
+ .jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;}
17
+ .jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;}
18
+ .jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;}
19
+ .jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;}
20
+ .jcrop-dragbar.ord-n{margin-top:-4px;}
21
+ .jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;}
22
+ .jcrop-dragbar.ord-e{margin-right:-4px;right:0;}
23
+ .jcrop-dragbar.ord-w{margin-left:-4px;}
24
+ .jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:Alpha(opacity=70)!important;opacity:.70!important;}
25
+ .jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;}
26
+ .jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:Alpha(opacity=70)!important;opacity:.7!important;}
27
+ .jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;}
28
+ .jcrop-holder img,img.jcrop-preview{max-width:none;}