class Message

Message

投稿1つを表すクラス。

Constants

PermalinkMatcher

Public Class Methods

container_class() click to toggle source
# File core/message.rb, line 76
def self.container_class
  Messages end
memory() click to toggle source
# File core/message.rb, line 84
def self.memory
  @memory ||= DataSource.new end
new(value) click to toggle source

::newで新しいインスタンスを作らないこと。インスタンスはコアが必要に応じて作る。 検索などをしたい場合は、 Diva のメソッドを使うこと

Calls superclass method
# File core/message.rb, line 89
def initialize(value)
  type_strict value => Hash
  if not(value[:image].is_a?(Message::Image)) and value[:image]
    value[:image] = Message::Image.new(value[:image]) end
  super(value)
  if self[:replyto].is_a? Message
    self[:replyto].add_child(self) end
  if self[:retweet].is_a? Message
    self[:retweet].add_child(self) end
  Message.appear(self)
end

Public Instance Methods

add_quoted_by(message) click to toggle source

selfを引用している Diva::Model を登録する

Args

message

Diva::Model selfを引用しているModel

Return

self

# File core/message.rb, line 362
def add_quoted_by(message)
  atomic do
    @quoted_by ||= Diva::Model.container_class.new
    unless @quoted_by.include? message
      if @quoted_by.frozen?
        @quoted_by = Diva::Model.container_class.new(@quoted_by + [message])
      else
        @quoted_by << message end end
    self end end
ancestor(force_retrieve=false) click to toggle source

投稿の宛先になっている投稿を再帰的にさかのぼり、何にも宛てられていない投稿を返す。 つまり、一番祖先を返す。

# File core/message.rb, line 422
def ancestor(force_retrieve=false)
  ancestors(force_retrieve).last end
ancestors(force_retrieve=false) click to toggle source

投稿の宛先になっている投稿を再帰的にさかのぼり、それらを配列にして返す。 配列インデックスが大きいものほど、早く投稿された投稿になる。 ([0]はへのリプライ)

# File core/message.rb, line 417
def ancestors(force_retrieve=false)
  ancestors_enumerator(force_retrieve).to_a end
around(force_retrieve = false) click to toggle source

このMessageが属する親子ツリーに属する全てのMessageを含むSetを返す

Args

force_retrieve

外部サーバに問い合わせる場合真

Return

関係する全てのツイート(Set)

# File core/message.rb, line 499
def around(force_retrieve = false)
  ancestor(force_retrieve).children_all end
body() click to toggle source

非公式リツイートやハッシュタグを適切に組み合わせて投稿する

# File core/message.rb, line 572
def body
  self[:message].to_s.freeze
end
children() click to toggle source

この投稿に宛てられた投稿をSetオブジェクトにまとめて返す。

# File core/message.rb, line 503
def children
  @children ||= Plugin.filtering(:replied_by, self, Set.new(retweeted_statuses))[1] end
children_all() click to toggle source

childrenを再帰的に遡り全てのMessageを返す

Return

このMessageの子全てをSetにまとめたもの

# File core/message.rb, line 509
def children_all
  children.inject(Diva::Model.container_class.new([self])){ |result, item| result.concat item.children_all } end
deletable?() click to toggle source

この投稿を削除する権限があればtrueを返す

# File core/message.rb, line 161
def deletable?
  from_me? end
destroy() { |*a| ... } click to toggle source

この投稿を削除する

# File core/message.rb, line 121
def destroy
  service = Service.primary
  if deletable? and service
    service.destroy(self){|*a| yield(*a) if block_given? } end end
each_ancestor(force_retrieve=false, &proc) click to toggle source

投稿の宛先になっている投稿を再帰的にさかのぼり、それぞれを引数に取って ブロックが呼ばれる。 ブロックが渡されていない場合、 Enumerator を返す。 force_retrieve は、 #receive_message の引数にそのまま渡される

Return

obj|Enumerator

# File core/message.rb, line 405
def each_ancestor(force_retrieve=false, &proc)
  e = ancestors_enumerator(force_retrieve)
  if block_given?
    e.each(&proc)
  else
    e end end
Also aliased as: each_ancestors
each_ancestors(force_retrieve=false, &proc)
Alias for: each_ancestor
each_retweet_ancestor(force_retrieve=false, &proc) click to toggle source

