Class: Narou::API

Inherits:
Object
  • Object
show all
Defined in:
lib/narou/api.rb

Overview

小説家になろうデベロッパーAPI操作クラス

Constant Summary collapse

BATCH_LIMIT =

一度に問い合わせする件数

300
GZIP_LEVEL =

なろうAPIの結果の圧縮レベル(1〜5)

5
REQUEST_INTERVAL =

リクエスト間ウェイト(sec)

3

Instance Method Summary collapse

Constructor Details

#initialize(api_url:, ncodes:, of:) ⇒ API

なろうデベロッパーAPIから情報を取得

api_url: なろうAPIのエンドポイントを指定。通常小説用と18禁小説用と分かれているため ncodes: 取得したい小説のNコードを指定。文字列か配列を指定可能 of: 出力パラメータ(dev.syosetu.com/man/api/#of_parm 参照)



35
36
37
38
39
40
# File 'lib/narou/api.rb', line 35

def initialize(api_url:, ncodes:, of:)
  @api_url = api_url
  @ncodes = Array(ncodes).map(&:downcase)
  @of = "n-#{of}"
  @splited_of = @of.split("-")
end

Instance Method Details

#[](key) ⇒ Object



42
43
44
# File 'lib/narou/api.rb', line 42

def [](key)
  @api_result[key]
end

#has_of?(type) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/narou/api.rb', line 81

def has_of?(type)
  @splited_of.include?(type)
end

#private_novelsObject



85
86
87
88
89
# File 'lib/narou/api.rb', line 85

def private_novels
  (@ncodes - @stores.map { |st| st["ncode"] }).map do |ncode|
    Downloader.get_data_by_target(ncode)["id"]
  end
end

#requestObject



46
47
48
49
50
51
52
53
# File 'lib/narou/api.rb', line 46

def request
  @stores = []
  @ncodes.each_slice(BATCH_LIMIT).with_index do |ncodes, index|
    sleep REQUEST_INTERVAL unless index.zero?
    request_api(ncodes)
  end
  @stores
end

#request_api(ncodes, limit = BATCH_LIMIT) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/narou/api.rb', line 55

def request_api(ncodes, limit = BATCH_LIMIT)
  url = "#{@api_url}?gzip=#{GZIP_LEVEL}&ncode=#{ncodes.join("-")}&of=#{@of}&lim=#{limit}&out=json"
  URI.open(url) do |fp|
    data = Zlib::GzipReader.wrap(fp).read.force_encoding(Encoding::UTF_8)
    results = JSON.parse(data)
    return if results[0]["allcount"].zero?
    store_results(results.drop(1))
  end
end

#store_results(results) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/narou/api.rb', line 65

def store_results(results)
  @stores += results.map do |result|
    result["ncode"].downcase!
    result["novel_type"] = result["noveltype"] if has_of?("nt")
    result["writer"] = result["writer"].to_s if has_of?("w")
    %w(general_firstup general_lastup novelupdated_at).each do |key|
      result[key] &&= Time.parse(result[key])
    end
    stat_end = result["end"]
    if stat_end
      result["end"] = stat_end.zero?
    end
    result
  end
end