~ubuntu-branches/ubuntu/saucy/tdiary/saucy-proposed

« back to all changes in this revision

Viewing changes to contrib2/util/image-gallery/misc/plugin/recent_image.rb

  • Committer: Bazaar Package Importer
  • Author(s): Daigo Moriwaki
  • Date: 2011-04-11 21:53:16 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110411215316-ih4gt4q8p29d2wf8
Tags: 3.0.1-1
* New upstream release (Closes: #542801, #594947)
* debian/control:
 - Bumped up Standards-Version to 3.9.1.
 - Updated version dependency.
* debian/tdiary-setup.rb: Followed the upstream changes, incorporating js and
  index.fcgi

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# recent_image.rb  $Revision: 2.0.0 $
 
2
#
 
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.
 
5
#
 
6
#  http://www1.whi.m-net.ne.jp/n-kashi/recent_image.htm
 
7
#
 
8
 
 
9
eval( <<MODIFY_CLASS, TOPLEVEL_BINDING )
 
10
module TDiary
 
11
  class TDiaryMonth
 
12
    attr_reader :diaries
 
13
  end
 
14
end
 
15
MODIFY_CLASS
 
16
 
 
17
eval( <<MODIFY_CLASS, TOPLEVEL_BINDING )
 
18
module TDiary
 
19
  class ImageData
 
20
    attr_reader :file, :url, :title, :subtitle, :date, :width, :height, :type
 
21
    attr_writer :file, :url, :title, :subtitle, :date, :width, :height, :type
 
22
  end
 
23
end
 
24
MODIFY_CLASS
 
25
 
 
26
unless Array.respond_to?( 'randomize' )
 
27
  eval( <<-MODIFY_CLASS, TOPLEVEL_BINDING )
 
28
  class Array
 
29
    def randomize
 
30
      arr = dup
 
31
      collect{ arr.slice!(rand(arr.length)) }
 
32
    end
 
33
  end
 
34
  MODIFY_CLASS
 
35
end
 
36
 
 
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
 
42
 
 
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'
 
46
 
 
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"
 
51
 
 
52
@recent_image_imgre = /[^_]image(?:_left|_right|_gps)?\s*\(?\s*([0-9]*)\s*\,?\s*[\"']([^'\"]*)[\"']/
 
53
 
 
54
#  Local Functions
 
55
 
 
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)
 
59
  f_imghash = Hash[]
 
60
 
 
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))
 
69
  end
 
70
 
 
71
  return f_imghash
 
72
end
 
73
 
 
74
 
 
75
def image_info_rcimg( filename )
 
76
  image_type = nil
 
77
  image_height = nil
 
78
  image_width = nil
 
79
 
 
80
  f = File.open(filename.untaint, "rb")
 
81
  return image_type, image_height, image_width if f == nil
 
82
 
 
83
  sig = f.read( 24 )
 
84
  if /\A\x89PNG\x0D\x0A\x1A\x0A(....)IHDR(........)/on =~ sig
 
85
    image_type = 'png'
 
86
    image_width, image_height = $2.unpack( 'NN' )
 
87
 
 
88
  elsif /\AGIF8[79]a(....)/on =~ sig
 
89
    image_type   = 'gif'
 
90
    image_width, image_height = $1.unpack( 'vv' )
 
91
 
 
92
  elsif /\A\xFF\xD8/on =~ sig
 
93
    image_type = 'jpg'
 
94
    data = $'
 
95
 
 
96
    until data.empty?
 
97
      break if data[0] != 0xFF
 
98
      break if data[1] == 0xD9
 
99
 
 
100
      data_size = data[2,2].unpack( 'n' ).first + 2
 
101
      case data[1]
 
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')
 
104
        break
 
105
      else
 
106
        if data.size < data_size
 
107
          f.seek(data_size - data.size, IO::SEEK_CUR)
 
108
          data = ''
 
109
        else
 
110
          data = data[data_size .. -1]
 
111
        end
 
112
        data << f.read( 128 ) if data.size <= 4
 
113
      end
 
114
    end
 
115
  end
 
116
 
 
117
  f.close
 
118
  return image_type, image_height, image_width
 
119
end
 
120
 
 
121
 
 
122
 
 
123
# Make sorted keys of @recent_image_hash
 
124
def keysort_rcimg
 
125
  sortproc = Proc.new {|a, b|
 
126
    a.gsub(/_(\d+)/) {"_%05d" % $1.to_i} <=>
 
127
    b.gsub(/_(\d+)/) {"_%05d" % $1.to_i}
 
128
  }
 
129
 
 
130
  @recent_image_keys  = @recent_image_hash.keys.sort(&sortproc)
 
131
  @recent_image_rkeys = @recent_image_keys.reverse
 
132
end
 
133
 
 
134
 
 
135
def load_cache_rcimg
 
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"]
 
141
    db.abort
 
142
  end
 
143
end
 
144
 
 
145
 
 
146
def save_cache_rcimg
 
147
  return if @recent_image_hash.length == 0
 
148
 
 
149
  cache_dir = File.dirname( @recent_image_cache )
 
150
  Dir.mkdir(cache_dir) unless File.directory?(cache_dir)
 
151
 
 
152
  db = PStore.new(@recent_image_cache)
 
153
  db.transaction do
 
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
 
159
    db.commit
 
160
    db.abort
 
161
  end
 
162
end
 
163
 
 
164
 
 
165
def make_image_hash_rcimg
 
166
  f_imghash = Hash[]
 
167
  f_imghash = get_filehash_rcimg("*")
 
168
 
 
169
  cgi = CGI::new
 
170
  def cgi.referer; nil;
 
171
  end
 
172
 
 
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|
 