retweet元を再帰的にさかのぼり、それぞれを引数に取って ブロックが呼ばれる。 ブロックが渡されていない場合、 Enumerator を返す。 force_retrieve は、 #retweet_parent の引数にそのまま渡される

Return

obj|Enumerator

# File core/message.rb, line 445
def each_retweet_ancestor(force_retrieve=false, &proc)
  e = retweet_ancestors_enumerator(force_retrieve)
  if block_given?
    e.each(&proc)
  else
    e end end
Also aliased as: each_retweet_ancestors
each_retweet_ancestors(force_retrieve=false, &proc)
favoriable?()
Alias for: favoritable?
favoritable?() click to toggle source

この投稿をお気に入りに追加する権限があればtrueを返す

# File core/message.rb, line 152
def favoritable?
  Service.primary end
Also aliased as: favoriable?
favorite(fav = true) click to toggle source

お気に入り状態を変更する。fav がtrueならお気に入りにし、falseならお気に入りから外す。

# File core/message.rb, line 127
def favorite(fav = true)
  service = Service.primary
  if favoritable? and service
    service.favorite(self, fav) end end
favorite?() click to toggle source

この投稿のお気に入り状態を返す。お気に入り状態だった場合にtrueを返す

# File core/message.rb, line 137
def favorite?
  favorited_by.include?(Service.primary!.user_obj)
rescue Service::NotExistError
  false end
favorited_by() click to toggle source

この投稿をお気に入りに登録したUserをSetオブジェクトにまとめて返す。

# File core/message.rb, line 513
def favorited_by
  @favorited ||= Plugin.filtering(:favorited_by, self, Set.new())[1] end
favorited_by_me?(me = Service.services) click to toggle source

この投稿を「自分」がふぁぼっていれば真

# File core/message.rb, line 517
def favorited_by_me?(me = Service.services)
  case me
  when Service
    favorited_by.include? me.user_obj
  when Enumerable
    not (Set.new(favorited_by.map(&:idname)) & Set.new(me.map(&:idname))).empty?
  else
    raise ArgumentError, "first argument should be `Service' or `Enumerable'. but given `#{me.class}'" end end
from_me?(services=Service) click to toggle source

この投稿の投稿主のアカウントの全権限を所有していればtrueを返す

# File core/message.rb, line 165
def from_me?(services=Service)
  services.map(&:user_obj).include?(self[:user]) end
has_receive_message?() click to toggle source

このメッセージが何かしらの別のメッセージに宛てられたものなら真

# File core/message.rb, line 224
def has_receive_message?
  !!(self[:replyto] || self[:in_reply_to_status_id]) end
Also aliased as: reply?
idname() click to toggle source

投稿主のidnameを返す

# File core/message.rb, line 102
def idname
  user.idname
end
introducer(me = Service.primary!) click to toggle source

この投稿をリツイート等して、 me のタイムラインに出現させたリツイートを返す。 特に誰もリツイートしていない場合は self を返す。 リツイート、ふぁぼなどを行う時に使用する。

Args

me

Service 対象とするService

Return

Message

# File core/message.rb, line 567
def introducer(me = Service.primary!)
  Plugin.filtering(:message_introducers, me, self, retweeted_statuses.reject{|m|m.user == me.to_user}).last.to_a.last || self
end
mentioned_by_me?() click to toggle source

自分がこのMessageにリプライを返していればtrue

# File core/message.rb, line 220
def mentioned_by_me?
  children.any?{ |m| m.from_me? } end
post(other) { |*a| ... } click to toggle source

この投稿へのリプライをつぶやく

# File core/message.rb, line 107
def post(other, &proc)
  other[:replyto] = self
  other[:receiver] = self[:user]
  service = Service.primary
  if service.is_a? Service
    service.post(other){|*a| yield(*a) if block_given? } end end
protected?() click to toggle source

この投稿が公開されているものならtrueを返す。少しでも公開範囲を限定しているならfalseを返す。

# File core/message.rb, line 173
def protected?
  if retweet?
    retweet_ancestor.protected?
  else
    user.protected? end end
quoted_by() click to toggle source

selfを引用しているDivaを返す

Return

Diva::Model.container_class selfを引用しているDiva::Modelの配列

