portage-cli 0.11.0 → 0.13.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 +98 -1
- data/README.md +88 -18
- data/lib/portage/cli/adapter_session.rb +34 -0
- data/lib/portage/cli/browser_import/importer.rb +1 -1
- data/lib/portage/cli/browser_import/plist_xml.rb +5 -12
- data/lib/portage/cli/browser_import/sqlite.rb +19 -25
- data/lib/portage/cli/browser_profile/cdp.rb +0 -9
- data/lib/portage/cli/buy.rb +217 -39
- data/lib/portage/cli/compare.rb +4 -3
- data/lib/portage/cli/confidence_check.rb +27 -7
- data/lib/portage/cli/confidence_state.rb +109 -0
- data/lib/portage/cli/find.rb +66 -9
- data/lib/portage/cli/generate/agent_profile.rb +1 -1
- data/lib/portage/cli/handoff_agents.rb +7 -21
- data/lib/portage/cli/handoff_reconciler.rb +2 -22
- data/lib/portage/cli/homepage_fetch.rb +5 -3
- data/lib/portage/cli/index/builder.rb +2 -11
- data/lib/portage/cli/index/known_cache.rb +9 -2
- data/lib/portage/cli/index/sources/stores_file.rb +2 -11
- data/lib/portage/cli/index/sources/wikidata.rb +2 -11
- data/lib/portage/cli/install_doctor.rb +2 -1
- data/lib/portage/cli/notifier.rb +16 -12
- data/lib/portage/cli/offer_sources.rb +3 -14
- data/lib/portage/cli/payment_methods.rb +7 -30
- data/lib/portage/cli/reconcile_notifier.rb +2 -5
- data/lib/portage/cli/setup_wizard/steps/env_keys_step.rb +40 -0
- data/lib/portage/cli/setup_wizard/steps/retailer_keys.rb +11 -23
- data/lib/portage/cli/setup_wizard/steps/search_keys.rb +10 -22
- data/lib/portage/cli/setup_wizard/steps/shipping.rb +5 -19
- data/lib/portage/cli/version.rb +1 -1
- data/lib/portage/cli.rb +25 -173
- metadata +5 -3
- data/lib/portage/cli/known_stores_url.rb +0 -15
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative "
|
|
1
|
+
require_relative "env_keys_step"
|
|
2
2
|
|
|
3
3
|
module Portage
|
|
4
4
|
module Cli
|
|
@@ -12,7 +12,7 @@ module Portage
|
|
|
12
12
|
# setting a key here only makes `find` show more real offers, it
|
|
13
13
|
# never lets `portage buy` complete a purchase at any of these
|
|
14
14
|
# retailers.
|
|
15
|
-
class RetailerKeys
|
|
15
|
+
class RetailerKeys < EnvKeysStep
|
|
16
16
|
FIELDS = {
|
|
17
17
|
"WALMART_AFFILIATE_API_KEY" => "Walmart Affiliate API key",
|
|
18
18
|
"EBAY_BROWSE_ACCESS_TOKEN" => "eBay Browse API access token (Buy It Now search only)",
|
|
@@ -21,33 +21,21 @@ module Portage
|
|
|
21
21
|
"AMAZON_CREATORS_ACCESS_TOKEN" => "Amazon Creators API access token"
|
|
22
22
|
}.freeze
|
|
23
23
|
|
|
24
|
-
def initialize(prompt:) = @prompt = prompt
|
|
25
|
-
|
|
26
24
|
def title = "Retailer offer sources"
|
|
27
25
|
def default_yes? = false
|
|
28
26
|
|
|
29
|
-
def call
|
|
30
|
-
@prompt.say("Optional: official buyer-side APIs for Walmart, eBay (Buy It Now only), Best " \
|
|
31
|
-
"Buy, Etsy and Amazon. Each needs its own key from that retailer's developer " \
|
|
32
|
-
"program — skip any you don't have. None of these ever completes a purchase: " \
|
|
33
|
-
"every offer they return still ends in hand-off, same as Amazon today. Neither " \
|
|
34
|
-
"key is echoed back; Enter keeps whatever's already set.")
|
|
35
|
-
assignments = collect
|
|
36
|
-
return @prompt.say("Left retailer offer source keys unchanged.") if assignments.empty?
|
|
37
|
-
|
|
38
|
-
path = DotEnv.update!(assignments)
|
|
39
|
-
@prompt.say("Saved #{assignments.keys.join(', ')} to #{path} (chmod 600).")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
27
|
private
|
|
43
28
|
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
29
|
+
def intro
|
|
30
|
+
"Optional: official buyer-side APIs for Walmart, eBay (Buy It Now only), Best " \
|
|
31
|
+
"Buy, Etsy and Amazon. Each needs its own key from that retailer's developer " \
|
|
32
|
+
"program — skip any you don't have. None of these ever completes a purchase: " \
|
|
33
|
+
"every offer they return still ends in hand-off, same as Amazon today. Neither " \
|
|
34
|
+
"key is echoed back; Enter keeps whatever's already set."
|
|
50
35
|
end
|
|
36
|
+
|
|
37
|
+
def unchanged_message = "Left retailer offer source keys unchanged."
|
|
38
|
+
def secret?(_var) = true
|
|
51
39
|
end
|
|
52
40
|
end
|
|
53
41
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative "
|
|
1
|
+
require_relative "env_keys_step"
|
|
2
2
|
|
|
3
3
|
module Portage
|
|
4
4
|
module Cli
|
|
@@ -10,7 +10,7 @@ module Portage
|
|
|
10
10
|
# with no URL only ever resolves DuckDuckGo's Instant Answer API,
|
|
11
11
|
# which is keyless but only ever matches a specific brand/product
|
|
12
12
|
# name, not an open-ended query ("coffee", "hiking boots").
|
|
13
|
-
class SearchKeys
|
|
13
|
+
class SearchKeys < EnvKeysStep
|
|
14
14
|
FIELDS = {
|
|
15
15
|
"BRAVE_SEARCH_API_KEY" => "Brave Search API key",
|
|
16
16
|
"GOOGLE_CSE_KEY" => "Google Programmable Search API key",
|
|
@@ -21,32 +21,20 @@ module Portage
|
|
|
21
21
|
# only the two API keys are secrets that never echo back.
|
|
22
22
|
SECRET = %w[BRAVE_SEARCH_API_KEY GOOGLE_CSE_KEY].freeze
|
|
23
23
|
|
|
24
|
-
def initialize(prompt:) = @prompt = prompt
|
|
25
|
-
|
|
26
24
|
def title = "Search API keys"
|
|
27
25
|
def default_yes? = true
|
|
28
26
|
|
|
29
|
-
def call
|
|
30
|
-
@prompt.say("DuckDuckGo's free API is already active and needs no key, but only resolves a " \
|
|
31
|
-
"specific brand/product name — set either Brave's key, or both Google fields, for " \
|
|
32
|
-
"real open-ended search. Neither key is echoed back; Enter keeps whatever's " \
|
|
33
|
-
"already set.")
|
|
34
|
-
assignments = collect
|
|
35
|
-
return @prompt.say("Left search API keys unchanged.") if assignments.empty?
|
|
36
|
-
|
|
37
|
-
path = DotEnv.update!(assignments)
|
|
38
|
-
@prompt.say("Saved #{assignments.keys.join(', ')} to #{path} (chmod 600).")
|
|
39
|
-
end
|
|
40
|
-
|
|
41
27
|
private
|
|
42
28
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
end
|
|
29
|
+
def intro
|
|
30
|
+
"DuckDuckGo's free API is already active and needs no key, but only resolves a " \
|
|
31
|
+
"specific brand/product name — set either Brave's key, or both Google fields, for " \
|
|
32
|
+
"real open-ended search. Neither key is echoed back; Enter keeps whatever's " \
|
|
33
|
+
"already set."
|
|
49
34
|
end
|
|
35
|
+
|
|
36
|
+
def unchanged_message = "Left search API keys unchanged."
|
|
37
|
+
def secret?(var) = SECRET.include?(var)
|
|
50
38
|
end
|
|
51
39
|
end
|
|
52
40
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require_relative "../../shipping_profile"
|
|
2
|
-
require_relative "
|
|
2
|
+
require_relative "env_keys_step"
|
|
3
3
|
|
|
4
4
|
module Portage
|
|
5
5
|
module Cli
|
|
@@ -12,7 +12,7 @@ module Portage
|
|
|
12
12
|
# store prices in no market and can report in-stock items as out of
|
|
13
13
|
# stock (see Doctor#shipping_finding, which this step exists to
|
|
14
14
|
# resolve).
|
|
15
|
-
class Shipping
|
|
15
|
+
class Shipping < EnvKeysStep
|
|
16
16
|
LABELS = {
|
|
17
17
|
street_address: "Street address", extended_address: "Apt/suite (optional)",
|
|
18
18
|
address_locality: "City", address_region: "State/region (optional)",
|
|
@@ -21,29 +21,15 @@ module Portage
|
|
|
21
21
|
phone_number: "Phone (optional)"
|
|
22
22
|
}.freeze
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
FIELDS = ShippingProfile::ENV_VARS.to_h { |key, var| [var, LABELS.fetch(key)] }.freeze
|
|
25
25
|
|
|
26
26
|
def title = "Shipping address"
|
|
27
27
|
def default_yes? = true
|
|
28
28
|
|
|
29
|
-
def call
|
|
30
|
-
@prompt.say("Enter keeps whatever's already set for a field.")
|
|
31
|
-
assignments = collect
|
|
32
|
-
return @prompt.say("Left shipping address unchanged.") if assignments.empty?
|
|
33
|
-
|
|
34
|
-
path = DotEnv.update!(assignments)
|
|
35
|
-
@prompt.say("Saved #{assignments.keys.join(', ')} to #{path} (chmod 600).")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
29
|
private
|
|
39
30
|
|
|
40
|
-
def
|
|
41
|
-
|
|
42
|
-
hint = ENV.fetch(var, nil).to_s.empty? ? "not set" : "already set"
|
|
43
|
-
answer = @prompt.ask(LABELS.fetch(key), hint: hint)
|
|
44
|
-
assignments[var] = answer if answer
|
|
45
|
-
end
|
|
46
|
-
end
|
|
31
|
+
def intro = "Enter keeps whatever's already set for a field."
|
|
32
|
+
def unchanged_message = "Left shipping address unchanged."
|
|
47
33
|
end
|
|
48
34
|
end
|
|
49
35
|
end
|
data/lib/portage/cli/version.rb
CHANGED