File: image_file_cache.rb

package info (click to toggle)
mikutter 3.0.9%2Bdfsg-1~bpo70%2B1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy-backports
  • size: 9,396 kB
  • sloc: ruby: 16,625; sh: 117; makefile: 27
file content (96 lines) | stat: -rw-r--r-- 3,177 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# -*- coding: utf-8 -*-

require 'set'

Plugin.create :image_file_cache do

  CacheWriteThread = SerialThreadGroup.new

  # appear_limit 回TLに出現したユーザはキャッシュに登録する
  # (30分ツイートしなければカウンタはリセット)
  onappear do |messages|
    messages.deach { |message|
      image_url = message.user[:profile_image_url]
      if not j_include?(image_url)
        appear_counter[image_url] ||= 0
        appear_counter[image_url] += 1
        cache_it(image_url) if(appear_counter[image_url] > appear_limit) end } end

  # キャッシュがあれば画像を返す
  filter_image_cache do |url, image, &stop|
    begin
      if j_get(url)
        path = get_local_image_name(url)
        if FileTest.exist?(path)
          body = file_get_contents(path)
          if(j_get(url)+cache_expire < Time.new)
            j_delete(url)
            FileUtils.rm(path) end
          stop.call([url, body])
        else
          j_delete(url) end end
      [url, image]
    rescue => e
      error e
      [url, image] end end

  def appear_counter
    @appear_counter ||= TimeLimitedStorage.new end

  # キャッシュする出現回数のしきい値を返す
  def appear_limit
    UserConfig[:image_file_cache_appear_limit] || 32 end

  # キャッシュの有効期限を秒単位で返す
  def cache_expire
    (UserConfig[:image_file_cache_expire] || 7) * 24 * 60 * 60 end

  # _url_ からキャッシュを取得した日時を返す。
  # キャッシュがなければ _nil_ を返す。
  def j_get(url)
    at(:journaling_data, {})[url] end

  # _url_ のキャッシュがあれば真
  def j_include?(url)
    j_data = at(:journaling_data)
    j_data.include? url if j_data end

  # _url_ のキャッシュの日時を現在に設定する。
  def j_set(url, time = Time.now)
    atomic {
      j_data = at(:journaling_data, {}).melt
      j_data[url.freeze] = time.freeze
      store(:journaling_data, j_data)
      Reserver.new(time + cache_expire){ j_delete(url) } } end

  # _url_ のキャッシュの日時を削除する。
  def j_delete(url)
    atomic {
      j_data = at(:journaling_data)
      if j_data and j_data.include?(url)
        j_data = j_data.melt
        j_data.delete(url)
        store(:journaling_data, j_data) end } end

  def cache_it(image_url)
    notice "cache image to #{get_local_image_name(image_url)}"
    CacheWriteThread.new {
      raw = Gdk::WebImageLoader.get_raw_data(image_url)
      if(raw)
        notice "broken image. cache failed"
        j_set(image_url)
        image_dir = get_local_dir_name(image_url)
        FileUtils.mkdir_p(image_dir)
        file_put_contents(get_local_image_name(image_url), raw) end } end

  def get_local_image_name(image_url)
    image_name = Digest::MD5.hexdigest(image_url)
    File.join(get_local_dir_name(image_url, image_name), image_name) end

  def get_local_dir_name(image_url, image_name = Digest::MD5.hexdigest(image_url))
    File.expand_path(File.join(Environment::CACHE, 'icon', image_name[0], image_name[1])) end

  at(:journaling_data, {}).each { |url, time|
    Reserver.new(time + cache_expire){ j_delete(url) } }

end