# File core/message.rb, line 375
def quoted_by
  if defined? @quoted_by
    @quoted_by
  else
    atomic do
      @quoted_by ||= Diva::Model.container_class.new end end.freeze end
quoted_by?() click to toggle source

self が、何らかのツイートから引用されているなら真を返す

Return

TrueClass|FalseClass

# File core/message.rb, line 385
def quoted_by?
  !quoted_by.empty? end
quoting?() click to toggle source

self が、何らかのツイートを引用しているなら真を返す

Return

TrueClass|FalseClass

# File core/message.rb, line 354
def quoting?
  !!quoting_ids.first end
quoting_ids() click to toggle source

このMessageが引用した投稿を全て返す

Return

Enumerable このMessageが引用したMessageのid(Fixnum)

# File core/message.rb, line 310
def quoting_ids
  entity.lazy.select{ |entity|
    :urls == entity[:slug]
  }.map{ |entity|
    PermalinkMatcher.match(entity[:expanded_url])
  }.select(&ret_nth).map do |matched|
    matched[:id].to_i end end
quoting_messages(force_retrieve=false) click to toggle source

このMessageが引用した投稿を全て返す。 force_retrieve に真が指定されたらこのメソッドはTwitter APIをリクエストする可能性がある。 そのため force_retrieve が真なら、Messageを取得してから返し、 偽ならAPIリクエストが必要ないので、Messageオブジェクトの取得を遅延する。 Twitter APIリクエストを行ったがツイートが削除されていた、メモリ上に存在しないなどの理由で 取得できなかったツイートに関しては、戻り値に含まれない

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Enumerable このMessageが引用したMessage

# File core/message.rb, line 328
def quoting_messages(force_retrieve=false)
  return @quoting_messages if defined? @quoting_messages
  if force_retrieve
    @quoting_messages ||= quoting_ids.map{|quoted_id|
      Message.findbyid(quoted_id, -1)
    }.to_a.compact.freeze.tap do |qs|
      qs.each do |q|
        q.add_quoted_by(self) end  end
  else
    quoting_ids.map{|quoted_id|
      Message.findbyid(quoted_id, 0) }.select(&ret_nth) end end
quoting_messages_d(force_retrieve=false) click to toggle source

このMessageが引用した投稿を全て返す。 force_retrieve に真が指定されたらこのメソッドはTwitter APIをリクエストする可能性がある。 Twitter APIリクエストを行ったがツイートが削除されていた、メモリ上に存在しないなどの理由で 取得できなかったツイートに関しては、結果がnilとなる

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Deferredable

# File core/message.rb, line 348
def quoting_messages_d(force_retrieve=false)
  Thread.new{ quoting_messages(force_retrieve) } end
receive_message(force_retrieve=false) click to toggle source

この投稿が別の投稿に宛てられたものならそれを返す。 force_retrieve がtrueなら、呼び出し元のスレッドでサーバに問い合わせるので、 親投稿を受信していなくてもこの時受信できるが、スレッドがブロッキングされる。 falseならサーバに問い合わせずに結果を返す。 Messageのインスタンスかnilを返す。

# File core/message.rb, line 237
def receive_message(force_retrieve=false)
  replyto_source(force_retrieve) or retweet_source(force_retrieve) end
receive_message_d(force_retrieve=false) click to toggle source
# File core/message.rb, line 240
def receive_message_d(force_retrieve=false)
  Thread.new{ receive_message(force_retrieve) } end
receive_to?(other) click to toggle source

ユーザ other に宛てられたメッセージならtrueを返す。 other は、 User かother[:id]とotherが呼び出し可能なもの。

# File core/message.rb, line 208
def receive_to?(other)
  type_strict other => :[]
  (self[:receiver] and other[:id] == self[:receiver].id) or receive_user_screen_names.include? other[:idname] end
receive_user_screen_names() click to toggle source

このツイートが宛てられたユーザを可能な限り推測して、その idname(screen_name) を配列で返す。 例えばツイート本文内に「@a @b @c」などと書かれていたら、[“a”, “b”, “c”]を返す。

Return

宛てられたユーザの idname(screen_name) の配列

# File core/message.rb, line 216
def receive_user_screen_names
  self[:message].to_s.scan(Diva::Entity::BasicTwitterEntity::MentionMatcher).map(&:first) end
