class Plugin::Photo::Photo

1種類の画像を扱うModel。 同じ画像の複数のサイズ、別形式(Photo Variant)を含むことができ、それらを自動的に使い分ける。

Public Class Methods

[](uri) click to toggle source

URIからPhoto Modelを得る。 uri がDiva::Modelだった場合はそれを返すので、PhotoかURIかわからないものをPhotoに変換するのに使える。 サードパーティプラグインはこれを呼ばず、以下のページを参考にすること。

# File core/plugin/photo/model/photo.rb, line 21
def self.[](uri)
  case uri
  when Diva::Model
    uri
  when URI, Addressable::URI, Diva::URI, String
    wrapped_uri = Diva::URI(uri)
    photos[wrapped_uri.to_s.hash] ||= wrap(wrapped_uri)
  end
end
generate(seeds, perma_link:) click to toggle source

perma_link のURIをもつPhotoが既にある場合、それを返す。 ない場合は、 seeds の内容を元に作る。

Args

seeds

variant情報のEnumerator(後述)

perma_link:

variantの代表となるパーマリンク

seedsについて

有限個のHashについて繰り返すEnumeratorで、 perma_link に対応するPhotoがまだ作られていない場合にだけ利用される。 各Hashは以下のキーを持つ。

:name

そのvariantの名前。Photoの管理上特に利用されないので、重複していても良い(Symbol)

:width

そのvariantの画像の幅(px)

:height

そのvariantの画像の高さ(px)

:policy

オリジナルからどのようにリサイズされたかを示す値(Symbol)

:photo

そのvariantの画像を示すPhoto Model又は画像のURL

seedsのpolicyキーについて

policyは以下のいずれかの値。

:original

オリジナル画像。一つだけ含まれていること。

その他

Plugin::Photo::PhotoVariantを参照

# File core/plugin/photo/model/photo.rb, line 48
def self.generate(seeds, perma_link:)
  cached = photos[perma_link.to_s.hash]
  return cached if cached
  orig, other = seeds.partition{|s| s[:policy] == :original }
  new(variants: other.map{|s|
        PhotoVariant.new(s.merge(photo: InnerPhoto[s[:photo]]))
      },
      perma_link: perma_link,
      original: InnerPhoto[orig.first[:photo]])
end
new(*params) click to toggle source
Calls superclass method
# File core/plugin/photo/model/photo.rb, line 66
def initialize(*params)
  super
  each_photos do |photo|
    self.class.photos[photo.uri.to_s.hash] = self
  end
  self.class.photos[uri.to_s.hash] = self
end
photos() click to toggle source
# File core/plugin/photo/model/photo.rb, line 14
def self.photos
  @photos ||= TimeLimitedStorage.new(Integer, self)
end
wrap(model_or_uri) click to toggle source
# File core/plugin/photo/model/photo.rb, line 59
def self.wrap(model_or_uri)
  inner_photo = InnerPhoto[model_or_uri]
  new(variants: [],
      perma_link: inner_photo.perma_link,
      original: inner_photo)
end

Public Instance Methods

blob() click to toggle source
# File core/plugin/photo/model/photo.rb, line 102
def blob
  maximum_original.blob
end
download(width: nil, height: nil, &partial_callback) click to toggle source
# File core/plugin/photo/model/photo.rb, line 88
def download(width: nil, height: nil, &partial_callback)
  if width && height
    larger_than(width: width, height: height)
      .download(width: width, height: height, &partial_callback)
  else
    maximum_original.download(width: width, height: height, &partial_callback)
  end
end
each_photos(&block) click to toggle source

variantが保持している各Photo Modelを引数にしてblockを呼び出す。 blockを指定しなかった場合は、Enumeratorを返す

Return

self

ブロックを渡した場合

Enumerator

Photo Modelを列挙するEnumerator

# File core/plugin/photo/model/photo.rb, line 79
def each_photos(&block)
  if block_given?
    variants.each{|pv| block.(pv.photo) }
    self
  else
    variants.lazy.map(&:photo)
  end
end
increase_read_count() click to toggle source

PhotoInterfaceをgtkプラグインが拡張し、内部でこのメソッドを呼ぶ。 このModelでは必要ないため空のメソッドを定義しておく。

# File core/plugin/photo/model/photo.rb, line 99
def increase_read_count
end
larger_than(width:, height:) click to toggle source

指定された幅と高さを上回るvariantを返す。 既に画像がダウンロードされているvariantのうち、最小のものを使う。 引数に指定された条件を満たす中で既にダウンロードされている画像がない場合は、条件を満たす最小のvariantを返す。

Args

width:

(Integer)

height:

(Integer)

Return

Photo Model

最適なPhoto Model

# File core/plugin/photo/model/photo.rb, line 114
def larger_than(width:, height:)
  largers = variants.select{|pv| pv.policy.to_sym == :fit && pv.width >= width && pv.height >= height }.sort_by(&:width)
  if largers.empty?
    maximum_original
  else
    (largers.find{|pv| pv.photo.completed? } || largers.first).photo
  end
end
maximum() click to toggle source

最大サイズのPhotoを返す。 originalがあればそれを返すが、なければfit policyのvariantのうち最大のものを返す。

Return

Photo Model

最大のPhoto

# File core/plugin/photo/model/photo.rb, line 127
def maximum
  self.class.wrap(maximum_original)
end