fetch_util 0.7.0 → 0.8.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 +4 -4
- data/CHANGELOG.md +27 -0
- data/lib/fetch_util/assets/extract.js +1 -1
- data/lib/fetch_util/browser/site_stabilization/communities/reddit.rb +71 -0
- data/lib/fetch_util/browser/site_stabilization/communities.rb +13 -0
- data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resource_modules.rb → forges/bitbucket/pulls/resource_modules.rb} +5 -5
- data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resources.rb → forges/bitbucket/pulls/resources.rb} +3 -34
- data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_threads.rb → forges/bitbucket/threads/index.rb} +3 -34
- data/lib/fetch_util/browser/site_stabilization/forges/gitea/stabilization.rb +31 -0
- data/lib/fetch_util/browser/site_stabilization/forges/observation_state.rb +59 -0
- data/lib/fetch_util/browser/site_stabilization/forges.rb +109 -0
- data/lib/fetch_util/browser/site_stabilization/marketplaces/ebay.rb +56 -0
- data/lib/fetch_util/browser/site_stabilization/marketplaces.rb +13 -0
- data/lib/fetch_util/browser/site_stabilization/{facebook_stabilization.rb → social/facebook.rb} +7 -0
- data/lib/fetch_util/browser/site_stabilization/{social_platforms.rb → social/instagram.rb} +6 -8
- data/lib/fetch_util/browser/site_stabilization/social.rb +15 -0
- data/lib/fetch_util/browser/site_stabilization/{travel_and_lodging.rb → travel/lodging.rb} +7 -9
- data/lib/fetch_util/browser/site_stabilization/travel.rb +13 -0
- data/lib/fetch_util/browser/site_stabilization.rb +10 -97
- data/lib/fetch_util/browser/stabilization/page_flow.rb +7 -5
- data/lib/fetch_util/browser.rb +3 -0
- data/lib/fetch_util/raw_docs_fallback.rb +5 -1
- data/lib/fetch_util/regulatory/cache_store.rb +5 -3
- data/lib/fetch_util/regulatory/cache_validation.rb +24 -0
- data/lib/fetch_util/regulatory/tdm_policy.rb +1 -1
- data/lib/fetch_util/regulatory.rb +1 -0
- data/lib/fetch_util/version.rb +1 -1
- metadata +56 -48
- data/lib/fetch_util/browser/site_stabilization/community_and_marketplace.rb +0 -117
- data/lib/fetch_util/browser/site_stabilization/gitea_family_stabilization.rb +0 -60
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_commit_details_script.rb → forges/azure_devops/pull_requests/commit_details_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_product_state_script.rb → forges/azure_devops/pull_requests/product_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_request_helpers_script.rb → forges/azure_devops/pull_requests/request_helpers_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_request_state_script.rb → forges/azure_devops/pull_requests/request_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_stabilization.rb → forges/azure_devops/pull_requests/stabilization.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_state.rb → forges/azure_devops/pull_requests/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_product_state.rb → forges/bitbucket/pulls/diff/product_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_request_state.rb → forges/bitbucket/pulls/diff/request_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_state.rb → forges/bitbucket/pulls/diff/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resource_state.rb → forges/bitbucket/pulls/resource_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_thread_state.rb → forges/bitbucket/threads/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_product_state_script.rb → forges/gerrit/changes/product_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_request_state_script.rb → forges/gerrit/changes/request_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_stabilization.rb → forges/gerrit/changes/stabilization.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_state.rb → forges/gerrit/changes/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_fetch_state_script.rb → forges/gerrit/resources/fetch_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_product_state_script.rb → forges/gerrit/resources/product_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_request_state_script.rb → forges/gerrit/resources/request_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_route_state_script.rb → forges/gerrit/resources/route_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_stabilization.rb → forges/gerrit/resources/stabilization.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_state.rb → forges/gerrit/resources/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_validation_state_script.rb → forges/gerrit/resources/validation_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resource_product_state.rb → forges/gitea/pulls/product_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resources.rb → forges/gitea/pulls/resources.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resource_state.rb → forges/gitea/pulls/state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_threads.rb → forges/gitea/threads/index.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_thread_product_state.rb → forges/gitea/threads/product_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_thread_timeline_state.rb → forges/gitea/threads/timeline_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitea_family_visibility_script.rb → forges/gitea/visibility_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{github_pull_resource_stabilization.rb → forges/github/pull_resource_stabilization.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{github_pull_resources.rb → forges/github/pull_resources.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{github_threads.rb → forges/github/threads.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_state.rb → forges/gitlab/merge_requests/resource_state.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_state_script.rb → forges/gitlab/merge_requests/resource_state_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_visibility_script.rb → forges/gitlab/merge_requests/resource_visibility_script.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resources.rb → forges/gitlab/merge_requests/resources.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_repo.rb → forges/gitlab/repository.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_stabilization.rb → forges/gitlab/stabilization.rb} +0 -0
- /data/lib/fetch_util/browser/site_stabilization/{gitlab_threads.rb → forges/gitlab/threads.rb} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
module RedditStabilization
|
|
7
|
+
REDDIT_STABILIZATION_PROFILE = {
|
|
8
|
+
host: "reddit.com",
|
|
9
|
+
strategy: :stabilize_reddit,
|
|
10
|
+
notes: "Use fast Reddit cookie dismissal/content readiness instead of full idle waits.",
|
|
11
|
+
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def stabilize_reddit(page, deadline: stabilization_deadline)
|
|
17
|
+
ready = retry_until_timeout(capped_timeout(3.0, deadline: deadline), interval: 0.1, deadline: deadline) do
|
|
18
|
+
dismiss_reddit_cookie_dialog(page)
|
|
19
|
+
reddit_content_ready?(page)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
settle_after_stabilization(0.25, deadline: deadline)
|
|
23
|
+
dismiss_reddit_cookie_dialog(page) if stabilization_time_remaining?(deadline)
|
|
24
|
+
ready
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def reddit_content_ready?(page)
|
|
28
|
+
safe_evaluate(page, <<~JS, default: false)
|
|
29
|
+
!!document.querySelector('shreddit-post, faceplate-screen-reader-content, shreddit-comment, [data-testid="comment"]')
|
|
30
|
+
JS
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def dismiss_reddit_cookie_dialog(page)
|
|
34
|
+
removed = dismiss_overlay_dialog(
|
|
35
|
+
page,
|
|
36
|
+
close_selectors: [],
|
|
37
|
+
dialog_selectors: [
|
|
38
|
+
'[data-testid="onboarding-modal"]',
|
|
39
|
+
'[data-testid="gdpr-modal"]',
|
|
40
|
+
'[aria-modal="true"]',
|
|
41
|
+
'[role="dialog"]',
|
|
42
|
+
"shreddit-experience-tree"
|
|
43
|
+
],
|
|
44
|
+
dialog_pattern: "before you continue to reddit|let us know your cookie preferences"
|
|
45
|
+
)
|
|
46
|
+
return true if removed
|
|
47
|
+
|
|
48
|
+
safe_evaluate(page, <<~JS)
|
|
49
|
+
(() => {
|
|
50
|
+
#{js_dom_helpers}
|
|
51
|
+
let removed = false;
|
|
52
|
+
document.querySelectorAll('section, div, aside, form, footer, shreddit-experience-tree').forEach((node) => {
|
|
53
|
+
const text = (node.innerText || node.textContent || '').replace(/\s+/g, ' ').trim();
|
|
54
|
+
if (/before you continue to reddit|let us know your cookie preferences/i.test(text) && text.length < 2000) {
|
|
55
|
+
node.remove();
|
|
56
|
+
removed = true;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (removed) {
|
|
61
|
+
restoreScroll();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return removed;
|
|
65
|
+
})()
|
|
66
|
+
JS
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
autoload :RedditStabilization, "fetch_util/browser/site_stabilization/communities/reddit"
|
|
7
|
+
|
|
8
|
+
module CommunityStabilization
|
|
9
|
+
include RedditStabilization
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -4,15 +4,15 @@ module FetchUtil
|
|
|
4
4
|
class Browser
|
|
5
5
|
module SiteStabilization
|
|
6
6
|
autoload :BitbucketCloudPullDiffProductState,
|
|
7
|
-
"fetch_util/browser/site_stabilization/
|
|
7
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/product_state"
|
|
8
8
|
autoload :BitbucketCloudPullDiffRequestState,
|
|
9
|
-
"fetch_util/browser/site_stabilization/
|
|
9
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/request_state"
|
|
10
10
|
autoload :BitbucketCloudPullDiffState,
|
|
11
|
-
"fetch_util/browser/site_stabilization/
|
|
11
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/state"
|
|
12
12
|
autoload :BitbucketCloudPullResourceState,
|
|
13
|
-
"fetch_util/browser/site_stabilization/
|
|
13
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/resource_state"
|
|
14
14
|
autoload :BitbucketCloudPullResources,
|
|
15
|
-
"fetch_util/browser/site_stabilization/
|
|
15
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/resources"
|
|
16
16
|
|
|
17
17
|
module BitbucketCloudPullResourceModules
|
|
18
18
|
include BitbucketCloudPullDiffProductState
|
|
@@ -16,11 +16,7 @@ module FetchUtil
|
|
|
16
16
|
private
|
|
17
17
|
|
|
18
18
|
def stabilize_bitbucket_cloud_pull_resource(page, deadline: stabilization_deadline)
|
|
19
|
-
|
|
20
|
-
stable_observations = 0
|
|
21
|
-
incomplete_signature = nil
|
|
22
|
-
incomplete_observations = 0
|
|
23
|
-
terminal_incomplete = false
|
|
19
|
+
observation = ForgeObservationState.new(reset_stability_when_incomplete: true)
|
|
24
20
|
observed = retry_until_timeout(
|
|
25
21
|
capped_timeout(6.0, deadline: deadline),
|
|
26
22
|
interval: 0.1,
|
|
@@ -30,37 +26,10 @@ module FetchUtil
|
|
|
30
26
|
return false if state.is_a?(Hash) && state["product"] == false
|
|
31
27
|
next false unless state.is_a?(Hash) && state["product"]
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
last_signature = nil
|
|
35
|
-
stable_observations = 0
|
|
36
|
-
if state["loading"]
|
|
37
|
-
incomplete_signature = nil
|
|
38
|
-
incomplete_observations = 0
|
|
39
|
-
elsif state["signature"] == incomplete_signature
|
|
40
|
-
incomplete_observations += 1
|
|
41
|
-
else
|
|
42
|
-
incomplete_signature = state["signature"]
|
|
43
|
-
incomplete_observations = 1
|
|
44
|
-
end
|
|
45
|
-
if incomplete_observations >= 10
|
|
46
|
-
terminal_incomplete = true
|
|
47
|
-
next true
|
|
48
|
-
end
|
|
49
|
-
next false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
incomplete_signature = nil
|
|
53
|
-
incomplete_observations = 0
|
|
54
|
-
if state["signature"] == last_signature
|
|
55
|
-
stable_observations += 1
|
|
56
|
-
else
|
|
57
|
-
last_signature = state["signature"]
|
|
58
|
-
stable_observations = 1
|
|
59
|
-
end
|
|
60
|
-
stable_observations >= 3
|
|
29
|
+
observation.observe(state)
|
|
61
30
|
end
|
|
62
31
|
|
|
63
|
-
return false if terminal_incomplete
|
|
32
|
+
return false if observation.terminal_incomplete?
|
|
64
33
|
|
|
65
34
|
fail_bitbucket_cloud_pull_diff_preparation(page) unless observed
|
|
66
35
|
|
|
@@ -16,11 +16,7 @@ module FetchUtil
|
|
|
16
16
|
private
|
|
17
17
|
|
|
18
18
|
def stabilize_bitbucket_cloud_thread(page, deadline: stabilization_deadline)
|
|
19
|
-
|
|
20
|
-
stable_observations = 0
|
|
21
|
-
incomplete_signature = nil
|
|
22
|
-
incomplete_observations = 0
|
|
23
|
-
terminal_incomplete = false
|
|
19
|
+
observation = ForgeObservationState.new(reset_stability_when_incomplete: true)
|
|
24
20
|
observed = retry_until_timeout(
|
|
25
21
|
capped_timeout(6.0, deadline: deadline),
|
|
26
22
|
interval: 0.1,
|
|
@@ -30,37 +26,10 @@ module FetchUtil
|
|
|
30
26
|
return false if state.is_a?(Hash) && state["product"] == false
|
|
31
27
|
next false unless state.is_a?(Hash) && state["product"]
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
last_signature = nil
|
|
35
|
-
stable_observations = 0
|
|
36
|
-
if state["loading"]
|
|
37
|
-
incomplete_signature = nil
|
|
38
|
-
incomplete_observations = 0
|
|
39
|
-
elsif state["signature"] == incomplete_signature
|
|
40
|
-
incomplete_observations += 1
|
|
41
|
-
else
|
|
42
|
-
incomplete_signature = state["signature"]
|
|
43
|
-
incomplete_observations = 1
|
|
44
|
-
end
|
|
45
|
-
if incomplete_observations >= 10
|
|
46
|
-
terminal_incomplete = true
|
|
47
|
-
next true
|
|
48
|
-
end
|
|
49
|
-
next false
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
incomplete_signature = nil
|
|
53
|
-
incomplete_observations = 0
|
|
54
|
-
if state["signature"] == last_signature
|
|
55
|
-
stable_observations += 1
|
|
56
|
-
else
|
|
57
|
-
last_signature = state["signature"]
|
|
58
|
-
stable_observations = 1
|
|
59
|
-
end
|
|
60
|
-
stable_observations >= 3
|
|
29
|
+
observation.observe(state)
|
|
61
30
|
end
|
|
62
31
|
|
|
63
|
-
return false if terminal_incomplete
|
|
32
|
+
return false if observation.terminal_incomplete?
|
|
64
33
|
|
|
65
34
|
settle_after_stabilization(0.5, deadline: deadline) if observed
|
|
66
35
|
!!observed
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
module GiteaFamilyStabilization
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def stabilize_gitea_family_state(page, state_script, deadline: stabilization_deadline)
|
|
10
|
+
observation = ForgeObservationState.new(reset_stability_when_incomplete: false)
|
|
11
|
+
observed = retry_until_timeout(
|
|
12
|
+
capped_timeout(6.0, deadline: deadline),
|
|
13
|
+
interval: 0.1,
|
|
14
|
+
deadline: deadline
|
|
15
|
+
) do
|
|
16
|
+
state = safe_evaluate(page, state_script, default: nil)
|
|
17
|
+
return false if state.is_a?(Hash) && state["product"] == false
|
|
18
|
+
next false unless state.is_a?(Hash) && state["product"]
|
|
19
|
+
|
|
20
|
+
observation.observe(state)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
return false if observation.terminal_incomplete?
|
|
24
|
+
|
|
25
|
+
settle_after_stabilization(0.5, deadline: deadline) if observed
|
|
26
|
+
!!observed
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
class ForgeObservationState
|
|
7
|
+
REQUIRED_STABLE_OBSERVATIONS = 3
|
|
8
|
+
REQUIRED_INCOMPLETE_OBSERVATIONS = 10
|
|
9
|
+
|
|
10
|
+
attr_reader :terminal_incomplete
|
|
11
|
+
alias terminal_incomplete? terminal_incomplete
|
|
12
|
+
|
|
13
|
+
def initialize(reset_stability_when_incomplete:)
|
|
14
|
+
@reset_stability_when_incomplete = reset_stability_when_incomplete
|
|
15
|
+
@last_signature = nil
|
|
16
|
+
@stable_observations = 0
|
|
17
|
+
@incomplete_signature = nil
|
|
18
|
+
@incomplete_observations = 0
|
|
19
|
+
@terminal_incomplete = false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def observe(state)
|
|
23
|
+
return observe_incomplete(state) unless state["ready"]
|
|
24
|
+
|
|
25
|
+
@incomplete_signature = nil
|
|
26
|
+
@incomplete_observations = 0
|
|
27
|
+
if state["signature"] == @last_signature
|
|
28
|
+
@stable_observations += 1
|
|
29
|
+
else
|
|
30
|
+
@last_signature = state["signature"]
|
|
31
|
+
@stable_observations = 1
|
|
32
|
+
end
|
|
33
|
+
@stable_observations >= REQUIRED_STABLE_OBSERVATIONS
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def observe_incomplete(state)
|
|
39
|
+
reset_stability if @reset_stability_when_incomplete
|
|
40
|
+
if state["loading"]
|
|
41
|
+
@incomplete_signature = nil
|
|
42
|
+
@incomplete_observations = 0
|
|
43
|
+
elsif state["signature"] == @incomplete_signature
|
|
44
|
+
@incomplete_observations += 1
|
|
45
|
+
else
|
|
46
|
+
@incomplete_signature = state["signature"]
|
|
47
|
+
@incomplete_observations = 1
|
|
48
|
+
end
|
|
49
|
+
@terminal_incomplete = @incomplete_observations >= REQUIRED_INCOMPLETE_OBSERVATIONS
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def reset_stability
|
|
53
|
+
@last_signature = nil
|
|
54
|
+
@stable_observations = 0
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
autoload :AzureDevopsPrProductStateScript,
|
|
7
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/product_state_script"
|
|
8
|
+
autoload :AzureDevopsPrCommitDetailsScript,
|
|
9
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/commit_details_script"
|
|
10
|
+
autoload :AzureDevopsPrRequestHelpersScript,
|
|
11
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/request_helpers_script"
|
|
12
|
+
autoload :AzureDevopsPrRequestStateScript,
|
|
13
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/request_state_script"
|
|
14
|
+
autoload :AzureDevopsPrState,
|
|
15
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/state"
|
|
16
|
+
autoload :AzureDevopsPrStabilization,
|
|
17
|
+
"fetch_util/browser/site_stabilization/forges/azure_devops/pull_requests/stabilization"
|
|
18
|
+
autoload :BitbucketCloudThreadState,
|
|
19
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/threads/state"
|
|
20
|
+
autoload :BitbucketCloudThreads,
|
|
21
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/threads/index"
|
|
22
|
+
autoload :BitbucketCloudPullResourceModules,
|
|
23
|
+
"fetch_util/browser/site_stabilization/forges/bitbucket/pulls/resource_modules"
|
|
24
|
+
autoload :GerritChangeProductStateScript,
|
|
25
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/changes/product_state_script"
|
|
26
|
+
autoload :GerritChangeRequestStateScript,
|
|
27
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/changes/request_state_script"
|
|
28
|
+
autoload :GerritChangeState,
|
|
29
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/changes/state"
|
|
30
|
+
autoload :GerritChangeStabilization,
|
|
31
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/changes/stabilization"
|
|
32
|
+
autoload :GerritFileResourceProductStateScript,
|
|
33
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/product_state_script"
|
|
34
|
+
autoload :GerritFileResourceRouteStateScript,
|
|
35
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/route_state_script"
|
|
36
|
+
autoload :GerritFileResourceFetchStateScript,
|
|
37
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/fetch_state_script"
|
|
38
|
+
autoload :GerritFileResourceValidationStateScript,
|
|
39
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/validation_state_script"
|
|
40
|
+
autoload :GerritFileResourceRequestStateScript,
|
|
41
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/request_state_script"
|
|
42
|
+
autoload :GerritFileResourceState,
|
|
43
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/state"
|
|
44
|
+
autoload :GerritFileResourceStabilization,
|
|
45
|
+
"fetch_util/browser/site_stabilization/forges/gerrit/resources/stabilization"
|
|
46
|
+
autoload :GithubPullResources,
|
|
47
|
+
"fetch_util/browser/site_stabilization/forges/github/pull_resources"
|
|
48
|
+
autoload :GithubPullResourceStabilization,
|
|
49
|
+
"fetch_util/browser/site_stabilization/forges/github/pull_resource_stabilization"
|
|
50
|
+
autoload :GithubThreads, "fetch_util/browser/site_stabilization/forges/github/threads"
|
|
51
|
+
autoload :ForgeObservationState, "fetch_util/browser/site_stabilization/forges/observation_state"
|
|
52
|
+
autoload :GiteaFamilyThreadProductState,
|
|
53
|
+
"fetch_util/browser/site_stabilization/forges/gitea/threads/product_state"
|
|
54
|
+
autoload :GiteaFamilyThreadTimelineState,
|
|
55
|
+
"fetch_util/browser/site_stabilization/forges/gitea/threads/timeline_state"
|
|
56
|
+
autoload :GiteaFamilyStabilization,
|
|
57
|
+
"fetch_util/browser/site_stabilization/forges/gitea/stabilization"
|
|
58
|
+
autoload :GiteaFamilyVisibilityScript,
|
|
59
|
+
"fetch_util/browser/site_stabilization/forges/gitea/visibility_script"
|
|
60
|
+
autoload :GiteaFamilyThreads,
|
|
61
|
+
"fetch_util/browser/site_stabilization/forges/gitea/threads/index"
|
|
62
|
+
autoload :GiteaFamilyPullResourceProductState,
|
|
63
|
+
"fetch_util/browser/site_stabilization/forges/gitea/pulls/product_state"
|
|
64
|
+
autoload :GiteaFamilyPullResourceState,
|
|
65
|
+
"fetch_util/browser/site_stabilization/forges/gitea/pulls/state"
|
|
66
|
+
autoload :GiteaFamilyPullResources,
|
|
67
|
+
"fetch_util/browser/site_stabilization/forges/gitea/pulls/resources"
|
|
68
|
+
autoload :GitlabRepo, "fetch_util/browser/site_stabilization/forges/gitlab/repository"
|
|
69
|
+
autoload :GitlabMergeRequestResourceVisibilityScript,
|
|
70
|
+
"fetch_util/browser/site_stabilization/forges/gitlab/merge_requests/resource_visibility_script"
|
|
71
|
+
autoload :GitlabMergeRequestResourceStateScript,
|
|
72
|
+
"fetch_util/browser/site_stabilization/forges/gitlab/merge_requests/resource_state_script"
|
|
73
|
+
autoload :GitlabMergeRequestResourceState,
|
|
74
|
+
"fetch_util/browser/site_stabilization/forges/gitlab/merge_requests/resource_state"
|
|
75
|
+
autoload :GitlabMergeRequestResources,
|
|
76
|
+
"fetch_util/browser/site_stabilization/forges/gitlab/merge_requests/resources"
|
|
77
|
+
autoload :GitlabStabilization,
|
|
78
|
+
"fetch_util/browser/site_stabilization/forges/gitlab/stabilization"
|
|
79
|
+
autoload :GitlabThreads, "fetch_util/browser/site_stabilization/forges/gitlab/threads"
|
|
80
|
+
|
|
81
|
+
module ForgeStabilization
|
|
82
|
+
include AzureDevopsPrState
|
|
83
|
+
include AzureDevopsPrStabilization
|
|
84
|
+
include BitbucketCloudThreadState
|
|
85
|
+
include BitbucketCloudThreads
|
|
86
|
+
include BitbucketCloudPullResourceModules
|
|
87
|
+
include GerritChangeState
|
|
88
|
+
include GerritChangeStabilization
|
|
89
|
+
include GerritFileResourceState
|
|
90
|
+
include GerritFileResourceStabilization
|
|
91
|
+
include GithubPullResources
|
|
92
|
+
include GithubPullResourceStabilization
|
|
93
|
+
include GithubThreads
|
|
94
|
+
include GiteaFamilyVisibilityScript
|
|
95
|
+
include GiteaFamilyThreadProductState
|
|
96
|
+
include GiteaFamilyThreadTimelineState
|
|
97
|
+
include GiteaFamilyStabilization
|
|
98
|
+
include GiteaFamilyThreads
|
|
99
|
+
include GiteaFamilyPullResourceProductState
|
|
100
|
+
include GiteaFamilyPullResourceState
|
|
101
|
+
include GiteaFamilyPullResources
|
|
102
|
+
include GitlabRepo
|
|
103
|
+
include GitlabStabilization
|
|
104
|
+
include GitlabMergeRequestResources
|
|
105
|
+
include GitlabThreads
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
module EbayStabilization
|
|
7
|
+
EBAY_STABILIZATION_PROFILE = {
|
|
8
|
+
host: "ebay.com",
|
|
9
|
+
path_query: ->(uri) { uri.path.include?("/sch/") || uri.query.to_s.include?("_nkw=") },
|
|
10
|
+
strategy: :stabilize_ebay_search,
|
|
11
|
+
notes: "Wait for search result items or short-lived eBay browser checks.",
|
|
12
|
+
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def stabilize_ebay_search(page, deadline: stabilization_deadline)
|
|
18
|
+
accepted_cookies = false
|
|
19
|
+
cookie_config = consent_config(
|
|
20
|
+
accept_labels: [
|
|
21
|
+
"accept all",
|
|
22
|
+
"accept all cookies",
|
|
23
|
+
"accept cookies",
|
|
24
|
+
"allow all",
|
|
25
|
+
"allow cookies",
|
|
26
|
+
"agree to cookies",
|
|
27
|
+
"continue with cookies"
|
|
28
|
+
]
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
retry_until_timeout(capped_timeout(6.0, deadline: deadline), interval: 0.15, deadline: deadline) do
|
|
32
|
+
accepted_cookies ||= click_visible_button_by_text(
|
|
33
|
+
page,
|
|
34
|
+
consent_accept_labels(cookie_config),
|
|
35
|
+
selectors: consent_button_selectors(cookie_config)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
state = safe_evaluate(page, <<~JS, default: { "itemCount" => 0, "challengeVisible" => false })
|
|
39
|
+
(() => {
|
|
40
|
+
const bodyText = document.body ? document.body.innerText : '';
|
|
41
|
+
return {
|
|
42
|
+
itemCount: document.querySelectorAll('li.s-item a[href*="/itm/"], ul.srp-results a[href*="/itm/"]').length,
|
|
43
|
+
challengeVisible: /checking your browser before you access ebay|your browser will redirect to your requested content shortly|pardon our interruption/i.test(bodyText)
|
|
44
|
+
};
|
|
45
|
+
})()
|
|
46
|
+
JS
|
|
47
|
+
|
|
48
|
+
state["itemCount"].to_i >= 4 || (state["challengeVisible"] ? 0.35 : false)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
settle_after_stabilization(0.25, deadline: deadline) if accepted_cookies
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
autoload :EbayStabilization, "fetch_util/browser/site_stabilization/marketplaces/ebay"
|
|
7
|
+
|
|
8
|
+
module MarketplaceStabilization
|
|
9
|
+
include EbayStabilization
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/fetch_util/browser/site_stabilization/{facebook_stabilization.rb → social/facebook.rb}
RENAMED
|
@@ -4,6 +4,13 @@ module FetchUtil
|
|
|
4
4
|
class Browser
|
|
5
5
|
module SiteStabilization
|
|
6
6
|
module FacebookStabilization
|
|
7
|
+
FACEBOOK_STABILIZATION_PROFILE = {
|
|
8
|
+
host: "facebook.com",
|
|
9
|
+
strategy: :stabilize_facebook,
|
|
10
|
+
notes: "Decline/accept Facebook cookie dialogs, then dismiss login prompts.",
|
|
11
|
+
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
7
14
|
private
|
|
8
15
|
|
|
9
16
|
def stabilize_facebook(page, deadline: stabilization_deadline)
|
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
module FetchUtil
|
|
4
4
|
class Browser
|
|
5
5
|
module SiteStabilization
|
|
6
|
-
module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
notes: "Decline/accept Facebook cookie dialogs, then dismiss login prompts.",
|
|
13
|
-
tests: "spec/fetch_util/browser_stabilization_spec.rb" }
|
|
6
|
+
module InstagramStabilization
|
|
7
|
+
INSTAGRAM_STABILIZATION_PROFILE = {
|
|
8
|
+
host: "instagram.com",
|
|
9
|
+
strategy: :stabilize_instagram,
|
|
10
|
+
notes: "Accept Instagram cookie prompts and dismiss login modals before extraction.",
|
|
11
|
+
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
14
12
|
}.freeze
|
|
15
13
|
|
|
16
14
|
private
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
autoload :FacebookStabilization, "fetch_util/browser/site_stabilization/social/facebook"
|
|
7
|
+
autoload :InstagramStabilization, "fetch_util/browser/site_stabilization/social/instagram"
|
|
8
|
+
|
|
9
|
+
module SocialStabilization
|
|
10
|
+
include FacebookStabilization
|
|
11
|
+
include InstagramStabilization
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -3,15 +3,13 @@
|
|
|
3
3
|
module FetchUtil
|
|
4
4
|
class Browser
|
|
5
5
|
module SiteStabilization
|
|
6
|
-
module
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
14
|
-
}
|
|
6
|
+
module LodgingStabilization
|
|
7
|
+
LODGING_STABILIZATION_PROFILE = {
|
|
8
|
+
host: %w[airbnb.com booking.com],
|
|
9
|
+
path_query: ->(uri) { uri.path.match?(%r{/(?:rooms|hotel)/}) },
|
|
10
|
+
strategy: :stabilize_lodging_detail,
|
|
11
|
+
notes: "Wait for client-rendered lodging detail cues without bypassing access controls.",
|
|
12
|
+
tests: "spec/fetch_util/browser_stabilization_spec.rb"
|
|
15
13
|
}.freeze
|
|
16
14
|
|
|
17
15
|
private
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FetchUtil
|
|
4
|
+
class Browser
|
|
5
|
+
module SiteStabilization
|
|
6
|
+
autoload :LodgingStabilization, "fetch_util/browser/site_stabilization/travel/lodging"
|
|
7
|
+
|
|
8
|
+
module TravelStabilization
|
|
9
|
+
include LodgingStabilization
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|