receiver() click to toggle source

この投稿を宛てられたユーザを返す

# File core/message.rb, line 193
def receiver
  if self[:receiver].is_a? User
    self[:receiver]
  elsif self[:receiver] and self[:in_reply_to_user_id]
    receiver_id = self[:in_reply_to_user_id]
    self[:receiver] = parallel{
      self[:receiver] = User.findbyid(receiver_id) }
  else
    match = Diva::Entity::BasicTwitterEntity::MentionMatcher.match(self[:message].to_s)
    if match
      result = User.findbyidname(match[1])
      self[:receiver] = result if result end end end
repliable?() click to toggle source

この投稿にリプライする権限があればtrueを返す

# File core/message.rb, line 148
def repliable?
  !!Service.primary end
reply?()
replyto_source(force_retrieve=false) click to toggle source

このMessageの宛先になっているMessageを取得して返す。

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Message|nil 宛先のMessage。宛先がなければnil

# File core/message.rb, line 248
def replyto_source(force_retrieve=false)
  if reply?
    if self[:replyto]
      self[:replyto]
    elsif self[:in_reply_to_status_id]
      result = Message.findbyid(self[:in_reply_to_status_id], force_retrieve ? Diva::DataSource::USE_ALL : Diva::DataSource::USE_LOCAL_ONLY)
      if result.is_a?(Message)
        result.add_child(self) unless result.children.include?(self)
        result
      end
    end
  end
end
replyto_source_d(force_retrieve=true) click to toggle source

#replyto_source の戻り値をnextに渡すDeferredableを返す

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Deferredable nextの引数に宛先のMessageを渡す。宛先が無い場合は失敗し、trap{}にnilを渡す

# File core/message.rb, line 267
def replyto_source_d(force_retrieve=true)
  Thread.new do
    result = replyto_source(force_retrieve)
    if result.is_a? Message
      result
    else
      Deferred.fail(result) end end end
retweet() { |*a| ... } click to toggle source

リツイートする

# File core/message.rb, line 115
def retweet
  service = Service.primary
  if retweetable? and service
    service.retweet(self){|*a| yield(*a) if block_given? } end end
retweet?() click to toggle source

このメッセージが何かに対するリツイートなら真

# File core/message.rb, line 229
def retweet?
  !!self[:retweet] end
retweet_ancestor(force_retrieve=false) click to toggle source

リツイート元を再帰的に遡り、リツイートではないツイートを返す。 selfがリツイートでない場合は、selfを返す。

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Message

# File core/message.rb, line 468
def retweet_ancestor(force_retrieve=false)
  retweet_ancestors(force_retrieve).last end
retweet_ancestors(force_retrieve=false) click to toggle source

retweet元を再帰的に遡り、それらを配列にして返す。 配列の最初の要素は必ずselfになり、以降は直前の要素のリツイート元となる。 ([0]はへのリツイート)

Return

Enumerator

# File core/message.rb, line 459
def retweet_ancestors(force_retrieve=false)
  retweet_ancestors_enumerator(force_retrieve).to_a end
retweet_parent(force_retrieve=false) click to toggle source

このMessageがリツイートであるなら、リツイート元のツイートを返す。 リツイートではないならnilを返す。リツイートであるかどうかを確認するには、 このメソッドの代わりに #retweet? を使う。

Args

force_retrieve

Return

Message|nil リツイート元のMessage。リツイートではないならnil

# File core/message.rb, line 282
def retweet_parent(force_retrieve=false)
  if retweet?
    case self[:retweet]
    when Integer
      self[:retweet] = Message.findbyid(retweet, force_retrieve ? -1 : 1) || self[:retweet]
    when Message
      self[:retweet].add_child(self) unless self[:retweet].retweeted_statuses.include?(self)
    end
    self[:retweet]
  end
end
retweet_parent_d(force_retrieve=true) click to toggle source

#retweet_parent の戻り値をnextに渡すDeferredableを返す

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Deferredable nextの引数にリプライ元のMessageを渡す。リツイートではない場合は失敗し、trap{}にnilを渡す

# File core/message.rb, line 299
def retweet_parent_d(force_retrieve=true)
  Thread.new do
    result = retweet_source(force_retrieve)
    if result.is_a? Message
      result
    else
      Deferred.fail(result) end end end
