qiita_matome 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +22 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +0 -0
  6. data/.travis.yml +8 -0
  7. data/CONTRIBUTING.md +44 -0
  8. data/Gemfile +13 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +210 -0
  11. data/Rakefile +8 -0
  12. data/bin/qiitam +34 -0
  13. data/lib/display.rb +10 -0
  14. data/lib/display/display_consts.rb +35 -0
  15. data/lib/display/displayer.rb +81 -0
  16. data/lib/file_writer.rb +19 -0
  17. data/lib/models/article.rb +38 -0
  18. data/lib/models/articles.rb +40 -0
  19. data/lib/qiita_json_loader.rb +43 -0
  20. data/lib/qiita_matome/version.rb +4 -0
  21. data/lib/qiita_matome_core.rb +121 -0
  22. data/lib/qiita_matome_dsl.rb +31 -0
  23. data/lib/qiita_matome_dsl_model.rb +37 -0
  24. data/lib/sort.rb +10 -0
  25. data/lib/sort/sort_consts.rb +28 -0
  26. data/lib/sort/sorter.rb +51 -0
  27. data/lib/validators.rb +13 -0
  28. data/lib/validators/article_validator.rb +19 -0
  29. data/lib/validators/articles_validator.rb +16 -0
  30. data/lib/validators/display_columns_validator.rb +41 -0
  31. data/lib/validators/sort_type_validator.rb +19 -0
  32. data/manual_test_docs/.gitkeep +0 -0
  33. data/qiita_matome.gemspec +28 -0
  34. data/samples/matome_title_asc.md +25 -0
  35. data/spec/display/displayer_spec.rb +341 -0
  36. data/spec/file_writer_spec.rb +92 -0
  37. data/spec/models/article_spec.rb +131 -0
  38. data/spec/models/articles_spec.rb +305 -0
  39. data/spec/qiita_matome_core_spec.rb +46 -0
  40. data/spec/sort/sorter_spec.rb +392 -0
  41. data/spec/spec_helper.rb +16 -0
  42. data/spec/validators/article_validator_spec.rb +53 -0
  43. data/spec/validators/articles_validator_spec.rb +54 -0
  44. data/spec/validators/display_columns_validator_spec.rb +58 -0
  45. data/spec/validators/sort_type_validator_spec.rb +54 -0
  46. metadata +202 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c28828004e752e84cbc90e62ab95234f7a1ca99
