qiita-export 0.0.2 → 0.0.3

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: 821a3351e6e0d5ae3a620e12828d645e9b985678
4
- data.tar.gz: 18d4e090f2d8f10f06e81344d9f13772cdace11c
3
+ metadata.gz: 07a761de535b3fac30e81ce02879ccecad548aaa
4
+ data.tar.gz: f7e388a44e4e543b30beca43b30b2d73d125999f
5
5
  SHA512:
6
- metadata.gz: 1551e1b916754310037f0993f8ed1048bd27fdd11f7eb5b57e209e68799ea30e5a509d69846183eae8ea7105703309814a9c869742ce138013ef24245addd994
7
- data.tar.gz: acf2bea60094739fdc10959eaf703ddcf27381fd587de0db4900de29482b008a169188fdf9415908c2e8fe1646d2b55dba358145efd5a3c586fe5b0e72bff865
6
+ metadata.gz: 55c498a11247a4179ecf9987af52a046327931449471a160bedeab72deff77c43d5ea0d93159e1ab6ed9e08989f9fdbb0283561520a08a1c05090a14e8c85076
7
+ data.tar.gz: 09558c17f085b0d3ea750728bd6ca1f807dc6adc01fe594681cbc89cdb76c2d6a6d28e54bf048867bc2298493f205a26f68761ed46fe3a7e4ee34e58951f9445
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  export tool for Qiita(http://qiita.com/).
4
4
 
5
+ qiita-export | RubyGems.org
6
+ https://rubygems.org/gems/qiita-export/
7
+
5
8
  ## Installation
6
9
 
7
10
  Add this line to your Gemfile:
@@ -33,6 +36,7 @@ Usage: qiita-export [options]
33
36
  -t, --team=teamname export Qiita Team articles only.
34
37
  -T, --team-all export Qiita Team all articles.
35
38
  -i, --image export with images.
39
+ -c, --comment export with comments.
36
40
  -h, --html export in html format(experimental).
37
41
  -o, --output-dir=dirpath specify the full path of destination directory.
38
42
  -a, --api-token=token specify API token for Qiita.
@@ -1,5 +1,6 @@
1
1
  require 'qiita-export/version'
2
2
  require 'qiita-export/image'
3
+ require 'qiita-export/comment'
3
4
  require 'qiita-export/article'
4
5
  require 'qiita-export/config'
5
6
  require 'qiita-export/exporter'
@@ -33,15 +33,20 @@ module QiitaExport
33
33
  end
34
34
 
35
35
  def save
36
- save_dir = File.join(Config.export_dir_path, Config.team_name(@url), @key)
36
+ save_dir = File.join(Config.export_dir_path(@url), @key)
37
37
 
38
38
  FileUtils.makedirs(save_dir) unless Dir.exists?(save_dir)
39
39
 
40
40
  file_path = File.join(save_dir, Config.filename(title))
41
41
  File.open(file_path, "w") { |f| f.write export_content }
42
- if (Config.image_export?)
42
+
43
+ if Config.image_export?
43
44
  @images.each { |image| image.save(save_dir) }
44
45
  end
46
+
47
+ if Config.comment_export?
48
+ Comment.new(@url).save(save_dir)
49
+ end
45
50
  end
46
51
 
47
52
  private
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'fileutils'
3
+ require 'uri'
4
+
5
+ module QiitaExport
6
+ class Comment
7
+ attr_reader :key
8
+
9
+ def initialize(url)
10
+ @endpoint = Fetcher::ApiEndPoint.instance(:comment)
11
+ @url = url
12
+ end
13
+
14
+ def request_header
15
+ Config.has_api_token? ? Config.auth_header : Config.default_header
16
+ end
17
+
18
+ def filename
19
+ "comments.json"
20
+ end
21
+
22
+ def save(path)
23
+ comments = find_comments
24
+ return if comments =~ /^\[\]$/i
25
+
26
+ file_path = File.join(File.expand_path(path), filename)
27
+ open(file_path, 'wb') do |out|
28
+ out.write(comments)
29
+ end
30
+ end
31
+
32
+ def find_comments
33
+ url = @endpoint.url(article_url: @url)
34
+ open(url, request_header) do |io|
35
+ io.read
36
+ end
37
+ rescue => e
38
+ $stderr.puts "#{e} : #{url}"
39
+ raise
40
+ end
41
+ end
42
+ end
@@ -27,6 +27,7 @@ module QiitaExport
27
27
  opt.on('-t', '--team=teamname', 'export Qiita Team articles only.') { |v| @option[:team] = v }
28
28
  opt.on('-T', '--team-all', 'export Qiita Team all articles.') { |v| @option[:'team-all'] = v }
29
29
  opt.on('-i', '--image', 'export with images.') { |v| @option[:image] = v }
30
+ opt.on('-c', '--comment', 'export with comments.') { |v| @option[:comment] = v }
30
31
  opt.on('-h', '--html', 'export in html format(experimental).') { |v| @option[:html] = v }
31
32
  opt.on('-o', '--output-dir=dirpath', 'specify the full path of destination directory.') { |v| @option[:'output-dir'] = v }
32
33
  opt.on('-a', '--api-token=token', 'specify API token for Qiita.') { |v| @option[:'api-token'] = v }
@@ -111,6 +112,10 @@ module QiitaExport
111
112
  @option[:image]
112
113
  end
113
114
 
115
+ def comment_export?
116
+ @option[:comment]
117
+ end
118
+
114
119
  def team_url?(url)
115
120
  url !~ /^https?:\/\/qiita\.com/
116
121
  end
@@ -126,6 +131,19 @@ module QiitaExport
126
131
  end
127
132
  end
128
133
 
134
+ USER_ID_PATTERN = Regexp.new("https?://[^/?&#]+/([^/]+)/")
135
+ def user_id(url = nil)
136
+ if url.nil?
137
+ @option[:'user-id']
138
+ else
139
+ url.match(USER_ID_PATTERN)[1]
140
+ end
141
+ end
142
+
143
+ def article_key(url)
144
+ File.basename(url)
145
+ end
146
+
129
147
  def article_urls
130
148
  urls = []
131
149
  urls << @option[:url] if present?(@option[:url])
@@ -180,16 +198,15 @@ module QiitaExport
180
198
  header
181
199
  end
182
200
 
183
- def user_id
184
- @option[:'user-id']
201
+ def output_dir
202
+ return "" unless file_export?
203
+ File.expand_path(@option[:'output-dir'].strip)
185
204
  end
186
205
 
187
- def export_dir_path
188
- if user?
189
- File.join(File.expand_path(@option[:'output-dir'].strip), user_id)
190
- else
191
- File.expand_path(@option[:'output-dir'].strip)
192
- end
206
+ def export_dir_path(url)
207
+ team = team_name(url)
208
+ user = user_id(url)
209
+ File.join(output_dir, team, user)
193
210
  end
194
211
 
195
212
  def filename(title)
@@ -37,8 +37,13 @@ module QiitaExport
37
37
  end
38
38
 
39
39
  def export_file(articles)
40
- $stdout.puts "export articles to #{Config.export_dir_path}"
41
- FileUtils.makedirs(Config.export_dir_path) unless Dir.exists?(Config.export_dir_path)
40
+ if articles.length < 1
41
+ $stdout.puts("no articles found.")
42
+ return
43
+ end
44
+
45
+ $stdout.puts "export articles to #{Config.output_dir}"
46
+
42
47
  articles.each do |article|
43
48
  article.save
44
49
  end
@@ -3,16 +3,22 @@
3
3
  module QiitaExport::Fetcher
4
4
  class ApiEndPoint
5
5
 
6
+ MAX_PER_PAGE = 100
7
+
6
8
  def initialize
7
9
  @config = ::QiitaExport::Config
8
10
  end
9
11
 
10
- def next_page(page)
12
+ def url(article_url: nil, page: 1)
11
13
  raise NotImplementedError.new("You must implement #{self.class}##{__method__}")
12
14
  end
13
15
 
14
16
  def self.instance(end_point_sym)
15
17
  case end_point_sym
18
+ when :item
19
+ ItemEndPoint.new
20
+ when :comment
21
+ CommentEndPoint.new
16
22
  when :user
17
23
  UserEndPoint.new
18
24
  when :team
@@ -23,19 +29,27 @@ module QiitaExport::Fetcher
23
29
  end
24
30
  end
25
31
 
26
- class UserEndPoint < ApiEndPoint
27
- PER_PAGE = 100
32
+ class ItemEndPoint < ApiEndPoint
33
+ def url(article_url: nil, page: 1)
34
+ "https://#{@config.api_domain(article_url)}/api/v2/items/#{@config.article_key(article_url)}"
35
+ end
36
+ end
28
37
 
29
- def next_page(page)
30
- "https://#{@config.api_domain}/api/v2/users/#{@config.user_id}/items?page=#{page}&per_page=#{PER_PAGE}"
38
+ class CommentEndPoint < ApiEndPoint
39
+ def url(article_url: nil, page: 1)
40
+ "https://#{@config.api_domain(article_url)}/api/v2/items/#{@config.article_key(article_url)}/comments"
31
41
  end
32
42
  end
33
43
 
34
- class TeamEndPoint < ApiEndPoint
35
- PER_PAGE = 100
44
+ class UserEndPoint < ApiEndPoint
45
+ def url(article_url: nil, page: 1)
46
+ "https://#{@config.api_domain}/api/v2/users/#{@config.user_id}/items?page=#{page}&per_page=#{MAX_PER_PAGE}"
47
+ end
48
+ end
36
49
 
37
- def next_page(page)
38
- "https://#{@config.api_domain}/api/v2/items?page=#{page}&per_page=#{PER_PAGE}"
50
+ class TeamEndPoint < ApiEndPoint
51
+ def url(article_url: nil, page: 1)
52
+ "https://#{@config.api_domain}/api/v2/items?page=#{page}&per_page=#{MAX_PER_PAGE}"
39
53
  end
40
54
  end
41
55
  end
@@ -20,10 +20,6 @@ module QiitaExport::Fetcher
20
20
  ::QiitaExport::Article.new(key, url, title, raw_body, rendered_body, created_at, updated_at, user_id)
21
21
  end
22
22
 
23
- def article_key(url)
24
- File.basename(url)
25
- end
26
-
27
23
  def request_header
28
24
  has_api_token? ? auth_header : default_header
29
25
  end
@@ -9,7 +9,7 @@ module QiitaExport::Fetcher
9
9
  :export_dir_path, :team?, :team_name,
10
10
  :article_urls, :has_api_token?, :api_token,
11
11
  :user_id, :default_header, :auth_header,
12
- :api_domain
12
+ :api_domain, :article_key
13
13
 
14
14
  def initialize
15
15
  @config = ::QiitaExport::Config
@@ -54,7 +54,7 @@ module QiitaExport::Fetcher
54
54
  private
55
55
 
56
56
  def to_article(row)
57
- key = File.basename(row['ZURL'])
57
+ key = article_key(row['ZURL'])
58
58
  url = row['ZURL']
59
59
  title = row['ZTITLE']
60
60
  raw_body = row['ZRAW_BODY']
@@ -5,8 +5,6 @@ require 'open-uri'
5
5
  module QiitaExport::Fetcher
6
6
  class PaginationFetcher < ApiFetcher
7
7
 
8
- PER_PAGE = 100
9
-
10
8
  def initialize(endpoint_sym)
11
9
  super()
12
10
  @endpoint = ApiEndPoint.instance(endpoint_sym)
@@ -33,8 +31,8 @@ module QiitaExport::Fetcher
33
31
  private
34
32
 
35
33
  def paginate_articles(page)
36
- url = @endpoint.next_page(page)
37
- open(@endpoint.next_page(page), request_header) do |io|
34
+ url = @endpoint.url(page: page)
35
+ open(url, request_header) do |io|
38
36
  JSON.parse(io.read)
39
37
  end
40
38
  rescue => e
@@ -5,6 +5,11 @@ require 'open-uri'
5
5
  module QiitaExport::Fetcher
6
6
  class UrlFetcher < ApiFetcher
7
7
 
8
+ def initialize
9
+ super()
10
+ @endpoint = ApiEndPoint.instance(:item)
11
+ end
12
+
8
13
  def find_articles
9
14
  articles = []
10
15
  article_urls.each do |url|
@@ -16,10 +21,14 @@ module QiitaExport::Fetcher
16
21
 
17
22
  private
18
23
 
19
- def find_article(url)
20
- open("https://#{api_domain(url)}/api/v2/items/#{article_key(url)}", request_header) do |io|
24
+ def find_article(article_url)
25
+ url = @endpoint.url(article_url: article_url)
26
+ open(url, request_header) do |io|
21
27
  JSON.parse(io.read)
22
28
  end
29
+ rescue => e
30
+ $stderr.puts "#{e} : #{url}"
31
+ raise
23
32
  end
24
33
  end
25
34
  end
@@ -1,4 +1,4 @@
1
1
  module QiitaExport
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
4
4
 
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
  spec.bindir = 'bin'
21
21
 
22
+ spec.required_ruby_version = '>= 2.0.0'
23
+
22
24
  spec.add_dependency "sqlite3"
23
25
 
24
26
  spec.add_development_dependency "bundler", "~> 1.7"
@@ -5,6 +5,7 @@ require 'qiita-export'
5
5
 
6
6
  describe QiitaExport::Config do
7
7
  let(:valid_url) { 'http://qiita.com/akishin/items/61630d628f4c8e141ef2' }
8
+ let(:valid_team_url) { 'http://example.qiita.com/foo@github/items/99999999999999999999' }
8
9
  let(:valid_kobito_db) { File.expand_path(QiitaExport::Config::DEFAULT_KOBITO_DB) }
9
10
  let(:valid_team_name) { 'example' }
10
11
  let(:valid_argv) {
@@ -42,6 +43,33 @@ describe QiitaExport::Config do
42
43
 
43
44
  end
44
45
 
46
+ describe ".user_id" do
47
+ context "with user_id option" do
48
+ subject do
49
+ described_class.configure(['--user-id', 'foo'])
50
+ end
51
+ it { expect(subject.user_id).to eq('foo') }
52
+ end
53
+
54
+ context "without user_id option" do
55
+ subject do
56
+ described_class.configure(valid_argv)
57
+ end
58
+ it { expect(subject.user_id).to be_nil }
59
+ it { expect(subject.user_id(valid_url)).to eq('akishin') }
60
+ it { expect(subject.user_id(valid_team_url)).to eq('foo@github') }
61
+ end
62
+ end
63
+
64
+ describe ".export_dir_path" do
65
+ subject do
66
+ described_class.configure(['--output-dir', '/tmp/output'])
67
+ end
68
+
69
+ it { expect(subject.export_dir_path(valid_url)).to eq('/tmp/output/qiita/akishin') }
70
+ it { expect(subject.export_dir_path(valid_team_url)).to eq('/tmp/output/example/foo@github') }
71
+ end
72
+
45
73
  end
46
74
 
47
75
 
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.2
4
+ version: 0.0.3
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-04-24 00:00:00.000000000 Z
11
+ date: 2016-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sqlite3
@@ -82,6 +82,7 @@ files:
82
82
  - bin/qiita-export
83
83
  - lib/qiita-export.rb
84
84
  - lib/qiita-export/article.rb
85
+ - lib/qiita-export/comment.rb
85
86
  - lib/qiita-export/config.rb
86
87
  - lib/qiita-export/exporter.rb
87
88
  - lib/qiita-export/fetcher/api_end_point.rb
@@ -108,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
109
  requirements:
109
110
  - - ">="
110
111
  - !ruby/object:Gem::Version
111
- version: '0'
112
+ version: 2.0.0
112
113
  required_rubygems_version: !ruby/object:Gem::Requirement
113
114
  requirements:
114
115
  - - ">="