nine-gag 0.1.3 → 0.1.4

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: ed51b9fff78efa65daf34555ba17d7a62d86a675
4
- data.tar.gz: baab575f82d737a51c03a5e9465ff9c37206e5a1
3
+ metadata.gz: c6cfcfb89ee1e7d21c3d9a9fe9d94dd05fbb9c7d
4
+ data.tar.gz: 7256019e4e1d63ceb97586aa88881d0c5dd4bce4
5
5
  SHA512:
6
- metadata.gz: f66eec53c4765f7b8d79ead0c9a100bb3f940c35a8586230f02d1641eea3cbfbc298d5676232f70bb6c43719f749d2c5ba58e9f5863211eb9ba8b4550fe516ae
7
- data.tar.gz: 63a70b89bae89eaecec6f113e2d8ef4410945d43259abe7816943724495b17e233a64982d7c44d477530f6dff7054dd8435ecddab06bb6ef2160bee4013c8225
6
+ metadata.gz: cd2a140402c1043a61debcb2a9ea95cbf89e3846988c50e3a8c00437a1fa855cc6d508482c2172f263dd6436f62efb144432b1504c2d30326600904b2313f62e
7
+ data.tar.gz: 9d2f8dc9dc04d6357eac5892aa19afb96f48690a04232a43bba9e2b81b55e6fe55652d4bfa04d7a83b49606a6657aa684c26c7848068cf17d7cb793aaf828976
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
- | master | develop |
2
- | ------ | ------- |
3
- | [![Build Status](https://travis-ci.org/dimasjt/nine-gag.svg?branch=master)](https://travis-ci.org/dimasjt/nine-gag) | [![Build Status](https://travis-ci.org/dimasjt/nine-gag.svg?branch=develop)](https://travis-ci.org/dimasjt/nine-gag) |
1
+ [![Gem Version](https://badge.fury.io/rb/nine-gag.svg)](https://badge.fury.io/rb/nine-gag)
2
+ [![Build Status](https://travis-ci.org/dimasjt/nine-gag.svg?branch=develop)](https://travis-ci.org/dimasjt/nine-gag)
3
+ [![Code Climate](https://codeclimate.com/github/dimasjt/nine-gag/badges/gpa.svg)](https://codeclimate.com/github/dimasjt/nine-gag)
4
4
 
5
5
  ## Installation
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'nine-gag'
10
+ gem 'nine-gag', '>= 0.1.3'
11
11
  ```
12
12
 
13
13
  And then execute:
@@ -20,30 +20,130 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- ### Get data from /section/type
23
+ * [Posts](https://github.com/dimasjt/nine-gag/tree/develop#get-posts)
24
+ * [Detail post](https://github.com/dimasjt/nine-gag/tree/develop#get-detail-post)
25
+ * [Comments post](https://github.com/dimasjt/nine-gag/tree/develop#get-comments-post)
26
+
27
+ ### Get Posts
28
+ #### Request
29
+ ```ruby
30
+ # http://9gag.com/funny/hot
31
+ NineGag.index('funny/hot')
32
+ ```
33
+
34
+ #### Response
24
35
  ```ruby
25
- # http://9gag.com/gif/hot
26
- NineGag.index('gif/hot')
36
+ [
37
+ {
38
+ :id => "ajqgWZp",
39
+ :title => "How deal with a Warlord",
40
+ :url => "http://9gag.com/gag/ajqgWZp",
41
+ :image => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460s.jpg",
42
+ :comments_count => 28,
43
+ :points => 464,
44
+ :media => {
45
+ :poster => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460s.jpg",
46
+ :mp4 => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460sv.mp4",
47
+ :webm => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460svwm.webm"
48
+ }
49
+ },
50
+ {
51
+ :id => "aERpNWM",
52
+ :title => "Some people really deserve this high-five",
53
+ :url => "http://9gag.com/gag/aERpNWM",
54
+ :image => "http://img-9gag-fun.9cache.com/photo/aERpNWM_460s.jpg",
55
+ :comments_count => 166,
56
+ :points => 6388,
57
+ :media => nil
58
+ },
59
+ ....
60
+ ]
27
61
  ```
28
62
 
29
63
  ### Load more data
30
64
  ```ruby
31
- NineGag.index('gif/hot', :last_id_post)
65
+ NineGag.index('funny/hot', :last_id_post)
32
66
 
33
67
  # example
34
68
  # page 1
35
- posts = NineGag.index('gif/hot')
69
+ posts = NineGag.index('funny/hot')
36
70
 
37
71
  # page 2
38
- last_id = posts.last.id
39
- posts = NineGag.index('gif/hot', last_id)
72
+ last_id = posts.last[:id]
73
+ posts = NineGag.index('funny/hot', last_id)
40
74
  ```
41
75
 
42
- ### Detail post
76
+ ### Get Detail Post
77
+ #### Request
43
78
  ```ruby
44
79
  post = NineGag.show(:post_id)
45
80
  ```
46
81
 
82
+ #### Response
83
+ ```ruby
84
+ {
85
+ :id => "ajqgWZp",
86
+ :title => "How deal with a Warlord",
87
+ :url => "http://9gag.com/gag/ajqgWZp",
88
+ :image => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460s.jpg",
89
+ :comments_count => 28,
90
+ :points => 464,
91
+ :media => {
92
+ :poster => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460s.jpg",
93
+ :mp4 => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460sv.mp4",
94
+ :webm => "http://img-9gag-fun.9cache.com/photo/ajqgWZp_460svwm.webm"
95
+ }
96
+ }
97
+ ```
98
+
99
+ ### Get Comments Post
100
+ #### Request
101
+ ```ruby
102
+ NineGag.comments(:post_id)
103
+ ```
104
+
105
+ #### Response
106
+ ```ruby
107
+ [
108
+ {
109
+ :id => "c_148359676629369444",
110
+ :text => "http://i.memeful.com/media/post/YRO9Qqw_700wa_0.gif",
111
+ :timestamp => 1483596766,
112
+ :user_id => "u_13994024017199",
113
+ :permalink => "http://9gag.com/gag/a6Mg7mL#cs_comment_id=c_148359676629369444",
114
+ :points => 25,
115
+ :media => {
116
+ :jpg => "http://img-comment-fun.9cache.com/media/9a1d1430145033986894189858_700w_0.jpg",
117
+ :gif => "http://img-comment-fun.9cache.com/media/9a1d1430145033986894189858_700wa_0.gif",
118
+ :mp4 => "http://img-comment-fun.9cache.com/media/9a1d1430145033986894189858_700wv_0.mp4"
119
+ },
120
+ :user => {
121
+ :id => "u_13994024017199",
122
+ :avatar => "http://accounts-cdn.9gag.com/media/avatar/17248840_100_13.jpg",
123
+ :username=>"mister_widodo"
124
+ },
125
+ :children => [
126
+ {
127
+ :id => "c_148359764385634228",
128
+ :text => "@mister_widodo perfect",
129
+ :timestamp => 1483597643,
130
+ :user_id => "u_145203259185649618",
131
+ :permalink => "http://9gag.com/gag/a6Mg7mL#cs_comment_id=c_148359764385634228",
132
+ :points => 1,
133
+ :media => nil,
134
+ :user => {
135
+ :id => "u_145203259185649618",
136
+ :avatar => "http://accounts-cdn.9gag.com/media/avatar/27974937_100_1.jpg",
137
+ :username => "psoric39"
138
+ }
139
+ }
140
+ ],
141
+ :order_key=>"score_00000000001004_14835967662936"
142
+ },
143
+ .......
144
+ ]
145
+ ```
146
+
47
147
  ## Contributing
48
148
 
49
149
  Bug reports and pull requests are welcome on GitHub at https://github.com/dimasjt/nine-gag. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -5,19 +5,24 @@ require 'json'
5
5
 
6
6
  require 'nine-gag/version'
7
7
  require 'nine-gag/scraper'
8
+ require 'nine-gag/generate'
8
9
 
9
10
  module NineGag
10
11
  def self.index(path, next_page = nil)
11
- NineGag::Scraper.index(full_url(path), next_page)
12
+ data = NineGag::Scraper.new(path).index(next_page)
13
+
14
+ NineGag::Generate.new(data).index
12
15
  end
13
16
 
14
17
  def self.show(path)
15
- NineGag::Scraper.show(full_url("gag/#{path}"))
18
+ data = NineGag::Scraper.new(path).show
19
+
20
+ NineGag::Generate.new(data).show
16
21
  end
17
22
 
18
- private
23
+ def self.comments(id, next_page = nil)
24
+ data = NineGag::Scraper.new(id).comments(next_page)
19
25
 
20
- def self.full_url(path)
21
- "http://9gag.com/#{path}"
26
+ NineGag::Generate.new(data).comments
22
27
  end
23
28
  end
@@ -0,0 +1,113 @@
1
+ module NineGag
2
+ class Generate
3
+ def initialize(data)
4
+ @data = data
5
+ end
6
+
7
+ def index
8
+ @data = JSON.parse(@data.body)["items"]
9
+ @data.map do |post|
10
+ post = Nokogiri::HTML(post.last).search('article').first
11
+ generate_show_data(post, true)
12
+ end
13
+ end
14
+
15
+ def show
16
+ @data = @data.search('article').first
17
+ generate_show_data(@data)
18
+ end
19
+
20
+ def comments
21
+ @data = JSON.parse(@data.body)["payload"]["comments"]
22
+ @data.map do |comment|
23
+ generated_comment = generate_comment_data(comment)
24
+ generated_comment.merge!(
25
+ children: [],
26
+ order_key: comment["orderKey"]
27
+ )
28
+
29
+ unless comment["children"].empty?
30
+ comment["children"].each do |child|
31
+ generated_comment[:children].push generate_comment_data(child)
32
+ end
33
+ end
34
+
35
+ generated_comment
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def generate_comment_data(comment)
42
+ {
43
+ id: comment["commentId"],
44
+ text: comment["text"],
45
+ timestamp: comment["timestamp"],
46
+ user_id: comment["userId"],
47
+ permalink: comment["permalink"],
48
+ points: comment["likeCount"],
49
+ media: media_comment_data(comment),
50
+ user: user_comment(comment["user"])
51
+ }
52
+ end
53
+
54
+ def user_comment(user)
55
+ {
56
+ id: user["userId"],
57
+ avatar: user["avatarUrl"],
58
+ username: user["displayName"]
59
+ }
60
+ end
61
+
62
+ def media_comment_data(comment)
63
+ return nil if comment["embedMediaMeta"]["embedImage"].nil?
64
+
65
+ {
66
+ jpg: media_comment(comment, "image"),
67
+ gif: media_comment(comment, "animated"),
68
+ mp4: media_comment(comment, "video")
69
+ }
70
+ end
71
+
72
+ def media_comment(comment, media)
73
+ comment["embedMediaMeta"].fetch("embedImage", {}).fetch(media, {}).fetch("url", nil)
74
+ end
75
+
76
+ def generate_show_data(post, index = false)
77
+ if index
78
+ title = post.search('h2.badge-item-title .badge-evt')
79
+ else
80
+ title = post.search('h2.badge-item-title')
81
+ end
82
+
83
+ post_meta = post.search('p.post-meta').first
84
+
85
+ {
86
+ id: post.attribute('data-entry-id').value,
87
+ title: title.text.strip,
88
+ url: post.attribute('data-entry-url').value,
89
+ image: image_data(post.search('div.badge-post-container a img').first),
90
+ comments_count: post_meta.search('a.comment').first.text.sub(' comments', '').sub(',', '').strip.to_i,
91
+ points: post_meta.search('.badge-item-love-count').first.text.sub(',', '').to_i,
92
+ media: media_data(post.search('video').first),
93
+ nsfw: !post.search('.nsfw-post').empty?
94
+ }
95
+ end
96
+
97
+ def image_data(image)
98
+ return "https://placeholdit.imgix.net/~text?txtsize=60&txt=NSFW&w=500&h=350&bg=000000&txtclr=ffffff" if image.nil?
99
+
100
+ image.attribute('src').value
101
+ end
102
+
103
+ def media_data(media)
104
+ return nil if media.nil?
105
+ videos = media.search('source')
106
+ {
107
+ poster: media.attribute('poster').value,
108
+ mp4: videos.first.attribute('src').value,
109
+ webm: videos.last.attribute('src').value
110
+ }
111
+ end
112
+ end
113
+ end
@@ -1,96 +1,50 @@
1
1
  module NineGag
2
2
  class Scraper
3
- # path = ":section/:type"
4
- # next_page = "last_id"
5
- def self.index(path, next_page = nil)
6
- data = if next_page.nil?
7
- scrape_html(path)
8
- else
9
- generate_json_posts(path, next_page)
10
- end
11
-
12
- generate_index_data(data, next_page)
3
+ def initialize(path)
4
+ @path = path
13
5
  end
14
6
 
15
- # path = "gag/:id"
16
- def self.show(path)
17
- generate_show_data(scrape_html(path).search('article').first)
18
- end
19
-
20
- private
21
-
22
- # will return Array of Nokogiri
23
- def self.generate_json_posts(path, next_page)
24
- items = JSON.parse(scrape_json(path, next_page).body)["items"]
25
-
26
- items.map { |item| scrape_html(item.last).search('article').first }
27
- end
28
-
29
- def self.scrape_json(path, next_page)
30
- RestClient.get(path,
31
- { Accept: 'application/json', "X-Requested-With": 'XMLHttpRequest',
32
- params: { id: next_page, c: 10 }
33
- }
34
- )
35
- end
7
+ # path = ":section/:type"
8
+ # next_page = "last_id"
9
+ def index(next_page = nil)
10
+ url = full_url(@path)
36
11
 
37
- # scrape html or from path
38
- def self.scrape_html(path)
39
- Nokogiri::HTML(path_or_html(path))
40
- end
12
+ headers = {
13
+ Accept: 'application/json',
14
+ 'X-Requested-With': 'XMLHttpRequest',
15
+ params: { id: next_page }
16
+ }
41
17
 
42
- # check parameter if path or html
43
- def self.path_or_html(data)
44
- # if path
45
- if data.length < 50
46
- open data
47
- else
48
- data
49
- end
18
+ RestClient.get(url, headers)
50
19
  end
51
20
 
52
- def self.generate_show_data(post, index = false)
53
- if index
54
- title = post.search('h2.badge-item-title .badge-evt')
55
- else
56
- title = post.search('h2.badge-item-title')
57
- end
58
-
59
- post_meta = post.search('p.post-meta').first
60
-
61
- {
62
- id: post.attribute('data-entry-id').value,
63
- title: title.text.strip,
64
- url: post.attribute('data-entry-url').value,
65
- image: image_data(post.search('div.badge-post-container a img').first),
66
- comments_count: post_meta.search('a.comment').first.text.sub(' comments', '').sub(',', '').strip.to_i,
67
- points: post_meta.search('a.point').first.text.sub(' points', '').sub(',', '').strip,
68
- media: media_data(post.search('video').first)
21
+ # path = "gag/:id"
22
+ def show
23
+ url = full_url("gag/#{@path}")
24
+
25
+ Nokogiri::HTML(open(url))
26
+ end
27
+
28
+ def comments(next_page)
29
+ url = 'http://comment-cdn.9gag.com/v1/cacheable/comment-list.json'
30
+ params = {
31
+ appId: "a_dd8f2b7d304a10edaf6f29517ea0ca4100a43d1b",
32
+ url: full_url("gag/#{@path}"),
33
+ count: 10,
34
+ level: 2,
35
+ order: 'score',
36
+ mentionMapping: true,
37
+ origin: '9gag.com'
69
38
  }
70
- end
71
-
72
- def self.generate_index_data(scrape, next_page)
73
- data = next_page.nil? ? scrape.search('article') : scrape
39
+ params.merge(ref: next_page) unless next_page.nil?
74
40
 
75
- data.map do |post|
76
- generate_show_data(post)
77
- end
41
+ RestClient.get(url, { params: params })
78
42
  end
79
43
 
80
- def self.image_data(image)
81
- return nil if image.nil?
82
-
83
- image.attribute('src').value
84
- end
44
+ private
85
45
 
86
- def self.media_data(media)
87
- return nil if media.nil?
88
- videos = media.search('source')
89
- {
90
- poster: media.attribute('poster').value,
91
- mp4: videos.first.attribute('src').value,
92
- webm: videos.last.attribute('src').value
93
- }
46
+ def full_url(path)
47
+ "http://9gag.com/#{path}"
94
48
  end
95
49
  end
96
50
  end
@@ -1,3 +1,3 @@
1
1
  module NineGag
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nine-gag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimas J. Taniawan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-23 00:00:00.000000000 Z
11
+ date: 2017-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -149,6 +149,7 @@ files:
149
149
  - bin/console
150
150
  - bin/setup
151
151
  - lib/nine-gag.rb
152
+ - lib/nine-gag/generate.rb
152
153
  - lib/nine-gag/scraper.rb
153
154
  - lib/nine-gag/version.rb
154
155
  - nine-gag.gemspec