Compare commits

...

117 Commits

Author SHA1 Message Date
48a27997ac Bump version: 0.16.0 → 0.16.1 2019-11-21 11:10:15 +02:00
90bec82630 12th anniversary minimal methods 2019-11-21 11:06:29 +02:00
aedfbf4465 12th anniversary endpoints 2019-11-21 10:42:55 +02:00
66f459c692 Inventory structure update 2019-10-30 19:42:05 +02:00
ef27960ff1 no message 2019-10-30 19:35:40 +02:00
c48af9a891 Thread stopping 2019-10-30 18:16:18 +02:00
1abfdb71ac Code cleanup and serialization improvements 2019-10-30 16:55:33 +02:00
e060f67666 More inventory structure updates 2019-10-29 16:06:07 +02:00
06d8d1c0b5 Telegram threading queue has been messing with error reporting 2019-10-29 16:05:22 +02:00
adda8dcb54 Structure requests by year/month/date folders, to keep requests in cleaner format.
The same medal kind (Maverick div BHs) can have different reward value - group them by kind-reward.
Citizen.post bugfix (with no data and json arguments) TODO: Must check where post is called without data or json
2019-10-28 14:17:45 +02:00
c7f084436d Inventory structure update 2019-10-18 18:18:39 +03:00
94a87091a4 Allow full energy reports once every half an hour 2019-10-17 19:15:17 +03:00
c0b97f112d TelegramBot.send_message should always append to send queue 2019-10-16 15:10:38 +03:00
3d895bd085 Damage calculation 2019-10-16 15:09:28 +03:00
d548d1bbf1 Hit calculation can be static 2019-10-15 20:03:38 +03:00
b1eefcc662 CSRF Attack Detecked loop on POST requests. 2019-10-15 20:03:22 +03:00
41798c446c Return successfully transfered item count 2019-10-15 11:28:56 +03:00
074da3adbe Telegram reporter queue bug 2019-10-14 19:21:00 +03:00
6c9a9e920d Delay telegram notification sending by appending multiple messages to queue and after minute of inactivity clear the queue by sending all messages 2019-10-14 13:44:31 +03:00
ffa2fc109c Travel for fighting fixed 2019-10-14 13:14:30 +03:00
f7f4028f32 Revert "Travel for fighting"
This reverts commit 07c8881092.
2019-10-14 13:03:36 +03:00
e91705ce90 no message 2019-10-14 13:03:19 +03:00
ca65a1ffe1 iPython indexer infinite loop and crash 2019-10-14 12:54:59 +03:00
07c8881092 Travel for fighting 2019-10-13 23:50:45 +03:00
25e534f783 Always print should_fight message 2019-10-08 09:32:00 +03:00
daa071f0f5 RTD build image url fixed, setup.py typo 2019-10-08 09:31:09 +03:00
2f8120bd0d Telegram formatting 2019-10-01 09:59:37 +03:00
6b2c073abe Damage booster activisation update and bugfix 2019-10-01 09:59:22 +03:00
c298d66086 Don't allow to fight before WeekChange even if force_fight (levelup, 75pp etc) 2019-10-01 09:58:37 +03:00
bf971972bf History update with version number 2019-09-29 09:47:15 +03:00
50f3d291ca Bump version: 0.15.3 → 0.16.0 2019-09-29 09:45:46 +03:00
b03140f2b8 RTD build image url fixed, setup.py typo 2019-09-29 09:42:24 +03:00
fe9a118875 Telegram loop traceback formatting
Fixed double code execution in Citizen.update_citizen_info(None) calling Citizen.update_citizen_info(html) and executing code twice.
2019-09-29 09:40:25 +03:00
17c73c79a7 Trying to find how and where Telegram spam happens 2019-09-28 16:03:31 +03:00
7533608316 Version updates 2019-09-27 13:51:09 +03:00
71a7f55338 Changes in eRepublik html 2019-09-27 11:50:51 +03:00
0ca0f49f92 bugfix 2019-09-27 11:20:00 +03:00
3f1b0018b2 Misplaced telegram queueing 2019-09-27 11:11:18 +03:00
2aaa4aad65 cleanup 2019-09-27 11:03:22 +03:00
b44a3a4b62 Init update 2019-09-27 11:03:02 +03:00
3a7dd9a6fa Init update 2019-09-27 11:02:26 +03:00
630c7cbc76 Was trying to send messages before citizen has been initialized 2019-09-27 10:26:53 +03:00
1ee47dfdcf Telegram integration 2019-09-26 15:53:21 +03:00
ab34135b73 Telegram integration 2019-09-26 15:44:21 +03:00
20bba4b9f9 Telegram integration 2019-09-26 15:42:16 +03:00
8db4ab1f0f Company sorting for wam: Raw factories, food, weapon, house, air, q7...q1, Final factories, food, weapon, house, air, q7...q1 2019-09-25 09:38:27 +03:00
acbf1590d7 If not enough food for wam - buy food and wam 2019-09-25 09:36:42 +03:00
63dd2d4f77 Optimisation and test cleanup 2019-09-05 15:36:01 +03:00
896b1b2432 Bugfix, cleanup and optimisation 2019-09-05 15:01:54 +03:00
60543e02c8 Merge branch 'master' into tests
* master:
  Update citizen.py
  Update citizen.py