4
+ data.tar.gz: 097cd2f62928e55f42ac75d500f3b2d7eba6982a
5
+ SHA512:
6
+ metadata.gz: c4e1227e445a85e8ec077313791ddeaaa92abe213865a940811477733dba71da41dcad873cee2435543fa525967aa3f629ce5197b567243fa437648c69ab409e
7
+ data.tar.gz: b39fb658de739614ff5af2fd9e7fc1cbaf7577d6adb8c993a3933a59aa68da95fe4a7c7aaa2b0f4c836f9eb7dc841facb31add61dbe8c364e90805d5a5d7104d
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
File without changes
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem update --system 2.1.11
4
+ - gem --version
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1
@@ -0,0 +1,44 @@
1
+ # contributing 注意事項
2
+
3
+ ## ブランチに関して
4
+ * *master* を直接編集せずにトピックブランチを作成して *pull request* を行うこと
5
+ * トピックブランチは修正内容を表した、わかりやすい名前にすること
6
+
7
+ ## コーディング規約について
8
+
9
+ * **Ruby Style Guide** に準じます
10
+
11
+ * [Ruby Style Guide 英語版](https://github.com/bbatsov/ruby-style-guide)
12
+ * [Ruby Style Guide 和訳版](https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
13
+
14
+ ## RuboCopの利用に関して
15
+ * *rubocop* の警告が1件も発生しない状態で *pull request* を行うこと
16
+
17
+ ~~~bash
18
+ # プロジェクトルートへ移動
19
+ $ cd qiita_matome
20
+ # プロジェクト全体に対して rubocop のチェックを実行
21
+ $ rubocop
22
+ Inspecting 32 file
23
+ .
24
+
25
+ 32 file inspected, no offenses detected
26
+
27
+ # ※ no offenses detected になっていること
28
+ ~~~
29
+
30
+ * *rubocop* の警告について、どうしても規約を守ることが難しい場合は警告除外用のコメントを利用してください
31
+
32
+ 除外方法については [こちらの記事](http://qiita.com/tbpgr/items/a9000c5c6fa92a46c206) を参照
33
+
34
+ ## RSpecのテストに関して
35
+ * RSpecの単体テストを一緒に作成してください。
36
+ * 事情があって **例外的に** 単体テストの作成をしない場合は、手動テストの項目・手順を *manual_test_docs* に作成してください。
37
+
38
+ ※なぜ単体テストを作成しないのか、 **理由** を *pull request* 時のコメントに記述してください。
39
+ 例えば、 *lib / qiita_json_loader.rb* などは、Qiita のWeb API へのアクセスが主であるため、
40
+ あえて単体テストを作成していません。
41
+
42
+ * テストの作成は [*rspec_piccolo gem*](https://github.com/tbpgr/rspec_piccolo) を利用していただけると体裁が整って嬉しいですが必須ではありません。
43
+
44
+ ※冗長なテストよりは **DRYなテストが好みです**
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "activemodel", "~> 4.0.2"
6
+ gem "thor", "~> 0.18.1"
7
+
8
+ gem "rspec", "~> 2.14.1"
9
+ gem "simplecov", "~> 0.8.2"
10
+ gem 'rubocop', '~> 0.23.0'
11
+ group :test do
12
+ gem 'coveralls', require: false
13
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 tbpgr
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.
@@ -0,0 +1,210 @@
1
+ # QiitaMatome
2
+
3
+ [![Build Status](https://travis-ci.org/tbpgr/qiita_matome.png?branch=master)](https://travis-ci.org/tbpgr/qiita_matome)
4
+ [![Coverage Status](https://coveralls.io/repos/tbpgr/qiita_matome/badge.png)](https://coveralls.io/r/tbpgr/qiita_matome)
5
+ [![Code Climate](https://codeclimate.com/github/tbpgr/qiita_matome.png)](https://codeclimate.com/github/tbpgr/qiita_matome)
6
+
7
+ Qiitaのまとめページジェネレーター
8
+
9
+ ## 概要
10
+
11
+ Qiitaの特定ユーザー、特定タグのリンクを一覧化したまとめ記事を生成する。
12
+
13
+ ## 前提
14
+ * 認証不要(認証不要APIである、`GET /api/v1/users/:url_name/items` のみを利用する)
15
+ * 任意のユーザーの任意の1つのタグに限定してまとめ記事を作成する
16
+
17
+ ※基本的には自分のユーザーのまとめを作ることを想定しています
18
+
19
+ ## 確認済み環境
20
+ * ruby 2.0.0p451 環境にて動作確認済み
21
+
22
+ ## サブコマンド
23
+
24
+ |コマンド|ショートカット|内容|
25
+ |:--|:--|:--|
26
+ |init|i|設定ファイル( *Qiitamatome* )を出力|
27
+ |matome|m|まとめ記事の生成。実行するためには事前に *Qiitamatome* を生成、編集する必要がある|
28
+ |help|h|ヘルプの表示|
29
+ |version|v|バージョンの表示|
30
+
31
+ ## 設定ファイルについて
32
+
33
+ RubyのDSLで作成されています。
34
+
35
+ ファイル名は *Qiitamatome*
36
+
37
+ ~~~ruby
38
+ qiitam init
39
+ ~~~
40
+
41
+ もしくは
42
+
43
+ ~~~ruby
44
+ qiitam i
45
+ ~~~
46
+
47
+ でテンプレートを生成できます。
48
+ Gemfileのような感覚でご利用ください。
49
+
50
+ Rubyの内部DSLになっているので、Rubyのコードを利用することも可能です。
51
+ 例えば、出力ファイルの名前に現在時刻を埋め込んだり、など。
52
+
53
+ ### 設定ファイル自動生成時の内容
54
+
55
+ ~~~ruby
56
+ # encoding: utf-8
57
+
58
+ # Set your qiita user name
59
+ # user is required
60
+ # user allow only String
61
+ user "your value"
62
+
63
+ # Set your matome target tag name
64
+ # tag is required
65
+ # tag allow only String
66
+ tag "your value"
67
+
68
+ # Set your matome title
69
+ # title is required
70
+ # title allow only String
71
+ title "your value"
72
+
73
+ # Set your matome file's output path
74
+ # output_file is required
75
+ # output_file allow only String
76
+ # output_file's default value => "matome.md"
77
+ output_file "matome.md"
78
+
79
+ # Set your matome sort type. you can choose created_at_asc/desc, updated_at_asc/desc, title_asc/desc, stock_count_asc/desc
80
+ # sort_type allow only String
81
+ # sort_type's default value => "created_at_desc"
82
+ sort_type "created_at_desc"
83
+
84
+ # Set your matome display columns. you can choose :title, :created_at, :updated_at, :stock_count and :no
85
+ # display_columns allow only Array
86
+ # display_columns's default value => [:no, :title, :created_at, :stock_count]
87
+ display_columns [:no, :title, :created_at, :stock_count]
88
+
89
+ # Set your matome exclude files
90
+ # excludes allow only Array
91
+ # excludes's default value => []
92
+ excludes []
93
+ ~~~
94
+
95
+ ### 設定項目一覧
96
+
97
+ |設定キー|必須|デフォルト|内容|
98
+ |:--|:--|:--|:--|
99
+ |user|○|なし|対象ユーザー|
100
+ |tag|○|なし|対象タグ|
101
+ |title|○|なし|まとめ記事タイトル|
102
+ |output_file|○|matome.md|出力パス|
103
+ |sort_type|×|created_at_desc|まとめ記事内のソート順。詳しくはソート種別参照|
104
+ |display_columns|×|[:no, :title, :created_at, :stock_count]|まとめ記事の表示項目指定。指定順に並ぶ。詳しくは表示項目参照|
105
+ |exclude|×|[id1, id2...]|除外記事ID(uuid)を配列で指定。例えば、まとめ記事自信を除外するために指定|
106
+
107
+ ### ソート種別
108
+
109
+ |種別|内容|
110
+ |:--|:--|
111
+ |created_at_asc|初回投稿日昇順|
112
+ |created_at_desc|初回投稿日降順|
113
+ |updated_at_asc|更新日昇順|
114
+ |updated_at_desc|更新日降順|
115
+ |title_asc|記事タイトル昇順|
116
+ |title_desc|記事タイトル降順|
117
+ |stock_count_asc|ストック数昇順|
118
+ |stock_count_desc|ストック数降順。つまり人気記事順|
119
+
120
+ ### 表示項目
121
+
122
+ |項目名|内容|
123
+ |:--|:--|
124
+ |:title|記事タイトル。該当記事へのリンクになる|
125
+ |:created_at|初回投稿日 「YYYY/MM/DD hh:mi:ss」 フォーマット|
126
+ |:updated_at|更新日 「YYYY/MM/DD hh:mi:ss」 フォーマット|
127
+ |:stock_count|ストック数|
128
+ |:no|連番|
129
+
130
+ ## インストール
131
+
132
+ Add this line to your application's Gemfile:
133
+
134
+ gem 'qiita_matome'
135
+
136
+ And then execute:
137
+
138
+ $ bundle
139
+
140
+ Or install it yourself as:
141
+
142
+ $ gem install qiita_matome
143
+
144
+
145
+ ## 使用手順の例
146
+
147
+ * 設定ファイル( *Qiitamatome* )の生成
148
+
149
+ ~~~bash
150
+ $ qiitam init
151
+ ~~~
152
+
153
+ または
154
+
155
+ ~~~bash
156
+ $ qiitam i
157
+ ~~~
158
+
159
+ * 設定ファイル( *Qiitamatome* )を編集
160
+
161
+ ユーザー *tbpgr* の *rubocop* タグの記事をまとめ記事として出力します。
162
+
163
+ ~~~bash
164
+ user "tbpgr"
165
+ tag "rubocop"
166
+ title "RuboCop まとめ タイトル昇順"
167
+ output_file "./matome_title_asc.md"
168
+ sort_type "title_asc"
169
+ display_columns [:no, :title, :created_at, :stock_count]
170
+ # まとめ記事を除外
171
+ excludes ['edbfecb6a6789dd54f47']
172
+ ~~~
173
+
174
+ * まとめ記事作成を実行
175
+
176
+ ~~~bash
177
+ $ qiitam matome
178
+ ~~~
179
+
180
+ または
181
+
182
+ ~~~bash
183
+ $ qiitam m
184
+ ~~~
185
+
186
+ * 結果を確認
187
+
188
+ ~~~bash
189
+ $ cat ./matome_title_asc.md
190
+ # 内容が表示される
191
+ ~~~
192
+
193
+ ## 出力サンプル
194
+
195
+ [matome_title_asc.md](./samples/matome_title_asc.md)
196
+
197
+ ## History
198
+ * version 0.0.1 : 2014/07/03 : first release
199
+
200
+ ## Contributing
201
+
202
+ 1. Fork it ( https://github.com/tbpgr/qiita_matome/fork )
203
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
204
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
205
+ 4. Push to the branch (`git push origin my-new-feature`)
206
+ 5. Create a new Pull Request
207
+
208
+ ## 補足
209
+ * この gem は [dslable gem](https://github.com/tbpgr/dslable) を利用して作成しています
210
+ * この gem のテストクラスは [rspec_piccolo gem](https://github.com/tbpgr/rspec_piccolo) を利用してひな形を生成しています
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+ task default: [:spec]
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = 'spec/**/*_spec.rb'
8
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'qiita_matome_core'
5
+ require 'qiita_matome/version'
6
+ require 'thor'
7
+
8
+ module QiitaMatome
9
+ # = QiitaMatome CLI
10
+ class CLI < Thor
11
+ class_option :help, type: :boolean, aliases: '-h', desc: 'help message.'
12
+ class_option :version, type: :boolean, desc: 'version'
13
+
14
+ desc 'matome', 'Generate QiitaMatome markdown file.'
15
+ def matome
16
+ QiitaMatome::Core.new.matome
17
+ rescue => e
18
+ warn(e.message)
19
+ exit(false)
20
+ end
21
+
22
+ desc 'init', 'generate Qiitamatomefile'
23
+ def init
24
+ QiitaMatome::Core.new.init
25
+ end
26
+
27
+ desc 'version', 'version'
28
+ def version
29
+ p QiitaMatome::VERSION
30
+ end
31
+ end
32
+ end
33
+
34
+ QiitaMatome::CLI.start(ARGV)
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require 'display/displayer'
4
+ require 'display/display_consts'
5
+
6
+ module QiitaMatome
7
+ # QiitaMatome::Display
8
+ module Display
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ module QiitaMatome
4
+ # QiitaMatome::Display
5
+ module Display
6
+ # QiitaMatome::Display::Consts
7
+ module Consts
8
+ TITLE = :title.freeze
9
+ CREATED_AT = :created_at.freeze
10
+ UPDATED_AT = :updated_at.freeze
11
+ STOCKED = :stock_count.freeze
12
+ NO = :no.freeze
13
+
14
+ ALIGN_RIGHT = :right
15
+ ALIGN_LEFT = :left
16
+ ALIGN_CENTER = :center
17
+
18
+ COLUMNS = [TITLE, CREATED_AT, UPDATED_AT, STOCKED, NO]
19
+ COLUMNS_ALIGN_MAP = {
20
+ TITLE => ALIGN_LEFT,
21
+ CREATED_AT => ALIGN_CENTER,
22
+ UPDATED_AT => ALIGN_CENTER,
23
+ STOCKED => ALIGN_RIGHT,
24
+ NO => ALIGN_RIGHT
25
+ }
26
+ COLUMNS_TITLE_MAP = {
27
+ TITLE => 'タイトル',
28
+ CREATED_AT => '作成日',
29
+ UPDATED_AT => '更新日',
30
+ STOCKED => 'ストック数',
31
+ NO => 'No.'
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+ require 'validators/articles_validator'
3
+ require 'validators/article_validator'
4
+ require 'validators/display_columns_validator'
5
+
6
+ module QiitaMatome
7
+ # QiitaMatome::Display
8
+ module Display
9
+ # QiitaMatome::Display::Displayer
10
+ class Displayer
11
+ attr_reader :title, :articles, :display_columns
12
+
13
+ def initialize(title, articles,
14
+ display_columns = [:no, :title, :created_at, :stock_count])
15
+ Validators::ArticlesValidator.validate(articles)
16
+ Validators::ArticleValidator.validate(articles)
17
+ display_columns_list = Array(display_columns)
18
+ Validators::DisplayColumnsValidator.validate(display_columns_list)
19
+ symbolized_display_columns = display_columns_list.map(&:to_sym)
20
+ @title = title
21
+ @articles = articles
22
+ @display_columns = symbolized_display_columns
23
+ end
24
+
25
+ def display_title
26
+ "# #{@title}"
27
+ end
28
+
29
+ def table_header
30
+ title_header = table_title_header
31
+ title_align = table_align
32
+ "#{title_header}\n#{title_align}\n"
33
+ end
34
+
35
+ def matome_updated
36
+ "更新日: #{DateTime.now.strftime('%Y/%m/%d %H:%M:%S')}"
37
+ end
38
+
39
+ def display_article(no, article)
40
+ disp = @display_columns.each_with_object([]) do |item, memo|
41
+ memo << case item
42
+ when :no then no
43
+ when :title then article.title_link
44
+ when :created_at then article.created_at_ymdhms
45
+ when :updated_at then article.updated_at_ymdhms
46
+ when :stock_count then article.stock_count
47
+ end
48
+ end
49
+ "|#{disp.join('|')}|"
50
+ end
51
+
52
+ def display_articles
53
+ display = []
54
+ @articles.each.with_index(1) do |article, no|
55
+ display << display_article(no, article)
56
+ end
57
+ display.join("\n") + "\n"
58
+ end
59
+
60
+ private
61
+
62
+ def table_title_header
63
+ header = @display_columns.each_with_object([]) do |item, memo|
64
+ memo << Consts::COLUMNS_TITLE_MAP[item]
65
+ end
66
+ "|#{header.join('|')}|"
67
+ end
68
+
69
+ def table_align
70
+ align = @display_columns.each_with_object([]) do |item, memo|
71
+ memo << case Consts::COLUMNS_ALIGN_MAP[item]
72
+ when Consts::ALIGN_RIGHT then '--:'
73
+ when Consts::ALIGN_LEFT then ':--'
74
+ when Consts::ALIGN_CENTER then ':--:'
75
+ end
76
+ end
77
+ "|#{align.join('|')}|"
78
+ end
79
+ end
80
+ end
81
+ end