Show client IP for "my ip" searches (#469)
This introduces a new UI element for displaying the client IP address when a search for "my ip" is used. Note that this does not show the IP address seen by Google if Whoogle is deployed remotely. It uses `request.remote_addr` to display the client IP address in the UI, not the actual address of the server (which is what Google sees in requests sent from remote Whoogle instances).main
parent
aff7b6c72f
commit
771bf34ce9
|
@ -8,17 +8,18 @@ import uuid
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import waitress
|
import waitress
|
||||||
from flask import jsonify, make_response, request, redirect, render_template, \
|
|
||||||
send_file, session, url_for
|
|
||||||
from requests import exceptions
|
|
||||||
|
|
||||||
from app import app
|
from app import app
|
||||||
from app.models.config import Config
|
from app.models.config import Config
|
||||||
from app.request import Request, TorError
|
from app.request import Request, TorError
|
||||||
from app.utils.bangs import resolve_bang
|
from app.utils.bangs import resolve_bang
|
||||||
from app.utils.misc import read_config_bool
|
from app.utils.misc import read_config_bool
|
||||||
from app.utils.session import generate_user_key, valid_user_session
|
from app.utils.results import add_ip_card
|
||||||
from app.utils.search import *
|
from app.utils.search import *
|
||||||
|
from app.utils.session import generate_user_key, valid_user_session
|
||||||
|
from bs4 import BeautifulSoup as bsoup
|
||||||
|
from flask import jsonify, make_response, request, redirect, render_template, \
|
||||||
|
send_file, session, url_for
|
||||||
|
from requests import exceptions
|
||||||
|
|
||||||
# Load DDG bang json files only on init
|
# Load DDG bang json files only on init
|
||||||
bang_json = json.load(open(app.config['BANG_FILE']))
|
bang_json = json.load(open(app.config['BANG_FILE']))
|
||||||
|
@ -250,6 +251,11 @@ def search():
|
||||||
# Return 503 if temporarily blocked by captcha
|
# Return 503 if temporarily blocked by captcha
|
||||||
resp_code = 503 if has_captcha(str(response)) else 200
|
resp_code = 503 if has_captcha(str(response)) else 200
|
||||||
|
|
||||||
|
# Feature to display IP address
|
||||||
|
if search_util.check_kw_ip():
|
||||||
|
html_soup = bsoup(response, "html.parser")
|
||||||
|
response = add_ip_card(html_soup, request.remote_addr)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'display.html',
|
'display.html',
|
||||||
query=urlparse.unquote(query),
|
query=urlparse.unquote(query),
|
||||||
|
@ -275,7 +281,8 @@ def search():
|
||||||
query=urlparse.unquote(query),
|
query=urlparse.unquote(query),
|
||||||
search_type=search_util.search_type,
|
search_type=search_util.search_type,
|
||||||
mobile=g.user_request.mobile)
|
mobile=g.user_request.mobile)
|
||||||
if 'isch' not in search_util.search_type else '')), resp_code
|
if 'isch' not in
|
||||||
|
search_util.search_type else '')), resp_code
|
||||||
|
|
||||||
|
|
||||||
@app.route('/config', methods=['GET', 'POST', 'PUT'])
|
@app.route('/config', methods=['GET', 'POST', 'PUT'])
|
||||||
|
|
|
@ -186,3 +186,7 @@ path {
|
||||||
.search-bar-desktop {
|
.search-bar-desktop {
|
||||||
color: var(--whoogle-dark-text) !important;
|
color: var(--whoogle-dark-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ip-text-div{
|
||||||
|
color: var(--whoogle-dark-secondary-text) !important;
|
||||||
|
}
|
||||||
|
|
|
@ -174,3 +174,7 @@ path {
|
||||||
color: var(--whoogle-text);
|
color: var(--whoogle-text);
|
||||||
border-bottom: 0px;
|
border-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ip-text-div{
|
||||||
|
color: var(--whoogle-secondary-text) !important;
|
||||||
|
}
|
||||||
|
|
|
@ -31,3 +31,11 @@ details summary {
|
||||||
height: 650px;
|
height: 650px;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ip-address-div {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ip-text-div {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
|
@ -138,3 +138,45 @@ def append_nojs(result: BeautifulSoup) -> None:
|
||||||
nojs_link.string = 'NoJS Link: ' + nojs_link['href']
|
nojs_link.string = 'NoJS Link: ' + nojs_link['href']
|
||||||
result.append(BeautifulSoup('<br><hr><br>', 'html.parser'))
|
result.append(BeautifulSoup('<br><hr><br>', 'html.parser'))
|
||||||
result.append(nojs_link)
|
result.append(nojs_link)
|
||||||
|
|
||||||
|
|
||||||
|
def add_ip_card(html_soup: BeautifulSoup, ip: str) -> BeautifulSoup:
|
||||||
|
"""Adds the client's IP address to the search results
|
||||||
|
if query contains keywords
|
||||||
|
|
||||||
|
Args:
|
||||||
|
html_soup: The parsed search result containing the keywords
|
||||||
|
ip: ip address of the client
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
BeautifulSoup
|
||||||
|
|
||||||
|
"""
|
||||||
|
if (not html_soup.select_one(".EY24We")
|
||||||
|
and html_soup.select_one(".OXXup").get_text().lower() == "all"):
|
||||||
|
# HTML IP card tag
|
||||||
|
ip_tag = html_soup.new_tag("div")
|
||||||
|
ip_tag["class"] = "ZINbbc xpd O9g5cc uUPGi"
|
||||||
|
|
||||||
|
# For IP Address html tag
|
||||||
|
ip_address = html_soup.new_tag("div")
|
||||||
|
ip_address["class"] = "kCrYT ip-address-div"
|
||||||
|
ip_address.string = ip
|
||||||
|
|
||||||
|
# Text below the IP address
|
||||||
|
ip_text = html_soup.new_tag("div")
|
||||||
|
ip_text.string = "Your public IP address"
|
||||||
|
ip_text["class"] = "kCrYT ip-text-div"
|
||||||
|
|
||||||
|
# Adding all the above html tags to the IP card
|
||||||
|
ip_tag.append(ip_address)
|
||||||
|
ip_tag.append(ip_text)
|
||||||
|
|
||||||
|
# Finding the element before which the IP card would be placed
|
||||||
|
f_link = html_soup.select_one(".BNeawe.vvjwJb.AP7Wnd")
|
||||||
|
ref_element = f_link.find_parent(class_="ZINbbc xpd O9g5cc" +
|
||||||
|
" uUPGi")
|
||||||
|
|
||||||
|
# Inserting the element
|
||||||
|
ref_element.insert_before(ip_tag)
|
||||||
|
return html_soup
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from bs4 import BeautifulSoup as bsoup
|
|
||||||
from cryptography.fernet import Fernet, InvalidToken
|
|
||||||
from flask import g
|
|
||||||
|
|
||||||
from app.filter import Filter, get_first_link
|
from app.filter import Filter, get_first_link
|
||||||
from app.request import gen_query
|
from app.request import gen_query
|
||||||
|
from bs4 import BeautifulSoup as bsoup
|
||||||
|
from cryptography.fernet import Fernet, InvalidToken
|
||||||
|
from flask import g
|
||||||
|
|
||||||
TOR_BANNER = '<hr><h1 style="text-align: center">You are using Tor</h1><hr>'
|
TOR_BANNER = '<hr><h1 style="text-align: center">You are using Tor</h1><hr>'
|
||||||
CAPTCHA = 'div class="g-recaptcha"'
|
CAPTCHA = 'div class="g-recaptcha"'
|
||||||
|
@ -54,6 +54,7 @@ class Search:
|
||||||
config: the current user config settings
|
config: the current user config settings
|
||||||
session: the flask user session
|
session: the flask user session
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, request, config, session, cookies_disabled=False):
|
def __init__(self, request, config, session, cookies_disabled=False):
|
||||||
method = request.method
|
method = request.method
|
||||||
self.request_params = request.args if method == 'GET' else request.form
|
self.request_params = request.args if method == 'GET' else request.form
|
||||||
|
@ -161,3 +162,14 @@ class Search:
|
||||||
link['href'] += param_str
|
link['href'] += param_str
|
||||||
|
|
||||||
return str(formatted_results)
|
return str(formatted_results)
|
||||||
|
|
||||||
|
def check_kw_ip(self) -> re.Match:
|
||||||
|
"""Checks for keywords related to 'my ip' in the query
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool
|
||||||
|
|
||||||
|
"""
|
||||||
|
return re.search("([^a-z0-9]|^)my *[^a-z0-9] *(ip|internet protocol)" +
|
||||||
|
"($|( *[^a-z0-9] *(((addres|address|adres|" +
|
||||||
|
"adress)|a)? *$)))", self.query.lower())
|
||||||
|
|
Loading…
Reference in New Issue