Compare commits
62 Commits
v0.23.3.2
...
v0.23.4.13
Author | SHA1 | Date | |
---|---|---|---|
0936dee06c | |||
a1c6fb06a0 | |||
c57bf99976 | |||
995b45464f | |||
ebe28c948a | |||
34d7230faf | |||
3235991cce | |||
3fba1d6b3d | |||
88c8d5a9a0 | |||
382749a8d8 | |||
0c877e315b | |||
c95f642fee | |||
da0276f9a6 | |||
f89f91e969 | |||
56c2ca1b6e | |||
3cee2d1f0f | |||
0ed03877ce | |||
491c9f5efe | |||
8445b556e7 | |||
d02c5c2969 | |||
bff4183cb6 | |||
47f5142837 | |||
a32fd039dd | |||
311e684c0c | |||
52038a86d5 | |||
c35a107641 | |||
b53b2f0fae | |||
8da9b6221a | |||
caa41c85f6 | |||
da3b5d5768 | |||
f96d0233f9 | |||
c693a5182e | |||
0dfba6a9ff | |||
ee3eca9658 | |||
0e8680daca | |||
8e3606f1a3 | |||
bd0bcc9ac7 | |||
c6f2226e64 | |||
308807d800 | |||
91565d840e | |||
b4a9dd88f8 | |||
8435aa23ba | |||
09cd275a69 | |||
e23a67231e | |||
6a03d99abf | |||
2e344749a6 | |||
5aecefbd9d | |||
8b9ee5042d | |||
1e93006c3d | |||
b13bfcdbf3 | |||
771dbdf826 | |||
9646d112d2 | |||
a09c37a065 | |||
ba75e961fa | |||
3b5780dbd6 | |||
fccd0134b5 | |||
b9010fa856 | |||
3e5410289e | |||
661a019b0a | |||
23d682959d | |||
5806ccb6ca | |||
a9bc78b701 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -37,7 +37,6 @@ pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
@ -103,5 +102,4 @@ ENV/
|
||||
|
||||
debug/
|
||||
log/
|
||||
docs/
|
||||
*dump.json
|
||||
|
13
.pre-commit-config.yaml
Normal file
13
.pre-commit-config.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
|
||||
default_language_version:
|
||||
python: python3.7
|
14
.travis.yml
14
.travis.yml
@ -1,14 +0,0 @@
|
||||
# Config file for automatic testing at travis-ci.org
|
||||
|
||||
language: python
|
||||
python:
|
||||
- 3.8
|
||||
- 3.7
|
||||
|
||||
# Command to install dependencies, e.g. pip install -r requirements_dev.txt --use-mirrors
|
||||
install: pip install -U tox-travis
|
||||
|
||||
# Command to run tests, e.g. python setup.py test
|
||||
script: tox
|
||||
|
||||
|
@ -70,14 +70,14 @@ Ready to contribute? Here's how to set up `erepublik` for local development.
|
||||
|
||||
Now you can make your changes locally.
|
||||
|
||||
5. When you're done making changes, check that your changes pass flake8 and the
|
||||
tests, including testing other Python versions with tox::
|
||||
5. When you're done making changes, check that your changes pass flake8, isort and the
|
||||
tests::
|
||||
|
||||
$ flake8 erepublik tests
|
||||
$ python setup.py test or py.test
|
||||
$ tox
|
||||
$ isort erepublik
|
||||
$ python setup.py test
|
||||
|
||||
To get flake8 and tox, just pip install them into your virtualenv.
|
||||
To get flake8 and isort, just pip install them into your virtualenv.
|
||||
|
||||
6. Commit your changes and push your branch to GitHub::
|
||||
|
||||
|
21
HISTORY.rst
21
HISTORY.rst
@ -2,6 +2,25 @@
|
||||
History
|
||||
=======
|
||||
|
||||
0.23.4 (2021-01-05)
|
||||
-------------------
|
||||
* Added expiration data to inventory items
|
||||
* Inventory is now based on `classes.Inventory`
|
||||
* Requirement update to make them more flexible regarding versions required
|
||||
* Restructured inventory
|
||||
|
||||
0.23.3 (2020-12-17)
|
||||
-------------------
|
||||
* Fixed carpet bombing
|
||||
* Fixed hits done amount when fighting on ground
|
||||
* Minor requirement updates
|
||||
* Minor tweaks to method signatures
|
||||
* Fixed buy food if unable to work or train because not enough energy and not enough food
|
||||
* Fixed applications for party presidency and congress if not a party member
|
||||
* Removed tox
|
||||
* Updates to github.io config generator
|
||||
* Fixed `Citizen.concurrency_available` stuck in unset state if exception is being raised while doing concurrency task
|
||||
|
||||
0.23.2 (2020-12-01)
|
||||
-------------------
|
||||
* Added concurrency checks to guard against simultaneous fighting/wam'ing/traveling
|
||||
@ -17,7 +36,7 @@ History
|
||||
|
||||
0.23.0 (2020-11-26)
|
||||
-------------------
|
||||
* ***0.23 - last supported version for Python 3.7.***
|
||||
* ***0.23 - last officially supported version for Python 3.7.***
|
||||
* Added `Config.maverick` switch, to allow/deny automated fighting in non native divisions if the player has MaverickPack
|
||||
* Added `CitizenMedia.get_article(article_id:int)` method to get article data
|
||||
* Added `CitizenMedia.delete_article(article_id:int)` method to delete article
|
||||
|
1
LICENSE
1
LICENSE
@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
4
Makefile
4
Makefile
@ -47,7 +47,6 @@ clean-pyc: ## remove Python file artifacts
|
||||
rm -rf log/
|
||||
|
||||
clean-test: ## remove test and coverage artifacts
|
||||
rm -fr .tox/
|
||||
rm -f .coverage
|
||||
rm -fr htmlcov/
|
||||
rm -fr .pytest_cache
|
||||
@ -58,9 +57,6 @@ lint: ## check style with flake8
|
||||
test: ## run tests quickly with the default Python
|
||||
python setup.py test
|
||||
|
||||
test-all: ## run tests on every Python version with tox
|
||||
tox
|
||||
|
||||
coverage: ## check code coverage quickly with the default Python
|
||||
coverage run --source erepublik setup.py test
|
||||
coverage report -m
|
||||
|
@ -34,4 +34,3 @@ This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypack
|
||||
|
||||
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
|
||||
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
|
||||
|
||||
|
61
docs/erepublik.rst
Normal file
61
docs/erepublik.rst
Normal file
@ -0,0 +1,61 @@
|
||||
erepublik package
|
||||
=================
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
erepublik.access\_points module
|
||||
-------------------------------
|
||||
|
||||
.. automodule:: erepublik.access_points
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
erepublik.citizen module
|
||||
------------------------
|
||||
|
||||
.. automodule:: erepublik.citizen
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
erepublik.classes module
|
||||
------------------------
|
||||
|
||||
.. automodule:: erepublik.classes
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
erepublik.constants module
|
||||
--------------------------
|
||||
|
||||
.. automodule:: erepublik.constants
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
erepublik.types module
|
||||
----------------------
|
||||
|
||||
.. automodule:: erepublik.types
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
erepublik.utils module
|
||||
----------------------
|
||||
|
||||
.. automodule:: erepublik.utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: erepublik
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
189
docs/index.html
189
docs/index.html
@ -8,15 +8,12 @@
|
||||
<meta name="generator" content="Jekyll v4.0.1">
|
||||
<title>eBot configuration</title>
|
||||
<!-- CSS only -->
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
|
||||
crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
@ -37,14 +34,14 @@
|
||||
<div class="col-12 col-sm-8 col-md-6">
|
||||
<h3>Login data</h3>
|
||||
<div class="form-group">
|
||||
<input type="email" class="form-control form-control-sm" onchange="updateJson()" id="email" placeholder="E-mail...">
|
||||
<input type="password" class="form-control form-control-sm mt-3" onchange="updateJson()" id="password" disabled placeholder="Password..."
|
||||
<label for="email" class="hidden"></label><input type="email" class="form-control" onchange="updateJson()" id="email" placeholder="E-mail...">
|
||||
<label for="password" class="hidden"></label><input type="password" class="form-control" onchange="updateJson()" id="password" disabled placeholder="Password..."
|
||||
aria-describedby="passwordHelpBlock">
|
||||
<small id="passwordHelpBlock" class="form-text text-muted"><strong>NEVER</strong> enter Your passwords on 3rd party sites and <strong class="text-upper">DO NOT</strong> reuse Your
|
||||
password!</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="col-6 col-sm-4 col-md-3">
|
||||
<h3>Basic tasks</h3>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="work" checked>
|
||||
@ -59,29 +56,6 @@
|
||||
<label class="custom-control-label" for="ot">Work overtime</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<h3>Misc</h3>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="renew_houses" checked>
|
||||
<label class="custom-control-label" for="renew_houses">Auto renew houses</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="random_sleep" checked>
|
||||
<label class="custom-control-label" for="random_sleep">Random sleep</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="buy_gold">
|
||||
<label class="custom-control-label" for="buy_gold">Auto buy 10g</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="interactive" checked>
|
||||
<label class="custom-control-label" for="interactive">Interactive</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="debug">
|
||||
<label class="custom-control-label" for="debug">Debug</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@ -200,6 +174,90 @@
|
||||
<label class="custom-control-label" for="epic_hunt_ebs">Spend <small>[all]</small> EBs in epics</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<h3 class="mt-4">Misc</h3>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="renew_houses" checked>
|
||||
<label class="custom-control-label" for="renew_houses">Auto renew houses</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="random_sleep" checked>
|
||||
<label class="custom-control-label" for="random_sleep">Random sleep</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="buy_gold">
|
||||
<label class="custom-control-label" for="buy_gold">Auto buy 10g</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="interactive" checked>
|
||||
<label class="custom-control-label" for="interactive">Interactive</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="debug">
|
||||
<label class="custom-control-label" for="debug">Debug</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="spin_wheel_of_fortune">
|
||||
<label class="custom-control-label" for="spin_wheel_of_fortune">Auto spin 10% of cc in WheelOfFortune</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="congress">
|
||||
<label class="custom-control-label" for="congress">Auto candidate for congress</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="party_president">
|
||||
<label class="custom-control-label" for="party_president">Auto candidate for party presidency</label>
|
||||
</div>
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="contribute_cc">
|
||||
<label class="custom-control-label" for="contribute_cc">Contribute cc to country's account (weekly)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<h3 class="mt-4">Advanced</h3>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="telegram">
|
||||
<label class="custom-control-label" for="telegram">Notify trough Telegram</label>
|
||||
</div>
|
||||
|
||||
<label for="telegram_chat_id">Telegram's chat ID</label>
|
||||
<input type="text" class="form-control" onchange="updateJson()" id="telegram_chat_id" placeholder="Chat ID">
|
||||
<label for="telegram_token">Telegram Bot token</label>
|
||||
<input type="text" class="form-control" onchange="updateJson()" id="telegram_token" placeholder="864251270:AAFzZZdjspI-kIgJVk4gF3TViGFoHnf8H4o">
|
||||
<small id="telegramTokenHelp" class="form-text text-muted">Only enter token if You want to use your own Telegram bot for notification sending</small>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="proxy">
|
||||
<label class="custom-control-label" for="proxy">Use proxy</label>
|
||||
</div>
|
||||
<label for="proxy_kind">Proxy kind</label>
|
||||
<div class="form-group">
|
||||
<select class="form-control custom-select" id="proxy_kind">
|
||||
<option value="socks" selected>SOCKS5</option>
|
||||
<option value="http">HTTP</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="proxy_host">Proxy hostname or IP address</label>
|
||||
<input type="text" class="form-control" onchange="updateJson()" id="proxy_host" placeholder="localhost">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="proxy_port">Proxy port</label>
|
||||
<input type="text" class="form-control" onchange="updateJson()" id="proxy_port" placeholder="8080">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="proxy_user">Proxy username (optional)</label>
|
||||
<input type="text" class="form-control" onchange="updateJson()" id="proxy_user" placeholder="user">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="proxy_password">Proxy password (optional)</label>
|
||||
<input type="password" class="form-control" onchange="updateJson()" id="proxy_password" placeholder="password" disabled>
|
||||
<small id="proxyHelpBlock" class="form-text text-muted"><strong>NEVER</strong> enter Your passwords on 3rd party sites and <strong class="text-upper">DO NOT</strong> reuse Your password!</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -212,7 +270,9 @@
|
||||
function disable(element){
|
||||
element.checked = false;
|
||||
element.disabled = true;
|
||||
element.value = null;
|
||||
}
|
||||
|
||||
function updateJson() {
|
||||
let config = {};
|
||||
let email = document.getElementById('email'); // Generated
|
||||
@ -228,6 +288,14 @@
|
||||
config.renew_houses = renew_houses.checked;
|
||||
let random_sleep = document.getElementById('random_sleep'); // Generated
|
||||
config.random_sleep = random_sleep.checked;
|
||||
let spin_wheel_of_fortune = document.getElementById('spin_wheel_of_fortune'); // Generated
|
||||
config.spin_wheel_of_fortune = spin_wheel_of_fortune.checked;
|
||||
let congress = document.getElementById('congress'); // Generated
|
||||
config.congress = congress.checked;
|
||||
let party_president = document.getElementById('party_president'); // Generated
|
||||
config.party_president = party_president.checked;
|
||||
let contribute_cc = document.getElementById('contribute_cc'); // Generated
|
||||
config.contribute_cc = contribute_cc.checked ? 10000 : false;
|
||||
let buy_gold = document.getElementById('buy_gold'); // Generated
|
||||
config.buy_gold = buy_gold.checked;
|
||||
let interactive = document.getElementById('interactive'); // Generated
|
||||
@ -297,7 +365,7 @@
|
||||
let travel_to_fight = document.getElementById('travel_to_fight'); // Generated
|
||||
let epic_hunt = document.getElementById('epic_hunt'); // Generated
|
||||
let epic_hunt_ebs = document.getElementById('epic_hunt_ebs'); // Generated
|
||||
if (config.fight){
|
||||
if (config.fight) {
|
||||
air.disabled = false;
|
||||
ground.disabled = false;
|
||||
boosters.disabled = false;
|
||||
@ -325,7 +393,7 @@
|
||||
}
|
||||
|
||||
config.air = air.checked;
|
||||
config.ground = ground.cehcked;
|
||||
config.ground = ground.checked;
|
||||
config.boosters = boosters.checked;
|
||||
config.continuous_fighting = continuous_fighting.checked;
|
||||
config.next_energy = next_energy.checked;
|
||||
@ -334,6 +402,59 @@
|
||||
config.travel_to_fight = travel_to_fight.checked;
|
||||
config.epic_hunt = epic_hunt.checked;
|
||||
config.epic_hunt_ebs = config.epic_hunt ? epic_hunt_ebs.checked : config.epic_hunt;
|
||||
config.maverick = false;
|
||||
|
||||
// Advanced
|
||||
let telegram = document.getElementById('telegram'); // Generated
|
||||
config.telegram = telegram.checked;
|
||||
let telegram_chat_id = document.getElementById('telegram_chat_id'); // Generated
|
||||
let telegram_token = document.getElementById('telegram_token'); // Generated
|
||||
if (config.telegram) {
|
||||
telegram_chat_id.disabled = false;
|
||||
telegram_token.disabled = false;
|
||||
} else {
|
||||
disable(telegram_chat_id);
|
||||
disable(telegram_token);
|
||||
}
|
||||
config.telegram_chat_id = telegram_chat_id.value;
|
||||
config.telegram_token = telegram_token.value;
|
||||
|
||||
let _proxy = {};
|
||||
let proxy = document.getElementById('proxy'); // Generated
|
||||
let proxy_kind = document.getElementById('proxy_kind'); // Generated
|
||||
let proxy_host = document.getElementById('proxy_host'); // Generated
|
||||
let proxy_port = document.getElementById('proxy_port'); // Generated
|
||||
let proxy_user = document.getElementById('proxy_user'); // Generated
|
||||
|
||||
if (proxy.checked) {
|
||||
proxy_kind.disabled = false;
|
||||
proxy_host.disabled = false;
|
||||
proxy_port.disabled = false;
|
||||
proxy_user.disabled = false;
|
||||
} else {
|
||||
disable(proxy_kind);
|
||||
disable(proxy_host);
|
||||
disable(proxy_port);
|
||||
disable(proxy_user);
|
||||
}
|
||||
_proxy.kind = proxy_kind.value;
|
||||
_proxy.host = proxy_host.value;
|
||||
_proxy.port = proxy_port.value;
|
||||
_proxy.username = proxy_user.value;
|
||||
_proxy.password = ""
|
||||
if (proxy.checked) {
|
||||
delete config._proxy;
|
||||
config.proxy = _proxy;
|
||||
} else {
|
||||
delete config.proxy;
|
||||
config._proxy = {
|
||||
'kind': 'socks or http',
|
||||
'host': 'localhost',
|
||||
'port': 8080,
|
||||
'username': 'optional',
|
||||
'password': 'optional'
|
||||
}
|
||||
}
|
||||
let pre = document.getElementById('json-output');
|
||||
pre.textContent = JSON.stringify(config, null, 2);
|
||||
}
|
||||
|
7
docs/modules.rst
Normal file
7
docs/modules.rst
Normal file
@ -0,0 +1,7 @@
|
||||
erepublik
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
erepublik
|
@ -7,4 +7,3 @@ To use eRepublik script in a project::
|
||||
from erepublik import Citizen
|
||||
player = Citizen('email@domain.com', 'password')
|
||||
player.update_all()
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
__author__ = """Eriks Karls"""
|
||||
__email__ = 'eriks@72.lv'
|
||||
__version__ = '0.23.3.2'
|
||||
__version__ = '0.23.4.13'
|
||||
|
||||
from erepublik import classes, utils, constants
|
||||
from erepublik import classes, constants, utils
|
||||
from erepublik.citizen import Citizen
|
||||
|
||||
__all__ = ["classes", "utils", "Citizen", 'constants']
|
||||
|
@ -13,43 +13,43 @@ __all__ = ['SlowRequests', 'CitizenAPI']
|
||||
class SlowRequests(Session):
|
||||
last_time: datetime.datetime
|
||||
timeout: datetime.timedelta = datetime.timedelta(milliseconds=500)
|
||||
uas: List[str] = [
|
||||
_uas: List[str] = [
|
||||
# Chrome
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36',
|
||||
|
||||
# FireFox
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0',
|
||||
]
|
||||
debug: bool = False
|
||||
|
||||
def __init__(self, proxies: Dict[str, str] = None):
|
||||
def __init__(self, proxies: Dict[str, str] = None, user_agent: str = None):
|
||||
super().__init__()
|
||||
if proxies:
|
||||
self.proxies = proxies
|
||||
if user_agent is None:
|
||||
user_agent = random.choice(self._uas)
|
||||
self.request_log_name = utils.get_file(utils.now().strftime("debug/requests_%Y-%m-%d.log"))
|
||||
self.last_time = utils.now()
|
||||
self.headers.update({
|
||||
'User-Agent': random.choice(self.uas)
|
||||
})
|
||||
self.headers.update({'User-Agent': user_agent})
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(last_time=self.last_time, timeout=self.timeout, user_agent=self.headers['User-Agent'],
|
||||
request_log_name=self.request_log_name, debug=self.debug)
|
||||
return dict(last_time=self.last_time, timeout=self.timeout, cookies=self.cookies.get_dict(), debug=self.debug,
|
||||
user_agent=self.headers['User-Agent'], request_log_name=self.request_log_name, proxies=self.proxies)
|
||||
|
||||
def request(self, method, url, *args, **kwargs):
|
||||
self._slow_down_requests()
|
||||
@ -120,6 +120,10 @@ class CitizenBaseAPI:
|
||||
self._req = SlowRequests()
|
||||
self.token = ""
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(url=self.url, request=self._req.as_dict, token=self.token)
|
||||
|
||||
def post(self, url: str, data=None, json=None, **kwargs) -> Response:
|
||||
return self._req.post(url, data, json, **kwargs)
|
||||
|
||||
@ -305,11 +309,11 @@ class ErepublikEconomyAPI(CitizenBaseAPI):
|
||||
return self.post(f"{self.url}/main/buyGoldItems", data=data)
|
||||
|
||||
def _post_economy_activate_booster(self, quality: int, duration: int, kind: str) -> Response:
|
||||
data = dict(type=kind, quality=quality, duration=duration, fromInventory=True)
|
||||
data = dict(type=kind, quality=quality, duration=duration, fromInventory=True, _token=self.token)
|
||||
return self.post(f"{self.url}/economy/activateBooster", data=data)
|
||||
|
||||
def _post_economy_activate_house(self, quality: int) -> Response:
|
||||
data = {"action": "activate", "quality": quality, "type": "house", "_token": self.token}
|
||||
data = dict(action="activate", quality=quality, type="house", _token=self.token)
|
||||
return self.post(f"{self.url}/economy/activateHouse", data=data)
|
||||
|
||||
def _post_economy_donate_items_action(self, citizen_id: int, amount: int, industry: int,
|
||||
@ -595,6 +599,10 @@ class ErepublikProfileAPI(CitizenBaseAPI):
|
||||
data = dict(_token=self.token, rewardId=reward_id)
|
||||
return self.post(f"{self.url}/main/weekly-challenge-collect-reward", data=data)
|
||||
|
||||
def _post_main_weekly_challenge_collect_all(self, max_reward_id: int) -> Response:
|
||||
data = dict(_token=self.token, maxRewardId=max_reward_id)
|
||||
return self.post(f"{self.url}/main/weekly-challenge-collect-all", data=data)
|
||||
|
||||
def _post_main_profile_update(self, action: str, params: str):
|
||||
data = {"action": action, "params": params, "_token": self.token}
|
||||
return self.post(f"{self.url}/main/profile-update", data=data)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,15 +3,15 @@ import hashlib
|
||||
import threading
|
||||
import weakref
|
||||
from decimal import Decimal
|
||||
from typing import Any, Dict, List, NamedTuple, Tuple, Union, NoReturn, Generator, Iterable
|
||||
from typing import Any, Dict, Generator, Iterable, List, NamedTuple, NoReturn, Union
|
||||
|
||||
from requests import Response, Session, post
|
||||
|
||||
from . import utils, constants
|
||||
from . import constants, types, utils
|
||||
|
||||
__all__ = ['Battle', 'BattleDivision', 'BattleSide', 'Company', 'Config', 'Details', 'Energy', 'ErepublikException',
|
||||
'ErepublikNetworkException', 'EnergyToFight',
|
||||
'Holding', 'MyCompanies', 'MyJSONEncoder', 'OfferItem', 'Politics', 'Reporter', 'TelegramReporter']
|
||||
'ErepublikJSONEncoder', 'ErepublikNetworkException', 'EnergyToFight', 'Holding', 'Inventory', 'MyCompanies',
|
||||
'OfferItem', 'Politics', 'Reporter', 'TelegramReporter', ]
|
||||
|
||||
|
||||
class ErepublikException(Exception):
|
||||
@ -396,11 +396,11 @@ class Config:
|
||||
self.spin_wheel_of_fortune = False
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[bool, int, str, List[str]]]:
|
||||
return dict(email=self.email, work=self.work, train=self.train, wam=self.wam, ot=self.ot,
|
||||
auto_sell=self.auto_sell, auto_sell_all=self.auto_sell_all, employees=self.employees,
|
||||
fight=self.fight, air=self.air, ground=self.ground, all_in=self.all_in,
|
||||
next_energy=self.next_energy, boosters=self.boosters, travel_to_fight=self.travel_to_fight,
|
||||
next_energy=self.next_energy, travel_to_fight=self.travel_to_fight,
|
||||
always_travel=self.always_travel, epic_hunt=self.epic_hunt, epic_hunt_ebs=self.epic_hunt_ebs,
|
||||
rw_def_side=self.rw_def_side, interactive=self.interactive, maverick=self.maverick,
|
||||
continuous_fighting=self.continuous_fighting, auto_buy_raw=self.auto_buy_raw,
|
||||
@ -454,7 +454,7 @@ class Energy:
|
||||
return self.recovered + self.recoverable
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[int, datetime.datetime, bool]]:
|
||||
return dict(limit=self.limit, interval=self.interval, recoverable=self.recoverable, recovered=self.recovered,
|
||||
reference_time=self.reference_time, food_fights=self.food_fights,
|
||||
is_recoverable_full=self.is_recoverable_full, is_recovered_full=self.is_recovered_full,
|
||||
@ -509,7 +509,7 @@ class Details:
|
||||
return next_level_up - self.xp
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[int, float, str, constants.Country, bool]]:
|
||||
return dict(xp=self.xp, cc=self.cc, pp=self.pp, pin=self.pin, gold=self.gold, next_pp=self.next_pp,
|
||||
citizen_id=self.citizen_id, citizenship=self.citizenship, current_region=self.current_region,
|
||||
current_country=self.current_country, residence_region=self.residence_region,
|
||||
@ -528,7 +528,7 @@ class Politics:
|
||||
is_country_president: bool = False
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[bool, int, str]]:
|
||||
return dict(is_party_member=self.is_party_member, party_id=self.party_id, party_slug=self.party_slug,
|
||||
is_party_president=self.is_party_president, is_congressman=self.is_congressman,
|
||||
is_country_president=self.is_country_president)
|
||||
@ -566,7 +566,7 @@ class Reporter:
|
||||
return self.citizen.details.citizen_id
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[bool, int, str, List[Dict[Any, Any]]]]:
|
||||
return dict(name=self.name, email=self.email, citizen_id=self.citizen_id, key=self.key, allowed=self.allowed,
|
||||
queue=self.__to_update)
|
||||
|
||||
@ -598,10 +598,10 @@ class Reporter:
|
||||
if self.__to_update:
|
||||
for unreported_data in self.__to_update:
|
||||
unreported_data.update(player_id=self.citizen_id, key=self.key)
|
||||
unreported_data = utils.json.loads(utils.json.dumps(unreported_data, cls=MyJSONEncoder))
|
||||
unreported_data = utils.json.loads(utils.json.dumps(unreported_data, cls=ErepublikJSONEncoder))
|
||||
self._req.post(f"{self.url}/bot/update", json=unreported_data)
|
||||
self.__to_update.clear()
|
||||
data = utils.json.loads(utils.json.dumps(data, cls=MyJSONEncoder))
|
||||
data = utils.json.loads(utils.json.dumps(data, cls=ErepublikJSONEncoder))
|
||||
r = self._req.post(f"{self.url}/bot/update", json=data)
|
||||
return r
|
||||
|
||||
@ -649,6 +649,16 @@ class Reporter:
|
||||
air=battle.has_air, hits=hits,
|
||||
round=battle.zone_id, extra=dict(battle=battle, side=side, division=division)))
|
||||
|
||||
def report_money_donation(self, citizen_id: int, amount: float, is_currency: bool = True):
|
||||
cur = 'cc' if is_currency else 'gold'
|
||||
self.report_action('DONATE_MONEY', dict(citizen_id=citizen_id, amount=amount, currency=cur),
|
||||
f"Successfully donated {amount}{cur} to citizen with id {citizen_id}!")
|
||||
|
||||
def report_item_donation(self, citizen_id: int, amount: float, quality: int, industry: str):
|
||||
self.report_action('DONATE_ITEMS',
|
||||
dict(citizen_id=citizen_id, amount=amount, quality=quality, industry=industry),
|
||||
f"Successfully donated {amount} x {industry} q{quality} to citizen with id {citizen_id}!")
|
||||
|
||||
def report_promo(self, kind: str, time_until: datetime.datetime):
|
||||
self._req.post(f"{self.url}/promos/add/", data=dict(kind=kind, time_untill=time_until))
|
||||
|
||||
@ -660,16 +670,19 @@ class Reporter:
|
||||
except: # noqa
|
||||
return []
|
||||
|
||||
def fetch_tasks(self) -> List[Union[str, Tuple[Any]]]:
|
||||
def fetch_tasks(self) -> List[Dict[str, Any]]:
|
||||
try:
|
||||
task_response = self._req.get(f'{self.url}/api/v1/command',
|
||||
params=dict(citizen=self.citizen_id, key=self.key))
|
||||
return task_response.json().get('task_collection')
|
||||
task_response = self._req.post(
|
||||
f'{self.url}/api/v1/command', data=dict(citizen=self.citizen_id, key=self.key)).json()
|
||||
if task_response.get('status'):
|
||||
return task_response.get('data')
|
||||
else:
|
||||
return []
|
||||
except: # noqa
|
||||
return []
|
||||
|
||||
|
||||
class MyJSONEncoder(utils.json.JSONEncoder):
|
||||
class ErepublikJSONEncoder(utils.json.JSONEncoder):
|
||||
def default(self, o):
|
||||
from erepublik.citizen import Citizen
|
||||
if isinstance(o, Decimal):
|
||||
@ -683,7 +696,7 @@ class MyJSONEncoder(utils.json.JSONEncoder):
|
||||
return dict(__type__='timedelta', days=o.days, seconds=o.seconds,
|
||||
microseconds=o.microseconds, total_seconds=o.total_seconds())
|
||||
elif isinstance(o, Response):
|
||||
return dict(headers=o.headers.__dict__, url=o.url, text=o.text)
|
||||
return dict(headers=dict(o.__dict__['headers']), url=o.url, text=o.text, status_code=o.status_code)
|
||||
elif hasattr(o, 'as_dict'):
|
||||
return o.as_dict
|
||||
elif isinstance(o, set):
|
||||
@ -730,7 +743,7 @@ class BattleSide:
|
||||
return self.country.iso
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
def as_dict(self) -> Dict[str, Union[int, constants.Country, bool, List[constants.Country]]]:
|
||||
return dict(points=self.points, country=self.country, is_defender=self.is_defender, allies=self.allies,
|
||||
deployed=self.deployed)
|
||||
|
||||
@ -973,7 +986,7 @@ class TelegramReporter:
|
||||
self._last_time = utils.good_timedelta(utils.now(), datetime.timedelta(minutes=-5))
|
||||
self._last_full_energy_report = utils.good_timedelta(utils.now(), datetime.timedelta(minutes=-30))
|
||||
if self.__queue:
|
||||
self.send_message("\n\n––––––––––––––––––––––\n\n".join(self.__queue))
|
||||
self.send_message("Telegram initialized")
|
||||
|
||||
def send_message(self, message: str) -> bool:
|
||||
self.__queue.append(message)
|
||||
@ -1001,15 +1014,29 @@ class TelegramReporter:
|
||||
new_line = '\n' if multiple else ''
|
||||
self.send_message(f"New award: {new_line}*{msg}*")
|
||||
|
||||
def report_fight(self, battle: "Battle", invader: bool, division: "BattleDivision", damage: float, hits: int):
|
||||
side_txt = (battle.invader if invader else battle.defender).country.iso
|
||||
self.send_message(f"*Fight report*:\n{int(damage):,d} dmg ({hits} hits) in"
|
||||
f" [battle {battle.id} for {battle.region_name[:16]}]({battle.link}) in d{division.div} on "
|
||||
f"{side_txt} side")
|
||||
|
||||
def report_item_donation(self, citizen_id: int, amount: float, product: str):
|
||||
self.send_message(f"*Donation*: {amount} x {product} to citizen "
|
||||
f"[{citizen_id}](https://www.erepublik.com/en/citizen/profile/{citizen_id})")
|
||||
|
||||
def report_money_donation(self, citizen_id: int, amount: float, is_currency: bool = True):
|
||||
self.send_message(f"*Donation*: {amount}{'cc' if is_currency else 'gold'} to citizen "
|
||||
f"[{citizen_id}](https://www.erepublik.com/en/citizen/profile/{citizen_id})")
|
||||
|
||||
def __send_messages(self):
|
||||
while self._next_time > utils.now():
|
||||
if self.__thread_stopper.is_set():
|
||||
break
|
||||
self.__thread_stopper.wait(utils.get_sleep_seconds(self._next_time))
|
||||
|
||||
message = "\n\n––––––––––––––––––––––\n\n".join(self.__queue)
|
||||
message = "\n\n".join(self.__queue)
|
||||
if self.player_name:
|
||||
message = f"Player *{self.player_name}*\n" + message
|
||||
message = f"Player *{self.player_name}*\n\n" + message
|
||||
response = post(self.api_url, json=dict(chat_id=self.chat_id, text=message, parse_mode="Markdown"))
|
||||
self._last_time = utils.now()
|
||||
if response.json().get('ok'):
|
||||
@ -1024,3 +1051,27 @@ class OfferItem(NamedTuple):
|
||||
amount: int = 0
|
||||
offer_id: int = 0
|
||||
citizen_id: int = 0
|
||||
|
||||
|
||||
class Inventory:
|
||||
final: types.InvFinal
|
||||
active: types.InvFinal
|
||||
boosters: types.InvBooster
|
||||
raw: types.InvRaw
|
||||
market: types.InvRaw
|
||||
used: int
|
||||
total: int
|
||||
|
||||
def __init__(self):
|
||||
self.active = {}
|
||||
self.final = {}
|
||||
self.boosters = {}
|
||||
self.raw = {}
|
||||
self.offers = {}
|
||||
self.used = 0
|
||||
self.total = 0
|
||||
|
||||
@property
|
||||
def as_dict(self) -> Dict[str, Union[types.InvFinal, types.InvRaw, int]]:
|
||||
return dict(active=self.active, final=self.final, boosters=self.boosters, raw=self.raw, offers=self.offers,
|
||||
total=self.total, used=self.used)
|
||||
|
7
erepublik/types.py
Normal file
7
erepublik/types.py
Normal file
@ -0,0 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Dict, List, Union
|
||||
|
||||
InvFinalItem = Dict[str, Union[str, int, List[Dict[str, Union[int, datetime]]]]]
|
||||
InvBooster = Dict[str, Dict[int, Dict[int, InvFinalItem]]]
|
||||
InvFinal = Dict[str, Dict[int, InvFinalItem]]
|
||||
InvRaw = Dict[str, Dict[int, Dict[str, Union[str, int]]]]
|
@ -10,8 +10,9 @@ import unicodedata
|
||||
import warnings
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
from typing import Any, List, Optional, Union, Dict
|
||||
from typing import Any, Dict, List, Union
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
from . import __version__, constants
|
||||
@ -25,11 +26,8 @@ __all__ = ['VERSION', 'calculate_hit', 'caught_error', 'date_from_eday', 'eday_f
|
||||
'get_air_hit_dmg_value', 'get_file', 'get_ground_hit_dmg_value', 'get_sleep_seconds', 'good_timedelta',
|
||||
'interactive_sleep', 'json', 'localize_dt', 'localize_timestamp', 'normalize_html_json', 'now',
|
||||
'process_error', 'process_warning', 'send_email', 'silent_sleep', 'slugify', 'write_file', 'write_request',
|
||||
'write_interactive_log', 'write_silent_log', 'get_final_hit_dmg', 'wait_for_lock']
|
||||
|
||||
if not sys.version_info >= (3, 6):
|
||||
raise AssertionError('This script requires Python version 3.6 and higher\n'
|
||||
'But Your version is v{}.{}.{}'.format(*sys.version_info))
|
||||
'write_interactive_log', 'write_silent_log', 'get_final_hit_dmg', 'wait_for_lock',
|
||||
'json_decode_object_hook', 'json_load', 'json_loads']
|
||||
|
||||
VERSION: str = __version__
|
||||
|
||||
@ -64,7 +62,9 @@ def good_timedelta(dt: datetime.datetime, td: datetime.timedelta) -> datetime.da
|
||||
return constants.erep_tz.normalize(dt + td)
|
||||
|
||||
|
||||
def eday_from_date(date: Union[datetime.date, datetime.datetime] = now()) -> int:
|
||||
def eday_from_date(date: Union[datetime.date, datetime.datetime] = None) -> int:
|
||||
if date is None:
|
||||
date = now()
|
||||
if isinstance(date, datetime.date):
|
||||
date = datetime.datetime.combine(date, datetime.time(0, 0, 0))
|
||||
return (date - datetime.datetime(2007, 11, 20, 0, 0, 0)).days
|
||||
@ -158,6 +158,7 @@ def write_file(filename: str, content: str) -> int:
|
||||
|
||||
def write_request(response: requests.Response, is_error: bool = False):
|
||||
from erepublik import Citizen
|
||||
|
||||
# Remove GET args from url name
|
||||
url = response.url
|
||||
last_index = url.index("?") if "?" in url else len(response.url)
|
||||
@ -231,8 +232,8 @@ def send_email(name: str, content: List[Any], player=None, local_vars: Dict[str,
|
||||
if isinstance(local_vars.get('citizen'), Citizen):
|
||||
local_vars['citizen'] = repr(local_vars['citizen'])
|
||||
|
||||
from erepublik.classes import MyJSONEncoder
|
||||
files.append(('file', ("local_vars.json", json.dumps(local_vars, cls=MyJSONEncoder),
|
||||
from erepublik.classes import ErepublikJSONEncoder
|
||||
files.append(('file', ("local_vars.json", json.dumps(local_vars, cls=ErepublikJSONEncoder),
|
||||
"application/json")))
|
||||
if isinstance(player, Citizen):
|
||||
files.append(('file', ("instance.json", player.to_json(indent=True), "application/json")))
|
||||
@ -252,7 +253,7 @@ def caught_error(e: Exception):
|
||||
|
||||
|
||||
def process_error(log_info: str, name: str, exc_info: tuple, citizen=None, commit_id: str = None,
|
||||
interactive: Optional[bool] = None):
|
||||
interactive: bool = None):
|
||||
"""
|
||||
Process error logging and email sending to developer
|
||||
:param interactive: Should print interactively
|
||||
@ -376,11 +377,6 @@ def get_final_hit_dmg(base_dmg: Union[Decimal, float, str], rang: int,
|
||||
dmg = dmg * 11 / 10
|
||||
return Decimal(dmg)
|
||||
|
||||
# def _clear_up_battle_memory(battle):
|
||||
# del battle.invader._battle, battle.defender._battle
|
||||
# for div_id, division in battle.div.items():
|
||||
# del division._battle
|
||||
|
||||
|
||||
def deprecation(message):
|
||||
warnings.warn(message, DeprecationWarning, stacklevel=2)
|
||||
@ -396,7 +392,45 @@ def wait_for_lock(function):
|
||||
return None
|
||||
else:
|
||||
instance.concurrency_available.clear()
|
||||
ret = function(instance, *args, **kwargs)
|
||||
try:
|
||||
ret = function(instance, *args, **kwargs)
|
||||
except Exception as e:
|
||||
instance.concurrency_available.set()
|
||||
raise e
|
||||
instance.concurrency_available.set()
|
||||
return ret
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def json_decode_object_hook(
|
||||
o: Union[Dict[str, Any], List[Any], int, float, str]
|
||||
) -> Union[Dict[str, Any], List[Any], int, float, str, datetime.date, datetime.datetime, datetime.timedelta]:
|
||||
""" Convert classes.ErepublikJSONEncoder datetime, date and timedelta to their python objects
|
||||
|
||||
:param o:
|
||||
:return: Union[Dict[str, Any], List[Any], int, float, str, datetime.date, datetime.datetime, datetime.timedelta]
|
||||
"""
|
||||
if o.get('__type__'):
|
||||
_type = o.get('__type__')
|
||||
if _type == 'datetime':
|
||||
dt = datetime.datetime.strptime(f"{o['date']} {o['time']}", "%Y-%m-%d %H:%M:%S")
|
||||
if o.get('tzinfo'):
|
||||
dt = pytz.timezone(o['tzinfo']).localize(dt)
|
||||
return dt
|
||||
elif _type == 'date':
|
||||
dt = datetime.datetime.strptime(f"{o['date']}", "%Y-%m-%d")
|
||||
return dt.date()
|
||||
elif _type == 'timedelta':
|
||||
return datetime.timedelta(seconds=o['total_seconds'])
|
||||
return o
|
||||
|
||||
|
||||
def json_load(f, **kwargs):
|
||||
kwargs.update(object_hook=json_decode_object_hook)
|
||||
return json.load(f, **kwargs)
|
||||
|
||||
|
||||
def json_loads(s: str, **kwargs):
|
||||
kwargs.update(object_hook=json_decode_object_hook)
|
||||
return json.loads(s, **kwargs)
|
||||
|
@ -1,6 +1,6 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from erepublik import Citizen, utils, constants
|
||||
from erepublik import Citizen, constants, utils
|
||||
|
||||
CONFIG = {
|
||||
'email': 'player@email.com',
|
||||
|
@ -1,19 +1,19 @@
|
||||
bump2version==1.0.1
|
||||
coverage==5.3
|
||||
edx-sphinx-theme==1.5.0
|
||||
coverage==5.3.1
|
||||
edx-sphinx-theme==1.6.1
|
||||
flake8==3.8.4
|
||||
ipython>=7.19.0
|
||||
isort==5.6.4
|
||||
pip==20.3.1
|
||||
PyInstaller==4.1
|
||||
pytz==2020.4
|
||||
pytest==6.1.2
|
||||
responses==0.12.1
|
||||
setuptools==51.0.0
|
||||
Sphinx==3.3.1
|
||||
requests==2.25.0
|
||||
isort==5.7.0
|
||||
pip==20.3.3
|
||||
pre-commit==2.9.3
|
||||
pur==5.3.0
|
||||
PyInstaller==4.2
|
||||
PySocks==1.7.1
|
||||
tox==3.20.1
|
||||
twine==3.2.0
|
||||
watchdog==1.0.0
|
||||
wheel==0.36.1
|
||||
pytest==6.2.1
|
||||
pytz>=2020.5
|
||||
requests>=2.25.1
|
||||
responses==0.12.1
|
||||
setuptools==51.3.3
|
||||
Sphinx==3.4.3
|
||||
twine==3.3.0
|
||||
wheel==0.36.2
|
||||
|
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.23.3.2
|
||||
current_version = 0.23.4.13
|
||||
commit = True
|
||||
tag = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)?
|
||||
@ -18,13 +18,13 @@ replace = __version__ = '{new_version}'
|
||||
universal = 1
|
||||
|
||||
[flake8]
|
||||
exclude = docs,.tox,.git,log,debug,venv
|
||||
exclude = docs,.git,log,debug,venv
|
||||
max-line-length = 120
|
||||
ignore = D100,D101,D102,D103
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 120
|
||||
exclude = .tox,.git,log,debug,venv, build
|
||||
exclude = .git,log,debug,venv, build
|
||||
|
||||
[mypy]
|
||||
python_version = 3.7
|
||||
@ -37,4 +37,3 @@ warn_unused_configs = True
|
||||
[isort]
|
||||
multi_line_output = 2
|
||||
line_length = 120
|
||||
not_skip = __init__.py
|
||||
|
6
setup.py
6
setup.py
@ -12,8 +12,8 @@ with open('HISTORY.rst') as history_file:
|
||||
history = history_file.read()
|
||||
|
||||
requirements = [
|
||||
'pytz==2020.4',
|
||||
'requests==2.25.0',
|
||||
'pytz>=2020.0',
|
||||
'requests>=2.24.0,<2.26.0',
|
||||
'PySocks==1.7.1'
|
||||
]
|
||||
|
||||
@ -50,6 +50,6 @@ setup(
|
||||
test_suite='tests',
|
||||
tests_require=test_requirements,
|
||||
url='https://github.com/eeriks/erepublik/',
|
||||
version='0.23.3.2',
|
||||
version='0.23.4.13',
|
||||
zip_safe=False,
|
||||
)
|
||||
|
Reference in New Issue
Block a user