2019-09-03 11:56:00 +03:00
b06e9a2933 Merge branch 'master' of github.com:eeriks/erepublik_script
* 'master' of github.com:eeriks/erepublik_script:
  Update citizen.py
  Update citizen.py
2019-09-03 11:55:44 +03:00
4eb96d7f1e Testing should travel and should fight 2019-09-03 11:55:34 +03:00
c8a1d8c8e8 Update citizen.py
If not employee find new job
2019-09-01 19:58:52 +03:00
c85f0417f2 Update citizen.py
Apply for work bugfix
2019-09-01 19:47:17 +03:00
7573f29950 Freshening up documentation 2019-08-28 17:16:46 +03:00
597d27117c Donating money now return status true or false 2019-08-27 11:16:36 +03:00
95570b7c17 Article voting and endorsing 2019-08-27 11:03:08 +03:00
bc4ba671d6 Endpoint method names renamed to better represent urls 2019-08-27 11:02:52 +03:00
088219a60a Endpoint method names renamed to better represent urls 2019-08-27 10:51:57 +03:00
53266b1c94 Merge branch 'master' of github.com:eeriks/erepublik_script 2019-08-27 10:17:34 +03:00
065a0ff3ec bugfix 2019-08-27 10:13:37 +03:00
c8e90ca910 bugfix 2019-08-27 10:13:14 +03:00
bbab84bf5b Update utils.py 2019-08-26 22:42:06 +03:00
fff17469e0 More verbose Citizen class serialization 2019-08-26 10:06:18 +03:00
0d208a8d32 Add timezone to datetime serialization 2019-08-26 10:05:52 +03:00
86004eb81b Don't serialize password nor email 2019-08-26 10:05:22 +03:00
7e05e35ebf More verbose Object representation in json format 2019-08-26 09:47:04 +03:00
411b158487 Citizen.buy_food() now buys 48h worth of food
When doing WAM and fialing because not enough food - buy food
Integrated new RW side chooser
2019-08-26 09:32:12 +03:00
d6e161d815 Bump version: 0.15.2 → 0.15.3 2019-08-24 15:44:22 +03:00
1285e95cec Inventory usage bugfixes 2019-08-24 10:48:04 +03:00
324db2c136 Fix new division numbering 2019-08-24 10:27:31 +03:00
1c6b41e41b Inventory updates and booster usage updates 2019-08-24 10:03:52 +03:00
a52552afb7 Use MyJSONEncoder from classes 2019-08-22 14:33:45 +03:00
28bfdc7b20 Use country ids from constant in utils 2019-08-22 14:33:07 +03:00
de1b734728 Don't check levelup when eating 2019-08-22 14:32:32 +03:00
fa5646ecfd Receive daily order 2019-08-22 14:32:00 +03:00
339392cfb0 Regex bugfix 2019-08-13 15:44:07 +03:00
7ebba458cb Max time timezones 2019-08-12 14:19:52 +03:00
4f436292af Organisation account fetcher - UNSTABLE 2019-08-12 12:54:58 +03:00
416c391d21 Improved levelup energy management 2019-08-11 01:45:49 +03:00
66c53ef985 Typo 2019-08-11 01:44:45 +03:00
3fa7d097fe Found awards switch to ASCII friendlier multiplier char - ✕ -> x
Localize max div end time
2019-08-05 11:55:39 +03:00
6af9675c39 Added gameTokensMarket endpoint 2019-08-05 10:20:36 +03:00
2343a6c6c8 WeeklyChallange end energy saver tweaks 2019-08-05 10:20:19 +03:00
7e56f01a38 Added gameTokensMarket endpoint 2019-08-05 10:13:48 +03:00
e14cbc18e9 Bump version: 0.15.1 → 0.15.2 2019-08-01 17:24:07 +03:00
048ce798dd All battle div div containing dicts where reference to the same object 2019-08-01 17:23:24 +03:00
e5b7cde044 Bump version: 0.15.0 → 0.15.1 2019-08-01 15:06:34 +03:00
6bbc7a1f64 Typehinting and battle/war stuff - last battle, attackable regions if CP, etc 2019-08-01 15:05:44 +03:00
4eccb339bb Deploy bombs 2019-08-01 15:04:16 +03:00
dbeb6e9ba5 Market scraper updates 2019-08-01 09:37:26 +03:00
9c9bb5ae40 Region attacking post updated 2019-08-01 09:37:08 +03:00
d8eb69f82a Travel bugfix and market scraper fixup 2019-07-31 22:39:54 +03:00
42c430213f Minor updates 2019-07-31 21:41:24 +03:00
39dbcaa27d Continuing work on return Response free Citizen class 2019-07-31 21:41:08 +03:00
8911adb81c Traveling improved for Citizen class 2019-07-31 21:38:34 +03:00
7927c162f8 More precise type hint 2019-07-31 21:37:29 +03:00
92b7c45a7d Report promos to erep.lv 2019-07-31 21:36:57 +03:00
53257487d8 Write on country wall update 2019-07-30 18:32:12 +03:00
8690c4d3f2 minor fix 2019-07-30 11:10:35 +03:00
43c6bce160 minor fix 2019-07-30 11:10:09 +03:00
c4f598c1ba Bump version: 0.14.7 → 0.15.0 2019-07-30 10:22:38 +03:00
c48d90dec3 First step towards removing manual response parsing in Citizen class 2019-07-30 10:22:29 +03:00
953902476f Bump version: 0.14.6.1 → 0.14.7 2019-07-30 09:32:10 +03:00
156cbbb61c Typehinting changes 2019-07-30 09:32:03 +03:00
b72039c865 PyPi needs new version number, even if accidentaly published version has been removed 2019-07-29 15:17:14 +03:00
9587538fdc Merge branch 'master' of github.com:eeriks/erepublik_script
* 'master' of github.com:eeriks/erepublik_script:
  Bump version: 0.14.5 → 0.14.6