retweet_source(force_retrieve=false) click to toggle source

このMessageがリツイートなら、何のリツイートであるかを返す。 返される値の retweet? は常に false になる

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Message|nil リツイートであればリツイート元のMessage、リツイートでなければnil

# File core/message.rb, line 477
def retweet_source(force_retrieve=false)
  if retweet?
    retweet_ancestor(force_retrieve) end end
retweet_source_d(force_retrieve=true) click to toggle source

#retweet_source の戻り値をnextに渡すDeferredableを返す

Args

force_retrieve

真なら、ツイートがメモリ上に見つからなかった場合Twitter APIリクエストを発行する

Return

Deferredable nextの引数にリプライ元のMessageを渡す。リツイートではない場合は失敗し、trap{}にnilを渡す

# File core/message.rb, line 486
def retweet_source_d(force_retrieve=true)
  Thread.new do
    result = retweet_source(force_retrieve)
    if result.is_a? Message
      result
    else
      Deferred.fail(result) end end end
retweetable?() click to toggle source

この投稿をリツイートする権限があればtrueを返す

# File core/message.rb, line 157
def retweetable?
  Service.primary and not protected? end
retweeted?() click to toggle source

選択されているユーザがこのツイートをリツイートしているなら真

# File core/message.rb, line 545
def retweeted?
  retweeted_users.include?(Service.primary!.user_obj)
rescue Service::NotExistError
  false end
retweeted_by() click to toggle source

この投稿をリツイートしたユーザを返す

Return

Enumerable リツイートしたユーザを、リツイートした順番に返す

# File core/message.rb, line 529
def retweeted_by
  has_status_user_ids = Set.new(retweeted_statuses.map(&:user).map(&:id))
  retweeted_sources.lazy.reject{|r|
    r.is_a?(User) and has_status_user_ids.include?(r.id)
  }.map(&:user) end
Also aliased as: retweeted_users
retweeted_by_me?(me = Service.services) click to toggle source

この投稿を「自分」がリツイートしていれば真

# File core/message.rb, line 551
def retweeted_by_me?(me = Service.services)
  case me
  when Service
    retweeted_users.include? me.user_obj
  when Enumerable
    not (Set.new(retweeted_users.map(&:idname)) & Set.new(me.map(&:idname))).empty?
  else
    raise ArgumentError, "first argument should be `Service' or `Enumerable'. but given `#{me.class}'" end end
retweeted_sources() click to toggle source

この投稿に対するリツイートまたはユーザを返す

# File core/message.rb, line 541
def retweeted_sources
  @retweets ||= Plugin.filtering(:retweeted_by, self, Set.new())[1].to_a.compact end
retweeted_statuses() click to toggle source

この投稿に対するリツイートを返す

# File core/message.rb, line 537
def retweeted_statuses
  retweeted_sources.lazy.select{|m| m.is_a?(Message) } end
retweeted_users()
Alias for: retweeted_by
service() click to toggle source
# File core/message.rb, line 188
def service
  warn "Message#service is obsolete method. use `Service.primary'."
  Service.primary end
system?() click to toggle source

投稿がシステムメッセージだった場合にtrueを返す

# File core/message.rb, line 143
def system?
  false
end
to_i() click to toggle source
# File core/message.rb, line 581
def to_i
  self[:id].to_i end
to_me?(services=Service) click to toggle source

この投稿が自分宛ならばtrueを返す

# File core/message.rb, line 169
def to_me?(services=Service)
  services.map(&:user_obj).find(&method(:receive_to?)) end
to_s() click to toggle source

#body と同じだが、投稿制限文字数を超えていた場合には、収まるように末尾を捨てる。

# File core/message.rb, line 577
def to_s
  body[0,140].freeze end
unfavorite() click to toggle source

お気に入りから削除する

# File core/message.rb, line 133
def unfavorite
  favorite(false) end
user() click to toggle source

この投稿の投稿主を返す。messageについては、userが必ず付与されていることが保証されているので Deferredを返さない

# File core/message.rb, line 185
def user
  self[:user] end
verified?() click to toggle source

この投稿が承認されているものならtrueを返す。

# File core/message.rb, line 180
def verified?
  user.verified? end