qiita-export 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6442dd02c9dd12b8a17344ad0a9e3f6dd780c371
4
- data.tar.gz: 1463061332a477bf955edcbd435db8a3c0fb6279
3
+ metadata.gz: 821a3351e6e0d5ae3a620e12828d645e9b985678
4
+ data.tar.gz: 18d4e090f2d8f10f06e81344d9f13772cdace11c
5
5
  SHA512:
6
- metadata.gz: 4668ef573aaa449d7d37248bc060a05700f555fd3bf16158d412b2809f20794130c1e5955d8cf15805966e2801ee861595a56deb79ae0970892007d4b76b943b
7
- data.tar.gz: ec2cb0016242ce4a2ee41e0d8926facb234e4f77b06142a4e73371ff3f950f97f6f92995529f25c8618f1b342d14fdde3c6a315e899101b22b80e90e22ecacbd
6
+ metadata.gz: 1551e1b916754310037f0993f8ed1048bd27fdd11f7eb5b57e209e68799ea30e5a509d69846183eae8ea7105703309814a9c869742ce138013ef24245addd994
7
+ data.tar.gz: acf2bea60094739fdc10959eaf703ddcf27381fd587de0db4900de29482b008a169188fdf9415908c2e8fe1646d2b55dba358145efd5a3c586fe5b0e72bff865
data/README.md CHANGED
@@ -4,10 +4,10 @@ export tool for Qiita(http://qiita.com/).
4
4
 
5
5
  ## Installation
6
6
 
7
- Add this line to your application's Gemfile:
7
+ Add this line to your Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'qiita_export'
10
+ gem 'qiita-export'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -19,7 +19,7 @@ $ bundle
19
19
  Or install it yourself as:
20
20
 
21
21
  ```
22
- $ gem install qiita_export
22
+ $ gem install qiita-export
23
23
  ```
24
24
 
25
25
  ## Usage
@@ -31,10 +31,12 @@ Usage: qiita-export [options]
31
31
  -U, --user-id=user_id specify the userid for the Qiita.
32
32
  -k, --kobito=[Kobito.db] export Kobito.app database.
33
33
  -t, --team=teamname export Qiita Team articles only.
34
+ -T, --team-all export Qiita Team all articles.
34
35
  -i, --image export with images.
35
36
  -h, --html export in html format(experimental).
36
37
  -o, --output-dir=dirpath specify the full path of destination directory.
37
38
  -a, --api-token=token specify API token for Qiita.
39
+ -e, --exclude-pattern=regexp specify the regexp pattern to exclude article title.
38
40
  ```
39
41
 
40
42
  ## Contributing
data/lib/qiita-export.rb CHANGED
@@ -3,8 +3,9 @@ require 'qiita-export/image'
3
3
  require 'qiita-export/article'
4
4
  require 'qiita-export/config'
5
5
  require 'qiita-export/exporter'
6
+ require 'qiita-export/fetcher/api_end_point'
6
7
  require 'qiita-export/fetcher/base'
7
8
  require 'qiita-export/fetcher/kobito_fetcher'
8
9
  require 'qiita-export/fetcher/api_fetcher'
9
10
  require 'qiita-export/fetcher/url_fetcher'
10
- require 'qiita-export/fetcher/user_fetcher'
11
+ require 'qiita-export/fetcher/pagination_fetcher'
@@ -6,6 +6,7 @@ module QiitaExport
6
6
  HOME_CONFIG_FILE = "~/.qiita-exportrc"
7
7
  LOCAL_CONFIG_FILE = "./.qiita-exportrc"
8
8
 
9
+ DEFAULT_HOST = "qiita.com"
9
10
  DEFAULT_USER_AGENT = "QiitaExport Gem #{QiitaExport::VERSION}"
10
11
 
11
12
  DEFAULT_HEADER = {
@@ -19,15 +20,17 @@ module QiitaExport
19
20
  @option = {}
20
21
  @parser = OptionParser.new do |opt|
21
22
  opt.version = QiitaExport::VERSION
22
- opt.on('-u', '--url=url', 'specify the URL for the Qiita(or Qiita Team).') { |v| @option[:url] = v }
23
- opt.on('-l', '--url-list=filepath', 'specify the file path of the URL list.') { |v| @option[:'url-list'] = v }
24
- opt.on('-U', '--user-id=user_id', 'specify the userid for the Qiita.') { |v| @option[:'user-id'] = v }
25
- opt.on('-k', '--kobito=[Kobito.db]', 'export Kobito.app database.') { |v| @option[:kobito] = v }
26
- opt.on('-t', '--team=teamname', 'export Qiita Team articles only.') { |v| @option[:team] = v }
27
- opt.on('-i', '--image', 'export with images.') { |v| @option[:image] = v }
28
- opt.on('-h', '--html', 'export in html format(experimental).') { |v| @option[:html] = v }
29
- opt.on('-o', '--output-dir=dirpath', 'specify the full path of destination directory.') { |v| @option[:'output-dir'] = v }
30
- opt.on('-a', '--api-token=token', 'specify API token for Qiita.') { |v| @option[:'api-token'] = v }
23
+ opt.on('-u', '--url=url', 'specify the URL for the Qiita(or Qiita Team).') { |v| @option[:url] = v }
24
+ opt.on('-l', '--url-list=filepath', 'specify the file path of the URL list.') { |v| @option[:'url-list'] = v }
25
+ opt.on('-U', '--user-id=user_id', 'specify the userid for the Qiita.') { |v| @option[:'user-id'] = v }
26
+ opt.on('-k', '--kobito=[Kobito.db]', 'export Kobito.app database.') { |v| @option[:kobito] = v }
27
+ opt.on('-t', '--team=teamname', 'export Qiita Team articles only.') { |v| @option[:team] = v }
28
+ opt.on('-T', '--team-all', 'export Qiita Team all articles.') { |v| @option[:'team-all'] = v }
29
+ opt.on('-i', '--image', 'export with images.') { |v| @option[:image] = v }
30
+ opt.on('-h', '--html', 'export in html format(experimental).') { |v| @option[:html] = v }
31
+ opt.on('-o', '--output-dir=dirpath', 'specify the full path of destination directory.') { |v| @option[:'output-dir'] = v }
32
+ opt.on('-a', '--api-token=token', 'specify API token for Qiita.') { |v| @option[:'api-token'] = v }
33
+ opt.on('-e', '--exclude-pattern=regexp', 'specify the regexp pattern to exclude article title.') { |v| @option[:'exclude-pattern'] = v }
31
34
  end
32
35
 
33
36
  # load home config
@@ -62,6 +65,18 @@ module QiitaExport
62
65
  if kobito? && api?
63
66
  fail ArgumentError.new("if you specify option --kobito, you cannot specify option --url, --url-list and --user-id.")
64
67
  end
68
+
69
+ if !kobito? && !api?
70
+ fail ArgumentError.new("one of the required options --kobito, --url, --url-list and --user-id must be specified.")
71
+ end
72
+
73
+ if !kobito? && team? && !has_api_token?
74
+ fail ArgumentError.new("if you specify option --team, option --api-token is required.")
75
+ end
76
+
77
+ if team_all? && !team?
78
+ fail ArgumentError.new("if you specify option --team-all, option --team is required.")
79
+ end
65
80
  end
66
81
 
67
82
  def kobito?
@@ -69,7 +84,7 @@ module QiitaExport
69
84
  end
70
85
 
71
86
  def api?
72
- present?(@option[:url]) || present?(@option[:'url-list']) || present?(@option[:'user-id'])
87
+ present?(@option[:url]) || present?(@option[:'url-list']) || present?(@option[:'user-id']) || team_all?
73
88
  end
74
89
 
75
90
  def user?
@@ -80,6 +95,10 @@ module QiitaExport
80
95
  present?(@option[:team])
81
96
  end
82
97
 
98
+ def team_all?
99
+ @option.key?(:'team-all')
100
+ end
101
+
83
102
  def file_export?
84
103
  present?(@option[:'output-dir'])
85
104
  end
@@ -98,10 +117,10 @@ module QiitaExport
98
117
 
99
118
  DOMAIN_PATTERN = Regexp.new("https?://([^/]+)/")
100
119
  def team_name(url = nil)
101
- if (kobito? || user?) && team?
102
- @option[:team]
103
- elsif api? && team_url?(url)
120
+ if present?(url)
104
121
  url.match(DOMAIN_PATTERN)[1].split('.')[0]
122
+ elsif team?
123
+ @option[:team]
105
124
  else
106
125
  ""
107
126
  end
@@ -131,10 +150,22 @@ module QiitaExport
131
150
  end
132
151
  end
133
152
 
153
+ def api_domain(url = nil)
154
+ if url.nil?
155
+ team? ? "#{team_name}.#{DEFAULT_HOST}" : DEFAULT_HOST
156
+ else
157
+ URI.parse(url).host
158
+ end
159
+ end
160
+
134
161
  def api_token
135
162
  @option[:'api-token']
136
163
  end
137
164
 
165
+ def exclude_pattern
166
+ @option[:'exclude-pattern']
167
+ end
168
+
138
169
  def has_api_token?
139
170
  present?(@option[:'api-token'])
140
171
  end
@@ -22,7 +22,9 @@ module QiitaExport
22
22
  if Config.kobito?
23
23
  QiitaExport::Fetcher::KobitoFetcher.new
24
24
  elsif Config.user?
25
- QiitaExport::Fetcher::UserFetcher.new
25
+ QiitaExport::Fetcher::PaginationFetcher.new(:user)
26
+ elsif Config.team_all?
27
+ QiitaExport::Fetcher::PaginationFetcher.new(:team)
26
28
  else
27
29
  QiitaExport::Fetcher::UrlFetcher.new
28
30
  end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module QiitaExport::Fetcher
4
+ class ApiEndPoint
5
+
6
+ def initialize
7
+ @config = ::QiitaExport::Config
8
+ end
9
+
10
+ def next_page(page)
11
+ raise NotImplementedError.new("You must implement #{self.class}##{__method__}")
12
+ end
13
+
14
+ def self.instance(end_point_sym)
15
+ case end_point_sym
16
+ when :user
17
+ UserEndPoint.new
18
+ when :team
19
+ TeamEndPoint.new
20
+ else
21
+ raise ArgumentError("unsupported endpont: #{end_point_sym}")
22
+ end
23
+ end
24
+ end
25
+
26
+ class UserEndPoint < ApiEndPoint
27
+ PER_PAGE = 100
28
+
29
+ def next_page(page)
30
+ "https://#{@config.api_domain}/api/v2/users/#{@config.user_id}/items?page=#{page}&per_page=#{PER_PAGE}"
31
+ end
32
+ end
33
+
34
+ class TeamEndPoint < ApiEndPoint
35
+ PER_PAGE = 100
36
+
37
+ def next_page(page)
38
+ "https://#{@config.api_domain}/api/v2/items?page=#{page}&per_page=#{PER_PAGE}"
39
+ end
40
+ end
41
+ end
@@ -5,8 +5,6 @@ require 'uri'
5
5
  module QiitaExport::Fetcher
6
6
  class ApiFetcher < Base
7
7
 
8
- DEFAULT_HOST = "qiita.com"
9
-
10
8
  protected
11
9
 
12
10
  def to_article(res)
@@ -30,13 +28,5 @@ module QiitaExport::Fetcher
30
28
  has_api_token? ? auth_header : default_header
31
29
  end
32
30
 
33
- def api_domain(url = nil)
34
- if url.nil?
35
- team? ? "#{team_name}.#{DEFAULT_HOST}" : DEFAULT_HOST
36
- else
37
- URI.parse(url).host
38
- end
39
- end
40
-
41
31
  end
42
32
  end
@@ -8,7 +8,8 @@ module QiitaExport::Fetcher
8
8
  def_delegators :@config, :kobito?, :kobito_db, :file_export?,
9
9
  :export_dir_path, :team?, :team_name,
10
10
  :article_urls, :has_api_token?, :api_token,
11
- :user_id, :default_header, :auth_header
11
+ :user_id, :default_header, :auth_header,
12
+ :api_domain
12
13
 
13
14
  def initialize
14
15
  @config = ::QiitaExport::Config
@@ -18,5 +19,12 @@ module QiitaExport::Fetcher
18
19
  raise NotImplementedError.new("You must implement #{self.class}##{__method__}")
19
20
  end
20
21
 
22
+ def exclude?(title)
23
+ if !@config.exclude_pattern.nil? && /#{@config.exclude_pattern}/ =~ title
24
+ return true
25
+ end
26
+ false
27
+ end
28
+
21
29
  end
22
30
  end
@@ -42,7 +42,8 @@ module QiitaExport::Fetcher
42
42
 
43
43
  articles = []
44
44
  while(row = rs.next)
45
- articles << to_article(row)
45
+ article = to_article(row)
46
+ articles << article unless exclude?(article.title)
46
47
  end
47
48
  articles
48
49
  ensure
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'json'
3
+ require 'open-uri'
4
+
5
+ module QiitaExport::Fetcher
6
+ class PaginationFetcher < ApiFetcher
7
+
8
+ PER_PAGE = 100
9
+
10
+ def initialize(endpoint_sym)
11
+ super()
12
+ @endpoint = ApiEndPoint.instance(endpoint_sym)
13
+ end
14
+
15
+ def find_articles
16
+ articles = []
17
+ page = 1
18
+ while true
19
+ api_responses = paginate_articles(page)
20
+ break if api_responses.empty?
21
+
22
+ api_responses.each do |api_response|
23
+ article = to_article(api_response)
24
+ articles << article unless exclude?(article.title)
25
+ end
26
+
27
+ page += 1
28
+ sleep(0.3)
29
+ end
30
+ articles.sort { |a, b| a.created_at <=> b.created_at }
31
+ end
32
+
33
+ private
34
+
35
+ def paginate_articles(page)
36
+ url = @endpoint.next_page(page)
37
+ open(@endpoint.next_page(page), request_header) do |io|
38
+ JSON.parse(io.read)
39
+ end
40
+ rescue => e
41
+ $stderr.puts "#{e} : #{url}"
42
+ raise
43
+ end
44
+ end
45
+ end
@@ -8,7 +8,8 @@ module QiitaExport::Fetcher
8
8
  def find_articles
9
9
  articles = []
10
10
  article_urls.each do |url|
11
- articles << to_article(find_article(url))
11
+ article = to_article(find_article(url))
12
+ articles << article unless exclude?(article.title)
12
13
  end
13
14
  articles
14
15
  end
@@ -1,4 +1,4 @@
1
1
  module QiitaExport
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
4
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita-export
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shin Akiyama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-19 00:00:00.000000000 Z
11
+ date: 2016-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3
@@ -84,11 +84,12 @@ files:
84
84
  - lib/qiita-export/article.rb
85
85
  - lib/qiita-export/config.rb
86
86
  - lib/qiita-export/exporter.rb
87
+ - lib/qiita-export/fetcher/api_end_point.rb
87
88
  - lib/qiita-export/fetcher/api_fetcher.rb
88
89
  - lib/qiita-export/fetcher/base.rb
89
90
  - lib/qiita-export/fetcher/kobito_fetcher.rb
91
+ - lib/qiita-export/fetcher/pagination_fetcher.rb
90
92
  - lib/qiita-export/fetcher/url_fetcher.rb
91
- - lib/qiita-export/fetcher/user_fetcher.rb
92
93
  - lib/qiita-export/image.rb
93
94
  - lib/qiita-export/version.rb
94
95
  - qiita-export.gemspec
@@ -1,35 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- require 'json'
3
- require 'open-uri'
4
-
5
- module QiitaExport::Fetcher
6
- class UserFetcher < ApiFetcher
7
-
8
- PER_PAGE = 100
9
-
10
- def find_articles
11
- articles = []
12
- page = 1
13
- while true
14
- user_articles = find_user_articles(page)
15
- break if user_articles.empty?
16
-
17
- user_articles.each do |user_article|
18
- articles << to_article(user_article)
19
- end
20
-
21
- page += 1
22
- sleep(0.3)
23
- end
24
- articles.sort { |a, b| a.created_at <=> b.created_at }
25
- end
26
-
27
- private
28
-
29
- def find_user_articles(page)
30
- open("https://#{api_domain}/api/v2/users/#{user_id}/items?page=#{page}&per_page=#{PER_PAGE}", request_header) do |io|
31
- JSON.parse(io.read)
32
- end
33
- end
34
- end
35
- end