nine-gag 0.2.0 → 1.0.0

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