nine-gag 0.2.0 → 1.0.0

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: 58bd4e0e7f29c7a6aa412515d8f98e68eaf70cf1
4
- data.tar.gz: 3f13e8a0eb860e74546420fe546eed20014e5940
3
+ metadata.gz: cb5ac4ad667ea7ae49fbaa7a16fdcbdb183bbf56
4
+ data.tar.gz: 78c8c5aaf3dbf17bcb410e90fbc0c3e1ebf67d4c
5
5
  SHA512:
6
- metadata.gz: 89e0b08c08a808a9f1027e15adb2441e68b9ed014f56b1abe4c8730fd73eb63c82692962307c2411745230b26ac8c0813476eff73cdb86996d5abcf675e8b16a
7
- data.tar.gz: a460e735ec08800ab7c157db69e1d29e7cfd2cee18eb0f219fe2e358c14e0aad83589b4aa36c863c8746f2bec111f7a41436b5fccf5cf1c61a2acf7cb83e082c
6
+ metadata.gz: 10a6abe20ba9ddd35729c9e9ea0657d7f6391d0d847b8ff3d460db552c16c0a20f13bc47c2001e805c170d6425ab84a804d2f83275ae3804b70f0b418929cd28
7
+ data.tar.gz: 7b33f9772c8529893674d4a6695b994312dc1ad274efbde063780c31495d4d2209b2805a6041b63df10039b97d143ff3dee30820d8635b8d47e3e343b1d899b3
data/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/nine-gag.svg)](https://badge.fury.io/rb/nine-gag)
2
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
3
 
5
4
  ## Installation
6
5
 
7
6
  Add this line to your application's Gemfile:
8
7
 
9
8
  ```ruby
10
- gem 'nine-gag', '>= 0.1.3'
9
+ gem 'nine-gag', '>= 1.0.0'
11
10
  ```
12
11
 
13
12
  And then execute:
@@ -20,128 +19,79 @@ Or install it yourself as:
20
19
 
21
20
  ## Usage
22
21
 
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)
22
+ * [Posts](#get-posts)
23
+ * [Comments post](#get-comments)
26
24
 
27
25
  ### Get Posts
28
26
  #### Request
29
27
  ```ruby
30
- # http://9gag.com/funny/hot
31
- NineGag.index('funny/hot')
28
+ NineGag.trending # http://9gag.com/trending
29
+ NineGag.hot # http://9ag.com/hot
30
+ NineGag.fresh # http://9gag.com/fresh
31
+
32
+ NineGag.gif({ type: "fresh" }) # http://9gag.com/gif/fresh
33
+ NineGag.nsfw({ type: "hot" }) # http://9gag.com/nsfw/hot
34
+ NineGag.cute({ type: "fresh", after: "aAxVod2" }) # http://9gag.com/cute/fresh pagination after post id aAxVod2
35
+ NineGag.video # http://9gag.com/video/hot
32
36
  ```
33
37
 
34
- #### Response
38
+ ### Result
35
39
  ```ruby
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
- ]
40
+ {
41
+ :status => "success",
42
+ :data => [
43
+ {
44
+ :id => "ayXpOeY",
45
+ :title => "Too cold",
46
+ :url => "http://9gag.com/gag/ayXpOeY",
47
+ :comments_count => 5,
48
+ :points => 35,
49
+ :nsfw => true,
50
+ :video => true,
51
+ :media => {
52
+ :image => "https://img-9gag-fun.9cache.com/photo/ayXpOeY_460s.jpg",
53
+ :poster => "https://img-9gag-fun.9cache.com/photo/ayXpOeY_460s.jpg",
54
+ :mp4 => "https://img-9gag-fun.9cache.com/photo/ayXpOeY_460sv.mp4",
55
+ :webvm => "https://img-9gag-fun.9cache.com/photo/ayXpOeY_460svwm.webm"
56
+ },
57
+ :tags => ["Awesome"]
58
+ },
59
+ ....
60
+ ]
61
+ }
61
62
  ```
62
63
 
63
- ### Load more data
64
- ```ruby
65
- NineGag.index('funny/hot', :last_id_post)
66
-
67
- # example
68
- # page 1
69
- posts = NineGag.index('funny/hot')
64
+ ### Get Comments
70
65
 
71
- # page 2
72
- last_id = posts.last[:id]
73
- posts = NineGag.index('funny/hot', last_id)
74
- ```
75
-
76
- ### Get Detail Post
77
66
  #### Request
67
+
78
68
  ```ruby
79
- post = NineGag.show(:post_id)
69
+ NineGag.comments("post-id")
80
70
  ```
81
71
 
82
- #### Response
72
+ ### Result
83
73
  ```ruby
84
74
  {
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
- }
75
+ :status => "success",
76
+ :data => [
77
+ {
78
+ :id => "c_151655950544877262",
79
+ :text => "they are paid according to the value that they bring to their employer",
80
+ :timestamp => 1516559505,
81
+ :level => 1,
82
+ :likes_count => 376,
83
+ :dislikes_count => 0,
84
+ :permalink => "http://9gag.com/gag/aeM3RWp#cs_comment_id=c_151655950544877262",
85
+ :user => {
86
+ :user_id => "u_13967520747952",
87
+ :avatar_url => "https://accounts-cdn.9gag.com/media/avatar/17107551_100_47.jpg",
88
+ :display_name => "aceofjz"
89
+ }
90
+ },
91
+ ....
92
+ ]
96
93
  }
97
- ```
98
-
99
- ### Get Comments Post
100
- #### Request
101
- ```ruby
102
- NineGag.comments(:post_id)
103
- ```
104
94
 
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
95
  ```
146
96
 
147
97
  ## Contributing
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "nine/gag"
4
+ require "nine-gag"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "nine/gag"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
14
- IRB.start
13
+ require "pry"
14
+ Pry.start
@@ -1,28 +1,118 @@
1
- require 'open-uri'
2
- require 'nokogiri'
3
1
  require 'rest-client'
4
2
  require 'json'
5
3
 
6
- require 'nine-gag/version'
7
- require 'nine-gag/scraper'
8
- require 'nine-gag/generate'
4
+ class NineGag
5
+ DEFAULT = %w[hot trending fresh].freeze
9
6
 
10
- module NineGag
11
- def self.index(path, next_page = nil)
12
- data = NineGag::Scraper.new(path).index(next_page)
7
+ def self.comments(id)
8
+ url = 'http://comment-cdn.9gag.com/v1/cacheable/comment-list.json'
9
+ params = {
10
+ appId: "a_dd8f2b7d304a10edaf6f29517ea0ca4100a43d1b",
11
+ url: "http://9gag.com/gag/#{id}",
12
+ count: 10,
13
+ level: 2,
14
+ order: 'score',
15
+ mentionMapping: true,
16
+ origin: '9gag.com'
17
+ }
18
+ # params.merge(ref: next_page) unless next_page.nil?
13
19
 
14
- NineGag::Generate.new(data).index
20
+ begin
21
+ result = RestClient.get(url, { params: params })
22
+ data = JSON.parse(result.body, symbolize_names: true)[:payload][:comments].map do |c|
23
+ user = c[:user]
24
+ comment = {
25
+ id: c[:commentId],
26
+ text: c[:text],
27
+ timestamp: c[:timestamp],
28
+ level: c[:level],
29
+ likes_count: c[:likeCount],
30
+ dislikes_count: c[:dislikeCount],
31
+ permalink: c[:permalink],
32
+ user: {
33
+ user_id: user[:userId],
34
+ avatar_url: user[:avatarUrl],
35
+ display_name: user[:displayName]
36
+ }
37
+ }
38
+ end
39
+ {
40
+ status: "success",
41
+ data: data
42
+ }
43
+ rescue RestClient::ExceptionWithResponse => e
44
+ {
45
+ status: "failed",
46
+ message: e.response
47
+ }
48
+ end
15
49
  end
16
50
 
17
- def self.show(path)
18
- data = NineGag::Scraper.new(path).show
51
+ def self.method_missing(method_name, *args, &block)
52
+ group =
53
+ if DEFAULT.include?(method_name)
54
+ "default"
55
+ else
56
+ method_name
57
+ end
19
58
 
20
- NineGag::Generate.new(data).show
59
+ opts = args[0] || {}
60
+ type = opts.fetch(:type, nil)
61
+ after = opts.fetch(:after, nil)
62
+
63
+ type = %w[hot fresh].include?(type) ? type : "hot"
64
+ post_scrape(group, type, after)
21
65
  end
22
66
 
23
- def self.comments(id, next_page = nil)
24
- data = NineGag::Scraper.new(id).comments(next_page)
67
+ private
68
+
69
+ def self.post_scrape(group = "default", type = "hot", after = nil)
70
+ url = "https://9gag.com/v1/group-posts/group/#{group}/type/#{type}"
71
+ headers = {
72
+ Accept: 'application/json',
73
+ 'X-Requested-With': 'XMLHttpRequest',
74
+ params: { after: after }
75
+ }
76
+
77
+ begin
78
+ result = RestClient.get(url, headers)
79
+ data =
80
+ JSON.parse(result.body, symbolize_names: true)[:data][:posts].map do |post|
81
+ p = {
82
+ id: post[:id],
83
+ title: post[:title],
84
+ url: post[:url],
85
+ comments_count: post[:commentsCount],
86
+ points: post[:upVoteCount],
87
+ nsfw: !post[:nsfw].zero?,
88
+ video: false,
89
+ media: {
90
+ image: post[:images][:image700][:url],
91
+ poster: post[:images][:image460][:url]
92
+ },
93
+ tags: post[:tags].map {|t| t[:key]}
94
+ }
95
+
96
+ if post[:type] == "Animated"
97
+ p[:video] = true
98
+ p[:media].merge!(
99
+ mp4: post[:images][:image460sv][:url],
100
+ webvm: post[:images][:image460svwm][:url]
101
+ )
102
+ end
103
+
104
+ p
105
+ end
25
106
 
26
- NineGag::Generate.new(data).comments
107
+ {
108
+ status: "success",
109
+ data: data
110
+ }
111
+ rescue RestClient::ExceptionWithResponse => e
112
+ {
113
+ status: "failed",
114
+ message: e.response
115
+ }
116
+ end
27
117
  end
28
118
  end
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'nine-gag/version'
4
+ require 'nine-gag'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'nine-gag'
8
- spec.version = NineGag::VERSION
8
+ spec.version = '1.0.0'
9
9
  spec.authors = ['Dimas J. Taniawan']
10
10
  spec.email = ['dimazniawan@gmail.com']
11
11
 
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.required_ruby_version = '>= 2.0.0'
25
25
 
26
- spec.add_dependency 'nokogiri', '~> 1.6.0', '>= 1.6.0'
26
+ # spec.add_dependency 'nokogiri', '~> 1.8.0', '>= 1.8.0'
27
27
  spec.add_dependency 'rest-client', '~> 2.0.0', '>= 2.0.0'
28
28
 
29
29
  spec.add_development_dependency 'bundler', '~> 1.13'
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nine-gag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
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: 2017-01-05 00:00:00.000000000 Z
11
+ date: 2018-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: nokogiri
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 1.6.0
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 1.6.0
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: 1.6.0
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 1.6.0
33
13
  - !ruby/object:Gem::Dependency
34
14
  name: rest-client
35
15
  requirement: !ruby/object:Gem::Requirement
@@ -149,9 +129,6 @@ files:
149
129
  - bin/console
150
130
  - bin/setup
151
131
  - lib/nine-gag.rb
152
- - lib/nine-gag/generate.rb
153
- - lib/nine-gag/scraper.rb
154
- - lib/nine-gag/version.rb
155
132
  - nine-gag.gemspec
156
133
  homepage: https://github.com/dimasjt/nine-gag
157
134
  licenses:
@@ -173,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
150
  version: '0'
174
151
  requirements: []
175
152
  rubyforge_project:
176
- rubygems_version: 2.5.1
153
+ rubygems_version: 2.6.11
177
154
  signing_key:
178
155
  specification_version: 4
179
156
  summary: 9Gag API
@@ -1,113 +0,0 @@
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,50 +0,0 @@
1
- module NineGag
2
- class Scraper
3
- def initialize(path)
4
- @path = path
5
- end
6
-
7
- # path = ":section/:type"
8
- # next_page = "last_id"
9
- def index(next_page = nil)
10
- url = full_url(@path)
11
-
12
- headers = {
13
- Accept: 'application/json',
14
- 'X-Requested-With': 'XMLHttpRequest',
15
- params: { id: next_page }
16
- }
17
-
18
- RestClient.get(url, headers)
19
- end
20
-
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'
38
- }
39
- params.merge(ref: next_page) unless next_page.nil?
40
-
41
- RestClient.get(url, { params: params })
42
- end
43
-
44
- private
45
-
46
- def full_url(path)
47
- "http://9gag.com/#{path}"
48
- end
49
- end
50
- end
@@ -1,3 +0,0 @@
1
- module NineGag
2
- VERSION = "0.2.0"
3
- end