2019-07-29 13:54:09 +03:00
e775679581 Bump version: 0.14.5 → 0.14.6 2019-07-29 13:53:17 +03:00
3aa305ea74 Switch from python-slugify to self hosted (Taken from Django 2.2.1 django.utils.text.slugify) 2019-07-29 13:52:33 +03:00
6b2e5ffb68 Bump version: 0.14.5 → 0.14.6 2019-07-29 13:33:02 +03:00
bb8634fe56 After deleting debug directory next request failed if SlowRequests.debug == True 2019-07-29 13:31:07 +03:00
25a0d8993e eRepublikAPI now has it's own token property 2019-07-29 13:19:19 +03:00
a1d10bb427 Bump version: 0.14.4 → 0.14.5 2019-07-23 17:55:08 +03:00
ec701396d9 project name migration 2019-07-23 17:55:04 +03:00
d8035b42e3 Underline too short 2019-07-23 17:53:00 +03:00
42320a14a4 no message 2019-07-23 17:50:14 +03:00
de4b059b7d Package name update: erepublik_script → eRepublik 2019-07-23 16:41:21 +03:00
21 changed files with 1517 additions and 944 deletions

View File

@ -15,7 +15,7 @@ Types of Contributions
Report Bugs
~~~~~~~~~~~
Report bugs at https://github.com/eeriks/erepublik_script/issues.
Report bugs at https://github.com/eeriks/erepublik/issues.
If you are reporting a bug, please include:
@ -45,7 +45,7 @@ articles, and such.
Submit Feedback
~~~~~~~~~~~~~~~
The best way to send feedback is to file an issue at https://github.com/eeriks/erepublik_script/issues.
The best way to send feedback is to file an issue at https://github.com/eeriks/erepublik/issues.
If you are proposing a feature:
@ -57,17 +57,17 @@ If you are proposing a feature:
Get Started!
------------
Ready to contribute? Here's how to set up `erepublik_script` for local development.
Ready to contribute? Here's how to set up `erepublik` for local development.
1. Fork the `erepublik_script` repo on GitHub.
2. Clone your fork locally::
$ git clone git@github.com:your_name_here/erepublik_script.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::
$ mkvirtualenv erepublik_script
$ cd erepublik_script/
$ mkvirtualenv erepublik
$ cd erepublik/
$ python setup.py develop
4. Create a branch for local development::
@ -79,7 +79,7 @@ Ready to contribute? Here's how to set up `erepublik_script` for local developme
5. When you're done making changes, check that your changes pass flake8 and the
tests, including testing other Python versions with tox::
$ flake8 erepublik_script tests
$ flake8 erepublik tests
$ python setup.py test or py.test
$ tox
@ -102,7 +102,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 2.7, 3.4, 3.5 and 3.6, and for PyPy. Check
3. The pull request should work for Python 3.7.1. Check
https://travis-ci.org/eeriks/erepublik_script/pull_requests
and make sure that the tests pass for all supported Python versions.

View File

