dailyshare 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -2
- data/lib/dailyshare.rb +4 -11
- data/lib/dailyshare/controllers.rb +111 -0
- data/lib/dailyshare/{helpers/helpers.rb → helpers.rb} +51 -0
- data/lib/dailyshare/models.rb +122 -0
- data/lib/dailyshare/version.rb +1 -1
- metadata +5 -8
- data/lib/dailyshare/controllers/admin.rb +0 -65
- data/lib/dailyshare/controllers/main.rb +0 -51
- data/lib/dailyshare/helpers/entry.rb +0 -51
- data/lib/dailyshare/models/member.rb +0 -36
- data/lib/dailyshare/models/photo.rb +0 -87
data/Gemfile
CHANGED
data/lib/dailyshare.rb
CHANGED
@@ -20,17 +20,10 @@ Encoding.default_internal = Encoding::UTF_8
|
|
20
20
|
require 'linguistics'
|
21
21
|
Linguistics::use(:en)
|
22
22
|
|
23
|
-
|
24
|
-
require 'dailyshare/
|
25
|
-
require 'dailyshare/
|
26
|
-
|
27
|
-
# load models
|
28
|
-
require 'dailyshare/models/member'
|
29
|
-
require 'dailyshare/models/photo'
|
30
|
-
|
31
|
-
# load controllers
|
32
|
-
require 'dailyshare/controllers/admin'
|
33
|
-
require 'dailyshare/controllers/main'
|
23
|
+
require 'dailyshare/helpers'
|
24
|
+
require 'dailyshare/models'
|
25
|
+
require 'dailyshare/models'
|
26
|
+
require 'dailyshare/controllers'
|
34
27
|
|
35
28
|
module DailyShare
|
36
29
|
class App < Sinatra::Base
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module DailyShare
|
2
|
+
|
3
|
+
class App < Sinatra::Base
|
4
|
+
|
5
|
+
|
6
|
+
get '/' do
|
7
|
+
context = context_from_date(Date.today)
|
8
|
+
@title = "#{CONFIG['seo']['title']} - day #{context[:count]}"
|
9
|
+
slim :index, :locals => context
|
10
|
+
end
|
11
|
+
|
12
|
+
get '/:y/:m/:d' do
|
13
|
+
begin
|
14
|
+
date = date_from_params(params)
|
15
|
+
context = context_from_date(date)
|
16
|
+
@title = "#{CONFIG['seo']['title']} - day #{context[:count]}"
|
17
|
+
rescue
|
18
|
+
pass
|
19
|
+
end
|
20
|
+
|
21
|
+
if valid_date?(date)
|
22
|
+
slim :index, :locals => context
|
23
|
+
else
|
24
|
+
redirect request.referrer
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/:name' do
|
29
|
+
if (member = Member.byName(params[:name])).nil?
|
30
|
+
redirect request.referrer
|
31
|
+
end
|
32
|
+
|
33
|
+
slim :member, :locals => { :member => member }
|
34
|
+
end
|
35
|
+
|
36
|
+
get '/:name/missing' do
|
37
|
+
if (member = Member.byName(params[:name])).nil?
|
38
|
+
redirect request.referrer
|
39
|
+
end
|
40
|
+
slim :member_missing, :locals => { :photos => member.missingPhotos }
|
41
|
+
end
|
42
|
+
|
43
|
+
get '/admin' do
|
44
|
+
protected!
|
45
|
+
redirect '/'
|
46
|
+
end
|
47
|
+
|
48
|
+
get '/logout' do
|
49
|
+
session.delete(:member_id)
|
50
|
+
session.delete(:member_name)
|
51
|
+
status 401
|
52
|
+
slim :logout
|
53
|
+
end
|
54
|
+
|
55
|
+
post '/upload' do
|
56
|
+
protected!
|
57
|
+
if params[:file]
|
58
|
+
save_photo(params, params[:file][:tempfile])
|
59
|
+
end
|
60
|
+
redirect request.referrer
|
61
|
+
end
|
62
|
+
|
63
|
+
post '/edit' do
|
64
|
+
protected!
|
65
|
+
puts params
|
66
|
+
|
67
|
+
photo = Photo[:id=>params[:photo_id]]
|
68
|
+
if photo
|
69
|
+
photo.update_fields(params, [:title, :description])
|
70
|
+
end
|
71
|
+
|
72
|
+
redirect request.referrer
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Receive emailed photos via Postmark.
|
77
|
+
#
|
78
|
+
post '/receiver' do
|
79
|
+
# parse post data
|
80
|
+
data = JSON.parse(request.body.read)
|
81
|
+
|
82
|
+
# grab image data
|
83
|
+
image = data['Attachments'][0]['Content']
|
84
|
+
|
85
|
+
# check which member this is based on sender
|
86
|
+
member = Member[:email=>data['From']]
|
87
|
+
|
88
|
+
# was there a member with that email?
|
89
|
+
if !member.nil?
|
90
|
+
|
91
|
+
# get most recent photo
|
92
|
+
recent = member.mostRecentPhoto
|
93
|
+
|
94
|
+
# only continue if a photo doesn't exist for today
|
95
|
+
if !recent.nil? && recent.date_added+1 <= Date.today
|
96
|
+
|
97
|
+
# prep params for submission
|
98
|
+
params = {
|
99
|
+
:member_id => member.id,
|
100
|
+
:title => data['Subject'],
|
101
|
+
:description => data['TextBody'],
|
102
|
+
:date_added => recent.date_added+1
|
103
|
+
}
|
104
|
+
save_photo(params,StringIO.new(Base64.decode64(image)))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
@@ -142,5 +142,56 @@ module DailyShare
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
+
def date_from_params(params)
|
146
|
+
if params[:y] && params[:m] && params[:d]
|
147
|
+
Date.parse("#{params[:y]}-#{params[:m]}-#{params[:d]}")
|
148
|
+
else
|
149
|
+
Date.today
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def valid_date?(date)
|
154
|
+
(date.year > 2011 || date <= Date.today)
|
155
|
+
end
|
156
|
+
|
157
|
+
def context_from_date(date)
|
158
|
+
edition = (date.strftime('%Y').to_i)-(CONFIG['dailyshare']['start'].strftime('%Y').to_i)
|
159
|
+
{
|
160
|
+
:ymd => date.strftime('%Y-%m-%d'),
|
161
|
+
:date => date,
|
162
|
+
:year => (edition+1).en.numwords,
|
163
|
+
:count => (((date-CONFIG['dailyshare']['start']).to_i)-((edition)*365).to_i).en.numwords,
|
164
|
+
:members => Member.order(:id).all
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def prev_entry(date)
|
169
|
+
(date-1).strftime('/%Y/%m/%d/')
|
170
|
+
end
|
171
|
+
|
172
|
+
def next_entry(date)
|
173
|
+
(date+1).strftime('/%Y/%m/%d/')
|
174
|
+
end
|
175
|
+
|
176
|
+
def save_photo(params, file)
|
177
|
+
begin
|
178
|
+
photo = Photo.new
|
179
|
+
photo.set_fields(params, [:title, :description, :date_added, :member_id])
|
180
|
+
puts photo.inspect
|
181
|
+
photo.save_original(file)
|
182
|
+
photo.generate_sizes
|
183
|
+
photo.save_to_s3
|
184
|
+
rescue
|
185
|
+
false
|
186
|
+
else
|
187
|
+
photo.save
|
188
|
+
send_email(
|
189
|
+
CONFIG['email']['to'],
|
190
|
+
"new submisson",
|
191
|
+
slim(:'emails/uploaded', {:locals=>{:photo=>photo},:layout=>false})
|
192
|
+
)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
145
196
|
end
|
146
197
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "stringio"
|
2
|
+
|
3
|
+
module DailyShare
|
4
|
+
class Photo < Sequel::Model
|
5
|
+
many_to_one :member
|
6
|
+
|
7
|
+
def before_save
|
8
|
+
description.strip!
|
9
|
+
end
|
10
|
+
|
11
|
+
def file(size)
|
12
|
+
case size
|
13
|
+
when :original
|
14
|
+
"#{date_added}-#{member.name}.jpg"
|
15
|
+
when :thumb
|
16
|
+
"#{date_added}-#{member.name}-thumb.jpg"
|
17
|
+
when :big
|
18
|
+
"#{date_added}-#{member.name}-big.jpg"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def url(size)
|
23
|
+
"#{CONFIG['url']['cdn']}/photos/#{file(size)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def save_original(tmpfile)
|
27
|
+
image = File.join(CONFIG['photo_dir'],file(:original))
|
28
|
+
File.open(image,'wb') {|f| f.write(tmpfile.read) }
|
29
|
+
image
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_sizes
|
33
|
+
img = Magick::Image::read(File.join(CONFIG['photo_dir'],file(:original))).first
|
34
|
+
if img
|
35
|
+
img.resize_to_fit(240,240).write(File.join(CONFIG['photo_dir'],file(:thumb)))
|
36
|
+
img.resize_to_fit(960,680).write(File.join(CONFIG['photo_dir'],file(:big)))
|
37
|
+
img.destroy!
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def sizes
|
45
|
+
[File.join(CONFIG['photo_dir'],file(:original)),
|
46
|
+
File.join(CONFIG['photo_dir'],file(:thumb)),
|
47
|
+
File.join(CONFIG['photo_dir'],file(:big))]
|
48
|
+
end
|
49
|
+
|
50
|
+
def save_to_s3
|
51
|
+
sizes.each do |file|
|
52
|
+
AWS::S3::S3Object.store(
|
53
|
+
"/photos/#{File.basename(file)}",
|
54
|
+
open(file),
|
55
|
+
AUTH['aws']['bucket'],
|
56
|
+
{
|
57
|
+
:cache_control => 'max-age=315360000',
|
58
|
+
:access => 'public_read'
|
59
|
+
}
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_exif
|
65
|
+
img = EXIFR::JPEG.new(file)
|
66
|
+
|
67
|
+
# store fstop/focal length for comparison
|
68
|
+
fstop = img.exif[:f_number].to_f
|
69
|
+
flen = img.exif[:focal_length].to_f
|
70
|
+
|
71
|
+
{
|
72
|
+
# if no decimal is needed, leave it off
|
73
|
+
:fstop => (fstop == fstop.to_i ? fstop.to_i : fstop),
|
74
|
+
# convert exposure to string
|
75
|
+
:exposure => img.exif[:exposure_time].to_s,
|
76
|
+
# if no decimal is needed, leave it off
|
77
|
+
:focal_length => (flen == flen.to_i ? flen.to_i : flen).to_s+'mm'
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
module DailyShare
|
86
|
+
class Member < Sequel::Model
|
87
|
+
one_to_many :photos
|
88
|
+
|
89
|
+
def self.byName(name)
|
90
|
+
self[:name=>name]
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.byEmail(email)
|
94
|
+
self[:email=>email.downcase]
|
95
|
+
end
|
96
|
+
|
97
|
+
def missingPhotos
|
98
|
+
DB["SELECT
|
99
|
+
date('2012-01-01'::date+(interval '1 day'*s.num)) AS date
|
100
|
+
FROM
|
101
|
+
(SELECT generate_series(0,now()::date-'2012-01-01'::date) AS num) AS s
|
102
|
+
WHERE
|
103
|
+
(SELECT
|
104
|
+
true
|
105
|
+
FROM
|
106
|
+
photos
|
107
|
+
WHERE
|
108
|
+
date_added=date('2012-01-01'::date+(interval '1 day'*s.num))
|
109
|
+
AND
|
110
|
+
member_id=?) IS null",id]
|
111
|
+
end
|
112
|
+
|
113
|
+
def mostRecentPhoto
|
114
|
+
photos_dataset.order(:date_added.desc).first
|
115
|
+
end
|
116
|
+
|
117
|
+
def submissionByDate(date)
|
118
|
+
photos_dataset.where(:date_added=>date).first
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
data/lib/dailyshare/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dailyshare
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: linguistics
|
@@ -104,12 +104,9 @@ files:
|
|
104
104
|
- Rakefile
|
105
105
|
- dailyshare.gemspec
|
106
106
|
- lib/dailyshare.rb
|
107
|
-
- lib/dailyshare/controllers
|
108
|
-
- lib/dailyshare/
|
109
|
-
- lib/dailyshare/
|
110
|
-
- lib/dailyshare/helpers/helpers.rb
|
111
|
-
- lib/dailyshare/models/member.rb
|
112
|
-
- lib/dailyshare/models/photo.rb
|
107
|
+
- lib/dailyshare/controllers.rb
|
108
|
+
- lib/dailyshare/helpers.rb
|
109
|
+
- lib/dailyshare/models.rb
|
113
110
|
- lib/dailyshare/version.rb
|
114
111
|
homepage: https://github.com/tkellen/ruby-dailyshare
|
115
112
|
licenses: []
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'base64'
|
2
|
-
|
3
|
-
module DailyShare
|
4
|
-
|
5
|
-
class App < Sinatra::Base
|
6
|
-
|
7
|
-
get '/admin' do
|
8
|
-
protected!
|
9
|
-
redirect '/'
|
10
|
-
end
|
11
|
-
|
12
|
-
post '/upload/:date_added/:name' do
|
13
|
-
protected!
|
14
|
-
if params[:file]
|
15
|
-
params[:member_id] = Member.byName(params[:name]).id
|
16
|
-
save_photo(params,params[:file][:tempfile])
|
17
|
-
end
|
18
|
-
redirect request.referrer
|
19
|
-
end
|
20
|
-
|
21
|
-
post '/edit/:date/:name' do
|
22
|
-
protected!
|
23
|
-
|
24
|
-
member = Member.byName(params[:name])
|
25
|
-
photo = Photo.by_date_and_member(params[:date],member)
|
26
|
-
photo.update_fields(params,[:title,:description])
|
27
|
-
|
28
|
-
redirect request.referrer
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# Receive emailed photos via Postmark.
|
33
|
-
#
|
34
|
-
post '/receiver' do
|
35
|
-
# parse post data
|
36
|
-
data = JSON.parse(request.body.read)
|
37
|
-
|
38
|
-
# grab image data
|
39
|
-
image = data['Attachments'][0]['Content']
|
40
|
-
|
41
|
-
# check which member this is based on sender
|
42
|
-
member = Member[:email=>data['From']]
|
43
|
-
|
44
|
-
# was there a member with that email?
|
45
|
-
if !member.nil?
|
46
|
-
|
47
|
-
# get most recent photo
|
48
|
-
recent = Photo.most_recent_by_member(member)
|
49
|
-
|
50
|
-
# only continue if a photo doesn't exist for today
|
51
|
-
if !recent.nil? && recent.date_added+1 <= Date.today
|
52
|
-
|
53
|
-
# prep params for submission
|
54
|
-
params = {
|
55
|
-
:member_id => member.id,
|
56
|
-
:title => data['Subject'],
|
57
|
-
:description => data['TextBody'],
|
58
|
-
:date_added => recent.date_added+1
|
59
|
-
}
|
60
|
-
save_photo(params,StringIO.new(Base64.decode64(image)))
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module DailyShare
|
2
|
-
|
3
|
-
class App < Sinatra::Base
|
4
|
-
|
5
|
-
get '/' do
|
6
|
-
context = context_from_date(Date.today)
|
7
|
-
@title = "#{CONFIG['seo']['title']} - day #{context[:count]}"
|
8
|
-
slim :index, :locals => context
|
9
|
-
end
|
10
|
-
|
11
|
-
get '/logout' do
|
12
|
-
session.delete(:member_id)
|
13
|
-
session.delete(:member_name)
|
14
|
-
status 401
|
15
|
-
slim :logout
|
16
|
-
end
|
17
|
-
|
18
|
-
get '/:y/:m/:d' do
|
19
|
-
begin
|
20
|
-
date = date_from_params(params)
|
21
|
-
context = context_from_date(date)
|
22
|
-
@title = "#{CONFIG['seo']['title']} - day #{context[:count]}"
|
23
|
-
rescue
|
24
|
-
pass
|
25
|
-
end
|
26
|
-
|
27
|
-
if valid_date?(date)
|
28
|
-
slim :index, :locals => context
|
29
|
-
else
|
30
|
-
redirect request.referrer
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
get '/:name' do
|
35
|
-
if (member = Member.byName(params[:name])).nil?
|
36
|
-
redirect request.referrer
|
37
|
-
end
|
38
|
-
|
39
|
-
slim :member, :locals => { :photos => member.photos }
|
40
|
-
end
|
41
|
-
|
42
|
-
get '/:name/missing' do
|
43
|
-
if (member = Member.byName(params[:name])).nil?
|
44
|
-
redirect request.referrer
|
45
|
-
end
|
46
|
-
slim :member_missing, :locals => { :photos => member.missingPhotos }
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module DailyShare
|
2
|
-
module Helpers
|
3
|
-
|
4
|
-
def date_from_params(params)
|
5
|
-
Date.parse("#{params[:y]}-#{params[:m]}-#{params[:d]}")
|
6
|
-
end
|
7
|
-
|
8
|
-
def valid_date?(date)
|
9
|
-
(date.year > 2011 || date <= Date.today)
|
10
|
-
end
|
11
|
-
|
12
|
-
def context_from_date(date)
|
13
|
-
edition = (date.strftime('%Y').to_i)-(CONFIG['dailyshare']['start'].strftime('%Y').to_i)
|
14
|
-
{
|
15
|
-
:ymd => date.strftime('%Y-%m-%d'),
|
16
|
-
:date => date,
|
17
|
-
:year => (edition+1).en.numwords,
|
18
|
-
:count => (((date-CONFIG['dailyshare']['start']).to_i)-((edition)*365).to_i).en.numwords,
|
19
|
-
:photos => Member.all_with_photo_for(date)
|
20
|
-
}
|
21
|
-
end
|
22
|
-
|
23
|
-
def prev_entry(date)
|
24
|
-
(date-1).strftime('/%Y/%m/%d/')
|
25
|
-
end
|
26
|
-
|
27
|
-
def next_entry(date)
|
28
|
-
(date+1).strftime('/%Y/%m/%d/')
|
29
|
-
end
|
30
|
-
|
31
|
-
def save_photo(params,file)
|
32
|
-
begin
|
33
|
-
photo = Photo.new
|
34
|
-
photo.set_fields(params,[:title,:description,:date_added,:member_id])
|
35
|
-
photo.save_original(file)
|
36
|
-
photo.generate_sizes
|
37
|
-
photo.save_to_s3
|
38
|
-
rescue
|
39
|
-
false
|
40
|
-
else
|
41
|
-
photo.save
|
42
|
-
send_email(
|
43
|
-
CONFIG['email']['to'],
|
44
|
-
"new submisson",
|
45
|
-
slim(:'emails/uploaded', {:locals=>{:photo=>photo},:layout=>false})
|
46
|
-
)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module DailyShare
|
2
|
-
class Member < Sequel::Model
|
3
|
-
one_to_many :photos
|
4
|
-
|
5
|
-
def self.byName(name)
|
6
|
-
self[:name=>name]
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.byEmail(email)
|
10
|
-
self[:email=>email.downcase]
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.all_with_photo_for(date)
|
14
|
-
select(:members__name,:p__title,:p__description,:p__date_added).
|
15
|
-
left_join(:photos.as(:p),[:p__member_id=>:members__id,:date.sql_function(:p__date_added)=>date]).
|
16
|
-
order(:members__id)
|
17
|
-
end
|
18
|
-
|
19
|
-
def missingPhotos
|
20
|
-
DB["SELECT
|
21
|
-
date('2012-01-01'::date+(interval '1 day'*s.num)) AS date
|
22
|
-
FROM
|
23
|
-
(SELECT generate_series(0,now()::date-'2012-01-01'::date) AS num) AS s
|
24
|
-
WHERE
|
25
|
-
(SELECT
|
26
|
-
true
|
27
|
-
FROM
|
28
|
-
photos
|
29
|
-
WHERE
|
30
|
-
date_added=date('2012-01-01'::date+(interval '1 day'*s.num))
|
31
|
-
AND
|
32
|
-
member_id=?) IS null",id]
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require "stringio"
|
2
|
-
|
3
|
-
module DailyShare
|
4
|
-
class Photo < Sequel::Model
|
5
|
-
many_to_one :member
|
6
|
-
|
7
|
-
def self.by_date_and_member(date,member)
|
8
|
-
where(:date.sql_function(:date_added)=>date,:member_id=>member.id).first
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.most_recent_by_member(member)
|
12
|
-
where(:member_id=>member.id).order(:date_added.desc).first
|
13
|
-
end
|
14
|
-
|
15
|
-
def before_save
|
16
|
-
description.strip!
|
17
|
-
end
|
18
|
-
|
19
|
-
def original
|
20
|
-
"#{date_added}-#{self.member.name}.jpg"
|
21
|
-
end
|
22
|
-
|
23
|
-
def thumb
|
24
|
-
"#{date_added}-#{self.member.name}-thumb.jpg"
|
25
|
-
end
|
26
|
-
|
27
|
-
def big
|
28
|
-
"#{date_added}-#{self.member.name}-big.jpg"
|
29
|
-
end
|
30
|
-
|
31
|
-
def save_original(file)
|
32
|
-
image = File.join(CONFIG['photo_dir'],original)
|
33
|
-
File.open(image,'wb') {|f| f.write file.read }
|
34
|
-
image
|
35
|
-
end
|
36
|
-
|
37
|
-
def generate_sizes
|
38
|
-
img = Magick::Image::read(File.join(CONFIG['photo_dir'],original)).first
|
39
|
-
if img
|
40
|
-
img.resize_to_fit(240,240).write(File.join(CONFIG['photo_dir'],thumb))
|
41
|
-
img.resize_to_fit(960,680).write(File.join(CONFIG['photo_dir'],big))
|
42
|
-
img.destroy!
|
43
|
-
true
|
44
|
-
else
|
45
|
-
false
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def sizes
|
50
|
-
[File.join(CONFIG['photo_dir'],original),
|
51
|
-
File.join(CONFIG['photo_dir'],thumb),
|
52
|
-
File.join(CONFIG['photo_dir'],big)]
|
53
|
-
end
|
54
|
-
|
55
|
-
def save_to_s3
|
56
|
-
sizes.each do |file|
|
57
|
-
AWS::S3::S3Object.store(
|
58
|
-
"/photos/#{File.basename(file)}",
|
59
|
-
open(file),
|
60
|
-
AUTH['aws']['bucket'],
|
61
|
-
{
|
62
|
-
:cache_control => 'max-age=315360000',
|
63
|
-
:access => 'public_read'
|
64
|
-
}
|
65
|
-
)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def parse_exif
|
70
|
-
img = EXIFR::JPEG.new(file)
|
71
|
-
|
72
|
-
# store fstop/focal length for comparison
|
73
|
-
fstop = img.exif[:f_number].to_f
|
74
|
-
flen = img.exif[:focal_length].to_f
|
75
|
-
|
76
|
-
{
|
77
|
-
# if no decimal is needed, leave it off
|
78
|
-
:fstop => (fstop == fstop.to_i ? fstop.to_i : fstop),
|
79
|
-
# convert exposure to string
|
80
|
-
:exposure => img.exif[:exposure_time].to_s,
|
81
|
-
# if no decimal is needed, leave it off
|
82
|
-
:focal_length => (flen == flen.to_i ? flen.to_i : flen).to_s+'mm'
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|