"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "googler" between
googler-4.3.1.tar.gz and googler-4.3.2.tar.gz

About: googler is a command line tool to search Google (Web & News) from the terminal (requires Python).

googler  (googler-4.3.1):googler  (googler-4.3.2)
#!/usr/bin/env python3 #!/usr/bin/env python3
# #
# Copyright © 2008 Henri Hakkinen # Copyright © 2008 Henri Hakkinen
# Copyright © 2015-2020 Arun Prakash Jana <engineerarun@gmail.com> # Copyright © 2015-2021 Arun Prakash Jana <engineerarun@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
skipping to change at line 38 skipping to change at line 38
import http.client import http.client
from http.client import HTTPSConnection from http.client import HTTPSConnection
import locale import locale
import logging import logging
import os import os
import platform import platform
import shutil import shutil
import signal import signal
import socket import socket
import ssl import ssl
import subprocess
from subprocess import Popen, PIPE, DEVNULL from subprocess import Popen, PIPE, DEVNULL
import sys import sys
import textwrap import textwrap
import unicodedata import unicodedata
import urllib.parse import urllib.parse
import uuid import uuid
import webbrowser import webbrowser
# Python optional dependency compatibility layer # Python optional dependency compatibility layer
try: try:
skipping to change at line 90 skipping to change at line 91
sys.exit(1) sys.exit(1)
try: try:
signal.signal(signal.SIGINT, sigint_handler) signal.signal(signal.SIGINT, sigint_handler)
except ValueError: except ValueError:
# signal only works in main thread # signal only works in main thread
pass pass
# Constants # Constants
_VERSION_ = '4.3.1' _VERSION_ = '4.3.2'
_EPOCH_ = '20201001' _EPOCH_ = '20210115'
COLORMAP = {k: '\x1b[%sm' % v for k, v in { COLORMAP = {k: '\x1b[%sm' % v for k, v in {
'a': '30', 'b': '31', 'c': '32', 'd': '33', 'a': '30', 'b': '31', 'c': '32', 'd': '33',
'e': '34', 'f': '35', 'g': '36', 'h': '37', 'e': '34', 'f': '35', 'g': '36', 'h': '37',
'i': '90', 'j': '91', 'k': '92', 'l': '93', 'i': '90', 'j': '91', 'k': '92', 'l': '93',
'm': '94', 'n': '95', 'o': '96', 'p': '97', 'm': '94', 'n': '95', 'o': '96', 'p': '97',
'A': '30;1', 'B': '31;1', 'C': '32;1', 'D': '33;1', 'A': '30;1', 'B': '31;1', 'C': '32;1', 'D': '33;1',
'E': '34;1', 'F': '35;1', 'G': '36;1', 'H': '37;1', 'E': '34;1', 'F': '35;1', 'G': '36;1', 'H': '37;1',
'I': '90;1', 'J': '91;1', 'K': '92;1', 'L': '93;1', 'I': '90;1', 'J': '91;1', 'K': '92;1', 'L': '93;1',
'M': '94;1', 'N': '95;1', 'O': '96;1', 'P': '97;1', 'M': '94;1', 'N': '95;1', 'O': '96;1', 'P': '97;1',
skipping to change at line 1434 skipping to change at line 1435
The string attribute ``open_url.override_text_browser`` can be used to The string attribute ``open_url.override_text_browser`` can be used to
ignore env var BROWSER as well as some known text-based browsers and ignore env var BROWSER as well as some known text-based browsers and
attempt to open url in a GUI browser available. attempt to open url in a GUI browser available.
Note: If a GUI browser is indeed found, this option ignores the program Note: If a GUI browser is indeed found, this option ignores the program
option `show-browser-logs` option `show-browser-logs`
""" """
logger.debug('Opening %s', url) logger.debug('Opening %s', url)
# Custom URL handler gets max priority # Custom URL handler gets max priority
if hasattr(open_url, 'url_handler'): if hasattr(open_url, 'url_handler'):
p = Popen([open_url.url_handler, url], stdin=PIPE) subprocess.run([open_url.url_handler, url])
p.communicate()
return return
browser = webbrowser.get() browser = webbrowser.get()
if open_url.override_text_browser: if open_url.override_text_browser:
browser_output = open_url.suppress_browser_output browser_output = open_url.suppress_browser_output
for name in [b for b in webbrowser._tryorder if b not in text_browsers]: for name in [b for b in webbrowser._tryorder if b not in text_browsers]:
browser = webbrowser.get(name) browser = webbrowser.get(name)
logger.debug(browser) logger.debug(browser)
# Found a GUI browser, suppress browser output # Found a GUI browser, suppress browser output
skipping to change at line 1531 skipping to change at line 1531
Please set a UTF-8 locale (e.g., en_US.UTF-8) or set Please set a UTF-8 locale (e.g., en_US.UTF-8) or set
PYTHONIOENCODING to utf-8. PYTHONIOENCODING to utf-8.
""".format( """.format(
encoding=encoding, encoding=encoding,
locale_lang=locale_lang, locale_lang=locale_lang,
locale_encoding=locale_encoding, locale_encoding=locale_encoding,
ioencoding=ioencoding, ioencoding=ioencoding,
)))) ))))
sys.exit(1) sys.exit(1)
def time_it(description=None):
def decorator(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
# Only profile in debug mode.
if not logger.isEnabledFor(logging.DEBUG):
return func(*args, **kwargs)
import time
mark = time.perf_counter()
ret = func(*args, **kwargs)
duration = time.perf_counter() - mark
logger.debug('%s completed in \x1b[33m%.3fs\x1b[0m', description or
func.__name__, duration)
return ret
return wrapped
return decorator
# Classes # Classes
class HardenedHTTPSConnection(HTTPSConnection): class HardenedHTTPSConnection(HTTPSConnection):
"""Overrides HTTPSConnection.connect to specify TLS version """Overrides HTTPSConnection.connect to specify TLS version
NOTE: TLS 1.2 is supported from Python 3.4 NOTE: TLS 1.2 is supported from Python 3.4
""" """
def __init__(self, host, address_family=0, **kwargs): def __init__(self, host, address_family=0, **kwargs):
HTTPSConnection.__init__(self, host, **kwargs) HTTPSConnection.__init__(self, host, **kwargs)
skipping to change at line 2056 skipping to change at line 2075
self._notweak = notweak self._notweak = notweak
self._conn = None self._conn = None
self.new_connection(host, port=port, timeout=timeout) self.new_connection(host, port=port, timeout=timeout)
self.cookie = '' self.cookie = ''
@property @property
def host(self): def host(self):
"""The host currently connected to.""" """The host currently connected to."""
return self._host return self._host
@time_it()
def new_connection(self, host=None, port=None, timeout=45): def new_connection(self, host=None, port=None, timeout=45):
"""Close the current connection (if any) and establish a new one. """Close the current connection (if any) and establish a new one.
Parameters Parameters
---------- ----------
See http.client.HTTPSConnection for documentation of the See http.client.HTTPSConnection for documentation of the
parameters. Renew the connection (i.e., reuse the current host parameters. Renew the connection (i.e., reuse the current host
and port) if host is None or empty. and port) if host is None or empty.
Raises Raises
skipping to change at line 2120 skipping to change at line 2140
raise GoogleConnectionError(msg) raise GoogleConnectionError(msg)
def renew_connection(self, timeout=45): def renew_connection(self, timeout=45):
"""Renew current connection. """Renew current connection.
Equivalent to ``new_connection(timeout=timeout)``. Equivalent to ``new_connection(timeout=timeout)``.
""" """
self.new_connection(timeout=timeout) self.new_connection(timeout=timeout)
@time_it()
def fetch_page(self, url): def fetch_page(self, url):
"""Fetch a URL. """Fetch a URL.
Allows one reconnection and multiple redirections before failing Allows one reconnection and multiple redirections before failing
and raising GoogleConnectionError. and raising GoogleConnectionError.
Parameters Parameters
---------- ----------
url : str url : str
The URL to fetch, relative to the host. The URL to fetch, relative to the host.
skipping to change at line 2274 skipping to change at line 2295
def __init__(self, html, *, news=False, videos=False): def __init__(self, html, *, news=False, videos=False):
self.news = news self.news = news
self.videos = videos self.videos = videos
self.autocorrected = False self.autocorrected = False
self.showing_results_for = None self.showing_results_for = None
self.filtered = False self.filtered = False
self.results = [] self.results = []
self.parse(html) self.parse(html)
@time_it()
def parse(self, html): def parse(self, html):
tree = parse_html(html) tree = parse_html(html)
if debugger: if debugger:
printerr('\x1b[1mInspect the DOM through the \x1b[4mtree\x1b[24m var iable.\x1b[0m') printerr('\x1b[1mInspect the DOM through the \x1b[4mtree\x1b[24m var iable.\x1b[0m')
printerr('') printerr('')
try: try:
import IPython import IPython
IPython.embed() IPython.embed()
except ImportError: except ImportError:
skipping to change at line 2317 skipping to change at line 2339
mime = div_g.select('.mime') mime = div_g.select('.mime')
if mime: if mime:
title = mime.text + ' ' + title title = mime.text + ' ' + title
abstract_node = div_g.select('.st') abstract_node = div_g.select('.st')
metadata_node = div_g.select('.f') metadata_node = div_g.select('.f')
else: else:
# Current structure as of October 2020. # Current structure as of October 2020.
# Note that a filetype tag (e.g. PDF) is now pretty # Note that a filetype tag (e.g. PDF) is now pretty
# damn hard to parse with confidence (that it'll # damn hard to parse with confidence (that it'll
# survive the slighest further change), so we don't. # survive the slighest further change), so we don't.
title_node, details_node, *_ = div_g.select_all('div.rc > di
v') # As of January 15th 2021, the html class is not rc anymore,
it's tF2Cxc.
# This approach is not very resilient to changes by Google,
but it works for now.
# title_node, details_node, *_ = div_g.select_all('div.rc >
div')
title_node, details_node, *_ = div_g.select_all('div.tF2Cxc
> div')
if 'yuRUbf' not in title_node.classes: if 'yuRUbf' not in title_node.classes:
logger.debug('unexpected title node class(es): expected %r, got %r', logger.debug('unexpected title node class(es): expected %r, got %r',
'yuRUbf', ' '.join(title_node.classes)) 'yuRUbf', ' '.join(title_node.classes))
if 'IsZvec' not in details_node.classes: if 'IsZvec' not in details_node.classes:
logger.debug('unexpected details node class(es): expecte d %r, got %r', logger.debug('unexpected details node class(es): expecte d %r, got %r',
'IsZvec', ' '.join(details_node.classes)) 'IsZvec', ' '.join(details_node.classes))
a = title_node.select('a') a = title_node.select('a')
h3 = a.select('h3') h3 = a.select('h3')
title = h3.text title = h3.text
abstract_node = details_node.select('span') abstract_node = details_node.select('span')
skipping to change at line 3185 skipping to change at line 3211
* other inputs issue a new search with original op tions * other inputs issue a new search with original op tions
""")) """))
# Print information on googler # Print information on googler
@staticmethod @staticmethod
def print_general_info(file=None): def print_general_info(file=None):
file = sys.stderr if file is None else file file = sys.stderr if file is None else file
file.write(textwrap.dedent(""" file.write(textwrap.dedent("""
Version %s Version %s
Copyright © 2008 Henri Hakkinen Copyright © 2008 Henri Hakkinen
Copyright © 2015-2020 Arun Prakash Jana <engineerarun@gmail.com> Copyright © 2015-2021 Arun Prakash Jana <engineerarun@gmail.com>
Zhiming Wang <zmwangx@gmail.com> Zhiming Wang <zmwangx@gmail.com>
License: GPLv3 License: GPLv3
Webpage: https://github.com/jarun/googler Webpage: https://github.com/jarun/googler
""" % _VERSION_)) """ % _VERSION_))
# Augment print_help to print more than synopsis and options # Augment print_help to print more than synopsis and options
def print_help(self, file=None): def print_help(self, file=None):
super().print_help(file) super().print_help(file)
self.print_omniprompt_help(file) self.print_omniprompt_help(file)
self.print_general_info(file) self.print_general_info(file)
 End of changes. 10 change blocks. 
8 lines changed or deleted 38 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)