mirror of
https://github.com/opelly27/streetmerchant.git
synced 2026-05-20 06:27:38 +00:00
Compare commits
507 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b97d581607 | |||
| eb700762a4 | |||
| 38630d478a | |||
| 2a5e2e8733 | |||
| 579cb97a0d | |||
| f70998f0d9 | |||
| 02825d009b | |||
| 0d75025cbb | |||
| db47827e6e | |||
| c3beedced8 | |||
| 0525119b9b | |||
| b6964b02f3 | |||
| 7329c6ede0 | |||
| cccfde245a | |||
| ad0b2fe525 | |||
| 064ce83f03 | |||
| ef452d8e58 | |||
| dca916b64e | |||
| e2bf5749c1 | |||
| da78362045 | |||
| c74ea28014 | |||
| 67b19a7a8b | |||
| 5786481b31 | |||
| 9b7c7e2881 | |||
| 7e3020a927 | |||
| 3386e8f50d | |||
| 7bfcc81fdc | |||
| 37962f00e5 | |||
| d92d58d235 | |||
| 9b3906ca00 | |||
| 0683430768 | |||
| b6ea0ea991 | |||
| 68eede5487 | |||
| 29175c77a8 | |||
| a44621f8f5 | |||
| 27cfb94de8 | |||
| b599c23b51 | |||
| 2115c0c906 | |||
| 4f60ad2a82 | |||
| 8d192317ba | |||
| 3841666d03 | |||
| 2632386a5b | |||
| 9dc04b3638 | |||
| b2738370b4 | |||
| 54ef0ef995 | |||
| ba5c50495b | |||
| 0e7de05fd2 | |||
| 578027a36b | |||
| 5e1dfc3568 | |||
| 5955d10a7f | |||
| 64f55c1b86 | |||
| 1538937661 | |||
| 46bed1ef3c | |||
| b56d214059 | |||
| 625ae0ee53 | |||
| d7602f3a0f | |||
| b806e1bb9c | |||
| 58f0a9c774 | |||
| 48a46d0217 | |||
| 53eeff0bfc | |||
| ac0bd2ac14 | |||
| 0072dda90b | |||
| d56bcddb05 | |||
| 5aa4fdc7b9 | |||
| 60508e2ddb | |||
| 4f7c9ed84f | |||
| e3eb38655a | |||
| b535b470ca | |||
| 30bed2ac01 | |||
| 84a6ff5973 | |||
| 84f2cb7d52 | |||
| d5bd7e3db2 | |||
| 1f63e99804 | |||
| 243109a4ff | |||
| bc2272e59a | |||
| 888b5225b8 | |||
| 0c59d1e232 | |||
| 15ec12b0a3 | |||
| f7b32e8ac5 | |||
| 9bf33eceda | |||
| 14cbd5a05b | |||
| ec0d9f50cb | |||
| 4616f60766 | |||
| 36e38068d8 | |||
| ca5553cb20 | |||
| 34a8fd475a | |||
| 0569629dc8 | |||
| 09f0236086 | |||
| e67d97fe93 | |||
| 75ee95b221 | |||
| 3c727f1c9a | |||
| 80e166c15d | |||
| 3b4fe78e95 | |||
| ac8785d1e9 | |||
| 06f3aafae6 | |||
| f2ae423fa8 | |||
| cbad0846af | |||
| a3a94c19d9 | |||
| 6fd023e81e | |||
| e836acf1e9 | |||
| 5bbdfa2abc | |||
| 1ed0593767 | |||
| cbc43304bf | |||
| feddac76d3 | |||
| 0e8774b1d0 | |||
| 0e5edee683 | |||
| 0b11238370 | |||
| 6de8c4a5ee | |||
| cf70f1ff4f | |||
| a0a961aa5b | |||
| 7d29ef80ba | |||
| e198e44613 | |||
| f7b753334f | |||
| 21e74cfe76 | |||
| ea456116da | |||
| a0a0ca8755 | |||
| c26bd8f06a | |||
| c5799fddc7 | |||
| af96c5f2e8 | |||
| 2fc018bbb2 | |||
| a72a35c755 | |||
| 202698f917 | |||
| d7f242780e | |||
| b2f5c1a3ed | |||
| 29478bff2d | |||
| beb50696fb | |||
| 490d44e1fd | |||
| 65df944973 | |||
| ce43654847 | |||
| e9a39c4092 | |||
| 4bccc6b407 | |||
| 37d62ebcd5 | |||
| af080f376d | |||
| 19eece18dc | |||
| 1774afc1c3 | |||
| 79a3f33150 | |||
| 796c2a52ac | |||
| 0b60d3cf9a | |||
| fb696bf85a | |||
| 0b8e0d498c | |||
| 8ecba2db96 | |||
| eb176d1735 | |||
| bea26450bf | |||
| 8c82705dd3 | |||
| feae978de9 | |||
| 5e6159b994 | |||
| 30a51a38be | |||
| de7036c7cc | |||
| a79ce6f406 | |||
| 0b4966e452 | |||
| be48520469 | |||
| d2efb91de4 | |||
| a519a79ee7 | |||
| 7db79345a0 | |||
| b28bf73157 | |||
| 11b6316371 | |||
| 10ce2db9ae | |||
| 364c6c25df | |||
| a8d9c033b6 | |||
| 7a441b4b65 | |||
| 09238da69c | |||
| 4d8700e856 | |||
| 1ee9d38b32 | |||
| db18157a49 | |||
| 3286d624a1 | |||
| f663579f3d | |||
| 20e8746748 | |||
| d0839beffe | |||
| 07b6b340f9 | |||
| a99eecb461 | |||
| f7f0b08e30 | |||
| efddd01aa9 | |||
| 0857b8a46e | |||
| 67605a6e28 | |||
| 80826ba0bd | |||
| 06214eb4a8 | |||
| a62bd2e587 | |||
| 4df57f578e | |||
| b4f34510d5 | |||
| 429effb544 | |||
| c2defe224a | |||
| e552c9102d | |||
| 292e3603fd | |||
| 85bbaf905e | |||
| 432d38bd5a | |||
| 2d01cfddff | |||
| 53739e05ab | |||
| 9ad9793dc1 | |||
| f6f5c6bfe7 | |||
| 28c965d653 | |||
| 4b689cb94e | |||
| c3f38fb2c9 | |||
| 239b5d3e8a | |||
| 7694829dd6 | |||
| d7921168cb | |||
| 9745190ee4 | |||
| b5435643da | |||
| af631c86f1 | |||
| 5eb36a6cb7 | |||
| 6f273305df | |||
| 6d292a11cd | |||
| 89a762e2f5 | |||
| f9b617dd69 | |||
| 7fea7d58f0 | |||
| f16a9fb331 | |||
| 777c31b420 | |||
| 229daabb34 | |||
| d0ebffd056 | |||
| 3feda151c5 | |||
| d41798ac23 | |||
| eb314afda5 | |||
| f377820894 | |||
| 8933896c5c | |||
| 88a1303f73 | |||
| 167713bb14 | |||
| 7c28c7f72b | |||
| b21b2440f7 | |||
| 63d550ca63 | |||
| 8e1744c6b1 | |||
| 0ed826fb5d | |||
| d47a3e064e | |||
| 501ea34a54 | |||
| b60ad12cf2 | |||
| ef2036b75d | |||
| c38bebb49d | |||
| 02d7c47c40 | |||
| efe0d64f06 | |||
| bd69e471f7 | |||
| bdd74e5b16 | |||
| 32702929a9 | |||
| b4de369ca8 | |||
| ccb207abeb | |||
| 841647c06c | |||
| 23d061b387 | |||
| a5249ecc7c | |||
| 0e730f4203 | |||
| bc8c14c88d | |||
| 5be33d045f | |||
| d19dd5a404 | |||
| b1f1ea6ef0 | |||
| 15e4520213 | |||
| 0904253cc6 | |||
| 318e626e78 | |||
| 0bf9ba2e18 | |||
| 9f28fe5803 | |||
| ab1fddf20c | |||
| ff79d9e70d | |||
| 050fd9faf6 | |||
| 0128718ba7 | |||
| 037056156e | |||
| d9692c7bbd | |||
| 0754feccae | |||
| e8fd2f7c5b | |||
| 314f533f0b | |||
| 4e086e9267 | |||
| dde9837829 | |||
| 25700567c5 | |||
| c02241c752 | |||
| 38937f6880 | |||
| 0362bf8081 | |||
| 815822f6f8 | |||
| f9a6fd025a | |||
| 2291b8eff5 | |||
| 8a459056c5 | |||
| 9320918335 | |||
| 0d14500d5d | |||
| 42ef7cfdce | |||
| 0a680e977b | |||
| 19fd6895e7 | |||
| e3fcc70bb3 | |||
| 71d5cb4261 | |||
| deb17d109f | |||
| 760ddf5d85 | |||
| 5db83484f3 | |||
| 85208c4452 | |||
| df3b10b9a5 | |||
| c8a9b0ba3e | |||
| 2955ea70ab | |||
| 7ec2894147 | |||
| 6924f362ba | |||
| 31a3d8f7e0 | |||
| a293f5e747 | |||
| 2d3ea40a59 | |||
| 6861b3d052 | |||
| 3f9b3c6017 | |||
| 30720d3ca6 | |||
| 0c550312bb | |||
| 30eb6a60cd | |||
| 2737574b03 | |||
| d3c1a0233e | |||
| 6ced13e993 | |||
| ec7be28f2e | |||
| 018784e653 | |||
| 3c5407f5cf | |||
| 0da1621595 | |||
| 5b3e95acdf | |||
| 601742cf2c | |||
| e62eb72056 | |||
| 6cbe72118e | |||
| bb3509f99b | |||
| 430f3ed220 | |||
| e00dafe8ff | |||
| 137c0efdf0 | |||
| ffa2fdc700 | |||
| a9f452f5a7 | |||
| 1d2a33b1d7 | |||
| 493834b526 | |||
| 1918fda5a2 | |||
| 7038be2944 | |||
| 2fc584bdbd | |||
| 191bf8b2ff | |||
| 3085dbcc7f | |||
| 92bb2ef915 | |||
| 2ec5baa37c | |||
| 0fe3db9c99 | |||
| 317c987b08 | |||
| d7360f71ef | |||
| ab4f779573 | |||
| f04c669143 | |||
| 72d66ab127 | |||
| cc114afd15 | |||
| 7c16f85abc | |||
| 8dd10424b3 | |||
| 13edbf311e | |||
| e5b0d7983b | |||
| 3976b21907 | |||
| 87f1c0191d | |||
| 9e0f767a1d | |||
| 2353ee2ef8 | |||
| 6b9ecaeb3d | |||
| 1d6beb8235 | |||
| bde6a25063 | |||
| 273d058414 | |||
| 8548c07e3b | |||
| fa90afc42c | |||
| ceb049b317 | |||
| 2213c9e140 | |||
| 3b5b2b1182 | |||
| 12dd49c387 | |||
| 0318f33234 | |||
| c1dda4f987 | |||
| 61a23fe978 | |||
| 2f57632479 | |||
| 17555ece11 | |||
| 16adc3efda | |||
| 3c22a458b2 | |||
| 3c111bd3a8 | |||
| 0a633ddcfb | |||
| 0b53cb5e51 | |||
| 5cfb1a62d7 | |||
| 373d1a9738 | |||
| 83f82d66d9 | |||
| 5a3bb437aa | |||
| e8b96eb649 | |||
| a42418f814 | |||
| 699de573f6 | |||
| a2af30b703 | |||
| 2e5db7af04 | |||
| f9c4c25874 | |||
| 503d76f3c7 | |||
| 11ee0bf1a3 | |||
| ac37f87793 | |||
| 4847725d3a | |||
| f6db3489b8 | |||
| 9de2307c64 | |||
| 6203a1c18b | |||
| 699e77d960 | |||
| 1f095ce6ac | |||
| 675f13abb8 | |||
| 58416e1994 | |||
| 062201f092 | |||
| aca6523333 | |||
| 10a81dcbd5 | |||
| 68ff5bf836 | |||
| 4fefe22a90 | |||
| 2b6457e840 | |||
| 5ea7cc4ca4 | |||
| 542b92301a | |||
| 0c8771e3eb | |||
| c82b986aab | |||
| 92c5a02f30 | |||
| d575b8b96a | |||
| 8e7b83a55a | |||
| 3b815a9f24 | |||
| 0263bf8b12 | |||
| 199fac45ea | |||
| dc2fcf5ab4 | |||
| 1aaa102c06 | |||
| 32f114b235 | |||
| 053b22100b | |||
| b319bc1080 | |||
| e0735903b7 | |||
| 586029c92a | |||
| 1f89945c57 | |||
| f24f56549e | |||
| 207bc411ed | |||
| 1efde6b783 | |||
| 51d8b5290a | |||
| 2b0eab656d | |||
| cbc3b0b025 | |||
| 81daa7c559 | |||
| 97357c19b8 | |||
| f7ed86506b | |||
| 0cdf6657bf | |||
| 5c61333df0 | |||
| e5909c532d | |||
| a04a0f34af | |||
| 79b9bfe9a8 | |||
| 4192b7108e | |||
| e7592db963 | |||
| c857985a6d | |||
| e1cae3ed71 | |||
| 92696d4654 | |||
| ed970fc397 | |||
| eac05c610d | |||
| 6b9d8cd006 | |||
| b43f352707 | |||
| 812093455e | |||
| 7274ead169 | |||
| 86bef5a617 | |||
| 8adc07a03e | |||
| 160ae37d7b | |||
| 332b4a8246 | |||
| 85a07dc0dc | |||
| b9b6b55c29 | |||
| ee8cb12156 | |||
| 4157a5d746 | |||
| 4ea417cfc1 | |||
| 5109227e88 | |||
| ae6bc86bcb | |||
| 8098a31092 | |||
| f006a8595b | |||
| 8ef8109830 | |||
| eb9d082d17 | |||
| fd3351c028 | |||
| b7e5941a95 | |||
| 9d5272a0a5 | |||
| 628cab1b60 | |||
| b4d8733d18 | |||
| 0c810d62e2 | |||
| 4085136269 | |||
| fd294d2baa | |||
| 02f9ed5e53 | |||
| 177203a085 | |||
| eee6b8183a | |||
| 313d176848 | |||
| fddc0021d3 | |||
| 7a981e7456 | |||
| 760d57b113 | |||
| 7ce6904887 | |||
| 4b3018345b | |||
| e27ea63674 | |||
| b8d4f2f83e | |||
| d3bb507edc | |||
| 5a5d03b259 | |||
| 4db4f1f9d7 | |||
| f980a0bba0 | |||
| 9e7976df57 | |||
| 7148451b66 | |||
| fdd92f9d65 | |||
| 589fbbcd34 | |||
| f1d22d1684 | |||
| d84a409fc7 | |||
| 1a0753e739 | |||
| b110a5a429 | |||
| 54a9890130 | |||
| e55398e789 | |||
| 3b7487e97a | |||
| 7d8897cd9f | |||
| d2476ddb08 | |||
| 95c28a8d6d | |||
| fdcd787f91 | |||
| 772de900a1 | |||
| 5b8d774b7c | |||
| 5414b249a6 | |||
| f2f8d81498 | |||
| 3b90bbbe5d | |||
| 1bac1b928d | |||
| 3bde805f2c | |||
| 8828dd15cd | |||
| 07bd246e87 | |||
| 24786a443a | |||
| 03755d5eb1 | |||
| 0aa7ab596c | |||
| eda6c85fc0 | |||
| 696b75dfbd | |||
| f6760d3c65 | |||
| 9636572c7d | |||
| 1bead4712b | |||
| a2983eb54c | |||
| 349f55d360 | |||
| 38ee437cc9 | |||
| 8d8e5b587d | |||
| d9dea3d0f2 | |||
| b868d1a483 | |||
| 7ef9d935c6 | |||
| c7a716f981 | |||
| d25a643425 | |||
| d69189f12c | |||
| 2893f76e29 | |||
| e992cf4db8 | |||
| 4c63acc75a | |||
| 21aa700a86 | |||
| 8165033ea4 | |||
| 62172d224a | |||
| 9d3b7d38ab | |||
| f277172191 |
@@ -0,0 +1,6 @@
|
|||||||
|
.idea/
|
||||||
|
.git/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
build/
|
||||||
|
node_modules/
|
||||||
+17
-12
@@ -1,12 +1,17 @@
|
|||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
indent_style = tab
|
indent_style = space
|
||||||
end_of_line = lf
|
indent_size = 2
|
||||||
charset = utf-8
|
end_of_line = lf
|
||||||
trim_trailing_whitespace = true
|
charset = utf-8
|
||||||
insert_final_newline = true
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
[*.yml]
|
|
||||||
indent_style = space
|
[*.md]
|
||||||
indent_size = 2
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.ts]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
# ** All configuration variables are optional **
|
|
||||||
# Read https://github.com/jef/nvidia-snatcher#customization for help on customizing this file
|
|
||||||
#############################################################################################
|
|
||||||
|
|
||||||
BROWSER_TRUSTED=""
|
|
||||||
DISCORD_NOTIFY_GROUP=""
|
|
||||||
DISCORD_WEB_HOOK=""
|
|
||||||
EMAIL_USERNAME=""
|
|
||||||
EMAIL_PASSWORD=""
|
|
||||||
HEADLESS=""
|
|
||||||
IN_STOCK_WAIT_TIME=""
|
|
||||||
LOG_LEVEL=""
|
|
||||||
MICROCENTER_LOCATION=""
|
|
||||||
OPEN_BROWSER=""
|
|
||||||
PAGE_TIMEOUT=""
|
|
||||||
PHONE_NUMBER=""
|
|
||||||
PHONE_CARRIER=""
|
|
||||||
PLAY_SOUND=""
|
|
||||||
PUSHBULLET=""
|
|
||||||
PUSHOVER_TOKEN=""
|
|
||||||
PUSHOVER_USER=""
|
|
||||||
PAGE_SLEEP_MIN=""
|
|
||||||
PAGE_SLEEP_MAX=""
|
|
||||||
SHOW_ONLY_BRANDS=""
|
|
||||||
SHOW_ONLY_MODELS=""
|
|
||||||
SHOW_ONLY_SERIES=""
|
|
||||||
SLACK_CHANNEL=""
|
|
||||||
SLACK_TOKEN=""
|
|
||||||
STORES=""
|
|
||||||
COUNTRY=""
|
|
||||||
SCREENSHOT="false"
|
|
||||||
TELEGRAM_ACCESS_TOKEN=""
|
|
||||||
TELEGRAM_CHAT_ID=""
|
|
||||||
TWITTER_CONSUMER_KEY=""
|
|
||||||
TWITTER_CONSUMER_SECRET=""
|
|
||||||
TWITTER_ACCESS_TOKEN_KEY=""
|
|
||||||
TWITTER_ACCESS_TOKEN_SECRET=""
|
|
||||||
TWITTER_TWEET_TAGS=""
|
|
||||||
USER_AGENT=""
|
|
||||||
@@ -1,3 +1,2 @@
|
|||||||
github: jef
|
github: jef
|
||||||
patreon: hijef
|
|
||||||
custom: ["https://www.paypal.me/jxf"]
|
custom: ["https://www.paypal.me/jxf"]
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: "\U0001F41B Bug report"
|
||||||
|
about: Report a bug for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: jef
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
<!--- Tell us what should happen -->
|
||||||
|
|
||||||
|
## Current Behavior
|
||||||
|
|
||||||
|
<!--- Tell us what happens instead of the expected behavior -->
|
||||||
|
|
||||||
|
## Steps to Reproduce
|
||||||
|
|
||||||
|
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
|
||||||
|
<!--- reproduce this bug. Include code to reproduce, if relevant -->
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
4.
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
|
||||||
|
**OS:**
|
||||||
|
**dotenv file:**
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
|
||||||
|
<!--- Provide a brief log -->
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
name: 🐛 Bug report
|
|
||||||
about: Report a bug for this project
|
|
||||||
title: ''
|
|
||||||
labels: 'bug'
|
|
||||||
assignees: jef
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!-- Describe the bug here. -->
|
|
||||||
<!-- Please be as detailed as possible. -->
|
|
||||||
<!-- Include OS, screenshots and console outputs. -->
|
|
||||||
|
|
||||||
### Possible solution
|
|
||||||
|
|
||||||
<!-- Describe the possible solution here. -->
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: 💡 Have an idea for a new feature?
|
||||||
|
url: https://github.com/jef/streetmerchant/discussions
|
||||||
|
about: Create a new idea discussion!
|
||||||
|
- name: 🙇 Need help with streetmerchant?
|
||||||
|
url: https://github.com/jef/streetmerchant/discussions
|
||||||
|
about: Create a new help discussion if it hasn't been asked before!
|
||||||
|
- name: 💬 Want to talk with others that use streetmerchant?
|
||||||
|
url: https://discord.gg/gbVY4vB9JF
|
||||||
|
about: Join our Discord to hangout and talk shop!
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
name: 🚀 Feature request
|
|
||||||
about: Suggest a feature for this project
|
|
||||||
title: ''
|
|
||||||
labels: 'enhancement'
|
|
||||||
assignees: jef
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!-- Describe the feature here. -->
|
|
||||||
|
|
||||||
### Possible solution
|
|
||||||
|
|
||||||
<!-- Describe the possible solution here. -->
|
|
||||||
@@ -4,17 +4,11 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
||||||
|
|||||||
@@ -7,9 +7,6 @@
|
|||||||
<!-- Fixes #(issue) -->
|
<!-- Fixes #(issue) -->
|
||||||
<!-- Please also include relevant motivation and context. -->
|
<!-- Please also include relevant motivation and context. -->
|
||||||
|
|
||||||
<!-- Feel free to include your Discord tag here and we'll consider making you a ringer! -->
|
|
||||||
<!-- Continuous improvements may also grant you contributor access. -->
|
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
<!-- Please describe the tests that you ran to verify your changes. -->
|
<!-- Please describe the tests that you ran to verify your changes. -->
|
||||||
|
|||||||
@@ -4,13 +4,26 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
jobs:
|
jobs:
|
||||||
cd:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: GoogleCloudPlatform/release-please-action@v2.4.1
|
- uses: GoogleCloudPlatform/release-please-action@v2.10
|
||||||
id: release
|
id: release
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
release-type: node
|
release-type: simple
|
||||||
package-name: nvidia-snatcher
|
package-name: streetmerchant
|
||||||
|
- name: login into github package registry
|
||||||
|
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
|
||||||
|
- name: build latest docker image
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
run: |
|
||||||
|
docker build \
|
||||||
|
-t "ghcr.io/${GITHUB_REPOSITORY}:${TAG_NAME}" \
|
||||||
|
-t "ghcr.io/${GITHUB_REPOSITORY}:latest" .
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ steps.release.outputs.tag_name }}
|
||||||
|
- name: publish latest image
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
jobs:
|
jobs:
|
||||||
build-lint:
|
build-and-lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v2.1.1
|
- uses: actions/setup-node@v2.1.3
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14.15.0
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: ~/.npm
|
path: ~/.npm
|
||||||
@@ -23,3 +23,17 @@ jobs:
|
|||||||
npm ci
|
npm ci
|
||||||
npm run build
|
npm run build
|
||||||
npm run lint
|
npm run lint
|
||||||
|
build-docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: dorny/paths-filter@v2.6.0
|
||||||
|
id: filter
|
||||||
|
with:
|
||||||
|
filters: |
|
||||||
|
build:
|
||||||
|
- 'Dockerfile'
|
||||||
|
- 'package*.json'
|
||||||
|
- name: Build image
|
||||||
|
if: steps.filter.outputs.build == 'true'
|
||||||
|
run: docker build .
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: documentation
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Python runtime
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
- name: Install Python dependencies
|
||||||
|
run: pip install mkdocs-material mkdocs-git-revision-date-plugin mkdocs-macros-plugin
|
||||||
|
- name: Deploy documentation
|
||||||
|
run: mkdocs gh-deploy --force
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: nightly
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
workflow_dispatch: {}
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: login into github package registry
|
||||||
|
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
|
||||||
|
- name: build nightly docker image
|
||||||
|
run: |
|
||||||
|
docker build \
|
||||||
|
-t "ghcr.io/${GITHUB_REPOSITORY}:${GITHUB_SHA:0:7}" \
|
||||||
|
-t "ghcr.io/${GITHUB_REPOSITORY}:nightly" .
|
||||||
|
- name: publish nightly image
|
||||||
|
run: docker push "ghcr.io/${GITHUB_REPOSITORY}"
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
name: pr-lint
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- edited
|
||||||
|
- reopened
|
||||||
|
- synchronize
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: amannn/action-semantic-pull-request@v2.1.1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
name: 'Close stale issues'
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v3
|
||||||
|
with:
|
||||||
|
close-issue-message: ${{ env.CLOSE_MESSAGE }}
|
||||||
|
close-pr-message: ${{ env.CLOSE_MESSAGE }}
|
||||||
|
days-before-stale: 30
|
||||||
|
days-before-close: 5
|
||||||
|
exempt-issue-labels: ${{ env.EXEMPT_LABEL }}
|
||||||
|
exempt-pr-labels: ${{ env.EXEMPT_LABEL }}
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
stale-issue-label: ${{ env.STALE_LABEL }}
|
||||||
|
stale-pr-label: ${{ env.STALE_LABEL }}
|
||||||
|
stale-issue-message: ${{ env.STALE_MESSAGE }}
|
||||||
|
stale-pr-message: ${{ env.STALE_MESSAGE }}
|
||||||
|
env:
|
||||||
|
CLOSE_MESSAGE: 'This issue has been closed because it is stale. Reopen if necessary.'
|
||||||
|
EXEMPT_LABEL: 'status: needs discussion'
|
||||||
|
STALE_LABEL: 'status: stale'
|
||||||
|
STALE_MESSAGE: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
|
||||||
+7
-1
@@ -3,10 +3,16 @@
|
|||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
src/config/*.yaml
|
||||||
|
|
||||||
.env
|
.env
|
||||||
|
dotenv
|
||||||
success-*.png
|
success-*.png
|
||||||
|
|
||||||
*.wav
|
*.wav
|
||||||
*.mp3
|
*.mp3
|
||||||
*.flac
|
*.flac
|
||||||
|
*.exe
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
twitch.json
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
14.11.0
|
14.15.0
|
||||||
|
|||||||
+394
-77
@@ -1,129 +1,446 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [1.5.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.4.0...v1.5.0) (2020-09-24)
|
## [3.3.0](https://www.github.com/jef/streetmerchant/compare/v3.2.0...v3.3.0) (2020-12-13)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* filter models ([#261](https://www.github.com/jef/nvidia-snatcher/issues/261)) ([e1b34a9](https://www.github.com/jef/nvidia-snatcher/commit/e1b34a9ccfa45fa1a11da9af9074059b6084904b))
|
* **discord:** dynamic currency symbol ([#1328](https://www.github.com/jef/streetmerchant/issues/1328)) ([cccfde2](https://www.github.com/jef/streetmerchant/commit/cccfde245affc11506c69d1ef6c30c09953307d4))
|
||||||
* **log:** colors for console logs ([#207](https://www.github.com/jef/nvidia-snatcher/issues/207)) ([0ad67fe](https://www.github.com/jef/nvidia-snatcher/commit/0ad67fe20453898ce0a6b5faff00062735411119))
|
* **docs:** add mkdocs ([243109a](https://www.github.com/jef/streetmerchant/commit/243109a4ffdfe1d1efe961af0b5cf28fd7e6ef1d))
|
||||||
* **notification:** add desktop notifications ([#140](https://www.github.com/jef/nvidia-snatcher/issues/140)) ([722eaf3](https://www.github.com/jef/nvidia-snatcher/commit/722eaf3cd680c4600b79f842c6c5acdb9e51ad71))
|
* **docs:** add table sorting ([#1258](https://www.github.com/jef/streetmerchant/issues/1258)) ([5955d10](https://www.github.com/jef/streetmerchant/commit/5955d10a7f2106c5ae1275fadacf2945626ca008))
|
||||||
* **notification:** add pushbullet, add url with notifications ([#226](https://www.github.com/jef/nvidia-snatcher/issues/226)) ([74490ea](https://www.github.com/jef/nvidia-snatcher/commit/74490eae3ab30de7d7a708d5dd970e070f27f2ea))
|
* **lookup:** use random user agents ([#1335](https://www.github.com/jef/streetmerchant/issues/1335)) ([b599c23](https://www.github.com/jef/streetmerchant/commit/b599c23b51735212e5369ce03a44bbd1bccafa42))
|
||||||
* **notification:** twitter integration ([#224](https://www.github.com/jef/nvidia-snatcher/issues/224)) ([908ed35](https://www.github.com/jef/nvidia-snatcher/commit/908ed358826f9de530f5892ded1a54964a304d15))
|
* **notification:** add discord groups ([#1211](https://www.github.com/jef/streetmerchant/issues/1211)) ([2632386](https://www.github.com/jef/streetmerchant/commit/2632386a5b99f3b23166e88f92af809f0036a6b7))
|
||||||
* **store:** add `bannedSeller` label for stores ([#173](https://www.github.com/jef/nvidia-snatcher/issues/173)) ([71c6774](https://www.github.com/jef/nvidia-snatcher/commit/71c6774511f7ba13d34d2e40b69abf52d06e6225))
|
* **notification:** add sound player executable option ([#1301](https://www.github.com/jef/streetmerchant/issues/1301)) ([8d19231](https://www.github.com/jef/streetmerchant/commit/8d192317badfd71a7cd8f0115ba9e6fc951c1874))
|
||||||
* **store:** add amazon-de ([#167](https://www.github.com/jef/nvidia-snatcher/issues/167)) ([8a70f14](https://www.github.com/jef/nvidia-snatcher/commit/8a70f147438584cc334710bc66220d05eb32fcbd))
|
* **playstation:** add queuing selector ([#1173](https://www.github.com/jef/streetmerchant/issues/1173)) ([67b19a7](https://www.github.com/jef/streetmerchant/commit/67b19a7a8b3dead5f5ab9575ee2b4f09924ce851))
|
||||||
* **store:** add bestbuy.ca ([#229](https://www.github.com/jef/nvidia-snatcher/issues/229)) ([22fd22f](https://www.github.com/jef/nvidia-snatcher/commit/22fd22fe743d3e286eae3430aecd6e7a0a5de8c0))
|
* **store:** add darkhero motherboard to asus and microcenter ([#1336](https://www.github.com/jef/streetmerchant/issues/1336)) ([29175c7](https://www.github.com/jef/streetmerchant/commit/29175c77a8fcbc082c944b057a919dfcc22ba606))
|
||||||
* **store:** add evga eu ([#172](https://www.github.com/jef/nvidia-snatcher/issues/172)) ([605bdd7](https://www.github.com/jef/nvidia-snatcher/commit/605bdd7ca73c585734f6c5df1a86f4fbfbff9163))
|
* **store:** add EBGames ([#1281](https://www.github.com/jef/streetmerchant/issues/1281)) ([27cfb94](https://www.github.com/jef/streetmerchant/commit/27cfb94de8d9ccef3c7fc76b250aee17d7c80257))
|
||||||
* **store:** add evga model ([#220](https://www.github.com/jef/nvidia-snatcher/issues/220)) ([190388c](https://www.github.com/jef/nvidia-snatcher/commit/190388cfe4a5e3f19abccd0ff786f654b9a04d2f))
|
* **store:** add Irish store variants ([#1373](https://www.github.com/jef/streetmerchant/issues/1373)) ([f70998f](https://www.github.com/jef/streetmerchant/commit/f70998f0d9a6cdfbc59fb31fecb87f801b0b3037))
|
||||||
* **store:** add microcenter store location config ([#215](https://www.github.com/jef/nvidia-snatcher/issues/215)) ([d6a27c9](https://www.github.com/jef/nvidia-snatcher/commit/d6a27c988c7b1011c7a10084d8283a60ed8aea5c))
|
* **store:** add Megekko ([#1216](https://www.github.com/jef/streetmerchant/issues/1216)) ([30bed2a](https://www.github.com/jef/streetmerchant/commit/30bed2ac016e9e543f67b1098819a484bc1394c3))
|
||||||
* **stores:** add 3090 for bestbuy, newegg ([#249](https://www.github.com/jef/nvidia-snatcher/issues/249)) ([dd45dba](https://www.github.com/jef/nvidia-snatcher/commit/dd45dba82cb86f7e7664298dd202b93bbbd46d9f))
|
* **store:** add several Australian stores, add some 3080 brands/models ([#1367](https://www.github.com/jef/streetmerchant/issues/1367)) ([579cb97](https://www.github.com/jef/streetmerchant/commit/579cb97a0d151cc374a37493b043ba4a399b55db))
|
||||||
* **stores:** add 3090s for amazon-ca, bestbuy-ca, newegg-ca ([#258](https://www.github.com/jef/nvidia-snatcher/issues/258)) ([482fb58](https://www.github.com/jef/nvidia-snatcher/commit/482fb58cbfde6f95fb6f77de790d76e6aa2a5926))
|
* **store:** add Toys R Us ([#1257](https://www.github.com/jef/streetmerchant/issues/1257)) ([ac0bd2a](https://www.github.com/jef/streetmerchant/commit/ac0bd2ac14d686a0f30931e885da65a1d7af6856))
|
||||||
* add chromium sandbox skipping ([#209](https://www.github.com/jef/nvidia-snatcher/issues/209)) ([2065680](https://www.github.com/jef/nvidia-snatcher/commit/20656805c1259637bb3a4db465a8d16d4780296a))
|
* **store:** add Walmart (CA) ([#1253](https://www.github.com/jef/streetmerchant/issues/1253)) ([b535b47](https://www.github.com/jef/streetmerchant/commit/b535b470cad38af034889b4d27578b20136e166d))
|
||||||
* deprecate nvidia (api), add 3080 add 3090 ([9f470f0](https://www.github.com/jef/nvidia-snatcher/commit/9f470f06e9e9fb605d340c0b0f9016d7288e8c0b))
|
|
||||||
* invert logic ([#141](https://www.github.com/jef/nvidia-snatcher/issues/141)) ([6608a79](https://www.github.com/jef/nvidia-snatcher/commit/6608a79769ff03543ab4ed2f2cead3410d7d7e99))
|
|
||||||
* multiple discord roles and webhooks, qol for envs ([#260](https://www.github.com/jef/nvidia-snatcher/issues/260)) ([8913879](https://www.github.com/jef/nvidia-snatcher/commit/8913879593252c9c83020b2e2c46bad7537b2a20))
|
|
||||||
* **store:** add newegg.ca ([#160](https://www.github.com/jef/nvidia-snatcher/issues/160)) ([76f5849](https://www.github.com/jef/nvidia-snatcher/commit/76f584988979a40269fd3641e996800a63b4b163)), closes [#159](https://www.github.com/jef/nvidia-snatcher/issues/159)
|
|
||||||
* **store:** add office depot ([#157](https://www.github.com/jef/nvidia-snatcher/issues/157)) ([0df2dcf](https://www.github.com/jef/nvidia-snatcher/commit/0df2dcfbd48235fba7126d96cd912634c5b4fdd9))
|
|
||||||
* **store:** add zotac store ([#214](https://www.github.com/jef/nvidia-snatcher/issues/214)) ([7875855](https://www.github.com/jef/nvidia-snatcher/commit/78758552b22e608dbdf3e76397f5b5efb893fef5))
|
|
||||||
* add delay on captcha to try and evade faster ([#119](https://www.github.com/jef/nvidia-snatcher/issues/119)) ([4f83b3b](https://www.github.com/jef/nvidia-snatcher/commit/4f83b3b233657841a4068a8ff9dd6c8dbff631c0))
|
|
||||||
* bestbuy bypass international splash, newegg add to cart ([#153](https://www.github.com/jef/nvidia-snatcher/issues/153)) ([133a54f](https://www.github.com/jef/nvidia-snatcher/commit/133a54fa170bb16dd26b0d72b1a02c56b3851b7f))
|
|
||||||
* card series filter, fix: newegg `oosLabels` ([#120](https://www.github.com/jef/nvidia-snatcher/issues/120)) ([252459d](https://www.github.com/jef/nvidia-snatcher/commit/252459d5d3de2b8cb25deee9ae318108e3dda2be))
|
|
||||||
* custom user agent ([#121](https://www.github.com/jef/nvidia-snatcher/issues/121)) ([d9be3fe](https://www.github.com/jef/nvidia-snatcher/commit/d9be3fe6183eaa9694b186c7a75e1f28bb31dace))
|
|
||||||
* include screenshot for emails + sms notifications ([#144](https://www.github.com/jef/nvidia-snatcher/issues/144)) ([7191e03](https://www.github.com/jef/nvidia-snatcher/commit/7191e03a80e577b59b2861289aa658cfa0ffc0fa))
|
|
||||||
* load puppeteer faster, run stores in parallel ([#83](https://www.github.com/jef/nvidia-snatcher/issues/83)) ([d1a5aa1](https://www.github.com/jef/nvidia-snatcher/commit/d1a5aa1f02ff0a8f293b93e3c078b5943908a95b))
|
|
||||||
* set country in config, login to nvidia when starting ([#162](https://www.github.com/jef/nvidia-snatcher/issues/162)) ([ebd6091](https://www.github.com/jef/nvidia-snatcher/commit/ebd6091a09fb5e52a66742767ae4b58323cd7447))
|
|
||||||
* temporarily pause requests if store has stock ([#147](https://www.github.com/jef/nvidia-snatcher/issues/147)) ([6413144](https://www.github.com/jef/nvidia-snatcher/commit/6413144c1cae89f33f852cc93870b407a784f2bb))
|
|
||||||
* update for complex add to cart, fix nvidia ([#108](https://www.github.com/jef/nvidia-snatcher/issues/108)) ([3ea146d](https://www.github.com/jef/nvidia-snatcher/commit/3ea146da14ea40d145ccfc05436beeb0a9fed8d9))
|
|
||||||
* **notification:** discord integration ([#82](https://www.github.com/jef/nvidia-snatcher/issues/82)) ([a3fc07d](https://www.github.com/jef/nvidia-snatcher/commit/a3fc07daf0a3f33f18e03d4cfc13d3477a9c4fa0))
|
|
||||||
* **scraping:** change lookup impl, add randomize sleep ([#110](https://www.github.com/jef/nvidia-snatcher/issues/110)) ([dc0f710](https://www.github.com/jef/nvidia-snatcher/commit/dc0f7106749b0afa0ff1c91cabb90b65be30e909))
|
|
||||||
* **store:** add adorama ([#104](https://www.github.com/jef/nvidia-snatcher/issues/104)) ([5b91065](https://www.github.com/jef/nvidia-snatcher/commit/5b910650430ad4806b22722efa9a013e72ea47e7))
|
|
||||||
* **store:** add asus ([#102](https://www.github.com/jef/nvidia-snatcher/issues/102)) ([a501cf7](https://www.github.com/jef/nvidia-snatcher/commit/a501cf703bb05f47af6240a4b16a3dc4dcf3baf5))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **store:** adorama captcha config ([#234](https://www.github.com/jef/nvidia-snatcher/issues/234)) ([9a53917](https://www.github.com/jef/nvidia-snatcher/commit/9a539175860f98de3b023009f751e59d94f0aaef))
|
* **adblock:** proxy another function to produce less errors ([#1379](https://www.github.com/jef/streetmerchant/issues/1379)) ([eb70076](https://www.github.com/jef/streetmerchant/commit/eb700762a4eee3a802bd81f0fb62e76243027c42))
|
||||||
* color logs and notification ([76b28a6](https://www.github.com/jef/nvidia-snatcher/commit/76b28a6dbdf5480c12a8c82b031c3f2880d17b11))
|
* **amazon-it:** maxPrice selector and links ([#1239](https://www.github.com/jef/streetmerchant/issues/1239)) ([84f2cb7](https://www.github.com/jef/streetmerchant/commit/84f2cb7d52fac7c3dbdd31318a51330e25808784))
|
||||||
* **notification:** change discord ping visibility ([#168](https://www.github.com/jef/nvidia-snatcher/issues/168)) ([9675c5b](https://www.github.com/jef/nvidia-snatcher/commit/9675c5b8d61226db4652964e7f1e7399bb82d04e))
|
* **amazon-nl:** inStock selector ([b6964b0](https://www.github.com/jef/streetmerchant/commit/b6964b02f38c947fd476d86de35d5983e5b229dd)), closes [#1366](https://www.github.com/jef/streetmerchant/issues/1366)
|
||||||
* **store:** bandh removed cards ([#201](https://www.github.com/jef/nvidia-snatcher/issues/201)) ([6409646](https://www.github.com/jef/nvidia-snatcher/commit/6409646d57bf2b2bb5a4bcf8239740abed8edafb))
|
* **bestbuy-ca:** add outOfStock text ([58f0a9c](https://www.github.com/jef/streetmerchant/commit/58f0a9c7740c46f3d820c8765dee5b0fc8516353)), closes [#1269](https://www.github.com/jef/streetmerchant/issues/1269)
|
||||||
* `rateLimitTimeout` not being defaulted ([#106](https://www.github.com/jef/nvidia-snatcher/issues/106)) ([28947be](https://www.github.com/jef/nvidia-snatcher/commit/28947be9bc8981d7a45a5d0e69c18d039fcd9ed3))
|
* **bestbuy-ca:** update selectors to help false positives ([#1278](https://www.github.com/jef/streetmerchant/issues/1278)) ([0525119](https://www.github.com/jef/streetmerchant/commit/0525119b9bae47425a6c01720d6a1ea6ab8e6a02)), closes [#895](https://www.github.com/jef/streetmerchant/issues/895)
|
||||||
* check response for rate limiting ([#58](https://www.github.com/jef/nvidia-snatcher/issues/58)) ([#98](https://www.github.com/jef/nvidia-snatcher/issues/98)) ([b7d9462](https://www.github.com/jef/nvidia-snatcher/commit/b7d9462e794ef3961fb57c79ef8f66e77d25d20a))
|
* **ci:** mkdocs deps ([1f63e99](https://www.github.com/jef/streetmerchant/commit/1f63e9980499ac567845473dc48e51cab78c838e))
|
||||||
* keep single `Store` from draining ([e819e46](https://www.github.com/jef/nvidia-snatcher/commit/e819e46116d4e0b067a59791094b5cfbd2d7cd45))
|
* **config:** disable docker by default ([dca916b](https://www.github.com/jef/streetmerchant/commit/dca916b64e9ac2d05d5e6af19e5466b8a0623ed5))
|
||||||
* memory leak due to adblocker ([#139](https://www.github.com/jef/nvidia-snatcher/issues/139)) ([0f6e570](https://www.github.com/jef/nvidia-snatcher/commit/0f6e570cc817dfc10bcddc5743a0faf3b1489270))
|
* **config:** remove quotes ([ef452d8](https://www.github.com/jef/streetmerchant/commit/ef452d8e586536a5039ee532d655d2951d551ac3))
|
||||||
* **nvidia:** false positives ([#132](https://www.github.com/jef/nvidia-snatcher/issues/132)) ([a75d214](https://www.github.com/jef/nvidia-snatcher/commit/a75d214dd555d5e0388cb54b15be324cc25b6a15))
|
* **discord:** notification groupings ([ad0b2fe](https://www.github.com/jef/streetmerchant/commit/ad0b2fe525d6403735ddcbf4ef55b91eb36ac10a))
|
||||||
* newegg out-of-stock ([#124](https://www.github.com/jef/nvidia-snatcher/issues/124)) ([770a13a](https://www.github.com/jef/nvidia-snatcher/commit/770a13ac3559401b430547908d1df014582c1e37))
|
* **docker:** run in docker, and build scripts for docker ([#1291](https://www.github.com/jef/streetmerchant/issues/1291)) ([c74ea28](https://www.github.com/jef/streetmerchant/commit/c74ea28014ee0d827ea216083844f92e30f142c9))
|
||||||
* newegg out-of-stock labels ([#134](https://www.github.com/jef/nvidia-snatcher/issues/134)) ([19c8f18](https://www.github.com/jef/nvidia-snatcher/commit/19c8f188c796258c469c2b4c6461fc5da3907a47))
|
* **eprice:** inStock selector ([5e1dfc3](https://www.github.com/jef/streetmerchant/commit/5e1dfc35680029620a1de7bc7a523140f2dae8af)), closes [#1067](https://www.github.com/jef/streetmerchant/issues/1067)
|
||||||
* **notification:** wrong condition for sounds playing ([#91](https://www.github.com/jef/nvidia-snatcher/issues/91)) ([103d96d](https://www.github.com/jef/nvidia-snatcher/commit/103d96dc81d6fd097fcdbed5bdd7487d7d73bf6e))
|
* **newegg:** dedupe nitro+ models ([#1300](https://www.github.com/jef/streetmerchant/issues/1300)) ([7329c6e](https://www.github.com/jef/streetmerchant/commit/7329c6ede0a5ab6d644b30ac878f4e7da11e43a8)), closes [#1230](https://www.github.com/jef/streetmerchant/issues/1230)
|
||||||
* **store:** false positives for nvidia. ([#85](https://www.github.com/jef/nvidia-snatcher/issues/85)) ([c65fa04](https://www.github.com/jef/nvidia-snatcher/commit/c65fa04666775060532e28076a0b4af50f8dd30b))
|
* **newegg:** price selector and mobile inStock ([c3beedc](https://www.github.com/jef/streetmerchant/commit/c3beedced82141e6bbb0735b3edb7c573907aa7a)), closes [#1356](https://www.github.com/jef/streetmerchant/issues/1356)
|
||||||
|
* **pushover:** add `expire` and `retry` ([0072dda](https://www.github.com/jef/streetmerchant/commit/0072dda90b637b93647cf3a35dc612cf43d89445)), closes [#983](https://www.github.com/jef/streetmerchant/issues/983)
|
||||||
|
* **store:** update UK stores ([#1372](https://www.github.com/jef/streetmerchant/issues/1372)) ([02825d0](https://www.github.com/jef/streetmerchant/commit/02825d009bd028f6dcdca02e2c155e77a7df8654))
|
||||||
|
* `.env` backwards compatibility ([9b7c7e2](https://www.github.com/jef/streetmerchant/commit/9b7c7e2881d756909af191094bda435ca7ef7e9b))
|
||||||
|
* add setRequestInterception ([#1312](https://www.github.com/jef/streetmerchant/issues/1312)) ([a44621f](https://www.github.com/jef/streetmerchant/commit/a44621f8f50cac9ba6614b0f89320d210370047a)), closes [#826](https://www.github.com/jef/streetmerchant/issues/826)
|
||||||
|
* **store:** italian store checks ([#1212](https://www.github.com/jef/streetmerchant/issues/1212)) ([e3eb386](https://www.github.com/jef/streetmerchant/commit/e3eb38655a3cefb85c4dbd573494955e06c72f71))
|
||||||
|
|
||||||
## [1.4.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.3.0...v1.4.0) (2020-09-19)
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* allow users to still use `USER_AGENT` ([3386e8f](https://www.github.com/jef/streetmerchant/commit/3386e8f50da27a800c5289c3b6bd7a1f76e77a49))
|
||||||
|
|
||||||
|
## [3.2.0](https://www.github.com/jef/streetmerchant/compare/v3.1.0...v3.2.0) (2020-12-06)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **notification:** add mint mobile carrier ([#70](https://www.github.com/jef/nvidia-snatcher/issues/70)) ([8aba7ec](https://www.github.com/jef/nvidia-snatcher/commit/8aba7ecbdb0bfce06257b7b9066e8fccbd82e47e))
|
* **bestbuy:** add 3060 series ([#1074](https://www.github.com/jef/streetmerchant/issues/1074)) ([e9a39c4](https://www.github.com/jef/streetmerchant/commit/e9a39c40925736a2126f6138c369710989904d1d))
|
||||||
* **notification:** add pushover ([#55](https://www.github.com/jef/nvidia-snatcher/issues/55)) ([c85658b](https://www.github.com/jef/nvidia-snatcher/commit/c85658bf82fdf360e5e9d8345eaa846f0572e67c))
|
* **bestbuy-ca:** add 3060ti cards ([29478bf](https://www.github.com/jef/streetmerchant/commit/29478bff2d27d780cc6142526f3970b4a87290bc))
|
||||||
* **notification:** add telegram ([#71](https://www.github.com/jef/nvidia-snatcher/issues/71)) ([393d5f6](https://www.github.com/jef/nvidia-snatcher/commit/393d5f689887bf1d6f30a37eea163b2e6bbd4efa))
|
* **notification:** add price to links ([#1209](https://www.github.com/jef/streetmerchant/issues/1209)) ([15ec12b](https://www.github.com/jef/streetmerchant/commit/15ec12b0a3a95716243bfd06f6d41959bff7c36e)), closes [#1188](https://www.github.com/jef/streetmerchant/issues/1188) [#673](https://www.github.com/jef/streetmerchant/issues/673) [#1187](https://www.github.com/jef/streetmerchant/issues/1187)
|
||||||
* **notification:** add telus sms ([6be74a1](https://www.github.com/jef/nvidia-snatcher/commit/6be74a19f3d3f999145d17ac8e91c59db2502071))
|
* **proxy:** socks5 support ([#933](https://www.github.com/jef/streetmerchant/issues/933)) ([364c6c2](https://www.github.com/jef/streetmerchant/commit/364c6c25dfe9dcbeb29cb20cb46e9e8dcc2fe86b))
|
||||||
* **store:** add amazon.ca, fix timeout ([#75](https://www.github.com/jef/nvidia-snatcher/issues/75)) ([d4de1a4](https://www.github.com/jef/nvidia-snatcher/commit/d4de1a4638e903eb9518354ab6fb2f8c4befc347))
|
* **store:** add 3060ti to newegg-ca, canadacomputer, memoryexpress ([#1172](https://www.github.com/jef/streetmerchant/issues/1172)) ([09f0236](https://www.github.com/jef/streetmerchant/commit/09f0236086c59b25ebe611041bf063d536e3cc3d))
|
||||||
* webpage toggle, sound notification, fix evga links ([#52](https://www.github.com/jef/nvidia-snatcher/issues/52)) ([a217409](https://www.github.com/jef/nvidia-snatcher/commit/a21740942bbbbe967948062fa06cfc82c31eb755))
|
* **store:** add amazon-de-warehouse ([#1102](https://www.github.com/jef/streetmerchant/issues/1102)) ([6de8c4a](https://www.github.com/jef/streetmerchant/commit/6de8c4a5eec8d66fb47d87e309866ba18f3e28c7))
|
||||||
|
* **store:** add antonline store ([#1042](https://www.github.com/jef/streetmerchant/issues/1042)) ([19eece1](https://www.github.com/jef/streetmerchant/commit/19eece18dccd4489e1e441b92061fc3b5743e4cd))
|
||||||
|
* **store:** add argos with ps5 ([b2f5c1a](https://www.github.com/jef/streetmerchant/commit/b2f5c1a3ed93cfd56e575ec634d235565a17b6bc))
|
||||||
|
* **store:** add awd(uk), add 3060ti link builders ([#1114](https://www.github.com/jef/streetmerchant/issues/1114)) ([36e3806](https://www.github.com/jef/streetmerchant/commit/36e38068d8cd284c741d4906d5ba5fe8cff85d24))
|
||||||
|
* **store:** add custom labels for links ([#1183](https://www.github.com/jef/streetmerchant/issues/1183)) ([f7b32e8](https://www.github.com/jef/streetmerchant/commit/f7b32e8ac56c29207c6b30b9168c34c021a5e227)), closes [#1132](https://www.github.com/jef/streetmerchant/issues/1132) [#1163](https://www.github.com/jef/streetmerchant/issues/1163)
|
||||||
|
* **store:** add el corte ingles ([#1107](https://www.github.com/jef/streetmerchant/issues/1107)) ([75ee95b](https://www.github.com/jef/streetmerchant/commit/75ee95b2217fb4bf667869011a009210ff8c22e7))
|
||||||
|
* **store:** add ePrice store ([#1016](https://www.github.com/jef/streetmerchant/issues/1016)) ([30a51a3](https://www.github.com/jef/streetmerchant/commit/30a51a38bee1c399276466e5db457bbe702edd5c))
|
||||||
|
* **store:** add Euronics DE ([#1045](https://www.github.com/jef/streetmerchant/issues/1045)) ([1774afc](https://www.github.com/jef/streetmerchant/commit/1774afc1c3010bd0b183907baa4f3486dc9e8c23))
|
||||||
|
* **store:** add expert ([#1105](https://www.github.com/jef/streetmerchant/issues/1105)) ([202698f](https://www.github.com/jef/streetmerchant/commit/202698f9179b081bd4214979f054e5ff7c805621))
|
||||||
|
* **store:** add Gamestop DE ([#1046](https://www.github.com/jef/streetmerchant/issues/1046)) ([79a3f33](https://www.github.com/jef/streetmerchant/commit/79a3f33150188c7ff0228a38f276ae1fe88b9714))
|
||||||
|
* **store:** add Medimax ([#1057](https://www.github.com/jef/streetmerchant/issues/1057)) ([7d29ef8](https://www.github.com/jef/streetmerchant/commit/7d29ef80ba1ae6682b486ac0b65a516b15a19f93))
|
||||||
|
* **store:** add Otto ([#1096](https://www.github.com/jef/streetmerchant/issues/1096)) ([af96c5f](https://www.github.com/jef/streetmerchant/commit/af96c5f2e808af7496f3c3299e4cf173105de48b))
|
||||||
|
* **store:** add smythstoys ([1ed0593](https://www.github.com/jef/streetmerchant/commit/1ed05937676c3b6961fcbbb1f3aa80afc3411ac3))
|
||||||
|
* **store:** add some italian stores with ps5 links ([#976](https://www.github.com/jef/streetmerchant/issues/976)) ([f663579](https://www.github.com/jef/streetmerchant/commit/f663579f3d744a5270878975407ad30b31ee0c0a))
|
||||||
|
* **store:** add spielegrotte ([#1056](https://www.github.com/jef/streetmerchant/issues/1056)) ([cf70f1f](https://www.github.com/jef/streetmerchant/commit/cf70f1ff4f942922bfa52adcd5b905e0b39c812a))
|
||||||
|
* **store:** add wipoid store ([#1018](https://www.github.com/jef/streetmerchant/issues/1018)) ([feae978](https://www.github.com/jef/streetmerchant/commit/feae978de9e90b96f542d2e53807144d82e380a4))
|
||||||
|
* **store:** update the italian store links ([#1002](https://www.github.com/jef/streetmerchant/issues/1002)) ([de7036c](https://www.github.com/jef/streetmerchant/commit/de7036c7cc6dd7e436ad1d31b988d9d56ad31f76))
|
||||||
|
* **topachat:** add `maxPrice` ([d7f2427](https://www.github.com/jef/streetmerchant/commit/d7f242780ef1a0a06d5b65ccfc0999e36a87d49d)), closes [#1097](https://www.github.com/jef/streetmerchant/issues/1097)
|
||||||
|
* add proxy rotation (settable per store) ([#1026](https://www.github.com/jef/streetmerchant/issues/1026)) ([490d44e](https://www.github.com/jef/streetmerchant/commit/490d44e1fdfdf91db7344dd3050ba8fd8d069631))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **amazon:** price and cart buttons ([6fd023e](https://www.github.com/jef/streetmerchant/commit/6fd023e81e0c54e8fb53b45817b63cb49b8a37ce)), closes [#1125](https://www.github.com/jef/streetmerchant/issues/1125)
|
||||||
|
* **amazon-de:** `inStock` selector ([14cbd5a](https://www.github.com/jef/streetmerchant/commit/14cbd5a05b6f9c3a3ebbc5978156ff2b090efd32)), closes [#1178](https://www.github.com/jef/streetmerchant/issues/1178)
|
||||||
|
* **amazon-de:** remove xbox cart links ([cbc4330](https://www.github.com/jef/streetmerchant/commit/cbc43304bf49863000f422fbff4ed200ea610914)), closes [#1095](https://www.github.com/jef/streetmerchant/issues/1095)
|
||||||
|
* **bestbuy-ca:** model always indicating in stock ([#1145](https://www.github.com/jef/streetmerchant/issues/1145)) ([06f3aaf](https://www.github.com/jef/streetmerchant/commit/06f3aafae6ec460c6227a92e6105639be71fc9b3))
|
||||||
|
* **bestbuy-ca:** replace old evga xc3 ultra ([#1058](https://www.github.com/jef/streetmerchant/issues/1058)) ([65df944](https://www.github.com/jef/streetmerchant/commit/65df9449730bce2acb82f5edac25a91bdddd94db))
|
||||||
|
* **canadacomputers:** add `inStock` selector, use english links ([#889](https://www.github.com/jef/streetmerchant/issues/889)) ([06214eb](https://www.github.com/jef/streetmerchant/commit/06214eb4a8a5c2d8a180e8dcf846f828d5cce2ed))
|
||||||
|
* **memoryexpress:** add backorder to `outOfStock` selector ([#890](https://www.github.com/jef/streetmerchant/issues/890)) ([67605a6](https://www.github.com/jef/streetmerchant/commit/67605a6e280af35f210c536bc03571a84ea1a7e9))
|
||||||
|
* **newegg:** maxPrice selector using used price ([feddac7](https://www.github.com/jef/streetmerchant/commit/feddac76d3824e947b0a96524cd940e6b45ffe70)), closes [#1052](https://www.github.com/jef/streetmerchant/issues/1052)
|
||||||
|
* **newegg:** typo in 5800x url([#903](https://www.github.com/jef/streetmerchant/issues/903)) ([a99eecb](https://www.github.com/jef/streetmerchant/commit/a99eecb4613bc136e65afe4e5e8788316beae39e))
|
||||||
|
* **scan:** links builder ([#1161](https://www.github.com/jef/streetmerchant/issues/1161)) ([ca5553c](https://www.github.com/jef/streetmerchant/commit/ca5553cb2044c00857412a2af009e5e7f2c1aabf))
|
||||||
|
* **smythstoys:** add out of stock label ([5bbdfa2](https://www.github.com/jef/streetmerchant/commit/5bbdfa2abc23c2e1fb1c606227754a1701cab194))
|
||||||
|
* **store:** add backoffStatusCodes and new captcha container ([#1110](https://www.github.com/jef/streetmerchant/issues/1110)) ([0b11238](https://www.github.com/jef/streetmerchant/commit/0b11238370040e9cd31e793e9a782ad384c22abf))
|
||||||
|
* **store:** removes unnecessary newegg links from bestbuy ([#1126](https://www.github.com/jef/streetmerchant/issues/1126)) ([f2ae423](https://www.github.com/jef/streetmerchant/commit/f2ae423fa83d1671a98b9cf3733e587d33727a59)), closes [#1119](https://www.github.com/jef/streetmerchant/issues/1119)
|
||||||
|
* **store:** update euroFormat for expert and otto ([#1108](https://www.github.com/jef/streetmerchant/issues/1108)) ([e198e44](https://www.github.com/jef/streetmerchant/commit/e198e44613cda27c0e67dc7e42ca514e66e9cf48))
|
||||||
|
* **walmart:** instock container and add test:series ([21e74cf](https://www.github.com/jef/streetmerchant/commit/21e74cfe76a5ccf82247315c9951a25e44bb1ce5)), closes [#1106](https://www.github.com/jef/streetmerchant/issues/1106)
|
||||||
|
* related products being picked up on scan ([#954](https://www.github.com/jef/streetmerchant/issues/954)) ([db18157](https://www.github.com/jef/streetmerchant/commit/db18157a490b9c9672c32de3372bff0b472a48f3))
|
||||||
|
|
||||||
|
## [3.1.0](https://www.github.com/jef/streetmerchant/compare/v3.0.0...v3.1.0) (2020-11-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **asus:** add backoff codes ([#790](https://www.github.com/jef/streetmerchant/issues/790)) ([501ea34](https://www.github.com/jef/streetmerchant/commit/501ea34a54e877600050d5a99fd3b71ec799e96a))
|
||||||
|
* **canadacomputers:** add ryzen 5000 series ([#842](https://www.github.com/jef/streetmerchant/issues/842)) ([6f27330](https://www.github.com/jef/streetmerchant/commit/6f273305df69ac7b420b5446b4c6824866821a7e))
|
||||||
|
* **coolmod:** add `maxPrice` ([#862](https://www.github.com/jef/streetmerchant/issues/862)) ([4b689cb](https://www.github.com/jef/streetmerchant/commit/4b689cb94e99b83c8829c11d1bfe4cd6db9fbd7a))
|
||||||
|
* **newegg-ca:** add big navi links ([#843](https://www.github.com/jef/streetmerchant/issues/843)) ([6d292a1](https://www.github.com/jef/streetmerchant/commit/6d292a11cd53bd3893d4a0ff5d13eb2ce3319faa))
|
||||||
|
* **notification:** add product link to email and telegram ([#816](https://www.github.com/jef/streetmerchant/issues/816)) ([777c31b](https://www.github.com/jef/streetmerchant/commit/777c31b420a38cab860d98bc6bd8b7ba990c55e7))
|
||||||
|
* **playstation:** add `outOfStock` label ([#812](https://www.github.com/jef/streetmerchant/issues/812)) ([eb314af](https://www.github.com/jef/streetmerchant/commit/eb314afda557369dd27266429ac991c47ecc6375))
|
||||||
|
* **store:** add `PlayStation` store ([#806](https://www.github.com/jef/streetmerchant/issues/806)) ([7c28c7f](https://www.github.com/jef/streetmerchant/commit/7c28c7f72b171ce914aba770d88e8b1213c41233))
|
||||||
|
* **store:** add 3070 models to pccomponentes & coolmod ([#820](https://www.github.com/jef/streetmerchant/issues/820)) ([d0ebffd](https://www.github.com/jef/streetmerchant/commit/d0ebffd056dc166e3557ccf694379bf8c10148b5))
|
||||||
|
* **store:** add amd rx 6000 series model ([#832](https://www.github.com/jef/streetmerchant/issues/832)) ([89a762e](https://www.github.com/jef/streetmerchant/commit/89a762e2f5cd2ebd56c2586b1ebead4171b67153))
|
||||||
|
* **store:** add captcha check to saturn and mediamarkt ([#876](https://www.github.com/jef/streetmerchant/issues/876)) ([2d01cfd](https://www.github.com/jef/streetmerchant/commit/2d01cfddff557f112c6d53473dad25eb299f2fc0))
|
||||||
|
* **store:** add corsair sfx PSUs ([#881](https://www.github.com/jef/streetmerchant/issues/881)) ([e552c91](https://www.github.com/jef/streetmerchant/commit/e552c9102dd9801dcfc35652f2aaa0b1eea18ebb))
|
||||||
|
* **store:** add topachat ([#776](https://www.github.com/jef/streetmerchant/issues/776)) ([c38bebb](https://www.github.com/jef/streetmerchant/commit/c38bebb49dbe8243d0e3f1205150a33f9ce745aa))
|
||||||
|
* **store:** add vsgamers ([#767](https://www.github.com/jef/streetmerchant/issues/767)) ([53739e0](https://www.github.com/jef/streetmerchant/commit/53739e05abf50bbaddb8079087339c9f353096c8))
|
||||||
|
* add amazon-fr to stores. ([#766](https://www.github.com/jef/streetmerchant/issues/766)) ([02d7c47](https://www.github.com/jef/streetmerchant/commit/02d7c47c4093ad71dfab31f93a9b1390f4cad8a0))
|
||||||
|
* **store:** support for canadacomputers ([#772](https://www.github.com/jef/streetmerchant/issues/772)) ([bd69e47](https://www.github.com/jef/streetmerchant/commit/bd69e471f7b47e7faf1d9858992d4157145518aa))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **amazon:** add 5800x and 5600x ([#802](https://www.github.com/jef/streetmerchant/issues/802)) ([167713b](https://www.github.com/jef/streetmerchant/commit/167713bb14080e5e1d2f77c7ee933918b6fd5cfc))
|
||||||
|
* **bestbuy-ca:** use proper selector ([#801](https://www.github.com/jef/streetmerchant/issues/801)) ([63d550c](https://www.github.com/jef/streetmerchant/commit/63d550ca63b9bfd534f37b7747a1fae057abedb4))
|
||||||
|
* **config:** correcting newline split for multiple user agents ([#824](https://www.github.com/jef/streetmerchant/issues/824)) ([f16a9fb](https://www.github.com/jef/streetmerchant/commit/f16a9fb331fd38590325f399bde369ffa17dbe10))
|
||||||
|
* **store:** generate links only for selected stores ([292e360](https://www.github.com/jef/streetmerchant/commit/292e3603fd527a4454639c9abb73bd80a8a95fae)), closes [#694](https://www.github.com/jef/streetmerchant/issues/694)
|
||||||
|
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* correcting newline split for multiple user agents ([af631c8](https://www.github.com/jef/streetmerchant/commit/af631c86f1a74d810cabf2d0de1b7bb31d350095)), closes [#824](https://www.github.com/jef/streetmerchant/issues/824)
|
||||||
|
* pipeline changes ([efe0d64](https://www.github.com/jef/streetmerchant/commit/efe0d64f060e812fd9846073a13837a3f2a27862))
|
||||||
|
|
||||||
|
## [3.0.0](https://www.github.com/jef/streetmerchant/compare/v2.0.0...v3.0.0) (2020-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* removed duplicated `Model`
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **amazon:** add more 3070s ([#719](https://www.github.com/jef/streetmerchant/issues/719)) ([dde9837](https://www.github.com/jef/streetmerchant/commit/dde9837829b9d52e43800a2ac826b5dd00f5a744))
|
||||||
|
* **coolmod:** add zen 3 ([#754](https://www.github.com/jef/streetmerchant/issues/754)) ([3270292](https://www.github.com/jef/streetmerchant/commit/32702929a97236d7dc51aa8f669140bc6d89aa9a))
|
||||||
|
* **discord:** add cart link to embed ([#762](https://www.github.com/jef/streetmerchant/issues/762)) ([ccb207a](https://www.github.com/jef/streetmerchant/commit/ccb207abeb43b8e85f32c5c0a7a02aa33b5cdd7c))
|
||||||
|
* **store:** support for kabum (amd and rtx 30 series) ([#727](https://www.github.com/jef/streetmerchant/issues/727)) ([23d061b](https://www.github.com/jef/streetmerchant/commit/23d061b387b540803a81212fee937d4c8c9b17ad))
|
||||||
|
* add option to disable auto add to cart ([#759](https://www.github.com/jef/streetmerchant/issues/759)) ([a5249ec](https://www.github.com/jef/streetmerchant/commit/a5249ecc7c3acc29a1f9d5285bd77397263cb135))
|
||||||
|
* fix metadata in logging, lint prettier, typed `Model`s ([#747](https://www.github.com/jef/streetmerchant/issues/747)) ([318e626](https://www.github.com/jef/streetmerchant/commit/318e626e78c18524c4d8624176ccb659c6b6d17c))
|
||||||
|
* **amazon-ca:** add ps5 ([#713](https://www.github.com/jef/streetmerchant/issues/713)) ([2570056](https://www.github.com/jef/streetmerchant/commit/25700567c57a303a9376351daf015741193350a3))
|
||||||
|
* **amd:** add 5950 config ([#685](https://www.github.com/jef/streetmerchant/issues/685)) ([31a3d8f](https://www.github.com/jef/streetmerchant/commit/31a3d8f7e068a17c72e0c296e176b93625bf9063))
|
||||||
|
* **amd:** add env vars and series filtering ([#696](https://www.github.com/jef/streetmerchant/issues/696)) ([df3b10b](https://www.github.com/jef/streetmerchant/commit/df3b10b9a5c2467e00cacb3ab93f818aafc95f02))
|
||||||
|
* **galaxus:** add zen 3 ([#729](https://www.github.com/jef/streetmerchant/issues/729)) ([4e086e9](https://www.github.com/jef/streetmerchant/commit/4e086e92675df97fe7f94c4e6d51b73d63e7effb))
|
||||||
|
* **mindfactory:** add ryzen 5900x, 5950x ([#720](https://www.github.com/jef/streetmerchant/issues/720)) ([0362bf8](https://www.github.com/jef/streetmerchant/commit/0362bf808198d47e6aaa4a4838251f870d6dce4a))
|
||||||
|
* **notification:** add philips hue ([#681](https://www.github.com/jef/streetmerchant/issues/681)) ([c8a9b0b](https://www.github.com/jef/streetmerchant/commit/c8a9b0ba3ed581a9fef7ee2b459b1de84d976ff0))
|
||||||
|
* **notification:** support for multiple phone numbers ([#738](https://www.github.com/jef/streetmerchant/issues/738)) ([9f28fe5](https://www.github.com/jef/streetmerchant/commit/9f28fe5803fc71bf64d303cd1e7d20d0be8fecac))
|
||||||
|
* **ps5:** add console and digital edition ([#709](https://www.github.com/jef/streetmerchant/issues/709)) ([42ef7cf](https://www.github.com/jef/streetmerchant/commit/42ef7cfdced8ae3bc4192e245469798324bc42d3))
|
||||||
|
* **store:** add `arlt` and `amd-de` ([#721](https://www.github.com/jef/streetmerchant/issues/721)) ([38937f6](https://www.github.com/jef/streetmerchant/commit/38937f6880fcffb3a56ef17acd278f7c2f8d251c))
|
||||||
|
* **store:** add `game` store, add ps5 for uk stores ([#736](https://www.github.com/jef/streetmerchant/issues/736)) ([0128718](https://www.github.com/jef/streetmerchant/commit/0128718ba76b0c431d790cea7dd2183d10a02278))
|
||||||
|
* **store:** add ps5 to german stores ([#715](https://www.github.com/jef/streetmerchant/issues/715)) ([2291b8e](https://www.github.com/jef/streetmerchant/commit/2291b8eff5b23613d1233cc4c3ead83a42286d85))
|
||||||
|
* **store:** add xbox series x and s ([#732](https://www.github.com/jef/streetmerchant/issues/732)) ([314f533](https://www.github.com/jef/streetmerchant/commit/314f533f0bab0a466a276c5895d2f00bf86741f4))
|
||||||
|
* **store:** add zen 3 to german stores ([#702](https://www.github.com/jef/streetmerchant/issues/702)) ([71d5cb4](https://www.github.com/jef/streetmerchant/commit/71d5cb426179f5e587adeba1ec60f9a9233ec7b6))
|
||||||
|
* **store:** add zen 3 to more stores ([#698](https://www.github.com/jef/streetmerchant/issues/698)) ([760ddf5](https://www.github.com/jef/streetmerchant/commit/760ddf5d8523e28e294146643dda16e105176dff))
|
||||||
|
* **store:** Adds AM3 to microcenter ([#707](https://www.github.com/jef/streetmerchant/issues/707)) ([8a45905](https://www.github.com/jef/streetmerchant/commit/8a459056c5ba8a5a90de55cfbb08c4c89ccb19d3))
|
||||||
|
* **target:** add additional selector for 'ship it' ([#737](https://www.github.com/jef/streetmerchant/issues/737)) ([ab1fddf](https://www.github.com/jef/streetmerchant/commit/ab1fddf20c3a735b746befda0e21462701882645))
|
||||||
|
* add production scripts and better `Dockerfile` ([0d14500](https://www.github.com/jef/streetmerchant/commit/0d14500d5d8b93204bb99baf34dc9de745ae645d)), closes [#710](https://www.github.com/jef/streetmerchant/issues/710)
|
||||||
|
* bring back ascii banner, but make it configurable ([#703](https://www.github.com/jef/streetmerchant/issues/703)) ([0a680e9](https://www.github.com/jef/streetmerchant/commit/0a680e977b7904e7f62a8c1c0f3d533329b23fb0))
|
||||||
|
* memoryexpress website support ([#717](https://www.github.com/jef/streetmerchant/issues/717)) ([c02241c](https://www.github.com/jef/streetmerchant/commit/c02241c7528656c2c2fba9befc36628b4db7befb))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **docker:** copy web directory ([#745](https://www.github.com/jef/streetmerchant/issues/745)) ([0754fec](https://www.github.com/jef/streetmerchant/commit/0754feccaea2ce2dd37e7caeed3fa0b53c0cdcb3))
|
||||||
|
* **walmart:** ps5 digital url ([#763](https://www.github.com/jef/streetmerchant/issues/763)) ([841647c](https://www.github.com/jef/streetmerchant/commit/841647c06c488cf6b9d6d6af3c3eb6c8dbadab7e))
|
||||||
|
* environment variables to match ryzen cpus ([5db8348](https://www.github.com/jef/streetmerchant/commit/5db83484f301d48509205d9d0b5146c5d7114d26))
|
||||||
|
* revert to 14.15.0 until 15 is stable for `tsc` ([2955ea7](https://www.github.com/jef/streetmerchant/commit/2955ea70ab59c1b0dd82ec506c7a03952f81ea01)), closes [#691](https://www.github.com/jef/streetmerchant/issues/691)
|
||||||
|
|
||||||
|
|
||||||
|
### Code Refactoring
|
||||||
|
|
||||||
|
* removed duplicated `Model` ([d19dd5a](https://www.github.com/jef/streetmerchant/commit/d19dd5a404f2a585dd80f4d23d0e3af2d435ae85))
|
||||||
|
|
||||||
|
## [2.0.0](https://www.github.com/jef/streetmerchant/compare/v1.7.0...v2.0.0) (2020-11-05)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* update naming to `streetmerchant`
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **asus:** realtime api ([#675](https://www.github.com/jef/streetmerchant/issues/675)) ([018784e](https://www.github.com/jef/streetmerchant/commit/018784e653831103465e8278db4929e04c52397c))
|
||||||
|
* **newegg-ca:** realtime api ([#674](https://www.github.com/jef/streetmerchant/issues/674)) ([3c5407f](https://www.github.com/jef/streetmerchant/commit/3c5407f5cfc635ae989101131188e999faa01d3c))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **filterBrandsSeriesModels:** always loop all stores ([#680](https://www.github.com/jef/streetmerchant/issues/680)) ([6ced13e](https://www.github.com/jef/streetmerchant/commit/6ced13e993f7b30bbdda5dc7615e895bac3e4f77))
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
|
||||||
|
* update naming to `streetmerchant` ([3f9b3c6](https://www.github.com/jef/streetmerchant/commit/3f9b3c6017431074d59550a6cd61c80a8897a9ae))
|
||||||
|
|
||||||
|
## [1.7.0](https://www.github.com/jef/streetmerchant/compare/v1.6.0...v1.7.0) (2020-11-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add deprecation notices ([601742c](https://www.github.com/jef/streetmerchant/commit/601742cf2c0b5ccf0131e4c4e904ad4037d80a8d))
|
||||||
|
* newegg realtime api ([#664](https://www.github.com/jef/streetmerchant/issues/664)) ([5b3e95a](https://www.github.com/jef/streetmerchant/commit/5b3e95acdf2f427a6098f15b9fbe65e88354a678))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **banner:** add version to docker image ([#649](https://www.github.com/jef/streetmerchant/issues/649)) ([1d2a33b](https://www.github.com/jef/streetmerchant/commit/1d2a33b1d765fece9d1c9bf7d548818d1f0c8d92))
|
||||||
|
|
||||||
|
## [1.6.0](https://www.github.com/jef/streetmerchant/compare/v1.5.0...v1.6.0) (2020-10-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add series to Discord webhook ([#618](https://www.github.com/jef/streetmerchant/issues/618)) ([273d058](https://www.github.com/jef/streetmerchant/commit/273d05841451ed896f1d505bcd24f2230a143d3a))
|
||||||
|
* **api:** add rudimentary web control panel ([#183](https://www.github.com/jef/streetmerchant/issues/183)) ([373d1a9](https://www.github.com/jef/streetmerchant/commit/373d1a973865b14b5753517aa70eabf85b136d94))
|
||||||
|
* **store:** add founders editions to notebooksbilliger.de ([#593](https://www.github.com/jef/streetmerchant/issues/593)) ([2e5db7a](https://www.github.com/jef/streetmerchant/commit/2e5db7af04e6ce79660477d8deb6636ec2e7845e))
|
||||||
|
* **store:** add max price containers to multiple stores ([#579](https://www.github.com/jef/streetmerchant/issues/579)) ([f9c4c25](https://www.github.com/jef/streetmerchant/commit/f9c4c258748ffd3735f1e7385bde15b6112a1ca7))
|
||||||
|
* **store:** add new cards to german web shops ([#597](https://www.github.com/jef/streetmerchant/issues/597)) ([699de57](https://www.github.com/jef/streetmerchant/commit/699de573f6579b59ba2c65cc2bf4dd6ccba3c863))
|
||||||
|
* **store:** Add PCComponentes and Amazon-ES Stores. ([#558](https://www.github.com/jef/streetmerchant/issues/558)) ([062201f](https://www.github.com/jef/streetmerchant/commit/062201f092c7a271202f27e7297b8eb9d7269c02))
|
||||||
|
* **store:** support for azerty ([#557](https://www.github.com/jef/streetmerchant/issues/557)) ([58416e1](https://www.github.com/jef/streetmerchant/commit/58416e1994006cc2e4055937c675e0f9191f6339))
|
||||||
|
* **store:** support for coolmod ([#605](https://www.github.com/jef/streetmerchant/issues/605)) ([c1dda4f](https://www.github.com/jef/streetmerchant/commit/c1dda4f9871988fad43d79f3bfe65f7c7860b9f7))
|
||||||
|
* add `meta` to logger ([#437](https://www.github.com/jef/streetmerchant/issues/437)) ([ae6bc86](https://www.github.com/jef/streetmerchant/commit/ae6bc86bcb75c154a2a68adda324f34f18281700))
|
||||||
|
* add alternate.nl support ([#552](https://www.github.com/jef/streetmerchant/issues/552)) ([aca6523](https://www.github.com/jef/streetmerchant/commit/aca65233339ddbbcc1dbd06f9011d6d44c6650cf))
|
||||||
|
* add asus-de store and asus 3080 tuf/oc to amazon-de ([#436](https://www.github.com/jef/streetmerchant/issues/436)) ([b4d8733](https://www.github.com/jef/streetmerchant/commit/b4d8733d1823e2fa5d3a1b80d2d4218bfa737cd7))
|
||||||
|
* add caseking and proshop-de store ([#521](https://www.github.com/jef/streetmerchant/issues/521)) ([1aaa102](https://www.github.com/jef/streetmerchant/commit/1aaa102c06281b60da593d04ced01f8b20a37a3b))
|
||||||
|
* add coolblue store ([#482](https://www.github.com/jef/streetmerchant/issues/482)) ([5c61333](https://www.github.com/jef/streetmerchant/commit/5c61333df00c0c30f04e4aced01a498c5816ad58))
|
||||||
|
* add german stores ([#462](https://www.github.com/jef/streetmerchant/issues/462)) ([85a07dc](https://www.github.com/jef/streetmerchant/commit/85a07dc0dc6a8dfe2aba1d4ea3e4cde6ec083086))
|
||||||
|
* add incognito mode ([#534](https://www.github.com/jef/streetmerchant/issues/534)) ([2b6457e](https://www.github.com/jef/streetmerchant/commit/2b6457e8409658b843204fa0aeafb00d48f9e53e))
|
||||||
|
* add link series to error message for better context ([#265](https://www.github.com/jef/streetmerchant/issues/265)) ([332b4a8](https://www.github.com/jef/streetmerchant/commit/332b4a8246320e458729c0b58c310d290df12530))
|
||||||
|
* Add PagerDuty Integration ([#565](https://www.github.com/jef/streetmerchant/issues/565)) ([11ee0bf](https://www.github.com/jef/streetmerchant/commit/11ee0bf1a3e2d0d550d2731f9de9e178c382ea1f))
|
||||||
|
* add proshop-dk ([#524](https://www.github.com/jef/streetmerchant/issues/524)) ([dc2fcf5](https://www.github.com/jef/streetmerchant/commit/dc2fcf5ab4dba8be459bd5aa6a41e3e097205d45))
|
||||||
|
* add support for multiple browser user agents ([#547](https://www.github.com/jef/streetmerchant/issues/547)) ([10a81dc](https://www.github.com/jef/streetmerchant/commit/10a81dcbd54557652537cb641cbbd727d39e34e5))
|
||||||
|
* add uk stores ([#455](https://www.github.com/jef/streetmerchant/issues/455)) ([b9b6b55](https://www.github.com/jef/streetmerchant/commit/b9b6b55c29d11f48b683816e5b8c1cab127ed5fd))
|
||||||
|
* allow filtering per model by a specific series ([#595](https://www.github.com/jef/streetmerchant/issues/595)) ([a42418f](https://www.github.com/jef/streetmerchant/commit/a42418f814dcd91354c136288d4c6a24e03a168d))
|
||||||
|
* optional per store min and max page sleep time ([#576](https://www.github.com/jef/streetmerchant/issues/576)) ([503d76f](https://www.github.com/jef/streetmerchant/commit/503d76f3c7d01368fc978af4ab02924d3d036ac0))
|
||||||
|
* **notification:** add `to` field for email ([#327](https://www.github.com/jef/streetmerchant/issues/327)) ([8828dd1](https://www.github.com/jef/streetmerchant/commit/8828dd15cd08959cd434bd256e8eac474dd17c49))
|
||||||
|
* **store:** add ttl for `scan` ([#555](https://www.github.com/jef/streetmerchant/issues/555)) ([4847725](https://www.github.com/jef/streetmerchant/commit/4847725d3a54d2f4dd0c349ff0ad80eb4bc4e9e3))
|
||||||
|
* add rog strix oc to amazon-de ([#471](https://www.github.com/jef/streetmerchant/issues/471)) ([e5909c5](https://www.github.com/jef/streetmerchant/commit/e5909c532da1c8b731e9835bffd8f31b76550d4d))
|
||||||
|
* add support for specifying smtp server ([#458](https://www.github.com/jef/streetmerchant/issues/458)) ([160ae37](https://www.github.com/jef/streetmerchant/commit/160ae37d7bee4f0323cb939566d586f1300aece6))
|
||||||
|
* allow multiple microcenter locations ([#487](https://www.github.com/jef/streetmerchant/issues/487)) ([2b0eab6](https://www.github.com/jef/streetmerchant/commit/2b0eab656d81314ce7d05064662ec138407550c3))
|
||||||
|
* clear cookies and cache ([#515](https://www.github.com/jef/streetmerchant/issues/515)) ([1f89945](https://www.github.com/jef/streetmerchant/commit/1f89945c5746befb2131381a358efdf8ac530e0c)), closes [#417](https://www.github.com/jef/streetmerchant/issues/417)
|
||||||
|
* max price per series ([#451](https://www.github.com/jef/streetmerchant/issues/451)) ([8adc07a](https://www.github.com/jef/streetmerchant/commit/8adc07a03e411dd536bebfdc7270db4bbf8ddb34))
|
||||||
|
* mqtt alerts ([#538](https://www.github.com/jef/streetmerchant/issues/538)) ([68ff5bf](https://www.github.com/jef/streetmerchant/commit/68ff5bf836c63c8e14d02c06777e02e64a6a0f38))
|
||||||
|
* twitch chat notification, multiple telegram chat ids and german web shop overhaul ([#528](https://www.github.com/jef/streetmerchant/issues/528)) ([675f13a](https://www.github.com/jef/streetmerchant/commit/675f13abb892d1158c92c41e3d57049313a5e0b8))
|
||||||
|
* **docker:** add docker and publish images to ghcr ([#411](https://www.github.com/jef/streetmerchant/issues/411)) ([c857985](https://www.github.com/jef/streetmerchant/commit/c857985a6d3736287976caf5b173f19046306465))
|
||||||
|
* **notification:** add at&t prepaid carrier ([#425](https://www.github.com/jef/streetmerchant/issues/425)) ([eb9d082](https://www.github.com/jef/streetmerchant/commit/eb9d082d178a42e35789ba822cfae7b35c0413c1))
|
||||||
|
* **notification:** add pushover priority setting ([#186](https://www.github.com/jef/streetmerchant/issues/186)) ([f277172](https://www.github.com/jef/streetmerchant/commit/f2771721914a20619833df8ccb2ac44298687b4d))
|
||||||
|
* **notification:** add Twillio notification provider ([#344](https://www.github.com/jef/streetmerchant/issues/344)) ([f2f8d81](https://www.github.com/jef/streetmerchant/commit/f2f8d81498d1acfb9359f4a690962042ec20d166))
|
||||||
|
* **store:** add `pny` ([#295](https://www.github.com/jef/streetmerchant/issues/295)) ([f6760d3](https://www.github.com/jef/streetmerchant/commit/f6760d3c65d60eae9e4b1e0fdba34e814f446a4c))
|
||||||
|
* **store:** add 3090s to amazon-ca ([#274](https://www.github.com/jef/streetmerchant/issues/274)) ([e992cf4](https://www.github.com/jef/streetmerchant/commit/e992cf4db85f045fc8d03c9b93286fb72bad1061))
|
||||||
|
* **store:** add additional cards to all stores ([#286](https://www.github.com/jef/streetmerchant/issues/286)) ([d25a643](https://www.github.com/jef/streetmerchant/commit/d25a643425020fa3f7cd48972360ede17501afeb))
|
||||||
|
* **store:** add amazon cards and `cartUrl`s ([#284](https://www.github.com/jef/streetmerchant/issues/284)) ([d69189f](https://www.github.com/jef/streetmerchant/commit/d69189f12c893fb6d88b198d802ff8e36a69bc88))
|
||||||
|
* **store:** add asus strix oc to asus store ([#385](https://www.github.com/jef/streetmerchant/issues/385)) ([e55398e](https://www.github.com/jef/streetmerchant/commit/e55398e789d52def6e15d1e5e10f56cdf5ea5bea))
|
||||||
|
* **store:** add evga 3090 to newegg canada ([#396](https://www.github.com/jef/streetmerchant/issues/396)) ([313d176](https://www.github.com/jef/streetmerchant/commit/313d176848a25f183334db8926ac0ec445a2c481))
|
||||||
|
* **store:** add ftw3 ultra to microcenter ([#448](https://www.github.com/jef/streetmerchant/issues/448)) ([5109227](https://www.github.com/jef/streetmerchant/commit/5109227e8899f57b828b157309a76c397c872559))
|
||||||
|
* **store:** add gamestop ([#390](https://www.github.com/jef/streetmerchant/issues/390)) ([7148451](https://www.github.com/jef/streetmerchant/commit/7148451b66e97f4f7dcdcc86ce06ba8712211bd5))
|
||||||
|
* **store:** add models to bestbuy ([#421](https://www.github.com/jef/streetmerchant/issues/421)) ([4085136](https://www.github.com/jef/streetmerchant/commit/4085136269b00f6bc5c8414836de8310dfec4166))
|
||||||
|
* **store:** add rog-strix-3080 to newegg-ca ([#489](https://www.github.com/jef/streetmerchant/issues/489)) ([207bc41](https://www.github.com/jef/streetmerchant/commit/207bc411ed240cd9150e018b21e735ba08a4d134))
|
||||||
|
* add `norway` to `nvidia-api` ([#304](https://www.github.com/jef/streetmerchant/issues/304)) ([eda6c85](https://www.github.com/jef/streetmerchant/commit/eda6c85fc03a70c5933308e96c572a480bb6c8a0))
|
||||||
|
* configurable status code behaviours ([#340](https://www.github.com/jef/streetmerchant/issues/340)) ([3b7487e](https://www.github.com/jef/streetmerchant/commit/3b7487e97ac9d93344403f50153f2de6243b1f0d))
|
||||||
|
* enhanced lookup behaviour ([#270](https://www.github.com/jef/streetmerchant/issues/270)) ([b868d1a](https://www.github.com/jef/streetmerchant/commit/b868d1a4833a8ec5ac1c79481530d75cd0c4b01e))
|
||||||
|
* in stock wait time per link now ([c7a716f](https://www.github.com/jef/streetmerchant/commit/c7a716f981976a76afe61a4d985bd6fe4343595b))
|
||||||
|
* low bandwidth mode ([#294](https://www.github.com/jef/streetmerchant/issues/294)) ([0aa7ab5](https://www.github.com/jef/streetmerchant/commit/0aa7ab596c907ce72c188eb4b1acdee088307437))
|
||||||
|
* max price filtering ([#383](https://www.github.com/jef/streetmerchant/issues/383)) ([fd294d2](https://www.github.com/jef/streetmerchant/commit/fd294d2baa06a1c0a68852497889a0412dea492e))
|
||||||
|
* **store:** adds aorus master 3080 to newegg ([#402](https://www.github.com/jef/streetmerchant/issues/402)) ([fddc002](https://www.github.com/jef/streetmerchant/commit/fddc0021d36e4d0a9dacccc546da8260684f0eeb))
|
||||||
|
* retry logic for nvidia session token and adding to cart ([#347](https://www.github.com/jef/streetmerchant/issues/347)) ([1bac1b9](https://www.github.com/jef/streetmerchant/commit/1bac1b928d401a819698848f3367edf54836b26f))
|
||||||
|
* support for proxy server ([#352](https://www.github.com/jef/streetmerchant/issues/352)) ([fdcd787](https://www.github.com/jef/streetmerchant/commit/fdcd787f91f26229db23e2291e8922b947007902))
|
||||||
|
* **store:** nvidia debug card for "product details" page ([#337](https://www.github.com/jef/streetmerchant/issues/337)) ([5b8d774](https://www.github.com/jef/streetmerchant/commit/5b8d774b7c7d31d6ba6fc43be3ea7b16a87d2e49))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* `amazon.{nl,de}` test urls ([#345](https://www.github.com/jef/streetmerchant/issues/345)) ([589fbbc](https://www.github.com/jef/streetmerchant/commit/589fbbcd34393ceb2bd7c0a8ac391c54e14a21be))
|
||||||
|
* `envOrNumber` behavior ([#364](https://www.github.com/jef/streetmerchant/issues/364)) ([7d8897c](https://www.github.com/jef/streetmerchant/commit/7d8897cd9fb9ae0db796fd85da3f2b9d1a9f73af))
|
||||||
|
* `nvidia-api` ([#314](https://www.github.com/jef/streetmerchant/issues/314)) ([8d8e5b5](https://www.github.com/jef/streetmerchant/commit/8d8e5b587d2279a95d3e7837a99bea8c5990a477))
|
||||||
|
* add `amazon-nl`, captcha `amazon-de`, add ftw3 `newegg` ([#293](https://www.github.com/jef/streetmerchant/issues/293)) ([a2983eb](https://www.github.com/jef/streetmerchant/commit/a2983eb54c419ba3a56abf80d316ea136a05e0fa))
|
||||||
|
* add status code `429` to bandh `backOffStatusCodes` ([#404](https://www.github.com/jef/streetmerchant/issues/404)) ([7a981e7](https://www.github.com/jef/streetmerchant/commit/7a981e745673f2b12d48d7eed71fc34a6e4ba5b2))
|
||||||
|
* add support for stores label text to have uppercase letters ([#526](https://www.github.com/jef/streetmerchant/issues/526)) ([5ea7cc4](https://www.github.com/jef/streetmerchant/commit/5ea7cc4ca45c506d2b98d4b643b44ca4ede1d7a9))
|
||||||
|
* asus store links ([#573](https://www.github.com/jef/streetmerchant/issues/573)) ([f6db348](https://www.github.com/jef/streetmerchant/commit/f6db3489b8b8a737dfc425880703928d5bc8916d))
|
||||||
|
* bestbuy label container selector precision ([#491](https://www.github.com/jef/streetmerchant/issues/491)) ([cbc3b0b](https://www.github.com/jef/streetmerchant/commit/cbc3b0b025469e9882ba8267f18f909c08c6c931))
|
||||||
|
* corrected norway locales ([#356](https://www.github.com/jef/streetmerchant/issues/356)) ([d2476dd](https://www.github.com/jef/streetmerchant/commit/d2476ddb08606545b32b9676e2d299d57ec5cb6a))
|
||||||
|
* cyclical dependencies ([ed970fc](https://www.github.com/jef/streetmerchant/commit/ed970fc397210eb6ff684c7e82c79eb685a5d0d9)), closes [#468](https://www.github.com/jef/streetmerchant/issues/468)
|
||||||
|
* denver `microcenter` name ([#296](https://www.github.com/jef/streetmerchant/issues/296)) ([349f55d](https://www.github.com/jef/streetmerchant/commit/349f55d3603517b5741fce6ac42b29141816ea79))
|
||||||
|
* dutch stores components ([#513](https://www.github.com/jef/streetmerchant/issues/513)) ([586029c](https://www.github.com/jef/streetmerchant/commit/586029c92aa19bdddcc85b7a837bb7a16bb1d28d))
|
||||||
|
* gamestop false positives ([#395](https://www.github.com/jef/streetmerchant/issues/395)) ([d3bb507](https://www.github.com/jef/streetmerchant/commit/d3bb507edca112124115ed88fb03cf14440d95ef))
|
||||||
|
* in stock wait time ([#325](https://www.github.com/jef/streetmerchant/issues/325)) ([07bd246](https://www.github.com/jef/streetmerchant/commit/07bd246e876cd27df1b5019af5ee8613bb5368f0)), closes [#315](https://www.github.com/jef/streetmerchant/issues/315)
|
||||||
|
* max price getter updated to match .env ([#516](https://www.github.com/jef/streetmerchant/issues/516)) ([32f114b](https://www.github.com/jef/streetmerchant/commit/32f114b23527ee247c84c081a2cd0264de3b4847)), closes [#514](https://www.github.com/jef/streetmerchant/issues/514) [#510](https://www.github.com/jef/streetmerchant/issues/510)
|
||||||
|
* page sleep ([#586](https://www.github.com/jef/streetmerchant/issues/586)) ([a2af30b](https://www.github.com/jef/streetmerchant/commit/a2af30b70334cdbbfa51140d5de23a2d6b8429c8)), closes [#594](https://www.github.com/jef/streetmerchant/issues/594) [#576](https://www.github.com/jef/streetmerchant/issues/576)
|
||||||
|
* remove 3090 drid for DK/FI regions ([#361](https://www.github.com/jef/streetmerchant/issues/361)) ([f1d22d1](https://www.github.com/jef/streetmerchant/commit/f1d22d1684c8e70f09acd9978e6ea802d7224c8b))
|
||||||
|
* trim strings from comma-separated values ([#472](https://www.github.com/jef/streetmerchant/issues/472)) ([f7ed865](https://www.github.com/jef/streetmerchant/commit/f7ed86506b4e76d5bc20787068be83a44ec485b5))
|
||||||
|
* typo in maxPrice for 3090 ([#496](https://www.github.com/jef/streetmerchant/issues/496)) ([e073590](https://www.github.com/jef/streetmerchant/commit/e0735903b7b4b0d542dbbd76b9a860b1eca24e96))
|
||||||
|
* update gigabyte model `vision oc` ([#550](https://www.github.com/jef/streetmerchant/issues/550)) ([4fefe22](https://www.github.com/jef/streetmerchant/commit/4fefe22a907094fa39af5b4f2e3f8f3fe6897115))
|
||||||
|
* update new additions with web panel and sleep operations ([#606](https://www.github.com/jef/streetmerchant/issues/606)) ([61a23fe](https://www.github.com/jef/streetmerchant/commit/61a23fe9782223dc067dbc8251c3b09adbca0a43))
|
||||||
|
* update pushbullet import to match package ([#637](https://www.github.com/jef/streetmerchant/issues/637)) ([d7360f7](https://www.github.com/jef/streetmerchant/commit/d7360f71ef1a076713246ad2832ca58e7163e492))
|
||||||
|
* **env:** default `LOG_LEVEL` ([9636572](https://www.github.com/jef/streetmerchant/commit/9636572c7de36f7ac6800ba31ac60fcd7bd2fd03))
|
||||||
|
* **notification:** discord false triggers ([#346](https://www.github.com/jef/streetmerchant/issues/346)) ([3b90bbb](https://www.github.com/jef/streetmerchant/commit/3b90bbbe5d751003a39823e9113eaee8cbfcf1a2))
|
||||||
|
* **notification:** sms subject output ([#298](https://www.github.com/jef/streetmerchant/issues/298)) ([03755d5](https://www.github.com/jef/streetmerchant/commit/03755d5eb117ac14797e0180c74f50b401e50cb5))
|
||||||
|
* **notifications:** twilio client creation ([#349](https://www.github.com/jef/streetmerchant/issues/349)) ([5414b24](https://www.github.com/jef/streetmerchant/commit/5414b249a6f938615cfad02ca22c171a5f86e127))
|
||||||
|
* **store:** gamestop `label.inStock` ([9e7976d](https://www.github.com/jef/streetmerchant/commit/9e7976df5778a953c4fb6ca7553773655c1f4127))
|
||||||
|
* **store:** pccomponents model normalization ([#563](https://www.github.com/jef/streetmerchant/issues/563)) ([699e77d](https://www.github.com/jef/streetmerchant/commit/699e77d960b17dcb50378975a1913b0badeabfcc))
|
||||||
|
* updating amazon test model card to an in stock product ([#492](https://www.github.com/jef/streetmerchant/issues/492)) ([81daa7c](https://www.github.com/jef/streetmerchant/commit/81daa7c5596ab23bd9e6aac29fa63ee09e136827))
|
||||||
|
* **config:** `MAX_PRICE` quotations ([#426](https://www.github.com/jef/streetmerchant/issues/426)) ([b7e5941](https://www.github.com/jef/streetmerchant/commit/b7e5941a9598a09afabbb79c5636b768345009a3))
|
||||||
|
* **store:** container names on `nvidia` ([#333](https://www.github.com/jef/streetmerchant/issues/333)) ([772de90](https://www.github.com/jef/streetmerchant/commit/772de900a1386e9635d139e152fe86366404ded4))
|
||||||
|
* **store:** update `inStock` and `maxPrice` for newegg, newegg-ca ([#433](https://www.github.com/jef/streetmerchant/issues/433)) ([628cab1](https://www.github.com/jef/streetmerchant/commit/628cab1b605e4363c8dd5ad43476292ecb12db74)), closes [#400](https://www.github.com/jef/streetmerchant/issues/400)
|
||||||
|
|
||||||
|
|
||||||
|
### Reverts
|
||||||
|
|
||||||
|
* reduce false-positive during ci/cd ([79b9bfe](https://www.github.com/jef/streetmerchant/commit/79b9bfe9a83858117f7a58b4b8b1a1569d80c442))
|
||||||
|
|
||||||
|
## [1.5.0](https://www.github.com/jef/streetmerchant/compare/v1.4.0...v1.5.0) (2020-09-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* filter models ([#261](https://www.github.com/jef/streetmerchant/issues/261)) ([e1b34a9](https://www.github.com/jef/streetmerchant/commit/e1b34a9ccfa45fa1a11da9af9074059b6084904b))
|
||||||
|
* **log:** colors for console logs ([#207](https://www.github.com/jef/streetmerchant/issues/207)) ([0ad67fe](https://www.github.com/jef/streetmerchant/commit/0ad67fe20453898ce0a6b5faff00062735411119))
|
||||||
|
* **notification:** add desktop notifications ([#140](https://www.github.com/jef/streetmerchant/issues/140)) ([722eaf3](https://www.github.com/jef/streetmerchant/commit/722eaf3cd680c4600b79f842c6c5acdb9e51ad71))
|
||||||
|
* **notification:** add pushbullet, add url with notifications ([#226](https://www.github.com/jef/streetmerchant/issues/226)) ([74490ea](https://www.github.com/jef/streetmerchant/commit/74490eae3ab30de7d7a708d5dd970e070f27f2ea))
|
||||||
|
* **notification:** twitter integration ([#224](https://www.github.com/jef/streetmerchant/issues/224)) ([908ed35](https://www.github.com/jef/streetmerchant/commit/908ed358826f9de530f5892ded1a54964a304d15))
|
||||||
|
* **store:** add `bannedSeller` label for stores ([#173](https://www.github.com/jef/streetmerchant/issues/173)) ([71c6774](https://www.github.com/jef/streetmerchant/commit/71c6774511f7ba13d34d2e40b69abf52d06e6225))
|
||||||
|
* **store:** add amazon-de ([#167](https://www.github.com/jef/streetmerchant/issues/167)) ([8a70f14](https://www.github.com/jef/streetmerchant/commit/8a70f147438584cc334710bc66220d05eb32fcbd))
|
||||||
|
* **store:** add bestbuy.ca ([#229](https://www.github.com/jef/streetmerchant/issues/229)) ([22fd22f](https://www.github.com/jef/streetmerchant/commit/22fd22fe743d3e286eae3430aecd6e7a0a5de8c0))
|
||||||
|
* **store:** add evga eu ([#172](https://www.github.com/jef/streetmerchant/issues/172)) ([605bdd7](https://www.github.com/jef/streetmerchant/commit/605bdd7ca73c585734f6c5df1a86f4fbfbff9163))
|
||||||
|
* **store:** add evga model ([#220](https://www.github.com/jef/streetmerchant/issues/220)) ([190388c](https://www.github.com/jef/streetmerchant/commit/190388cfe4a5e3f19abccd0ff786f654b9a04d2f))
|
||||||
|
* **store:** add microcenter store location config ([#215](https://www.github.com/jef/streetmerchant/issues/215)) ([d6a27c9](https://www.github.com/jef/streetmerchant/commit/d6a27c988c7b1011c7a10084d8283a60ed8aea5c))
|
||||||
|
* **stores:** add 3090 for bestbuy, newegg ([#249](https://www.github.com/jef/streetmerchant/issues/249)) ([dd45dba](https://www.github.com/jef/streetmerchant/commit/dd45dba82cb86f7e7664298dd202b93bbbd46d9f))
|
||||||
|
* **stores:** add 3090s for amazon-ca, bestbuy-ca, newegg-ca ([#258](https://www.github.com/jef/streetmerchant/issues/258)) ([482fb58](https://www.github.com/jef/streetmerchant/commit/482fb58cbfde6f95fb6f77de790d76e6aa2a5926))
|
||||||
|
* add chromium sandbox skipping ([#209](https://www.github.com/jef/streetmerchant/issues/209)) ([2065680](https://www.github.com/jef/streetmerchant/commit/20656805c1259637bb3a4db465a8d16d4780296a))
|
||||||
|
* deprecate nvidia (api), add 3080 add 3090 ([9f470f0](https://www.github.com/jef/streetmerchant/commit/9f470f06e9e9fb605d340c0b0f9016d7288e8c0b))
|
||||||
|
* invert logic ([#141](https://www.github.com/jef/streetmerchant/issues/141)) ([6608a79](https://www.github.com/jef/streetmerchant/commit/6608a79769ff03543ab4ed2f2cead3410d7d7e99))
|
||||||
|
* multiple discord roles and webhooks, qol for envs ([#260](https://www.github.com/jef/streetmerchant/issues/260)) ([8913879](https://www.github.com/jef/streetmerchant/commit/8913879593252c9c83020b2e2c46bad7537b2a20))
|
||||||
|
* **store:** add newegg.ca ([#160](https://www.github.com/jef/streetmerchant/issues/160)) ([76f5849](https://www.github.com/jef/streetmerchant/commit/76f584988979a40269fd3641e996800a63b4b163)), closes [#159](https://www.github.com/jef/streetmerchant/issues/159)
|
||||||
|
* **store:** add office depot ([#157](https://www.github.com/jef/streetmerchant/issues/157)) ([0df2dcf](https://www.github.com/jef/streetmerchant/commit/0df2dcfbd48235fba7126d96cd912634c5b4fdd9))
|
||||||
|
* **store:** add zotac store ([#214](https://www.github.com/jef/streetmerchant/issues/214)) ([7875855](https://www.github.com/jef/streetmerchant/commit/78758552b22e608dbdf3e76397f5b5efb893fef5))
|
||||||
|
* add delay on captcha to try and evade faster ([#119](https://www.github.com/jef/streetmerchant/issues/119)) ([4f83b3b](https://www.github.com/jef/streetmerchant/commit/4f83b3b233657841a4068a8ff9dd6c8dbff631c0))
|
||||||
|
* bestbuy bypass international splash, newegg add to cart ([#153](https://www.github.com/jef/streetmerchant/issues/153)) ([133a54f](https://www.github.com/jef/streetmerchant/commit/133a54fa170bb16dd26b0d72b1a02c56b3851b7f))
|
||||||
|
* card series filter, fix: newegg `oosLabels` ([#120](https://www.github.com/jef/streetmerchant/issues/120)) ([252459d](https://www.github.com/jef/streetmerchant/commit/252459d5d3de2b8cb25deee9ae318108e3dda2be))
|
||||||
|
* custom user agent ([#121](https://www.github.com/jef/streetmerchant/issues/121)) ([d9be3fe](https://www.github.com/jef/streetmerchant/commit/d9be3fe6183eaa9694b186c7a75e1f28bb31dace))
|
||||||
|
* include screenshot for emails + sms notifications ([#144](https://www.github.com/jef/streetmerchant/issues/144)) ([7191e03](https://www.github.com/jef/streetmerchant/commit/7191e03a80e577b59b2861289aa658cfa0ffc0fa))
|
||||||
|
* load puppeteer faster, run stores in parallel ([#83](https://www.github.com/jef/streetmerchant/issues/83)) ([d1a5aa1](https://www.github.com/jef/streetmerchant/commit/d1a5aa1f02ff0a8f293b93e3c078b5943908a95b))
|
||||||
|
* set country in config, login to nvidia when starting ([#162](https://www.github.com/jef/streetmerchant/issues/162)) ([ebd6091](https://www.github.com/jef/streetmerchant/commit/ebd6091a09fb5e52a66742767ae4b58323cd7447))
|
||||||
|
* temporarily pause requests if store has stock ([#147](https://www.github.com/jef/streetmerchant/issues/147)) ([6413144](https://www.github.com/jef/streetmerchant/commit/6413144c1cae89f33f852cc93870b407a784f2bb))
|
||||||
|
* update for complex add to cart, fix nvidia ([#108](https://www.github.com/jef/streetmerchant/issues/108)) ([3ea146d](https://www.github.com/jef/streetmerchant/commit/3ea146da14ea40d145ccfc05436beeb0a9fed8d9))
|
||||||
|
* **notification:** discord integration ([#82](https://www.github.com/jef/streetmerchant/issues/82)) ([a3fc07d](https://www.github.com/jef/streetmerchant/commit/a3fc07daf0a3f33f18e03d4cfc13d3477a9c4fa0))
|
||||||
|
* **scraping:** change lookup impl, add randomize sleep ([#110](https://www.github.com/jef/streetmerchant/issues/110)) ([dc0f710](https://www.github.com/jef/streetmerchant/commit/dc0f7106749b0afa0ff1c91cabb90b65be30e909))
|
||||||
|
* **store:** add adorama ([#104](https://www.github.com/jef/streetmerchant/issues/104)) ([5b91065](https://www.github.com/jef/streetmerchant/commit/5b910650430ad4806b22722efa9a013e72ea47e7))
|
||||||
|
* **store:** add asus ([#102](https://www.github.com/jef/streetmerchant/issues/102)) ([a501cf7](https://www.github.com/jef/streetmerchant/commit/a501cf703bb05f47af6240a4b16a3dc4dcf3baf5))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **store:** adorama captcha config ([#234](https://www.github.com/jef/streetmerchant/issues/234)) ([9a53917](https://www.github.com/jef/streetmerchant/commit/9a539175860f98de3b023009f751e59d94f0aaef))
|
||||||
|
* color logs and notification ([76b28a6](https://www.github.com/jef/streetmerchant/commit/76b28a6dbdf5480c12a8c82b031c3f2880d17b11))
|
||||||
|
* **notification:** change discord ping visibility ([#168](https://www.github.com/jef/streetmerchant/issues/168)) ([9675c5b](https://www.github.com/jef/streetmerchant/commit/9675c5b8d61226db4652964e7f1e7399bb82d04e))
|
||||||
|
* **store:** bandh removed cards ([#201](https://www.github.com/jef/streetmerchant/issues/201)) ([6409646](https://www.github.com/jef/streetmerchant/commit/6409646d57bf2b2bb5a4bcf8239740abed8edafb))
|
||||||
|
* `rateLimitTimeout` not being defaulted ([#106](https://www.github.com/jef/streetmerchant/issues/106)) ([28947be](https://www.github.com/jef/streetmerchant/commit/28947be9bc8981d7a45a5d0e69c18d039fcd9ed3))
|
||||||
|
* check response for rate limiting ([#58](https://www.github.com/jef/streetmerchant/issues/58)) ([#98](https://www.github.com/jef/streetmerchant/issues/98)) ([b7d9462](https://www.github.com/jef/streetmerchant/commit/b7d9462e794ef3961fb57c79ef8f66e77d25d20a))
|
||||||
|
* keep single `Store` from draining ([e819e46](https://www.github.com/jef/streetmerchant/commit/e819e46116d4e0b067a59791094b5cfbd2d7cd45))
|
||||||
|
* memory leak due to adblocker ([#139](https://www.github.com/jef/streetmerchant/issues/139)) ([0f6e570](https://www.github.com/jef/streetmerchant/commit/0f6e570cc817dfc10bcddc5743a0faf3b1489270))
|
||||||
|
* **nvidia:** false positives ([#132](https://www.github.com/jef/streetmerchant/issues/132)) ([a75d214](https://www.github.com/jef/streetmerchant/commit/a75d214dd555d5e0388cb54b15be324cc25b6a15))
|
||||||
|
* newegg out-of-stock ([#124](https://www.github.com/jef/streetmerchant/issues/124)) ([770a13a](https://www.github.com/jef/streetmerchant/commit/770a13ac3559401b430547908d1df014582c1e37))
|
||||||
|
* newegg out-of-stock labels ([#134](https://www.github.com/jef/streetmerchant/issues/134)) ([19c8f18](https://www.github.com/jef/streetmerchant/commit/19c8f188c796258c469c2b4c6461fc5da3907a47))
|
||||||
|
* **notification:** wrong condition for sounds playing ([#91](https://www.github.com/jef/streetmerchant/issues/91)) ([103d96d](https://www.github.com/jef/streetmerchant/commit/103d96dc81d6fd097fcdbed5bdd7487d7d73bf6e))
|
||||||
|
* **store:** false positives for nvidia. ([#85](https://www.github.com/jef/streetmerchant/issues/85)) ([c65fa04](https://www.github.com/jef/streetmerchant/commit/c65fa04666775060532e28076a0b4af50f8dd30b))
|
||||||
|
|
||||||
|
## [1.4.0](https://www.github.com/jef/streetmerchant/compare/v1.3.0...v1.4.0) (2020-09-19)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **notification:** add mint mobile carrier ([#70](https://www.github.com/jef/streetmerchant/issues/70)) ([8aba7ec](https://www.github.com/jef/streetmerchant/commit/8aba7ecbdb0bfce06257b7b9066e8fccbd82e47e))
|
||||||
|
* **notification:** add pushover ([#55](https://www.github.com/jef/streetmerchant/issues/55)) ([c85658b](https://www.github.com/jef/streetmerchant/commit/c85658bf82fdf360e5e9d8345eaa846f0572e67c))
|
||||||
|
* **notification:** add telegram ([#71](https://www.github.com/jef/streetmerchant/issues/71)) ([393d5f6](https://www.github.com/jef/streetmerchant/commit/393d5f689887bf1d6f30a37eea163b2e6bbd4efa))
|
||||||
|
* **notification:** add telus sms ([6be74a1](https://www.github.com/jef/streetmerchant/commit/6be74a19f3d3f999145d17ac8e91c59db2502071))
|
||||||
|
* **store:** add amazon.ca, fix timeout ([#75](https://www.github.com/jef/streetmerchant/issues/75)) ([d4de1a4](https://www.github.com/jef/streetmerchant/commit/d4de1a4638e903eb9518354ab6fb2f8c4befc347))
|
||||||
|
* webpage toggle, sound notification, fix evga links ([#52](https://www.github.com/jef/streetmerchant/issues/52)) ([a217409](https://www.github.com/jef/streetmerchant/commit/a21740942bbbbe967948062fa06cfc82c31eb755))
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
||||||
* browser abstraction ([#68](https://www.github.com/jef/nvidia-snatcher/issues/68)) ([#81](https://www.github.com/jef/nvidia-snatcher/issues/81)) ([ebbdfe3](https://www.github.com/jef/nvidia-snatcher/commit/ebbdfe3f6378516112f4b6e004bbd6ccf13af685))
|
* browser abstraction ([#68](https://www.github.com/jef/streetmerchant/issues/68)) ([#81](https://www.github.com/jef/streetmerchant/issues/81)) ([ebbdfe3](https://www.github.com/jef/streetmerchant/commit/ebbdfe3f6378516112f4b6e004bbd6ccf13af685))
|
||||||
|
|
||||||
## [1.3.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.2.0...v1.3.0) (2020-09-19)
|
## [1.3.0](https://www.github.com/jef/streetmerchant/compare/v1.2.0...v1.3.0) (2020-09-19)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **logging:** add timestamp ([#48](https://www.github.com/jef/nvidia-snatcher/issues/48)) ([6c3cd01](https://www.github.com/jef/nvidia-snatcher/commit/6c3cd016850d03a6c6a894cab24ba2d3781a9af1))
|
* **logging:** add timestamp ([#48](https://www.github.com/jef/streetmerchant/issues/48)) ([6c3cd01](https://www.github.com/jef/streetmerchant/commit/6c3cd016850d03a6c6a894cab24ba2d3781a9af1))
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **store:** amazon captcha false-positives ([#54](https://www.github.com/jef/nvidia-snatcher/issues/54)) ([5c9e0b6](https://www.github.com/jef/nvidia-snatcher/commit/5c9e0b6d06bd7e1223a7587fec067c8e79c9cfd6))
|
* **store:** amazon captcha false-positives ([#54](https://www.github.com/jef/streetmerchant/issues/54)) ([5c9e0b6](https://www.github.com/jef/streetmerchant/commit/5c9e0b6d06bd7e1223a7587fec067c8e79c9cfd6))
|
||||||
* evga xc3 ultra link ([#56](https://www.github.com/jef/nvidia-snatcher/issues/56)) ([d907092](https://www.github.com/jef/nvidia-snatcher/commit/d907092b443b056605e09cb2ca3e94e6ca811d9e))
|
* evga xc3 ultra link ([#56](https://www.github.com/jef/streetmerchant/issues/56)) ([d907092](https://www.github.com/jef/streetmerchant/commit/d907092b443b056605e09cb2ca3e94e6ca811d9e))
|
||||||
* screenshot size, add screenshot config setting ([#53](https://www.github.com/jef/nvidia-snatcher/issues/53)) ([7cfc7c7](https://www.github.com/jef/nvidia-snatcher/commit/7cfc7c74429c808fa14468cdd497eb9f9aeb922c))
|
* screenshot size, add screenshot config setting ([#53](https://www.github.com/jef/streetmerchant/issues/53)) ([7cfc7c7](https://www.github.com/jef/streetmerchant/commit/7cfc7c74429c808fa14468cdd497eb9f9aeb922c))
|
||||||
* sms carrier config, add google carrier ([#44](https://www.github.com/jef/nvidia-snatcher/issues/44)) ([971fec2](https://www.github.com/jef/nvidia-snatcher/commit/971fec20e441e2b12a38d5c8d17d2d4cb5e64d6b))
|
* sms carrier config, add google carrier ([#44](https://www.github.com/jef/streetmerchant/issues/44)) ([971fec2](https://www.github.com/jef/streetmerchant/commit/971fec20e441e2b12a38d5c8d17d2d4cb5e64d6b))
|
||||||
|
|
||||||
## [1.2.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.1.0...v1.2.0) (2020-09-19)
|
## [1.2.0](https://www.github.com/jef/streetmerchant/compare/v1.1.0...v1.2.0) (2020-09-19)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **ci:** add `npm run build` ([faad3e6](https://www.github.com/jef/nvidia-snatcher/commit/faad3e68efafaab135b77080b02af83429b6eca6))
|
* **ci:** add `npm run build` ([faad3e6](https://www.github.com/jef/streetmerchant/commit/faad3e68efafaab135b77080b02af83429b6eca6))
|
||||||
* **store:** microcenter ([#39](https://www.github.com/jef/nvidia-snatcher/issues/39)) ([edf17e9](https://www.github.com/jef/nvidia-snatcher/commit/edf17e926f3d186e7630da2834d78de3e540a956))
|
* **store:** microcenter ([#39](https://www.github.com/jef/streetmerchant/issues/39)) ([edf17e9](https://www.github.com/jef/streetmerchant/commit/edf17e926f3d186e7630da2834d78de3e540a956))
|
||||||
* add Amazon links ([#26](https://www.github.com/jef/nvidia-snatcher/issues/26)) ([f0560ce](https://www.github.com/jef/nvidia-snatcher/commit/f0560ce72bfbfdd6360b85e23edaa875d58f228f))
|
* add Amazon links ([#26](https://www.github.com/jef/streetmerchant/issues/26)) ([f0560ce](https://www.github.com/jef/streetmerchant/commit/f0560ce72bfbfdd6360b85e23edaa875d58f228f))
|
||||||
* add email test, fix memory leak ([#24](https://www.github.com/jef/nvidia-snatcher/issues/24)) ([a2fb973](https://www.github.com/jef/nvidia-snatcher/commit/a2fb97333c6eb81250b24ccb6859e9356acded21))
|
* add email test, fix memory leak ([#24](https://www.github.com/jef/streetmerchant/issues/24)) ([a2fb973](https://www.github.com/jef/streetmerchant/commit/a2fb97333c6eb81250b24ccb6859e9356acded21))
|
||||||
* more Best Buy AIBs ([#41](https://www.github.com/jef/nvidia-snatcher/issues/41)) ([7d7bd18](https://www.github.com/jef/nvidia-snatcher/commit/7d7bd18b4dd656ec01ef2fb2d8519e2a7f34ef70))
|
* more Best Buy AIBs ([#41](https://www.github.com/jef/streetmerchant/issues/41)) ([7d7bd18](https://www.github.com/jef/streetmerchant/commit/7d7bd18b4dd656ec01ef2fb2d8519e2a7f34ef70))
|
||||||
* page timeout ([#22](https://www.github.com/jef/nvidia-snatcher/issues/22)) ([643045c](https://www.github.com/jef/nvidia-snatcher/commit/643045c7e0158fb6526bd09427b96cce7958bcea))
|
* page timeout ([#22](https://www.github.com/jef/streetmerchant/issues/22)) ([643045c](https://www.github.com/jef/streetmerchant/commit/643045c7e0158fb6526bd09427b96cce7958bcea))
|
||||||
* slack integration ([#34](https://www.github.com/jef/nvidia-snatcher/issues/34)) ([c0a881a](https://www.github.com/jef/nvidia-snatcher/commit/c0a881a16ebb573bf35b7f29cb27e5b3c2e1fe78))
|
* slack integration ([#34](https://www.github.com/jef/streetmerchant/issues/34)) ([c0a881a](https://www.github.com/jef/streetmerchant/commit/c0a881a16ebb573bf35b7f29cb27e5b3c2e1fe78))
|
||||||
* sms notification for usa carriers ([#40](https://www.github.com/jef/nvidia-snatcher/issues/40)) ([5a3636b](https://www.github.com/jef/nvidia-snatcher/commit/5a3636bcb639bb33bc586af96264f5df2f3a8307))
|
* sms notification for usa carriers ([#40](https://www.github.com/jef/streetmerchant/issues/40)) ([5a3636b](https://www.github.com/jef/streetmerchant/commit/5a3636bcb639bb33bc586af96264f5df2f3a8307))
|
||||||
* update to check if FE in-stock via Digital River ([#29](https://www.github.com/jef/nvidia-snatcher/issues/29)) ([00ede13](https://www.github.com/jef/nvidia-snatcher/commit/00ede13501082f530ea672a349816be1d31621a8))
|
* update to check if FE in-stock via Digital River ([#29](https://www.github.com/jef/streetmerchant/issues/29)) ([00ede13](https://www.github.com/jef/streetmerchant/commit/00ede13501082f530ea672a349816be1d31621a8))
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* small error in `isOutOfStock` logic ([#33](https://www.github.com/jef/nvidia-snatcher/issues/33)) ([c2a210c](https://www.github.com/jef/nvidia-snatcher/commit/c2a210cc815c3aa06f6f14d33954f65577d95954))
|
* small error in `isOutOfStock` logic ([#33](https://www.github.com/jef/streetmerchant/issues/33)) ([c2a210c](https://www.github.com/jef/streetmerchant/commit/c2a210cc815c3aa06f6f14d33954f65577d95954))
|
||||||
|
|
||||||
## [1.1.0](https://www.github.com/jef/nvidia-snatcher/compare/v1.0.0...v1.1.0) (2020-09-18)
|
## [1.1.0](https://www.github.com/jef/streetmerchant/compare/v1.0.0...v1.1.0) (2020-09-18)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add conventional commits ([#14](https://www.github.com/jef/nvidia-snatcher/issues/14)) ([eb4f5e0](https://www.github.com/jef/nvidia-snatcher/commit/eb4f5e034176a286eabe381c98ced77cd197d7fb))
|
* add conventional commits ([#14](https://www.github.com/jef/streetmerchant/issues/14)) ([eb4f5e0](https://www.github.com/jef/streetmerchant/commit/eb4f5e034176a286eabe381c98ced77cd197d7fb))
|
||||||
* add evga ([#17](https://www.github.com/jef/nvidia-snatcher/issues/17)) ([#18](https://www.github.com/jef/nvidia-snatcher/issues/18)) ([6c65032](https://www.github.com/jef/nvidia-snatcher/commit/6c6503219f7c188783c24a44f7052b276a4b39a3))
|
* add evga ([#17](https://www.github.com/jef/streetmerchant/issues/17)) ([#18](https://www.github.com/jef/streetmerchant/issues/18)) ([6c65032](https://www.github.com/jef/streetmerchant/commit/6c6503219f7c188783c24a44f7052b276a4b39a3))
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* exception handling `TimeoutError` ([#20](https://www.github.com/jef/nvidia-snatcher/issues/20)) ([#21](https://www.github.com/jef/nvidia-snatcher/issues/21)) ([00a0687](https://www.github.com/jef/nvidia-snatcher/commit/00a0687d3eba6a8fca871161b447529be00c8896))
|
* exception handling `TimeoutError` ([#20](https://www.github.com/jef/streetmerchant/issues/20)) ([#21](https://www.github.com/jef/streetmerchant/issues/21)) ([00a0687](https://www.github.com/jef/streetmerchant/commit/00a0687d3eba6a8fca871161b447529be00c8896))
|
||||||
|
|
||||||
## 1.0.0 (2020-09-18)
|
## 1.0.0 (2020-09-18)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* use ts, update cd, update `README` ([#12](https://www.github.com/jef/nvidia-snatcher/issues/12)) ([e9fc0bf](https://www.github.com/jef/nvidia-snatcher/commit/e9fc0bf5f770481d5e508d8b520e1020624e05d2))
|
* use ts, update cd, update `README` ([#12](https://www.github.com/jef/streetmerchant/issues/12)) ([e9fc0bf](https://www.github.com/jef/streetmerchant/commit/e9fc0bf5f770481d5e508d8b520e1020624e05d2))
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at jeffreylec@gmail.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
FROM node:14.15.0-alpine3.12 AS builder
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/jef/streetmerchant"
|
||||||
|
|
||||||
|
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
COPY package.json package.json
|
||||||
|
COPY package-lock.json package-lock.json
|
||||||
|
COPY tsconfig.json tsconfig.json
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY src/ src/
|
||||||
|
RUN npm run build
|
||||||
|
RUN npm prune --production
|
||||||
|
|
||||||
|
FROM node:14.15.0-alpine3.12
|
||||||
|
|
||||||
|
RUN apk add --no-cache chromium
|
||||||
|
|
||||||
|
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
|
||||||
|
DOCKER=true
|
||||||
|
|
||||||
|
RUN addgroup -S appuser && adduser -S -g appuser appuser \
|
||||||
|
&& mkdir -p /home/appuser/Downloads /app \
|
||||||
|
&& chown -R appuser:appuser /home/appuser \
|
||||||
|
&& chown -R appuser:appuser /app
|
||||||
|
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /build/node_modules/ node_modules/
|
||||||
|
COPY --from=builder /build/build/ build/
|
||||||
|
COPY web/ web/
|
||||||
|
COPY package.json package.json
|
||||||
|
COPY version.txt version.txt
|
||||||
|
|
||||||
|
ENTRYPOINT ["npm", "run"]
|
||||||
|
CMD ["start:production"]
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
.DEFAULT_GOAL := run
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
docker-compose build streetmerchant
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run:
|
||||||
|
docker-compose up
|
||||||
|
|
||||||
|
.PHONY: run-detached
|
||||||
|
run-detached:
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
.PHONY: stop
|
||||||
|
stop:
|
||||||
|
docker-compose down
|
||||||
@@ -1,204 +1,48 @@
|
|||||||
# nvidia-snatcher [](https://github.com/jef/nvidia-snatcher/actions?query=workflow%3Aci) [](https://discord.gg/Cyc7nrz)
|
<p align="center">
|
||||||
|
<a href="https://jef.codes/streetmerchant"
|
||||||
|
><img
|
||||||
|
src="https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-banner.png"
|
||||||
|
alt="streetmerchant"
|
||||||
|
/></a>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<strong>The world's easiest, most powerful stock checker</strong>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/jef/streetmerchant/actions?query=workflow%3Aci"
|
||||||
|
><img src="https://github.com/jef/streetmerchant/workflows/ci/badge.svg"
|
||||||
|
/></a>
|
||||||
|
<a href="https://discord.gg/gbVY4vB9JF"
|
||||||
|
><img
|
||||||
|
src="https://img.shields.io/discord/773913070665859073.svg?label=chat&logo=discord&logoColor=ffffff&color=7389D8"
|
||||||
|
alt="Tweet"
|
||||||
|
/></a>
|
||||||
|
<a
|
||||||
|
href="https://twitter.com/intent/tweet?text=Beat%20the%20masses%20with%20streetmerchant&url=https://github.com/jef/streetmerchant&hashtags=typescript,opensource,bot,shopping"
|
||||||
|
><img
|
||||||
|
src="https://img.shields.io/badge/twitter-share-green?logo=twitter&style=social"
|
||||||
|
alt="Tweet"
|
||||||
|
/></a>
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<em>To get started, visit <a href="https://jef.codes/streetmerchant">jef.codes/streetmerchant</a></em>
|
||||||
|
</p>
|
||||||
|
|
||||||
[FAQ](#FAQ) | [Issues](https://github.com/jef/nvidia-snatcher/issues) | [Wiki](https://github.com/jef/nvidia-snatcher/wiki)
|
## Features
|
||||||
|
|
||||||

|
First and foremost, this service _will not_ automatically buy for you.
|
||||||
|
|
||||||
The purpose of this bot is to get an Nvidia card. It tries multiple things to do that.
|
- **Checks stock continuously** -- runs 24/7, 365, looking for the items you want.
|
||||||
|
- **Ready for checkout** -- ability to add to cart when available and even opens the browser for you.
|
||||||
|
- **Notifications galore** -- when you're not by your computer, worry free with notifications to most platforms and devices when an item comes in stock.
|
||||||
|
|
||||||
- Currently, `nvidia-snatcher` is not capable of purchasing a card for you
|
## Quick start
|
||||||
- Scrapes multiple websites for patterns of being stocked
|
|
||||||
- API requests are a work in progress (very soon)
|
|
||||||
- Opens browser when stock is available
|
|
||||||
- Sends an email to you when stock is avaiable (must have Gmail)
|
|
||||||
|
|
||||||
<details>
|
streetmerchant runs on Node.js 14:
|
||||||
<summary>What you may see if you're lucky</summary>
|
|
||||||
|
|
||||||
```sh
|
```shell
|
||||||
2020-09-18T07:06:28.535Z info :: ✖ [nvidia] nvidia founders edition is still out of stock
|
git clone https://github.com/jef/streetmerchant.git
|
||||||
2020-09-18T07:06:31.241Z info :: ✖ [nvidia] nvidia founders edition is still out of stock
|
cd streetmerchant && npm i && npm run start
|
||||||
2020-09-18T07:06:34.212Z info :: ✖ [bestbuy] nvidia founder edition is still out of stock
|
|
||||||
2020-09-18T07:06:39.878Z info :: ✖ [bandh] gigabyte black is still out of stock
|
|
||||||
2020-09-18T07:06:43.236Z info :: ✖ [bestbuy] gigabyte black is still out of stock
|
|
||||||
2020-09-18T07:06:43.318Z info :: ↗ trying stores again
|
|
||||||
2020-09-18T07:06:43.318Z info :: 🚀🚀🚀 [nvidia] nvidia founders edition IN STOCK 🚀🚀🚀
|
|
||||||
2020-09-18T07:06:43.318Z info :: https://store.nvidia.com/store/nvidia/en_US/buy/productID.5438481700/clearCart.yes/nextPage.QuickBuyCartPage
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
For more information and customization, visit [jef.codes/streetmerchant/getting-started](https://jef.codes/streetmerchant/getting-started).
|
||||||
|
|
||||||
> :point_right: You may get false positives from time to time, so I apologize for that. The library currently waits for all calls to be completed before parsing, but sometimes this can have unknown behavior. Patience is a virtue :)
|
|
||||||
|
|
||||||
| | **Adorama** | **Amazon** | **Amazon (CA)** | **ASUS** | **B&H** | **Best Buy** | **Best Buy (CA)** | **EVGA** | **Micro Center** | **Newegg** | **Newegg (CA)** | **Nvidia** | **Office Depot** | **Zotac** |
|
|
||||||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
|
||||||
| **3070**| | | | | | | | | | | | | | |
|
|
||||||
| **3080** | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` | `✔` |
|
|
||||||
| **3090** | | | | | | `✔` | `✔` | | | `✔` | `✔` | `✔` | | |
|
|
||||||
|
|
||||||
## Installation and prerequisites
|
|
||||||
|
|
||||||
Linux, macOS, and Windows are all capable operating systems.
|
|
||||||
|
|
||||||
You do not need any computer skills, smarts, or anything of that nature. You are very capable as you have made it this far. Some basic understanding how a terminal, git, and or Node.js is a bonus, but that does not limit you to getting `nvidia-snatcher` running!
|
|
||||||
|
|
||||||
### Quick overview
|
|
||||||
|
|
||||||
- [Node.js 14](https://nodejs.org/en/)
|
|
||||||
- [git](https://git-scm.com/)
|
|
||||||
- Clone this project `git clone https://github.com/jef/nvidia-snatcher.git`
|
|
||||||
- Run `npm install`
|
|
||||||
- Copy `.env.example` to a new file `.env` and edit the `.env` file to your liking using your [favorite text editor](https://code.visualstudio.com/)
|
|
||||||
- More on this in [customization](#Customization)
|
|
||||||
- Run `npm run start` to start
|
|
||||||
|
|
||||||
At any point you want the program to stop, use <kbd>Ctrl</kbd> + <kbd>C</kbd>.
|
|
||||||
|
|
||||||
> :point_right: Please visit the [wiki](https://github.com/jef/nvidia-snatcher/wiki) if you need more help with installation.
|
|
||||||
|
|
||||||
### Customization
|
|
||||||
|
|
||||||
To customize `nvidia-snatcher`, make a copy of `.env-example` as `.env` and make any changes to your liking. _All environment variables are **optional**._
|
|
||||||
|
|
||||||
Here is a list of variables that you can use to customize your newly copied `.env` file:
|
|
||||||
|
|
||||||
| **Environment variable** | **Description** | **Notes** |
|
|
||||||
|:---:|---|---|
|
|
||||||
| `BROWSER_TRUSTED` | Skip Chromium Sandbox | Useful for containerized environments, default: `false` |
|
|
||||||
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier) | Default: `false` |
|
|
||||||
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify | Can be comma separated, use role ID, E.g.: `<@2834729847239842>` |
|
|
||||||
| `DISCORD_WEB_HOOK` | Discord Web Hook URL | Can be comma separated, use whole webhook URL |
|
|
||||||
| `EMAIL_USERNAME` | Gmail address | E.g.: `jensen.robbed.us@gmail.com` |
|
|
||||||
| `EMAIL_PASSWORD` | Gmail password | See below if you have MFA |
|
|
||||||
| `HEADLESS` | Puppeteer to run headless or not | Debugging related, default: `true` |
|
|
||||||
| `IN_STOCK_WAIT_TIME` | Time to wait between requests to the same store if it has cards in stock | In seconds, default: `0` |
|
|
||||||
| `LOG_LEVEL` | [Logging levels](https://github.com/winstonjs/winston#logging-levels) | Debugging related, default: `info` |
|
|
||||||
| `MICROCENTER_LOCATION` | Specific MicroCenter location to search | Default : `web` |
|
|
||||||
| `OPEN_BROWSER` | Toggle for whether or not the browser should open when item is found | Default: `true` |
|
|
||||||
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds | `0` for infinite, default: `30000` |
|
|
||||||
| `PHONE_NUMBER` | 10 digit phone number | E.g.: `1234567890`, email configuration required |
|
|
||||||
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS | Email configuration required |
|
|
||||||
| `PLAY_SOUND` | Play this sound notification if a card is found | Relative path accepted, valid formats: wav, mp3, flac, E.g.: `path/to/notification.wav`, [free sounds available](https://notificationsounds.com/) |
|
|
||||||
| `PUSHBULLET` | PushBullet API key | Generate at https://www.pushbullet.com/#settings/account | |
|
|
||||||
| `PUSHOVER_TOKEN` | Pushover access token | Generate at https://pushover.net/apps/build | |
|
|
||||||
| `PUSHOVER_USER` | Pushover username | |
|
|
||||||
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same store | In milliseconds, default: `5000` |
|
|
||||||
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same store | In milliseconds, default: `10000` |
|
|
||||||
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
|
|
||||||
| `SHOW_ONLY_BRANDS` | Filter to show specified brands | Comma separated, e.g.: `evga,zotac` |
|
|
||||||
| `SHOW_ONLY_MODELS` | Filter to show specified models | Comma separated, e.g.: `founders edition,rog strix` |
|
|
||||||
| `SHOW_ONLY_SERIES` | Filter to show specified series | Comma separated, e.g.: `3080` |
|
|
||||||
| `SLACK_CHANNEL` | Slack channel for posting | E.g.: `update`, no need for `#` |
|
|
||||||
| `SLACK_TOKEN` | Slack API token | |
|
|
||||||
| `STORES` | [Supported stores](#supported-stores) you want to be scraped | Comma separated, default: `nvidia` |
|
|
||||||
| `COUNTRY` | [Supported country](#supported-countries) you want to be scraped | Currently only used by Nvidia, default: `usa` |
|
|
||||||
| `SCREENSHOT` | Capture screenshot of page if a card is found | Default: `true` |
|
|
||||||
| `TELEGRAM_ACCESS_TOKEN` | Telegram access token | |
|
|
||||||
| `TELEGRAM_CHAT_ID` | Telegram chat ID | |
|
|
||||||
| `USER_AGENT` | Custom User-Agent header for HTTP requests | Default: `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36` |
|
|
||||||
| `TWITTER_CONSUMER_KEY` | Twitter Consumer Key | Generate all Twitter keys at: https://developer.twitter.com/ |
|
|
||||||
| `TWITTER_CONSUMER_SECRET` | Twitter Consumer Secret | |
|
|
||||||
| `TWITTER_ACCESS_TOKEN_KEY` | Twitter Token Key | |
|
|
||||||
| `TWITTER_ACCESS_TOKEN_SECRET` | Twitter Token Secret | |
|
|
||||||
| `TWITTER_TWEET_TAGS` | Optional list of hashtags to append to the tweet message | E.g.: `#nvidia #nvidiastock` |
|
|
||||||
|
|
||||||
> :point_right: If you have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
|
|
||||||
|
|
||||||
> :point_right: You can find your computer's user agent by [searching google for "my user agent"](http://google.com/search?q=my+user+agent)
|
|
||||||
|
|
||||||
> :point_right: You can test your notification configuration by running `npm run test:notification`.
|
|
||||||
|
|
||||||
#### Supported stores
|
|
||||||
|
|
||||||
| **Stores** | **Environment variable** |
|
|
||||||
|:---:|:---:|
|
|
||||||
| Adorama | `adorama`|
|
|
||||||
| Amazon | `amazon`|
|
|
||||||
| Amazon (CA) | `amazon-ca`|
|
|
||||||
| Amazon (DE) | `amazon-de`|
|
|
||||||
| ASUS | `asus` |
|
|
||||||
| B&H | `bandh`|
|
|
||||||
| Best Buy | `bestbuy`|
|
|
||||||
| Best Buy (CA) | `bestbuy-ca`|
|
|
||||||
| EVGA | `evga`|
|
|
||||||
| EVGA (EU) | `evga-eu`|
|
|
||||||
| Micro Center | `microcenter`|
|
|
||||||
| Newegg | `newegg`|
|
|
||||||
| Newegg (CA) | `newegg-ca`|
|
|
||||||
| Nvidia | `nvidia`|
|
|
||||||
| Nvidia (API) | `nvidia-api`|
|
|
||||||
| Office Depot | `officedepot`|
|
|
||||||
| Zotac | `zotac`|
|
|
||||||
|
|
||||||
#### Supported carriers
|
|
||||||
|
|
||||||
| **Carrier** | **Environment variable** | **Notes** |
|
|
||||||
|:---:|:---:|:---:|
|
|
||||||
| AT&T | `att`| |
|
|
||||||
| Bell | `bell` | |
|
|
||||||
| Fido | `fido` | |
|
|
||||||
| Google | `google`| |
|
|
||||||
| Koodo | `koodo` | |
|
|
||||||
| Mint | `mint`| |
|
|
||||||
| Rogers | `rogers` | |
|
|
||||||
| Sprint | `sprint`| |
|
|
||||||
| Telus | `telus`| |
|
|
||||||
| T-Mobile | `tmobile`| |
|
|
||||||
| Verizon | `verizon`| Works with Visible |
|
|
||||||
| Virgin | `virgin`| |
|
|
||||||
| Virgin (CA) | `virgin-ca`| |
|
|
||||||
|
|
||||||
#### Supported countries
|
|
||||||
|
|
||||||
| **Country** | **Nvidia.com (3080 FE)** | **Nvidia.com (3090 FE)** | **Notes** |
|
|
||||||
|:---:|:---:|:---:|:---:|
|
|
||||||
| austria | `✔` | | |
|
|
||||||
| belgium | `✔` | | Nvidia supports debug |
|
|
||||||
| canada | `✔` | | |
|
|
||||||
| czechia | `✔` | | |
|
|
||||||
| denmark | `✔` | | |
|
|
||||||
| finland | `✔` | | |
|
|
||||||
| france | `✔` | | |
|
|
||||||
| germany | `✔` | | |
|
|
||||||
| great_britain | `✔` | | |
|
|
||||||
| ireland | `✔` | | |
|
|
||||||
| italy | `✔` | | |
|
|
||||||
| luxembourg | `✔` | | Nvidia supports debug |
|
|
||||||
| netherlands | `✔` | | Nvidia supports debug |
|
|
||||||
| poland | `✔` | | |
|
|
||||||
| portugal | `✔` | | |
|
|
||||||
| russia | | | Missing all IDs |
|
|
||||||
| spain | `✔` | | |
|
|
||||||
| sweden | `✔` | | |
|
|
||||||
| usa | `✔` | | Nvidia supports debug |
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
**Q: What's Node.js and how do I install it?** Visit [their website](https://nodejs.org/en/) and download and install it. Very straight forward. Otherwise, Google more information related to your system needs.
|
|
||||||
|
|
||||||
**Q: Will this harm my computer?** No.
|
|
||||||
|
|
||||||
**Q: Have you gotten a card yet?** No. :cry:
|
|
||||||
|
|
||||||
**Q: Will I get banned from of the stores?** Perhaps, but getting a card is a nice outcome.
|
|
||||||
|
|
||||||
**Q: I got a problem and need help!** File an [issue](https://github.com/jef/nvidia-snatcher/issues/new/choose), I'll do my best to get to you. I work a full time job and this is only a hobby of mine.
|
|
||||||
|
|
||||||
**Q: How do I get the latest code?** Take look at this [wiki page](https://github.com/jef/nvidia-snatcher/wiki/Troubleshoot:-General:-Getting-the-latest-code)
|
|
||||||
|
|
||||||
**Q: Why don't my notifications work?** There are probably an [issue](https://github.com/jef/nvidia-snatcher/issues?q=is%3Aissue+sort%3Aupdated-desc+sound+is%3Aclosed) [that] has [already](https://github.com/jef/nvidia-snatcher/issues/182) [been](https://github.com/jef/nvidia-snatcher/issues/116) [resolved](https://github.com/jef/nvidia-snatcher/issues/155)
|
|
||||||
|
|
||||||
**Q: I'd love to contribute, how do I do that?** Make a [pull request](https://github.com/jef/nvidia-snatcher/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)! All contributions are welcome.
|
|
||||||
|
|
||||||
**Q: Why do I have to download all this stuff just to get this bot working?** Well, I would rather you didn't either. See [#11](https://github.com/jef/nvidia-snatcher/issues/11).
|
|
||||||
|
|
||||||
### Acknowledgements
|
|
||||||
|
|
||||||
Thanks to the great contributors that make this project possible
|
|
||||||
|
|
||||||
Special shout to initial developers:
|
|
||||||
|
|
||||||
- [@andirew](https://github.com/andirew)
|
|
||||||
- [@fuckingrobot](https://github.com/fuckingrobot)
|
|
||||||
- [@ioncaza](https://github.com/IonCaza)
|
|
||||||
- [@malbert69](https://github.com/malbert69)
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
version: '3.0'
|
||||||
|
services:
|
||||||
|
streetmerchant:
|
||||||
|
image: ghcr.io/jef/streetmerchant:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: streetmerchant
|
||||||
|
env_file:
|
||||||
|
- dotenv
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# About
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
Remember on September 17th, 2020 at 9 AM EST the Nvidia site went from **Notify Me** to **Out of Stock** instantly? Well, they didn't sell any cards. The real reason was that they weren't ready to sell them to us yet. That's right, they turned off their third party storefronts because they were being overloaded with our clicks. They still kept the other cards that use those APIs online, but they removed that one. It was re-enabled at some point for a brief moment, but the same thing happened -- servers overloaded with API requests.
|
||||||
|
|
||||||
|
This is where streetmerchant comes in. It doesn't buy anything for you, but it makes it more of a stress free job to refresh and check sites while you go about your daily business. People took off work, missed appointments, and gave up other lively needs in hopes to buy a _graphics card_. Now we reach beyond graphics cards in hopes for other products!
|
||||||
|
|
||||||
|
Please enjoy,
|
||||||
|
|
||||||
|
jef
|
||||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../CHANGELOG.md
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
# FAQ
|
||||||
|
|
||||||
|
## What's Node.js and how do I install it?
|
||||||
|
|
||||||
|
Visit [their website](https://nodejs.org/en/) and download and install it. Very straight forward. Otherwise, Google more information related to your system needs.
|
||||||
|
|
||||||
|
## Will this harm my computer?
|
||||||
|
|
||||||
|
No.
|
||||||
|
|
||||||
|
## Have you gotten a card yet?
|
||||||
|
|
||||||
|
[Sure did!](https://i.imgur.com/59CRzGq.png)
|
||||||
|
|
||||||
|
## Will I get banned from of the stores?
|
||||||
|
|
||||||
|
Perhaps, but it's the risk we're willing to take! To help minimize this, take a look at [#1050](https://github.com/jef/streetmerchant/issues/1050).
|
||||||
|
|
||||||
|
## I got a problem and need help
|
||||||
|
|
||||||
|
File an [issue](https://github.com/jef/streetmerchant/issues/new/choose). I'll do my best to get to you. I work a full time job and this is only a hobby of mine.
|
||||||
|
|
||||||
|
## How do I get the latest code?
|
||||||
|
|
||||||
|
Run the following commands:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git pull origin main
|
||||||
|
npm install
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
|
||||||
|
If you changed the code at all, this will most likely fail. You can clear out your changes by doing:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git checkout .
|
||||||
|
git pull origin main
|
||||||
|
npm install
|
||||||
|
npm run start
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also to [git-stash](https://git-scm.com/docs/git-stash), but we won't expand on that here.
|
||||||
|
|
||||||
|
|
||||||
|
## Why don't my notifications work?
|
||||||
|
|
||||||
|
There is probably an [issue](https://github.com/jef/streetmerchant/issues?q=is%3Aissue+sort%3Aupdated-desc+sound+is%3Aclosed) that has [already](https://github.com/jef/streetmerchant/issues/182) [been](https://github.com/jef/streetmerchant/issues/116) [resolved](https://github.com/jef/streetmerchant/issues/155).
|
||||||
|
|
||||||
|
## I'd love to contribute, how do I do that?
|
||||||
|
|
||||||
|
Make a [pull request](https://github.com/jef/streetmerchant/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)! All contributions are welcome.
|
||||||
|
|
||||||
|
## How do I add a store?
|
||||||
|
|
||||||
|
Here's a little write-up I did: [Adding a store](help/general.md#adding-a-store).
|
||||||
|
|
||||||
|
## Why do I have to download all this stuff just to get this bot working?
|
||||||
|
|
||||||
|
Well, I would rather you didn't either. See [#11](https://github.com/jef/streetmerchant/issues/11).
|
||||||
|
|
||||||
|
## Why does Amazon show an error page (with a picture of an animal) instead of adding to cart or going to the detail page?
|
||||||
|
|
||||||
|
This is intended; see [#733](https://github.com/jef/streetmerchant/issues/733). This indicates that the item is out of stock and only available from a third-party seller (often at a markup).
|
||||||
|
|
||||||
|
## I'm using streetmerchant in the cloud and X isn't working.
|
||||||
|
|
||||||
|
There is _a lot_ of undefined behavior with using streetmerchant in the cloud. Some sites may block IPs from your cloud provider. It is possible that a VPN will help circumvent these problems.
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
# Getting started
|
||||||
|
|
||||||
|
You do not need any computer skills, smarts, or anything of that nature. You are very capable as you have made it this far. Some basic understanding how a terminal, git, and or Node.js is a bonus, but that does not limit you to getting streetmerchant running!
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- [git](https://git-scm.com/)
|
||||||
|
- Either [Node.js 14](https://nodejs.org/en/) or [Docker (1.13.0+)](https://docs.docker.com/get-docker/) (advanced users)
|
||||||
|
|
||||||
|
## Using Node.js
|
||||||
|
|
||||||
|
| Reference | Note |
|
||||||
|
|:---:|---|
|
||||||
|
| tag | Example, `v1.0.0`; stable |
|
||||||
|
| `main` | Latest HEAD; not tagged, could be unstable |
|
||||||
|
|
||||||
|
1. Download [Node.js 14](https://nodejs.org/en/)
|
||||||
|
1. Clone this project `git clone https://github.com/jef/streetmerchant.git`.
|
||||||
|
1. To checkout a particular reference, use `git checkout <ref name>` after cloning.
|
||||||
|
1. Navigate to this project by entering `cd streetmerchant`.
|
||||||
|
1. Run `npm install`.
|
||||||
|
1. Make a copy of `dotenv-example` and name it `dotenv`.
|
||||||
|
1. Edit the `dotenv` file to your liking using a text editor (like [vscode](https://code.visualstudio.com/)).
|
||||||
|
1. Run `npm run start` to start.
|
||||||
|
|
||||||
|
At any point you want the program to stop, use ++ctrl+c++.
|
||||||
|
|
||||||
|
???+ tip
|
||||||
|
Community based help can also be found on the [wiki](https://github.com/jef/streetmerchant/wiki). Feel free to check that out if you're having problems running. If you're still having problems running, you're probably not the first. Make some searches through the [GitHub issues](https://github.com/jef/streetmerchant/issues) before making one.
|
||||||
|
|
||||||
|
## Using Docker
|
||||||
|
|
||||||
|
Available via GitHub Container Registry.
|
||||||
|
|
||||||
|
| Tag | Note |
|
||||||
|
|:---:|---|
|
||||||
|
| `latest` | Latest release; stable |
|
||||||
|
| `nightly` | Latest HEAD each day at midnight UTC; could be unstable |
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# to run docker nightly
|
||||||
|
docker run -it --rm \
|
||||||
|
--env-file ./dotenv \
|
||||||
|
ghcr.io/jef/streetmerchant:nightly
|
||||||
|
|
||||||
|
# to test notifications
|
||||||
|
docker run -it --rm \
|
||||||
|
--env-file ./dotenv \
|
||||||
|
ghcr.io/jef/streetmerchant:nightly test:notification:production
|
||||||
|
```
|
||||||
|
|
||||||
|
See [Developing in docker](#developing-in-docker) for more information
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
To customize streetmerchant, make a copy of `dotenv-example` as `dotenv` and make any changes to your liking. View [Reference](reference/application.md) for more information on variables and their usage.
|
||||||
|
|
||||||
|
???+ tip
|
||||||
|
All environment variables are optional.
|
||||||
|
|
||||||
|
## For developers
|
||||||
|
|
||||||
|
### Developing in Node.js
|
||||||
|
|
||||||
|
The command `npm run start:dev` can be used instead of `npm run start` to automatically restart the project when filesystem changes are detected in the `src/` folder or `dotenv` file.
|
||||||
|
|
||||||
|
Use `npm run lint` to see any linting uses and `npm run lint:fix` to automatically fix the issues it can.
|
||||||
|
|
||||||
|
### Developing in Docker
|
||||||
|
|
||||||
|
#### Prerequisites
|
||||||
|
|
||||||
|
- [Docker (1.13.0+)](https://docs.docker.com/get-docker/)
|
||||||
|
- [GNU Make](https://www.gnu.org/software/make/)
|
||||||
|
- Optional, but increases quality of life
|
||||||
|
- [Docker Compose](https://docs.docker.com/compose/install/)
|
||||||
|
- Depending on your system, you may already have this. Check before installing.
|
||||||
|
|
||||||
|
#### Starting with `docker-compose`
|
||||||
|
|
||||||
|
1. Make a copy of `dotenv-example` and name it `dotenv`.
|
||||||
|
1. Edit the `dotenv` file to your liking using a text editor (like [vscode](https://code.visualstudio.com/)).
|
||||||
|
1. If you're using `make`, you can run `make run` to start and `make stop` to stop.
|
||||||
|
1. There are more options in the `Makefile`, feel free to explore.
|
||||||
|
1. If you do not have `make`, you can run `docker-compose` directly:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# To start
|
||||||
|
# Use `-d` if you want to run in detached mode
|
||||||
|
# Use `--build` if you want to build the image before running (default image is latest in GitHub Container Registry).
|
||||||
|
docker-compose up
|
||||||
|
|
||||||
|
# To break down
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
If you are using `WEB_PORT`, then you will need to add the following to docker-compose:
|
||||||
|
|
||||||
|
```
|
||||||
|
ports:
|
||||||
|
- "<WEB_PORT>:<WEB_PORT>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `<WEB_PORT>` with the value you gave in your `dotenv`.
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
# General
|
||||||
|
|
||||||
|
## Adding a store
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
This is subject to change in the future
|
||||||
|
|
||||||
|
In the following examples, I will be using "NewStore" as the store I'm wanting to add.
|
||||||
|
|
||||||
|
### Creating a store file
|
||||||
|
|
||||||
|
First, create a TypeScript file in `src/store/model`. In this example, I'll create a file named `new-store.ts`. At this point, you can copy and paste any of the other stores and change accordingly.
|
||||||
|
|
||||||
|
#### How to grab a container (aka selector)
|
||||||
|
|
||||||
|
For the containers, what you'll wanna do is use <kbd>F12</kbd> on the site you want to Inspect and click this button
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Hover over the item you want and it should give you the context:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
You can also right-click on any website element and select 'Inspect'. That should also give you the same results.
|
||||||
|
|
||||||
|
Some people will decide to choose a parent element as it can be unique. Like this case!
|
||||||
|
|
||||||
|
I'd rather use `.button.spin-button.prod-ProductCTA--primary.button--primary` instead of `.spin-button-children` as there are probably other elements on the page that are also `.spin-button-children`.
|
||||||
|
|
||||||
|
The reason why we use these selectors anyway is to wait for the webpage to load these specific elements, to help eliminate false positives.
|
||||||
|
|
||||||
|
For easily getting the selector, you can also copy it by right clicking on the tag, Copy > Copy selector.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Updating the models
|
||||||
|
|
||||||
|
You'll now want to add the new store to `src/store/model/index.ts`.
|
||||||
|
|
||||||
|
This is what it will look like:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- a/src/store/model/index.ts
|
||||||
|
+++ b/src/store/model/index.ts
|
||||||
|
@@ -48,6 +48,7 @@ import {MicroCenter} from './microcenter';
|
||||||
|
import {Mindfactory} from './mindfactory';
|
||||||
|
import {Newegg} from './newegg';
|
||||||
|
import {NeweggCa} from './newegg-ca';
|
||||||
|
+import {NewStore} from './new-store';
|
||||||
|
import {Notebooksbilliger} from './notebooksbilliger';
|
||||||
|
import {Novatech} from './novatech';
|
||||||
|
import {Nvidia} from './nvidia';
|
||||||
|
@@ -123,6 +124,7 @@ export const storeList = new Map([
|
||||||
|
[Mindfactory.name, Mindfactory],
|
||||||
|
[Newegg.name, Newegg],
|
||||||
|
[NeweggCa.name, NeweggCa],
|
||||||
|
+ [NewStore.name, NewStore],
|
||||||
|
[Notebooksbilliger.name, Notebooksbilliger],
|
||||||
|
[Novatech.name, Novatech],
|
||||||
|
[Nvidia.name, Nvidia],
|
||||||
|
```
|
||||||
|
|
||||||
|
After that, you're pretty much set. If you plan on adding new models or series, you will have to add them to `src/store/model/store.ts` and `src/config.ts`.
|
||||||
|
|
||||||
|
Here's an example:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- a/src/store/model/store.ts
|
||||||
|
+++ b/src/store/model/store.ts
|
||||||
|
@@ -23,6 +23,7 @@ export type Brand =
|
||||||
|
| 'kfa2'
|
||||||
|
| 'microsoft'
|
||||||
|
| 'msi'
|
||||||
|
+ | 'new brand'
|
||||||
|
| 'nvidia'
|
||||||
|
| 'palit'
|
||||||
|
| 'pny'
|
||||||
|
@@ -37,6 +38,7 @@ export type Series =
|
||||||
|
| '3070'
|
||||||
|
| '3080'
|
||||||
|
| '3090'
|
||||||
|
+ | 'new series'
|
||||||
|
| 'rx6800'
|
||||||
|
| 'rx6800xt'
|
||||||
|
| 'rx6900xt'
|
||||||
|
@@ -83,6 +85,7 @@ export type Model =
|
||||||
|
| 'ichill x2'
|
||||||
|
| 'ichill x3'
|
||||||
|
| 'ichill x4'
|
||||||
|
+ | 'new model'
|
||||||
|
| 'nitro+'
|
||||||
|
| 'nitro oc se'
|
||||||
|
| 'nitro oc'
|
||||||
|
```
|
||||||
|
|
||||||
|
```diff
|
||||||
|
--- a/src/config.ts
|
||||||
|
+++ b/src/config.ts
|
||||||
|
@@ -308,6 +308,7 @@ const store = {
|
||||||
|
country: envOrString(process.env.COUNTRY, 'usa'),
|
||||||
|
maxPrice: {
|
||||||
|
series: {
|
||||||
|
+ 'new series': -1,
|
||||||
|
'3060ti': envOrNumber(process.env.MAX_PRICE_SERIES_3060TI),
|
||||||
|
3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070),
|
||||||
|
3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080),
|
||||||
|
@@ -337,6 +338,7 @@ const store = {
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, [
|
||||||
|
+ 'new series',
|
||||||
|
'3060ti',
|
||||||
|
'3070',
|
||||||
|
'3080',
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
And voila! You're done! If you'd like to contribute to the project, feel free to create a [Pull Request](https://github.com/jef/streetmerchant/compare)! Don't forget to add the store (and brand, model, and series if you added) to the `README.md`.
|
||||||
|
|
||||||
|
???+ tip
|
||||||
|
Here's an [example](https://github.com/jef/streetmerchant/commit/af96c5f2e808af7496f3c3299e4cf173105de48b). If you'd like to include a max price, you can add `MAX_PRICE_SERIES_NEW_SERIES` to the above instead of the `-1`.
|
||||||
|
|
||||||
|
## Creating a Discord webhook
|
||||||
|
|
||||||
|
Take a look at Discord's [Intro to Webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks), that should get you going.
|
||||||
|
|
||||||
|
This is the main portion:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Use the full URL that you just copied and set that value to `DISOCRD_WEB_HOOK`.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Troubleshoot
|
||||||
|
|
||||||
|
## Captcha issues
|
||||||
|
|
||||||
|
### Option 1
|
||||||
|
|
||||||
|
If you're running into problems, try running in headful mode: `HEADLESS="false"`.
|
||||||
|
|
||||||
|
This will open a browser and run streetmerchant. Note that this isn't a great solution for those running in a headless environment, i.e.: VPS, cloud, docker. Instead, it would be a good solution for those running on separate computer that won't be blocked by running in the background.
|
||||||
|
|
||||||
|
### Option 2
|
||||||
|
|
||||||
|
As a last case scenario, use `PUPPETEER_EXECUTABLE_PATH`. This will use your computer's Chrome browser. You can run this is headless or headful mode.
|
||||||
|
|
||||||
|
> From the puppeteer doc:
|
||||||
|
>
|
||||||
|
> `PUPPETEER_EXECUTABLE_PATH` - specify an executable path to be used in `puppeteer.launch`. See [puppeteer.launch([options])](https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#puppeteerlaunchoptions) on how the executable path is inferred. **BEWARE**: Puppeteer is only [guaranteed to work](https://github.com/puppeteer/puppeteer/#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
`dotenv`:
|
||||||
|
|
||||||
|
```
|
||||||
|
PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable
|
||||||
|
```
|
||||||
|
|
||||||
|
This will vary depending on your operating system and install path. Please use full paths.
|
||||||
|
|
||||||
|
## macOS code signing
|
||||||
|
|
||||||
|
If you're getting a popup like this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Then run this command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo codesign --force --deep --sign - ./node_modules/puppeteer/.local-chromium/mac-800071/chrome-mac/Chromium.app
|
||||||
|
```
|
||||||
|
|
||||||
|
???+ tip
|
||||||
|
The `mac-800071` may be different on your machine, so I would start from `./node_modules/puppeteer/.local-chromium` and auto complete from there.
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
[](https://jef.codes/streetmerchant)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
First and foremost, this service _will not_ automatically buy for you.
|
||||||
|
|
||||||
|
- **Checks stock continuously** -- runs 24/7, 365, looking for the items you want.
|
||||||
|
- **Ready for checkout** -- ability to add to cart when available and even opens the browser for you.
|
||||||
|
- **Notifications galore** -- when you're not by your computer, worry free with notifications to most platforms and devices when an item comes in stock.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
You'll find most of the content on the left sidebar. The right sidebar will help you navigate a page.
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
- Give helpful tips and tricks to the [community based wiki](https://github.com/jef/streetmerchant/wiki).
|
||||||
|
- Add to the documentation through [pull requests](https://github.com/jef/streetmerchant/pulls).
|
||||||
|
- Fork and make a pull request to the repository.
|
||||||
|
|
||||||
|
### Looking for help
|
||||||
|
|
||||||
|
- Have an idea, question, or need help? Visit our [GitHub discussion board](https://github.com/jef/streetmerchant/discussions).
|
||||||
|
- Ran into a bug? File a [GitHub issue](https://github.com/jef/streetmerchant/issues/new/choose).
|
||||||
|
- Looking to hang out and talk shop? Join us on [Discord](https://discord.gg/gbVY4vB9JF).
|
||||||
|
|
||||||
|
### Supporting the project
|
||||||
|
|
||||||
|
The best way to support me is to donate to [Diabetes Research Institute](https://www.diabetesresearch.org/Give).
|
||||||
|
|
||||||
|
> The Diabetes Research Institute leads the world in cure-focused diabetes research.
|
||||||
|
>
|
||||||
|
> [diabetesresearch.org](https://www.diabetesresearch.org/about-DRI)
|
||||||
|
|
||||||
|
If you feel inclined to support me directly, here are those options:
|
||||||
|
|
||||||
|
- [GitHub Sponsors](https://github.com/sponsors/jef)
|
||||||
|
- [Paypal](https://www.paypal.me/jxf)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
app.document$.subscribe(function() {
|
||||||
|
var tables = document.querySelectorAll("article table")
|
||||||
|
tables.forEach(function(table) {
|
||||||
|
new Tablesort(table)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Application
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `AUTO_ADD_TO_CART` | Enable auto add to cart on support stores, default: `true` |
|
||||||
|
| `BROWSER_TRUSTED` | Skip Chromium Sandbox. Useful for containerized environments, default: `false` |
|
||||||
|
| `HEADLESS` | Puppeteer to run headless or not. Debugging related, default: `true` |
|
||||||
|
| `INCOGNITO` | Puppeteer to run incognito or not. Debugging related, default: `false` |
|
||||||
|
| `IN_STOCK_WAIT_TIME` | Time to wait between requests to the same link if it has that card in stock. In seconds, default: `0` |
|
||||||
|
| `LOG_LEVEL` | [Logging levels](https://github.com/winstonjs/winston#logging-levels). Debugging related, default: `info` |
|
||||||
|
| `LOW_BANDWIDTH` | Blocks images/fonts to reduce traffic. Disables ad blocker, default: `false` |
|
||||||
|
| `OPEN_BROWSER` | Toggle for whether or not the browser should open when item is found. Default: `true` |
|
||||||
|
| `PAGE_BACKOFF_MIN` | Minimum backoff time between retrying requests for the same store when a forbidden response is received. Default: `10000` |
|
||||||
|
| `PAGE_BACKOFF_MAX` | Maximum backoff time between retrying requests for the same store when a forbidden response is received. Default: `3600000` |
|
||||||
|
| `PAGE_SLEEP_MIN` | Minimum sleep time between queries of the same product page. In milliseconds, default: `5000` |
|
||||||
|
| `PAGE_SLEEP_MAX` | Maximum sleep time between queries of the same product page. In milliseconds, default: `10000` |
|
||||||
|
| `PAGE_TIMEOUT` | Navigation Timeout in milliseconds. `0` for infinite, default: `30000` |
|
||||||
|
| `PROXY_PROTOCOL` | Protocol of proxy server, such as `socks5`. Default: `http` |
|
||||||
|
| `PROXY_ADDRESS` | IP Address or fqdn of proxy server |
|
||||||
|
| `PROXY_PORT` | TCP Port number on which the proxy is listening for connections. Default: `80` |
|
||||||
|
| `SCREENSHOT` | Capture screenshot of page if a card is found. Default: `true` |
|
||||||
|
| `WEB_PORT` | Starts a webserver to be able to control the bot while it is running. Setting this value starts this service. |
|
||||||
|
|
||||||
|
???+ info
|
||||||
|
You can also have a list of proxies that are rotated while searching stores. Proxies can be read from a file named `STORENAME.proxies` in the format of `socks5://username:password@ip`; one per line. In this case, there is no need to use the `PROXY_*` environments.
|
||||||
|
|
||||||
|
???+ tip
|
||||||
|
- You can also have a list of proxies that are rotated while searching stores. Proxies can be read from a file named `STORENAME.proxies` in the format of `socks5://username:password@ip`; one per line.
|
||||||
|
- Data usage is [known to be high](https://github.com/jef/streetmerchant/issues?q=is%3Aissue+sort%3Aupdated-desc+bandwidth). This is expected as the program scrapes many websites in parallel 24/7. To help reduce this, use `LOW_BANDWIDTH="true"`. We are looking into other solutions as well, but is low priority.
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
# Filter
|
||||||
|
|
||||||
|
| Environment variable | Description | Notes |
|
||||||
|
|:---:|---|---|
|
||||||
|
| `COUNTRY` | [Supported country](#supported-countries) you want to be scraped | Only used with `nvidia-api`, default: `usa` |
|
||||||
|
| `MAX_PRICE_SERIES_3060TI` | Maximum price allowed for a match, applies 3060 Ti series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_3070` | Maximum price allowed for a match, applies 3070 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_3080` | Maximum price allowed for a match, applies 3080 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_3090` | Maximum price allowed for a match, applies 3090 series cards (does not apply to these sites: Nvidia, Asus, EVGA) | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - Cards above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_CORSAIR_SF` | Maximum price allowed for a match, applies to Corsair PSUs | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - PSUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_DARKHERO` | Maximum price allowed for a match, applies to ASUS Dark Hero motherboards | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - PSUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_RYZEN5600` | Maximum price allowed for a match, applies AMD 5600 series cpus | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - CPUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_RYZEN5800` | Maximum price allowed for a match, applies AMD 5800 series cpus | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - CPUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_RYZEN5900` | Maximum price allowed for a match, applies AMD 5900 series cpus | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - CPUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_RYZEN5950` | Maximum price allowed for a match, applies AMD 5950 series cpus | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - CPUs above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_SONYPS5C` | Maximum price allowed for a match, applies PS5 console | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - PS5 above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_SONYPS5DE` | Maximum price allowed for a match, applies PS5 digital edition | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - PS5 above `1234` will be skipped. |
|
||||||
|
| `MAX_PRICE_SERIES_TEST` | Maximum price allowed for a match, applies `test:series` | Default: leave empty for no limit, otherwise enter a price (enter whole dollar amounts only, avoid use of: dollar symbols, commas, and periods.) e.g.: `1234` - PS5 above `1234` will be skipped. |
|
||||||
|
| `MICROCENTER_LOCATION` | Specific MicroCenter location(s) to search | Comma separated, e.g.: `marietta,duluth`, default: `web` |
|
||||||
|
| `NVIDIA_ADD_TO_CART_ATTEMPTS` | The maximum number of times the `nvidia-api` add to cart feature will be attempted before failing | Default: `10` |
|
||||||
|
| `NVIDIA_SESSION_TTL` | The time in milliseconds to keep the cart active while using `nvidia-api` | Default: `60000` |
|
||||||
|
| `SHOW_ONLY_BRANDS` | Filter to show specified brands | Comma separated, e.g.: `evga,zotac` |
|
||||||
|
| `SHOW_ONLY_MODELS` | Filter to show specified models | Both supported formats are comma separated <br/><br/>1. Standard E.g.: `founders edition,rog strix` <br/><br/> 2. Advanced E.g: `MODEL:SERIES`, E.g: `founders edition:3090,rog strix` |
|
||||||
|
| `SHOW_ONLY_SERIES` | Filter to show specified series | Comma separated, e.g.: `3080,ryzen5900` |
|
||||||
|
| `STORES` | [Supported stores](#supported-stores) you want to be scraped | Both supported formats are comma separated <br/><br/>1. Standard E.g.: `"nvidia"` <br/><br/> 2. Advanced E.g: `STORE:PAGE_SLEEP_MIN:PAGE_SLEEP_MAX`, E.g: `nvidia:10000:30000` <br/><br/>Default: `nvidia` |
|
||||||
|
|
||||||
|
## Supported stores
|
||||||
|
|
||||||
|
Used with the `STORES` variable.
|
||||||
|
|
||||||
|
| Stores | Country | Environment variable |
|
||||||
|
|---|---|---|
|
||||||
|
| Adorama | US | `adorama`|
|
||||||
|
| Alternate | DE | `alternate`|
|
||||||
|
| Alternate | NL | `alternate-nl`|
|
||||||
|
| Amazon | US | `amazon`|
|
||||||
|
| Amazon | CA | `amazon-ca`|
|
||||||
|
| Amazon | DE | `amazon-de`|
|
||||||
|
| Amazon Warehouse | DE | `amazon-de-warehouse`|
|
||||||
|
| Amazon | ES | `amazon-es`|
|
||||||
|
| Amazon | FR | `amazon-fr`|
|
||||||
|
| Amazon | IT | `amazon-it`|
|
||||||
|
| Amazon | NL | `amazon-nl`|
|
||||||
|
| Amazon | UK | `amazon-uk`|
|
||||||
|
| AMD | US | `amd`|
|
||||||
|
| AMD | CA | `amd-ca`|
|
||||||
|
| AMD | DE | `amd-de`|
|
||||||
|
| AMD | IT | `amd-it`|
|
||||||
|
| AntOnline | US | `antonline`|
|
||||||
|
| Argos | UK | `argos`|
|
||||||
|
| Argos | IE | `argos-ie`|
|
||||||
|
| Aria PC | UK | `aria`|
|
||||||
|
| ARLT | DE | `arlt`|
|
||||||
|
| ASUS | US | `asus` |
|
||||||
|
| ASUS | DE | `asus-de` |
|
||||||
|
| Azerty | NL | `azerty`|
|
||||||
|
| B&H | US | `bandh`|
|
||||||
|
| Best Buy | US | `bestbuy`|
|
||||||
|
| Best Buy | CA | `bestbuy-ca`|
|
||||||
|
| Box | UK | `box`|
|
||||||
|
| BPCTech | AU | `bpctech`|
|
||||||
|
| CanadaComputers | CA | `canadacomputers` |
|
||||||
|
| Caseking | DE | `caseking`|
|
||||||
|
| CCL | UK | `ccl`|
|
||||||
|
| Centrecom | AU | `centrecom`|
|
||||||
|
| Comet | IT | `comet`|
|
||||||
|
| Computeruniverse | DE | `computeruniverse` |
|
||||||
|
| Coolblue | NL | `coolblue`|
|
||||||
|
| Coolmod | ES | `coolmod`|
|
||||||
|
| Corsair | US | `corsair`|
|
||||||
|
| CPL | AU | `cpl`|
|
||||||
|
| Currys | UK | `currys`|
|
||||||
|
| Cyberport | DE | `cyberport` |
|
||||||
|
| EBGames | CA | `ebgames`|
|
||||||
|
| eBuyer | UK | `ebuyer`|
|
||||||
|
| El Corte Inglés | ES | `elcorteingles`|
|
||||||
|
| ePrice | IT | `eprice`|
|
||||||
|
| Euronics | IT | `euronics`|
|
||||||
|
| Euronics | DE | `euronics-de`|
|
||||||
|
| EVGA | US | `evga`|
|
||||||
|
| EVGA | EU | `evga-eu`|
|
||||||
|
| Expert | DE | `expert`|
|
||||||
|
| Galaxus | DE | `galaxus`|
|
||||||
|
| Game | UK | `game`|
|
||||||
|
| Gamestop | US | `gamestop`|
|
||||||
|
| Gamestop | DE | `gamestop-de`|
|
||||||
|
| Gamestop | IE | `gamestop-ie`|
|
||||||
|
| Harvey Normans | IE | | `harveynorman-ie` |
|
||||||
|
| Kabum | BR | `kabum`|
|
||||||
|
| Mediamarkt | DE | `mediamarkt`|
|
||||||
|
| Medimax | DE | `medimax`|
|
||||||
|
| Megekko | NL | `megekko`|
|
||||||
|
| MemoryExpress | CA | `memoryexpress`|
|
||||||
|
| Micro Center | US | `microcenter`|
|
||||||
|
| Mindfactory | DE | `mindfactory` |
|
||||||
|
| Mwave | AU | `mwave`|
|
||||||
|
| Newegg | US | `newegg`|
|
||||||
|
| Newegg | CA | `newegg-ca`|
|
||||||
|
| Notebooksbilliger | DE |`notebooksbilliger`|
|
||||||
|
| Novatech | UK | `novatech`|
|
||||||
|
| Nvidia | US | `nvidia`|
|
||||||
|
| Nvidia API | | `nvidia-api`|
|
||||||
|
| Office Depot | US | `officedepot`|
|
||||||
|
| Otto | DE | `otto`|
|
||||||
|
| Overclockers | UK | `overclockers`|
|
||||||
|
| PCCG | AU | `pccg`|
|
||||||
|
| PCComponentes | ES | `pccomponentes`|
|
||||||
|
| PlayStation | US | `playstation`|
|
||||||
|
| PNY | US | `pny`|
|
||||||
|
| Proshop | DE | `proshop-de`|
|
||||||
|
| Proshop | DK | `proshop-dk`|
|
||||||
|
| Saturn | DE | `saturn`|
|
||||||
|
| Scan | UK | `scan`|
|
||||||
|
| Scorptec | AU | `scorptec`|
|
||||||
|
| Smyths Toys | UK | `smythstoys`|
|
||||||
|
| Smyths Toys | IE | `smythstoys-ie`|
|
||||||
|
| Spielegrotte | DE | `spielegrotte`|
|
||||||
|
| Target | US | `target`|
|
||||||
|
| Tesco | IE | `tesco-ie`|
|
||||||
|
| Toys R Us | US | `toysrus` |
|
||||||
|
| Umart | AU | `umart`|
|
||||||
|
| Unieuro | IT | `unieuro`|
|
||||||
|
| Very | UK | `very`|
|
||||||
|
| Walmart | US | `walmart`|
|
||||||
|
| Walmart | CA | `walmart-ca`|
|
||||||
|
| Wipoid | ES | `wipoid`|
|
||||||
|
| Zotac | US | `zotac`|
|
||||||
|
| TopAchat | GR | `topachat`|
|
||||||
|
|
||||||
|
### Micro Center stores
|
||||||
|
|
||||||
|
Used with the `MICROCENTER_LOCATION` variable.
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
Before using `web`, please review [this issue comment](https://github.com/jef/streetmerchant/issues/442#issuecomment-703297393).
|
||||||
|
|
||||||
|
| | | | |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `brooklyn` | `brentwood` | `cambridge` | `chicago` |
|
||||||
|
| `columbus` | `dallas` | `denver` | `duluth` |
|
||||||
|
| `fairfax` | `flushing` | `houston` | `madison-heights` |
|
||||||
|
| `marietta` | `mayfield-heights` | `north-jersey` | `overland-park` |
|
||||||
|
| `parkville` | `rockville` | `sharonville` | `st-davids` |
|
||||||
|
| `st-louis-park` | `tustin` | `westbury` | `westmont` |
|
||||||
|
| `yonkers` |
|
||||||
|
|
||||||
|
## Supported brands and models
|
||||||
|
|
||||||
|
Used with the `SHOW_ONLY_BRANDS` and `SHOW_ONLY_MODELS` variables.
|
||||||
|
|
||||||
|
| Brand | Model |
|
||||||
|
|:---:|---|
|
||||||
|
| `amd` | `5600x`, `5800x`, `5900x`, `5950x`, `amd reference` |
|
||||||
|
| `asus` | `crosshair viii`, `dual`, `dual oc`, `strix`, `strix oc`, `tuf`, `tuf oc` |
|
||||||
|
| `corsair` | `750 platinum`, `600 platinum` |
|
||||||
|
| `colorful` | `igame advanced oc`, `igame vulcan oc` |
|
||||||
|
| `evga` | `ftw3`, `ftw3 ultra`, `ftw3 ultra hydro copper`, `xc3`, `xc3 black`, `xc3 ultra` |
|
||||||
|
| `gainward` | `phantom gs`, `phoenix`, `phoenix gs`, `phoenix gs oc` |
|
||||||
|
| `gigabyte` | `aorus master`, `aorus xtreme`, `aorus xtreme waterforce`, `aorus xtreme waterforce wb`, `eagle`, `eagle oc`, `gaming`, `gaming oc`, `turbo`, `vision`, `vision oc` |
|
||||||
|
| `galax` | `sg`, `sg oc` |
|
||||||
|
| `inno3d` | `gaming x3`, `ichill x3`, `ichill x4`, `ichill frostbite`, `twin x2 oc` |
|
||||||
|
| `kfa2` | `sg`, `sg oc` |
|
||||||
|
| `leadtek` | `hurricane` |
|
||||||
|
| `microsoft` | `xbox series x`, `xbox series s` |
|
||||||
|
| `msi` | `gaming x trio`, `suprim x`, `ventus 2x oc`, `ventus 3x`, `ventus 3x oc` |
|
||||||
|
| `nvidia` | `founders edition` |
|
||||||
|
| `palit` | `gamerock oc`, `gaming pro`, `gaming pro oc` |
|
||||||
|
| `pny` | `dual fan`, `xlr8 revel`, `xlr8 uprising` |
|
||||||
|
| `sony` | `ps5 console`, `ps5 digital` |
|
||||||
|
| `xfx` | `merc`, `amd reference` |
|
||||||
|
| `zotac` | `amp holo`, `amp extreme holo`, `trinity`, `trinity oc`, `twin edge`, `twin edge oc` |
|
||||||
|
|
||||||
|
## Supported series
|
||||||
|
|
||||||
|
Used with the `SHOW_ONLY_SERIES` variable.
|
||||||
|
|
||||||
|
| Series | Value |
|
||||||
|
|:---:|:---:|
|
||||||
|
| AMD Ryzen 5600x | `ryzen5600` |
|
||||||
|
| AMD Ryzen 5800x | `ryzen5800` |
|
||||||
|
| AMD Ryzen 5900x | `ryzen5900` |
|
||||||
|
| AMD Ryzen 5950x | `ryzen5950` |
|
||||||
|
| AMD RX 6800 | `rx6800` |
|
||||||
|
| AMD RX 6800XT | `rx6800xt` |
|
||||||
|
| AMD RX 6900XT | `rx6900xt` |
|
||||||
|
| Nvidia RTX 3060 Ti | `3060ti` |
|
||||||
|
| Nvidia RTX 3070 | `3070` |
|
||||||
|
| Nvidia RTX 3080 | `3080` |
|
||||||
|
| Nvidia RTX 3090 | `3090` |
|
||||||
|
| Corsair SFX PSU | `sf` |
|
||||||
|
| Crosshair VIII | `darkhero` |
|
||||||
|
| Sony PS5 | `sonyps5c` |
|
||||||
|
| Sony PS5 Digital Edition | `sonyps5de` |
|
||||||
|
| Xbox Series S | `xboxss` |
|
||||||
|
| Xbox Series X | `xboxsx` |
|
||||||
|
|
||||||
|
## Supported countries
|
||||||
|
|
||||||
|
Used with the `COUNTRY` variable.
|
||||||
|
|
||||||
|
???+ attention
|
||||||
|
Used _only_ with `nvidia` and `nvidia-api`.
|
||||||
|
|
||||||
|
| Country | 3080 FE | 3090 FE | Test Card | Notes |
|
||||||
|
|:---:|:---:|:---:|:---:|:---:|
|
||||||
|
| `austria` | `✔` | `✔` | `✔` | |
|
||||||
|
| `belgium` | `✔` | `✔` | `✔` | |
|
||||||
|
| `canada` | `✔` | `✔` | `✔` | |
|
||||||
|
| `czechia` | `✔` | `✔` | `✔` | |
|
||||||
|
| `denmark` | `✔` | | `✔` | Missing RTX 3090 |
|
||||||
|
| `finland` | `✔` | | `✔` | Missing RTX 3090 |
|
||||||
|
| `france` | `✔` | `✔` | `✔` | |
|
||||||
|
| `germany` | `✔` | `✔` | `✔` | |
|
||||||
|
| `great_britain` | `✔` | `✔` | `✔` | |
|
||||||
|
| `ireland` | `✔` | `✔` | `✔` | |
|
||||||
|
| `italy` | `✔` | `✔` | `✔` | |
|
||||||
|
| `luxembourg` | `✔` | `✔` | `✔` | |
|
||||||
|
| `netherlands` | `✔` | `✔` | `✔` | |
|
||||||
|
| `norway` | `✔` | `✔` | `✔` | |
|
||||||
|
| `poland` | `✔` | `✔` | `✔` | |
|
||||||
|
| `portugal` | `✔` | | | RTX 3080 only |
|
||||||
|
| `spain` | `✔` | `✔` | `✔` | |
|
||||||
|
| `sweden` | `✔` | `✔` | `✔` | |
|
||||||
|
| `usa` | `✔` | `✔` | `✔` | |
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
# Notification
|
||||||
|
|
||||||
|
You can test your notification configuration by running `npm run test:notification`.
|
||||||
|
|
||||||
|
## Desktop
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|---|---|
|
||||||
|
| `DESKTOP_NOTIFICATIONS` | Display desktop notifications using [node-notifier](https://www.npmjs.com/package/node-notifier). |
|
||||||
|
| `PLAY_SOUND` | Play this sound notification if a product is found. Relative path accepted, valid formats: wav, mp3, flac, E.g.: `path/to/notification.wav`, [free sounds available](https://notificationsounds.com/) |
|
||||||
|
| `SOUND_PLAYER` | Override the default sound player using the specified executable. |
|
||||||
|
|
||||||
|
???+ attention
|
||||||
|
If you're on Windows, you must have the proper library to run.
|
||||||
|
|
||||||
|
## Discord
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `DISCORD_NOTIFY_GROUP` | Discord group you would like to notify |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_3060TI` | Discord group to notify on 3060 Ti stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_3070` | Discord group to notify on 3070 stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_3080` | Discord group to notify on 3080 stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_3090` | Discord group to notify on 3090 stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_RYZEN5600` | Discord group to notify on 5600X stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_RYZEN5800` | Discord group to notify on 5800X stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_RYZEN5900` | Discord group to notify on 5900X stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_RYZEN5950` | Discord group to notify on 5950X stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_DARKHERO` | Discord group to notify on Dark Hero stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_CORSAIR_SF` | Discord group to notify on Corsair SF stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_SONYPS5C` | Discord group to notify on Sony PS5 stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_SONYPS5DE` | Discord group to notify on Sony PS5 Digital stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_XBOXSX` | Discord group to notify on Xbox Series X stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_XBOXSS` | Discord group to notify on Xbox Series S stock |
|
||||||
|
| `DISCORD_NOTIFY_GROUP_TEST` | Discord group to notify on test stock |
|
||||||
|
| `DISCORD_WEB_HOOK` | Discord Web Hook URL. Can be comma separated. Use whole webhook URL |
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
All ground can be comma separated. `DISCORD_NOTIFY_GROUP` is always used if set.
|
||||||
|
|
||||||
|
- If you're using a role, please use `<@&2834729847239842>`
|
||||||
|
- If you're using a user, please use `<@2834729847239842>`
|
||||||
|
|
||||||
|
## Email and SMS
|
||||||
|
|
||||||
|
Default provider is Gmail. If you use a different email provider, you must provide SMTP settings.
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `EMAIL_PASSWORD` | Email password. (See below for Gmail MFA users) |
|
||||||
|
| `EMAIL_TO` | Destination Email. Defaults to username if not set. Can be comma separated |
|
||||||
|
| `EMAIL_USERNAME` | Email address |
|
||||||
|
| `PHONE_CARRIER` | [Supported carriers](#supported-carriers) for SMS. E.g.: `att` or `att,verizon,google`, email configuration required. If multiple phone numbers are listed, enter a carrier for each phone number |
|
||||||
|
| `PHONE_NUMBER` | 10 digit phone number(s). E.g.: `1234567890` or `1234567890,0987654321,11112223333`, email configuration required |
|
||||||
|
| `SMTP_ADDRESS` | IP Address or FQDN of SMTP server |
|
||||||
|
| `SMTP_PORT` | TCP Port number on which the smtp server is listening for connections. Default: `25` |
|
||||||
|
|
||||||
|
???+ attention
|
||||||
|
If you use Gmail and have multi-factor authentication (MFA), you will need to create an [app password](https://myaccount.google.com/apppasswords) and use this instead of your Gmail password.
|
||||||
|
|
||||||
|
### Supported carriers
|
||||||
|
|
||||||
|
| Carrier | Environment variable |
|
||||||
|
|:---:|:---:|
|
||||||
|
| AT&T | `att` |
|
||||||
|
| AT&T Prepaid | `attgo` |
|
||||||
|
| Bell | `bell` |
|
||||||
|
| Fido | `fido` |
|
||||||
|
| Google | `google`|
|
||||||
|
| Koodo | `koodo` |
|
||||||
|
| Mint | `mint`|
|
||||||
|
| Rogers | `rogers` |
|
||||||
|
| Sprint | `sprint`|
|
||||||
|
| Telus | `telus`|
|
||||||
|
| T-Mobile | `tmobile`|
|
||||||
|
| Verizon | `verizon`|
|
||||||
|
| Virgin | `virgin`|
|
||||||
|
| Virgin (CA) | `virgin-ca`|
|
||||||
|
| Visible | `visible`|
|
||||||
|
|
||||||
|
## MQTT
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `MQTT_BROKER_ADDRESS` | IP address or URL of MQTT Broker, e.g.: `192.168.1.xxx` or `broker.hivemq.com` |
|
||||||
|
| `MQTT_BROKER_PORT` | Network port of MQTT Broker. Default: `1883` |
|
||||||
|
| `MQTT_CLIENT_ID` | Unique Client ID (only if required by MQTT Broker), typically not required when only publishing alerts |
|
||||||
|
| `MQTT_PASSWORD` | MQTT password - only use with MQTT brokers on private networks, if required. Will not be sent over public networks for safety |
|
||||||
|
| `MQTT_QOS` | QoS level for published alerts to broker (https://www.npmjs.com/package/mqtt#about-qos). Default: `0`, Can be `0`, `1`, or `2` |
|
||||||
|
| `MQTT_TOPIC` | Topic to publish alerts to. Can include `%store%`, `%series%`, `%brand%`, `%model%` for dynamic topics. Default: `streetmerchant/alert`. E.g.: `nv-alert/%store%/%series%/%brand%/%model%/alert` |
|
||||||
|
| `MQTT_USERNAME` | MQTT username - (only if required by MQTT Broker) |
|
||||||
|
|
||||||
|
## PagerDuty
|
||||||
|
|
||||||
|
Obtained in PagerDuty - <Service you want to use> - Integrations
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `PAGERDUTY_INTEGRATION_KEY` | PagerDuty Events API v2 Integration Key. |
|
||||||
|
| `PAGERDUTY_SEVERITY` | Severity of PagerDuty events |
|
||||||
|
|
||||||
|
## Philips Hue
|
||||||
|
|
||||||
|
Generate required keys using [instructions](https://developers.meethue.com/develop/get-started-2/). This will be used for both LAN and cloud access over the official Remote Hue API.
|
||||||
|
|
||||||
|
For cloud only usage, instructions to generate are located [here](https://developers.meethue.com/develop/hue-api/remote-authentication/).
|
||||||
|
|
||||||
|
> :point_right: Here's a [video demonstration](https://vimeo.com/476083242).
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `PHILIPS_HUE_API_KEY` | Hue Bridge API Key |
|
||||||
|
| `PHILIPS_HUE_LAN_BRIDGE_IP` | LAN IP Address of your Hue Bridge. LAN only, e.g. `192.168.x.x` |
|
||||||
|
| `PHILIPS_HUE_LIGHT_IDS` | Light IDs. All lights if not supplied. Can be comma separated, e.g.: `1,2`. See Hue App -> About for IDs |
|
||||||
|
| `PHILIPS_HUE_LIGHT_COLOR` | Color in RGB Format. Nvidia green if not supplied. Can be comma separated, e.g.: `255,255,255` |
|
||||||
|
| `PHILIPS_HUE_LIGHT_PATTERN` | Lights will flash for 30 seconds if `blink` is given |
|
||||||
|
| `PHILIPS_HUE_CLOUD_ACCESS_TOKEN` | Cloud Access Token. Cloud only |
|
||||||
|
| `PHILIPS_HUE_CLOUD_REFRESH_TOKEN` | Cloud Refresh Token. Cloud only |
|
||||||
|
| `PHILIPS_HUE_CLOUD_CLIENT_ID` | Cloud Client ID. Cloud only |
|
||||||
|
| `PHILIPS_HUE_CLOUD_CLIENT_SECRET` | Cloud Client Secret. Cloud only |
|
||||||
|
|
||||||
|
## Pushbullet
|
||||||
|
|
||||||
|
Generate token at https://www.pushbullet.com/#settings/account.
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `PUSHBULLET` | API key |
|
||||||
|
|
||||||
|
## Pushover
|
||||||
|
|
||||||
|
Generate token at https://pushover.net/apps/build.
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `PUSHOVER_EXPIRE` | How many seconds your notification will continue to be retried for (every `PUSHOVER_RETRY` seconds) |
|
||||||
|
| `PUSHOVER_RETRY` | How often (in seconds) the Pushover servers will send the same notification to the user |
|
||||||
|
| `PUSHOVER_PRIORITY` | Message priority |
|
||||||
|
| `PUSHOVER_TOKEN` | API token |
|
||||||
|
| `PUSHOVER_USER` | Username |
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
`PUSHOVER_EXPIRE` and `PUSHOVER_RETRY` are only used when `PUSHOVER_PRIORITY="2"`
|
||||||
|
|
||||||
|
## Slack
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `SLACK_CHANNEL` | Channel for posting |
|
||||||
|
| `SLACK_TOKEN` | API token |
|
||||||
|
|
||||||
|
## Telegram
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `TELEGRAM_ACCESS_TOKEN` | Access token |
|
||||||
|
| `TELEGRAM_CHAT_ID` | Chat ID. Can be comma separated, e.g.: `123456789,987654321` |
|
||||||
|
|
||||||
|
## Twilio
|
||||||
|
|
||||||
|
Token generation can be found at https://twilio.com/console.
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `TWILIO_ACCOUNT_SID` | Account SID |
|
||||||
|
| `TWILIO_AUTH_TOKEN` | Auth Token |
|
||||||
|
| `TWILIO_FROM_NUMBER` | Provided phone number to send messages from |
|
||||||
|
| `TWILIO_TO_NUMBER` | Mobile number to send SMS to |
|
||||||
|
|
||||||
|
???+ note
|
||||||
|
Include country codes in phone numbers. Example: `+4401234567890`
|
||||||
|
|
||||||
|
## Twitter
|
||||||
|
|
||||||
|
Generate all Twitter keys at: https://developer.twitter.com/
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `TWITTER_ACCESS_TOKEN_KEY` | Twitter Token Key |
|
||||||
|
| `TWITTER_ACCESS_TOKEN_SECRET` | Twitter Token Secret |
|
||||||
|
| `TWITTER_CONSUMER_KEY` | Twitter Consumer Key |
|
||||||
|
| `TWITTER_CONSUMER_SECRET` | Twitter Consumer Secret |
|
||||||
|
| `TWITTER_TWEET_TAGS` | List of hashtags to append to the tweet message, e.g.: `#nvidia #nvidiastock` |
|
||||||
|
|
||||||
|
## Twitch
|
||||||
|
|
||||||
|
| Environment variable | Description |
|
||||||
|
|:---:|---|
|
||||||
|
| `TWITCH_CLIENT_ID` | Twitch client ID |
|
||||||
|
| `TWITCH_CLIENT_SECRET`| Twitch client secret |
|
||||||
|
| `TWITCH_ACCESS_TOKEN` | Twitch access token |
|
||||||
|
| `TWITCH_REFRESH_TOKEN` | Twitch refresh token |
|
||||||
|
| `TWITCH_CHANNEL` | Twitch channel |
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
# ** All configuration variables are optional **
|
||||||
|
# Copy this file and name it as `dotenv` (without backticks)
|
||||||
|
# Read https://jef.codes/streetmerchant/getting-started/#customization for help on customizing this file
|
||||||
|
########################################################################################################
|
||||||
|
|
||||||
|
ASCII_BANNER=
|
||||||
|
ASCII_COLOR=
|
||||||
|
AUTO_ADD_TO_CART=
|
||||||
|
BROWSER_TRUSTED=
|
||||||
|
COUNTRY=
|
||||||
|
DESKTOP_NOTIFICATIONS=
|
||||||
|
DISCORD_NOTIFY_GROUP=
|
||||||
|
DISCORD_NOTIFY_GROUP_3060TI=
|
||||||
|
DISCORD_NOTIFY_GROUP_3070=
|
||||||
|
DISCORD_NOTIFY_GROUP_3080=
|
||||||
|
DISCORD_NOTIFY_GROUP_3090=
|
||||||
|
DISCORD_NOTIFY_GROUP_CORSAIR_SF=
|
||||||
|
DISCORD_NOTIFY_GROUP_RX6800=
|
||||||
|
DISCORD_NOTIFY_GROUP_RX6800XT=
|
||||||
|
DISCORD_NOTIFY_GROUP_RX6900XT=
|
||||||
|
DISCORD_NOTIFY_GROUP_RYZEN5600=
|
||||||
|
DISCORD_NOTIFY_GROUP_RYZEN5800=
|
||||||
|
DISCORD_NOTIFY_GROUP_RYZEN5900=
|
||||||
|
DISCORD_NOTIFY_GROUP_RYZEN5950=
|
||||||
|
DISCORD_NOTIFY_GROUP_SONYPS5C=
|
||||||
|
DISCORD_NOTIFY_GROUP_SONYPS5DE=
|
||||||
|
DISCORD_NOTIFY_GROUP_XBOXSX=
|
||||||
|
DISCORD_NOTIFY_GROUP_XBOXSS=
|
||||||
|
DISCORD_NOTIFY_GROUP_TEST=
|
||||||
|
DISCORD_WEB_HOOK=
|
||||||
|
EMAIL_PASSWORD=
|
||||||
|
EMAIL_TO=
|
||||||
|
EMAIL_USERNAME=
|
||||||
|
HEADLESS=
|
||||||
|
IN_STOCK_WAIT_TIME=
|
||||||
|
LOG_LEVEL=
|
||||||
|
LOW_BANDWIDTH=
|
||||||
|
MAX_PRICE_SERIES_3060TI=
|
||||||
|
MAX_PRICE_SERIES_3070=
|
||||||
|
MAX_PRICE_SERIES_3080=
|
||||||
|
MAX_PRICE_SERIES_3090=
|
||||||
|
MAX_PRICE_SERIES_CORSAIR_SF=
|
||||||
|
MAX_PRICE_SERIES_RX6800=
|
||||||
|
MAX_PRICE_SERIES_RX6800XT=
|
||||||
|
MAX_PRICE_SERIES_RX6900XT=
|
||||||
|
MAX_PRICE_SERIES_RYZEN5600=
|
||||||
|
MAX_PRICE_SERIES_RYZEN5800=
|
||||||
|
MAX_PRICE_SERIES_RYZEN5900=
|
||||||
|
MAX_PRICE_SERIES_RYZEN5950=
|
||||||
|
MAX_PRICE_SERIES_SONYPS5C=
|
||||||
|
MAX_PRICE_SERIES_SONYPS5DE=
|
||||||
|
MAX_PRICE_SERIES_TEST=
|
||||||
|
MICROCENTER_LOCATION=
|
||||||
|
MQTT_BROKER_ADDRESS=
|
||||||
|
MQTT_BROKER_PORT=
|
||||||
|
MQTT_CLIENT_ID=
|
||||||
|
MQTT_PASSWORD=
|
||||||
|
MQTT_QOS=
|
||||||
|
MQTT_TOPIC=
|
||||||
|
MQTT_USERNAME=
|
||||||
|
NVIDIA_ADD_TO_CART_ATTEMPTS=
|
||||||
|
NVIDIA_SESSION_TTL=
|
||||||
|
OPEN_BROWSER=
|
||||||
|
PAGE_BACKOFF_MIN=
|
||||||
|
PAGE_BACKOFF_MAX=
|
||||||
|
PAGE_SLEEP_MIN=
|
||||||
|
PAGE_SLEEP_MAX=
|
||||||
|
PAGE_TIMEOUT=
|
||||||
|
PAGERDUTY_INTEGRATION_KEY=
|
||||||
|
PAGERDUTY_SEVERITY=
|
||||||
|
PHILIPS_HUE_API_KEY=
|
||||||
|
PHILIPS_HUE_CLOUD_ACCESS_TOKEN=
|
||||||
|
PHILIPS_HUE_CLOUD_CLIENT_ID=
|
||||||
|
PHILIPS_HUE_CLOUD_CLIENT_SECRET=
|
||||||
|
PHILIPS_HUE_CLOUD_REFRESH_TOKEN=
|
||||||
|
PHILIPS_HUE_LAN_BRIDGE_IP=
|
||||||
|
PHILIPS_HUE_LIGHT_COLOR=
|
||||||
|
PHILIPS_HUE_LIGHT_IDS=
|
||||||
|
PHILIPS_HUE_LIGHT_PATTERN=
|
||||||
|
PHONE_CARRIER=
|
||||||
|
PHONE_NUMBER=
|
||||||
|
PLAY_SOUND=
|
||||||
|
PROXY_ADDRESS=
|
||||||
|
PROXY_PROTOCOL=
|
||||||
|
PROXY_PORT=
|
||||||
|
PUSHBULLET=
|
||||||
|
PUSHOVER_EXPIRE=
|
||||||
|
PUSHOVER_RETRY=
|
||||||
|
PUSHOVER_TOKEN=
|
||||||
|
PUSHOVER_USER=
|
||||||
|
PUSHOVER_PRIORITY=
|
||||||
|
SCREENSHOT=
|
||||||
|
SHOW_ONLY_BRANDS=
|
||||||
|
SHOW_ONLY_MODELS=
|
||||||
|
SHOW_ONLY_SERIES=
|
||||||
|
SLACK_CHANNEL=
|
||||||
|
SLACK_TOKEN=
|
||||||
|
SMTP_ADDRESS=
|
||||||
|
SMTP_PORT=
|
||||||
|
STORES=
|
||||||
|
TELEGRAM_ACCESS_TOKEN=
|
||||||
|
TELEGRAM_CHAT_ID=
|
||||||
|
TWILIO_ACCOUNT_SID=
|
||||||
|
TWILIO_AUTH_TOKEN=
|
||||||
|
TWILIO_FROM_NUMBER=
|
||||||
|
TWILIO_TO_NUMBER=
|
||||||
|
TWITCH_ACCESS_TOKEN=
|
||||||
|
TWITCH_CHANNEL=
|
||||||
|
TWITCH_CLIENT_ID=
|
||||||
|
TWITCH_CLIENT_SECRET=
|
||||||
|
TWITCH_REFRESH_TOKEN=
|
||||||
|
TWITTER_ACCESS_TOKEN_KEY=
|
||||||
|
TWITTER_ACCESS_TOKEN_SECRET=
|
||||||
|
TWITTER_CONSUMER_KEY=
|
||||||
|
TWITTER_CONSUMER_SECRET=
|
||||||
|
TWITTER_TWEET_TAGS=
|
||||||
|
WEB_PORT=
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 149 KiB |
+91
@@ -0,0 +1,91 @@
|
|||||||
|
# Project information
|
||||||
|
site_name: streetmerchant
|
||||||
|
site_url: https://jef.codes/streetmerchant
|
||||||
|
site_author: Jef LeCompte
|
||||||
|
site_description: The world's easiest, most powerful stock checker
|
||||||
|
|
||||||
|
# Repository
|
||||||
|
repo_name: jef/streetmerchant
|
||||||
|
repo_url: https://github.com/jef/streetmerchant
|
||||||
|
|
||||||
|
# Copyright
|
||||||
|
copyright: Copyright © 2016 - 2020 Jef LeCompte
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
theme:
|
||||||
|
favicon: https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-logo.png
|
||||||
|
features:
|
||||||
|
- search.suggest
|
||||||
|
font:
|
||||||
|
text: Noto Sans
|
||||||
|
code: JetBrains Mono
|
||||||
|
icon:
|
||||||
|
repo: octicons/octoface-24
|
||||||
|
logo: assets/images/streetmerchant-logo.png
|
||||||
|
language: en
|
||||||
|
name: material
|
||||||
|
palette:
|
||||||
|
scheme: default
|
||||||
|
primary: indigo
|
||||||
|
accent: indigo
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
plugins:
|
||||||
|
- git-revision-date
|
||||||
|
- macros
|
||||||
|
- search
|
||||||
|
|
||||||
|
# Customization
|
||||||
|
extra:
|
||||||
|
social:
|
||||||
|
- icon: fontawesome/brands/github
|
||||||
|
link: https://github.com/jef
|
||||||
|
- icon: fontawesome/brands/twitter
|
||||||
|
link: https://twitter.com/hijxf
|
||||||
|
- icon: fontawesome/brands/linkedin
|
||||||
|
link: https://www.linkedin.com/in/jeflecompte/
|
||||||
|
|
||||||
|
extra_javascript:
|
||||||
|
- https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js
|
||||||
|
- javascripts/tables.js
|
||||||
|
|
||||||
|
# Extensions
|
||||||
|
markdown_extensions:
|
||||||
|
- admonition
|
||||||
|
- attr_list
|
||||||
|
- footnotes
|
||||||
|
- meta
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
- pymdownx.caret
|
||||||
|
- pymdownx.critic
|
||||||
|
- pymdownx.details
|
||||||
|
- pymdownx.emoji:
|
||||||
|
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||||
|
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||||
|
- pymdownx.highlight:
|
||||||
|
linenums: true
|
||||||
|
- pymdownx.inlinehilite
|
||||||
|
- pymdownx.keys
|
||||||
|
- pymdownx.mark
|
||||||
|
- pymdownx.smartsymbols
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.tabbed
|
||||||
|
- pymdownx.tasklist:
|
||||||
|
custom_checkbox: true
|
||||||
|
- pymdownx.tilde
|
||||||
|
|
||||||
|
# Page tree
|
||||||
|
nav:
|
||||||
|
- Home: index.md
|
||||||
|
- Getting started: getting-started.md
|
||||||
|
- Reference:
|
||||||
|
- Application: reference/application.md
|
||||||
|
- Filter: reference/filter.md
|
||||||
|
- Notification: reference/notification.md
|
||||||
|
- Help:
|
||||||
|
- General: help/general.md
|
||||||
|
- Troubleshoot: help/troubleshoot.md
|
||||||
|
- FAQ: faq.md
|
||||||
|
- Changelog: changelog.md
|
||||||
|
- About: about.md
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"exec": "ts-node --files ./src/index",
|
||||||
|
"ext": "ts",
|
||||||
|
"watch": [
|
||||||
|
"src/",
|
||||||
|
"dotenv"
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
+5549
-1392
File diff suppressed because it is too large
Load Diff
+45
-28
@@ -1,67 +1,84 @@
|
|||||||
{
|
{
|
||||||
"name": "nvidia-snatcher",
|
"name": "streetmerchant",
|
||||||
"version": "1.5.0",
|
|
||||||
"description": "🔮 For all your Nvidia needs",
|
"description": "🔮 For all your Nvidia needs",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rimraf ./build && tsc",
|
"all": "npm run build && npm run lint",
|
||||||
|
"build": "tsc",
|
||||||
"lint": "xo",
|
"lint": "xo",
|
||||||
"lint:fix": "xo --fix",
|
"lint:fix": "xo --fix",
|
||||||
"start": "npm run build && node build/index.js",
|
"start": "npm run build && node build/index.js",
|
||||||
"test:notification": "npm run build && node build/__test__/notification-test.js"
|
"start:dev": "nodemon --config nodemon.json",
|
||||||
|
"start:production": "node build/index.js",
|
||||||
|
"test:notification": "npm run build && node build/__test__/notification-test.js",
|
||||||
|
"test:notification:production": "node build/__test__/notification-test.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/jef/nvidia-snatcher.git"
|
"url": "git+https://github.com/jef/streetmerchant.git"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "jef",
|
"author": "jef",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/jef/nvidia-snatcher/issues"
|
"url": "https://github.com/jef/streetmerchant/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/jef/nvidia-snatcher#readme",
|
"homepage": "https://github.com/jef/streetmerchant#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@jef/pushbullet": "^2.4.3",
|
||||||
|
"@slack/web-api": "^5.14.0",
|
||||||
|
"@types/random-useragent": "^0.3.0",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
|
"cheerio": "^1.0.0-rc.3",
|
||||||
|
"discord.js": "^12.5.1",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"messaging-api-telegram": "^1.0.1",
|
"messaging-api-telegram": "^1.0.1",
|
||||||
|
"mqtt": "^4.2.6",
|
||||||
|
"node-fetch": "^2.6.1",
|
||||||
|
"node-hue-api": "^4.0.9",
|
||||||
"node-notifier": "^8.0.0",
|
"node-notifier": "^8.0.0",
|
||||||
"nodemailer": "^6.4.11",
|
"node-pagerduty": "^1.3.6",
|
||||||
"open": "^7.2.1",
|
"nodemailer": "^6.4.16",
|
||||||
"puppeteer": "^5.3.1",
|
"open": "^7.3.0",
|
||||||
|
"play-sound": "^1.1.3",
|
||||||
|
"puppeteer": "^5.5.0",
|
||||||
"puppeteer-extra": "^3.1.15",
|
"puppeteer-extra": "^3.1.15",
|
||||||
"puppeteer-extra-plugin-adblocker": "^2.11.6",
|
"puppeteer-extra-plugin-adblocker": "^2.11.9",
|
||||||
"puppeteer-extra-plugin-stealth": "^2.6.1",
|
"puppeteer-extra-plugin-block-resources": "^2.2.7",
|
||||||
"pushbullet": "^2.4.0",
|
"puppeteer-extra-plugin-stealth": "^2.6.5",
|
||||||
|
"puppeteer-page-proxy": "^1.2.8",
|
||||||
"pushover-notifications": "^1.2.2",
|
"pushover-notifications": "^1.2.2",
|
||||||
|
"random-useragent": "^0.5.0",
|
||||||
|
"twilio": "^3.54.0",
|
||||||
|
"twitch": "^4.3.5",
|
||||||
|
"twitch-auth": "^4.3.5",
|
||||||
|
"twitch-chat-client": "^4.3.6",
|
||||||
"twitter": "^1.7.1",
|
"twitter": "^1.7.1",
|
||||||
"winston": "^3.3.3"
|
"winston": "^3.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@slack/web-api": "^5.12.0",
|
"@types/async": "^3.2.5",
|
||||||
"@types/async": "^3.2.3",
|
"@types/cheerio": "^0.22.23",
|
||||||
"@types/node": "^14.11.2",
|
"@types/node": "^14.14.12",
|
||||||
|
"@types/node-fetch": "^2.5.7",
|
||||||
"@types/node-notifier": "^8.0.0",
|
"@types/node-notifier": "^8.0.0",
|
||||||
"@types/nodemailer": "^6.4.0",
|
"@types/nodemailer": "^6.4.0",
|
||||||
"@types/puppeteer": "^3.0.2",
|
"@types/puppeteer": "^5.4.2",
|
||||||
"@types/twitter": "^1.7.0",
|
"@types/twitter": "^1.7.0",
|
||||||
"discord-webhook-node": "^1.1.8",
|
"nodemon": "^2.0.6",
|
||||||
"husky": "^4.3.0",
|
"ts-node": "^9.1.1",
|
||||||
"play-sound": "^1.1.3",
|
"typescript": "^4.1.2",
|
||||||
"rimraf": "^3.0.2",
|
"webpack": "^5.10.0",
|
||||||
"typescript": "^4.0.2",
|
"xo": "^0.36.1"
|
||||||
"xo": "^0.33.1"
|
|
||||||
},
|
},
|
||||||
"xo": {
|
"xo": {
|
||||||
|
"prettier": true,
|
||||||
|
"ignores": "docs/javascripts",
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"no-warning-comments": "off",
|
||||||
"sort-imports": "error",
|
"sort-imports": "error",
|
||||||
"sort-keys": "error",
|
"sort-keys": "error",
|
||||||
"sort-vars": "error"
|
"sort-vars": "error"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"pre-commit": "npm run lint"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ const link: Link = {
|
|||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
cartUrl: 'https://www.example.com/cartUrl',
|
cartUrl: 'https://www.example.com/cartUrl',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
|
price: 100,
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.example.com/url'
|
url: 'https://www.example.com/url'
|
||||||
};
|
};
|
||||||
|
|
||||||
const store: Store = {
|
const store: Store = {
|
||||||
|
currency: '',
|
||||||
labels: {
|
labels: {
|
||||||
inStock: {
|
inStock: {
|
||||||
container: 'test:container',
|
container: 'test:container',
|
||||||
|
|||||||
@@ -5,7 +5,20 @@ export const adBlocker = new PuppeteerExtraPluginAdblocker({
|
|||||||
blockTrackers: true
|
blockTrackers: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export async function enableBlockerInPage(page: Page) {
|
||||||
|
const blockerObject = await adBlocker.getBlocker();
|
||||||
|
if (blockerObject.isBlockingEnabled(page)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await blockerObject.enableBlockingInPage(page);
|
||||||
|
}
|
||||||
|
|
||||||
export async function disableBlockerInPage(page: Page) {
|
export async function disableBlockerInPage(page: Page) {
|
||||||
const blockerObject = await adBlocker.getBlocker();
|
const blockerObject = await adBlocker.getBlocker();
|
||||||
|
if (!blockerObject.isBlockingEnabled(page)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await blockerObject.disableBlockingInPage(page);
|
await blockerObject.disableBlockingInPage(page);
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-10
@@ -1,12 +1,25 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import {readFileSync} from 'fs';
|
||||||
|
|
||||||
export const banner = chalk.green.bold(`
|
const version = readFileSync('version.txt', 'utf8');
|
||||||
$$\\ $$\\ $$\\ $$\\ $$\\
|
|
||||||
\\__| $$ |\\__| $$ | $$ |
|
export const banner = {
|
||||||
$$$$$$$\\ $$\\ $$\\ $$\\ $$$$$$$ |$$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$$$$$\\ $$$$$$\\
|
asciiVersion: `
|
||||||
$$ __$$\\\\$$\\ $$ |$$ |$$ __$$ |$$ | \\____$$\\ $$$$$$\\ $$ _____|$$ __$$\\ \\____$$\\\\_$$ _| $$ _____|$$ __$$\\ $$ __$$\\ $$ __$$\\
|
██████ ▄▄▄█████▓ ██▀███ ▓█████ ▓█████▄▄▄█████▓ ███▄ ▄███▓▓█████ ██▀███ ▄████▄ ██░ ██ ▄▄▄ ███▄ █ ▄▄▄█████▓
|
||||||
$$ | $$ |\\$$\\$$ / $$ |$$ / $$ |$$ | $$$$$$$ |\\______|\\$$$$$$\\ $$ | $$ | $$$$$$$ | $$ | $$ / $$ | $$ |$$$$$$$$ |$$ | \\__|
|
▒██ ▒ ▓ ██▒ ▓▒▓██ ▒ ██▒▓█ ▀ ▓█ ▀▓ ██▒ ▓▒▓██▒▀█▀ ██▒▓█ ▀ ▓██ ▒ ██▒▒██▀ ▀█ ▓██░ ██▒▒████▄ ██ ▀█ █ ▓ ██▒ ▓▒
|
||||||
$$ | $$ | \\$$$ / $$ |$$ | $$ |$$ |$$ __$$ | \\____$$\\ $$ | $$ |$$ __$$ | $$ |$$\\ $$ | $$ | $$ |$$ ____|$$ |
|
░ ▓██▄ ▒ ▓██░ ▒░▓██ ░▄█ ▒▒███ ▒███ ▒ ▓██░ ▒░▓██ ▓██░▒███ ▓██ ░▄█ ▒▒▓█ ▄ ▒██▀▀██░▒██ ▀█▄ ▓██ ▀█ ██▒▒ ▓██░ ▒░
|
||||||
$$ | $$ | \\$ / $$ |\\$$$$$$$ |$$ |\\$$$$$$$ | $$$$$$$ |$$ | $$ |\\$$$$$$$ | \\$$$$ |\\$$$$$$$\\ $$ | $$ |\\$$$$$$$\\ $$ |
|
▒ ██▒░ ▓██▓ ░ ▒██▀▀█▄ ▒▓█ ▄ ▒▓█ ▄░ ▓██▓ ░ ▒██ ▒██ ▒▓█ ▄ ▒██▀▀█▄ ▒▓▓▄ ▄██▒░▓█ ░██ ░██▄▄▄▄██ ▓██▒ ▐▌██▒░ ▓██▓ ░
|
||||||
\\__| \\__| \\_/ \\__| \\_______|\\__| \\_______| \\_______/ \\__| \\__| \\_______| \\____/ \\_______|\\__| \\__| \\_______|\\__|
|
▒██████▒▒ ▒██▒ ░ ░██▓ ▒██▒░▒████▒░▒████▒ ▒██▒ ░ ▒██▒ ░██▒░▒████▒░██▓ ▒██▒▒ ▓███▀ ░░▓█▒░██▓ ▓█ ▓██▒▒██░ ▓██░ ▒██▒ ░
|
||||||
`);
|
▒ ▒▓▒ ▒ ░ ▒ ░░ ░ ▒▓ ░▒▓░░░ ▒░ ░░░ ▒░ ░ ▒ ░░ ░ ▒░ ░ ░░░ ▒░ ░░ ▒▓ ░▒▓░░ ░▒ ▒ ░ ▒ ░░▒░▒ ▒▒ ▓▒█░░ ▒░ ▒ ▒ ▒ ░░
|
||||||
|
░ ░▒ ░ ░ ░ ░▒ ░ ▒░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░▒ ░ ▒░ ░ ▒ ▒ ░▒░ ░ ▒ ▒▒ ░░ ░░ ░ ▒░ ░
|
||||||
|
░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░░ ░ ░ ▒ ░ ░ ░ ░
|
||||||
|
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
|
||||||
|
${version}`,
|
||||||
|
render(ascii: boolean, hexColor: string) {
|
||||||
|
return chalk
|
||||||
|
.hex(hexColor)
|
||||||
|
.bold(ascii ? this.asciiVersion : this.stringVersion);
|
||||||
|
},
|
||||||
|
stringVersion: `STREETMERCHANT
|
||||||
|
${version}`
|
||||||
|
};
|
||||||
|
|||||||
+327
-30
@@ -1,10 +1,20 @@
|
|||||||
|
import {existsSync, readFileSync} from 'fs';
|
||||||
import {banner} from './banner';
|
import {banner} from './banner';
|
||||||
console.log(banner);
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
import {config} from 'dotenv';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
config({path: path.resolve(__dirname, '../.env')});
|
if (existsSync(path.resolve(__dirname, '../dotenv'))) {
|
||||||
|
dotenv.config({path: path.resolve(__dirname, '../dotenv')});
|
||||||
|
} else {
|
||||||
|
dotenv.config({path: path.resolve(__dirname, '../.env')});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info(
|
||||||
|
banner.render(
|
||||||
|
envOrBoolean(process.env.ASCII_BANNER, false),
|
||||||
|
envOrString(process.env.BANNER_COLOR, '#808080')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns environment variable, given array, or default array.
|
* Returns environment variable, given array, or default array.
|
||||||
@@ -12,8 +22,16 @@ config({path: path.resolve(__dirname, '../.env')});
|
|||||||
* @param environment Interested environment variable.
|
* @param environment Interested environment variable.
|
||||||
* @param array Default array. If not set, is `[]`.
|
* @param array Default array. If not set, is `[]`.
|
||||||
*/
|
*/
|
||||||
function envOrArray(environment: string | undefined, array?: string[]): string[] {
|
function envOrArray(
|
||||||
return environment ? environment.split(',') : (array ?? []);
|
environment: string | undefined,
|
||||||
|
array?: string[]
|
||||||
|
): string[] {
|
||||||
|
return (environment
|
||||||
|
? environment.includes('\n')
|
||||||
|
? environment.split('\n')
|
||||||
|
: environment.split(',')
|
||||||
|
: array ?? []
|
||||||
|
).map((s) => s.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,8 +40,11 @@ function envOrArray(environment: string | undefined, array?: string[]): string[]
|
|||||||
* @param environment Interested environment variable.
|
* @param environment Interested environment variable.
|
||||||
* @param boolean Default boolean. If not set, is `true`.
|
* @param boolean Default boolean. If not set, is `true`.
|
||||||
*/
|
*/
|
||||||
function envOrBoolean(environment: string | undefined, boolean?: boolean): boolean {
|
function envOrBoolean(
|
||||||
return environment ? environment === 'true' : (boolean ?? true);
|
environment: string | undefined,
|
||||||
|
boolean?: boolean
|
||||||
|
): boolean {
|
||||||
|
return environment ? environment === 'true' : boolean ?? true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +54,7 @@ function envOrBoolean(environment: string | undefined, boolean?: boolean): boole
|
|||||||
* @param string Default string. If not set, is `''`.
|
* @param string Default string. If not set, is `''`.
|
||||||
*/
|
*/
|
||||||
function envOrString(environment: string | undefined, string?: string): string {
|
function envOrString(environment: string | undefined, string?: string): string {
|
||||||
return environment ? environment : (string ?? '');
|
return environment ? environment : string ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,32 +64,187 @@ function envOrString(environment: string | undefined, string?: string): string {
|
|||||||
* @param number Default number. If not set, is `0`.
|
* @param number Default number. If not set, is `0`.
|
||||||
*/
|
*/
|
||||||
function envOrNumber(environment: string | undefined, number?: number): number {
|
function envOrNumber(environment: string | undefined, number?: number): number {
|
||||||
return Number(environment ?? (number ?? 0));
|
return environment ? Number(environment) : number ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns environment variable, given number, or default number,
|
||||||
|
* while handling dotenv input errors for a Min/Max pair.
|
||||||
|
* dotenv errors handled:
|
||||||
|
* - Min/Max swapped (Min larger than Max, Max smaller than Min)
|
||||||
|
* - Min larger than default Max when no Max defined
|
||||||
|
* - Max smaller than default Min when no Min defined
|
||||||
|
*
|
||||||
|
* @param environmentMin Min environment variable of Min/Max pair.
|
||||||
|
* @param environmentMax Max environment variable of Min/Max pair.
|
||||||
|
* @param number Default number. If not set, is `0`.
|
||||||
|
*/
|
||||||
|
function envOrNumberMin(
|
||||||
|
environmentMin: string | undefined,
|
||||||
|
environmentMax: string | undefined,
|
||||||
|
number?: number
|
||||||
|
) {
|
||||||
|
if (environmentMin || environmentMax) {
|
||||||
|
if (environmentMin && environmentMax) {
|
||||||
|
return Number(
|
||||||
|
Number(environmentMin) < Number(environmentMax)
|
||||||
|
? environmentMin
|
||||||
|
: environmentMax
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environmentMax) {
|
||||||
|
return Number(environmentMax) < (number ?? 0)
|
||||||
|
? Number(environmentMax)
|
||||||
|
: number ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environmentMin) {
|
||||||
|
return Number(environmentMin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns environment variable, given number, or default number,
|
||||||
|
* while handling dotenv input errors for a Min/Max pair.
|
||||||
|
* dotenv errors handled:
|
||||||
|
* - Min/Max swapped (Min larger than Max, Max smaller than Min)
|
||||||
|
* - Min larger than default Max when no Max defined
|
||||||
|
* - Max smaller than default Min when no Min defined
|
||||||
|
*
|
||||||
|
* @param environmentMin Min environment variable of Min/Max pair.
|
||||||
|
* @param environmentMax Max environment variable of Min/Max pair.
|
||||||
|
* @param number Default number. If not set, is `0`.
|
||||||
|
*/
|
||||||
|
function envOrNumberMax(
|
||||||
|
environmentMin: string | undefined,
|
||||||
|
environmentMax: string | undefined,
|
||||||
|
number?: number
|
||||||
|
) {
|
||||||
|
if (environmentMin || environmentMax) {
|
||||||
|
if (environmentMin && environmentMax) {
|
||||||
|
return Number(
|
||||||
|
Number(environmentMin) < Number(environmentMax)
|
||||||
|
? environmentMax
|
||||||
|
: environmentMax
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environmentMin) {
|
||||||
|
return Number(environmentMin) > (number ?? 0)
|
||||||
|
? Number(environmentMin)
|
||||||
|
: number ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environmentMax) {
|
||||||
|
return Number(environmentMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const browser = {
|
const browser = {
|
||||||
isHeadless: envOrBoolean(process.env.HEADLESS),
|
isHeadless: envOrBoolean(process.env.HEADLESS),
|
||||||
|
isIncognito: envOrBoolean(process.env.INCOGNITO, false),
|
||||||
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
|
isTrusted: envOrBoolean(process.env.BROWSER_TRUSTED, false),
|
||||||
maxSleep: envOrNumber(process.env.PAGE_SLEEP_MAX, 10000),
|
lowBandwidth: envOrBoolean(process.env.LOW_BANDWIDTH, false),
|
||||||
minSleep: envOrNumber(process.env.PAGE_SLEEP_MIN, 5000),
|
maxBackoff: envOrNumberMax(
|
||||||
open: envOrBoolean(process.env.OPEN_BROWSER)
|
process.env.PAGE_BACKOFF_MIN,
|
||||||
|
process.env.PAGE_BACKOFF_MAX,
|
||||||
|
3600000
|
||||||
|
),
|
||||||
|
maxSleep: envOrNumberMax(
|
||||||
|
process.env.PAGE_SLEEP_MIN,
|
||||||
|
process.env.PAGE_SLEEP_MAX,
|
||||||
|
10000
|
||||||
|
),
|
||||||
|
minBackoff: envOrNumberMin(
|
||||||
|
process.env.PAGE_BACKOFF_MIN,
|
||||||
|
process.env.PAGE_BACKOFF_MAX,
|
||||||
|
10000
|
||||||
|
),
|
||||||
|
minSleep: envOrNumberMin(
|
||||||
|
process.env.PAGE_SLEEP_MIN,
|
||||||
|
process.env.PAGE_SLEEP_MAX,
|
||||||
|
5000
|
||||||
|
),
|
||||||
|
open: envOrBoolean(process.env.OPEN_BROWSER),
|
||||||
|
userAgent: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const logLevel = process.env.LOG_LEVEL ?? 'info';
|
const docker = envOrBoolean(process.env.DOCKER, false);
|
||||||
|
|
||||||
|
const logLevel = envOrString(process.env.LOG_LEVEL, 'info');
|
||||||
|
|
||||||
const notifications = {
|
const notifications = {
|
||||||
desktop: process.env.DESKTOP_NOTIFICATIONS === 'true',
|
desktop: process.env.DESKTOP_NOTIFICATIONS === 'true',
|
||||||
discord: {
|
discord: {
|
||||||
notifyGroup: envOrArray(process.env.DISCORD_NOTIFY_GROUP),
|
notifyGroup: envOrArray(process.env.DISCORD_NOTIFY_GROUP),
|
||||||
webHookUrl: envOrArray(process.env.DISCORD_WEB_HOOK)
|
notifyGroupSeries: {
|
||||||
|
'3060ti': envOrArray(process.env.DISCORD_NOTIFY_GROUP_3060TI),
|
||||||
|
3070: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3070),
|
||||||
|
3080: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3080),
|
||||||
|
3090: envOrArray(process.env.DISCORD_NOTIFY_GROUP_3090),
|
||||||
|
darkhero: envOrArray(process.env.DISCORD_NOTIFY_GROUP_DARKHERO),
|
||||||
|
rx6800: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800),
|
||||||
|
rx6800xt: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6800XT),
|
||||||
|
rx6900xt: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RX6900XT),
|
||||||
|
ryzen5600: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5600),
|
||||||
|
ryzen5800: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5800),
|
||||||
|
ryzen5900: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5900),
|
||||||
|
ryzen5950: envOrArray(process.env.DISCORD_NOTIFY_GROUP_RYZEN5950),
|
||||||
|
sf: envOrArray(process.env.DISCORD_NOTIFY_GROUP_CORSAIR_SF),
|
||||||
|
sonyps5c: envOrArray(process.env.DISCORD_NOTIFY_GROUP_SONYPS5C),
|
||||||
|
sonyps5de: envOrArray(process.env.DISCORD_NOTIFY_GROUP_SONYPS5DE),
|
||||||
|
'test:series': envOrArray(process.env.DISCORD_NOTIFY_GROUP_TEST),
|
||||||
|
xboxss: envOrArray(process.env.DISCORD_NOTIFY_GROUP_XBOXSS),
|
||||||
|
xboxsx: envOrArray(process.env.DISCORD_NOTIFY_GROUP_XBOXSX)
|
||||||
|
},
|
||||||
|
webhooks: envOrArray(process.env.DISCORD_WEB_HOOK)
|
||||||
},
|
},
|
||||||
email: {
|
email: {
|
||||||
password: envOrString(process.env.EMAIL_PASSWORD),
|
password: envOrString(process.env.EMAIL_PASSWORD),
|
||||||
|
smtpAddress: envOrString(process.env.SMTP_ADDRESS),
|
||||||
|
smtpPort: envOrNumber(process.env.SMTP_PORT, 25),
|
||||||
|
to: envOrString(
|
||||||
|
process.env.EMAIL_TO,
|
||||||
|
envOrString(process.env.EMAIL_USERNAME)
|
||||||
|
),
|
||||||
username: envOrString(process.env.EMAIL_USERNAME)
|
username: envOrString(process.env.EMAIL_USERNAME)
|
||||||
},
|
},
|
||||||
|
mqtt: {
|
||||||
|
broker: envOrString(process.env.MQTT_BROKER_ADDRESS),
|
||||||
|
clientId: envOrString(process.env.MQTT_CLIENT_ID),
|
||||||
|
password: envOrString(process.env.MQTT_PASSWORD),
|
||||||
|
port: envOrNumber(process.env.MQTT_BROKER_PORT, 1883),
|
||||||
|
qos: envOrNumber(process.env.MQTT_QOS, 0),
|
||||||
|
topic: envOrString(process.env.MQTT_TOPIC, 'streetmerchant/alert'),
|
||||||
|
username: envOrString(process.env.MQTT_USERNAME)
|
||||||
|
},
|
||||||
|
pagerduty: {
|
||||||
|
integrationKey: envOrString(process.env.PAGERDUTY_INTEGRATION_KEY),
|
||||||
|
severity: envOrString(process.env.PAGERDUTY_SEVERITY, 'info')
|
||||||
|
},
|
||||||
|
philips_hue: {
|
||||||
|
accessToken: envOrString(process.env.PHILIPS_HUE_CLOUD_ACCESS_TOKEN),
|
||||||
|
apiKey: envOrString(process.env.PHILIPS_HUE_API_KEY),
|
||||||
|
bridgeIp: envOrString(process.env.PHILIPS_HUE_LAN_BRIDGE_IP),
|
||||||
|
clientId: envOrString(process.env.PHILIPS_HUE_CLOUD_CLIENT_ID),
|
||||||
|
clientSecret: envOrString(process.env.PHILIPS_HUE_CLOUD_CLIENT_SECRET),
|
||||||
|
lightColor: envOrString(process.env.PHILIPS_HUE_LIGHT_COLOR),
|
||||||
|
lightIds: envOrString(process.env.PHILIPS_HUE_LIGHT_IDS),
|
||||||
|
lightPattern: envOrString(process.env.PHILIPS_HUE_LIGHT_PATTERN),
|
||||||
|
refreshToken: envOrString(process.env.PHILIPS_HUE_CLOUD_REFRESH_TOKEN),
|
||||||
|
remoteApiUsername: envOrString(process.env.PHILIPS_HUE_API_KEY)
|
||||||
|
},
|
||||||
phone: {
|
phone: {
|
||||||
availableCarriers: new Map([
|
availableCarriers: new Map([
|
||||||
['att', 'txt.att.net'],
|
['att', 'txt.att.net'],
|
||||||
|
['attgo', 'mms.att.net'],
|
||||||
['bell', 'txt.bell.ca'],
|
['bell', 'txt.bell.ca'],
|
||||||
['fido', 'fido.ca'],
|
['fido', 'fido.ca'],
|
||||||
['google', 'msg.fi.google.com'],
|
['google', 'msg.fi.google.com'],
|
||||||
@@ -80,14 +256,18 @@ const notifications = {
|
|||||||
['tmobile', 'tmomail.net'],
|
['tmobile', 'tmomail.net'],
|
||||||
['verizon', 'vtext.com'],
|
['verizon', 'vtext.com'],
|
||||||
['virgin', 'vmobl.com'],
|
['virgin', 'vmobl.com'],
|
||||||
['virgin-ca', 'vmobile.ca']
|
['virgin-ca', 'vmobile.ca'],
|
||||||
|
['visible', 'vtext.com']
|
||||||
]),
|
]),
|
||||||
carrier: envOrString(process.env.PHONE_CARRIER),
|
carrier: envOrArray(process.env.PHONE_CARRIER),
|
||||||
number: envOrString(process.env.PHONE_NUMBER)
|
number: envOrArray(process.env.PHONE_NUMBER)
|
||||||
},
|
},
|
||||||
playSound: envOrString(process.env.PLAY_SOUND),
|
playSound: envOrString(process.env.PLAY_SOUND),
|
||||||
pushBulletApiKey: envOrString(process.env.PUSHBULLET),
|
pushbullet: envOrString(process.env.PUSHBULLET),
|
||||||
pushover: {
|
pushover: {
|
||||||
|
expire: envOrNumber(process.env.PUSHOVER_EXPIRE),
|
||||||
|
priority: envOrNumber(process.env.PUSHOVER_PRIORITY),
|
||||||
|
retry: envOrNumber(process.env.PUSHOVER_RETRY),
|
||||||
token: envOrString(process.env.PUSHOVER_TOKEN),
|
token: envOrString(process.env.PUSHOVER_TOKEN),
|
||||||
username: envOrString(process.env.PUSHOVER_USER)
|
username: envOrString(process.env.PUSHOVER_USER)
|
||||||
},
|
},
|
||||||
@@ -95,9 +275,23 @@ const notifications = {
|
|||||||
channel: envOrString(process.env.SLACK_CHANNEL),
|
channel: envOrString(process.env.SLACK_CHANNEL),
|
||||||
token: envOrString(process.env.SLACK_TOKEN)
|
token: envOrString(process.env.SLACK_TOKEN)
|
||||||
},
|
},
|
||||||
|
soundPlayer: envOrString(process.env.SOUND_PLAYER),
|
||||||
telegram: {
|
telegram: {
|
||||||
accessToken: envOrString(process.env.TELEGRAM_ACCESS_TOKEN),
|
accessToken: envOrString(process.env.TELEGRAM_ACCESS_TOKEN),
|
||||||
chatId: envOrString(process.env.TELEGRAM_CHAT_ID)
|
chatId: envOrArray(process.env.TELEGRAM_CHAT_ID)
|
||||||
|
},
|
||||||
|
twilio: {
|
||||||
|
accountSid: envOrString(process.env.TWILIO_ACCOUNT_SID),
|
||||||
|
authToken: envOrString(process.env.TWILIO_AUTH_TOKEN),
|
||||||
|
from: envOrString(process.env.TWILIO_FROM_NUMBER),
|
||||||
|
to: envOrString(process.env.TWILIO_TO_NUMBER)
|
||||||
|
},
|
||||||
|
twitch: {
|
||||||
|
accessToken: envOrString(process.env.TWITCH_ACCESS_TOKEN),
|
||||||
|
channel: envOrString(process.env.TWITCH_CHANNEL),
|
||||||
|
clientId: envOrString(process.env.TWITCH_CLIENT_ID),
|
||||||
|
clientSecret: envOrString(process.env.TWITCH_CLIENT_SECRET),
|
||||||
|
refreshToken: envOrString(process.env.TWITCH_REFRESH_TOKEN)
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
accessTokenKey: envOrString(process.env.TWITTER_ACCESS_TOKEN_KEY),
|
accessTokenKey: envOrString(process.env.TWITTER_ACCESS_TOKEN_KEY),
|
||||||
@@ -108,28 +302,131 @@ const notifications = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const nvidia = {
|
||||||
|
addToCardAttempts: envOrNumber(process.env.NVIDIA_ADD_TO_CART_ATTEMPTS, 10),
|
||||||
|
sessionTtl: envOrNumber(process.env.NVIDIA_SESSION_TTL, 60000)
|
||||||
|
};
|
||||||
|
|
||||||
const page = {
|
const page = {
|
||||||
height: 1080,
|
height: 1080,
|
||||||
inStockWaitTime: envOrNumber(process.env.IN_STOCK_WAIT_TIME),
|
inStockWaitTime: envOrNumber(process.env.IN_STOCK_WAIT_TIME),
|
||||||
navigationTimeout: envOrNumber(process.env.PAGE_TIMEOUT, 30000),
|
|
||||||
screenshot: envOrBoolean(process.env.SCREENSHOT),
|
screenshot: envOrBoolean(process.env.SCREENSHOT),
|
||||||
userAgent: envOrString(process.env.USER_AGENT, 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'),
|
timeout: envOrNumber(process.env.PAGE_TIMEOUT, 30000),
|
||||||
width: 1920
|
width: 1920
|
||||||
};
|
};
|
||||||
|
|
||||||
const store = {
|
const proxy = {
|
||||||
country: envOrString(process.env.COUNTRY, 'usa'),
|
address: envOrString(process.env.PROXY_ADDRESS),
|
||||||
microCenterLocation: envOrString(process.env.MICROCENTER_LOCATION, 'web'),
|
port: envOrNumber(process.env.PROXY_PORT, 80),
|
||||||
showOnlyBrands: envOrArray(process.env.SHOW_ONLY_BRANDS),
|
protocol: envOrString(process.env.PROXY_PROTOCOL, 'http')
|
||||||
showOnlyModels: envOrArray(process.env.SHOW_ONLY_MODELS),
|
|
||||||
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, ['3070', '3080', '3090']),
|
|
||||||
stores: envOrArray(process.env.STORES, ['nvidia'])
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Config = {
|
// Check for deprecated configuration values
|
||||||
|
if (process.env.MAX_PRICE) {
|
||||||
|
console.warn(
|
||||||
|
'ℹ MAX_PRICE is deprecated, please use MAX_PRICE_SERIES_{{series}}'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = {
|
||||||
|
autoAddToCart: envOrBoolean(process.env.AUTO_ADD_TO_CART, true),
|
||||||
|
country: envOrString(process.env.COUNTRY, 'usa'),
|
||||||
|
maxPrice: {
|
||||||
|
series: {
|
||||||
|
'3060ti': envOrNumber(process.env.MAX_PRICE_SERIES_3060TI),
|
||||||
|
3070: envOrNumber(process.env.MAX_PRICE_SERIES_3070),
|
||||||
|
3080: envOrNumber(process.env.MAX_PRICE_SERIES_3080),
|
||||||
|
3090: envOrNumber(process.env.MAX_PRICE_SERIES_3090),
|
||||||
|
darkhero: envOrNumber(process.env.MAX_PRICE_SERIES_DARKHERO),
|
||||||
|
rx6800: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800),
|
||||||
|
rx6800xt: envOrNumber(process.env.MAX_PRICE_SERIES_RX6800XT),
|
||||||
|
rx6900xt: envOrNumber(process.env.MAX_PRICE_SERIES_RX6900XT),
|
||||||
|
ryzen5600: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5600),
|
||||||
|
ryzen5800: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5800),
|
||||||
|
ryzen5900: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5900),
|
||||||
|
ryzen5950: envOrNumber(process.env.MAX_PRICE_SERIES_RYZEN5950),
|
||||||
|
sf: envOrNumber(process.env.MAX_PRICE_SERIES_CORSAIR_SF),
|
||||||
|
sonyps5c: envOrNumber(process.env.MAX_PRICE_SERIES_SONYPS5C),
|
||||||
|
sonyps5de: envOrNumber(process.env.MAX_PRICE_SERIES_SONYPS5DE),
|
||||||
|
'test:series': envOrNumber(process.env.MAX_PRICE_SERIES_TEST),
|
||||||
|
xboxss: -1,
|
||||||
|
xboxsx: -1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
microCenterLocation: envOrArray(process.env.MICROCENTER_LOCATION, ['web']),
|
||||||
|
showOnlyBrands: envOrArray(process.env.SHOW_ONLY_BRANDS),
|
||||||
|
showOnlyModels: envOrArray(process.env.SHOW_ONLY_MODELS).map((entry) => {
|
||||||
|
const [name, series] = entry.match(/[^:]+/g) ?? [];
|
||||||
|
return {
|
||||||
|
name: envOrString(name),
|
||||||
|
series: envOrString(series)
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
showOnlySeries: envOrArray(process.env.SHOW_ONLY_SERIES, [
|
||||||
|
'3060ti',
|
||||||
|
'3070',
|
||||||
|
'3080',
|
||||||
|
'3090',
|
||||||
|
'rx6800',
|
||||||
|
'rx6800xt',
|
||||||
|
'rx6900xt',
|
||||||
|
'ryzen5600',
|
||||||
|
'ryzen5800',
|
||||||
|
'ryzen5900',
|
||||||
|
'ryzen5950',
|
||||||
|
'sonyps5c',
|
||||||
|
'sonyps5de',
|
||||||
|
'xboxss',
|
||||||
|
'xboxsx'
|
||||||
|
]),
|
||||||
|
stores: envOrArray(process.env.STORES, ['nvidia']).map((entry) => {
|
||||||
|
const [name, minPageSleep, maxPageSleep] = entry.match(/[^:]+/g) ?? [];
|
||||||
|
|
||||||
|
let proxyList;
|
||||||
|
try {
|
||||||
|
proxyList = readFileSync(`${name}.proxies`)
|
||||||
|
.toString()
|
||||||
|
.trim()
|
||||||
|
.split('\n')
|
||||||
|
.map((x) => x.trim());
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
maxPageSleep: envOrNumberMax(
|
||||||
|
minPageSleep,
|
||||||
|
maxPageSleep,
|
||||||
|
browser.maxSleep
|
||||||
|
),
|
||||||
|
minPageSleep: envOrNumberMin(
|
||||||
|
minPageSleep,
|
||||||
|
maxPageSleep,
|
||||||
|
browser.minSleep
|
||||||
|
),
|
||||||
|
name: envOrString(name),
|
||||||
|
proxyList
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
export const defaultStoreData = {
|
||||||
|
maxPageSleep: browser.maxSleep,
|
||||||
|
minPageSleep: browser.minSleep
|
||||||
|
};
|
||||||
|
|
||||||
|
export const config = {
|
||||||
browser,
|
browser,
|
||||||
|
docker,
|
||||||
logLevel,
|
logLevel,
|
||||||
notifications,
|
notifications,
|
||||||
|
nvidia,
|
||||||
page,
|
page,
|
||||||
|
proxy,
|
||||||
store
|
store
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function setConfig(newConfig: any) {
|
||||||
|
const writeConfig = config as any;
|
||||||
|
for (const key of Object.keys(newConfig)) {
|
||||||
|
writeConfig[key] = newConfig[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+74
-23
@@ -1,58 +1,109 @@
|
|||||||
import {Config} from './config';
|
import {config} from './config'; // Needs to be loaded first
|
||||||
import {Logger} from './logger';
|
import {startAPIServer, stopAPIServer} from './web'; // eslint-disable-line sort-imports
|
||||||
import {Stores} from './store/model';
|
import {Browser} from 'puppeteer';
|
||||||
import {adBlocker} from './adblocker';
|
|
||||||
import {getSleepTime} from './util';
|
import {getSleepTime} from './util';
|
||||||
|
import {logger} from './logger';
|
||||||
import puppeteer from 'puppeteer-extra';
|
import puppeteer from 'puppeteer-extra';
|
||||||
import stealthPlugin from 'puppeteer-extra-plugin-stealth';
|
import stealthPlugin from 'puppeteer-extra-plugin-stealth';
|
||||||
|
import {storeList} from './store/model';
|
||||||
import {tryLookupAndLoop} from './store';
|
import {tryLookupAndLoop} from './store';
|
||||||
|
|
||||||
puppeteer.use(stealthPlugin());
|
puppeteer.use(stealthPlugin());
|
||||||
puppeteer.use(adBlocker);
|
|
||||||
|
let browser: Browser | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the bot.
|
* Starts the bot.
|
||||||
*/
|
*/
|
||||||
async function main() {
|
async function main() {
|
||||||
if (Stores.length === 0) {
|
|
||||||
Logger.error('✖ no stores selected', Stores);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const args: string[] = [];
|
const args: string[] = [];
|
||||||
|
|
||||||
// Skip Chromium Linux Sandbox
|
// Skip Chromium Linux Sandbox
|
||||||
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
|
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
|
||||||
if (Config.browser.isTrusted) {
|
if (config.browser.isTrusted) {
|
||||||
args.push('--no-sandbox');
|
args.push('--no-sandbox');
|
||||||
args.push('--disable-setuid-sandbox');
|
args.push('--disable-setuid-sandbox');
|
||||||
}
|
}
|
||||||
|
|
||||||
const browser = await puppeteer.launch({
|
// https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#tips
|
||||||
|
// https://stackoverflow.com/questions/48230901/docker-alpine-with-node-js-and-chromium-headless-puppeter-failed-to-launch-c
|
||||||
|
if (config.docker) {
|
||||||
|
args.push('--disable-dev-shm-usage');
|
||||||
|
args.push('--no-sandbox');
|
||||||
|
args.push('--disable-setuid-sandbox');
|
||||||
|
args.push('--headless');
|
||||||
|
args.push('--disable-gpu');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the address of the proxy server if defined
|
||||||
|
if (config.proxy.address) {
|
||||||
|
args.push(
|
||||||
|
`--proxy-server=${config.proxy.protocol}://${config.proxy.address}:${config.proxy.port}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length > 0) {
|
||||||
|
logger.info('ℹ puppeteer config: ', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
await stop();
|
||||||
|
browser = await puppeteer.launch({
|
||||||
args,
|
args,
|
||||||
defaultViewport: {
|
defaultViewport: {
|
||||||
height: Config.page.height,
|
height: config.page.height,
|
||||||
width: Config.page.width
|
width: config.page.width
|
||||||
},
|
},
|
||||||
headless: Config.browser.isHeadless
|
headless: config.browser.isHeadless
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const store of Stores) {
|
config.browser.userAgent = await browser.userAgent();
|
||||||
Logger.debug(store.links);
|
|
||||||
|
for (const store of storeList.values()) {
|
||||||
|
logger.debug('store links', {meta: {links: store.links}});
|
||||||
if (store.setupAction !== undefined) {
|
if (store.setupAction !== undefined) {
|
||||||
store.setupAction(browser);
|
store.setupAction(browser);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(tryLookupAndLoop, getSleepTime(), browser, store);
|
setTimeout(tryLookupAndLoop, getSleepTime(store), browser, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await startAPIServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function stop() {
|
||||||
|
await stopAPIServer();
|
||||||
|
|
||||||
|
if (browser) {
|
||||||
|
// Use temporary swap variable to avoid any race condition
|
||||||
|
const browserTemporary = browser;
|
||||||
|
browser = undefined;
|
||||||
|
await browserTemporary.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function stopAndExit() {
|
||||||
|
await stop();
|
||||||
|
// eslint-disable-next-line unicorn/no-process-exit
|
||||||
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will continually run until user interferes.
|
* Will continually run until user interferes.
|
||||||
*/
|
*/
|
||||||
try {
|
async function loopMain() {
|
||||||
void main();
|
try {
|
||||||
} catch (error) {
|
await main();
|
||||||
Logger.error('✖ something bad happened, resetting nvidia-snatcher', error);
|
} catch (error: unknown) {
|
||||||
void main();
|
logger.error(
|
||||||
|
'✖ something bad happened, resetting streetmerchant in 5 seconds',
|
||||||
|
error
|
||||||
|
);
|
||||||
|
setTimeout(loopMain, 5000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loopMain();
|
||||||
|
|
||||||
|
process.on('SIGINT', stopAndExit);
|
||||||
|
process.on('SIGQUIT', stopAndExit);
|
||||||
|
process.on('SIGTERM', stopAndExit);
|
||||||
|
|||||||
+184
-20
@@ -1,64 +1,228 @@
|
|||||||
import {Link, Store} from './store/model';
|
import {Link, Store} from './store/model';
|
||||||
import winston, {format} from 'winston';
|
|
||||||
import {Config} from './config';
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import {config} from './config';
|
||||||
|
import winston from 'winston';
|
||||||
|
|
||||||
const prettyJson = format.printf(info => {
|
const prettyJson = winston.format.printf((info) => {
|
||||||
const timestamp = new Date().toLocaleTimeString();
|
const timestamp = new Date().toLocaleTimeString();
|
||||||
|
|
||||||
if (typeof info.message === 'object') {
|
let out = `${chalk.grey(`[${timestamp}]`)} ${info.level} ${chalk.grey(
|
||||||
info.message = JSON.stringify(info.message, null, 4);
|
'::'
|
||||||
|
)} ${info.message}`;
|
||||||
|
|
||||||
|
if (Object.keys(info.metadata).length > 0) {
|
||||||
|
out = `${out} ${chalk.magenta(JSON.stringify(info.metadata, null, 2))}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return chalk.grey(`[${timestamp}]`) + ` ${info.level} ` + chalk.grey('::') + ` ${info.message}`;
|
return out;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Logger = winston.createLogger({
|
export const logger = winston.createLogger({
|
||||||
format: format.combine(
|
format: winston.format.combine(
|
||||||
format.colorize(),
|
winston.format.colorize(),
|
||||||
format.prettyPrint(),
|
winston.format.metadata({
|
||||||
format.splat(),
|
fillExcept: ['level', 'message', 'timestamp']
|
||||||
format.simple(),
|
}),
|
||||||
prettyJson
|
prettyJson
|
||||||
),
|
),
|
||||||
level: Config.logLevel,
|
level: config.logLevel,
|
||||||
transports: [new winston.transports.Console({})]
|
transports: [new winston.transports.Console({})]
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Print = {
|
export const Print = {
|
||||||
|
backoff(
|
||||||
|
link: Link,
|
||||||
|
store: Store,
|
||||||
|
parameters: {delay: number; statusCode: number},
|
||||||
|
color?: boolean
|
||||||
|
): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow(
|
||||||
|
`BACKOFF DELAY status=${parameters.statusCode} delay=${parameters.delay}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: BACKOFF DELAY status=${
|
||||||
|
parameters.statusCode
|
||||||
|
} delay=${parameters.delay}`;
|
||||||
|
},
|
||||||
|
badStatusCode(
|
||||||
|
link: Link,
|
||||||
|
store: Store,
|
||||||
|
statusCode: number,
|
||||||
|
color?: boolean
|
||||||
|
): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow(`STATUS CODE ERROR ${statusCode}`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(
|
||||||
|
link,
|
||||||
|
store
|
||||||
|
)} :: STATUS CODE ERROR ${statusCode}`;
|
||||||
|
},
|
||||||
|
bannedSeller(link: Link, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow('BANNED SELLER')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: BANNED SELLER`;
|
||||||
|
},
|
||||||
captcha(link: Link, store: Store, color?: boolean): string {
|
captcha(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('CAPTCHA');
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow('CAPTCHA')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `✖ ${buildProductString(link, store)} :: CAPTCHA`;
|
return `✖ ${buildProductString(link, store)} :: CAPTCHA`;
|
||||||
},
|
},
|
||||||
inStock(link: Link, store: Store, color?: boolean): string {
|
inStock(link: Link, store: Store, color?: boolean, sms?: boolean): string {
|
||||||
|
const productString = `${buildProductString(link, store)} :: IN STOCK`;
|
||||||
|
|
||||||
if (color) {
|
if (color) {
|
||||||
return chalk.green.bold(`🚀🚨 ${buildProductString(link, store, true)} :: IN STOCK 🚨🚀`);
|
return chalk.bgGreen.white.bold(`🚀🚨 ${productString} 🚨🚀`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `🚀🚨 ${buildProductString(link, store)} :: IN STOCK 🚨🚀`;
|
if (sms) {
|
||||||
|
return productString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `🚀🚨 ${productString} 🚨🚀`;
|
||||||
|
},
|
||||||
|
inStockWaiting(link: Link, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'ℹ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow('IN STOCK, WAITING')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `ℹ ${buildProductString(link, store)} :: IN STOCK, WAITING`;
|
||||||
|
},
|
||||||
|
maxPrice(
|
||||||
|
link: Link,
|
||||||
|
store: Store,
|
||||||
|
maxPrice: number,
|
||||||
|
color?: boolean
|
||||||
|
): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow(
|
||||||
|
`PRICE ${link.price ?? ''} EXCEEDS LIMIT ${maxPrice}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: PRICE ${
|
||||||
|
link.price ?? ''
|
||||||
|
} EXCEEDS LIMIT ${maxPrice}`;
|
||||||
|
},
|
||||||
|
message(
|
||||||
|
message: string,
|
||||||
|
topic: string,
|
||||||
|
store: Store,
|
||||||
|
color?: boolean
|
||||||
|
): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildSetupString(topic, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow(message)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildSetupString(topic, store)} :: ${message}`;
|
||||||
|
},
|
||||||
|
noResponse(link: Link, store: Store, color?: boolean): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow('NO RESPONSE')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `✖ ${buildProductString(link, store)} :: NO RESPONSE`;
|
||||||
},
|
},
|
||||||
outOfStock(link: Link, store: Store, color?: boolean): string {
|
outOfStock(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.red('OUT OF STOCK');
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.red('OUT OF STOCK')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `✖ ${buildProductString(link, store)} :: OUT OF STOCK`;
|
return `✖ ${buildProductString(link, store)} :: OUT OF STOCK`;
|
||||||
},
|
},
|
||||||
|
productInStock(link: Link): string {
|
||||||
|
let productString = `Product Page: ${link.url}`;
|
||||||
|
if (link.cartUrl)
|
||||||
|
productString += `\nAdd To Cart Link: ${link.cartUrl}`;
|
||||||
|
|
||||||
|
return productString;
|
||||||
|
},
|
||||||
rateLimit(link: Link, store: Store, color?: boolean): string {
|
rateLimit(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return '✖ ' + buildProductString(link, store, true) + ' :: ' + chalk.yellow('RATE LIMIT EXCEEDED');
|
return (
|
||||||
|
'✖ ' +
|
||||||
|
buildProductString(link, store, true) +
|
||||||
|
' :: ' +
|
||||||
|
chalk.yellow('RATE LIMIT EXCEEDED')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `✖ ${buildProductString(link, store)} :: RATE LIMIT EXCEEDED`;
|
return `✖ ${buildProductString(link, store)} :: RATE LIMIT EXCEEDED`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function buildSetupString(
|
||||||
|
topic: string,
|
||||||
|
store: Store,
|
||||||
|
color?: boolean
|
||||||
|
): string {
|
||||||
|
if (color) {
|
||||||
|
return (
|
||||||
|
chalk.cyan(`[${store.name}]`) + chalk.grey(` [setup (${topic})]`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `[${store.name}] [setup (${topic})]`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildProductString(link: Link, store: Store, color?: boolean): string {
|
function buildProductString(link: Link, store: Store, color?: boolean): string {
|
||||||
if (color) {
|
if (color) {
|
||||||
return chalk.cyan(`[${store.name}]`) + chalk.grey(` [${link.brand} (${link.series})] ${link.model}`);
|
return (
|
||||||
|
chalk.cyan(`[${store.name}]`) +
|
||||||
|
chalk.grey(` [${link.brand} (${link.series})] ${link.model}`)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `[${store.name}] [${link.brand} (${link.series})] ${link.model}`;
|
return `[${store.name}] [${link.brand} (${link.series})] ${link.model}`;
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
|
import {config} from '../config';
|
||||||
import notifier from 'node-notifier';
|
import notifier from 'node-notifier';
|
||||||
|
|
||||||
export function sendDesktopNotification(link: Link, store: Store) {
|
const desktop = config.notifications.desktop;
|
||||||
(async () => {
|
|
||||||
notifier.notify({
|
|
||||||
message: link.cartUrl ? link.cartUrl : link.url,
|
|
||||||
title: Print.inStock(link, store)
|
|
||||||
});
|
|
||||||
|
|
||||||
Logger.info('✔ desktop notification sent');
|
export function sendDesktopNotification(link: Link, store: Store) {
|
||||||
})();
|
if (desktop) {
|
||||||
|
logger.debug('↗ sending desktop notification');
|
||||||
|
(async () => {
|
||||||
|
notifier.notify({
|
||||||
|
message: link.cartUrl ? link.cartUrl : link.url,
|
||||||
|
title: Print.inStock(link, store)
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.info('✔ desktop notification sent');
|
||||||
|
})();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+83
-31
@@ -1,38 +1,90 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {MessageBuilder, Webhook} from 'discord-webhook-node';
|
import Discord from 'discord.js';
|
||||||
import {Config} from '../config';
|
import {config} from '../config';
|
||||||
import {Logger} from '../logger';
|
import {logger} from '../logger';
|
||||||
|
|
||||||
const hooks = Config.notifications.discord.webHookUrl;
|
const discord = config.notifications.discord;
|
||||||
const notifyGroup = Config.notifications.discord.notifyGroup;
|
const {notifyGroup, webhooks, notifyGroupSeries} = discord;
|
||||||
|
|
||||||
|
function getIdAndToken(webhook: string) {
|
||||||
|
const match = /.*\/webhooks\/(\d+)\/(.+)/.exec(webhook);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
throw new Error('could not get discord webhook');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: match[1],
|
||||||
|
token: match[2]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function sendDiscordMessage(link: Link, store: Store) {
|
export function sendDiscordMessage(link: Link, store: Store) {
|
||||||
(async () => {
|
if (webhooks.length > 0) {
|
||||||
try {
|
logger.debug('↗ sending discord message');
|
||||||
const embed = new MessageBuilder();
|
|
||||||
embed.setTitle('Stock Notification');
|
|
||||||
embed.addField('URL', link.cartUrl ? link.cartUrl : link.url, true);
|
|
||||||
embed.addField('Store', store.name, true);
|
|
||||||
embed.addField('Brand', link.brand, true);
|
|
||||||
embed.addField('Model', link.model, true);
|
|
||||||
|
|
||||||
if (notifyGroup) {
|
(async () => {
|
||||||
embed.setText(notifyGroup.join(' '));
|
try {
|
||||||
|
const embed = new Discord.MessageEmbed()
|
||||||
|
.setTitle('_**Stock alert!**_')
|
||||||
|
.setDescription(
|
||||||
|
'> provided by [streetmerchant](https://github.com/jef/streetmerchant) with :heart:'
|
||||||
|
)
|
||||||
|
.setThumbnail(
|
||||||
|
'https://raw.githubusercontent.com/jef/streetmerchant/main/docs/assets/images/streetmerchant-logo.png'
|
||||||
|
)
|
||||||
|
.setColor('#52b788')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
embed.addField('Store', store.name, true);
|
||||||
|
if (link.price)
|
||||||
|
embed.addField(
|
||||||
|
'Price',
|
||||||
|
`${store.currency}${link.price}`,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
embed.addField('Product Page', link.url);
|
||||||
|
if (link.cartUrl) embed.addField('Add to Cart', link.cartUrl);
|
||||||
|
embed.addField('Brand', link.brand, true);
|
||||||
|
embed.addField('Model', link.model, true);
|
||||||
|
embed.addField('Series', link.series, true);
|
||||||
|
|
||||||
|
embed.setTimestamp();
|
||||||
|
|
||||||
|
let notifyText: string[] = [];
|
||||||
|
|
||||||
|
if (notifyGroup) {
|
||||||
|
notifyText = notifyText.concat(notifyGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(notifyGroupSeries).indexOf(link.series) !== 0) {
|
||||||
|
notifyText = notifyText.concat(
|
||||||
|
notifyGroupSeries[link.series]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
for (const webhook of webhooks) {
|
||||||
|
const {id, token} = getIdAndToken(webhook);
|
||||||
|
const client = new Discord.WebhookClient(id, token);
|
||||||
|
|
||||||
|
promises.push({
|
||||||
|
client,
|
||||||
|
message: client.send(notifyText.join(' '), {
|
||||||
|
embeds: [embed],
|
||||||
|
username: 'streetmerchant'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
(await Promise.all(promises)).forEach(({client}) =>
|
||||||
|
client.destroy()
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.info('✔ discord message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send discord message", error);
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
embed.setColor(0x76B900);
|
}
|
||||||
embed.setTimestamp();
|
|
||||||
|
|
||||||
const promises = [];
|
|
||||||
for (const hook of hooks) {
|
|
||||||
promises.push(new Webhook(hook).send(embed));
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(promises);
|
|
||||||
|
|
||||||
Logger.info('✔ discord message sent');
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error('✖ couldn\'t send discord message', error);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-28
@@ -1,38 +1,55 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
|
||||||
import Mail from 'nodemailer/lib/mailer';
|
import Mail from 'nodemailer/lib/mailer';
|
||||||
|
import {config} from '../config';
|
||||||
import nodemailer from 'nodemailer';
|
import nodemailer from 'nodemailer';
|
||||||
|
|
||||||
const email = Config.notifications.email;
|
const email = config.notifications.email;
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
const transportOptions: any = {};
|
||||||
auth: {
|
|
||||||
pass: email.password,
|
if (email.username && (email.password || email.smtpAddress)) {
|
||||||
user: email.username
|
transportOptions.auth = {};
|
||||||
},
|
transportOptions.auth.user = email.username;
|
||||||
service: 'gmail'
|
transportOptions.auth.pass = email.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (email.smtpAddress) {
|
||||||
|
transportOptions.host = email.smtpAddress;
|
||||||
|
transportOptions.port = email.smtpPort;
|
||||||
|
} else {
|
||||||
|
transportOptions.service = 'gmail';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const transporter = nodemailer.createTransport({
|
||||||
|
...transportOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
export function sendEmail(link: Link, store: Store) {
|
export function sendEmail(link: Link, store: Store) {
|
||||||
const mailOptions: Mail.Options = {
|
if (email.username && (email.password || email.smtpAddress)) {
|
||||||
attachments: link.screenshot ? [
|
logger.debug('↗ sending email');
|
||||||
{
|
|
||||||
filename: link.screenshot,
|
|
||||||
path: `./${link.screenshot}`
|
|
||||||
}
|
|
||||||
] : undefined,
|
|
||||||
from: email.username,
|
|
||||||
subject: Print.inStock(link, store),
|
|
||||||
text: link.cartUrl ? link.cartUrl : link.url,
|
|
||||||
to: email.username
|
|
||||||
};
|
|
||||||
|
|
||||||
transporter.sendMail(mailOptions, error => {
|
const mailOptions: Mail.Options = {
|
||||||
if (error) {
|
attachments: link.screenshot
|
||||||
Logger.error('✖ couldn\'t send email', error);
|
? [
|
||||||
} else {
|
{
|
||||||
Logger.info('✔ email sent');
|
filename: link.screenshot,
|
||||||
}
|
path: `./${link.screenshot}`
|
||||||
});
|
}
|
||||||
|
]
|
||||||
|
: undefined,
|
||||||
|
from: email.username,
|
||||||
|
subject: Print.inStock(link, store),
|
||||||
|
text: Print.productInStock(link),
|
||||||
|
to: email.to
|
||||||
|
};
|
||||||
|
|
||||||
|
transporter.sendMail(mailOptions, (error) => {
|
||||||
|
if (error) {
|
||||||
|
logger.error("✖ couldn't send email", error);
|
||||||
|
} else {
|
||||||
|
logger.info('✔ email sent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import {Link, Store} from '../store/model';
|
||||||
|
import MqttClient, {IClientOptions, IClientPublishOptions} from 'mqtt';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
|
const mqtt = config.notifications.mqtt;
|
||||||
|
let client: MqttClient.Client;
|
||||||
|
|
||||||
|
if (mqtt.broker) {
|
||||||
|
if (checkInsecureUsage(mqtt.password, mqtt.broker)) {
|
||||||
|
logger.warn(
|
||||||
|
'✖ Insecure transport of password - Only use credentials with MQTT brokers on private networks.'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const clientOptions: IClientOptions = {
|
||||||
|
clean: mqtt.clientId === '',
|
||||||
|
clientId: mqtt.clientId === '' ? undefined : mqtt.clientId,
|
||||||
|
password: mqtt.password === '' ? undefined : mqtt.password,
|
||||||
|
username: mqtt.username === '' ? undefined : mqtt.username
|
||||||
|
};
|
||||||
|
client = MqttClient.connect(
|
||||||
|
`mqtt://${mqtt.broker}:${mqtt.port}`,
|
||||||
|
clientOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendMqttMessage(link: Link, store: Store) {
|
||||||
|
if (client) {
|
||||||
|
logger.debug('↗ sending mqtt message');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||||
|
const message = `{"msg":"${Print.inStock(
|
||||||
|
link,
|
||||||
|
store
|
||||||
|
)}", "url":"${givenUrl}"}`;
|
||||||
|
const topic = generateTopic(link, store, mqtt.topic);
|
||||||
|
const pubOptions: IClientPublishOptions = {
|
||||||
|
qos: mqtt.qos as 0 | 1 | 2,
|
||||||
|
retain: false
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
client.publish(topic, message, pubOptions);
|
||||||
|
logger.info('✔ mqtt message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send mqtt message", error);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateTopic(link: Link, store: Store, topic: string): string {
|
||||||
|
topic.trim();
|
||||||
|
topic = topic.replace(/^\//, '');
|
||||||
|
topic = topic
|
||||||
|
.replace(/%series%/g, link.series)
|
||||||
|
.replace(/%brand%/g, link.brand)
|
||||||
|
.replace(/%model%/g, link.model)
|
||||||
|
.replace(/%store%/g, store.name);
|
||||||
|
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic protection against sending credentials in the clear over public networks.
|
||||||
|
* - Returns 'true' if password is supplied in dotenv but address/URL is not part of a private network
|
||||||
|
* - Private networks evaluated: Class A, B, or C private IP's or linklocal URL ("*.local")
|
||||||
|
* - TLS could be implemented, however, the majority of MQTT services on the internet do not require user authentication.
|
||||||
|
* - If you find a 'cloud' MQTT broker requiring authentication for publishing alerts, consider using another MQTT service (for now).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function checkInsecureUsage(pass: string, address: string): boolean {
|
||||||
|
if (pass !== '') {
|
||||||
|
if (
|
||||||
|
isClassANet(address) ||
|
||||||
|
isClassBNet(address) ||
|
||||||
|
isClassCNet(address) ||
|
||||||
|
isLinkLocal(address)
|
||||||
|
) {
|
||||||
|
logger.debug(`MQTT using private network broker: ${address}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`MQTT using public network broker: ${address}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isClassANet(address: string): boolean {
|
||||||
|
const classRegex = /^(10\.(\d|[1-9]\d|[12][0-5]{2})\.(\d|[1-9]\d|[12][0-5]{2})\.(\d|[1-9]\d|[12][0-5]{2}))$/;
|
||||||
|
|
||||||
|
return Boolean(classRegex.exec(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isClassBNet(address: string): boolean {
|
||||||
|
const classRegex = /^(172\.(1[6-9]|2\d|3[01])\.(\d|[1-9]\d|[12][0-5]{2})\.(\d|[1-9]\d|[12][0-5]{2}))$/;
|
||||||
|
|
||||||
|
return Boolean(classRegex.exec(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isClassCNet(address: string): boolean {
|
||||||
|
const classRegex = /^(192\.168\.(\d|[1-9]\d|[12][0-5]{2})\.(\d|[1-9]\d|[12][0-5]{2}))$/;
|
||||||
|
|
||||||
|
return Boolean(classRegex.exec(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLinkLocal(address: string): boolean {
|
||||||
|
const linkLocal = /.+\.local$/;
|
||||||
|
|
||||||
|
return Boolean(linkLocal.exec(address));
|
||||||
|
}
|
||||||
@@ -1,75 +1,36 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Config} from '../config';
|
import {adjustPhilipsHueLights} from './philips-hue';
|
||||||
import {Logger} from '../logger';
|
|
||||||
import {playSound} from './sound';
|
import {playSound} from './sound';
|
||||||
import {sendDesktopNotification} from './desktop';
|
import {sendDesktopNotification} from './desktop';
|
||||||
import {sendDiscordMessage} from './discord';
|
import {sendDiscordMessage} from './discord';
|
||||||
import {sendEmail} from './email';
|
import {sendEmail} from './email';
|
||||||
import {sendPushBulletNotification} from './pushbullet';
|
import {sendMqttMessage} from './mqtt';
|
||||||
|
import {sendPagerDutyNotification} from './pagerduty';
|
||||||
|
import {sendPushbulletNotification} from './pushbullet';
|
||||||
import {sendPushoverNotification} from './pushover';
|
import {sendPushoverNotification} from './pushover';
|
||||||
import {sendSMS} from './sms';
|
|
||||||
import {sendSlackMessage} from './slack';
|
import {sendSlackMessage} from './slack';
|
||||||
|
import {sendSms} from './sms';
|
||||||
import {sendTelegramMessage} from './telegram';
|
import {sendTelegramMessage} from './telegram';
|
||||||
import {sendTweet} from './twitter';
|
import {sendTweet} from './twitter';
|
||||||
|
import {sendTwilioMessage} from './twilio';
|
||||||
const notifications = Config.notifications;
|
import {sendTwitchMessage} from './twitch';
|
||||||
|
|
||||||
export function sendNotification(link: Link, store: Store) {
|
export function sendNotification(link: Link, store: Store) {
|
||||||
if (notifications.email.username && notifications.email.password) {
|
// Priority
|
||||||
Logger.debug('↗ sending email');
|
playSound();
|
||||||
sendEmail(link, store);
|
sendDiscordMessage(link, store);
|
||||||
}
|
sendDesktopNotification(link, store);
|
||||||
|
sendEmail(link, store);
|
||||||
if (notifications.phone.number) {
|
sendSms(link, store);
|
||||||
Logger.debug('↗ sending sms');
|
// Non-priority
|
||||||
const carrier = notifications.phone.carrier;
|
adjustPhilipsHueLights();
|
||||||
if (carrier && notifications.phone.availableCarriers.has(carrier)) {
|
sendMqttMessage(link, store);
|
||||||
sendSMS(link, store);
|
sendPagerDutyNotification(link, store);
|
||||||
}
|
sendPushbulletNotification(link, store);
|
||||||
}
|
sendPushoverNotification(link, store);
|
||||||
|
sendSlackMessage(link, store);
|
||||||
if (notifications.playSound) {
|
sendTelegramMessage(link, store);
|
||||||
Logger.debug('↗ playing sound');
|
sendTweet(link, store);
|
||||||
playSound();
|
sendTwilioMessage(link, store);
|
||||||
}
|
sendTwitchMessage(link, store);
|
||||||
|
|
||||||
if (notifications.desktop) {
|
|
||||||
Logger.debug('↗ sending desktop notification');
|
|
||||||
sendDesktopNotification(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notifications.discord.webHookUrl) {
|
|
||||||
Logger.debug('↗ sending discord message');
|
|
||||||
sendDiscordMessage(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notifications.slack.channel && notifications.slack.token) {
|
|
||||||
Logger.debug('↗ sending slack message');
|
|
||||||
sendSlackMessage(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notifications.telegram.accessToken && notifications.telegram.chatId) {
|
|
||||||
Logger.debug('↗ sending telegram message');
|
|
||||||
sendTelegramMessage(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notifications.pushBulletApiKey) {
|
|
||||||
Logger.debug('↗ sending pushbullet message');
|
|
||||||
sendPushBulletNotification(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notifications.pushover.token && notifications.pushover.username) {
|
|
||||||
Logger.debug('↗ sending pushover message');
|
|
||||||
sendPushoverNotification(link, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
notifications.twitter.accessTokenKey &&
|
|
||||||
notifications.twitter.accessTokenSecret &&
|
|
||||||
notifications.twitter.consumerKey &&
|
|
||||||
notifications.twitter.consumerSecret
|
|
||||||
) {
|
|
||||||
Logger.debug('↗ sending twitter message');
|
|
||||||
sendTweet(link, store);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import {Link, Store} from '../store/model';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import PDClient from 'node-pagerduty';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
|
const pd = new PDClient('');
|
||||||
|
|
||||||
|
export function sendPagerDutyNotification(link: Link, store: Store) {
|
||||||
|
if (config.notifications.pagerduty.integrationKey) {
|
||||||
|
logger.debug('↗ sending pagerduty message');
|
||||||
|
const links = [{href: link.url, text: 'Visit Store'}];
|
||||||
|
if (link.cartUrl) {
|
||||||
|
links.push({
|
||||||
|
href: link.cartUrl,
|
||||||
|
text: 'Add to Cart'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pd.events.sendEvent({
|
||||||
|
dedup_key: link.url,
|
||||||
|
event_action: 'trigger',
|
||||||
|
payload: {
|
||||||
|
links,
|
||||||
|
severity: config.notifications.pagerduty.severity,
|
||||||
|
source: store.name,
|
||||||
|
summary: Print.inStock(link, store)
|
||||||
|
},
|
||||||
|
routing_key: config.notifications.pagerduty.integrationKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import type Api from 'node-hue-api/lib/api/Api';
|
||||||
|
import {config} from '../config';
|
||||||
|
import {v3 as hueAPI} from 'node-hue-api';
|
||||||
|
import {logger} from '../logger';
|
||||||
|
|
||||||
|
const hue = config.notifications.philips_hue;
|
||||||
|
const apiKey = hue.apiKey;
|
||||||
|
const bridgeIp = hue.bridgeIp;
|
||||||
|
const lightIds = hue.lightIds;
|
||||||
|
const lightColor = hue.lightColor;
|
||||||
|
const lightPattern = hue.lightPattern;
|
||||||
|
const LightState = hueAPI.lightStates.LightState;
|
||||||
|
const clientId = hue.clientId;
|
||||||
|
const clientSecret = hue.clientSecret;
|
||||||
|
const accessToken = hue.accessToken;
|
||||||
|
const refreshToken = hue.refreshToken;
|
||||||
|
const remoteApiUsername = hue.remoteApiUsername;
|
||||||
|
|
||||||
|
// Default Light State
|
||||||
|
const lightState = new LightState()
|
||||||
|
.on(true)
|
||||||
|
.brightness(100)
|
||||||
|
.rgb(46.27, 72.55, 0);
|
||||||
|
|
||||||
|
const adjustLightsWithAPI = (hueBridge: Api) => {
|
||||||
|
logger.debug('Connected to Philips Hue bridge.');
|
||||||
|
// Set the custom light state (COLOR and METHOD here)
|
||||||
|
if (lightColor) {
|
||||||
|
const rgbArray = lightColor.split(',');
|
||||||
|
// If there's not three values, must not be RGB
|
||||||
|
if (rgbArray.length === 3) {
|
||||||
|
lightState.rgb(rgbArray[0], rgbArray[1], rgbArray[2]);
|
||||||
|
} else {
|
||||||
|
logger.debug('✖ Error assigning RGB Values');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If blink is specified, then blink the lights
|
||||||
|
if (lightPattern === 'blink') {
|
||||||
|
lightState.alertLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've been given light IDs, then only adjust those IDs
|
||||||
|
if (lightIds) {
|
||||||
|
const arrayOfIDs = lightIds.split(',');
|
||||||
|
arrayOfIDs.forEach((light) => {
|
||||||
|
logger.debug('adjusting all hue lights');
|
||||||
|
(hueBridge.lights.setLightState(
|
||||||
|
light,
|
||||||
|
lightState
|
||||||
|
) as Promise<any>).catch((error: Error) => {
|
||||||
|
logger.error('Failed to adjust all lights.');
|
||||||
|
logger.error(error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Adjust all light IDs
|
||||||
|
hueBridge.lights
|
||||||
|
.getAll()
|
||||||
|
.then((allLights: any[]) => {
|
||||||
|
allLights.forEach((light: any) => {
|
||||||
|
logger.debug('adjusting specified lights');
|
||||||
|
(hueBridge.lights.setLightState(
|
||||||
|
light,
|
||||||
|
lightState
|
||||||
|
) as Promise<any>).catch((error: Error) => {
|
||||||
|
logger.error('Failed to adjust specified lights.');
|
||||||
|
logger.error(error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error: Error) => {
|
||||||
|
logger.error('Failed to get all lights.');
|
||||||
|
logger.error(error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function adjustPhilipsHueLights() {
|
||||||
|
// Check if the required variables have been set
|
||||||
|
if (hue.apiKey && hue.bridgeIp) {
|
||||||
|
logger.info('↗ adjusting Philips Hue lights over LAN');
|
||||||
|
(async () => {
|
||||||
|
logger.debug(
|
||||||
|
'Attempting to connect to Philips Hue bridge at ' + bridgeIp
|
||||||
|
);
|
||||||
|
hueAPI.api
|
||||||
|
.createLocal(bridgeIp)
|
||||||
|
.connect(apiKey)
|
||||||
|
.then(
|
||||||
|
(hueBridge) => {
|
||||||
|
adjustLightsWithAPI(hueBridge);
|
||||||
|
logger.info('✔ adjusted Philips Hue lights over LAN');
|
||||||
|
},
|
||||||
|
(error: Error) => {
|
||||||
|
logger.error("✖ couldn't adjust hue lights.", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
} else if (hue.apiKey && hue.clientId && hue.clientSecret) {
|
||||||
|
logger.info('↗ adjusting Philips Hue lights over cloud');
|
||||||
|
(async () => {
|
||||||
|
logger.debug(
|
||||||
|
'Attempting to connect to Philips Hue bridge over cloud'
|
||||||
|
);
|
||||||
|
const remoteBootstrap = hueAPI.api.createRemote(
|
||||||
|
clientId,
|
||||||
|
clientSecret
|
||||||
|
);
|
||||||
|
if (hue.accessToken && hue.refreshToken) {
|
||||||
|
remoteBootstrap
|
||||||
|
.connectWithTokens(
|
||||||
|
accessToken,
|
||||||
|
refreshToken,
|
||||||
|
remoteApiUsername
|
||||||
|
)
|
||||||
|
.then(
|
||||||
|
(hueBridge) => {
|
||||||
|
adjustLightsWithAPI(hueBridge);
|
||||||
|
logger.info(
|
||||||
|
'✔ adjusted Philips Hue lights over cloud'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(error: Error) => {
|
||||||
|
logger.error(
|
||||||
|
'Failed to get a remote Philips Hue connection using supplied tokens.'
|
||||||
|
);
|
||||||
|
logger.error(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,27 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
import PushBullet from '@jef/pushbullet';
|
||||||
import PushBullet from 'pushbullet';
|
import {config} from '../config';
|
||||||
|
|
||||||
const pushBulletApiKey = Config.notifications.pushBulletApiKey;
|
const pushbullet = config.notifications.pushbullet;
|
||||||
|
|
||||||
export function sendPushBulletNotification(link: Link, store: Store) {
|
export function sendPushbulletNotification(link: Link, store: Store) {
|
||||||
const pusher = new PushBullet(pushBulletApiKey);
|
if (pushbullet) {
|
||||||
|
logger.debug('↗ sending pushbullet message');
|
||||||
|
|
||||||
pusher.note(
|
const pusher = new PushBullet(pushbullet);
|
||||||
{},
|
|
||||||
Print.inStock(link, store),
|
pusher.note(
|
||||||
link.cartUrl ? link.cartUrl : link.url,
|
{},
|
||||||
(error: Error) => {
|
Print.inStock(link, store),
|
||||||
if (error) {
|
link.cartUrl ? link.cartUrl : link.url,
|
||||||
Logger.error('✖ couldn\'t send pushbullet message', error);
|
(error: Error) => {
|
||||||
} else {
|
if (error) {
|
||||||
Logger.info('✔ pushbullet message sent');
|
logger.error("✖ couldn't send pushbullet message", error);
|
||||||
|
} else {
|
||||||
|
logger.info('✔ pushbullet message sent');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,40 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
import Push, {PushoverMessage} from 'pushover-notifications';
|
||||||
import Push from 'pushover-notifications';
|
import {config} from '../config';
|
||||||
|
|
||||||
const pushover = Config.notifications.pushover;
|
const pushover = config.notifications.pushover;
|
||||||
const push = new Push({
|
|
||||||
token: pushover.token,
|
|
||||||
user: pushover.username
|
|
||||||
});
|
|
||||||
|
|
||||||
export function sendPushoverNotification(link: Link, store: Store) {
|
export function sendPushoverNotification(link: Link, store: Store) {
|
||||||
const message = {
|
if (pushover.token && pushover.username) {
|
||||||
message: link.cartUrl ? link.cartUrl : link.url,
|
logger.debug('↗ sending pushover message');
|
||||||
title: Print.inStock(link, store)
|
|
||||||
};
|
|
||||||
|
|
||||||
push.send(message, (error: Error) => {
|
const push = new Push({
|
||||||
if (error) {
|
token: pushover.token,
|
||||||
Logger.error('✖ couldn\'t send pushover message', error);
|
user: pushover.username
|
||||||
} else {
|
});
|
||||||
Logger.info('✔ pushover message sent');
|
|
||||||
}
|
const message: PushoverMessage =
|
||||||
});
|
pushover.priority < 2
|
||||||
|
? {
|
||||||
|
message: link.cartUrl ? link.cartUrl : link.url,
|
||||||
|
priority: pushover.priority,
|
||||||
|
title: Print.inStock(link, store)
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
expire: pushover.expire,
|
||||||
|
message: link.cartUrl ? link.cartUrl : link.url,
|
||||||
|
priority: pushover.priority,
|
||||||
|
retry: pushover.retry,
|
||||||
|
title: Print.inStock(link, store)
|
||||||
|
};
|
||||||
|
|
||||||
|
push.send(message, (error: Error) => {
|
||||||
|
if (error) {
|
||||||
|
logger.error("✖ couldn't send pushover message", error);
|
||||||
|
} else {
|
||||||
|
logger.info('✔ pushover message sent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-20
@@ -1,30 +1,35 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
|
||||||
import {WebClient} from '@slack/web-api';
|
import {WebClient} from '@slack/web-api';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
const channel = Config.notifications.slack.channel;
|
const slack = config.notifications.slack;
|
||||||
const token = Config.notifications.slack.token;
|
const channel = slack.channel.replace('#', '');
|
||||||
|
const token = slack.token;
|
||||||
const web = new WebClient(token);
|
const web = new WebClient(token);
|
||||||
|
|
||||||
export function sendSlackMessage(link: Link, store: Store) {
|
export function sendSlackMessage(link: Link, store: Store) {
|
||||||
(async () => {
|
if (slack.channel && slack.token) {
|
||||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
logger.debug('↗ sending slack message');
|
||||||
|
|
||||||
try {
|
(async () => {
|
||||||
const result = await web.chat.postMessage({
|
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||||
channel,
|
|
||||||
text: `${Print.inStock(link, store)}\n${givenUrl}`
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.ok) {
|
try {
|
||||||
Logger.error('✖ couldn\'t send slack message', result);
|
const result = await web.chat.postMessage({
|
||||||
return;
|
channel,
|
||||||
|
text: `${Print.inStock(link, store)}\n${givenUrl}`
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
logger.error("✖ couldn't send slack message", result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('✔ slack message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send slack message", error);
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
Logger.info('✔ slack message sent');
|
}
|
||||||
} catch (error) {
|
|
||||||
Logger.error('✖ couldn\'t send slack message', error);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-40
@@ -1,52 +1,78 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
|
||||||
import Mail from 'nodemailer/lib/mailer';
|
import Mail from 'nodemailer/lib/mailer';
|
||||||
import nodemailer from 'nodemailer';
|
import {config} from '../config';
|
||||||
|
import {transporter} from './email';
|
||||||
|
|
||||||
if (Config.notifications.phone.number && !Config.notifications.email.username) {
|
const [email, phone] = [config.notifications.email, config.notifications.phone];
|
||||||
Logger.warn('✖ in order to recieve sms alerts, email notifications must also be configured');
|
|
||||||
|
if (phone.number.length > 0 && (!email.username || !email.password)) {
|
||||||
|
logger.warn(
|
||||||
|
'✖ in order to receive sms alerts, email notifications must also be configured'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [email, phone] = [Config.notifications.email, Config.notifications.phone];
|
if (phone.carrier.length !== phone.number.length) {
|
||||||
|
logger.warn(
|
||||||
|
'✖ the number of carriers must match the number of phone numbers',
|
||||||
|
{carrier: phone.carrier, number: phone.number}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
export function sendSms(link: Link, store: Store) {
|
||||||
auth: {
|
for (
|
||||||
pass: email.password,
|
let i = 0;
|
||||||
user: email.username
|
i < Math.max(phone.number.length, phone.carrier.length);
|
||||||
},
|
i++
|
||||||
service: 'gmail'
|
) {
|
||||||
});
|
const currentNumber = phone.number[i];
|
||||||
|
const currentCarrier = phone.carrier[i];
|
||||||
|
|
||||||
export function sendSMS(link: Link, store: Store) {
|
if (!currentNumber) {
|
||||||
const mailOptions: Mail.Options = {
|
logger.error(`✖ ${currentCarrier} is not associated with a number`);
|
||||||
attachments: link.screenshot ? [
|
continue;
|
||||||
{
|
} else if (!currentCarrier) {
|
||||||
filename: link.screenshot,
|
logger.error(`✖ ${currentNumber} is not associated with a carrier`);
|
||||||
path: `./${link.screenshot}`
|
continue;
|
||||||
}
|
|
||||||
] : undefined,
|
|
||||||
from: email.username,
|
|
||||||
subject: Print.inStock(link, store),
|
|
||||||
text: link.cartUrl ? link.cartUrl : link.url,
|
|
||||||
to: generateAddress()
|
|
||||||
};
|
|
||||||
|
|
||||||
transporter.sendMail(mailOptions, error => {
|
|
||||||
if (error) {
|
|
||||||
Logger.error('✖ couldn\'t send sms', error);
|
|
||||||
} else {
|
|
||||||
Logger.info('✔ sms sent');
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateAddress() {
|
if (!phone.availableCarriers.has(currentCarrier)) {
|
||||||
const carrier = phone.carrier;
|
logger.error(`✖ unknown carrier ${currentCarrier}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (carrier && phone.availableCarriers.has(carrier)) {
|
logger.debug('↗ sending sms');
|
||||||
return [phone.number, phone.availableCarriers.get(carrier)].join('@');
|
|
||||||
|
const mailOptions: Mail.Options = {
|
||||||
|
attachments: link.screenshot
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
filename: link.screenshot,
|
||||||
|
path: `./${link.screenshot}`
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: undefined,
|
||||||
|
from: email.username,
|
||||||
|
subject: Print.inStock(link, store, false, true),
|
||||||
|
text: link.cartUrl ? link.cartUrl : link.url,
|
||||||
|
to: generateAddress(currentNumber, currentCarrier)
|
||||||
|
};
|
||||||
|
|
||||||
|
transporter.sendMail(mailOptions, (error) => {
|
||||||
|
if (error) {
|
||||||
|
logger.error(
|
||||||
|
`✖ couldn't send sms to ${currentNumber} for carrier ${currentCarrier}`,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logger.info('✔ sms sent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateAddress(number: string, carrier: string) {
|
||||||
|
if (carrier && phone.availableCarriers.has(carrier)) {
|
||||||
|
return [number, phone.availableCarriers.get(carrier)].join('@');
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.error('✖ unknown carrier', carrier);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-20
@@ -1,36 +1,46 @@
|
|||||||
import {Config} from '../config';
|
import playerLib, {PlaySound} from 'play-sound';
|
||||||
import {Logger} from '../logger';
|
import {config} from '../config';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import playerLib from 'play-sound';
|
import {logger} from '../logger';
|
||||||
|
|
||||||
let player: any;
|
let player: PlaySound;
|
||||||
|
|
||||||
if (Config.notifications.playSound) {
|
if (config.notifications.playSound) {
|
||||||
player = playerLib();
|
player = config.notifications.soundPlayer
|
||||||
|
? playerLib({players: [config.notifications.soundPlayer]})
|
||||||
|
: playerLib();
|
||||||
|
|
||||||
if (player.player === null) {
|
if (player.player === null) {
|
||||||
Logger.warn('✖ couldn\'t find sound player');
|
logger.warn("✖ couldn't find sound player");
|
||||||
} else {
|
} else {
|
||||||
const playerName: string = player.player;
|
const playerName = player.player;
|
||||||
Logger.info(`✔ sound player found: ${playerName}`);
|
logger.info(`✔ sound player found: ${playerName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function playSound() {
|
export function playSound() {
|
||||||
if (player.player !== null) {
|
if (config.notifications.playSound && player.player !== null) {
|
||||||
fs.access(Config.notifications.playSound, fs.constants.F_OK, error => {
|
logger.debug('↗ playing sound');
|
||||||
if (error) {
|
|
||||||
Logger.error(`✖ error opening sound file: ${error.message}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.play(Config.notifications.playSound, (error: Error) => {
|
fs.access(
|
||||||
|
config.notifications.playSound,
|
||||||
|
fs.constants.F_OK,
|
||||||
|
(error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
Logger.error('✖ couldn\'t play sound', error);
|
logger.error(
|
||||||
|
`✖ error opening sound file: ${error.message}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.info('✔ played sound');
|
player.play(config.notifications.playSound, (error: Error) => {
|
||||||
});
|
if (error) {
|
||||||
});
|
logger.error("✖ couldn't play sound", error);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('✔ played sound');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,37 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
|
||||||
import {TelegramClient} from 'messaging-api-telegram';
|
import {TelegramClient} from 'messaging-api-telegram';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
const telegram = Config.notifications.telegram;
|
const telegram = config.notifications.telegram;
|
||||||
|
|
||||||
const client = new TelegramClient({
|
const client = new TelegramClient({
|
||||||
accessToken: telegram.accessToken
|
accessToken: telegram.accessToken
|
||||||
});
|
});
|
||||||
|
|
||||||
export function sendTelegramMessage(link: Link, store: Store) {
|
export function sendTelegramMessage(link: Link, store: Store) {
|
||||||
(async () => {
|
if (telegram.accessToken && telegram.chatId) {
|
||||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
logger.debug('↗ sending telegram message');
|
||||||
|
|
||||||
try {
|
(async () => {
|
||||||
await client.sendMessage(telegram.chatId, `${Print.inStock(link, store)}\n${givenUrl}`);
|
const message = Print.productInStock(link);
|
||||||
Logger.info('✔ telegram message sent');
|
const results = [];
|
||||||
} catch (error) {
|
|
||||||
Logger.error('✖ couldn\'t send telegram message', error);
|
for (const chatId of telegram.chatId) {
|
||||||
}
|
try {
|
||||||
})();
|
results.push(
|
||||||
|
client.sendMessage(
|
||||||
|
chatId,
|
||||||
|
`${Print.inStock(link, store)}\n${message}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
logger.info('✔ telegram message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send telegram message", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(results);
|
||||||
|
})();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import {Link, Store} from '../store/model';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import {Twilio} from 'twilio';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
|
const twilio = config.notifications.twilio;
|
||||||
|
let client: Twilio;
|
||||||
|
|
||||||
|
if (twilio.accountSid && twilio.authToken) {
|
||||||
|
client = new Twilio(twilio.accountSid, twilio.authToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendTwilioMessage(link: Link, store: Store) {
|
||||||
|
if (client) {
|
||||||
|
logger.debug('↗ sending twilio message');
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
||||||
|
const message = `${Print.inStock(link, store)}\n${givenUrl}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.messages.create({
|
||||||
|
body: message,
|
||||||
|
from: twilio.from,
|
||||||
|
to: twilio.to
|
||||||
|
});
|
||||||
|
logger.info('✔ twilio message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send twilio message", error);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import {Link, Store} from '../store/model';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import {RefreshableAuthProvider, StaticAuthProvider} from 'twitch-auth';
|
||||||
|
import {existsSync, promises, readFileSync} from 'fs';
|
||||||
|
import {ChatClient} from 'twitch-chat-client';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
|
const twitch = config.notifications.twitch;
|
||||||
|
|
||||||
|
const messages: string[] = [];
|
||||||
|
let alreadySaying = false;
|
||||||
|
|
||||||
|
let tokenData = {
|
||||||
|
accessToken: twitch.accessToken,
|
||||||
|
expiryTimestamp: 0,
|
||||||
|
refreshToken: twitch.refreshToken
|
||||||
|
};
|
||||||
|
|
||||||
|
if (existsSync('./twitch.json')) {
|
||||||
|
tokenData = {
|
||||||
|
...JSON.parse(readFileSync('./twitch.json', 'utf-8')),
|
||||||
|
...tokenData
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatClient: ChatClient = new ChatClient(
|
||||||
|
new RefreshableAuthProvider(
|
||||||
|
new StaticAuthProvider(twitch.clientId, tokenData.accessToken),
|
||||||
|
{
|
||||||
|
clientSecret: twitch.clientSecret,
|
||||||
|
expiry:
|
||||||
|
tokenData.expiryTimestamp === null
|
||||||
|
? null
|
||||||
|
: new Date(tokenData.expiryTimestamp),
|
||||||
|
onRefresh: async ({accessToken, refreshToken, expiryDate}) => {
|
||||||
|
return promises.writeFile(
|
||||||
|
'./twitch.json',
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
accessToken,
|
||||||
|
expiryTimestamp:
|
||||||
|
expiryDate === null
|
||||||
|
? null
|
||||||
|
: expiryDate.getTime(),
|
||||||
|
refreshToken
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
4
|
||||||
|
),
|
||||||
|
'utf-8'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
refreshToken: tokenData.refreshToken
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{
|
||||||
|
channels: [twitch.channel]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
chatClient.onJoin((channel: string, user: string) => {
|
||||||
|
if (channel === `#${twitch.channel}` && user === chatClient.currentNick) {
|
||||||
|
while (messages.length) {
|
||||||
|
const message: string | undefined = messages.shift();
|
||||||
|
|
||||||
|
if (message !== undefined) {
|
||||||
|
try {
|
||||||
|
chatClient.say(channel, message);
|
||||||
|
logger.info('✔ twitch message sent');
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error("✖ couldn't send twitch message", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void chatClient.quit();
|
||||||
|
});
|
||||||
|
|
||||||
|
chatClient.onDisconnect(() => {
|
||||||
|
alreadySaying = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
export function sendTwitchMessage(link: Link, store: Store) {
|
||||||
|
if (
|
||||||
|
tokenData.accessToken &&
|
||||||
|
twitch.channel &&
|
||||||
|
twitch.clientId &&
|
||||||
|
twitch.clientSecret &&
|
||||||
|
tokenData.refreshToken
|
||||||
|
) {
|
||||||
|
logger.debug('↗ sending twitch message');
|
||||||
|
|
||||||
|
messages.push(
|
||||||
|
`${Print.inStock(link, store)}\n${
|
||||||
|
link.cartUrl ? link.cartUrl : link.url
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!alreadySaying) {
|
||||||
|
alreadySaying = true;
|
||||||
|
void chatClient.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
-13
@@ -1,9 +1,9 @@
|
|||||||
import {Link, Store} from '../store/model';
|
import {Link, Store} from '../store/model';
|
||||||
import {Logger, Print} from '../logger';
|
import {Print, logger} from '../logger';
|
||||||
import {Config} from '../config';
|
|
||||||
import Twitter from 'twitter';
|
import Twitter from 'twitter';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
const twitter = Config.notifications.twitter;
|
const twitter = config.notifications.twitter;
|
||||||
|
|
||||||
const client = new Twitter({
|
const client = new Twitter({
|
||||||
access_token_key: twitter.accessTokenKey,
|
access_token_key: twitter.accessTokenKey,
|
||||||
@@ -13,17 +13,28 @@ const client = new Twitter({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export function sendTweet(link: Link, store: Store) {
|
export function sendTweet(link: Link, store: Store) {
|
||||||
let status = `${Print.inStock(link, store)}\n${link.cartUrl ? link.cartUrl : link.url}`;
|
if (
|
||||||
|
twitter.accessTokenKey &&
|
||||||
|
twitter.accessTokenSecret &&
|
||||||
|
twitter.consumerKey &&
|
||||||
|
twitter.consumerSecret
|
||||||
|
) {
|
||||||
|
logger.debug('↗ sending twitter message');
|
||||||
|
|
||||||
if (twitter.tweetTags) {
|
let status = `${Print.inStock(link, store)}\n${
|
||||||
status += `\n\n${twitter.tweetTags}`;
|
link.cartUrl ? link.cartUrl : link.url
|
||||||
}
|
}`;
|
||||||
|
|
||||||
client.post('statuses/update', {status}, error => {
|
if (twitter.tweetTags) {
|
||||||
if (error) {
|
status += `\n\n${twitter.tweetTags}`;
|
||||||
Logger.error('✖ couldn\'t send twitter notification', error);
|
|
||||||
} else {
|
|
||||||
Logger.info('✔ twitter notification sent');
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
client.post('statuses/update', {status}, (error) => {
|
||||||
|
if (error) {
|
||||||
|
logger.error("✖ couldn't send twitter notification", error);
|
||||||
|
} else {
|
||||||
|
logger.info('✔ twitter notification sent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import {Link, Series, Store} from './model';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import {Browser} from 'puppeteer';
|
||||||
|
import cheerio from 'cheerio';
|
||||||
|
import {filterSeries} from './filter';
|
||||||
|
import {usingResponse} from '../util';
|
||||||
|
|
||||||
|
function addNewLinks(store: Store, links: Link[], series: Series) {
|
||||||
|
if (links.length === 0) {
|
||||||
|
logger.debug(
|
||||||
|
Print.message('NO STORE LINKS FOUND', series, store, true)
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingUrls = new Set(store.links.map((link) => link.url));
|
||||||
|
const newLinks = links.filter((link) => !existingUrls.has(link.url));
|
||||||
|
|
||||||
|
if (newLinks.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
Print.message(
|
||||||
|
`FOUND ${newLinks.length} STORE LINKS`,
|
||||||
|
series,
|
||||||
|
store,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
logger.debug(JSON.stringify(newLinks, null, 2));
|
||||||
|
|
||||||
|
store.links = store.links.concat(newLinks);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchLinks(store: Store, browser: Browser) {
|
||||||
|
if (!store.linksBuilder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises: Array<Promise<void>> = [];
|
||||||
|
|
||||||
|
for (let {series, url} of store.linksBuilder.urls) {
|
||||||
|
if (!filterSeries(series)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
Print.message('DETECTING STORE LINKS', series, store, true)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!Array.isArray(url)) {
|
||||||
|
url = [url];
|
||||||
|
}
|
||||||
|
|
||||||
|
url.map((x) =>
|
||||||
|
promises.push(
|
||||||
|
usingResponse(browser, x, async (response) => {
|
||||||
|
const text = await response?.text();
|
||||||
|
|
||||||
|
if (!text) {
|
||||||
|
logger.error(
|
||||||
|
Print.message('NO RESPONSE', series, store, true)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const docElement = cheerio.load(text).root();
|
||||||
|
const links = store.linksBuilder!.builder(
|
||||||
|
docElement,
|
||||||
|
series
|
||||||
|
);
|
||||||
|
|
||||||
|
addNewLinks(store, links, series);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
||||||
+25
-12
@@ -1,5 +1,5 @@
|
|||||||
import {Config} from '../config';
|
|
||||||
import {Link} from './model';
|
import {Link} from './model';
|
||||||
|
import {config} from '../config';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the brand should be checked for stock
|
* Returns true if the brand should be checked for stock
|
||||||
@@ -7,27 +7,40 @@ import {Link} from './model';
|
|||||||
* @param brand The brand of the GPU
|
* @param brand The brand of the GPU
|
||||||
*/
|
*/
|
||||||
function filterBrand(brand: Link['brand']): boolean {
|
function filterBrand(brand: Link['brand']): boolean {
|
||||||
if (Config.store.showOnlyBrands.length === 0) {
|
if (config.store.showOnlyBrands.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Config.store.showOnlyBrands.includes(brand);
|
return config.store.showOnlyBrands.includes(brand);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the model should be checked for stock
|
* Returns true if the model should be checked for stock
|
||||||
*
|
*
|
||||||
* @param model The model of the GPU
|
* @param model The model of the GPU
|
||||||
|
* @param series The series of the GPU
|
||||||
*/
|
*/
|
||||||
function filterModel(model: Link['model']): boolean {
|
function filterModel(model: Link['model'], series: Link['series']): boolean {
|
||||||
if (Config.store.showOnlyModels.length === 0) {
|
if (config.store.showOnlyModels.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sanitizedModel = model.replace(/\s/g, '');
|
const sanitizedModel = model.replace(/\s/g, '');
|
||||||
for (const configModel of Config.store.showOnlyModels) {
|
const sanitizedSeries = series.replace(/\s/g, '');
|
||||||
const sanitizedConfigModel = configModel.replace(/\s/g, '');
|
for (const configModelEntry of config.store.showOnlyModels) {
|
||||||
if (sanitizedModel === sanitizedConfigModel) {
|
const sanitizedConfigModel = configModelEntry.name.replace(/\s/g, '');
|
||||||
|
const sanitizedConfigSeries = configModelEntry.series.replace(
|
||||||
|
/\s/g,
|
||||||
|
''
|
||||||
|
);
|
||||||
|
if (sanitizedConfigSeries) {
|
||||||
|
if (
|
||||||
|
sanitizedSeries === sanitizedConfigSeries &&
|
||||||
|
sanitizedModel === sanitizedConfigModel
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (sanitizedModel === sanitizedConfigModel) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,12 +53,12 @@ function filterModel(model: Link['model']): boolean {
|
|||||||
*
|
*
|
||||||
* @param series The series of the GPU
|
* @param series The series of the GPU
|
||||||
*/
|
*/
|
||||||
function filterSeries(series: Link['series']): boolean {
|
export function filterSeries(series: Link['series']): boolean {
|
||||||
if (Config.store.showOnlySeries.length === 0) {
|
if (config.store.showOnlySeries.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Config.store.showOnlySeries.includes(series);
|
return config.store.showOnlySeries.includes(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,7 +69,7 @@ function filterSeries(series: Link['series']): boolean {
|
|||||||
export function filterStoreLink(link: Link): boolean {
|
export function filterStoreLink(link: Link): boolean {
|
||||||
return (
|
return (
|
||||||
filterBrand(link.brand) &&
|
filterBrand(link.brand) &&
|
||||||
filterModel(link.model) &&
|
filterModel(link.model, link.series) &&
|
||||||
filterSeries(link.series)
|
filterSeries(link.series)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,138 @@
|
|||||||
|
import {Element, LabelQuery, Pricing} from './model';
|
||||||
|
import {Page} from 'puppeteer';
|
||||||
|
import {logger} from '../logger';
|
||||||
|
|
||||||
|
export type Selector = {
|
||||||
|
requireVisible: boolean;
|
||||||
|
selector: string;
|
||||||
|
type: 'innerHTML' | 'outerHTML' | 'textContent';
|
||||||
|
};
|
||||||
|
|
||||||
|
function isElementArray(query: LabelQuery): query is Element[] {
|
||||||
|
return (
|
||||||
|
Array.isArray(query) && query.length > 0 && typeof query[0] === 'object'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getQueryAsElementArray(
|
||||||
|
query: LabelQuery,
|
||||||
|
defaultContainer: string
|
||||||
|
): Array<Required<Element>> {
|
||||||
|
if (isElementArray(query)) {
|
||||||
|
return query.map((x) => ({
|
||||||
|
container: x.container ?? defaultContainer,
|
||||||
|
text: x.text
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(query)) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
container: defaultContainer,
|
||||||
|
text: query
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
container: query.container ?? defaultContainer,
|
||||||
|
text: query.text
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function pageIncludesLabels(
|
||||||
|
page: Page,
|
||||||
|
query: LabelQuery,
|
||||||
|
options: Selector
|
||||||
|
) {
|
||||||
|
const elementQueries = getQueryAsElementArray(query, options.selector);
|
||||||
|
|
||||||
|
const resolved = await Promise.all(
|
||||||
|
elementQueries.map(async (query) => {
|
||||||
|
const selector = {...options, selector: query.container};
|
||||||
|
const contents = (await extractPageContents(page, selector)) ?? '';
|
||||||
|
|
||||||
|
if (!contents) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(contents);
|
||||||
|
|
||||||
|
return includesLabels(contents, query.text);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return resolved.includes(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function extractPageContents(
|
||||||
|
page: Page,
|
||||||
|
selector: Selector
|
||||||
|
): Promise<string | null> {
|
||||||
|
return page.evaluate((options: Selector) => {
|
||||||
|
const element: globalThis.HTMLElement | null = document.querySelector(
|
||||||
|
options.selector
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
options.requireVisible &&
|
||||||
|
!(element.offsetWidth > 0 && element.offsetHeight > 0)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (options.type) {
|
||||||
|
case 'innerHTML':
|
||||||
|
return element.innerHTML;
|
||||||
|
case 'outerHTML':
|
||||||
|
return element.outerHTML;
|
||||||
|
case 'textContent':
|
||||||
|
return element.textContent;
|
||||||
|
default:
|
||||||
|
return 'Error: selector.type is unknown';
|
||||||
|
}
|
||||||
|
}, selector);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if DOM has any related text.
|
* Checks if DOM has any related text.
|
||||||
*
|
*
|
||||||
* @param domText Complete DOM of website.
|
* @param domText Complete DOM of website.
|
||||||
* @param searchLabels Search labels for a match.
|
* @param searchLabels Search labels for a match.
|
||||||
*/
|
*/
|
||||||
export function includesLabels(domText: string, searchLabels: string[]): boolean {
|
export function includesLabels(
|
||||||
|
domText: string,
|
||||||
|
searchLabels: string[]
|
||||||
|
): boolean {
|
||||||
const domTextLowerCase = domText.toLowerCase();
|
const domTextLowerCase = domText.toLowerCase();
|
||||||
return searchLabels.some(label => domTextLowerCase.includes(label));
|
return searchLabels.some((label) =>
|
||||||
|
domTextLowerCase.includes(label.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPrice(
|
||||||
|
page: Page,
|
||||||
|
query: Pricing,
|
||||||
|
options: Selector
|
||||||
|
): Promise<number | null> {
|
||||||
|
const selector = {...options, selector: query.container};
|
||||||
|
const priceString = await extractPageContents(page, selector);
|
||||||
|
|
||||||
|
if (priceString) {
|
||||||
|
const priceSeparator = query.euroFormat ? /\./g : /,/g;
|
||||||
|
const price = Number.parseFloat(
|
||||||
|
priceString.replace(priceSeparator, '').match(/\d+/g)!.join('.')
|
||||||
|
);
|
||||||
|
|
||||||
|
logger.debug('received price', price);
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+366
-74
@@ -1,15 +1,137 @@
|
|||||||
import {Browser, Page, Response} from 'puppeteer';
|
import {
|
||||||
import {Link, Store} from './model';
|
Browser,
|
||||||
import {Logger, Print} from '../logger';
|
Page,
|
||||||
import {closePage, delay, getSleepTime} from '../util';
|
PageEventObj,
|
||||||
import {Config} from '../config';
|
Request,
|
||||||
|
RespondOptions,
|
||||||
|
Response
|
||||||
|
} from 'puppeteer';
|
||||||
|
import {Link, Store, getStores} from './model';
|
||||||
|
import {Print, logger} from '../logger';
|
||||||
|
import {Selector, getPrice, pageIncludesLabels} from './includes-labels';
|
||||||
|
import {
|
||||||
|
closePage,
|
||||||
|
delay,
|
||||||
|
getRandomUserAgent,
|
||||||
|
getSleepTime,
|
||||||
|
isStatusCodeInRange
|
||||||
|
} from '../util';
|
||||||
|
import {disableBlockerInPage, enableBlockerInPage} from '../adblocker';
|
||||||
|
import {config} from '../config';
|
||||||
|
import {fetchLinks} from './fetch-links';
|
||||||
import {filterStoreLink} from './filter';
|
import {filterStoreLink} from './filter';
|
||||||
import {includesLabels} from './includes-labels';
|
|
||||||
import open from 'open';
|
import open from 'open';
|
||||||
|
import {processBackoffDelay} from './model/helpers/backoff';
|
||||||
import {sendNotification} from '../notification';
|
import {sendNotification} from '../notification';
|
||||||
|
import useProxy from 'puppeteer-page-proxy';
|
||||||
|
|
||||||
const inStock: Record<string, boolean> = {};
|
const inStock: Record<string, boolean> = {};
|
||||||
|
|
||||||
|
const linkBuilderLastRunTimes: Record<string, number> = {};
|
||||||
|
|
||||||
|
function nextProxy(store: Store) {
|
||||||
|
if (!store.proxyList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store.currentProxyIndex === undefined) {
|
||||||
|
store.currentProxyIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
store.currentProxyIndex++;
|
||||||
|
if (store.currentProxyIndex >= store.proxyList.length) {
|
||||||
|
store.currentProxyIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
`ℹ [${store.name}] Next proxy index: ${store.currentProxyIndex} / Count: ${store.proxyList.length}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return store.proxyList[store.currentProxyIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleLowBandwidth(request: Request) {
|
||||||
|
if (!config.browser.lowBandwidth) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const typ = request.resourceType();
|
||||||
|
if (typ === 'font' || typ === 'image') {
|
||||||
|
try {
|
||||||
|
await request.abort();
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleProxy(request: Request, proxy?: string) {
|
||||||
|
if (!proxy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await useProxy(request, proxy);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error(error);
|
||||||
|
try {
|
||||||
|
await request.abort();
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleAdBlock(request: Request, adBlockRequestHandler: any) {
|
||||||
|
if (!adBlockRequestHandler) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const continueFunc = async () => {
|
||||||
|
resolve(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const abortFunc = async () => {
|
||||||
|
try {
|
||||||
|
await request.abort();
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const respondFunc = async (response: RespondOptions) => {
|
||||||
|
try {
|
||||||
|
await request.respond(response);
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const requestProxy = new Proxy(request, {
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
if (prop === 'continue') {
|
||||||
|
return continueFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop === 'abort') {
|
||||||
|
return abortFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop === 'respond') {
|
||||||
|
return respondFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Reflect.get(target, prop, receiver);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
adBlockRequestHandler(requestProxy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for looking up information about a each product within
|
* Responsible for looking up information about a each product within
|
||||||
* a `Store`. It's important that we ignore `no-await-in-loop` here
|
* a `Store`. It's important that we ignore `no-await-in-loop` here
|
||||||
@@ -19,116 +141,286 @@ const inStock: Record<string, boolean> = {};
|
|||||||
* @param store Vendor of graphics cards.
|
* @param store Vendor of graphics cards.
|
||||||
*/
|
*/
|
||||||
async function lookup(browser: Browser, store: Store) {
|
async function lookup(browser: Browser, store: Store) {
|
||||||
|
if (!getStores().has(store.name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store.linksBuilder) {
|
||||||
|
const lastRunTime = linkBuilderLastRunTimes[store.name] ?? -1;
|
||||||
|
const ttl = store.linksBuilder.ttl ?? Number.MAX_SAFE_INTEGER;
|
||||||
|
if (lastRunTime === -1 || Date.now() - lastRunTime > ttl) {
|
||||||
|
logger.info(`[${store.name}] Running linksBuilder...`);
|
||||||
|
try {
|
||||||
|
await fetchLinks(store, browser);
|
||||||
|
linkBuilderLastRunTimes[store.name] = Date.now();
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
for (const link of store.links) {
|
for (const link of store.links) {
|
||||||
if (!filterStoreLink(link)) {
|
if (!filterStoreLink(link)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = await browser.newPage();
|
if (config.page.inStockWaitTime && inStock[link.url]) {
|
||||||
page.setDefaultNavigationTimeout(Config.page.navigationTimeout);
|
logger.info(Print.inStockWaiting(link, store, true));
|
||||||
await page.setUserAgent(Config.page.userAgent);
|
continue;
|
||||||
|
|
||||||
try {
|
|
||||||
await lookupCard(browser, store, page, link);
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error(`✖ [${store.name}] ${link.brand} ${link.model} - ${error.message as string}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const proxy = nextProxy(store);
|
||||||
|
|
||||||
|
const useAdBlock =
|
||||||
|
!config.browser.lowBandwidth && !store.disableAdBlocker;
|
||||||
|
const customContext = config.browser.isIncognito;
|
||||||
|
|
||||||
|
const context = customContext
|
||||||
|
? await browser.createIncognitoBrowserContext()
|
||||||
|
: browser.defaultBrowserContext();
|
||||||
|
const page = await context.newPage();
|
||||||
|
await page.setRequestInterception(true);
|
||||||
|
|
||||||
|
page.setDefaultNavigationTimeout(config.page.timeout);
|
||||||
|
await page.setUserAgent(await getRandomUserAgent());
|
||||||
|
|
||||||
|
let adBlockRequestHandler: any;
|
||||||
|
let pageProxy;
|
||||||
|
if (useAdBlock) {
|
||||||
|
const onProxyFunc = (event: keyof PageEventObj, handler: any) => {
|
||||||
|
if (event !== 'request') {
|
||||||
|
page.on(event, handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
adBlockRequestHandler = handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
pageProxy = new Proxy(page, {
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
if (prop === 'on') {
|
||||||
|
return onProxyFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Reflect.get(target, prop, receiver);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await enableBlockerInPage(pageProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.setRequestInterception(true);
|
||||||
|
page.on('request', async (request) => {
|
||||||
|
if (await handleLowBandwidth(request)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await handleAdBlock(request, adBlockRequestHandler)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await handleProxy(request, proxy)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await request.continue();
|
||||||
|
} catch {}
|
||||||
|
});
|
||||||
|
|
||||||
|
let statusCode = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
statusCode = await lookupCard(browser, store, page, link);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error(
|
||||||
|
`✖ [${store.name}] ${link.brand} ${link.series} ${
|
||||||
|
link.model
|
||||||
|
} - ${(error as Error).message}`
|
||||||
|
);
|
||||||
|
const client = await page.target().createCDPSession();
|
||||||
|
await client.send('Network.clearBrowserCookies');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pageProxy) {
|
||||||
|
await disableBlockerInPage(pageProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must apply backoff before closing the page, e.g. if CloudFlare is
|
||||||
|
// used to detect bot traffic, it introduces a 5 second page delay
|
||||||
|
// before redirecting to the next page
|
||||||
|
await processBackoffDelay(store, link, statusCode);
|
||||||
await closePage(page);
|
await closePage(page);
|
||||||
|
if (customContext) {
|
||||||
|
await context.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* eslint-enable no-await-in-loop */
|
/* eslint-enable no-await-in-loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
async function lookupCard(browser: Browser, store: Store, page: Page, link: Link) {
|
async function lookupCard(
|
||||||
|
browser: Browser,
|
||||||
|
store: Store,
|
||||||
|
page: Page,
|
||||||
|
link: Link
|
||||||
|
): Promise<number> {
|
||||||
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
|
const givenWaitFor = store.waitUntil ? store.waitUntil : 'networkidle0';
|
||||||
const response: Response | null = await page.goto(link.url, {waitUntil: givenWaitFor});
|
const response: Response | null = await page.goto(link.url, {
|
||||||
|
waitUntil: givenWaitFor
|
||||||
|
});
|
||||||
|
|
||||||
if (await lookupCardInStock(store, page)) {
|
if (!response) {
|
||||||
const givenUrl = link.cartUrl ? link.cartUrl : link.url;
|
logger.debug(Print.noResponse(link, store, true));
|
||||||
Logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
|
}
|
||||||
|
|
||||||
if (Config.browser.open) {
|
const successStatusCodes = store.successStatusCodes ?? [[0, 399]];
|
||||||
if (link.openCartAction === undefined) {
|
const statusCode = response?.status() ?? 0;
|
||||||
await open(givenUrl);
|
if (!isStatusCodeInRange(statusCode, successStatusCodes)) {
|
||||||
} else {
|
if (statusCode === 429) {
|
||||||
await link.openCartAction(browser);
|
logger.warn(Print.rateLimit(link, store, true));
|
||||||
}
|
} else {
|
||||||
|
logger.warn(Print.badStatusCode(link, store, statusCode, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await lookupCardInStock(store, page, link)) {
|
||||||
|
const givenUrl =
|
||||||
|
link.cartUrl && config.store.autoAddToCart
|
||||||
|
? link.cartUrl
|
||||||
|
: link.url;
|
||||||
|
logger.info(`${Print.inStock(link, store, true)}\n${givenUrl}`);
|
||||||
|
|
||||||
|
if (config.browser.open) {
|
||||||
|
await (link.openCartAction === undefined
|
||||||
|
? open(givenUrl)
|
||||||
|
: link.openCartAction(browser));
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNotification(link, store);
|
sendNotification(link, store);
|
||||||
|
|
||||||
if (Config.page.inStockWaitTime) {
|
if (config.page.inStockWaitTime) {
|
||||||
inStock[store.name] = true;
|
inStock[link.url] = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inStock[store.name] = false;
|
inStock[link.url] = false;
|
||||||
}, 1000 * Config.page.inStockWaitTime);
|
}, 1000 * config.page.inStockWaitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.page.screenshot) {
|
if (config.page.screenshot) {
|
||||||
Logger.debug('ℹ saving screenshot');
|
logger.debug('ℹ saving screenshot');
|
||||||
|
|
||||||
link.screenshot = `success-${Date.now()}.png`;
|
link.screenshot = `success-${Date.now()}.png`;
|
||||||
await page.screenshot({path: link.screenshot});
|
await page.screenshot({path: link.screenshot});
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await lookupPageHasCaptcha(store, page)) {
|
return statusCode;
|
||||||
Logger.warn(Print.captcha(link, store, true));
|
|
||||||
await delay(getSleepTime());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && response.status() === 429) {
|
|
||||||
Logger.warn(Print.rateLimit(link, store, true));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(Print.outOfStock(link, store, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function lookupCardInStock(store: Store, page: Page) {
|
async function lookupCardInStock(store: Store, page: Page, link: Link) {
|
||||||
const stockHandle = await page.$(store.labels.inStock.container);
|
const baseOptions: Selector = {
|
||||||
|
requireVisible: false,
|
||||||
|
selector: store.labels.container ?? 'body',
|
||||||
|
type: 'textContent'
|
||||||
|
};
|
||||||
|
|
||||||
const visible = await page.evaluate(element => element && element.offsetWidth > 0 && element.offsetHeight > 0, stockHandle);
|
if (store.labels.captcha) {
|
||||||
if (!visible) {
|
if (await pageIncludesLabels(page, store.labels.captcha, baseOptions)) {
|
||||||
return false;
|
logger.warn(Print.captcha(link, store, true));
|
||||||
|
await delay(getSleepTime(store));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stockContent = await page.evaluate(element => element.outerHTML, stockHandle);
|
if (store.labels.bannedSeller) {
|
||||||
|
if (
|
||||||
Logger.debug(stockContent);
|
await pageIncludesLabels(
|
||||||
|
page,
|
||||||
return includesLabels(stockContent, store.labels.inStock.text);
|
store.labels.bannedSeller,
|
||||||
}
|
baseOptions
|
||||||
|
)
|
||||||
async function lookupPageHasCaptcha(store: Store, page: Page) {
|
) {
|
||||||
if (!store.labels.captcha) {
|
logger.warn(Print.bannedSeller(link, store, true));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const captchaHandle = await page.$(store.labels.captcha.container);
|
if (store.labels.maxPrice) {
|
||||||
const captchaContent = await page.evaluate(element => element.textContent, captchaHandle);
|
const maxPrice = config.store.maxPrice.series[link.series];
|
||||||
|
|
||||||
return includesLabels(captchaContent, store.labels.captcha.text);
|
link.price = await getPrice(page, store.labels.maxPrice, baseOptions);
|
||||||
|
|
||||||
|
if (link.price && link.price > maxPrice && maxPrice > 0) {
|
||||||
|
logger.info(Print.maxPrice(link, store, maxPrice, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixme: currently causing issues
|
||||||
|
// Do API inventory validation in realtime (no cache) if available
|
||||||
|
// if (
|
||||||
|
// store.realTimeInventoryLookup !== undefined &&
|
||||||
|
// link.itemNumber !== undefined
|
||||||
|
// ) {
|
||||||
|
// return store.realTimeInventoryLookup(link.itemNumber);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (store.labels.outOfStock) {
|
||||||
|
if (
|
||||||
|
await pageIncludesLabels(page, store.labels.outOfStock, baseOptions)
|
||||||
|
) {
|
||||||
|
logger.info(Print.outOfStock(link, store, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store.labels.inStock) {
|
||||||
|
const options = {
|
||||||
|
...baseOptions,
|
||||||
|
requireVisible: true,
|
||||||
|
type: 'outerHTML' as const
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(await pageIncludesLabels(page, store.labels.inStock, options))) {
|
||||||
|
logger.info(Print.outOfStock(link, store, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link.labels?.inStock) {
|
||||||
|
const options = {
|
||||||
|
...baseOptions,
|
||||||
|
requireVisible: true,
|
||||||
|
type: 'outerHTML' as const
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(await pageIncludesLabels(page, link.labels.inStock, options))) {
|
||||||
|
logger.info(Print.outOfStock(link, store, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function tryLookupAndLoop(browser: Browser, store: Store) {
|
export async function tryLookupAndLoop(browser: Browser, store: Store) {
|
||||||
Logger.debug(`[${store.name}] Starting lookup...`);
|
if (!browser.isConnected()) {
|
||||||
try {
|
logger.debug(
|
||||||
if (Config.page.inStockWaitTime && inStock[store.name]) {
|
`[${store.name}] Ending this loop as browser is disposed...`
|
||||||
Logger.info(`[${store.name}] Has stock, waiting before trying to lookup again...`);
|
);
|
||||||
} else {
|
return;
|
||||||
await lookup(browser, store);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
Logger.error(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sleepTime = getSleepTime();
|
logger.debug(`[${store.name}] Starting lookup...`);
|
||||||
Logger.debug(`[${store.name}] Lookup done, next one in ${sleepTime} ms`);
|
try {
|
||||||
|
await lookup(browser, store);
|
||||||
|
} catch (error: unknown) {
|
||||||
|
logger.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sleepTime = getSleepTime(store);
|
||||||
|
logger.debug(`[${store.name}] Lookup done, next one in ${sleepTime} ms`);
|
||||||
setTimeout(tryLookupAndLoop, sleepTime, browser, store);
|
setTimeout(tryLookupAndLoop, sleepTime, browser, store);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const Adorama: Store = {
|
export const Adorama: Store = {
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
captcha: {
|
captcha: {
|
||||||
container: 'body',
|
container: 'body',
|
||||||
@@ -9,6 +10,10 @@ export const Adorama: Store = {
|
|||||||
inStock: {
|
inStock: {
|
||||||
container: '.buy-section.purchase',
|
container: '.buy-section.purchase',
|
||||||
text: ['add to cart']
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.your-price',
|
||||||
|
euroFormat: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
@@ -20,7 +25,7 @@ export const Adorama: Store = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'pny',
|
||||||
model: 'xlr8',
|
model: 'xlr8 revel',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.adorama.com/pnv301tfxmpb.html'
|
url: 'https://www.adorama.com/pnv301tfxmpb.html'
|
||||||
},
|
},
|
||||||
@@ -68,9 +73,57 @@ export const Adorama: Store = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'pny',
|
||||||
model: 'xlr8 rbg',
|
model: 'xlr8 revel',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.adorama.com/png30801tfxb.html'
|
url: 'https://www.adorama.com/png30801tfxb.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.adorama.com/asrx3080o10g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.adorama.com/astr3080o10g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.adorama.com/astrx308010g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.adorama.com/msig390gxt24.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.adorama.com/msig39v3x24c.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.adorama.com/asrtx309024g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.adorama.com/ast3090o24g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.adorama.com/asrx3090o24g.html'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'adorama'
|
name: 'adorama'
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AlternateNL: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.stockStatus',
|
||||||
|
text: ['Direct leverbaar']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: 'div.price > span',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.stockStatus',
|
||||||
|
text: ['Levertermijn onbekend', 'pre-order']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.alternate.nl/product/1516616'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672756'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672345'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672251'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672753'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672343'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672634'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672867'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673512'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672612'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1674164'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1672868'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
model: 'gaming pro oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673431'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1677989'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1681134'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673520'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix gs',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673442'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673136'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673524'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1680168'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673517'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'amp holo',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1677985'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'amp extreme holo',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1677982'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'twin x2 oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673137'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x4',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.nl/product/1673134'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'alternate-nl'
|
||||||
|
};
|
||||||
@@ -0,0 +1,429 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const Alternate: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.stockStatus',
|
||||||
|
text: [
|
||||||
|
'auf lager',
|
||||||
|
'ware neu eingetroffen',
|
||||||
|
'in kürze versandfertig',
|
||||||
|
'ware im zulauf'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: 'div.price > span',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '.stockStatus',
|
||||||
|
text: ['liefertermin unbekannt']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '.stockStatus',
|
||||||
|
text: ['Artikel kann nicht gekauft werden']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.alternate.de/product/1662088'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672868'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672867'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672251'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672634'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673517'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673524'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673512'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673520'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1674164'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phantom gs',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1688597'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix gs',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673442'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1680168'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus xtreme',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1680168'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672756'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672753'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1681134'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673136'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x4',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673134'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'twin x2 oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673137'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672343'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672345'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
model: 'gamerock oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1688594'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
model: 'gaming pro oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1673431'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'amp extreme holo',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1677982'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'amp holo',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1677985'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1677989'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.alternate.de/product/1672612'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672870'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672872'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672259'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672629'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673530'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673531'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673521'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673525'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673529'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix gs',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673440'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus xtreme',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1680670'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1687793'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672744'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672749'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'turbo',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1687703'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'gaming x3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673131'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673135'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x4',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673129'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672341'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672346'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
model: 'gaming pro oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1673434'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.alternate.de/product/1672611'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.alternate.de/product/1685588'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.alternate.de/product/1685585'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.alternate.de/product/1685590'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.alternate.de/product/1685584'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.alternate.de/product/1651220'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.alternate.de/product/1651221'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
model: 'merc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.alternate.de/product/1698792'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
model: 'nitro oc se',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.alternate.de/product/1696478'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
model: 'nitro oc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.alternate.de/product/1696482'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix lc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.alternate.de/product/1695392'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.alternate.de/product/1697044'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url: 'https://www.alternate.de/product/1702773'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url: 'https://www.alternate.de/product/1700508'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.alternate.de/product/1675115'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.alternate.de/product/1675117'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.alternate.de/product/1676874'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'alternate'
|
||||||
|
};
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const AmazonCa: Store = {
|
export const AmazonCa: Store = {
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
captcha: {
|
captcha: {
|
||||||
container: 'body',
|
container: 'body',
|
||||||
@@ -9,80 +10,267 @@ export const AmazonCa: Store = {
|
|||||||
inStock: {
|
inStock: {
|
||||||
container: '#desktop_buybox',
|
container: '#desktop_buybox',
|
||||||
text: ['add to cart']
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B07PBLD2MX&Quantity.1=1',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.amazon.ca/dp/B07PBLD2MX'
|
url: 'https://www.amazon.ca/dp/B07PBLD2MX'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08KWN2LZG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08KWLMZV4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08LW46GH2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08L8L71SM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08L8L9TCZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1',
|
||||||
model: 'gaming x trio',
|
model: 'gaming x trio',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR7SV3M'
|
url: 'https://www.amazon.ca/dp/B08HR7SV3M'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HR5SXPS'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1',
|
||||||
model: 'ftw3',
|
model: 'ftw3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR3DPGW'
|
url: 'https://www.amazon.ca/dp/B08HR3DPGW'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
|
||||||
model: 'ftw3 ultra',
|
model: 'ftw3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR3Y5GQ'
|
url: 'https://www.amazon.ca/dp/B08HR3Y5GQ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
|
||||||
model: 'xc3 ultra',
|
model: 'xc3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR55YB5'
|
url: 'https://www.amazon.ca/dp/B08HR55YB5'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
|
||||||
model: 'xc3',
|
model: 'xc3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR4RJ3Q'
|
url: 'https://www.amazon.ca/dp/B08HR4RJ3Q'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
|
||||||
model: 'xc3 black',
|
model: 'xc3 black',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR6FMF3'
|
url: 'https://www.amazon.ca/dp/B08HR6FMF3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
|
||||||
model: 'gaming oc',
|
model: 'gaming oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HJTH61J'
|
url: 'https://www.amazon.ca/dp/B08HJTH61J'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
|
||||||
model: 'eagle oc',
|
model: 'eagle oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HJS2JLJ'
|
url: 'https://www.amazon.ca/dp/B08HJS2JLJ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HHDP9DW'
|
url: 'https://www.amazon.ca/dp/B08HHDP9DW'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
|
||||||
model: 'tuf oc',
|
model: 'tuf oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HH5WF97'
|
url: 'https://www.amazon.ca/dp/B08HH5WF97'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'zotac',
|
||||||
model: 'ventus 3x oc',
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.ca/dp/B08HR5SXPS'
|
url: 'https://www.amazon.ca/dp/B08HJNKT3P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HJQ182D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HR9D2JS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HJRF2CN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HJPDJTY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HJGNJ81'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08HJLLF7G'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.ca/dp/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.ca/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08GSC5D9G&Quantity.1=1',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08GSC5D9G'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08GS1N24H&Quantity.1=1',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08GS1N24H'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08H75RTZ8&Quantity.1=1',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08H75RTZ8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.ca/gp/aws/cart/add.html?ASIN.1=B08G9J44ZN&Quantity.1=1',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.ca/dp/B08G9J44ZN'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'amazon-ca'
|
name: 'amazon-ca'
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmazonDeWarehouse: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: [
|
||||||
|
'geben sie die unten angezeigten zeichen ein',
|
||||||
|
'geben sie die zeichen unten ein'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
inStock: {
|
||||||
|
container: '#a-autoid-0-announce',
|
||||||
|
text: ['In den Einkaufswagen']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: 'a-size-large a-color-price olpOfferPrice a-text-bold',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '.a-size-medium',
|
||||||
|
text: [
|
||||||
|
'Derzeit gibt es keine Verkäufer, die diesen Artikel an Ihren Standort liefern können'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amazon.de/gp/offer-listing/B07PW9VBK5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.de/gp/offer-listing/B08H93ZRK9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.de/gp/offer-listing/B08H98GVK8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.de/gp/offer-listing/B087VM5XC6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.de/gp/offer-listing/B08H93ZRLL'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amazon-de-warehouse'
|
||||||
|
};
|
||||||
+487
-30
@@ -1,100 +1,557 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const AmazonDe: Store = {
|
export const AmazonDe: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '€',
|
||||||
labels: {
|
labels: {
|
||||||
captcha: {
|
captcha: {
|
||||||
container: 'body',
|
container: 'body',
|
||||||
text: ['geben sie die unten angezeigten zeichen ein']
|
text: [
|
||||||
|
'geben sie die unten angezeigten zeichen ein',
|
||||||
|
'geben sie die zeichen unten ein'
|
||||||
|
]
|
||||||
},
|
},
|
||||||
inStock: {
|
inStock: {
|
||||||
container: '#desktop_buybox',
|
container: '#add-to-cart-button',
|
||||||
text: ['in den einkaufswagen']
|
text: ['in den einkaufswagen']
|
||||||
}
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '#availability',
|
||||||
|
text: ['Derzeit nicht verfügbar']
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B07PW9VBK5&Quantity.1=1',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.amazon.com/dp/B07MQ36Z6L'
|
url: 'https://www.amazon.de/dp/B07PW9VBK5'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'asus',
|
||||||
model: 'xlr8',
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN7VVLJ&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HBTJMLJ'
|
url: 'https://www.amazon.de/dp/B08HN7VVLJ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'asus',
|
||||||
model: 'xlr8-rgb',
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN6KYS3&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HBR7QBM'
|
url: 'https://www.amazon.de/dp/B08HN6KYS3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'asus',
|
||||||
model: 'gaming x trio',
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN37VQK&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HM4V2DH'
|
url: 'https://www.amazon.de/dp/B08HN37VQK'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'asus',
|
||||||
model: 'ftw3 ultra',
|
cartUrl:
|
||||||
series: '3080',
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN4DSTC&Quantity.1=1',
|
||||||
url: 'https://www.amazon.de/dp/B08HGYXP4C'
|
model: 'tuf oc',
|
||||||
},
|
series: '3080',
|
||||||
{
|
url: 'https://www.amazon.de/dp/B08HN4DSTC'
|
||||||
brand: 'evga',
|
|
||||||
model: 'xc3 ultra',
|
|
||||||
series: '3080',
|
|
||||||
url: 'https://www.amazon.de/dp/B08HJ9XFNM'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGBYWQ6&Quantity.1=1',
|
||||||
model: 'ftw3',
|
model: 'ftw3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HGBYWQ6'
|
url: 'https://www.amazon.de/dp/B08HGBYWQ6'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGYXP4C&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGYXP4C'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGLN78Q&Quantity.1=1',
|
||||||
model: 'xc3',
|
model: 'xc3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HGLN78Q'
|
url: 'https://www.amazon.de/dp/B08HGLN78Q'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
|
||||||
model: 'xc3 black',
|
model: 'xc3 black',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HH1BMQQ'
|
url: 'https://www.amazon.de/dp/B08HH1BMQQ'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HJ9XFNM'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHLDS72&Quantity.1=1',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KHLDS72'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HHZVZ3N&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HHZVZ3N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HLZXHZY&Quantity.1=1',
|
||||||
model: 'gaming oc',
|
model: 'gaming oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HLZXHZY'
|
url: 'https://www.amazon.de/dp/B08HLZXHZY'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
model: 'eagle oc',
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KH7RL89&Quantity.1=1',
|
||||||
|
model: 'vision oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HHZVZ3N'
|
url: 'https://www.amazon.de/dp/B08KH7RL89'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'inno3d',
|
||||||
model: 'tuf',
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JD6QPXD&Quantity.1=1',
|
||||||
|
model: 'twin x2 oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HN4DSTC'
|
url: 'https://www.amazon.de/dp/B08JD6QPXD'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HM4V2DH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
|
||||||
model: 'ventus 3x oc',
|
model: 'ventus 3x oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HM4M621'
|
url: 'https://www.amazon.de/dp/B08HM4M621'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JCVWTQY&Quantity.1=1',
|
||||||
|
model: 'gaming pro',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08JCVWTQY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JCKYYL8&Quantity.1=1',
|
||||||
|
model: 'gaming pro oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.de/dp/B08JCKYYL8'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
brand: 'zotac',
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HR1NPPQ&Quantity.1=1',
|
||||||
model: 'trinity',
|
model: 'trinity',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.de/dp/B08HR1NPPQ'
|
url: 'https://www.amazon.de/dp/B08HR1NPPQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN642LY&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HN642LY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN51T8Q&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HN51T8Q'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN4FLFJ&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HN4FLFJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HN5B8FJ&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HN5B8FJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGFNPJQ&Quantity.1=1',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGFNPJQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08J5NMDP7&Quantity.1=1',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08J5NMDP7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGS1SXH&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGS1SXH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGZ4XSZ&Quantity.1=1',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGZ4XSZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGKQ527&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGKQ527'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HGTNDL4&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HGTNDL4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KH7R4FQ&Quantity.1=1',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KH7R4FQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HJPDJTY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHKDTSJ&Quantity.1=1',
|
||||||
|
model: 'turbo',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KHKDTSJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HJRF2CN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HRBW6VB'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HM661YM&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HM661YM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'palit',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08JQQ1VD1&Quantity.1=1',
|
||||||
|
model: 'gaming pro',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08JQQ1VD1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HR6ZBYJ&Quantity.1=1',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HR6ZBYJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HJQ182D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HSJ1622&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HSJ1622'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHFZN9P&Quantity.1=1',
|
||||||
|
model: 'dual oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KHFZN9P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HT7PR9Y&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HT7PR9Y'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08L8JNTXQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KWPDXJZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L6PCZTR&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08L6PCZTR'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KWN2LZG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08M13DXSZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHL21CV&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KHL21CV'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08KHL2J5X&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08KHL2J5X'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3QCZKZ&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08L3QCZKZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3QZP7W&Quantity.1=1',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08L3QZP7W'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08L3Q41SM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08L3Q41SM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HRBR7K9&Quantity.1=1',
|
||||||
|
model: 'twin edge',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HRBR7K9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08LBVNKT1&Quantity.1=1',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08LBVNKT1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
|
||||||
|
model: 'dual fan',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HBF5L3K'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.de/dp/B08HBJB7YD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.de/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.de/dp/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.de/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.de/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H93ZRK9&Quantity.1=1',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '#productTitle',
|
||||||
|
text: ['sony playstation 5']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.de/dp/B08H93ZRK9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H98GVK8&Quantity.1=1',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '#productTitle',
|
||||||
|
text: ['sony playstation 5']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.de/dp/B08H98GVK8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
// Fixme: disabled because of #1095, enable when working again
|
||||||
|
// cartUrl:
|
||||||
|
// 'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B08H93ZRLL&Quantity.1=1',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.de/dp/B08H93ZRLL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
// Fixme: disabled because of #1095, enable when working again
|
||||||
|
// cartUrl:
|
||||||
|
// 'https://www.amazon.de/gp/aws/cart/add.html?ASIN.1=B087VM5XC6&Quantity.1=1',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.de/dp/B087VM5XC6'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'amazon-de'
|
name: 'amazon-de'
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmazonEs: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: ['introduzca los caracteres que ve a continuación']
|
||||||
|
},
|
||||||
|
inStock: {
|
||||||
|
container: '#desktop_buybox',
|
||||||
|
text: ['añadir a la cesta']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice'
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '#availability',
|
||||||
|
text: ['No disponible']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B07PW9VBK5&Quantity.1=1',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amazon.es/dp/B07PW9VBK5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HM4V2DH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGYXP4C&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HGYXP4C'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HJ9XFNM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGBYWQ6&Quantity.1=1',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HGBYWQ6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HGLN78Q&Quantity.1=1',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HGLN78Q'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HH1BMQQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HLZXHZY&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HLZXHZY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HHZVZ3N&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HHZVZ3N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN37VQK&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HN37VQK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN4DSTC&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HN4DSTC'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HN6KYS3&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HN6KYS3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HM4M621'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08HR1NPPQ&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.es/dp/B08HR1NPPQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.es/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.es/dp/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.es/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.es/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08KKJ37F7&Quantity.1=1',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.es/dp/B08KKJ37F7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08KJF2D25&Quantity.1=1',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.es/dp/B08KJF2D25'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B08H93ZRLL&Quantity.1=1',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.es/dp/B08H93ZRLL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.es/gp/aws/cart/add.html?ASIN.1=B087VM5XC6&Quantity.1=1',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.es/dp/B087VM5XC6'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amazon-es'
|
||||||
|
};
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmazonFr: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: ['entrez les caractères que vous voyez ci-dessous']
|
||||||
|
},
|
||||||
|
inStock: {
|
||||||
|
container: '#desktop_buybox',
|
||||||
|
text: ['ajouter au panier']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '#availability',
|
||||||
|
text: ['Actuellement indisponible']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amazon.fr/dp/B07PW9VBK5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR7SV3M'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR5SXPS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR3DPGW'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR3Y5GQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR55YB5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR4RJ3Q'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR6FMF3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJTH61J'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJS2JLJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HHDP9DW'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HH5WF97'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJNKT3P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJQ182D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HR9D2JS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJRF2CN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJPDJTY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJGNJ81'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08HJLLF7G'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.fr/dp/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.fr/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08H93ZRK9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08H98GVK8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.fr/dp/B08H93ZRLL'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.fr/dp/B087VM5XC6'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amazon-fr'
|
||||||
|
};
|
||||||
@@ -0,0 +1,417 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmazonIt: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: [
|
||||||
|
'Inserisci i caratteri visualizzati nello spazio sottostante'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
inStock: {
|
||||||
|
container: '#desktop_buybox',
|
||||||
|
text: ['Aggiungi al carrello']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice',
|
||||||
|
euroFormat: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KHFZN9P&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KHFZN9P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08L8HPKR6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08L8JNTXQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08L8KC1J7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KY266MG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
|
||||||
|
model: 'gaming',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KWN2LZG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBJB7YD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
|
||||||
|
model: 'xlr8 uprising',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBF5L3K'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KWPDXJZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KWLMZV4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
|
||||||
|
model: 'gaming',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08LF32LJ6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08L8L71SM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08L8L9TCZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KY266MG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08M13DXSZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KXZV626'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBR7QBM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBTJMLJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR3Y5GQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR55YB5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR4RJ3Q'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR6FMF3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJTH61J'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJS2JLJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HH5WF97'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HHDP9DW'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08J6GMWCQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR5SXPS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJNKT3P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJQ182D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBQWBHH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HBVX53D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HRBW6VB'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
|
||||||
|
model: 'ventus 3x',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HR9D2JS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJRF2CN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJPDJTY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJGNJ81'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.it/dp/B08HJLLF7G'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.it/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.it/dp/product/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.it/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.it/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08MVC76SR&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.it/dp/B08MVC76SR'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08MVCLBWK&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.it/dp/B08MVCLBWK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KKJ37F7&Quantity.1=1',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KKJ37F7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08KJF2D25&Quantity.1=1',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.it/dp/B08KJF2D25'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08JDSW1ZW&Quantity.1=1',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.it/dp/B08JDSW1ZW'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B08JDTCXRG&Quantity.1=1',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.it/dp/B08JDTCXRG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.it/gp/aws/cart/add.html?ASIN.1=B07M63H81H&Quantity.1=1',
|
||||||
|
model: '750 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url: 'https://www.amazon.it/dp/B07M63H81H'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amazon-it'
|
||||||
|
};
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmazonNl: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: ['voer de karakters in die u hieronder ziet']
|
||||||
|
},
|
||||||
|
inStock: [
|
||||||
|
{
|
||||||
|
container: '#add-to-cart-button',
|
||||||
|
text: ['in winkelwagen']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '#buy-now-button',
|
||||||
|
text: ['nu kopen']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '#availability',
|
||||||
|
text: ['tijdelijk niet']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '#outOfStock',
|
||||||
|
text: [
|
||||||
|
'we weten niet of en wanneer dit item weer op voorraad is'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B085K45C3S&Quantity.1=1',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amazon.nl/dp/B085K45C3S'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HM4M621&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08HM4M621'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HM4V2DH&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08HM4V2DH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HJ9XFNM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08HJ9XFNM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HH1BMQQ&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08HH1BMQQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08HN7VVLJ&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08HN7VVLJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P2DQ28S'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW2YJB2&Quantity.1=1',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08NW2YJB2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
|
||||||
|
model: 'twin edge',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P3XJLJJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P3V572B'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3BJ9Y8&Quantity.1=1',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P3BJ9Y8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P3JPX8P&Quantity.1=1',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P3JPX8P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW2X37Z&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08NW2X37Z'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW528S1&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08NW528S1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NW693LG&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08NW693LG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B083Z5P6TX'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08NZ4G4T2&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08NZ4G4T2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
|
||||||
|
model: 'dual oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08P2HBBLX'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDN36R3&Quantity.1=1',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08PDN36R3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDP837W&Quantity.1=1',
|
||||||
|
model: 'xc gaming',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08PDP837W'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08PDMVPZ4&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08PDMVPZ4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.nl/dp/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.nl/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.nl/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.nl/dp/B0815Y8J9N'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amazon-nl'
|
||||||
|
};
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
import {Link, Store} from './store';
|
||||||
|
import {logger} from '../../logger';
|
||||||
|
import {parseCard} from './helpers/card';
|
||||||
|
|
||||||
|
export const AmazonUk: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '£',
|
||||||
|
labels: {
|
||||||
|
captcha: {
|
||||||
|
container: 'body',
|
||||||
|
text: ['enter the characters you see below']
|
||||||
|
},
|
||||||
|
inStock: {
|
||||||
|
container: '#availability',
|
||||||
|
text: ['in stock']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice'
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '#availability',
|
||||||
|
text: ['out of stock', 'unavailable']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '#backInStock',
|
||||||
|
text: ['unavailable']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B0753R2TWC&Quantity.1=1',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amazon.co.uk/dp/B0753R2TWC/'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H95Y452&Quantity.1=1',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.co.uk/dp/B08H95Y452'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H97NYGP&Quantity.1=1',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.co.uk/dp/B08H97NYGP'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08H93GKNJ&Quantity.1=1',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.co.uk/dp/B08H93GKNJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=B08GD9MNZB&Quantity.1=1',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.co.uk/dp/B08GD9MNZB'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
linksBuilder: {
|
||||||
|
builder: (docElement, series) => {
|
||||||
|
const productElements = docElement.find(
|
||||||
|
'.s-result-list .s-result-item[data-asin]'
|
||||||
|
);
|
||||||
|
const links: Link[] = [];
|
||||||
|
for (let i = 0; i < productElements.length; i++) {
|
||||||
|
const productElement = productElements.eq(i);
|
||||||
|
const asin = productElement.attr()['data-asin'];
|
||||||
|
|
||||||
|
if (!asin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `https://www.amazon.co.uk/dp/${asin}/`;
|
||||||
|
const titleElement = productElement
|
||||||
|
.find('.sg-col-inner h2 a.a-text-normal[href] span')
|
||||||
|
.first();
|
||||||
|
const title = titleElement.text().trim();
|
||||||
|
|
||||||
|
if (!title || !new RegExp(`RTX.*${series}`, 'i').exec(title)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const card = parseCard(title);
|
||||||
|
|
||||||
|
if (card) {
|
||||||
|
links.push({
|
||||||
|
brand: card.brand as any,
|
||||||
|
cartUrl: `https://www.amazon.co.uk/gp/aws/cart/add.html?ASIN.1=${asin}&Quantity.1=1`,
|
||||||
|
model: card.model,
|
||||||
|
series,
|
||||||
|
url
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
logger.error(`Failed to parse card: ${title}`, {url});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return links;
|
||||||
|
},
|
||||||
|
ttl: 300000,
|
||||||
|
urls: [
|
||||||
|
{
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3060+TI%22+-2060+-2070+-2080+-SUPER+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675291sb_noss'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3070%22+-2060+-2070+-2080+-SUPER+-GTX+-3080&rh=n%3A430500031&ref=nb_sb_noss'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3080',
|
||||||
|
url: [
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3080%22+-2080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675291',
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3080%22+-2080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675594&page=2'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3090',
|
||||||
|
url: [
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3090%22+-3080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675291',
|
||||||
|
'https://www.amazon.co.uk/s?k=%2B%22RTX+3090%22+-3080+-GTX&i=computers&rh=n%3A430500031%2Cp_n_availability%3A419162031&s=relevancerank&dc&qid=1601675594&page=2'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
name: 'amazon-uk'
|
||||||
|
};
|
||||||
+606
-7
@@ -1,112 +1,711 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const Amazon: Store = {
|
export const Amazon: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
captcha: {
|
captcha: {
|
||||||
container: 'body',
|
container: 'body',
|
||||||
text: ['enter the characters you see below']
|
text: ['enter the characters you see below']
|
||||||
},
|
},
|
||||||
inStock: {
|
inStock: [
|
||||||
container: '#desktop_buybox',
|
{
|
||||||
text: ['add to cart']
|
container: '#add-to-cart-button',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '#buy-now-button',
|
||||||
|
text: ['buy now']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
maxPrice: {
|
||||||
|
container: '#priceblock_ourprice'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B083248S3B&Quantity.1=1',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.amazon.com/dp/B07MQ36Z6L'
|
url: 'https://www.amazon.com/dp/B083248S3B'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2HBBLX&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P2HBBLX'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYP7KG6&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NYP7KG6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYPLXPJ&Quantity.1=1',
|
||||||
|
model: 'gaming oc pro',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NYPLXPJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYNJ6RC&Quantity.1=1',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NYNJ6RC'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B083Z5P6TX&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B083Z5P6TX'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2D3JSG&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P2D3JSG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2DQ28S&Quantity.1=1',
|
||||||
|
model: 'ventus 2x',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P2DQ28S'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3XJLJJ&Quantity.1=1',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P3XJLJJ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3V572B&Quantity.1=1',
|
||||||
|
model: 'twin edge',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P3V572B'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2D1JZZ&Quantity.1=1',
|
||||||
|
model: 'ko',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P2D1JZZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B083Z7TR8Z&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B083Z7TR8Z'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P2H5LW2&Quantity.1=1',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P2H5LW2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NYPKW1Z&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NYPKW1Z'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8LG4M3&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8LG4M3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8HPKR6&Quantity.1=1',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8HPKR6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08LW46GH2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8JNTXQ&Quantity.1=1',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8JNTXQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8KC1J7&Quantity.1=1',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8KC1J7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KY266MG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWN2LZG&Quantity.1=1',
|
||||||
|
model: 'gaming',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KWN2LZG'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'pny',
|
||||||
model: 'xlr8',
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBJB7YD&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HBJB7YD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBF5L3K&Quantity.1=1',
|
||||||
|
model: 'xlr8 uprising',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HBF5L3K'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWPDXJZ&Quantity.1=1',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KWPDXJZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KWLMZV4&Quantity.1=1',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KWLMZV4'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LF1CWT2&Quantity.1=1',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08LF1CWT2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LF32LJ6&Quantity.1=1',
|
||||||
|
model: 'gaming',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08LF32LJ6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8L71SM&Quantity.1=1',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8L71SM'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08L8L9TCZ&Quantity.1=1',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08L8L9TCZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08LW46GH2&Quantity.1=1',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08LW46GH2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY266MG&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KY266MG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08M13DXSZ&Quantity.1=1',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08M13DXSZ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08M4YFNX2&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08M4YFNX2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KXZV626&Quantity.1=1',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KXZV626'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08KY322TH&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3070',
|
||||||
|
url: 'https://www.amazon.com/dp/B08KY322TH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBR7QBM&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HBR7QBM'
|
url: 'https://www.amazon.com/dp/B08HBR7QBM'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'pny',
|
brand: 'pny',
|
||||||
model: 'xlr8 rgb',
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBTJMLJ&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HBTJMLJ'
|
url: 'https://www.amazon.com/dp/B08HBTJMLJ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR7SV3M&Quantity.1=1',
|
||||||
model: 'gaming x trio',
|
model: 'gaming x trio',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR7SV3M'
|
url: 'https://www.amazon.com/dp/B08HR7SV3M'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3Y5GQ&Quantity.1=1',
|
||||||
model: 'ftw3 ultra',
|
model: 'ftw3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR3Y5GQ'
|
url: 'https://www.amazon.com/dp/B08HR3Y5GQ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR55YB5&Quantity.1=1',
|
||||||
model: 'xc3 ultra',
|
model: 'xc3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR55YB5'
|
url: 'https://www.amazon.com/dp/B08HR55YB5'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR3DPGW&Quantity.1=1',
|
||||||
model: 'ftw3',
|
model: 'ftw3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR3DPGW'
|
url: 'https://www.amazon.com/dp/B08HR3DPGW'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR4RJ3Q&Quantity.1=1',
|
||||||
model: 'xc3',
|
model: 'xc3',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR4RJ3Q'
|
url: 'https://www.amazon.com/dp/B08HR4RJ3Q'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR6FMF3&Quantity.1=1',
|
||||||
model: 'xc3 black',
|
model: 'xc3 black',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR6FMF3'
|
url: 'https://www.amazon.com/dp/B08HR6FMF3'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJTH61J&Quantity.1=1',
|
||||||
model: 'gaming oc',
|
model: 'gaming oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HJTH61J'
|
url: 'https://www.amazon.com/dp/B08HJTH61J'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJS2JLJ&Quantity.1=1',
|
||||||
model: 'eagle oc',
|
model: 'eagle oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HJS2JLJ'
|
url: 'https://www.amazon.com/dp/B08HJS2JLJ'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HH5WF97&Quantity.1=1',
|
||||||
model: 'tuf oc',
|
model: 'tuf oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HH5WF97'
|
url: 'https://www.amazon.com/dp/B08HH5WF97'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HHDP9DW&Quantity.1=1',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HHDP9DW'
|
url: 'https://www.amazon.com/dp/B08HHDP9DW'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'strix',
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6F174Z&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08J6F174Z'
|
url: 'https://www.amazon.com/dp/B08J6F174Z'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08J6GMWCQ&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08J6GMWCQ'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR5SXPS&Quantity.1=1',
|
||||||
model: 'ventus 3x oc',
|
model: 'ventus 3x oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HR5SXPS'
|
url: 'https://www.amazon.com/dp/B08HR5SXPS'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'zotac',
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJNKT3P&Quantity.1=1',
|
||||||
model: 'trinity',
|
model: 'trinity',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.amazon.com/dp/B08HJNKT3P'
|
url: 'https://www.amazon.com/dp/B08HJNKT3P'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJQ182D&Quantity.1=1',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HJQ182D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBQWBHH&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HBQWBHH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HBVX53D&Quantity.1=1',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HBVX53D'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HRBW6VB&Quantity.1=1',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HRBW6VB'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HR9D2JS&Quantity.1=1',
|
||||||
|
model: 'ventus 3x',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HR9D2JS'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJRF2CN&Quantity.1=1',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HJRF2CN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJPDJTY&Quantity.1=1',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HJPDJTY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJGNJ81&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HJGNJ81'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08HJLLF7G&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://www.amazon.com/dp/B08HJLLF7G'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08166SLDF&Quantity.1=1',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amazon.com/dp/B08166SLDF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B0815XFSGK&Quantity.1=1',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amazon.com/dp/product/B0815XFSGK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08164VTWH&Quantity.1=1',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amazon.com/dp/B08164VTWH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B0815Y8J9N&Quantity.1=1',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amazon.com/dp/B0815Y8J9N'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NS4W2ZY&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NS4W2ZY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MVC76SR&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08MVC76SR'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXXT7WN&Quantity.1=1',
|
||||||
|
model: 'nitro+',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NXXT7WN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXYNLMR&Quantity.1=1',
|
||||||
|
model: 'pulse',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NXYNLMR'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXVNMPQ&Quantity.1=1',
|
||||||
|
model: 'nitro+',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NXVNMPQ'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08N6ZLX9B&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08N6ZLX9B'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NX14LV1&Quantity.1=1',
|
||||||
|
model: 'merc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NX14LV1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NN76VJD&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NN76VJD'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P5YFZCY&Quantity.1=1',
|
||||||
|
model: 'merc',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P5YFZCY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'powercolor',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MNZM5TK&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08MNZM5TK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08MVCLBWK&Quantity.1=1',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08MVCLBWK'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXZSPMY&Quantity.1=1',
|
||||||
|
model: 'nitro+',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NXZSPMY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sapphire',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NXYBVDB&Quantity.1=1',
|
||||||
|
model: 'pulse',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NXYBVDB'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NWJ29NB&Quantity.1=1',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NWJ29NB'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08P3YT3MY&Quantity.1=1',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amazon.com/dp/B08P3YT3MY'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08NWHKGS9&Quantity.1=1',
|
||||||
|
model: 'strix lc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amazon.com/dp/B08NWHKGS9'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08FC5L3RG&Quantity.1=1',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.amazon.com/dp/B08FC5L3RG'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B08FC6MR62&Quantity.1=1',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.amazon.com/dp/B08FC6MR62'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.amazon.com/dp/B08H75RTZ8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.amazon.com/dp/B08G9J44ZN'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B07M63H81H&Quantity.1=1',
|
||||||
|
model: '750 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url: 'https://www.amazon.com/dp/B07M63H81H'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amazon.com/gp/aws/cart/add.html?ASIN.1=B07F84FJ1G&Quantity.1=1',
|
||||||
|
model: '600 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url: 'https://www.amazon.com/dp/B07F84FJ1G'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'amazon'
|
name: 'amazon'
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmdCa: Store = {
|
||||||
|
currency: '$',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.btn-shopping-cart',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.product-page-description h4',
|
||||||
|
euroFormat: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458373400/ca'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458373400/ca?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458373400/ca'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458372800/ca?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458372800/ca'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amd-ca'
|
||||||
|
};
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmdDe: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.btn-shopping-cart',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.product-page-description h4',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.btn-radeon',
|
||||||
|
text: ['ausverkauft']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5450881400/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5450881400/de?add-to-cart=true',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5450881400/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5450881500/de?add-to-cart=true',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5450881500/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5450881600/de?add-to-cart=true',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5450881600/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5450881700/de?add-to-cart=true',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5450881700/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5458374000/de?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5458374000/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5458374100/de?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5458374100/de'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/de/direct-buy/5458374200/de?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url: 'https://www.amd.com/de/direct-buy/5458374200/de'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amd-de'
|
||||||
|
};
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmdIt: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.btn-shopping-cart',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.product-page-description h4',
|
||||||
|
euroFormat: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/it'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881400/it?add-to-cart=true',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/it'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881500/it?add-to-cart=true',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881500/it'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881600/it?add-to-cart=true',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881600/it'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881700/it?add-to-cart=true',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881700/it'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458374100/it?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458374100/it'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amd-it'
|
||||||
|
};
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AmdUk: Store = {
|
||||||
|
currency: '£',
|
||||||
|
labels: {
|
||||||
|
inStock: [
|
||||||
|
{
|
||||||
|
container: '.btn-shopping-cart',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '.btn-radeon',
|
||||||
|
text: ['add to cart']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
maxPrice: {
|
||||||
|
container: '.product-page-description h4',
|
||||||
|
euroFormat: false
|
||||||
|
},
|
||||||
|
outOfStock: [
|
||||||
|
{
|
||||||
|
container: '.product-out-of-stock',
|
||||||
|
text: ['out of stock']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
container: '.btn-radeon',
|
||||||
|
text: ['sold out']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881400/gb?add-to-cart=true',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881500/gb?add-to-cart=true',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881500/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881600/gb?add-to-cart=true',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881600/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881700/gb?add-to-cart=true',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881700/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458374000/gb?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458374000/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458374100/gb?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458374100/gb'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458374200/gb?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458374200/gb'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amd-uk'
|
||||||
|
};
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const Amd: Store = {
|
||||||
|
currency: '$',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.btn-shopping-cart',
|
||||||
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.product-page-description h4',
|
||||||
|
euroFormat: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881400/us?add-to-cart=true',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881400/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881500/us?add-to-cart=true',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881500/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881600/us?add-to-cart=true',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881600/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5450881700/us?add-to-cart=true',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5450881700/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458372200/us?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458372200/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458372800/us?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458372800/us'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl:
|
||||||
|
'https://www.amd.com/en/direct-buy/5458373400/us?add-to-cart=true',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url: 'https://www.amd.com/en/direct-buy/5458373400/us'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'amd'
|
||||||
|
};
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AntOnline: Store = {
|
||||||
|
currency: '$',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.uk-button',
|
||||||
|
text: ['Add to Cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.cPrice',
|
||||||
|
euroFormat: false
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.priceView-price .priceView-hero-price span',
|
||||||
|
text: ['Sold Out']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url:
|
||||||
|
'https://www.antonline.com/Sony/Electronics/Gaming_Devices/Gaming_Consoles/1409507'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url:
|
||||||
|
'https://www.antonline.com/Microsoft/Electronics/Gaming_Devices/Gaming_Consoles/1414487'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url:
|
||||||
|
'https://www.antonline.com/Microsoft/Electronics/Gaming_Devices/Gaming_Consoles/1409527'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'antonline'
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const ArgosIE: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.btnbuyreserve',
|
||||||
|
text: ['buy or reserve']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.price'
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '#subCopy',
|
||||||
|
text: ["We're working hard to get more stock."]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url:
|
||||||
|
'http://www.argos.ie/static/Product/partNumber/8448262/Trail/searchtext%3EXBOX+SERIES+X.htm'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url:
|
||||||
|
'http://www.argos.ie/static/Product/partNumber/8349000/Trail/searchtext%3EPS5+CONSOLE.htm'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'argos-ie'
|
||||||
|
};
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const Argos: Store = {
|
||||||
|
currency: '£',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: 'button[data-test="add-to-trolley-button-button"',
|
||||||
|
text: ['to trolley']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: 'li[itemprop="price"]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url: 'https://www.argos.co.uk/product/5718469'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url: 'https://www.argos.co.uk/product/8349000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url: 'https://www.argos.co.uk/product/8349024'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url: 'https://www.argos.co.uk/product/8448262'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url: 'https://www.argos.co.uk/product/8448248'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'argos'
|
||||||
|
};
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
import {getProductLinksBuilder} from './helpers/card';
|
||||||
|
|
||||||
|
export const Aria: Store = {
|
||||||
|
currency: '£',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '#addQuantity',
|
||||||
|
text: ['add to shopping basket']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.priceBig',
|
||||||
|
euroFormat: false // Note: Aria uses non-euroFromat as price seperator
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.fBox',
|
||||||
|
text: ['out of stock', 'there is currently no stock of this item']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+2060+Super/Gigabyte+NVIDIA+GeForce+RTX+2060+SUPER+8GB+WINDFORCE+OC+Turing+Graphics+Card+%2B+RTX+Bundle%21?productId=71541'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Processors/AMD+CPUs/Ryzen+9+-+Socket+AM4/AMD+Ryzen+9+5950X+16+Core+AM4+CPU%2FProcessor?productId=72868'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
linksBuilder: {
|
||||||
|
builder: getProductLinksBuilder({
|
||||||
|
productsSelector: '#productListingInner .listTable .listTableTr',
|
||||||
|
sitePrefix: 'https://www.aria.co.uk',
|
||||||
|
titleSelector: 'strong > a[href]'
|
||||||
|
}),
|
||||||
|
urls: [
|
||||||
|
{
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3060+Ti'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3070'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.aria.co.uk/Products/Components/Graphics+Cards/NVIDIA+GeForce/GeForce+RTX+3090'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
name: 'aria',
|
||||||
|
waitUntil: 'domcontentloaded'
|
||||||
|
};
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const Arlt: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.articleDesc .shippingtext',
|
||||||
|
text: ['auf Lager', 'Lieferzeit 2-3 Werktage', 'Ware im Zulauf']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.articleprice .price',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.articleDesc .shippingtext',
|
||||||
|
text: ['Neuer Artikel in Kürze verfügbar', 'Liefertermin unbekannt']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/ASUS-GeForce-GTX1650-Super-TUF-GTX1650S-O4G-GAMING.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Gaming/Gaming-Hardware/Grafikkarten/ASUS-Dual-GeForce-RTX-3070.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'dual oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/ASUS-Dual-GeForce-RTX-3070-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Gaming/Gaming-Hardware/Grafikkarten/ASUS-TUF-Gaming-GeForce-RTX-3070-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3070/ASUS-ROG-Strix-GeForce-RTX-3070.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3070/MSI-GeForce-RTX-3070-Ventus-2X-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/Gainward-GeForce-RTX-3070-Phoenix.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix gs',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Gaming/Gaming-Hardware/Gainward-GeForce-RTX-3070-Phoenix-GS.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/ASUS-TUF-Gaming-GeForce-RTX-3080-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3080/MSI-GeForce-RTX-3080-Ventus-3X-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3090/ASUS-TUF-Gaming-GeForce-RTX-3090-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Grafikkarten/NVIDIA/GeForce-RTX/RTX-3090/ASUS-ROG-Strix-GeForce-RTX-3090-OC.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gainward',
|
||||||
|
model: 'phoenix gs',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Gaming/Gaming-Hardware/Gainward-GeForce-RTX-3090-Phoenix-GS.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-5-5600X-boxed.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-7-5800X-boxed.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-9-5900X-boxed.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url:
|
||||||
|
'https://www.arlt.com/Hardware/PC-Komponenten/Prozessoren-arlt/AMD-Ryzen-9-5950X-boxed.html'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'arlt'
|
||||||
|
};
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const AsusDe: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.buybox--button',
|
||||||
|
text: ['in den warenkorb']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2766/asus-rog-strix-rtx2060s-o8g-evo-v2-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2828/asus-rog-strix-rtx3080-10g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2829/asus-rog-strix-rtx3080-o10g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2824/asus-tuf-rtx3080-10g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2825/asus-tuf-rtx3080-o10g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2826/asus-rog-strix-rtx3090-24g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2827/asus-rog-strix-rtx3090-o24g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2822/asus-tuf-rtx3090-24g-gaming'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://webshop.asus.com/de/komponenten/grafikkarten/nvidia-serie/2823/asus-tuf-rtx3090-o24g-gaming'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'asus-de'
|
||||||
|
};
|
||||||
+63
-5
@@ -1,6 +1,9 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
|
||||||
export const Asus: Store = {
|
export const Asus: Store = {
|
||||||
|
backoffStatusCodes: [403, 429, 503],
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
inStock: {
|
inStock: {
|
||||||
container: '#item_add_cart',
|
container: '#item_add_cart',
|
||||||
@@ -10,23 +13,78 @@ export const Asus: Store = {
|
|||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
|
itemNumber: '202007AM020000005',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://store.asus.com/us/item/202003AM280000002/'
|
url: 'https://store.asus.com/us/item/202007AM020000005'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
itemNumber: '202009AM160000001',
|
||||||
model: 'tuf oc',
|
model: 'tuf oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://store.asus.com/us/item/202009AM160000001/'
|
url: 'https://store.asus.com/us/item/202009AM160000001'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
itemNumber: '202009AM150000004',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://store.asus.com/us/item/202009AM150000004/'
|
url: 'https://store.asus.com/us/item/202009AM150000004'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
itemNumber: '202009AM150000003',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://store.asus.com/us/item/202009AM150000003'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
itemNumber: '202009AM150000001',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url: 'https://store.asus.com/us/item/202009AM150000001'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
itemNumber: '202009AM290000002',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url: 'https://store.asus.com/us/item/202009AM290000002'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
itemNumber: '202011AM200000003',
|
||||||
|
model: 'crosshair viii',
|
||||||
|
series: 'darkhero',
|
||||||
|
url: 'https://store.asus.com/us/item/202011AM200000003'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'asus'
|
name: 'asus',
|
||||||
};
|
realTimeInventoryLookup: async (itemNumber: string) => {
|
||||||
|
const request_url =
|
||||||
|
'https://store.asus.com/us/category/get_real_time_data';
|
||||||
|
const response = await fetch(request_url, {
|
||||||
|
body: 'sm_seq_list%5B%5D=' + itemNumber,
|
||||||
|
headers: {
|
||||||
|
'accept-language': 'en-US,en;q=0.9',
|
||||||
|
'cache-control': 'no-cache',
|
||||||
|
'content-type':
|
||||||
|
'application/x-www-form-urlencoded; charset=UTF-8'
|
||||||
|
},
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
const response_json = await response.json();
|
||||||
|
|
||||||
|
if (response_json.data[itemNumber] !== undefined) {
|
||||||
|
const item_info = response_json.data[itemNumber].market_info;
|
||||||
|
if (item_info.buy === true || item_info.quantity > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
successStatusCodes: [[0, 399], 404]
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
import {getProductLinksBuilder} from './helpers/card';
|
||||||
|
|
||||||
|
export const Awd: Store = {
|
||||||
|
currency: '£',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.vs-stock .ty-qty-in-stock',
|
||||||
|
text: ['item(s)']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.ty-price',
|
||||||
|
euroFormat: false // Note: Awd uses non-euroFromat as price seperator
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.vs-stock.ty-float-left',
|
||||||
|
text: ['Out-of-stock']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/asus-nvidia-geforce-gt-710-silent-low-profile-2gb-gddr5-graphics-card-pci-e.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/amd-ryzen-5-5600x-cpu-six-core-3.7ghz-processor-socket-am4-retail.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/amd-ryzen-7-5800x-cpu-eight-core-3.8ghz-processor-socket-am4-retail.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/amd-ryzen-9-5900x-cpu-twelve-core-3.7ghz-processor-socket-am4-retail.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/amd-ryzen-9-5950x-sixteen-core-socket-am4-3.4ghz-processor.html'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
linksBuilder: {
|
||||||
|
builder: getProductLinksBuilder({
|
||||||
|
productsSelector: '.grid-list .ty-grid-list__item',
|
||||||
|
sitePrefix: 'https://www.awd-it.co.uk',
|
||||||
|
titleSelector: '.product-title'
|
||||||
|
}),
|
||||||
|
urls: [
|
||||||
|
{
|
||||||
|
series: 'rx6800',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/components/graphics-cards/ati/amd-radeon-6800-6800xt.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/components/graphics-cards/nvidia/nvidia-geforce-rtx-3060ti.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/components/graphics-cards/nvidia/nvidia-geforce-rtx-3070.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/components/graphics-cards/nvidia/nvidia-geforce-rtx-3080.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.awd-it.co.uk/components/graphics-cards/nvidia/nvidia-geforce-rtx-3090.html'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
name: 'awd',
|
||||||
|
waitUntil: 'domcontentloaded'
|
||||||
|
};
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
import {Store} from './store';
|
||||||
|
|
||||||
|
export const Azerty: Store = {
|
||||||
|
currency: '€',
|
||||||
|
labels: {
|
||||||
|
inStock: {
|
||||||
|
container: '.orderdelay',
|
||||||
|
text: ['Volgende werkdag in huis', '1 werkdag', '2-3 werkdagen']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: '.mod_article .price',
|
||||||
|
euroFormat: true
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.orderdelay',
|
||||||
|
text: ['Onbekend', 'meer dan 10 werkdagen', 'Pre-order']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{
|
||||||
|
brand: 'test:brand',
|
||||||
|
model: 'test:model',
|
||||||
|
series: 'test:series',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/gigabyte/3756757/geforce-rtx-2060-oc-6g-grafische-kaart-geforce-rtx-2060'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus xtreme',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/gigabyte/4349658/aorus-geforce-rtx-3080-xtreme-10g-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/msi/4346262/geforce-rtx-3080-ventus-3x-10g-oc-grafische-kaart-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4346679/tuf-gaming-geforce-rtx-3080-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/msi/4346263/geforce-rtx-3080-gaming-x-trio-10g-grafische-kaart-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4348176/tuf-gaming-geforce-rtx-3080-oc-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4348174/rog-strix-geforce-rtx-3080-oc-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/zotac/4352301/gaming-geforce-rtx-3080-trinity-oc-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/gigabyte/4349651/aorus-geforce-rtx-3080-master-10g-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/pny/4342269/geforce-rtx-3080-xlr8-gaming-revel-epic-x-rgb-triple-fan-gaming-edition-grafische-kaart-gf-rtx-3080'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4363892/rog-strix-gaming-geforce-rtx-3070-o8g-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4373096/rog-strix-gaming-geforce-rtx-3070-8g-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4363910/tuf-gaming-geforce-rtx-3070-oc-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/asus/4373099/tuf-gaming-geforce-rtx-3070-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x4',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/inno3d/4369725/geforce-rtx-3070-ichill-x4-videokaart-8-gb-ddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'inno3d',
|
||||||
|
model: 'ichill x3',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/inno3d/4369726/geforce-rtx-3070-ichill-x3-videokaart-8-gb-ddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/msi/4374747/geforce-rtx-3070-ventus-3x-oc-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/msi/4365398/geforce-rtx-3070-gaming-x-trio-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
model: 'dual fan',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/pny/4342270/uprising-dual-fan-geforce-rtx-3070'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/pny/4342271/epic-x-rgb-geforce-rtx-3070-triple-fan-gaming-edition-xlr8--videokaart-8-gb-gddr6x'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/evga/4377247/geforce-rtx-3070-ftw3-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/evga/4377248/xc3-geforce-rtx-3070-xc3-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/evga/4377250/ftw3-ultra-geforce-rtx-3070-videokaart-8-gb-gddr6'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://azerty.nl/product/evga/4377252/xc3-black-geforce-rtx-3070-videokaart-8-gb-gddr6'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
name: 'azerty'
|
||||||
|
};
|
||||||
+184
-9
@@ -1,10 +1,16 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const BAndH: Store = {
|
export const BAndH: Store = {
|
||||||
|
backoffStatusCodes: [403, 429],
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
inStock: {
|
inStock: {
|
||||||
container: 'div[data-selenium="addToCartSection"]',
|
container: 'div[data-selenium="addToCartSection"]',
|
||||||
text: ['add to cart']
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container: 'div[data-selenium="pricingPrice"]',
|
||||||
|
euroFormat: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
@@ -12,7 +18,29 @@ export const BAndH: Store = {
|
|||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1452927-REG/evga_06g_p4_2063_kr_geforce_rtx_2060_xc.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1452927-REG/evga_06g_p4_2063_kr_geforce_rtx_2060_xc.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'dual',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1602755-REG/asus_dualrtx30708g_geforce_rtx_3070_8g.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
model: 'dual fan',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1595984-REG/pny_technologies_vcg30708tfxppb_geforce_rtx_3070_epic_x.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'strix oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1602756-REG/asus_strixrtx3070o8_rog_strix_geforce_rtx.html'
|
||||||
},
|
},
|
||||||
// TUF was removed from BH, not sure why so commenting out listing for now
|
// TUF was removed from BH, not sure why so commenting out listing for now
|
||||||
// {
|
// {
|
||||||
@@ -25,13 +53,15 @@ export const BAndH: Store = {
|
|||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
model: 'gaming oc',
|
model: 'gaming oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1593333-REG/gigabyte_gv_n3080gaming_oc_10gd_geforce_rtx_3080_gaming.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593333-REG/gigabyte_gv_n3080gaming_oc_10gd_geforce_rtx_3080_gaming.html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'zotac',
|
brand: 'zotac',
|
||||||
model: 'trinity',
|
model: 'trinity',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1592969-REG/zotac_zt_a30800d_10p_gaming_geforce_rtx_3080.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1592969-REG/zotac_zt_a30800d_10p_gaming_geforce_rtx_3080.html'
|
||||||
},
|
},
|
||||||
// TUF was removed from BH, not sure why so commenting out listing for now
|
// TUF was removed from BH, not sure why so commenting out listing for now
|
||||||
// {
|
// {
|
||||||
@@ -40,29 +70,174 @@ export const BAndH: Store = {
|
|||||||
// series: '3080',
|
// series: '3080',
|
||||||
// url: 'https://www.bhphotovideo.com/c/product/1593650-REG/asus_tuf_rtx3080_o10g_gaming_tuf_gaming_geforce_rtx.html'
|
// url: 'https://www.bhphotovideo.com/c/product/1593650-REG/asus_tuf_rtx3080_o10g_gaming_tuf_gaming_geforce_rtx.html'
|
||||||
// },
|
// },
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1606948-REG/gigabyte_gv_n306teagle_oc_8gd_rtx_3060_ti_eagle.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1606949-REG/gigabyte_gv_n306teagle_8gd_rtx_3060_ti_eagle.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'aorus',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1606945-REG/gigabyte_gv_n306taorus_m_8gd_aorus_rtx_3060_ti.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1606947-REG/gigabyte_gv_n306tgaming_oc_8gd_rtx_3060_ti_gaming.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming pro',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1606946-REG/gigabyte_gv_n306tgamingoc_pro_8gd_rtx_3060_ti_gaming.html'
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'gaming x trio',
|
model: 'gaming x trio',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1593996-REG/msi_g3080gxt10_geforce_rtx_3080_gaming.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593996-REG/msi_g3080gxt10_geforce_rtx_3080_gaming.html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'ventus 3x oc',
|
model: 'ventus 3x oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1593997-REG/msi_g3080v3x10c_geforce_rtx_3080_ventus.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593997-REG/msi_g3080v3x10c_geforce_rtx_3080_ventus.html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'gaming x trio - duplicate',
|
model: 'gaming x trio',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1593645-REG/msi_geforce_rtx_3080_gaming.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593645-REG/msi_geforce_rtx_3080_gaming.html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'ventus 3x oc - duplicate',
|
model: 'ventus 3x oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bhphotovideo.com/c/product/1593646-REG/msi_geforce_rtx_3080_ventus.html'
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593646-REG/msi_geforce_rtx_3080_ventus.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'trinity',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1592970-REG/zotac_zt_a30900d_10p_gaming_geforce_rtx_3090.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593647-REG/msi_geforce_rtx_3090_gaming.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'gaming x trio',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593994-REG/msi_g3090gxt24_geforce_rtx_3090_gaming.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593648-REG/msi_geforce_rtx_3090_ventus.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593995-REG/msi_g3090v3x24c_geforce_rtx_3090_ventus.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593334-REG/gigabyte_gv_n3090eagle_oc_24gd_geforce_rtx_3090_eagle.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1593335-REG/gigabyte_gv_n3090gaming_oc_24gd_geforce_rtx3090_gaming_oc.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1594454-REG/asus_90yv0fd0_m0am00_tuf_gaming_geforce_rtx.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
model: 'tuf oc',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1594451-REG/asus_90yv0fd1_m0am00_tuf_gaming_geforce_rtx.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1598372-REG/amd_100_100000059wof_ryzen_9_5950x_3_4.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1598373-REG/amd_100_100000061wof_ryzen_9_5900x_3_7.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1598376-REG/amd_100_100000063wof_ryzen_7_5800x_3_8.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1598377-REG/amd_100_100000065box_ryzen_5_5600x_3_7.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1598377-REG/amd_100_100000065box_ryzen_5_5600x_3_7.html'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
model: '750 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url:
|
||||||
|
'https://www.bhphotovideo.com/c/product/1560680-REG/corsair_cp_9020186_na_corsair_sf750_power_supply.html'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'bandh'
|
name: 'bandh'
|
||||||
|
|||||||
+121
-15
@@ -1,10 +1,15 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const BestBuyCa: Store = {
|
export const BestBuyCa: Store = {
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
inStock: {
|
maxPrice: {
|
||||||
container: '#root',
|
container: 'div[class*="pricingContainer"]',
|
||||||
text: ['available online']
|
euroFormat: false
|
||||||
|
},
|
||||||
|
outOfStock: {
|
||||||
|
container: '.addToCartButton:disabled',
|
||||||
|
text: ['add to cart']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
@@ -12,61 +17,162 @@ export const BestBuyCa: Store = {
|
|||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-2060-super-gaming-x-8gb-gddr6-video-card/14419420?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-nvidia-geforce-gtx-1660-super-twin-fan-6gb-gddr6-video-card/14415897'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3060-ti-ventus-2x-oc-8gb-gddr6-video-card/15178453?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/nvidia-geforce-rtx-3060-ti-8gb-gddr6-video-card/15166285?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3060-ti-twin-edge-oc-8gb-gddr6-video-card/15178452?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'twin edge',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3060-ti-twin-edge-8gb-gddr6-video-card/15178583?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/evga-geforce-rtx-3060-ti-ftw3-ultra-8gb-gddr6-video-card/15200164?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'zotac',
|
brand: 'zotac',
|
||||||
model: 'trinity',
|
model: 'trinity',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3080-trinity-10gb-gddr6x-video-card/14953249?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3080-trinity-10gb-gddr6x-video-card/14953249?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'ventus 3x',
|
model: 'ventus 3x',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3080-ventus-3x-10gb-gddr6x-video-card/14950588?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3080-ventus-3x-10gb-gddr6x-video-card/14950588?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
model: 'xc3 ultra',
|
model: 'xc3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/evga-geforce-rtx-3080-xc3-ultra-gaming-10gb-gddr6x-video-card/14961449?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/evga-geforce-rtx-3080-xc3-ultra-gaming-10gb-gddr6x-video-card/15084753?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/asus-tuf-gaming-geforce-rtx-3080-10gb-gddr6x-video-card/14953248?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/asus-tuf-gaming-geforce-rtx-3080-10gb-gddr6x-video-card/14953248?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'rog strix',
|
model: 'strix',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/asus-rog-strix-geforce-rtx-3080-10gb-gddr6x-video-card/14954116?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/asus-rog-strix-geforce-rtx-3080-10gb-gddr6x-video-card/14954116?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'zotac',
|
brand: 'zotac',
|
||||||
model: 'trinity',
|
model: 'trinity',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3090-trinity-24gb-gddr6x-video-card/14953250?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-geforce-rtx-3090-trinity-24gb-gddr6x-video-card/14953250?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/asus-tuf-gaming-geforce-rtx-3090-24gb-gddr6x-video-card/14953247?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/asus-tuf-gaming-geforce-rtx-3090-24gb-gddr6x-video-card/14953247?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'rog strix',
|
model: 'strix',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/asus-rog-strix-geforce-rtx-3090-24gb-gddr6x-video-card/14954117?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/asus-rog-strix-geforce-rtx-3090-24gb-gddr6x-video-card/14954117?intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
model: 'ventus 3x',
|
model: 'ventus 3x',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3090-ventus-3x-oc-24gb-gddr6x-video-card/14966477?intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3090-ventus-3x-oc-24gb-gddr6x-video-card/14966477?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'ventus 3x',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/msi-nvidia-geforce-rtx-3070-ventus-3x-oc-8gb-gddr6x-video-card/15038016?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'twin edge oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-nvidia-geforce-rtx-3070-twin-edge-oc-8gb-gddr6x-video-card/15000078?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'zotac',
|
||||||
|
model: 'twin edge',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/zotac-nvidia-geforce-rtx-3070-twin-edge-8gb-gddr6x-video-card/15000079?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/nvidia-geforce-rtx-3070-8gb-gddr6-video-card-only-at-best-buy/15078017?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/playstation-5-console-online-only/14962185?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/playstation-5-digital-edition-console-online-only/14962184?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/xbox-series-x-1tb-console-new-model-online-only/14964951'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.ca/en-ca/product/xbox-series-s-512gb-console-new-model-online-only/14964950'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'bestbuy-ca',
|
name: 'bestbuy-ca',
|
||||||
|
|||||||
+419
-17
@@ -1,10 +1,16 @@
|
|||||||
import {Store} from './store';
|
import {Store} from './store';
|
||||||
|
|
||||||
export const BestBuy: Store = {
|
export const BestBuy: Store = {
|
||||||
|
currency: '$',
|
||||||
labels: {
|
labels: {
|
||||||
inStock: {
|
inStock: {
|
||||||
container: '.v-m-bottom-g',
|
container:
|
||||||
|
'[data-sticky-media-gallery] .fulfillment-add-to-cart-button',
|
||||||
text: ['add to cart']
|
text: ['add to cart']
|
||||||
|
},
|
||||||
|
maxPrice: {
|
||||||
|
container:
|
||||||
|
'[data-sticky-media-gallery] .priceView-price .priceView-hero-price span'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
@@ -12,92 +18,488 @@ export const BestBuy: Store = {
|
|||||||
brand: 'test:brand',
|
brand: 'test:brand',
|
||||||
model: 'test:model',
|
model: 'test:model',
|
||||||
series: 'test:series',
|
series: 'test:series',
|
||||||
url: 'https://www.bestbuy.com/site/nvidia-geforce-rtx-2060-super-8gb-gddr6-pci-express-graphics-card-black-silver/6361329.p?skuId=6361329&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/insignia-8qt-digital-multi-cooker-stainless-steel/6258941.p?skuId=6258941&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6429442/cart',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/nvidia-geforce-rtx-3070-8gb-gddr6-pci-express-4-0-graphics-card-dark-platinum-and-black/6429442.p?skuId=6429442&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439300/cart',
|
||||||
|
model: 'xc3 black',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3070-xc3-black-gaming-8gb-gddr6x-pci-express-4-0-graphics-card/6439300.p?skuId=6439300&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6437912/cart',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3070-8g-gddr6-pci-express-4-0-graphics-card-black/6437912.p?skuId=6437912&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6437909/cart',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3070-8g-gddr6-pci-express-4-0-graphics-card-black/6437909.p?skuId=6437909&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432654/cart',
|
||||||
|
model: 'dual fan',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/pny-geforce-rtx-3070-8gb-dual-fan-graphics-card/6432654.p?skuId=6432654&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432653/cart',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/pny-geforce-rtx-3070-8gb-xlr8-gaming-epic-x-rgb-triple-fan-graphics-card/6432653.p?skuId=6432653&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439384/cart',
|
||||||
|
model: 'aorus',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3070-8g-gddr6-pci-express-4-0-graphics-card-black/6439384.p?skuId=6439384'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439385/cart',
|
||||||
|
model: 'vision',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3070-8g-gddr6-pci-express-4-0-graphics-card-white/6439385.p?skuId=6439385'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439128/cart',
|
||||||
|
model: 'tuf',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/asus-tuf-rtx3070-8gb-gddr6-pci-express-4-0-graphics-card-black/6439128.p?skuId=6439128'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6438278/cart',
|
||||||
|
model: 'ventus 3x oc',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-geforce-rtx-3070-ventus-3x-oc-bv-8gb-gddr6-pci-express-4-0-graphics-card-black/6438278.p?skuId=6438278'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'asus',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439127/cart',
|
||||||
|
model: 'strix',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/asus-rog-strix-rtx3070-8gb-gddr6-pci-express-4-0-graphics-card-black/6439127.p?skuId=6439127'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439301/cart',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3070-ftw3-ultra-gaming-8gb-gddr6x-pci-express-4-0-graphics-card/6439301.p?skuId=6439301'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439299/cart',
|
||||||
|
model: 'xc3 ultra',
|
||||||
|
series: '3070',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3070-xc3-ultra-gaming-8gb-gddr6x-pci-express-4-0-graphics-card/6439299.p?skuId=6439299'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'nvidia',
|
brand: 'nvidia',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6429440/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6429440/cart',
|
||||||
model: 'founders edition',
|
model: 'founders edition',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/nvidia-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card-titanium-and-black/6429440.p?skuId=6429440&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/nvidia-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card-titanium-and-black/6429440.p?skuId=6429440&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6432445/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6432445/cart',
|
||||||
model: 'rog strix',
|
model: 'strix',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/asus-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-strix-graphics-card-black/6432445.p?skuId=6432445&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/asus-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-strix-graphics-card-black/6432445.p?skuId=6432445&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6432399/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6432399/cart',
|
||||||
model: 'xc3 black',
|
model: 'xc3 black',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6432399.p?skuId=6432399&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6432399.p?skuId=6432399&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436194/cart',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6436194.p?skuId=6436194&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'evga',
|
brand: 'evga',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6432400/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6432400/cart',
|
||||||
model: 'xc3 ultra',
|
model: 'xc3 ultra',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6432400.p?skuId=6432400&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6432400.p?skuId=6432400&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436196/cart',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6436196.p?skuId=6436196&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436191/cart',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3080-10gb-gddr6x-pci-express-4-0-graphics-card/6436191.p?skuId=6436191&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6430620/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6430620/cart',
|
||||||
model: 'gaming oc',
|
model: 'gaming oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-black/6430620.p?acampID=0&cmp=RMX&loc=Hatch&ref=198&skuId=6430620&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-black/6430620.p?acampID=0&cmp=RMX&loc=Hatch&ref=198&skuId=6430620&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6430621/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6430621/cart',
|
||||||
model: 'eagle oc',
|
model: 'eagle oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-black/6430621.p?skuId=6430621&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-black/6430621.p?skuId=6430621&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436219/cart',
|
||||||
|
model: 'vision oc',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-white/6436219.p?skuId=6436219&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436223/cart',
|
||||||
|
model: 'aorus master',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3080-10g-gddr6x-pci-express-4-0-graphics-card-black/6436223.p?skuId=6436223&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
cartUrl: 'https://api.bestbuy.com/click/-/6430175/cart',
|
cartUrl: 'https://api.bestbuy.com/click/-/6430175/cart',
|
||||||
model: 'ventus 3x oc',
|
model: 'ventus 3x oc',
|
||||||
series: '3080',
|
series: '3080',
|
||||||
url: 'https://www.bestbuy.com/site/msi-geforce-rtx-3080-ventus-3x-10g-oc-bv-gddr6x-pci-express-4-0-graphic-card-black-silver/6430175.p?skuId=6430175&intl=nosplash'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-geforce-rtx-3080-ventus-3x-10g-oc-bv-gddr6x-pci-express-4-0-graphic-card-black-silver/6430175.p?skuId=6430175&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432655/cart',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/pny-geforce-rtx-3080-10gb-xlr8-gaming-epic-x-rgb-triple-fan-graphics-card/6432655.p?skuId=6432655&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432658/cart',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3080',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/pny-geforce-rtx-3080-10gb-xlr8-gaming-epic-x-rgb-triple-fan-graphics-card/6432658.p?skuId=6432658&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'nvidia',
|
brand: 'nvidia',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6429434/cart',
|
||||||
model: 'founders edition',
|
model: 'founders edition',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/nvidia-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card-titanium-and-black/6429434.p?skuId=6429434'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/nvidia-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card-titanium-and-black/6429434.p?skuId=6429434&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
model: 'rog strix',
|
cartUrl: 'https://api.bestbuy.com/click/-/6432447/cart',
|
||||||
|
model: 'strix',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/asus-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-strix-graphics-card-black/6432447.p?skuId=6432447'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/asus-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-strix-graphics-card-black/6432447.p?skuId=6432447&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'asus',
|
brand: 'asus',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432446/cart',
|
||||||
model: 'tuf',
|
model: 'tuf',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/asus-tuf-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card-black/6432446.p?skuId=6432446'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/asus-tuf-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card-black/6432446.p?skuId=6432446&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'msi',
|
brand: 'msi',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6430215/cart',
|
||||||
model: 'ventus 3x oc',
|
model: 'ventus 3x oc',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/msi-geforce-rtx-3090-ventus-3x-24g-oc-bv-24gb-gddr6x-pci-express-4-0-graphics-card-black-silver/6430215.p?skuId=6430215'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-geforce-rtx-3090-ventus-3x-24g-oc-bv-24gb-gddr6x-pci-express-4-0-graphics-card-black-silver/6430215.p?skuId=6430215&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6430623/cart',
|
||||||
model: 'gaming',
|
model: 'gaming',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3090-24g-gddr6x-pci-express-4-0-graphics-card-black/6430623.p?skuId=6430623'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3090-24g-gddr6x-pci-express-4-0-graphics-card-black/6430623.p?skuId=6430623&intl=nosplash'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
brand: 'gigabyte',
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6430624/cart',
|
||||||
model: 'eagle',
|
model: 'eagle',
|
||||||
series: '3090',
|
series: '3090',
|
||||||
url: 'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3090-24g-gddr6x-pci-express-4-0-graphics-card-black/6430624.p?skuId=6430624'
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-geforce-rtx-3090-24g-gddr6x-pci-express-4-0-graphics-card-black/6430624.p?skuId=6430624&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6434363/cart',
|
||||||
|
model: 'xc3',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card/6434363.p?skuId=6434363&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436193/cart',
|
||||||
|
model: 'ftw3',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card/6436193.p?skuId=6436193&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'evga',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6436192/cart',
|
||||||
|
model: 'ftw3 ultra',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/evga-geforce-rtx-3090-24gb-gddr6x-pci-express-4-0-graphics-card/6436192.p?skuId=6436192&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'pny',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6432657/cart',
|
||||||
|
model: 'xlr8 revel',
|
||||||
|
series: '3090',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/pny-geforce-rtx-3090-24gb-xlr8-gaming-epic-x-rgb-triple-fan-graphics-card/6432657.p?skuId=6432657&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439402/cart',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/nvidia-geforce-rtx-3060-ti-8gb-gddr6-pci-express-4-0-graphics-card-steel-and-black/6439402.p?skuId=6439402&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6441172/cart',
|
||||||
|
model: 'ventus 2x',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-geforce-rtx-3060-ti-ventus-2x-oc-bv-8gb-gddr6-pci-express-4-0-graphics-card-black-black/6441172.p?skuId=6441172&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6442484/cart',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-nvidia-geforce-rtx-3060-ti-gaming-oc-8g-gddr6-pci-express-4-0-graphics-card-black/6442484.p?skuId=6442484?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6442485/cart',
|
||||||
|
model: 'eagle',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-nvidia-geforce-rtx-3060-ti-eagle-oc-8g-gddr6-pci-express-4-0-graphics-card-black/6442485.p?skuId=6442485?intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6438942/cart',
|
||||||
|
model: '5900x',
|
||||||
|
series: 'ryzen5900',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/amd-ryzen-9-5900x-4th-gen-12-core-24-threads-unlocked-desktop-processor-without-cooler/6438942.p?skuId=6438942&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6438941/cart',
|
||||||
|
model: '5950x',
|
||||||
|
series: 'ryzen5950',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/amd-ryzen-9-5950x-4th-gen-16-core-32-threads-unlocked-desktop-processor-without-cooler/6438941.p?skuId=6438941&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439000/cart',
|
||||||
|
model: '5800x',
|
||||||
|
series: 'ryzen5800',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/amd-ryzen-7-5800x-4th-gen-8-core-16-threads-unlocked-desktop-processor-without-cooler/6439000.p?skuId=6439000&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'amd',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6438943/cart',
|
||||||
|
model: '5600x',
|
||||||
|
series: 'ryzen5600',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/amd-ryzen-5-5600x-4th-gen-6-core-12-threads-unlocked-desktop-processor-with-wraith-stealth-cooler/6438943.p?skuId=6438943&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6426149/cart',
|
||||||
|
model: 'ps5 console',
|
||||||
|
series: 'sonyps5c',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/sony-playstation-5-console/6426149.p?skuId=6426149&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'sony',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6430161/cart',
|
||||||
|
model: 'ps5 digital',
|
||||||
|
series: 'sonyps5de',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/sony-playstation-5-digital-edition-console/6430161.p?skuId=6430161&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series x',
|
||||||
|
series: 'xboxsx',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/microsoft-xbox-series-x-1tb-console-black/6428324.p?skuId=6428324'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'microsoft',
|
||||||
|
model: 'xbox series s',
|
||||||
|
series: 'xboxss',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/microsoft-xbox-series-s-512-gb-all-digital-console-disc-free-gaming-white/6430277.p?skuId=6430277'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-radeon-rx-6800-xt-16g-16gb-gddr6-pci-express-4-0-graphics-card-black-black/6440913.p?skuId=6440913'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-radeon-rx-6800-16g-16gb-gddr6-pci-express-4-0-graphics-card-black-black/6441020.p?skuId=6441020'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/xfx-amd-radeon-rx-6800-16gb-gddr6-pci-express-4-0-gaming-graphics-card-black/6442077.p?skuId=6442077'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/xfx-amd-radeon-rx-6800xt-16gb-gddr6-pci-express-4-0-gaming-graphics-card-black/6441226.p?skuId=6441226'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
model: 'merc',
|
||||||
|
series: 'rx6800xt',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/xfx-merc-319-amd-radeon-rx-6800xt-16gb-gddr6-pci-express-4-0-gaming-graphics-card-black/6442585.p?skuId=6442585'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'xfx',
|
||||||
|
model: 'amd reference',
|
||||||
|
series: 'rx6900xt',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/xfx-amd-radeon-rx-6900-xt-16gb-gddr6-pci-express-4-0-gaming-graphics-card-black/6444358.p?skuId=6444358'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6351845/cart',
|
||||||
|
model: '750 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/corsair-sf-series-750w-atx12v-2-4-eps12v-2-92-sfx12v-80-plus-platinum-modular-power-supply-black/6351845.p?skuId=6351845'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'corsair',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6351844/cart',
|
||||||
|
model: '600 platinum',
|
||||||
|
series: 'sf',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/corsair-sf-series-600w-atx12v-2-4-eps12v-2-92-sfx12v-80-plus-platinum-modular-power-supply-black/6351844.p?skuId=6351844'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'nvidia',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6439402/cart',
|
||||||
|
model: 'founders edition',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/nvidia-geforce-rtx-3060-ti-8gb-gddr6-pci-express-4-0-graphics-card-steel-and-black/6439402.p?skuId=6439402&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6442484/cart',
|
||||||
|
model: 'gaming oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-nvidia-geforce-rtx-3060-ti-gaming-oc-8g-gddr6-pci-express-4-0-graphics-card-black/6442484.p?skuId=6442484&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'gigabyte',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6442485/cart',
|
||||||
|
model: 'eagle oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/gigabyte-nvidia-geforce-rtx-3060-ti-eagle-oc-8g-gddr6-pci-express-4-0-graphics-card-black/6442485.p?skuId=6442485&intl=nosplash'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
brand: 'msi',
|
||||||
|
cartUrl: 'https://api.bestbuy.com/click/-/6441172/cart',
|
||||||
|
model: 'ventus 2x oc',
|
||||||
|
series: '3060ti',
|
||||||
|
url:
|
||||||
|
'https://www.bestbuy.com/site/msi-geforce-rtx-3060-ti-ventus-2x-oc-bv-8gb-gddr6-pci-express-4-0-graphics-card-black-black/6441172.p?skuId=6441172&intl=nosplash'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
name: 'bestbuy'
|
name: 'bestbuy'
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user