kiita 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.simplecov +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +7 -0
- data/LICENSE.md +22 -0
- data/README.md +129 -0
- data/Rakefile +1 -0
- data/kiita.gemspec +27 -0
- data/lib/kiita.rb +26 -0
- data/lib/kiita/api.rb +118 -0
- data/lib/kiita/errors.rb +43 -0
- data/lib/kiita/model.rb +33 -0
- data/lib/kiita/post.rb +41 -0
- data/lib/kiita/tag.rb +30 -0
- data/lib/kiita/user.rb +57 -0
- data/lib/kiita/version.rb +3 -0
- data/spec/kiita/api_spec.rb +301 -0
- data/spec/kiita/errors_spec.rb +5 -0
- data/spec/kiita/post_spec.rb +64 -0
- data/spec/kiita/tag_spec.rb +26 -0
- data/spec/kiita/user_spec.rb +63 -0
- data/spec/kiita_spec.rb +13 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/api_responses/auth.json +4 -0
- data/spec/support/api_responses/search.json +37 -0
- data/spec/support/api_responses/user.json +17 -0
- data/spec/support/api_responses/user_stocks.json +38 -0
- data/spec/support/vcr.rb +22 -0
- metadata +183 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3-p194@kiita --create
|
data/.simplecov
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Yuki Nishijima
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Kiita
|
2
|
+
|
3
|
+
Yet Another Qiita API Wrapper.
|
4
|
+
|
5
|
+
[![Build Status](https://secure.travis-ci.org/yuki24/kiita.png)](http://travis-ci.org/yuki24/kiita) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/yuki24/kiita)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'kiita'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
```sh
|
18
|
+
$ bundle
|
19
|
+
```
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
```sh
|
24
|
+
$ gem install kiita
|
25
|
+
```
|
26
|
+
|
27
|
+
# Usage
|
28
|
+
|
29
|
+
## Public APIs
|
30
|
+
|
31
|
+
### See rate_limit
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
rate = Kiita::API.rate_limit
|
35
|
+
|
36
|
+
rate["remaning"] # => 148
|
37
|
+
rate["limit"] # => 150
|
38
|
+
```
|
39
|
+
|
40
|
+
### Get an authentication token
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
auth = Kiita::API.authenticate("user", "password")
|
44
|
+
|
45
|
+
auth["url_name"] # => "user"
|
46
|
+
auth["token"] # => "a875scr65rc86a5s��"
|
47
|
+
```
|
48
|
+
|
49
|
+
### Get a user's information
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
user = Kiita::API.user("yuki24")
|
53
|
+
|
54
|
+
user.class # => Kiita:;User
|
55
|
+
user.name # => "Yuki Nishijima"
|
56
|
+
user.location # => "Tokyo, Japan"
|
57
|
+
user.description # => "I'm a guy."
|
58
|
+
```
|
59
|
+
|
60
|
+
### Get a user's posts
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
posts = Kiita::API.user("yuki24").posts
|
64
|
+
post = posts.first
|
65
|
+
|
66
|
+
post.class # => Kiita::Post
|
67
|
+
post.title # => "I'm a title!"
|
68
|
+
post.body # => "I'm a body!"
|
69
|
+
```
|
70
|
+
|
71
|
+
## APIs that require authentication
|
72
|
+
|
73
|
+
First create an object with the token like this:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
user = Kiita::API.new(token: "a875scr65rc86a5s")
|
77
|
+
```
|
78
|
+
|
79
|
+
then you can do the followings.
|
80
|
+
|
81
|
+
### Get my information
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
user.me # => your information
|
85
|
+
```
|
86
|
+
|
87
|
+
### Get your stocks
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
user.stocks # collection of the posts that you stocked before.
|
91
|
+
```
|
92
|
+
|
93
|
+
### Stock a post
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
user.stock!("e6654a3b258b7c6b7d1") # => true if success
|
97
|
+
```
|
98
|
+
|
99
|
+
### Unstock a post
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
user.unstock!("e6654a3b258b7c6b7d1") # => true if success
|
103
|
+
```
|
104
|
+
|
105
|
+
## Configuration
|
106
|
+
|
107
|
+
Kiita currently doesn't allow to configure anything. But in the near future, it will support some confgurations like timeout and keep alive.
|
108
|
+
|
109
|
+
## Support
|
110
|
+
|
111
|
+
* Ruby 1.9.2, 1.9.3
|
112
|
+
|
113
|
+
Note that *Ruby 1.8.7 is NOT supported*.
|
114
|
+
|
115
|
+
## TODO
|
116
|
+
|
117
|
+
1. Implementation of the APIs that use POST, PUT or DELETE
|
118
|
+
2. Writing up rdoc as well as this README
|
119
|
+
|
120
|
+
## Contributing
|
121
|
+
|
122
|
+
1. Fork it
|
123
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
124
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
125
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
126
|
+
5. Create new Pull Request
|
127
|
+
|
128
|
+
## Copyright
|
129
|
+
Copyright (c) 2012 Yuki Nishijima. See LICENSE.md for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/kiita.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kiita/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "kiita"
|
8
|
+
gem.version = Kiita::VERSION
|
9
|
+
gem.authors = ["Yuki Nishijima"]
|
10
|
+
gem.email = ["mail@yukinishijima.net"]
|
11
|
+
gem.description = %q{Kiita is yet another Qiita API wrapper.}
|
12
|
+
gem.summary = %q{Yet Another Qiita API Wrapper}
|
13
|
+
gem.homepage = "https://github.com/yuki24/kiita"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'httpclient'
|
21
|
+
gem.add_dependency 'oj'
|
22
|
+
gem.add_dependency 'activesupport', '>= 3.0.0'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'rspec'
|
25
|
+
gem.add_development_dependency 'vcr'
|
26
|
+
gem.add_development_dependency 'webmock'
|
27
|
+
end
|
data/lib/kiita.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'httpclient'
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
require 'kiita/errors'
|
6
|
+
require 'kiita/api'
|
7
|
+
require 'kiita/version'
|
8
|
+
|
9
|
+
module Kiita
|
10
|
+
|
11
|
+
# Default API endpoint
|
12
|
+
mattr_accessor :api_endpoint
|
13
|
+
@@api_endpoint = "https://qiita.com/api/v1"
|
14
|
+
|
15
|
+
# Connect timeout in sec.
|
16
|
+
mattr_accessor :timeout
|
17
|
+
@@timeout = 30
|
18
|
+
|
19
|
+
# Reuse the same connection within this timeout in sec. from last used.
|
20
|
+
mattr_accessor :keep_alive
|
21
|
+
@@keep_alive = 0
|
22
|
+
|
23
|
+
def self.connection
|
24
|
+
@connection ||= HTTPClient.new
|
25
|
+
end
|
26
|
+
end
|
data/lib/kiita/api.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'kiita/model'
|
2
|
+
require 'kiita/user'
|
3
|
+
require 'kiita/tag'
|
4
|
+
require 'kiita/post'
|
5
|
+
|
6
|
+
module Kiita
|
7
|
+
class API
|
8
|
+
extend Kiita::Errors::HandlerMethods
|
9
|
+
attr_reader :token
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@token = options[:token]
|
13
|
+
end
|
14
|
+
|
15
|
+
def me
|
16
|
+
Kiita::User.new(get("/user"))
|
17
|
+
end
|
18
|
+
|
19
|
+
def search(keyword, options = {})
|
20
|
+
get("/search", options.merge!(q: keyword)).map{|post| Kiita::Post.new(post) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def stocks(options = {})
|
24
|
+
get("/stocks", options).map{|post| Kiita::Post.new(post) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def stock!(uuid)
|
28
|
+
(response = put("/items/#{uuid}/stock")).nil? ? true : response
|
29
|
+
end
|
30
|
+
|
31
|
+
def unstock!(uuid)
|
32
|
+
(response = delete("/items/#{uuid}/stock")).nil? ? true : response
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.rate_limit
|
36
|
+
get("/rate_limit")
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.authenticate(url_name, password)
|
40
|
+
post("/auth", url_name: url_name, password: password)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.user(url_name)
|
44
|
+
Kiita::User.lazy_load(url_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.item(uuid)
|
48
|
+
Kiita::Post.lazy_load(uuid)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.items(options = {})
|
52
|
+
Kiita::Post.all(options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.search(keyword, options = {})
|
56
|
+
Kiita::Post.search(keyword, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.tag(url_name)
|
60
|
+
Kiita::Tag.new(url_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.tags(options = {})
|
64
|
+
Kiita::Tag.all(options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def get(path, options = {})
|
68
|
+
self.class.get(path_with_credentials(path), options.merge!(token: token))
|
69
|
+
end
|
70
|
+
|
71
|
+
def post(path, options = {})
|
72
|
+
self.class.post(path_with_credentials(path), options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def put(path, options = {})
|
76
|
+
self.class.put(path_with_credentials(path), options)
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete(path, options = {})
|
80
|
+
self.class.delete(path_with_credentials(path), options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.get(path, options = {})
|
84
|
+
handle_response(connection.get(qiita_url(path), options))
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.post(path, options = {})
|
88
|
+
handle_response(connection.post(qiita_url(path), options))
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.put(path, options = {})
|
92
|
+
handle_response(connection.put(qiita_url(path), options))
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.delete(path, options = {})
|
96
|
+
handle_response(connection.delete(qiita_url(path), options))
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def path_with_credentials(path)
|
102
|
+
token ? (path + "?token=#{token}") : path
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.connection
|
106
|
+
Kiita.connection
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.qiita_url(path)
|
110
|
+
Kiita.api_endpoint + path
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.handle_response(response)
|
114
|
+
on_complete(response)
|
115
|
+
Oj.load(response.body.empty? ? "null" : response.body)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/kiita/errors.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Kiita
|
2
|
+
class Error < StandardError; end
|
3
|
+
class BadRequest < Error; end # 400
|
4
|
+
class Unauthorized < Error; end # 401
|
5
|
+
class Forbidden < Error; end # 403
|
6
|
+
class NotFound < Error; end # 404
|
7
|
+
class InternalServerError < Error; end # 500
|
8
|
+
|
9
|
+
module Errors
|
10
|
+
module HandlerMethods
|
11
|
+
def on_complete(response)
|
12
|
+
case response.status
|
13
|
+
when 400
|
14
|
+
raise Kiita::BadRequest, error_message(response)
|
15
|
+
when 401
|
16
|
+
raise Kiita::Unauthorized, error_message(response)
|
17
|
+
when 403
|
18
|
+
raise Kiita::Forbidden, error_message(response)
|
19
|
+
when 404
|
20
|
+
raise Kiita::NotFound, error_message(response)
|
21
|
+
# when 406
|
22
|
+
# raise Kiita::NotAcceptable, error_message(response)
|
23
|
+
# when 422
|
24
|
+
# raise Kiita::UnprocessableEntity, error_message(response)
|
25
|
+
when 500
|
26
|
+
raise Kiita::InternalServerError, error_message(response)
|
27
|
+
# when 503
|
28
|
+
# raise Kiita::ServiceUnavailable, error_message(response)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
private :on_complete
|
32
|
+
|
33
|
+
def error_message(response)
|
34
|
+
if response.body.empty?
|
35
|
+
"#{response.http_header.request_method} #{response.http_header.request_uri.to_s}: #{response.status}"
|
36
|
+
else
|
37
|
+
Oj.load(response.body)["error"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
private :error_message
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/kiita/model.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Kiita::Model
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
set_raw_attributes(options.slice(*attributes)) if options.slice(*attributes).present?
|
6
|
+
end
|
7
|
+
|
8
|
+
def raw_attributes
|
9
|
+
@raw_attributes ||= set_raw_attributes(raw_data)
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def set_raw_attributes(attrs)
|
15
|
+
@raw_attributes = attrs.tap do |raw_data|
|
16
|
+
raw_data.each{|key, value| instance_eval("@#{key}= value") }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def define_attributes(attrs, getter_method)
|
22
|
+
attrs.each do |attribute_name|
|
23
|
+
class_eval <<-RUBY
|
24
|
+
def #{attribute_name}
|
25
|
+
@#{attribute_name} ||= raw_attributes["#{attribute_name}"]
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
|
30
|
+
define_method(:raw_data, &getter_method)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|