1
# recent_image.rb $Revision: 2.0.0 $
3
# Copyright (c) 2005-2010 N.KASHIJUKU <n-kashi[at]whi.m-net.ne.jp>
4
# You can redistribute it and/or modify it under GPL2.
6
# http://www1.whi.m-net.ne.jp/n-kashi/recent_image.htm
9
eval( <<MODIFY_CLASS, TOPLEVEL_BINDING )
17
eval( <<MODIFY_CLASS, TOPLEVEL_BINDING )
20
attr_reader :file, :url, :title, :subtitle, :date, :width, :height, :type
21
attr_writer :file, :url, :title, :subtitle, :date, :width, :height, :type
26
unless Array.respond_to?( 'randomize' )
27
eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
31
collect{ arr.slice!(rand(arr.length)) }
37
@recent_image_dir = @options && @options['image.dir'] || './images/'
38
@recent_image_dir.chop! if /\/$/ =~ @recent_image_dir
39
@recent_image_url = @options && @options['image.url'] || './images/'
40
@recent_image_url.chop! if /\/$/ =~ @recent_image_url
41
@recent_imageex_yearlydir = @options && @options['image_ex.yearlydir'] || 0
43
@recent_image_hash = Hash[] # the Hash table. "<yyyymmdd>_<n>" => ImageData Objects
44
@recent_image_keys = [] # sorted keys of '@recent_image_hash'
45
@recent_image_rkeys = [] # reverse sorted keys of '@recent_image_hash'
47
@recent_image_use_cache = true
48
@recent_image_show_exif = @options['image-gallery.show_exif']
49
@recent_image_show_exif = false if @recent_image_show_exif == nil
50
@recent_image_cache = "#{@cache_path}/gallery/image-gallery2.dat"
52
@recent_image_imgre = /[^_]image(?:_left|_right|_gps)?\s*\(?\s*([0-9]*)\s*\,?\s*[\"']([^'\"]*)[\"']/
56
# Search 'image' directory(s) and return a hash table.
57
# "yyyymmdd_nn" => "File name" (or Thmbnail's File name)
58
def get_filehash_rcimg(target)
61
f_list = Dir.glob(%Q[#{@recent_image_dir}/**/#{target}].untaint)
62
f_list = f_list + Dir.glob(%Q[#{@recent_image_dir}/**/s#{target}].untaint) if target != "*"
63
f_list.each do |f_name|
64
b_name = File.basename(f_name)
65
next unless b_name.match("^([0-9]{8}_[0-9]+)\..+")
66
tmb_name = %Q[#{File.dirname(f_name)}/s#{b_name}]
67
file = (f_list.include?(tmb_name) ? tmb_name : f_name)
68
f_imghash[$1] = (@recent_imageex_yearlydir == 1 ? %Q[#{$1[0,4]}/#{File.basename(file)}] : File.basename(file))
75
def image_info_rcimg( filename )
80
f = File.open(filename.untaint, "rb")
81
return image_type, image_height, image_width if f == nil
84
if /\A\x89PNG\x0D\x0A\x1A\x0A(....)IHDR(........)/on =~ sig
86
image_width, image_height = $2.unpack( 'NN' )
88
elsif /\AGIF8[79]a(....)/on =~ sig
90
image_width, image_height = $1.unpack( 'vv' )
92
elsif /\A\xFF\xD8/on =~ sig
97
break if data[0] != 0xFF
98
break if data[1] == 0xD9
100
data_size = data[2,2].unpack( 'n' ).first + 2
102
when 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf
103
image_height, image_width = data[5,4].unpack('nn')
106
if data.size < data_size
107
f.seek(data_size - data.size, IO::SEEK_CUR)
110
data = data[data_size .. -1]
112
data << f.read( 128 ) if data.size <= 4
118
return image_type, image_height, image_width
123
# Make sorted keys of @recent_image_hash
125
sortproc = Proc.new {|a, b|
126
a.gsub(/_(\d+)/) {"_%05d" % $1.to_i} <=>
127
b.gsub(/_(\d+)/) {"_%05d" % $1.to_i}
130
@recent_image_keys = @recent_image_hash.keys.sort(&sortproc)
131
@recent_image_rkeys = @recent_image_keys.reverse
136
db = PStore.new(@recent_image_cache)
137
db.transaction(true) do
138
@recent_image_hash = db["recent_image_hash"]
139
@recent_image_keys = db["recent_image_keys"]
140
@recent_image_rkeys= db["recent_image_rkeys"]
147
return if @recent_image_hash.length == 0
149
cache_dir = File.dirname( @recent_image_cache )
150
Dir.mkdir(cache_dir) unless File.directory?(cache_dir)
152
db = PStore.new(@recent_image_cache)
154
db["recent_image_hash"] = @recent_image_hash
155
db["recent_image_keys"] = @recent_image_keys
156
db["recent_image_rkeys"] = @recent_image_rkeys
157
db["recent_image_dir"] = @recent_image_dir
158
db["recent_image_url"] = @recent_image_url
165
def make_image_hash_rcimg
167
f_imghash = get_filehash_rcimg("*")
170
def cgi.referer; nil;
173
@years.keys.sort.reverse_each do |year|
174
@years[year].sort.reverse_each do |month|
175
cgi.params['date'] = ["#{year}#{month}"]
176
m = TDiaryMonth::new(cgi, '', @conf)
177
m.diaries.keys.sort.reverse_each do |date|
178
next unless m.diaries[date].visible?
179
m.diaries[date].each_section do |section|
181
subtitle = section.subtitle.gsub(/[<{](.*?)[}>]/,'') if section.subtitle
182
search_img_rcimg(date, section.subtitle, subtitle, f_imghash)
183
search_img_rcimg(date, section.body, subtitle, f_imghash)
190
def search_img_rcimg(date, body, subtitle, f_imghash)
191
body.to_s.scan(@recent_image_imgre).each do |num, title| # Search "image plugin" in all diaries
192
f_name = f_imghash[%Q[#{date}_#{num}]] # and pick up params. -> image[0]=number, image[1]=title
193
next if f_name == nil
195
type, height, width = image_info_rcimg(%Q[#{@recent_image_dir}/#{f_name.delete("s")}])
196
image = ImageData.new
198
image.file = f_name.delete("s")
201
image.subtitle = subtitle
203
image.height = height
205
@recent_image_hash[%Q[#{date}_#{num}]] = image
211
# Initial Function ... Make a hash table : "<yyyymmdd>_<n>" => ["Filename", "title"]
213
return if @recent_image_hash != nil and @recent_image_hash.length != 0
214
return unless @mode == 'day' or @mode == 'month' or @mode == 'latest' or @mode == 'preview' or @mode == 'nyear'
216
if @recent_image_use_cache and File.exist?(@recent_image_cache)
219
make_image_hash_rcimg
221
if @recent_image_use_cache
230
def recent_image(items = 4, width = 80, link_mode = 1, name_filter = nil, title_filter = nil, reverse = false, random = false)
237
return ("") if items == -1
239
keys = (random ? @recent_image_keys.randomize : (reverse ? @recent_image_keys : @recent_image_rkeys))
243
image = @recent_image_hash[key]
244
next if name_filter != nil and image.file.match(name_filter) == nil
245
next if title_filter != nil and image.title.match(title_filter) == nil
248
throw :exit if items == images.length
253
result = %Q[<div class="recentimage">\n]
254
images.each do |image|
255
if image.height.to_i > image.width.to_i
256
sizestr = %Q[width="#{width*image.width.to_i/image.height.to_i}" height="#{width}"]
258
sizestr = %Q[width="#{width}" height="#{width*image.height.to_i/image.width.to_i}"]
262
result << %Q[<a href="./image-gallery.rb?mode=viewer;key=#{File.basename(image.file, ".*")}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n]
264
result << %Q[<a href="./?date=#{image.date}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n]
266
result << %Q[<a href="#{@recent_image_url}/#{image.file}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n]
268
result << %Q[<a onclick="window.open(this.href, '_recent_image', 'scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="#{@recent_image_url}/#{image.file}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n]
270
result << %Q[<a onclick="window.open(this.href, '_recent_image', 'width=#{link_mode[1]},height=#{link_mode[2]},scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false" href="#{@recent_image_url}/#{image.file}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n] if link_mode[0] == 3
281
def count_image(name_filter = nil, title_filter = nil)
285
if name_filter == nil and title_filter == nil
286
count = @recent_image_keys.length
288
@recent_image_keys.each do |key|
289
image = @recent_image_hash[key]
290
next if name_filter != nil and image.file.match(name_filter) == nil
291
next if title_filter != nil and image.title.match(title_filter) == nil
296
count.to_s.reverse.gsub(/\d\d\d/, '\0,').reverse.sub(/^([-]{0,1}),/, '\1')
301
# view_exif() ... input EXIF datas of images in your diary.
303
def view_exif(id = 0, exifparam ="")
304
init_rcimg if @recent_image_hash == nil or @recent_image_hash.length == 0
308
@image_date_exif ||= @date.strftime("%Y%m%d")
309
@exifparser = ExifParser.new(%Q[#{@image_dir}/#{@recent_image_hash[@image_date_exif+"_"+id.to_s].file}].untaint)
311
if exifparam == "" # return a formatted string.
312
model = @exifparser['Model'].to_s
313
focallength = @exifparser['FocalLength'].to_s
314
fnumber = @exifparser['FNumber'].to_s
315
exposuretime = @exifparser['ExposureTime'].to_s
316
isospeedratings = @exifparser['ISOSpeedRatings'].to_s
317
exposurebiasvalue = @exifparser['ExposureBiasValue'].to_s
318
if @exifparser.tag?('LensParameters')
319
lensname = "("+ @exifparser['LensParameters'].to_s + ")"
323
return %Q[<div class="exifdatastr"><p>#{model}, #{focallength}, #{fnumber}, #{exposuretime}, ISO#{isospeedratings}, #{exposurebiasvalue}EV #{lensname}</p></div>]
324
else # return the requested value.
325
return @exifparser[exifparam.untaint].to_s
329
exp = ($!).to_s + "<br>"
330
($!).backtrace.each do |btinfo|
341
# this is for view_exif().
342
add_body_enter_proc(Proc.new do |date|
343
@image_date_exif = date.strftime("%Y%m%d")
347
# Update Proc of the plugin
351
if @recent_image_hash.length == 0
352
if @recent_image_use_cache
355
make_image_hash_rcimg
359
date = @date.strftime('%Y%m%d')
360
@recent_image_hash.keys.each do |key| # Clear all data of the day in @recent_image_hash
361
if key.include?(date)
362
@recent_image_hash.delete(key)
366
diary = @diaries[date]
368
f_imghash = get_filehash_rcimg(%Q|#{date}_*|)
369
diary.each_section do |section|
371
subtitle = section.subtitle.gsub(/[<{](.*?)[}>]/,'') if section.subtitle
372
search_img_rcimg(date, section.subtitle, subtitle, f_imghash)
373
search_img_rcimg(date, section.body, subtitle, f_imghash)
378
save_cache_rcimg if @recent_image_use_cache
382
# for SmoothGallery (SildeShow mode of 'tDiary Image Gallery')
383
if /image-gallery\.(?:cgi|rb)$/ =~ $0
386
<link rel="stylesheet" href="js/SmoothGallery/css/jd.gallery.css" type="text/css" media="screen" charset="utf-8" />
387
<link rel="stylesheet" href="js/SmoothGallery/css/ReMooz.css" type="text/css" media="screen" charset="utf-8" />
388
<link rel="stylesheet" href="#{theme_url}/image-gallery.css" type="text/css" media="all">
389
<script src="js/SmoothGallery/scripts/mootools-1.2.1-core-yc.js" type="text/javascript"></script>
390
<script src="js/SmoothGallery/scripts/mootools-1.2-more.js" type="text/javascript"></script>
391
<script src="js/SmoothGallery/scripts/ReMooz.js" type="text/javascript"></script>
392
<script src="js/SmoothGallery/scripts/jd.gallery.js" type="text/javascript"></script>