diff --git a/README.md b/README.md index 83f11bf..964f343 100644 --- a/README.md +++ b/README.md @@ -256,18 +256,20 @@ There are a few optional environment variables available for customizing a Whoog ### Config Environment Variables These environment variables allow setting default config values, but can be overwritten manually by using the home page config menu. These allow a shortcut for destroying/rebuilding an instance to the same config state every time. -| Variable | Description | -| ----------------------- | --------------------------------------------------------------- | -| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country | -| WHOOGLE_CONFIG_LANGUAGE | Set interface and search result language | -| WHOOGLE_CONFIG_DARK | Enable dark theme | -| WHOOGLE_CONFIG_SAFE | Enable safe searches | -| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) | -| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) | -| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab | -| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only | -| WHOOGLE_CONFIG_URL | The root url of the instance (`https:///`) | -| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (must be single line) | +| Variable | Description | +| ----------------------- | --------------------------------------------------------------- | +| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country | +| WHOOGLE_CONFIG_LANGUAGE | Set interface and search result language | +| WHOOGLE_CONFIG_DARK | Enable dark theme | +| WHOOGLE_CONFIG_SAFE | Enable safe searches | +| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) | +| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) | +| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab | +| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option | +| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only | +| WHOOGLE_CONFIG_URL | The root url of the instance (`https:///`) | +| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (must be single line) | + ## Usage Same as most search engines, with the exception of filtering by time range. diff --git a/app/filter.py b/app/filter.py index 8f457f3..2ee51e7 100644 --- a/app/filter.py +++ b/app/filter.py @@ -253,3 +253,63 @@ class Filter: # Replace link destination link_desc[0].replace_with(get_site_alt(link_desc[0])) + + def view_image(self, soup) -> BeautifulSoup: + """Replaces the soup with a new one that handles mobile results. + + Args: + soup: A BeautifulSoup object containing the image mobile results. + + Returns: + BeautifulSoup: The new BeautifulSoup object + """ + with open("tmp.html", "w") as f: + f.write(soup.prettify()) + # get some tags that are unchanged between mobile and pc versions + search_input = soup.find_all('td', attrs={'class': "O4cRJf"})[0] + search_options = soup.find_all('div', attrs={'class': "M7pB2"})[0] + cor_suggested = soup.find_all('table', attrs={'class': "By0U9"}) + next_pages = soup.find_all('table', attrs={'class': "uZgmoc"})[0] + information = soup.find_all('div', attrs={'class': "TuS8Ad"})[0] + + results = [] + # find results div + results_div = soup.find_all('div', attrs={'class': "nQvrDb"})[0] + # find all the results + results_all = results_div.find_all('div', attrs={'class': "lIMUZd"}) + + for item in results_all: + urls = item.find('a')['href'].split('&imgrefurl=') + + img_url = urlparse.unquote(urls[0].replace('/imgres?imgurl=', '')) + webpage = urlparse.unquote(urls[1].split('&')[0]) + img_tbn = urlparse.unquote(item.find('a').find('img')['src']) + results.append({ + 'domain': urlparse.urlparse(webpage).netloc, + 'img_url': img_url, + 'webpage': webpage, + 'img_tbn': img_tbn + }) + + soup = BeautifulSoup(render_template('imageresults.html', + length=len(results), + results=results)) + # replace search input object + soup.find_all('td', + attrs={'class': "O4cRJf"})[0].replaceWith(search_input) + # replace search options object (All, Images, Videos, etc.) + soup.find_all('div', + attrs={'class': "M7pB2"})[0].replaceWith(search_options) + # replace correction suggested by google object if exists + if len(cor_suggested): + soup.find_all( + 'table', + attrs={'class': "By0U9"} + )[0].replaceWith(cor_suggested[0]) + # replace next page object at the bottom of the page + soup.find_all('table', + attrs={'class': "uZgmoc"})[0].replaceWith(next_pages) + # replace information about user connection at the bottom of the page + soup.find_all('div', + attrs={'class': "TuS8Ad"})[0].replaceWith(information) + return soup diff --git a/app/models/config.py b/app/models/config.py index b2ebc57..5dbb80b 100644 --- a/app/models/config.py +++ b/app/models/config.py @@ -18,6 +18,7 @@ class Config: self.tor = bool(os.getenv('WHOOGLE_CONFIG_TOR', False)) self.near = os.getenv('WHOOGLE_CONFIG_NEAR', '') self.new_tab = bool(os.getenv('WHOOGLE_CONFIG_NEW_TAB', False)) + self.view_image = bool(os.getenv('WHOOGLE_CONFIG_VIEW_IMAGE', False)) self.get_only = bool(os.getenv('WHOOGLE_CONFIG_GET_ONLY', False)) self.safe_keys = [ 'lang_search', diff --git a/app/request.py b/app/request.py index 4cd9fcf..0752f9a 100644 --- a/app/request.py +++ b/app/request.py @@ -147,6 +147,8 @@ class Request: self.language = config.lang_search self.mobile = 'Android' in normal_ua or 'iPhone' in normal_ua self.modified_user_agent = gen_user_agent(self.mobile) + if not self.mobile: + self.modified_user_agent_mobile = gen_user_agent(True) # Set up proxy, if previously configured if os.environ.get('WHOOGLE_PROXY_LOC'): @@ -193,7 +195,8 @@ class Request: return [_.attrib['data'] for _ in root.findall('.//suggestion/[@data]')] - def send(self, base_url=SEARCH_URL, query='', attempt=0) -> Response: + def send(self, base_url=SEARCH_URL, query='', attempt=0, + force_mobile=False) -> Response: """Sends an outbound request to a URL. Optionally sends the request using Tor, if enabled by the user. @@ -207,8 +210,13 @@ class Request: Response: The Response object returned by the requests call """ + if force_mobile and not self.mobile: + modified_user_agent = self.modified_user_agent_mobile + else: + modified_user_agent = self.modified_user_agent + headers = { - 'User-Agent': self.modified_user_agent + 'User-Agent': modified_user_agent } # FIXME: Should investigate this further to ensure the consent diff --git a/app/templates/imageresults.html b/app/templates/imageresults.html new file mode 100644 index 0000000..b1c7e6d --- /dev/null +++ b/app/templates/imageresults.html @@ -0,0 +1,119 @@ + + + + + + + + + + + +
+
+ + Google + +
+
+
+ + + + + + + + + + + +
+ + + +
+
+
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+ + {% for i in range(length // 4) %} + + {% for j in range(4) %} + + {% endfor %} + + {% endfor %} +
+ +
+
+ + +
+
+
+ +
+
+ + \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index c49943e..c8ac885 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -118,6 +118,12 @@
+
+ + +
— Adds the View Image option. + The thumbnails are blurry because mobile thumbnails are smaller.
+
diff --git a/app/utils/search.py b/app/utils/search.py index b71e6dd..9328229 100644 --- a/app/utils/search.py +++ b/app/utils/search.py @@ -120,11 +120,20 @@ class Search: self.request_params, self.config, content_filter.near) - get_body = g.user_request.send(query=full_query) + + # force mobile search when view image is true + view_image = 'tbm=isch' in full_query and self.config.view_image + + get_body = g.user_request.send(query=full_query, + force_mobile=view_image) # Produce cleanable html soup from response html_soup = bsoup(content_filter.reskin(get_body.text), 'html.parser') + # Replace current soup if view_image is active + if view_image: + html_soup = content_filter.view_image(html_soup) + # Indicate whether or not a Tor connection is active tor_banner = bsoup('', 'html.parser') if g.user_request.tor_valid: