Compare commits

...

21 Commits

Author SHA1 Message Date
8243664c24 Bump version: 0.27.2 → 0.28.0 2021-11-16 22:47:32 +02:00
c8834e0f9e Fixed medal amounts, removed military related stuff 2021-11-16 22:47:02 +02:00
954e9d576b Bump version: 0.27.1 → 0.27.2 2021-11-02 18:44:50 +02:00
47ec6c03df Updated requirements 2021-11-02 18:44:40 +02:00
44360bd143 erep.lv url update 2021-11-02 18:32:13 +02:00
3e0caae041 Doc update 2021-10-23 16:55:26 +03:00
5ce4c62f22 Bump version: 0.27.0 → 0.27.1 2021-10-23 16:32:22 +03:00
b80fa43e99 Updates 2021-10-23 16:30:04 +03:00
62f53c0396 Short Maintenance message 2021-10-23 16:19:00 +03:00
051d4765a4 Correct sleeping if no energy 2021-10-23 16:19:00 +03:00
365ad9a719 Send state update and let the bg task live even if Captcha is required 2021-10-23 16:19:00 +03:00
81f00bdbf6 Create codeql-analysis.yml 2021-10-23 16:16:40 +03:00
44d221ac1b Merge branch 'master' of github.com:eeriks/erepublik 2021-10-23 16:16:17 +03:00
7054ae2b05 Bump version: 0.26.0.2 → 0.27.0 2021-08-30 16:36:35 +03:00
2288fe01ea Fixed promo reporting 2021-08-30 16:36:25 +03:00
dfa6f7e0be Changed linting make command 2021-08-30 16:36:05 +03:00
1746f27193 Bump version: 0.26.0.1 → 0.26.0.2 2021-08-28 10:41:47 +03:00
c8f9ac9768 PromoFixup 2021-08-28 10:41:44 +03:00
7773b63520 fix
fix
2021-08-27 19:35:15 +03:00
e4814cfa8e updates 2021-08-18 10:40:19 +03:00
ba336fe8ed Zero medal reward update 2021-08-18 09:28:00 +03:00
23 changed files with 1427 additions and 1080 deletions

5
.flake8 Normal file
View File

@ -0,0 +1,5 @@
[flake8]
ignore = E203,E722
exclude = .git,__pycache__,venv,docs,debug,log
max-line-length = 120
#max-complexity = 10

71
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '16 0 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: [3.7, 3.8] python-version: [3.8, 3.9]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2

View File

@ -58,10 +58,10 @@ Ready to contribute? Here's how to set up `erepublik` for local development.
$ git clone git@github.com:your_name_here/erepublik.git $ git clone git@github.com:your_name_here/erepublik.git
3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: 3. This is how you set up your fork for local development::
$ mkvirtualenv erepublik
$ cd erepublik/ $ cd erepublik/
$ python3 -m venv venv
$ python setup.py develop $ python setup.py develop
4. Create a branch for local development:: 4. Create a branch for local development::
@ -73,8 +73,7 @@ Ready to contribute? Here's how to set up `erepublik` for local development.
5. When you're done making changes, check that your changes pass flake8, isort and the 5. When you're done making changes, check that your changes pass flake8, isort and the
tests:: tests::
$ flake8 erepublik tests $ make lint
$ isort erepublik
$ python setup.py test $ python setup.py test
To get flake8 and isort, just pip install them into your virtualenv. To get flake8 and isort, just pip install them into your virtualenv.
@ -115,8 +114,6 @@ A reminder for the maintainers on how to deploy.
Make sure all your changes are committed (including an entry in HISTORY.rst). Make sure all your changes are committed (including an entry in HISTORY.rst).
Then run:: Then run::
$ bumpversion patch # possible: major / minor / patch $ bumpversion patch # possible: major / minor / patch / dev
$ git push $ git push
$ git push --tags $ git push --tags
Travis will then deploy to PyPI if tests pass.

View File

@ -52,8 +52,9 @@ clean-test: ## remove test and coverage artifacts
rm -fr .pytest_cache rm -fr .pytest_cache
lint: ## check style with flake8 lint: ## check style with flake8
black erepublik tests isort erepublik examples tests
flake8 erepublik tests black erepublik examples tests
flake8 erepublik examples tests
test: ## run tests quickly with the default Python test: ## run tests quickly with the default Python
python -m unittest python -m unittest

View File

