forked from PokemonGoF/PokemonGo-Bot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Better enforce rules about Pokemons to retain. (PokemonGoF#2073)
Rules about maximum CP and IV to transfer Pokemons are applied also when keeping the best ones.
- Loading branch information
1 parent
248ac53
commit 1ea32ca
Showing
4 changed files
with
216 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
from datetime import datetime, timedelta | ||
from time import sleep | ||
from random import uniform | ||
from pokemongo_bot import logger | ||
from pokemongo_bot.cell_workers.base_task import BaseTask | ||
|
||
|
||
class Sleeper(BaseTask): | ||
"""Pauses the execution of the bot every day for some time | ||
Simulates the user going to sleep every day for some time, the sleep time | ||
and the duration is changed every day by a random offset defined in the | ||
config file | ||
Example Config: | ||
{ | ||
"type": "Sleeper", | ||
"config": { | ||
"time": "12:00", | ||
"duration":"5:30", | ||
"time_random_offset": "00:30", | ||
"duration_random_offset": "00:30" | ||
} | ||
} | ||
time: (HH:MM) local time that the bot should sleep | ||
duration: (HH:MM) the duration of sleep | ||
time_random_offset: (HH:MM) random offset of time that the sleep will start | ||
for this example the possible start time is 11:30-12:30 | ||
duration_random_offset: (HH:MM) random offset of duration of sleep | ||
for this example the possible duration is 5:00-6:00 | ||
""" | ||
|
||
LOG_INTERVAL_SECONDS = 600 | ||
SCHEDULING_MARGIN = timedelta(minutes=10) # Skip if next sleep is RESCHEDULING_MARGIN from now | ||
|
||
def initialize(self): | ||
# self.bot.event_manager.register_event('sleeper_scheduled', parameters=('datetime',)) | ||
self._process_config() | ||
self._schedule_next_sleep() | ||
|
||
def work(self): | ||
if datetime.now() >= self._next_sleep: | ||
self._sleep() | ||
self._schedule_next_sleep() | ||
self.bot.login() | ||
|
||
def _process_config(self): | ||
self.time = datetime.strptime(self.config.get('time', '01:00'), '%H:%M') | ||
|
||
# Using datetime for easier stripping of timedeltas | ||
duration = datetime.strptime(self.config.get('duration', '07:00'), '%H:%M') | ||
self.duration = int(timedelta(hours=duration.hour, minutes=duration.minute).total_seconds()) | ||
|
||
time_random_offset = datetime.strptime(self.config.get('time_random_offset', '01:00'), '%H:%M') | ||
self.time_random_offset = int( | ||
timedelta( | ||
hours=time_random_offset.hour, minutes=time_random_offset.minute).total_seconds()) | ||
|
||
duration_random_offset = datetime.strptime(self.config.get('duration_random_offset', '00:30'), '%H:%M') | ||
self.duration_random_offset = int( | ||
timedelta( | ||
hours=duration_random_offset.hour, minutes=duration_random_offset.minute).total_seconds()) | ||
|
||
def _schedule_next_sleep(self): | ||
self._next_sleep = self._get_next_sleep_schedule() | ||
self._next_duration = self._get_next_duration() | ||
logger.log('Sleeper: next sleep at {}'.format(str(self._next_sleep)), color='green') | ||
|
||
def _get_next_sleep_schedule(self): | ||
now = datetime.now() + self.SCHEDULING_MARGIN | ||
next_time = now.replace(hour=self.time.hour, minute=self.time.minute) | ||
|
||
next_time += timedelta(seconds=self._get_random_offset(self.time_random_offset)) | ||
|
||
# If sleep time is passed add one day | ||
if next_time <= now: | ||
next_time += timedelta(days=1) | ||
|
||
return next_time | ||
|
||
def _get_next_duration(self): | ||
duration = self.duration + self._get_random_offset(self.duration_random_offset) | ||
return duration | ||
|
||
def _get_random_offset(self, max_offset): | ||
offset = uniform(-max_offset, max_offset) | ||
return int(offset) | ||
|
||
def _sleep(self): | ||
sleep_to_go = self._next_duration | ||
logger.log('It\'s time for sleep.') | ||
while sleep_to_go > 0: | ||
logger.log('Sleeping for {} more seconds'.format(sleep_to_go), 'yellow') | ||
if sleep_to_go < self.LOG_INTERVAL_SECONDS: | ||
sleep(sleep_to_go) | ||
sleep_to_go = 0 | ||
else: | ||
sleep(self.LOG_INTERVAL_SECONDS) | ||
sleep_to_go -= self.LOG_INTERVAL_SECONDS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import unittest | ||
from datetime import timedelta, datetime | ||
from mock import patch, MagicMock | ||
from pokemongo_bot.cell_workers.sleeper import Sleeper | ||
from tests import FakeBot | ||
|
||
|
||
class SleeperTestCase(unittest.TestCase): | ||
config = {'time': '12:20', 'duration': '01:05', 'time_random_offset': '00:05', 'duration_random_offset': '00:05'} | ||
|
||
def setUp(self): | ||
self.bot = FakeBot() | ||
self.worker = Sleeper(self.bot, self.config) | ||
|
||
def test_config(self): | ||
self.assertEqual(self.worker.time.hour, 12) | ||
self.assertEqual(self.worker.time.minute, 20) | ||
self.assertEqual(self.worker.duration, timedelta(hours=1, minutes=5).total_seconds()) | ||
self.assertEqual(self.worker.time_random_offset, timedelta(minutes=5).total_seconds()) | ||
self.assertEqual(self.worker.duration_random_offset, timedelta(minutes=5).total_seconds()) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.datetime') | ||
def test_get_next_time(self, mock_datetime): | ||
mock_datetime.now.return_value = datetime(year=2016, month=8, day=01, hour=8, minute=0) | ||
|
||
next_time = self.worker._get_next_sleep_schedule() | ||
from_date = datetime(year=2016, month=8, day=1, hour=12, minute=15) | ||
to_date = datetime(year=2016, month=8, day=1, hour=12, minute=25) | ||
|
||
self.assertGreaterEqual(next_time, from_date) | ||
self.assertLessEqual(next_time, to_date) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.datetime') | ||
def test_get_next_time_called_near_activation_time(self, mock_datetime): | ||
mock_datetime.now.return_value = datetime(year=2016, month=8, day=1, hour=12, minute=25) | ||
|
||
next = self.worker._get_next_sleep_schedule() | ||
from_date = datetime(year=2016, month=8, day=02, hour=12, minute=15) | ||
to_date = datetime(year=2016, month=8, day=02, hour=12, minute=25) | ||
|
||
self.assertGreaterEqual(next, from_date) | ||
self.assertLessEqual(next, to_date) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.datetime') | ||
def test_get_next_time_called_when_this_days_time_passed(self, mock_datetime): | ||
mock_datetime.now.return_value = datetime(year=2016, month=8, day=1, hour=14, minute=0) | ||
|
||
next = self.worker._get_next_sleep_schedule() | ||
from_date = datetime(year=2016, month=8, day=02, hour=12, minute=15) | ||
to_date = datetime(year=2016, month=8, day=02, hour=12, minute=25) | ||
|
||
self.assertGreaterEqual(next, from_date) | ||
self.assertLessEqual(next, to_date) | ||
|
||
def test_get_next_duration(self): | ||
from_seconds = int(timedelta(hours=1).total_seconds()) | ||
to_seconds = int(timedelta(hours=1, minutes=10).total_seconds()) | ||
|
||
duration = self.worker._get_next_duration() | ||
|
||
self.assertGreaterEqual(duration, from_seconds) | ||
self.assertLessEqual(duration, to_seconds) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.sleep') | ||
def test_sleep(self, mock_sleep): | ||
self.worker._next_duration = Sleeper.LOG_INTERVAL_SECONDS * 10 | ||
self.worker._sleep() | ||
#Sleep should be called 10 times with LOG_INTERVAL_SECONDS as argument | ||
self.assertEqual(mock_sleep.call_count, 10) | ||
calls = [x[0][0] for x in mock_sleep.call_args_list] | ||
for arg in calls: | ||
self.assertEqual(arg, Sleeper.LOG_INTERVAL_SECONDS) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.sleep') | ||
def test_sleep_not_divedable_by_interval(self, mock_sleep): | ||
self.worker._next_duration = Sleeper.LOG_INTERVAL_SECONDS * 10 + 5 | ||
self.worker._sleep() | ||
self.assertEqual(mock_sleep.call_count, 11) | ||
|
||
calls = [x[0][0] for x in mock_sleep.call_args_list] | ||
for arg in calls[:-1]: | ||
self.assertEqual(arg, Sleeper.LOG_INTERVAL_SECONDS) | ||
#Last call must be 5 | ||
self.assertEqual(calls[-1], 5) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.sleep') | ||
@patch('pokemongo_bot.cell_workers.sleeper.datetime') | ||
def test_call_work_before_schedule(self, mock_datetime, mock_sleep): | ||
self.worker._next_sleep = datetime(year=2016, month=8, day=1, hour=12, minute=0) | ||
mock_datetime.now.return_value = self.worker._next_sleep - timedelta(minutes=5) | ||
|
||
self.worker.work() | ||
|
||
self.assertEqual(mock_sleep.call_count, 0) | ||
|
||
@patch('pokemongo_bot.cell_workers.sleeper.sleep') | ||
@patch('pokemongo_bot.cell_workers.sleeper.datetime') | ||
def test_call_work_after_schedule(self, mock_datetime, mock_sleep): | ||
self.bot.login = MagicMock() | ||
self.worker._next_sleep = datetime(year=2016, month=8, day=1, hour=12, minute=0) | ||
# Change time to be after schedule | ||
mock_datetime.now.return_value = self.worker._next_sleep + timedelta(minutes=5) | ||
|
||
self.worker.work() | ||
|
||
self.assertGreater(mock_sleep.call_count, 0) | ||
self.assertGreater(self.bot.login.call_count, 0) |