@ -2,6 +2,39 @@
History
=======
* WC end fighting energy bugfix
* More strict fighting limiting before week change
* Improved and fixed ground damage booster usage
0.16.0 (2019-09-29)
-------------------
* Telegram notification integration
* Improved serialization to JSON
* When failing to do WAM because of not enough food - buy food
* Buy food buys 48h worth instead of 24h energy
0.15.3 (2019-08-24)
-------------------
* Update after eRepublik changed campaign apis
0.15.0 (2019-07-30)
-------------------
* CitizenAPI class methods renamed to "private", they are intended to be used internally.
* TODO: None of the Citizen class's methods should return Response object - CitizenAPI is meant for that.
0.14.4 (2019-07-23)
-------------------
* Wall post comment endpoints updated with comment create endpoints.
0.1.0 (2019-07-19)
------------------

View File

@ -51,7 +51,7 @@ clean-test: ## remove test and coverage artifacts
rm -fr .pytest_cache
lint: ## check style with flake8
flake8 erepublik_script tests
flake8 erepublik tests
test: ## run tests quickly with the default Python
python setup.py test
@ -60,15 +60,15 @@ test-all: ## run tests on every Python version with tox
tox
coverage: ## check code coverage quickly with the default Python
coverage run --source erepublik_script setup.py test
coverage run --source erepublik setup.py test
coverage report -m
coverage html
$(BROWSER) htmlcov/index.html
docs: ## generate Sphinx HTML documentation, including API docs
rm -f docs/erepublik_script.rst
rm -f docs/erepublik.rst
rm -f docs/modules.rst
sphinx-apidoc -o docs/ erepublik_script
sphinx-apidoc -o docs/ erepublik
$(MAKE) -C docs clean
$(MAKE) -C docs html
$(BROWSER) docs/_build/html/index.html

View File

@ -3,11 +3,11 @@ eRepublik script
================
.. image:: https://img.shields.io/pypi/v/erepublik_script.svg
:target: https://pypi.python.org/pypi/erepublik_script
.. image:: https://img.shields.io/pypi/v/erepublik.svg
:target: https://pypi.python.org/pypi/erepublik
.. image:: https://readthedocs.org/projects/erepublik-script/badge/?version=latest
:target: https://erepublik-script.readthedocs.io/en/latest/?badge=latest
.. image:: https://readthedocs.org/projects/erepublik/badge/?version=latest
:target: https://erepublik.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
@ -15,7 +15,7 @@ Python package for automated eRepublik playing
* Free software: MIT license
* Documentation: https://erepublik-script.readthedocs.io.
* Documentation: https://erepublik.readthedocs.io/en/latest/
Features

View File

@ -33,4 +33,4 @@
"travel_to_fight": true,
"wam": true,
"work": true
}
}

View File

@ -4,7 +4,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = erepublik_script
SPHINXPROJ = erepublik
SOURCEDIR = .
BUILDDIR = _build

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# erepublik_script documentation build configuration file, created by
# erepublik documentation build configuration file, created by
# sphinx-quickstart on Fri Jun 9 13:47:02 2017.
#
# This file is execfile()d with the current directory set to its
@ -22,7 +22,8 @@ import os
import sys
sys.path.insert(0, os.path.abspath('..'))
import erepublik_script
import erepublik
import edx_theme
# -- General configuration ---------------------------------------------
@ -32,7 +33,7 @@ import erepublik_script
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'edx_theme']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@ -56,9 +57,9 @@ author = u"Eriks Karls"
# the built documents.
#
# The short X.Y version.
version = erepublik_script.__version__
version = erepublik.__version__
# The full version, including alpha/beta/rc tags.
release = erepublik_script.__version__
release = erepublik.__version__
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -84,7 +85,8 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = 'edx_theme'
html_theme_path = [edx_theme.get_html_theme_path()]
# Theme options are theme-specific and customize the look and feel of a
# theme further. For a list of options available for each theme, see the
@ -101,7 +103,7 @@ html_static_path = ['_static']
# -- Options for HTMLHelp output ---------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'erepublik_scriptdoc'
htmlhelp_basename = 'erepublikdoc'
# -- Options for LaTeX output ------------------------------------------
@ -128,7 +130,7 @@ latex_elements = {
# (source start file, target name, title, author, documentclass
# [howto, manual, or own class]).
latex_documents = [
(master_doc, 'erepublik_script.tex',
(master_doc, 'erepublik.tex',
u'eRepublik script Documentation',
u'Eriks Karls', 'manual'),
]
@ -139,7 +141,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'erepublik_script',
(master_doc, 'erepublik',
u'eRepublik script Documentation',
[author], 1)
]
@ -151,13 +153,10 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'erepublik_script',
(master_doc, 'erepublik',
u'eRepublik script Documentation',
author,
'erepublik_script',
'erepublik',
'One line description of project.',
'Miscellaneous'),
]

View File

@ -1,5 +1,5 @@
Welcome to eRepublik script's documentation!
======================================
============================================
.. toctree::
:maxdepth: 2

View File

