File: connect.rb

package info (click to toggle)
mikutter 3.8.6%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 10,544 kB
  • sloc: ruby: 20,548; sh: 99; makefile: 19
file content (89 lines) | stat: -rw-r--r-- 2,616 bytes parent folder | download
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
# -*- coding: utf-8 -*-

require_relative "basic"
require_relative "utils"
require_relative "authentication_failed_action"
require_relative "rate_limiting"
require "oauth"

# OAuth関連
module MikuTwitter::Connect

  INVALID_REQUEST = 32
  PAGE_DOES_NOT_EXIST = 34
  BASIC_AUTHENTICATION_IS_NOT_SUPPORTED = 53
  RATE_LIMIT_EXCEEDED = 88
  INVALID_OR_EXPIRED_TOKEN = 89
  OVER_CAPACITY = 130
  INTERNAL_ERROR = 131
  TIMESTAMP_TOOLATE = 135
  BAD_AUTHENTICATION_DATA = 215

  IDENTITY_SEED = 'r.A3%Z83n84GDw@KyN-mH-%+_&TnTJ2/'.freeze

  attr_accessor :consumer_key, :consumer_secret, :a_token, :a_secret, :oauth_url

  def initialize(*a, &b)
    @oauth_url = 'https://twitter.com'
    super(*a, &b)
  end

  # キャッシュのキーなどで使う、アカウント毎の一意なID
  def account_identity
    Digest::MD5.hexdigest([consumer_key, consumer_secret, a_token, a_secret, IDENTITY_SEED].join) end

  def consumer(url=oauth_url)
    OAuth::Consumer.new(consumer_key, consumer_secret,
                        :site => url) end

  def access_token(url=@oauth_url)
    OAuth::AccessToken.new(consumer(url), a_token, a_secret) end

  def request_oauth_token
    consumer.get_request_token end

  # OAuth経由でurlを叩く
  # ==== Args
  # [method] メソッド。:get, :post, :put, :delete の何れか
  # [url] 叩くURL
  # [options]
  #   API引数。ただし、以下のキーは特別扱いされ、API引数からは除外される
  #   :head :: HTTPリクエストヘッダ(Hash)
  # ==== Return
  # 戻り値(HTTPResponse)
  # ==== Exceptions
  # TimeoutError
  def query_with_oauth!(method, url, options = {})
    if [:get, :delete].include? method
      path = url + get_args(options)
      res = access_token.__send__(method, path, options[:head])
    else
      path = url
      query_args = options.melt
      head = options[:head]
      query_args.delete(:head)
      res = access_token.__send__(method, path, query_args, head) end
    if res.is_a? Net::HTTPResponse
      case res.code
      when '200'
      when '401'
        begin
          errors = (JSON.parse(res.body)["errors"] rescue nil)
          errors.each { |error|
            if [INVALID_OR_EXPIRED_TOKEN].include? error["code"]
              atoken = authentication_failed_action(method, url, options, res)
              return query_with_oauth!(method, url, options) if atoken end }
        rescue Exception => e
          warn e end
      when '429'
        raise MikuTwitter::RateLimitError.new("Rate limit #{url}", nil)
      end
    end
    res
  end

end

class MikuTwitter; include MikuTwitter::Connect end