@ -23,9 +23,12 @@ import sys
sys.path.insert(0, os.path.abspath("..")) sys.path.insert(0, os.path.abspath(".."))
import erepublik import datetime
import edx_theme import edx_theme
import erepublik
# -- General configuration --------------------------------------------- # -- General configuration ---------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here. # If your documentation needs a minimal Sphinx version, state it here.
@ -50,7 +53,7 @@ master_doc = "index"
# General information about the project. # General information about the project.
project = "eRepublik script" project = "eRepublik script"
copyright = "2019, Eriks Karls" copyright = "2017-%i, Eriks Karls" % datetime.date.today().year
author = "Eriks Karls" author = "Eriks Karls"
# The version info for the project you're documenting, acts as replacement # The version info for the project you're documenting, acts as replacement
@ -145,5 +148,13 @@ man_pages = [(master_doc, "erepublik", "eRepublik script Documentation", [author
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(master_doc, "erepublik", "eRepublik script Documentation", author, "erepublik", "One line description of project.", "Miscellaneous"), (
master_doc,
"erepublik",
"eRepublik script Documentation",
author,
"erepublik",
"One line description of project.",
"Miscellaneous",
),
] ]

View File

@ -44,14 +44,6 @@ erepublik.utils module
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:
erepublik.ws module
-------------------
.. automodule:: erepublik.ws
:members:
:undoc-members:
:show-inheritance:
Module contents Module contents
--------------- ---------------

View File

@ -8,12 +8,10 @@
<meta name="generator" content="Jekyll v4.0.1"> <meta name="generator" content="Jekyll v4.0.1">
<title>eBot configuration</title> <title>eBot configuration</title>
<!-- CSS only --> <!-- CSS only -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<!-- JS, Popper.js, and jQuery --> <!-- 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://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.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" 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> </head>
<body> <body>
<div class="container"> <div class="container">
@ -120,57 +118,57 @@
</div> </div>
<div class="col-12 col-sm-6"> <div class="col-12 col-sm-6">
<h3>Fighting</h3> <h3><span style="text-decoration: line-through;">Fighting</span></h3>
<div class="form-group"> <div class="form-group">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="fight" checked> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="fight" disabled>
<label class="custom-control-label" for="fight">Fight</label> <label class="custom-control-label" for="fight">Fight</label>
</div> </div>
<div class="custom-control custom-switch custom-control-inline"> <div class="custom-control custom-switch custom-control-inline">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="air" checked> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="air" disabled>
<label class="custom-control-label" for="air">Air</label> <label class="custom-control-label" for="air">Air</label>
</div> </div>
<div class="custom-control custom-switch custom-control-inline"> <div class="custom-control custom-switch custom-control-inline">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="ground"> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="ground" disabled>
<label class="custom-control-label" for="ground">Ground</label> <label class="custom-control-label" for="ground">Ground</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="boosters"> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="boosters" disabled>
<label class="custom-control-label" for="boosters">Use ground boosters</label> <label class="custom-control-label" for="boosters">Use ground boosters</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="continuous_fighting"> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="continuous_fighting" disabled>
<label class="custom-control-label" for="continuous_fighting">Continue fighting all FF in round</label> <label class="custom-control-label" for="continuous_fighting">Continue fighting all FF in round</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="next_energy" checked> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="next_energy" disabled>
<label class="custom-control-label" for="next_energy">Fight for next WC +1hp/6min if reachable by FF</label> <label class="custom-control-label" for="next_energy">Fight for next WC +1hp/6min if reachable by FF</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input type="radio" class="form-check-input" onchange="updateJson()" id="all_in" name="fight_amount" value="all_in"> <input type="radio" class="form-check-input" onchange="updateJson()" id="all_in" name="fight_amount" value="all_in" disabled>
<label class="form-check-label" for="all_in">All energy</label> <label class="form-check-label" for="all_in">All energy</label>
</div> </div>
<div class="form-check form-check-inline"> <div class="form-check form-check-inline">
<input type="radio" class="form-check-input" onchange="updateJson()" id="h_energy" name="fight_amount" value="h_energy" checked> <input type="radio" class="form-check-input" onchange="updateJson()" id="h_energy" name="fight_amount" value="h_energy" disabled>
<label class="form-check-label" for="h_energy">1h energy</label> <label class="form-check-label" for="h_energy">1h energy</label>
</div> </div>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="rw_def_side" checked> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="rw_def_side" disabled>
<label class="custom-control-label" for="rw_def_side">In RWs fight on right side (occupier/defender)</label> <label class="custom-control-label" for="rw_def_side">In RWs fight on right side (occupier/defender)</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="travel_to_fight" checked> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="travel_to_fight" disabled>
<label class="custom-control-label" for="travel_to_fight">Travel to fight</label> <label class="custom-control-label" for="travel_to_fight">Travel to fight</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="epic_hunt"> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="epic_hunt" disabled>
<label class="custom-control-label" for="epic_hunt">Hunt epics</label> <label class="custom-control-label" for="epic_hunt">Hunt epics</label>
</div> </div>
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" onchange="updateJson()" id="epic_hunt_ebs"> <input type="checkbox" class="custom-control-input" onchange="updateJson()" id="epic_hunt_ebs" disabled>
<label class="custom-control-label" for="epic_hunt_ebs">Spend <small>[all]</small> EBs in epics</label> <label class="custom-control-label" for="epic_hunt_ebs">Spend <small>[all]</small> EBs in epics</label>
</div> </div>
</div> </div>
@ -262,7 +260,13 @@
</form> </form>
</div> </div>
<div class="col-12"> <div class="col-12">
<pre id="json-output"></pre> <div class="card">
<div class="card-body">
<h5 class="card-title">config.json</h5>
<h6 class="card-subtitle mb-2 text-muted">Copy-paste the content below into 'config.json' file</h6>
<pre id="json-output" class="bg-light card-text"></pre>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,7 +4,7 @@
__author__ = """Eriks Karls""" __author__ = """Eriks Karls"""
__email__ = "eriks@72.lv" __email__ = "eriks@72.lv"
__version__ = "0.26.0.1" __version__ = "0.28.0"
from erepublik.citizen import Citizen from erepublik.citizen import Citizen

View File

@ -133,7 +133,9 @@ class ErepublikErrorHTTTPHandler(handlers.HTTPHandler):
except: # noqa except: # noqa
resp_time = slugify(response.headers.get("date")) resp_time = slugify(response.headers.get("date"))
return dict( return dict(
name=f"{resp_time}_{name}.{ext}", content=html.encode("utf-8"), mimetype="application/json" if ext == "json" else "text/html" name=f"{resp_time}_{name}.{ext}",
content=html.encode("utf-8"),
mimetype="application/json" if ext == "json" else "text/html",
) )
def _get_local_vars(self) -> str: def _get_local_vars(self) -> str:

View File

@ -115,7 +115,9 @@ class SlowRequests(Session):
firefox_template = "Mozilla/5.0 ({osystem}; rv:{version}.0) Gecko/20100101 Firefox/{version}.0" firefox_template = "Mozilla/5.0 ({osystem}; rv:{version}.0) Gecko/20100101 Firefox/{version}.0"
firefox_versions = range(85, 92) firefox_versions = range(85, 92)
chrome_template = "Mozilla/5.0 ({osystem}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{version} Safari/537.36" chrome_template = (
"Mozilla/5.0 ({osystem}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{version} Safari/537.36"
)
chrome_versions = [ chrome_versions = [
"85.0.4183.121", "85.0.4183.121",
"86.0.4240.183", "86.0.4240.183",
@ -187,15 +189,19 @@ class CitizenBaseAPI:
) -> Response: ) -> Response:
c = [cookie.name for cookie in self._req.cookies if not cookie.has_nonstandard_attr("HttpOnly")] c = [cookie.name for cookie in self._req.cookies if not cookie.has_nonstandard_attr("HttpOnly")]
env = dict(l=["tets"], s=[], c=c, m=0) env = dict(l=["tets"], s=[], c=c, m=0)
cookies = dict(
sh=hashlib.sha256(",".join(env["l"] + env["s"]).encode("utf8")).hexdigest(), session_hash = hashlib.sha256(",".join(env["l"] + env["s"]).encode("utf8")).hexdigest()
ch=hashlib.sha256(",".join(env["c"]).encode("utf8")).hexdigest(), cookies_hash = hashlib.sha256(",".join(env["c"]).encode("utf8")).hexdigest()
)
cookie_kwargs = dict( cookie_kwargs = dict(
expires=int(time.time()) + 120, path="/en/main/sessionUnlock", domain=".www.erepublik.com", secure=True, rest={"HttpOnly": True} expires=int(time.time()) + 120,
path="/en/main/sessionUnlock",
domain=".www.erepublik.com",
secure=True,
rest={"HttpOnly": True},
) )
self._req.cookies.set("sh", cookies["sh"], **cookie_kwargs) self._req.cookies.set("sh", session_hash, **cookie_kwargs)
self._req.cookies.set("ch", cookies["ch"], **cookie_kwargs) self._req.cookies.set("ch", cookies_hash, **cookie_kwargs)
b64_env = utils.b64json(env) b64_env = utils.b64json(env)
data = dict( data = dict(
_token=self.token, _token=self.token,
@ -271,7 +277,13 @@ class ErepublikArticleAPI(CitizenBaseAPI):
return self.post(f"{self.url}/main/donate-article", data=data) return self.post(f"{self.url}/main/donate-article", data=data)
def _post_main_write_article(self, title: str, content: str, country_id: int, kind_id: int) -> Response: def _post_main_write_article(self, title: str, content: str, country_id: int, kind_id: int) -> Response:
data = dict(_token=self.token, article_name=title, article_body=content, article_location=country_id, article_category=kind_id) data = dict(
_token=self.token,
article_name=title,
article_body=content,
article_location=country_id,
article_category=kind_id,
)
return self.post(f"{self.url}/main/write-article", data=data) return self.post(f"{self.url}/main/write-article", data=data)
def _post_main_vote_article(self, article_id: int) -> Response: def _post_main_vote_article(self, article_id: int) -> Response:
@ -286,7 +298,9 @@ class ErepublikCompanyAPI(CitizenBaseAPI):
def _post_economy_create_company(self, industry_id: int, building_type: int = 1) -> Response: def _post_economy_create_company(self, industry_id: int, building_type: int = 1) -> Response:
data = {"_token": self.token, "company[industry_id]": industry_id, "company[building_type]": building_type} data = {"_token": self.token, "company[industry_id]": industry_id, "company[building_type]": building_type}
return self.post(f"{self.url}/economy/create-company", data=data, headers={"Referer": f"{self.url}/economy/create-company"}) return self.post(
f"{self.url}/economy/create-company", data=data, headers={"Referer": f"{self.url}/economy/create-company"}
)
def _get_economy_inventory_items(self) -> Response: def _get_economy_inventory_items(self) -> Response:
return self.get(f"{self.url}/economy/inventory-items/") return self.get(f"{self.url}/economy/inventory-items/")
@ -366,9 +380,13 @@ class ErepublikCountryAPI(CitizenBaseAPI):
def _get_country_military(self, country_name: str) -> Response: def _get_country_military(self, country_name: str) -> Response:
return self.get(f"{self.url}/country/military/{country_name}") return self.get(f"{self.url}/country/military/{country_name}")
def _post_main_country_donate(self, country_id: int, action: str, value: Union[int, float], quality: int = None) -> Response: def _post_main_country_donate(
self, country_id: int, action: str, value: Union[int, float], quality: int = None
) -> Response:
data = dict(countryId=country_id, action=action, _token=self.token, value=value, quality=quality) data = dict(countryId=country_id, action=action, _token=self.token, value=value, quality=quality)
return self.post(f"{self.url}/main/country-donate", data=data, headers={"Referer": f"{self.url}/country/economy/Latvia"}) return self.post(
f"{self.url}/main/country-donate", data=data, headers={"Referer": f"{self.url}/country/economy/Latvia"}
)
class ErepublikEconomyAPI(CitizenBaseAPI): class ErepublikEconomyAPI(CitizenBaseAPI):
@ -396,13 +414,17 @@ class ErepublikEconomyAPI(CitizenBaseAPI):
def _post_economy_donate_items_action(self, citizen_id: int, amount: int, industry: int, quality: int) -> Response: def _post_economy_donate_items_action(self, citizen_id: int, amount: int, industry: int, quality: int) -> Response:
data = dict(citizen_id=citizen_id, amount=amount, industry_id=industry, quality=quality, _token=self.token) data = dict(citizen_id=citizen_id, amount=amount, industry_id=industry, quality=quality, _token=self.token)
return self.post( return self.post(
f"{self.url}/economy/donate-items-action", data=data, headers={"Referer": f"{self.url}/economy/donate-items/{citizen_id}"} f"{self.url}/economy/donate-items-action",
data=data,
headers={"Referer": f"{self.url}/economy/donate-items/{citizen_id}"},
) )
def _post_economy_donate_money_action(self, citizen_id: int, amount: float = 0.0, currency: int = 62) -> Response: def _post_economy_donate_money_action(self, citizen_id: int, amount: float = 0.0, currency: int = 62) -> Response:
data = dict(citizen_id=citizen_id, _token=self.token, currency_id=currency, amount=amount) data = dict(citizen_id=citizen_id, _token=self.token, currency_id=currency, amount=amount)
return self.post( return self.post(
f"{self.url}/economy/donate-money-action", data=data, headers={"Referer": f"{self.url}/economy/donate-money/{citizen_id}"} f"{self.url}/economy/donate-money-action",
data=data,
headers={"Referer": f"{self.url}/economy/donate-money/{citizen_id}"},
) )
def _post_economy_exchange_purchase(self, amount: float, currency: int, offer: int) -> Response: def _post_economy_exchange_purchase(self, amount: float, currency: int, offer: int) -> Response:
@ -434,7 +456,12 @@ class ErepublikEconomyAPI(CitizenBaseAPI):
def _post_economy_marketplace_actions(self, action: str, **kwargs) -> Response: def _post_economy_marketplace_actions(self, action: str, **kwargs) -> Response:
if action == "buy": if action == "buy":
data = dict( data = dict(
_token=self.token, offerId=kwargs["offer"], amount=kwargs["amount"], orderBy="price_asc", currentPage=1, buyAction=1 _token=self.token,
offerId=kwargs["offer"],
amount=kwargs["amount"],
orderBy="price_asc",
currentPage=1,
buyAction=1,
) )
elif action == "sell": elif action == "sell":
data = dict( data = dict(
@ -454,16 +481,24 @@ class ErepublikEconomyAPI(CitizenBaseAPI):
class ErepublikLeaderBoardAPI(CitizenBaseAPI): class ErepublikLeaderBoardAPI(CitizenBaseAPI):
def _get_main_leaderboards_damage_aircraft_rankings(self, country_id: int, weeks: int = 0, mu_id: int = 0) -> Response: # noqa def _get_main_leaderboards_damage_aircraft_rankings(
self, country_id: int, weeks: int = 0, mu_id: int = 0
) -> Response: # noqa
return self.get(f"{self.url}/main/leaderboards-damage-aircraft-rankings/{country_id}/{weeks}/{mu_id}/0") return self.get(f"{self.url}/main/leaderboards-damage-aircraft-rankings/{country_id}/{weeks}/{mu_id}/0")
def _get_main_leaderboards_damage_rankings(self, country_id: int, weeks: int = 0, mu_id: int = 0, div: int = 0) -> Response: # noqa def _get_main_leaderboards_damage_rankings(
self, country_id: int, weeks: int = 0, mu_id: int = 0, div: int = 0
) -> Response: # noqa
return self.get(f"{self.url}/main/leaderboards-damage-rankings/{country_id}/{weeks}/{mu_id}/{div}") return self.get(f"{self.url}/main/leaderboards-damage-rankings/{country_id}/{weeks}/{mu_id}/{div}")
def _get_main_leaderboards_kills_aircraft_rankings(self, country_id: int, weeks: int = 0, mu_id: int = 0) -> Response: # noqa def _get_main_leaderboards_kills_aircraft_rankings(
self, country_id: int, weeks: int = 0, mu_id: int = 0
) -> Response: # noqa
return self.get(f"{self.url}/main/leaderboards-kills-aircraft-rankings/{country_id}/{weeks}/{mu_id}/0") return self.get(f"{self.url}/main/leaderboards-kills-aircraft-rankings/{country_id}/{weeks}/{mu_id}/0")
def _get_main_leaderboards_kills_rankings(self, country_id: int, weeks: int = 0, mu_id: int = 0, div: int = 0) -> Response: # noqa def _get_main_leaderboards_kills_rankings(
self, country_id: int, weeks: int = 0, mu_id: int = 0, div: int = 0
) -> Response: # noqa
return self.get(f"{self.url}/main/leaderboards-kills-rankings/{country_id}/{weeks}/{mu_id}/{div}") return self.get(f"{self.url}/main/leaderboards-kills-rankings/{country_id}/{weeks}/{mu_id}/{div}")
@ -543,7 +578,14 @@ class ErepublikMilitaryAPI(CitizenBaseAPI):
return self.post(f"{self.url}/military/battle-console", data=data) return self.post(f"{self.url}/military/battle-console", data=data)
def _post_military_deploy_bomb(self, battle_id: int, division_id: int, side_id: int, bomb_id: int) -> Response: def _post_military_deploy_bomb(self, battle_id: int, division_id: int, side_id: int, bomb_id: int) -> Response:
data = dict(battleId=battle_id, battleZoneId=division_id, sideId=side_id, sideCountryId=side_id, bombId=bomb_id, _token=self.token) data = dict(
battleId=battle_id,
battleZoneId=division_id,
sideId=side_id,
sideCountryId=side_id,
bombId=bomb_id,
_token=self.token,
)
return self.post(f"{self.url}/military/deploy-bomb", data=data) return self.post(f"{self.url}/military/deploy-bomb", data=data)
def _post_military_fight_air(self, battle_id: int, side_id: int, zone_id: int) -> Response: def _post_military_fight_air(self, battle_id: int, side_id: int, zone_id: int) -> Response:
@ -599,7 +641,9 @@ class ErepublikPoliticsAPI(CitizenBaseAPI):
return self.get(f"{self.url}/main/presidential-elections/{country_id}/{timestamp}") return self.get(f"{self.url}/main/presidential-elections/{country_id}/{timestamp}")
def _post_propose_president_candidate(self, party_slug: str, citizen_id: int) -> Response: def _post_propose_president_candidate(self, party_slug: str, citizen_id: int) -> Response:
return self.post(f"{self.url}/propose-president-candidate/{party_slug}", data=dict(_token=self.token, citizen=citizen_id)) return self.post(
f"{self.url}/propose-president-candidate/{party_slug}", data=dict(_token=self.token, citizen=citizen_id)
)
def _get_auto_propose_president_candidate(self, party_slug: str) -> Response: def _get_auto_propose_president_candidate(self, party_slug: str) -> Response:
return self.get(f"{self.url}/auto-propose-president-candidate/{party_slug}") return self.get(f"{self.url}/auto-propose-president-candidate/{party_slug}")
@ -611,11 +655,24 @@ class ErepublikPresidentAPI(CitizenBaseAPI):
return self.post(f"{self.url}/wars/attack-region/{war_id}/{region_id}", data=data) return self.post(f"{self.url}/wars/attack-region/{war_id}/{region_id}", data=data)
def _post_new_war(self, self_country_id: int, attack_country_id: int, debate: str = "") -> Response: def _post_new_war(self, self_country_id: int, attack_country_id: int, debate: str = "") -> Response:
data = dict(requirments=1, _token=self.token, debate=debate, countryNameConfirm=constants.COUNTRIES[attack_country_id].link) data = dict(
requirments=1,
_token=self.token,
debate=debate,
countryNameConfirm=constants.COUNTRIES[attack_country_id].link,
)
return self.post(f"{self.url}/{constants.COUNTRIES[self_country_id].link}/new-war", data=data) return self.post(f"{self.url}/{constants.COUNTRIES[self_country_id].link}/new-war", data=data)
def _post_new_donation(self, country_id: int, amount: int, org_name: str, debate: str = "") -> Response: def _post_new_donation(self, country_id: int, amount: int, org_name: str, debate: str = "") -> Response:
data = dict(requirments=1, _token=self.token, debate=debate, currency=1, value=amount, commit="Propose", type_name=org_name) data = dict(
requirments=1,
_token=self.token,
debate=debate,
currency=1,
value=amount,
commit="Propose",
type_name=org_name,
)
return self.post(f"{self.url}/{constants.COUNTRIES[country_id].link}/new-donation", data=data) return self.post(f"{self.url}/{constants.COUNTRIES[country_id].link}/new-donation", data=data)
@ -705,7 +762,12 @@ class ErepublikProfileAPI(CitizenBaseAPI):
def _post_main_messages_compose(self, subject: str, body: str, citizens: List[int]) -> Response: def _post_main_messages_compose(self, subject: str, body: str, citizens: List[int]) -> Response:
url_pk = 0 if len(citizens) > 1 else str(citizens[0]) url_pk = 0 if len(citizens) > 1 else str(citizens[0])
data = dict(citizen_name=",".join([str(x) for x in citizens]), citizen_subject=subject, _token=self.token, citizen_message=body) data = dict(
citizen_name=",".join([str(x) for x in citizens]),
citizen_subject=subject,
_token=self.token,
citizen_message=body,
)
return self.post(f"{self.url}/main/messages-compose/{url_pk}", data=data) return self.post(f"{self.url}/main/messages-compose/{url_pk}", data=data)
def _post_military_group_missions(self) -> Response: def _post_military_group_missions(self) -> Response:
@ -810,7 +872,8 @@ class ErepublikWallPostAPI(CitizenBaseAPI):
# ## Medal posting # ## Medal posting
def _post_main_wall_post_automatic(self, message: str, achievement_id: int) -> Response: def _post_main_wall_post_automatic(self, message: str, achievement_id: int) -> Response:
return self.post( return self.post(
f"{self.url}/main/wall-post/automatic", data=dict(_token=self.token, message=message, achievementId=achievement_id) f"{self.url}/main/wall-post/automatic",
data=dict(_token=self.token, message=message, achievementId=achievement_id),
) )

File diff suppressed because it is too large Load Diff

View File

@ -129,7 +129,13 @@ class Holding:
@property @property
def as_dict(self) -> Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]: def as_dict(self) -> Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]:
return dict(name=self.name, id=self.id, region=self.region, companies=[c.as_dict for c in self.companies], wam_count=self.wam_count) return dict(
name=self.name,
id=self.id,
region=self.region,
companies=[c.as_dict for c in self.companies],
wam_count=self.wam_count,
)
@property @property
def citizen(self): def citizen(self):
@ -303,7 +309,13 @@ class MyCompanies:
""" """
for holding in holdings.values(): for holding in holdings.values():
if holding.get("id") not in self.holdings: if holding.get("id") not in self.holdings:
self.holdings.update({int(holding.get("id")): Holding(holding["id"], holding["region_id"], self.citizen, holding["name"])}) self.holdings.update(
{
int(holding.get("id")): Holding(
holding["id"], holding["region_id"], self.citizen, holding["name"]
)
}
)
if not self.holdings.get(0): if not self.holdings.get(0):
self.holdings.update({0: Holding(0, 0, self.citizen, "Unassigned")}) # unassigned self.holdings.update({0: Holding(0, 0, self.citizen, "Unassigned")}) # unassigned
@ -373,7 +385,12 @@ class MyCompanies:
self, self,
) -> Dict[ ) -> Dict[
str, str,
Union[str, int, datetime.datetime, Dict[str, Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]]], Union[
str,
int,
datetime.datetime,
Dict[str, Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]],
],
]: ]:
return dict( return dict(
name=str(self), name=str(self),
@ -530,12 +547,16 @@ class Energy:
@property @property
def is_recoverable_full(self): def is_recoverable_full(self):
warnings.warn("Deprecated since auto auto-eat! Will be removed soon. Use Energy.is_energy_full", DeprecationWarning) warnings.warn(
"Deprecated since auto auto-eat! Will be removed soon. Use Energy.is_energy_full", DeprecationWarning
)
return self.is_energy_full return self.is_energy_full
@property @property
def is_recovered_full(self): def is_recovered_full(self):
warnings.warn("Deprecated since auto auto-eat! Will be removed soon. Use Energy.is_energy_full", DeprecationWarning) warnings.warn(
"Deprecated since auto auto-eat! Will be removed soon. Use Energy.is_energy_full", DeprecationWarning
)
return self.is_energy_full return self.is_energy_full
@property @property
@ -691,13 +712,18 @@ class Reporter:
@property @property
def as_dict(self) -> Dict[str, Union[bool, int, str, List[Dict[Any, Any]]]]: def as_dict(self) -> Dict[str, Union[bool, int, str, List[Dict[Any, Any]]]]:
return dict( return dict(
name=self.name, email=self.email, citizen_id=self.citizen_id, key=self.key, allowed=self.allowed, queue=self.__to_update name=self.name,
email=self.email,
citizen_id=self.citizen_id,
key=self.key,
allowed=self.allowed,
queue=self.__to_update,
) )
def __init__(self, citizen): def __init__(self, citizen):
self._citizen = weakref.ref(citizen) self._citizen = weakref.ref(citizen)
self._req = Session() self._req = Session()
self.url = "https://api.erep.lv" self.url = "https://erep.lv"
self._req.headers.update( self._req.headers.update(
{ {
"user-agent": "eRepublik Script Reporter v3", "user-agent": "eRepublik Script Reporter v3",
@ -751,7 +777,10 @@ class Reporter:
r = self.__bot_update(dict(key=self.key, check=True, player_id=self.citizen_id)) r = self.__bot_update(dict(key=self.key, check=True, player_id=self.citizen_id))
if r: if r:
if not r.json().get("status"): if not r.json().get("status"):
self._req.post(f"{self.url}/bot/register", json=dict(name=self.name, email=self.email, player_id=self.citizen_id)) self._req.post(
f"{self.url}/bot/register",
json=dict(name=self.name, email=self.email, player_id=self.citizen_id),
)
self.__registered = True self.__registered = True
self.allowed = True self.allowed = True
self.report_action("STARTED", value=utils.now().strftime("%F %T")) self.report_action("STARTED", value=utils.now().strftime("%F %T"))
@ -790,7 +819,9 @@ class Reporter:
self._bot_update(data) self._bot_update(data)
def report_action(self, action: str, json_val: Dict[Any, Any] = None, value: str = None): def report_action(self, action: str, json_val: Dict[Any, Any] = None, value: str = None):
json_data = dict(player_id=getattr(self, "citizen_id", None), log={"action": action}, key=getattr(self, "key", None)) json_data = dict(
player_id=getattr(self, "citizen_id", None), log={"action": action}, key=getattr(self, "key", None)
)
if json_val: if json_val:
json_data["log"].update(dict(json=json_val)) json_data["log"].update(dict(json=json_val))
if value: if value:
@ -836,14 +867,18 @@ class Reporter:
try: try:
battle_response = self._req.get(f"{self.url}/api/v1/battles/{country.id}") battle_response = self._req.get(f"{self.url}/api/v1/battles/{country.id}")
return [ return [
self.citizen.all_battles[bid] for bid in battle_response.json().get("battle_ids", []) if bid in self.citizen.all_battles self.citizen.all_battles[bid]
for bid in battle_response.json().get("battle_ids", [])
if bid in self.citizen.all_battles
] ]
except: # noqa except: # noqa
return [] return []
def fetch_tasks(self) -> List[Dict[str, Any]]: def fetch_tasks(self) -> List[Dict[str, Any]]:
try: try:
task_response = self._req.post(f"{self.url}/api/v1/command", data=dict(citizen=self.citizen_id, key=self.key)).json() 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"): if task_response.get("status"):
return task_response.get("data") return task_response.get("data")
else: else:
@ -894,7 +929,13 @@ class BattleSide:
@property @property
def as_dict(self) -> Dict[str, Union[int, constants.Country, bool, List[constants.Country]]]: 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) return dict(
points=self.points,
country=self.country,
is_defender=self.is_defender,
allies=self.allies,
deployed=self.deployed,
)
@property @property
def battle(self): def battle(self):
@ -917,7 +958,12 @@ class BattleDivision:
@property @property
def as_dict(self): def as_dict(self):
return dict( return dict(
id=self.id, division=self.div, terrain=(self.terrain, self.terrain_display), wall=self.wall, epic=self.epic, end=self.div_end id=self.id,
division=self.div,
terrain=(self.terrain, self.terrain_display),
wall=self.wall,
epic=self.epic,
end=self.div_end,
) )
@property @property
@ -1210,7 +1256,8 @@ class TelegramReporter:
def report_item_donation(self, citizen_id: int, amount: float, product: str): def report_item_donation(self, citizen_id: int, amount: float, product: str):
self.send_message( self.send_message(
f"*Donation*: {amount} x {product} to citizen " f"[{citizen_id}](https://www.erepublik.com/en/citizen/profile/{citizen_id})" 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): def report_money_donation(self, citizen_id: int, amount: float, is_currency: bool = True):
@ -1228,7 +1275,9 @@ class TelegramReporter:
message = "\n\n".join(self.__queue) message = "\n\n".join(self.__queue)
if self.player_name: if self.player_name:
message = f"Player *{self.player_name}*\n\n" + message message = f"Player *{self.player_name}*\n\n" + message
response = post(f"{self.api_url}/sendMessage", json=dict(chat_id=self.chat_id, text=message, parse_mode="Markdown")) response = post(
f"{self.api_url}/sendMessage", json=dict(chat_id=self.chat_id, text=message, parse_mode="Markdown")
)
self._last_time = utils.now() self._last_time = utils.now()
if response.json().get("ok"): if response.json().get("ok"):
self.__queue.clear() self.__queue.clear()
@ -1275,5 +1324,11 @@ class Inventory:
@property @property
def as_dict(self) -> Dict[str, Union[types.InvFinal, types.InvRaw, int]]: def as_dict(self) -> Dict[str, Union[types.InvFinal, types.InvRaw, int]]:
return dict( return dict(
active=self.active, final=self.final, boosters=self.boosters, raw=self.raw, offers=self.offers, total=self.total, used=self.used active=self.active,
final=self.final,
boosters=self.boosters,
raw=self.raw,
offers=self.offers,
total=self.total,
used=self.used,
) )

View File

@ -182,7 +182,14 @@ def slugify(value, allow_unicode=False) -> str:
def calculate_hit( def calculate_hit(
strength: float, rang: int, tp: bool, elite: bool, ne: bool, booster: int = 0, weapon: int = 200, is_deploy: bool = False strength: float,
rang: int,
tp: bool,
elite: bool,
ne: bool,
booster: int = 0,
weapon: int = 200,
is_deploy: bool = False,
) -> Decimal: ) -> Decimal:
dec = 3 if is_deploy else 0 dec = 3 if is_deploy else 0
base_str = 1 + Decimal(str(round(strength, 3))) / 400 base_str = 1 + Decimal(str(round(strength, 3))) / 400
@ -217,7 +224,12 @@ def get_air_hit_dmg_value(
def get_final_hit_dmg( def get_final_hit_dmg(
base_dmg: Union[Decimal, float, str], rang: int, tp: bool = False, elite: bool = False, ne: bool = False, booster: int = 0 base_dmg: Union[Decimal, float, str],
rang: int,
tp: bool = False,
elite: bool = False,
ne: bool = False,
booster: int = 0,
) -> Decimal: ) -> Decimal:
dmg = Decimal(str(base_dmg)) dmg = Decimal(str(base_dmg))
@ -313,7 +325,11 @@ class ErepublikJSONEncoder(json.JSONEncoder):
return dict(__type__="date", date=o.strftime("%Y-%m-%d")) return dict(__type__="date", date=o.strftime("%Y-%m-%d"))
elif isinstance(o, datetime.timedelta): elif isinstance(o, datetime.timedelta):
return dict( return dict(
__type__="timedelta", days=o.days, seconds=o.seconds, microseconds=o.microseconds, total_seconds=o.total_seconds() __type__="timedelta",
days=o.days,
seconds=o.seconds,
microseconds=o.microseconds,
total_seconds=o.total_seconds(),
) )
elif isinstance(o, Response): elif isinstance(o, Response):
return dict(headers=dict(o.__dict__["headers"]), url=o.url, text=o.text, status_code=o.status_code) return dict(headers=dict(o.__dict__["headers"]), url=o.url, text=o.text, status_code=o.status_code)

View File

@ -60,7 +60,9 @@ def main():
player.write_log("Doing task: Work as manager") player.write_log("Doing task: Work as manager")
success = player.work_as_manager() success = player.work_as_manager()
if success: if success:
next_time = utils.good_timedelta(now.replace(hour=14, minute=0, second=0, microsecond=0), timedelta(days=1)) next_time = utils.good_timedelta(
now.replace(hour=14, minute=0, second=0, microsecond=0), timedelta(days=1)
)
else: else:
next_time = utils.good_timedelta(now.replace(second=0, microsecond=0), timedelta(minutes=30)) next_time = utils.good_timedelta(now.replace(second=0, microsecond=0), timedelta(minutes=30))
@ -86,7 +88,9 @@ def main():
if sleep_seconds <= 0: if sleep_seconds <= 0:
player.write_log(f"Loop detected! Offending task: '{next_tasks[0]}'") player.write_log(f"Loop detected! Offending task: '{next_tasks[0]}'")
player.write_log("My next Tasks and there time:\n" + "\n".join(sorted(next_tasks))) player.write_log("My next Tasks and there time:\n" + "\n".join(sorted(next_tasks)))
player.write_log(f"Sleeping until (eRep): {closest_next_time.strftime('%F %T')}" f" (sleeping for {sleep_seconds}s)") player.write_log(
f"Sleeping until (eRep): {closest_next_time.strftime('%F %T')}" f" (sleeping for {sleep_seconds}s)"
)
seconds_to_sleep = sleep_seconds if sleep_seconds > 0 else 0 seconds_to_sleep = sleep_seconds if sleep_seconds > 0 else 0
player.sleep(seconds_to_sleep) player.sleep(seconds_to_sleep)
except Exception as e: except Exception as e:

View File

@ -1,4 +1,11 @@
[tool.black] [tool.black]
line-length = 140 line-length = 120
target-version = ['py38', 'py39'] target-version = ['py38', 'py39']
extend-exclude = 'venv'
workers = 4
[tool.isort]
profile = "black"
multi_line_output = 3
line_length = 120

16
requirements-dev.txt Normal file
View File

@ -0,0 +1,16 @@
-r requirements.txt
-r requirements-tests.txt
bump2version==1.0.1
coverage==6.1.1
edx-sphinx-theme==3.0.0
flake8==4.0.1
ipython>=7.29.0
jedi!=0.18.0
isort==5.9.3
pre-commit==2.15.0
pur==5.4.2
responses==0.15.0
Sphinx==4.2.0
twine==3.4.2
wheel==0.37.0
black==21.7b0

2
requirements-tests.txt Normal file
View File

@ -0,0 +1,2 @@
-r requirements.txt
pytest==6.2.5

4
requirements.txt Normal file
View File

@ -0,0 +1,4 @@
PySocks==1.7.1
pytz==2021.3
requests==2.26.0
requests-toolbelt==0.9.1

View File

@ -1,22 +0,0 @@
bump2version==1.0.1
coverage==5.5
edx-sphinx-theme==3.0.0
flake8==3.9.2
ipython>=7.26.0
jedi!=0.18.0
isort==5.9.3
pip==21.2.4
pre-commit==2.14.0
pur==5.4.2
PyInstaller==4.5.1
PySocks==1.7.1
pytest==6.2.4
pytz==2021.1
requests==2.26.0
requests-toolbelt==0.9.1
responses==0.13.4
setuptools==57.4.0
Sphinx==4.1.2
twine==3.4.2
wheel==0.37.0
black==21.7b0

View File

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.26.0.1 current_version = 0.28.0
commit = True commit = True
tag = True tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)?
@ -29,7 +29,7 @@ max-line-length = 140
exclude = .git,log,debug,venv, build exclude = .git,log,debug,venv, build
[mypy] [mypy]
python_version = 3.8 python_version = 3.9
check_untyped_defs = True check_untyped_defs = True
ignore_missing_imports = False ignore_missing_imports = False
warn_unused_ignores = True warn_unused_ignores = True

View File

@ -11,18 +11,17 @@ with open("README.rst") as readme_file:
with open("HISTORY.rst") as history_file: with open("HISTORY.rst") as history_file:
history = history_file.read() history = history_file.read()
requirements = [ with open("requirements.txt") as requirements_file:
"PySocks==1.7.1", requirements = requirements_file.read()
"pytz==2021.1", requirements = requirements.split()
"requests==2.26.0",
"requests-toolbelt==0.9.1",
]
setup_requirements = [] setup_requirements = []
test_requirements = [ with open("requirements-tests.txt") as test_req_file:
"pytest==6.2.4", test_requirements = test_req_file.read()
] test_requirements = [
line.strip() for line in test_requirements.split() if line.strip()[:2].strip() not in ("#", "-r")
]
setup( setup(
author="Eriks Karls", author="Eriks Karls",
@ -30,7 +29,7 @@ setup(
classifiers=[ classifiers=[
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"License :: OSI Approved :: GPLv3 License", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Natural Language :: English", "Natural Language :: English",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
@ -39,7 +38,7 @@ setup(
description="Python package for automated eRepublik playing", description="Python package for automated eRepublik playing",
entry_points={}, entry_points={},
install_requires=requirements, install_requires=requirements,
license="GPLv3 license", license="GPLv3",
long_description=readme + "\n\n" + history, long_description=readme + "\n\n" + history,
include_package_data=True, include_package_data=True,
keywords="erepublik", keywords="erepublik",
@ -50,6 +49,6 @@ setup(
test_suite="tests", test_suite="tests",
tests_require=test_requirements, tests_require=test_requirements,
url="https://github.com/eeriks/erepublik/", url="https://github.com/eeriks/erepublik/",
version="0.26.0.1", version="0.28.0",
zip_safe=False, zip_safe=False,
) )

View File

@ -3,10 +3,10 @@
"""Tests for `erepublik` package.""" """Tests for `erepublik` package."""
from erepublik import Citizen
import unittest import unittest
from erepublik import Citizen
class TestErepublik(unittest.TestCase): class TestErepublik(unittest.TestCase):
"""Tests for `erepublik` package.""" """Tests for `erepublik` package."""