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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/lib/fetch_util/assets/extract.js +1 -1
  4. data/lib/fetch_util/browser/site_stabilization/communities/reddit.rb +71 -0
  5. data/lib/fetch_util/browser/site_stabilization/communities.rb +13 -0
  6. data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resource_modules.rb → forges/bitbucket/pulls/resource_modules.rb} +5 -5
  7. data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resources.rb → forges/bitbucket/pulls/resources.rb} +3 -34
  8. data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_threads.rb → forges/bitbucket/threads/index.rb} +3 -34
  9. data/lib/fetch_util/browser/site_stabilization/forges/gitea/stabilization.rb +31 -0
  10. data/lib/fetch_util/browser/site_stabilization/forges/observation_state.rb +59 -0
  11. data/lib/fetch_util/browser/site_stabilization/forges.rb +109 -0
  12. data/lib/fetch_util/browser/site_stabilization/marketplaces/ebay.rb +56 -0
  13. data/lib/fetch_util/browser/site_stabilization/marketplaces.rb +13 -0
  14. data/lib/fetch_util/browser/site_stabilization/{facebook_stabilization.rb → social/facebook.rb} +7 -0
  15. data/lib/fetch_util/browser/site_stabilization/{social_platforms.rb → social/instagram.rb} +6 -8
  16. data/lib/fetch_util/browser/site_stabilization/social.rb +15 -0
  17. data/lib/fetch_util/browser/site_stabilization/{travel_and_lodging.rb → travel/lodging.rb} +7 -9
  18. data/lib/fetch_util/browser/site_stabilization/travel.rb +13 -0
  19. data/lib/fetch_util/browser/site_stabilization.rb +10 -97
  20. data/lib/fetch_util/browser/stabilization/page_flow.rb +7 -5
  21. data/lib/fetch_util/browser.rb +3 -0
  22. data/lib/fetch_util/raw_docs_fallback.rb +5 -1
  23. data/lib/fetch_util/regulatory/cache_store.rb +5 -3
  24. data/lib/fetch_util/regulatory/cache_validation.rb +24 -0
  25. data/lib/fetch_util/regulatory/tdm_policy.rb +1 -1
  26. data/lib/fetch_util/regulatory.rb +1 -0
  27. data/lib/fetch_util/version.rb +1 -1
  28. metadata +56 -48
  29. data/lib/fetch_util/browser/site_stabilization/community_and_marketplace.rb +0 -117
  30. data/lib/fetch_util/browser/site_stabilization/gitea_family_stabilization.rb +0 -60
  31. /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
  32. /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
  33. /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
  34. /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
  35. /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_stabilization.rb → forges/azure_devops/pull_requests/stabilization.rb} +0 -0
  36. /data/lib/fetch_util/browser/site_stabilization/{azure_devops_pr_state.rb → forges/azure_devops/pull_requests/state.rb} +0 -0
  37. /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_product_state.rb → forges/bitbucket/pulls/diff/product_state.rb} +0 -0
  38. /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_request_state.rb → forges/bitbucket/pulls/diff/request_state.rb} +0 -0
  39. /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_diff_state.rb → forges/bitbucket/pulls/diff/state.rb} +0 -0
  40. /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_pull_resource_state.rb → forges/bitbucket/pulls/resource_state.rb} +0 -0
  41. /data/lib/fetch_util/browser/site_stabilization/{bitbucket_cloud_thread_state.rb → forges/bitbucket/threads/state.rb} +0 -0
  42. /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_product_state_script.rb → forges/gerrit/changes/product_state_script.rb} +0 -0
  43. /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_request_state_script.rb → forges/gerrit/changes/request_state_script.rb} +0 -0
  44. /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_stabilization.rb → forges/gerrit/changes/stabilization.rb} +0 -0
  45. /data/lib/fetch_util/browser/site_stabilization/{gerrit_change_state.rb → forges/gerrit/changes/state.rb} +0 -0
  46. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_fetch_state_script.rb → forges/gerrit/resources/fetch_state_script.rb} +0 -0
  47. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_product_state_script.rb → forges/gerrit/resources/product_state_script.rb} +0 -0
  48. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_request_state_script.rb → forges/gerrit/resources/request_state_script.rb} +0 -0
  49. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_route_state_script.rb → forges/gerrit/resources/route_state_script.rb} +0 -0
  50. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_stabilization.rb → forges/gerrit/resources/stabilization.rb} +0 -0
  51. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_state.rb → forges/gerrit/resources/state.rb} +0 -0
  52. /data/lib/fetch_util/browser/site_stabilization/{gerrit_file_resource_validation_state_script.rb → forges/gerrit/resources/validation_state_script.rb} +0 -0
  53. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resource_product_state.rb → forges/gitea/pulls/product_state.rb} +0 -0
  54. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resources.rb → forges/gitea/pulls/resources.rb} +0 -0
  55. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_pull_resource_state.rb → forges/gitea/pulls/state.rb} +0 -0
  56. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_threads.rb → forges/gitea/threads/index.rb} +0 -0
  57. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_thread_product_state.rb → forges/gitea/threads/product_state.rb} +0 -0
  58. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_thread_timeline_state.rb → forges/gitea/threads/timeline_state.rb} +0 -0
  59. /data/lib/fetch_util/browser/site_stabilization/{gitea_family_visibility_script.rb → forges/gitea/visibility_script.rb} +0 -0
  60. /data/lib/fetch_util/browser/site_stabilization/{github_pull_resource_stabilization.rb → forges/github/pull_resource_stabilization.rb} +0 -0
  61. /data/lib/fetch_util/browser/site_stabilization/{github_pull_resources.rb → forges/github/pull_resources.rb} +0 -0
  62. /data/lib/fetch_util/browser/site_stabilization/{github_threads.rb → forges/github/threads.rb} +0 -0
  63. /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_state.rb → forges/gitlab/merge_requests/resource_state.rb} +0 -0
  64. /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_state_script.rb → forges/gitlab/merge_requests/resource_state_script.rb} +0 -0
  65. /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resource_visibility_script.rb → forges/gitlab/merge_requests/resource_visibility_script.rb} +0 -0
  66. /data/lib/fetch_util/browser/site_stabilization/{gitlab_merge_request_resources.rb → forges/gitlab/merge_requests/resources.rb} +0 -0
  67. /data/lib/fetch_util/browser/site_stabilization/{gitlab_repo.rb → forges/gitlab/repository.rb} +0 -0
  68. /data/lib/fetch_util/browser/site_stabilization/{gitlab_stabilization.rb → forges/gitlab/stabilization.rb} +0 -0
  69. /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/bitbucket_cloud_pull_diff_product_state"
