bad_pigeon 0.1.2 → 0.1.3
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 +4 -4
- data/lib/bad_pigeon/elements/component.rb +5 -0
- data/lib/bad_pigeon/elements/timeline_entry.rb +7 -0
- data/lib/bad_pigeon/elements/timeline_instruction.rb +6 -0
- data/lib/bad_pigeon/elements/timeline_tweet.rb +7 -19
- data/lib/bad_pigeon/entry_filter.rb +3 -0
- data/lib/bad_pigeon/har/har_archive.rb +5 -0
- data/lib/bad_pigeon/har/har_request.rb +9 -0
- data/lib/bad_pigeon/models/tweet.rb +21 -3
- data/lib/bad_pigeon/models/url_entity.rb +5 -0
- data/lib/bad_pigeon/models/user.rb +5 -0
- data/lib/bad_pigeon/timelines/home_timeline.rb +6 -0
- data/lib/bad_pigeon/timelines/list_timeline.rb +6 -0
- data/lib/bad_pigeon/timelines/user_timeline.rb +6 -0
- data/lib/bad_pigeon/tweet_extractor.rb +4 -0
- data/lib/bad_pigeon/util/assertions.rb +4 -0
- data/lib/bad_pigeon/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 603fc8ee8a14e3cdeee420620d4457fcd20b3e86c83f104c714848ad384c27b9
|
4
|
+
data.tar.gz: 4d342a48e1b0b3478ee16e42ed3826b97f1056e09b53461e9cd2b4c3e3fbd348
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70d24323f1b0973bc143e41d07842fce248a25316e24d3e642cea3f862a716867c4728e20254363dbe659d7392235dc40eeac394af09ee986ccc53d303957d9
|
7
|
+
data.tar.gz: ee3c1b8e89badd193f386a2f70a3c4642e6e40eb3767d1136f167534003f9cd51de45a2bf46e33de79e60710515f1c7ee45e0072fd5ff85a42b1b610f6b1b517
|
@@ -2,6 +2,10 @@ module BadPigeon
|
|
2
2
|
module Component
|
3
3
|
# normal tweet in e.g. home/latest or a user's timeline
|
4
4
|
ORGANIC_FEED_TWEET = "suggest_ranked_organic_tweet"
|
5
|
+
NORMAL_TWEET = "tweet"
|
6
|
+
|
7
|
+
# tweet in the latest timeline
|
8
|
+
FOLLOWING = "following_in_network"
|
5
9
|
|
6
10
|
# tweet in a list timeline
|
7
11
|
ORGANIC_LIST_TWEET = "suggest_organic_list_tweet"
|
@@ -19,6 +23,7 @@ module BadPigeon
|
|
19
23
|
|
20
24
|
# promoted tweet (ad)
|
21
25
|
PROMOTED_TWEET = "suggest_promoted"
|
26
|
+
FOLLOWING_PROMOTED = "following_promoted"
|
22
27
|
|
23
28
|
# "Who to follow" block
|
24
29
|
FOLLOW_SUGGESTIONS = "suggest_who_to_follow"
|
@@ -2,6 +2,13 @@ require 'bad_pigeon/elements/timeline_tweet'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents an "entry" which is a part of a timeline response. An entry in most cases is a wrapper for either one
|
7
|
+
# tweet or a group of connected tweets (e.g. a parent and a reply).
|
8
|
+
#
|
9
|
+
# Tweets can be extracted from an entry using ({#items}) method, which returns an array of tweets as instances of
|
10
|
+
# {BadPigeon::TimelineTweet} class.
|
11
|
+
|
5
12
|
class TimelineEntry
|
6
13
|
include Assertions
|
7
14
|
|
@@ -2,6 +2,12 @@ require 'bad_pigeon/elements/timeline_entry'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents an "instruction" which is a part of a timeline response. An instruction can be e.g. pinning one entry
|
7
|
+
# to the top or adding some number of entries to the list view.
|
8
|
+
#
|
9
|
+
# A timeline includes one or more "entries" ({BadPigeon::TimelineEntry}), most of which contain one or more tweets.
|
10
|
+
|
5
11
|
class TimelineInstruction
|
6
12
|
include Assertions
|
7
13
|
|
@@ -2,6 +2,12 @@ require 'bad_pigeon/models/tweet'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents a single tweet in a timeline (may possibly include no data in some cases).
|
7
|
+
#
|
8
|
+
# Use the {#tweet} method to get an instance of {BadPigeon::Tweet}, which is the final tweet model from which you can
|
9
|
+
# extract specific fields or a properly formatted JSON representation.
|
10
|
+
|
5
11
|
class TimelineTweet
|
6
12
|
include Assertions
|
7
13
|
|
@@ -9,26 +15,8 @@ module BadPigeon
|
|
9
15
|
@json = json
|
10
16
|
end
|
11
17
|
|
12
|
-
def result_type
|
13
|
-
@json['tweet_results']['result'] && @json['tweet_results']['result']['__typename']
|
14
|
-
end
|
15
|
-
|
16
|
-
def tweet_data
|
17
|
-
case result_type
|
18
|
-
when 'Tweet', 'TweetWithVisibilityResults'
|
19
|
-
@json['tweet_results']['result']
|
20
|
-
when 'TweetUnavailable'
|
21
|
-
nil
|
22
|
-
when nil
|
23
|
-
nil
|
24
|
-
else
|
25
|
-
assert("Unknown tweet result type: #{result_type}")
|
26
|
-
nil
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
18
|
def tweet
|
31
|
-
|
19
|
+
@json['tweet_results']['result'] && Tweet.from_result(@json['tweet_results']['result'])
|
32
20
|
end
|
33
21
|
end
|
34
22
|
end
|
@@ -9,6 +9,8 @@ module BadPigeon
|
|
9
9
|
case entry.component
|
10
10
|
when Component::ORGANIC_FEED_TWEET,
|
11
11
|
Component::ORGANIC_LIST_TWEET,
|
12
|
+
Component::NORMAL_TWEET,
|
13
|
+
Component::FOLLOWING,
|
12
14
|
Component::PINNED_TWEET,
|
13
15
|
Component::EXTENDED_REPLY,
|
14
16
|
Component::SOCIAL_CONTEXT,
|
@@ -17,6 +19,7 @@ module BadPigeon
|
|
17
19
|
then true
|
18
20
|
|
19
21
|
when Component::PROMOTED_TWEET,
|
22
|
+
Component::FOLLOWING_PROMOTED,
|
20
23
|
Component::FOLLOW_SUGGESTIONS
|
21
24
|
then false
|
22
25
|
|
@@ -2,6 +2,11 @@ require_relative 'har_request'
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents a whole request archive bundle loaded from a *.har file.
|
7
|
+
#
|
8
|
+
# An archive consists of some number of requests ({BadPigeon::HARRequest}).
|
9
|
+
|
5
10
|
class HARArchive
|
6
11
|
def initialize(data)
|
7
12
|
@json = JSON.parse(data)
|
@@ -2,6 +2,15 @@ require 'addressable/uri'
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents info about one request and response to it, including the complete response data ({#response_body},
|
7
|
+
# or {#response_json} for a parsed JSON form).
|
8
|
+
#
|
9
|
+
# Requests that may potentially include tweet data return true from the {#includes_tweet_data?} method. The JSON
|
10
|
+
# data from each such request represents a "timeline" and may be parsed using a specific timeline class like
|
11
|
+
# {BadPigeon::HomeTimeline} or {BadPigeon::UserTimeline}; the {BadPigeon::TIMELINE_TYPES} hash provides a mapping
|
12
|
+
# of GraphQL endpoint names to timeline classes, and the endpoint name can be read using {#endpoint_name} method.
|
13
|
+
|
5
14
|
class HARRequest
|
6
15
|
def initialize(json)
|
7
16
|
@json = json
|
@@ -6,11 +6,29 @@ require 'bad_pigeon/util/strict_hash'
|
|
6
6
|
require 'time'
|
7
7
|
|
8
8
|
module BadPigeon
|
9
|
+
|
10
|
+
#
|
11
|
+
# A model that represents one tweet with an interface matching that from the original `twitter` Ruby gem.
|
12
|
+
#
|
13
|
+
|
9
14
|
class Tweet
|
10
15
|
include Assertions
|
16
|
+
extend Assertions
|
11
17
|
|
12
18
|
attr_reader :json
|
13
19
|
|
20
|
+
def self.from_result(json)
|
21
|
+
case json['__typename']
|
22
|
+
when 'Tweet', 'TweetWithVisibilityResults'
|
23
|
+
Tweet.new(json)
|
24
|
+
when nil, 'TweetUnavailable', 'TweetTombstone'
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
assert("Unknown tweet result type: #{json['__typename']}")
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
14
32
|
def initialize(json)
|
15
33
|
case json['__typename']
|
16
34
|
when 'Tweet'
|
@@ -50,17 +68,17 @@ module BadPigeon
|
|
50
68
|
alias retweeted_status? retweet?
|
51
69
|
|
52
70
|
def retweeted_status
|
53
|
-
legacy['retweeted_status_result'] && Tweet.
|
71
|
+
legacy['retweeted_status_result'] && Tweet.from_result(legacy['retweeted_status_result']['result'])
|
54
72
|
end
|
55
73
|
|
56
74
|
def quoted_status?
|
57
75
|
# there is also legacy['is_quote_status'], but it may be true while quoted_status_result
|
58
76
|
# is not set if the quoted status was deleted
|
59
|
-
!!
|
77
|
+
!!quoted_status
|
60
78
|
end
|
61
79
|
|
62
80
|
def quoted_status
|
63
|
-
json['quoted_status_result'] && Tweet.
|
81
|
+
json['quoted_status_result'] && Tweet.from_result(json['quoted_status_result']['result'])
|
64
82
|
end
|
65
83
|
|
66
84
|
alias quoted_tweet? quoted_status?
|
@@ -2,6 +2,12 @@ require 'bad_pigeon/elements/timeline_instruction'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents a timeline response for user's "For You" or "Following" timeline.
|
7
|
+
#
|
8
|
+
# A timeline includes one or more "instructions" ({BadPigeon::TimelineInstruction}), and usually in particular a
|
9
|
+
# "TimelineAddEntries" instruction which provides one or more entries containing tweets.
|
10
|
+
|
5
11
|
class HomeTimeline
|
6
12
|
include Assertions
|
7
13
|
|
@@ -2,6 +2,12 @@ require 'bad_pigeon/elements/timeline_instruction'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents a timeline response for a list timeline.
|
7
|
+
#
|
8
|
+
# A timeline includes one or more "instructions" ({BadPigeon::TimelineInstruction}), and usually in particular a
|
9
|
+
# "TimelineAddEntries" instruction which provides one or more entries containing tweets.
|
10
|
+
|
5
11
|
class ListTimeline
|
6
12
|
include Assertions
|
7
13
|
|
@@ -2,6 +2,12 @@ require 'bad_pigeon/elements/timeline_instruction'
|
|
2
2
|
require 'bad_pigeon/util/assertions'
|
3
3
|
|
4
4
|
module BadPigeon
|
5
|
+
|
6
|
+
# Represents a timeline response for a timeline of user's posts as seen on their profile page.
|
7
|
+
#
|
8
|
+
# A timeline includes one or more "instructions" ({BadPigeon::TimelineInstruction}), and usually in particular a
|
9
|
+
# "TimelineAddEntries" instruction which provides one or more entries containing tweets.
|
10
|
+
|
5
11
|
class UserTimeline
|
6
12
|
include Assertions
|
7
13
|
|
@@ -6,6 +6,10 @@ require_relative 'timelines'
|
|
6
6
|
require 'uri'
|
7
7
|
|
8
8
|
module BadPigeon
|
9
|
+
|
10
|
+
# The main entry point to the library. Pass the contents of a HAR archive file to {#get_tweets_from_har} and get
|
11
|
+
# a flat list of all extracted tweets in return.
|
12
|
+
|
9
13
|
class TweetExtractor
|
10
14
|
include Assertions
|
11
15
|
|
data/lib/bad_pigeon/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bad_pigeon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kuba Suder
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|