Skip to content

Commit

Permalink
[PROPOSAL] Better, simpler and unified config (#248)
Browse files Browse the repository at this point in the history
> [!WARNING]
> The purpose of this PR is to discuss a potentially better way to
handle configuration. While it is 100% functional as it is, it involves
huge changes to the script, especially the user interactions, and may
introduce unwanted behavior, and should be discussed before merging
anything.

This takes a different approach to configuration, with two goals in
mind: simplicity, both for users and maintainers, and dynamism.

> Replaces the old static configuration system with a dynamic `Config`
class that supports nested merges, defaults, YAML serialization, and
direct access as attributes. Introduces improved CLI options for better
usability and removes deprecated configuration files and structures.

# Benefits

## For developers
- A single way to access all user-configurable options, flags and
arguments, regardless of their origin, through the `CONFIG` variable.
- No need to pass command line arguments through each method where they
are needed.
- Much less verbose and fail-safe way to access options:
- Using `CONFIG[]`: `CONFIG["apprise.notify.login-code"]` instead of
`CONFIG["apprise"]["notify"]["login-code"]`.
- Using `CONFIG.get()`: `CONFIG.get("apprise.notify.login-code")`
instead of `CONFIG.get("apprise").get("notify").get("login-code")`
*(Note that the old method would throw an error if
`CONFIG.get("apprise")` returns `None`, because the `.get` method is not
a valid method for `NoneType`, but the new one allows you to get `None`
even if the `apprise` key is not in the config.*
- Using direct attribute access: `CONFIG.activities.ignore` (equivalent
to `CONFIG["activities"]["ignore"]`).
- All previous access options are still perfectly usable; the new ones
are just shorter and allow better readability.
- Easier to test, thanks to the `--debug`, `--email`, `--password` and
`--config` flags, and the 0-configuration-run.

## For users
- A single documented configuration file, instead of multiple files
created in different ways.
- No useless command-line flags.
- More useful command line flags (especially the `--email` and
`--password` flags, which allow 0-configuration-run).
- More advanced configuration options through the configuration file,
such as `activities.search` (useful to quickly add your own language
searches), `cooldown.min`/`cooldown.max` (useful to speed up the program
or try to avoid banning it at most), previously command-line specific
options, and more. For the full list of allowed configuration variables,
see the
[`README.md`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/README.md#configuration-file).
- Allows partial configuration (thanks to the new `Config` class), no
need to rewrite/copy the whole configuration, just add what you need.

# Changes

## Added
- The `Config` type, which extends the functionality of dictionaries to
allow simpler ways to manage configuration.
- Ability to configure the global proxy from the configuration file.
- Ability to configure headless mode from the configuration file.
- Ability to configure the activity titles to be searched from the
configuration file.
- Ability to configure the minimum and maximum cooldown between
retirements from the configuration file.
- Ability to configure the type of search to be performed from the
configuration file.
- The `--config` flag, which can be used to specify the configuration
path.
- The `--create-config` flag, which can be used to create an empty
configuration file (instead of copying and renaming a template file).
Note that the created file will already be populated with any
configuration options passed from the command line.
- The `--email` and `--password` flags, which allow the script to be run
for a single user, even without a configuration file.
- The `--debug` flag, which allows to set the logging level to `DEBUG`.

## Changed
- All configuration files have been merged into a single file,
`config.yaml`.
- All command line arguments are merged into the configuration
(`CONFIG`) and accessed through it.
- If no account is specified (either from the command line or from the
configuration file), a message is displayed to help the user create a
configuration file or specify an account from the command line.
- The `account.username` values have been renamed to `account.email`,
both internally and in the configuration.
- Some configuration variables have been moved, such as
`apprise.notify.uncaught-exception.enabled`, which has been moved to
`apprise.notify.uncaught-exception` (because the `enabled` key is
redundant), and `apprise.notify.incomplete-activity.ignore`, which has
been moved to `activities.ignore` (because it does not only affect
apprise). For the full list of allowed configuration variables, see the
[`README.md`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/README.md#configuration-file).
- Rewrote
[`README.md`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/README.md),
[`.github/ISSUE_TEMPLATE/bug_report.yml`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/.github/ISSUE_TEMPLATE/bug_report.yml),
[`test/test_main.py`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/test/test_main.py)
and
[`test/test_utils.py`](https://github.com/Kyrela/MS-Rewards-Farmer/blob/63c6b3200aacba5d38aedbaa8d46aba7619d2a65/test/test_utils.py)
to reflect these changes.

## Removed
- The `Account` data model.
- The `--chromeversion` flag, deprecated as of
982a592.
- The `--verbosenotifs` flag, deprecated as of
77fc8f0.
- The default configuration files and templates, now unused.
  • Loading branch information
klept0 authored Jan 21, 2025
2 parents 8604039 + a3d2aac commit 770e318
Show file tree
Hide file tree
Showing 17 changed files with 589 additions and 348 deletions.
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ body:
attributes:
label: Copy and paste your error
description: |
From the terminal that was running the farmer, copy and paste the error/bug here.
Run the program with -d argument (ex: python main.py -d) and, from the terminal that was running the farmer,
copy and paste the log/error/bug here.
validations:
required: true
- type: textarea
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,4 @@ runbot.bat
/google_trends.bak
/config-private.yaml
mypy.ini
config.yaml
4 changes: 0 additions & 4 deletions .template-config-private.yaml

This file was deleted.

161 changes: 124 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,22 @@
this [link](https://learn.microsoft.com/en-GB/cpp/windows/latest-supported-vc-redist?view=msvc-170)
and reboot your computer

4. Edit the `.template-config-private.yaml` accordingly and rename it to `config-private.yaml`.
4. Run the script with the following arguments:
```
python main.py -C
```

5. Edit the `accounts.json.sample` with your accounts credentials and rename it by removing
`.sample` at the end.
5. Open the generated `config.yaml` file and edit it with your information.

The "totp" field is not mandatory, only enter your TOTP key if you use it for 2FA (if
ommitting, don't keep it as an empty string, remove the line completely).

The "proxy" field is not mandatory, you can omit it if you don't want to use proxy (don't
keep it as an empty string, remove the line completely).

- If you want to add more than one account, the syntax is the following:

```json
[
{
"username": "Your Email 1",
"password": "Your Password 1",
"totp": "0123 4567 89ab cdef",
"proxy": "http://user:pass@host1:port"
},
{
"username": "Your Email 2",
"password": "Your Password 2",
"totp": "0123 4567 89ab cdef",
"proxy": "http://user:pass@host2:port"
}
]
```
You can add or remove accounts according to your will.

the "apprise.urls" field is not mandatory, you can remove it if you don't want to get notifications.

6. Run the script:

Expand All @@ -90,22 +77,122 @@
To import the XML file into Task Scheduler,
see [this guide](https://superuser.com/a/485565/709704).

## Launch arguments

- `-v/--visible` to disable headless
- `-l/--lang` to force a language (ex: en) see https://serpapi.com/google-languages for options
- `-g/--geo` to force a searching geolocation (ex: US)
see https://serpapi.com/google-trends-locations for options
`https://trends.google.com/trends/ for proper geolocation abbreviation for your choice. These MUST be uppercase!!!`
- `-p/--proxy` to add a proxy to the whole program, supports http/https/socks4/socks5 (
overrides per-account proxy in accounts.json)
`(ex: http://user:pass@host:port)`
- `-cv/--chromeversion` to use a specific version of chrome
`(ex: 118)`
- `-da/--disable-apprise` disables Apprise notifications for the session,
overriding [config.yaml](config.yaml).
Useful when running manually as opposed to on a schedule.
- `-t/--searchtype` to only do `desktop` or `mobile` searches, `(ex: --searchtype=mobile)`
## Configuration file

All the variable listed here can be added to you `config.yaml` configuration file, and the values represented here show
the default ones, if not said otherwise.

```yaml
# config.yaml
apprise: # 'apprise' is the name of the service used for notifications https://github.com/caronc/apprise
enabled: true # set it to false to disable apprise globally, can be overridden with command-line arguments.
notify:
incomplete-activity: true # set it to false to disable notifications for incomplete activities
uncaught-exception: true # set it to false to disable notifications for uncaught exceptions
login-code: true # set it to false to disable notifications for the temporary M$ Authenticator login code
summary: ON_ERROR # set it to ALWAYS to always receive a summary about your points progression or errors, or to
# NEVER to never receive a summary, even in case of an error.
urls: # add apprise urls here to receive notifications on the specified services :
# https://github.com/caronc/apprise#supported-notifications
# Empty by default.
- discord://{WebhookID}/{WebhookToken} # Exemple url
browser:
geolocation: US # Replace with your country code https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2.
# Can be overridden with command-line arguments.
language: en # Replace with your language code https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes.
# Can be overridden with command-line arguments.
visible: false # set it to true to show the browser window, can be overridden with command-line arguments.
proxy: null # set the global proxy using the 'http://user:pass@host:port' syntax.
# Override per-account proxies. Can be overridden with command-line arguments.
activities:
ignore: # list of activities to ignore, like activities that can't be completed
- Get 50 entries plus 1000 points!
- Safeguard your family's info
search: # list of searches to do for search-based activities
"Black Friday shopping": black friday deals
"Discover open job roles": jobs at microsoft
"Expand your vocabulary": define demure
"Find places to stay": hotels rome italy
"Find somewhere new to explore": directions to new york
"Gaming time": vampire survivors video game
"Get your shopping done faster": new iphone
"Houses near you": apartments manhattan
"How's the economy?": sp 500
"Learn to cook a new recipe": how cook pierogi
"Let's watch that movie again!": aliens movie
"Plan a quick getaway": flights nyc to paris
"Prepare for the weather": weather tomorrow
"Quickly convert your money": convert 374 usd to yen
"Search the lyrics of a song": black sabbath supernaut lyrics
"Stay on top of the elections": election news latest
"Too tired to cook tonight?": Pizza Hut near me
"Translate anything": translate pencil sharpener to spanish
"What time is it?": china time
"What's for Thanksgiving dinner?": pumpkin pie recipe
"Who won?": braves score
"You can track your package": usps tracking
logging:
level: INFO # Set to DEBUG, WARNING, ERROR or CRITICAL to change the level of displayed information in the terminal
# See https://docs.python.org/3/library/logging.html#logging-levels. Can be overridden with command-line arguments.
retries:
base_delay_in_seconds: 120 # The base wait time between each retries. Multiplied by two each try.
max: 4 # The maximal number of retries to do
strategy: EXPONENTIAL # Set it to CONSTANT to use the same delay between each retries.
# Else, increase it exponentially each time.
cooldown:
min: 300 # The minimal wait time between two searches/activities
max: 600 # The maximal wait time between two searches/activities
search:
type: both # Set it to 'mobile' or 'desktop' to only complete searches on one plateform,
# can be overridden with command-line arguments.
accounts: # The accounts to use. You can put zero, one or an infinite number of accounts here.
# Empty by default, can be overridden with command-line arguments.
- email: Your Email 1 # replace with your email
password: Your Password 1 # replace with your password
totp: 0123 4567 89ab cdef # replace with your totp, or remove it
proxy: http://user:pass@host1:port # replace with your account proxy, or remove it
- email: Your Email 2 # replace with your email
password: Your Password 2 # replace with your password
totp: 0123 4567 89ab cdef # replace with your totp, or remove it
proxy: http://user:pass@host2:port # replace with your account proxy, or remove it
```
## Usage
```
usage: main.py [-h] [-c CONFIG] [-C] [-v] [-l LANG] [-g GEO] [-em EMAIL] [-pw PASSWORD]
[-p PROXY] [-t {desktop,mobile,both}] [-da] [-d]

A simple bot that uses Selenium to farm M$ Rewards in Python

options:
-h, --help show this help message and exit
-c CONFIG, --config CONFIG
Specify the configuration file path
-C, --create-config Create a fillable configuration file with basic settings and given
ones if none exists
-v, --visible Visible browser (Disable headless mode)
-l LANG, --lang LANG Language (ex: en) see https://serpapi.com/google-languages for options
-g GEO, --geo GEO Searching geolocation (ex: US) see https://serpapi.com/google-trends-
locations for options (should be uppercase)
-em EMAIL, --email EMAIL
Email address of the account to run. Only used if a password is given.
-pw PASSWORD, --password PASSWORD
Password of the account to run. Only used if an email is given.
-p PROXY, --proxy PROXY
Global Proxy, supports http/https/socks4/socks5 (overrides config per-
account proxies) `(ex: http://user:pass@host:port)`
-t {desktop,mobile,both}, --searchtype {desktop,mobile,both}
Set to search in either desktop, mobile or both (default: both)
-da, --disable-apprise
Disable Apprise notifications, useful when developing
-d, --debug Set the logging level to DEBUG

At least one account should be specified, either using command line arguments or a
configuration file. All specified arguments will override the configuration file values
```

You can display this message at any moment using `python main.py -h`.

## Features

Expand Down
14 changes: 0 additions & 14 deletions accounts.json.sample

This file was deleted.

22 changes: 0 additions & 22 deletions config.yaml

This file was deleted.

Loading

0 comments on commit 770e318

Please sign in to comment.