@ -12,7 +12,7 @@ To install eRepublik script, run this command in your terminal:
.. code-block:: console
$ pip install erepublik_script
$ pip install erepublik
This is the preferred method to install eRepublik script, as it will always install the most recent stable release.
@ -32,13 +32,13 @@ You can either clone the public repository:
.. code-block:: console
$ git clone git://github.com/eeriks/erepublik_script
$ git clone git://github.com/eeriks/erepublik
Or download the `tarball`_:
.. code-block:: console
$ curl -OL https://github.com/eeriks/erepublik_script/tarball/master
$ curl -OL https://github.com/eeriks/erepublik/tarball/master
Once you have a copy of the source, you can install it with:
@ -47,5 +47,5 @@ Once you have a copy of the source, you can install it with:
$ python setup.py install
.. _Github repo: https://github.com/eeriks/erepublik_script
.. _tarball: https://github.com/eeriks/erepublik_script/tarball/master
.. _Github repo: https://github.com/eeriks/erepublik
.. _tarball: https://github.com/eeriks/erepublik/tarball/master

View File

@ -1,36 +1,36 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=python -msphinx
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=erepublik_script
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The Sphinx module was not found. Make sure you have Sphinx installed,
echo.then set the SPHINXBUILD environment variable to point to the full
echo.path of the 'sphinx-build' executable. Alternatively you may add the
echo.Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=python -msphinx
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=erepublik
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The Sphinx module was not found. Make sure you have Sphinx installed,
echo.then set the SPHINXBUILD environment variable to point to the full
echo.path of the 'sphinx-build' executable. Alternatively you may add the
echo.Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

View File

@ -4,4 +4,7 @@ Usage
To use eRepublik script in a project::
import erepublik_script
from erepublik import Citizen
player = Citizen('email@domain.com', 'password')
player.update_all()

View File