180
          subtitle = ""
 
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)
 
184
        end
 
185
      end
 
186
    end
 
187
  end
 
188
end
 
189
 
 
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
 
194
    begin
 
195
      type, height, width = image_info_rcimg(%Q[#{@recent_image_dir}/#{f_name.delete("s")}])
 
196
      image = ImageData.new
 
197
      image.url   = f_name
 
198
      image.file  = f_name.delete("s")
 
199
      image.date  = date
 
200
      image.title = title
 
201
      image.subtitle = subtitle
 
202
      image.type  = type
 
203
      image.height = height
 
204
      image.width = width
 
205
      @recent_image_hash[%Q[#{date}_#{num}]] = image
 
206
    rescue
 
207
    end
 
208
  end
 
209
end
 
210
 
 
211
#  Initial Function ... Make a hash table : "<yyyymmdd>_<n>" => ["Filename", "title"]
 
212
def init_rcimg
 
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'
 
215
 
 
216
  if @recent_image_use_cache and File.exist?(@recent_image_cache)
 
217
    load_cache_rcimg
 
218
  else
 
219
    make_image_hash_rcimg
 
220
    keysort_rcimg
 
221
    if @recent_image_use_cache
 
222
      save_cache_rcimg 
 
223
    end
 
224
  end
 
225
end
 
226
 
 
227
#  PLUGIN body
 
228
#   recent_image()
 
229
#
 
230
def recent_image(items = 4, width = 80, link_mode = 1, name_filter = nil, title_filter = nil, reverse = false, random = false)
 
231
  items = items.to_i
 
232
  images = []
 
233
  keys = []
 
234
 
 
235
  init_rcimg
 
236
 
 
237
  return ("") if items == -1
 
238
 
 
239
  keys = (random ? @recent_image_keys.randomize : (reverse ? @recent_image_keys : @recent_image_rkeys))
 
240
 
 
241
  catch(:exit) {
 
242
    keys.each do |key|
 
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
 
246
      images.push(image)
 
247
      if items != 0
 
248
        throw :exit if items == images.length
 
249
      end
 
250
    end
 
251
  }
 
252
 
 
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}"]
 
257
    else
 
258
      sizestr = %Q[width="#{width}" height="#{width*image.height.to_i/image.width.to_i}"]
 
259
    end
 
260
    case link_mode
 
261
    when 0
 
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]
 
263
    when 1
 
264
      result << %Q[<a href="./?date=#{image.date}"><img src="#{@recent_image_url}/#{image.url}" #{sizestr} alt="#{image.title}" title="#{image.title}"></a>\n]
 
265
    when 2
 
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]
 
267
    when 3
 
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]
 
269
    when Array
 
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
 
271
    else
 
272
    end
 
273
  end
 
274
  result << "</div>"
 
275
end
 
276
 
 
277
 
 
278
# PLUGIN body
 
279
#    count_image()
 
280
#
 
281
def count_image(name_filter = nil, title_filter = nil)
 
282
  count = 0
 
283
  init_rcimg
 
284
 
 
285
  if name_filter == nil and title_filter == nil
 
286
    count = @recent_image_keys.length 
 
287
  else
 
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
 
292
      count = count + 1
 
293
    end
 
294
  end
 
295
 
 
296
  count.to_s.reverse.gsub(/\d\d\d/, '\0,').reverse.sub(/^([-]{0,1}),/, '\1')
 
297
end
 
298
 
 
299
 
 
300
# PLUGIN body
 
301
#     view_exif() ... input EXIF datas of images in your diary.
 
302
#
 
303
def view_exif(id = 0, exifparam ="")
 
304
  init_rcimg if @recent_image_hash == nil or @recent_image_hash.length == 0
 
305
  begin
 
306
    require 'exifparser'
 
307
 
 
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)
 
310
 
 
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 + ")"
 
320
      else
 
321
        lensname        = ""
 
322
      end
 
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
 
326
    end
 
327
 
 
328
  rescue
 
329
    exp = ($!).to_s + "<br>"
 
330
    ($!).backtrace.each do |btinfo|
 
331
      exp += btinfo
 
332
      exp += "<br>"
 
333
    end
 
334
    return exp
 
335
  end
 
336
end
 
337
 
 
338
 
 
339
#  Callback Functions
 
340
 
 
341
# this is for view_exif().
 
342
add_body_enter_proc(Proc.new do |date| 
 
343
  @image_date_exif = date.strftime("%Y%m%d")
 
344
  ""
 
345
end)
 
346
 
 
347
#  Update Proc of the plugin
 
348
add_update_proc do
 
349
  f_imghash = Hash[]
 
350
 
 
351
  if @recent_image_hash.length == 0
 
352
    if @recent_image_use_cache
 
353
      load_cache_rcimg
 
354
    else
 
355
      make_image_hash_rcimg
 
356
    end
 
357
  end
 
358
 
 
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)
 
363
    end
 
364
  end
 
365
 
 
366
  diary = @diaries[date]
 
367
  if diary.visible?
 
368
    f_imghash = get_filehash_rcimg(%Q|#{date}_*|)
 
369
    diary.each_section do |section|
 
370
      subtitle = ""
 
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)
 
374
    end
 
375
  end
 
376
 
 
377
  keysort_rcimg
 
378
  save_cache_rcimg if @recent_image_use_cache
 
379
end
 
380
 
 
381
 
 
382
# for SmoothGallery (SildeShow mode of 'tDiary Image Gallery')
 
383
if /image-gallery\.(?:cgi|rb)$/ =~ $0
 
384
  add_header_proc do
 
385
<<EOS
 
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>
 
393
EOS
 
394
  end
 
395
end