7
+ "fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/product_state"
8
8
  autoload :BitbucketCloudPullDiffRequestState,
9
- "fetch_util/browser/site_stabilization/bitbucket_cloud_pull_diff_request_state"
9
+ "fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/request_state"
10
10
  autoload :BitbucketCloudPullDiffState,
11
- "fetch_util/browser/site_stabilization/bitbucket_cloud_pull_diff_state"
11
+ "fetch_util/browser/site_stabilization/forges/bitbucket/pulls/diff/state"
12
12
  autoload :BitbucketCloudPullResourceState,
13
- "fetch_util/browser/site_stabilization/bitbucket_cloud_pull_resource_state"
13
+ "fetch_util/browser/site_stabilization/forges/bitbucket/pulls/resource_state"
14
14
  autoload :BitbucketCloudPullResources,
15
- "fetch_util/browser/site_stabilization/bitbucket_cloud_pull_resources"
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
- last_signature = nil
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
- unless state["ready"]
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
- last_signature = nil
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
- unless state["ready"]
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
@@ -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 SocialPlatforms
7
- SOCIAL_PLATFORM_STABILIZATION_PROFILES = {
8
- stabilize_instagram: { host: "instagram.com", strategy: :stabilize_instagram,
9
- notes: "Accept Instagram cookie prompts and dismiss login modals before extraction.",
10
- tests: "spec/fetch_util/browser_stabilization_spec.rb" },
11
- stabilize_facebook: { host: "facebook.com", strategy: :stabilize_facebook,
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 TravelAndLodging
7
- TRAVEL_LODGING_STABILIZATION_PROFILES = {
8
- stabilize_lodging_detail: {
9
- host: %w[airbnb.com booking.com],
10
- path_query: ->(uri) { uri.path.match?(%r{/(?:rooms|hotel)/}) },
11
- strategy: :stabilize_lodging_detail,
12
- notes: "Wait for client-rendered lodging detail cues without bypassing access controls.",
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