Skip to content

Commit

Permalink
Add ColoredLoggingHandler (PokemonGoF#3198)
Browse files Browse the repository at this point in the history
  • Loading branch information
eevee-github authored and douglascamata committed Aug 10, 2016
1 parent b94d369 commit 9f9146c
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 3 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@
* nikhil-pandey
* thebigjc
* JaapMoolenaar
* eevee-github
1 change: 1 addition & 0 deletions configs/config.json.cluster.example
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"evolve_captured": "NONE",
"catch_randomize_reticle_factor": 1.0,
"catch_randomize_spin_factor": 1.0,
"logging_color": true,
"catch": {
"any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
"// Example of always catching Rattata:": {},
Expand Down
1 change: 1 addition & 0 deletions configs/config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"evolve_captured": "NONE",
"catch_randomize_reticle_factor": 1.0,
"catch_randomize_spin_factor": 1.0,
"logging_color": true,
"catch": {
"any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
"// Example of always catching Rattata:": {},
Expand Down
1 change: 1 addition & 0 deletions configs/config.json.map.example
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@
"evolve_captured": "NONE",
"catch_randomize_reticle_factor": 1.0,
"catch_randomize_spin_factor": 1.0,
"logging_color": true,
"catch": {
"any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
"// Example of always catching Rattata:": {},
Expand Down
1 change: 1 addition & 0 deletions configs/config.json.path.example
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"evolve_captured": "NONE",
"catch_randomize_reticle_factor": 1.0,
"catch_randomize_spin_factor": 1.0,
"logging_color": true,
"catch": {
"any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
"// Example of always catching Rattata:": {},
Expand Down
1 change: 1 addition & 0 deletions configs/config.json.pokemon.example
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"evolve_captured": "NONE",
"catch_randomize_reticle_factor": 1.0,
"catch_randomize_spin_factor": 1.0,
"logging_color": true,
"catch": {
"any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or" },

Expand Down
8 changes: 8 additions & 0 deletions pokecli.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@ def _json_loader(filename):
type=float,
default=5.0
)
add_config(
parser,
load,
long_flag="--logging_color",
help="If logging_color is set to true, colorized logging handler will be used",
type=bool,
default=True
)

# Start to parse other attrs
config = parser.parse_args()
Expand Down
10 changes: 7 additions & 3 deletions pokemongo_bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from human_behaviour import sleep
from item_list import Item
from metrics import Metrics
from pokemongo_bot.event_handlers import LoggingHandler, SocketIoHandler
from pokemongo_bot.event_handlers import LoggingHandler, SocketIoHandler, ColoredLoggingHandler
from pokemongo_bot.socketio_server.runner import SocketIoRunner
from pokemongo_bot.websocket_remote_control import WebsocketRemoteControl
from pokemongo_bot.base_dir import _base_dir
Expand Down Expand Up @@ -88,7 +88,12 @@ def start(self):
random.seed()

def _setup_event_system(self):
handlers = [LoggingHandler()]
handlers = []
if self.config.logging_color:
handlers.append(ColoredLoggingHandler())
else:
handlers.append(LoggingHandler())

if self.config.websocket_server_url:
if self.config.websocket_start_embedded_server:
self.sio_runner = SocketIoRunner(self.config.websocket_server_url)
Expand All @@ -103,7 +108,6 @@ def _setup_event_system(self):
if self.config.websocket_remote_control:
remote_control = WebsocketRemoteControl(self).start()


self.event_manager = EventManager(*handlers)
self._register_events()
if self.config.show_events:
Expand Down
1 change: 1 addition & 0 deletions pokemongo_bot/event_handlers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from logging_handler import LoggingHandler
from socketio_handler import SocketIoHandler
from colored_logging_handler import ColoredLoggingHandler
172 changes: 172 additions & 0 deletions pokemongo_bot/event_handlers/colored_logging_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time
import sys
import struct

from pokemongo_bot.event_manager import EventHandler

class ColoredLoggingHandler(EventHandler):
EVENT_COLOR_MAP = {
'api_error': 'red',
'bot_exit': 'red',
'bot_start': 'green',
'config_error': 'red',
'egg_already_incubating': 'yellow',
'egg_hatched': 'green',
'future_pokemon_release': 'yellow',
'incubate': 'green',
'incubator_already_used': 'yellow',
'inventory_full': 'yellow',
'item_discard_fail': 'red',
'item_discarded': 'green',
'keep_best_release': 'green',
'level_up': 'green',
'level_up_reward': 'green',
'location_cache_error': 'yellow',
'location_cache_ignored': 'yellow',
'login_failed': 'red',
'login_successful': 'green',
'lucky_egg_error': 'red',
'move_to_map_pokemon_encounter': 'green',
'move_to_map_pokemon_fail': 'red',
'next_egg_incubates': 'yellow',
'next_sleep': 'green',
'no_pokeballs': 'red',
'pokemon_appeared': 'yellow',
'pokemon_capture_failed': 'red',
'pokemon_caught': 'blue',
'pokemon_evolved': 'green',
'pokemon_fled': 'red',
'pokemon_inventory_full': 'red',
'pokemon_nickname_invalid': 'red',
'pokemon_not_in_range': 'yellow',
'pokemon_release': 'green',
'pokemon_vanished': 'red',
'pokestop_empty': 'yellow',
'pokestop_searching_too_often': 'yellow',
'rename_pokemon': 'green',
'skip_evolve': 'yellow',
'softban': 'red',
'spun_pokestop': 'cyan',
'threw_berry_failed': 'red',
'unknown_spin_result': 'red',
'unset_pokemon_nickname': 'red',
'vip_pokemon': 'red',

# event names for 'white' still here to remember that these events are already determined its color.
'arrived_at_cluster': 'white',
'arrived_at_fort': 'white',
'bot_sleep': 'white',
'catchable_pokemon': 'white',
'found_cluster': 'white',
'incubate_try': 'white',
'load_cached_location': 'white',
'location_found': 'white',
'login_started': 'white',
'lured_pokemon_found': 'white',
'move_to_map_pokemon_move_towards': 'white',
'move_to_map_pokemon_teleport_back': 'white',
'move_to_map_pokemon_updated_map': 'white',
'moving_to_fort': 'white',
'moving_to_lured_fort': 'white',
'pokemon_catch_rate': 'white',
'pokemon_evolve_fail': 'white',
'pokestop_on_cooldown': 'white',
'pokestop_out_of_range': 'white',
'polyline_request': 'white',
'position_update': 'white',
'set_start_location': 'white',
'softban_fix': 'white',
'softban_fix_done': 'white',
'spun_fort': 'white',
'threw_berry': 'white',
'threw_pokeball': 'white',
'used_lucky_egg': 'white'
}
CONTINUOUS_EVENT_NAMES = [
'catchable_pokemon',
'moving_to_lured_fort',
'spun_fort'
]
COLOR_CODE = {
'red': '91',
'green': '92',
'yellow': '93',
'blue': '94',
'cyan': '96'
}

def __init__(self):
self._last_event = None
try:
# this `try ... except` is for ImportError on Windows
import fcntl
import termios
self._ioctl = fcntl.ioctl
self._TIOCGWINSZ = termios.TIOCGWINSZ
except ImportError:
self._ioctl = None
self._TIOCGWINSZ = None

def handle_event(self, event, sender, level, formatted_msg, data):
# Prepare message string
message = None
if formatted_msg:
try:
message = formatted_msg.decode('utf-8')
except UnicodeEncodeError:
message = formatted_msg
else:
message = '{}'.format(str(data))

# Replace message if necessary
if event == 'catchable_pokemon':
message = 'Something rustles nearby!'

# Truncate previous line if same event continues
if event in ColoredLoggingHandler.CONTINUOUS_EVENT_NAMES and self._last_event == event:
# Filling with "' ' * terminal_width" in order to completely clear last line
terminal_width = self._terminal_width()
if terminal_width:
sys.stdout.write('\r{}\r'.format(' ' * terminal_width))
else:
sys.stdout.write('\r')
else:
sys.stdout.write("\n")

color_name = None
if event in ColoredLoggingHandler.EVENT_COLOR_MAP:
color_name = ColoredLoggingHandler.EVENT_COLOR_MAP[event]

# Change color if necessary
if event == 'egg_hatched' and data.get('pokemon', 'error') == 'error':
# `egg_hatched` event will be dispatched in both cases: hatched pokemon info is successfully taken or not.
# change color from 'green' to 'red' in case of error.
color_name = 'red'

if color_name in ColoredLoggingHandler.COLOR_CODE:
sys.stdout.write(
'[{time}] \033[{color}m{message}\033[0m'.format(
time=time.strftime("%H:%M:%S"),
color=ColoredLoggingHandler.COLOR_CODE[color_name],
message=message
)
)
else:
sys.stdout.write('[{time}] {message}'.format(
time=time.strftime("%H:%M:%S"),
message=message
))

sys.stdout.flush()
self._last_event = event

def _terminal_width(self):
if self._ioctl is None or self._TIOCGWINSZ is None:
return None

h, w, hp, wp = struct.unpack('HHHH',
self._ioctl(0, self._TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return w

0 comments on commit 9f9146c

Please sign in to comment.