@ -4,8 +4,7 @@
__author__ = """Eriks Karls"""
__email__ = 'eriks@72.lv'
__version__ = '0.14.4'
from erepublik_script import classes, utils
from erepublik_script.citizen import Citizen
__version__ = '0.16.1'
from erepublik import classes, utils
from erepublik.citizen import Citizen

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -6,24 +6,18 @@ import re
import sys
import time
import traceback
from collections import deque
from decimal import Decimal
from json import JSONEncoder
import unicodedata
from pathlib import Path
from typing import Union
from typing import Union, Any, List, NoReturn, Mapping
import pytz
import requests
from requests import Response
from slugify import slugify
__all__ = ["FOOD_ENERGY", "COMMIT_ID", "COUNTRIES", "erep_tz",
__all__ = ["FOOD_ENERGY", "COMMIT_ID", "COUNTRIES", "erep_tz", 'COUNTRY_LINK',
"now", "localize_dt", "localize_timestamp", "good_timedelta", "eday_from_date", "date_from_eday",
"get_sleep_seconds", "interactive_sleep", "silent_sleep",
"write_silent_log", "write_interactive_log", "get_file", "write_file",
"send_email", "normalize_html_json", "process_error", ]
"send_email", "normalize_html_json", "process_error", 'report_promo', 'calculate_hit']
FOOD_ENERGY = dict(q1=2, q2=4, q3=6, q4=8, q5=10, q6=12, q7=20)
COMMIT_ID = "7b92e19"
@ -85,40 +79,37 @@ COUNTRIES = {1: 'Romania', 9: 'Brazil', 10: 'Italy', 11: 'France', 12: 'Germany'
82: 'Cyprus', 83: 'Belarus', 84: 'New Zealand', 164: 'Saudi Arabia', 165: 'Egypt',
166: 'United Arab Emirates', 167: 'Albania', 168: 'Georgia', 169: 'Armenia', 170: 'Nigeria', 171: 'Cuba'}
class MyJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, Decimal):
return float("{:.02f}".format(o))
elif isinstance(o, datetime.datetime):
return dict(__type__='datetime', year=o.year, month=o.month, day=o.day, hour=o.hour, minute=o.minute,
second=o.second, microsecond=o.microsecond)
elif isinstance(o, datetime.date):
return dict(__type__='date', year=o.year, month=o.month, day=o.day)
elif isinstance(o, datetime.timedelta):
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)
elif hasattr(o, '__dict__'):
return o.__dict__
elif isinstance(o, deque):
return list(o)
return super().default(o)
COUNTRY_LINK = {1: 'Romania', 9: 'Brazil', 11: 'France', 12: 'Germany', 13: 'Hungary', 82: 'Cyprus', 168: 'Georgia',
15: 'Spain', 23: 'Canada', 26: 'Mexico', 27: 'Argentina', 28: 'Venezuela', 80: 'Montenegro', 24: 'USA',
29: 'United-Kingdom', 50: 'Australia', 47: 'South-Korea', 171: 'Cuba',
79: 'Republic-of-Macedonia-FYROM',
30: 'Switzerland', 31: 'Netherlands', 32: 'Belgium', 33: 'Austria', 34: 'Czech-Republic', 35: 'Poland',
36: 'Slovakia', 37: 'Norway', 38: 'Sweden', 39: 'Finland', 40: 'Ukraine', 41: 'Russia', 42: 'Bulgaria',
43: 'Turkey', 44: 'Greece', 45: 'Japan', 48: 'India', 49: 'Indonesia', 78: 'Colombia', 68: 'Singapore',
51: 'South Africa', 52: 'Republic-of-Moldova', 53: 'Portugal', 54: 'Ireland', 55: 'Denmark', 56: 'Iran',
57: 'Pakistan', 58: 'Israel', 59: 'Thailand', 61: 'Slovenia', 63: 'Croatia', 64: 'Chile', 65: 'Serbia',
66: 'Malaysia', 67: 'Philippines', 70: 'Estonia', 165: 'Egypt', 14: 'China', 77: 'Peru', 10: 'Italy',
71: 'Latvia', 72: 'Lithuania', 73: 'North-Korea', 74: 'Uruguay', 75: 'Paraguay', 76: 'Bolivia',
81: 'Republic-of-China-Taiwan', 166: 'United-Arab-Emirates', 167: 'Albania', 69: 'Bosnia-Herzegovina',
169: 'Armenia', 83: 'Belarus', 84: 'New-Zealand', 164: 'Saudi-Arabia', 170: 'Nigeria', }
def now():
def now() -> datetime.datetime:
return datetime.datetime.now(erep_tz).replace(microsecond=0)
def localize_timestamp(timestamp: int):
def localize_timestamp(timestamp: int) -> datetime.datetime:
return datetime.datetime.fromtimestamp(timestamp, erep_tz)
def localize_dt(dt: Union[datetime.date, datetime.datetime]):
if isinstance(dt, datetime.date):
dt = datetime.datetime.combine(dt, datetime.time(0, 0, 0))
return erep_tz.localize(dt)
def localize_dt(dt: Union[datetime.date, datetime.datetime]) -> datetime.datetime:
try:
try:
return erep_tz.localize(dt)
except AttributeError:
return erep_tz.localize(datetime.datetime.combine(dt, datetime.time(0, 0, 0)))
except ValueError:
return dt.astimezone(erep_tz)
def good_timedelta(dt: datetime.datetime, td: datetime.timedelta) -> datetime.datetime:
@ -214,7 +205,7 @@ def write_file(filename: str, content: str) -> int:
def write_request(response: requests.Response, is_error: bool = False):
from erepublik_script import Citizen
from erepublik import Citizen
# Remove GET args from url name
url = response.url
last_index = url.index("?") if "?" in url else len(response.url)
@ -237,8 +228,11 @@ def write_request(response: requests.Response, is_error: bool = False):
"mimetype": "application/json" if ext == "json" else "text/html"}
def send_email(name, content: list, player=None, local_vars=dict, promo: bool = False, captcha: bool = False):
from erepublik_script import Citizen
def send_email(name: str, content: List[Any], player=None, local_vars: Mapping[Any, Any] = None,
promo: bool = False, captcha: bool = False):
if local_vars is None:
local_vars = {}
from erepublik import Citizen
file_content_template = "<html><head><title>{title}</title></head><body>{body}</body></html>"
if isinstance(player, Citizen):
@ -277,6 +271,7 @@ def send_email(name, content: list, player=None, local_vars=dict, promo: bool =
if local_vars:
if "state_thread" in local_vars:
local_vars.pop('state_thread', None)
from erepublik.classes import MyJSONEncoder
files.append(('file', ("local_vars.json", json.dumps(local_vars, indent=2,
cls=MyJSONEncoder, sort_keys=True), "application/json")))
if isinstance(player, Citizen):
@ -296,7 +291,6 @@ def process_error(log_info: str, name: str, exc_info: tuple, citizen=None, commi
interactive: bool = False):
"""
Process error logging and email sending to developer
:param error:
:param interactive: Should print interactively
:param log_info: String to be written in output
:param name: String Instance name
@ -312,4 +306,69 @@ def process_error(log_info: str, name: str, exc_info: tuple, citizen=None, commi
write_interactive_log(log_info)
else:
write_silent_log(log_info)
send_email(name, bugtrace, citizen, local_vars=inspect.trace()[-1][0].f_locals)
trace = inspect.trace()
if trace:
trace = trace[-1][0].f_locals
else:
trace = dict()
send_email(name, bugtrace, citizen, local_vars=trace)
def report_promo(kind: str, time_untill: datetime.datetime) -> NoReturn:
requests.post('https://api.erep.lv/promos/add/', data=dict(kind=kind, time_untill=time_untill))
def slugify(value, allow_unicode=False) -> str:
"""
Function copied from Django2.2.1 django.utils.text.slugify
Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens.
Remove characters that aren't alphanumerics, underscores, or hyphens.
Convert to lowercase. Also strip leading and trailing whitespace.
"""
value = str(value)
if allow_unicode:
value = unicodedata.normalize('NFKC', value)
else:
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
value = re.sub(r'[^\w\s-]', '_', value).strip().lower()
return re.sub(r'[-\s]+', '-', value)
def calculate_hit(strength: float, rang: int, tp: bool, elite: bool, ne: bool, booster: int = 0,
weapon: int = 200) -> float:
base_dmg = 10 * (1 + strength / 400) * (1 + rang / 5) * (1 + weapon / 100)
dmg = int(base_dmg * 10 + 5) // 10
booster_multiplier = (100 + booster) / 100
booster_dmg = dmg * booster_multiplier
dmg = int(booster_dmg * 10 + 5) // 10
elite = 1.1 if elite else 1
elite_dmg = dmg * elite
dmg = int(elite_dmg)
legend = 1 if (not tp or rang < 70) else 1 + (rang - 69) / 10
legend_dmg = dmg * legend
dmg = int(legend_dmg)
return dmg * (1.1 if ne else 1)
def ground_hit_dmg_value(citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False,
booster: int = 0, weapon_power: int = 200) -> float:
r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
rang = r['military']['militaryData']['ground']['rankNumber']
strength = r['military']['militaryData']['ground']['strength']
elite = r['citizenAttributes']['level'] > 100
if natural_enemy:
true_patriot = True
return calculate_hit(strength, rang, true_patriot, elite, natural_enemy, booster, weapon_power)
def air_hit_dmg_value(citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False, booster: int = 0,
weapon_power: int = 0) -> float:
r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
rang = r['military']['militaryData']['aircraft']['rankNumber']
elite = r['citizenAttributes']['level'] > 100
return calculate_hit(0, rang, true_patriot, elite, natural_enemy, booster, weapon_power)

View File

@ -5,11 +5,10 @@ watchdog==0.9.0
flake8==3.7.8
tox==3.13.2
coverage==4.5.3
Sphinx==2.1.2
twine==1.13.0
ipython==7.6.1
PyInstaller==3.5
Sphinx==2.2.0
twine==2.0.0
ipython
PyInstaller
pytz==2019.1
requests==2.22.0
pycryptodome==3.8.2
python-slugify==2.0.1
edx-sphinx-theme

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.14.4
current_version = 0.16.1
commit = True
tag = True
@ -7,7 +7,7 @@ tag = True
search = version='{current_version}'
replace = version='{new_version}'
[bumpversion:file:erepublik_script/__init__.py]
[bumpversion:file:erepublik/__init__.py]
search = __version__ = '{current_version}'
replace = __version__ = '{new_version}'
@ -17,7 +17,7 @@ universal = 1
[flake8]
exclude = docs
max-line-length = 120
ignore = E722
ignore = E722 F401
[aliases]

View File

@ -11,36 +11,37 @@ with open('README.rst') as readme_file:
with open('HISTORY.rst') as history_file:
history = history_file.read()
requirements = ['pytz==2019.1', 'requests==2.22.0', 'python-slugify<3.0.0']
requirements = ['pytz>=2019.2', 'requests>=2.22']
setup_requirements = [ ]
setup_requirements = []
test_requirements = [ ]
test_requirements = []
setup(
author="Eriks Karls",
author_email='eriks@72.lv',
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
],
description="Python package for eRepublik automated playing",
description="Python package for automated eRepublik playing",
entry_points={},
install_requires=requirements,
license="MIT license",
long_description=readme + '\n\n' + history,
include_package_data=True,
keywords='erepublik_script',
name='erepublik_script',
packages=find_packages(include=['erepublik_script']),
keywords='erepublik',
name='eRepublik',
packages=find_packages(include=['erepublik']),
python_requires='>=3.7.*, <4',
setup_requires=setup_requirements,
test_suite='tests',
tests_require=test_requirements,
url='https://github.com/eeriks/erepublik_script',
version='0.14.4',
url='https://github.com/eeriks/erepublik/',
version='0.16.1',
zip_safe=False,
)

View File

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Unit test package for erepublik_script."""
"""Unit test package for erepublik."""

View File

@ -1,34 +1,130 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Tests for `erepublik_script` package."""
"""Tests for `erepublik` package."""
import unittest
from click.testing import CliRunner
from erepublik_script import Citizen
from erepublik_script import cli
from erepublik import Citizen
class TestErepublik_script(unittest.TestCase):
"""Tests for `erepublik_script` package."""
class TestErepublik(unittest.TestCase):
"""Tests for `erepublik` package."""
def setUp(self):
"""Set up test fixtures, if any."""
self.citizen = Citizen("email", "password", False)
self.citizen.config.interactive = False
def tearDown(self):
"""Tear down test fixtures, if any."""
def test_should_do_levelup(self):
self.citizen.energy.recovered = 1900
self.citizen.energy.recoverable = 2940
self.citizen.energy.interval = 30
self.citizen.energy.limit = 3000
self.citizen.details.xp = 14850
self.assertTrue(self.citizen.should_do_levelup)
def test_000_something(self):
"""Test something."""
self.citizen.energy.recoverable = 1000
self.assertFalse(self.citizen.should_do_levelup)
def test_should_travel_to_fight(self):
self.citizen.config.always_travel = True
self.assertTrue(self.citizen.should_travel_to_fight())
self.citizen.config.always_travel = False
self.assertFalse(self.citizen.should_travel_to_fight())
self.citizen.energy.recovered = 1900
self.citizen.energy.recoverable = 2940
self.citizen.energy.interval = 30
self.citizen.energy.limit = 3000
self.citizen.details.xp = 14850
self.assertTrue(self.citizen.should_travel_to_fight())
self.citizen.details.xp = 15000
self.assertFalse(self.citizen.should_travel_to_fight())
self.citizen.energy.recovered = 3000
self.citizen.energy.recoverable = 2910
self.assertTrue(self.citizen.should_travel_to_fight())
self.citizen.energy.recoverable = 2900
self.assertFalse(self.citizen.should_travel_to_fight())
# self.citizen.next_reachable_energy and self.citizen.config.next_energy
self.citizen.config.next_energy = True
self.citizen.energy.limit = 5000
self.citizen.details.next_pp = [5000, 5250, 5750, 6250, 6750]
self.citizen.details.pp = 4900
self.citizen.energy.recovered = 4000
self.citizen.energy.recoverable = 4510
self.assertEqual(self.citizen.next_reachable_energy, 850)
self.citizen.energy.recoverable = 4490
self.assertTrue(self.citizen.should_travel_to_fight())
self.assertEqual(self.citizen.next_reachable_energy, 350)
self.citizen.energy.recovered = 100
self.citizen.energy.recoverable = 150
self.assertFalse(self.citizen.should_travel_to_fight())
self.assertEqual(self.citizen.next_reachable_energy, 0)
def test_should_fight(self):
self.citizen.config.fight = False
self.assertEqual(self.citizen.should_fight(), 0)
self.citizen.config.fight = True
# Level up
self.citizen.energy.limit = 3000
self.citizen.details.xp = 24705
self.assertEqual(self.citizen.should_fight(), 0)
self.citizen.energy.recovered = 3000
self.citizen.energy.recoverable = 2950
self.citizen.energy.interval = 30
self.assertEqual(self.citizen.should_fight(), 900)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 900)
self.citizen.my_companies.ff_lockdown = 0
# Level up reachable
self.citizen.details.xp = 24400
self.assertEqual(self.citizen.should_fight(), 305)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 305)
self.citizen.my_companies.ff_lockdown = 0
self.citizen.details.xp = 21000
self.assertEqual(self.citizen.should_fight(), 75)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 75)
self.citizen.my_companies.ff_lockdown = 0
self.citizen.details.pp = 80
# All-in (type = all-in and full ff)
self.citizen.config.all_in = True
self.assertEqual(self.citizen.should_fight(), 595)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 435)
self.citizen.my_companies.ff_lockdown = 0
self.citizen.config.air = True
self.citizen.energy.recoverable = 1000
self.assertEqual(self.citizen.should_fight(), 400)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 240)
self.citizen.my_companies.ff_lockdown = 0
self.citizen.config.all_in = False
self.citizen.config.next_energy = True
self.citizen.energy.limit = 5000
self.citizen.details.next_pp = [100, 150, 250, 400, 500]
self.assertEqual(self.citizen.should_fight(), 320)
self.citizen.my_companies.ff_lockdown = 160
self.assertEqual(self.citizen.should_fight(), 160)
self.citizen.my_companies.ff_lockdown = 0
self.citizen.energy.limit = 3000
self.citizen.details.next_pp = [19250, 20000]
self.citizen.config.next_energy = False
# 1h worth of energy
self.citizen.energy.recoverable = 2910
self.assertEqual(self.citizen.should_fight(), 30)
def test_command_line_interface(self):
"""Test the CLI."""
runner = CliRunner()
result = runner.invoke(cli.main)
assert result.exit_code == 0
assert 'erepublik_script.cli.main' in result.output
help_result = runner.invoke(cli.main, ['--help'])
assert help_result.exit_code == 0
assert '--help Show this message and exit.' in help_result.output

View File

@ -1,10 +1,9 @@
[tox]
envlist = py36, py37, flake8
envlist = py37, flake8
[travis]
python =
3.7: py37
3.6: py36
[testenv:flake8]
basepython = python