Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initialized stats.py #414

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions howdoi/howdoi.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
from howdoi import __version__
from howdoi.errors import GoogleValidationError, BingValidationError, DDGValidationError

from .stats import CollectStats

DEFAULT_DIR = appdirs.user_cache_dir('howdoi-local-stats')

logging.basicConfig(format='%(levelname)s: %(message)s')
if os.getenv('HOWDOI_DISABLE_SSL'): # Set http instead of https
SCHEME = 'http://'
Expand Down Expand Up @@ -88,7 +92,7 @@
CACHE_ENTRY_MAX = 128

HTML_CACHE_PATH = 'page_cache'
SUPPORTED_HELP_QUERIES = ['use howdoi', 'howdoi', 'run howdoi', 'setup howdoi',
SUPPORTED_HELP_QUERIES = ['use howdoi', 'howdoi', 'run howdoi',
'do howdoi', 'howdoi howdoi', 'howdoi use howdoi']

# variables for text formatting, prepend to string to begin text formatting.
Expand All @@ -104,14 +108,15 @@
STASH_REMOVE = 'remove'
STASH_EMPTY = 'empty'

BLOCKED_ENGINES = []

if os.getenv('HOWDOI_DISABLE_CACHE'):
# works like an always empty cache
cache = NullCache()
else:
cache = FileSystemCache(CACHE_DIR, CACHE_ENTRY_MAX, default_timeout=0)

ENABLE_USER_STATS = True
# creating object -> initialiing constructor
CollectStats_obj = CollectStats(cache)
howdoi_session = requests.session()


Expand Down Expand Up @@ -187,6 +192,16 @@ def _get_result(url):
'HTTPS by setting the environment variable "HOWDOI_DISABLE_SSL".\n%s', RED, END_FORMAT)
raise error

def _get_from_cache(cache_key):
# As of cachelib 0.3.0, it internally logging a warning on cache miss
current_log_level = logging.getLogger().getEffectiveLevel()
# Reduce the log level so the warning is not printed
logging.getLogger().setLevel(logging.ERROR)
page = cache.get(cache_key) # pylint: disable=assignment-from-none
# Restore the log level
logging.getLogger().setLevel(current_log_level)
return page


def _add_links_to_text(element):
hyperlinks = element.find('a')
Expand Down Expand Up @@ -280,7 +295,7 @@ def _get_links(query):
result = None
if not result or _is_blocked(result):
logging.error('%sUnable to find an answer because the search engine temporarily blocked the request. '
'Attempting to use a different search engine.%s', RED, END_FORMAT)
'Please wait a few minutes or select a different search engine.%s', RED, END_FORMAT)
raise BlockError('Temporary block by search engine')

html = pq(result)
Expand Down Expand Up @@ -402,7 +417,7 @@ def _get_links_with_cache(query):

question_links = _get_questions(links)
cache.set(cache_key, question_links or CACHE_EMPTY_VAL)

CollectStats_obj.process_links(question_links)
return question_links


Expand Down Expand Up @@ -591,8 +606,8 @@ def howdoi(raw_query):
else:
args = raw_query

search_engine = args['search_engine'] or os.getenv('HOWDOI_SEARCH_ENGINE') or 'google'
os.environ['HOWDOI_SEARCH_ENGINE'] = search_engine
os.environ['HOWDOI_SEARCH_ENGINE'] = args['search_engine'] or os.getenv('HOWDOI_SEARCH_ENGINE') or 'google'
search_engine = os.getenv('HOWDOI_SEARCH_ENGINE')
if search_engine not in SUPPORTED_SEARCH_ENGINES:
supported_search_engines = ', '.join(SUPPORTED_SEARCH_ENGINES)
message = f'Unsupported engine {search_engine}. The supported engines are: {supported_search_engines}'
Expand All @@ -605,9 +620,13 @@ def howdoi(raw_query):
if _is_help_query(args['query']):
return _get_help_instructions() + '\n'

res = cache.get(cache_key) # pylint: disable=assignment-from-none
if ENABLE_USER_STATS:
CollectStats_obj.run(args)
res = _get_from_cache(cache_key) # pylint: disable=assignment-from-none

if res:
CollectStats_obj.increase_cache_hits()
CollectStats_obj.process_response(res)
logging.info('Using cached response (add -C to clear the cache)')
return _parse_cmd(args, res)

Expand All @@ -622,17 +641,9 @@ def howdoi(raw_query):
res = {'error': message}
cache.set(cache_key, res)
except (RequestsConnectionError, SSLError):
res = {'error': f'Unable to reach {search_engine}. Do you need to use a proxy?\n'}
except BlockError:
BLOCKED_ENGINES.append(search_engine)
next_engine = next((engine for engine in SUPPORTED_SEARCH_ENGINES if engine not in BLOCKED_ENGINES), None)
if next_engine is None:
res = {'error': 'Unable to get a response from any search engine\n'}
else:
args['search_engine'] = next_engine
args['query'] = args['query'].split()
logging.info('%sRetrying search with %s%s', GREEN, next_engine, END_FORMAT)
return howdoi(args)
res = {'error': f'Unable to reach {args["search_engine"]}. Do you need to use a proxy?\n'}

CollectStats_obj.process_response(res)
return _parse_cmd(args, res)


Expand Down Expand Up @@ -676,6 +687,8 @@ def get_parser():
action='store_true')
parser.add_argument('--sanity-check', help=argparse.SUPPRESS,
action='store_true')
parser.add_argument('--stats', help='view your local statistics for howdoi', action='store_true')
parser.add_argument('--disable_stats', help='disable local stats collection for howdoi', action='store_true')
return parser


Expand Down Expand Up @@ -765,6 +778,9 @@ def command_line_runner(): # pylint: disable=too-many-return-statements,too-man
perform_sanity_check()
)

if args['stats']:
CollectStats_obj.render_stats()

if args['clear_cache']:
if _clear_cache():
print(f'{GREEN}Cache cleared successfully{END_FORMAT}')
Expand Down
Loading