nine-gag 0.1.3 → 0.1.4

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: 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