qiita-export 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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