diff --git a/app/filter.py b/app/filter.py index 5e5ec01..8a30b12 100644 --- a/app/filter.py +++ b/app/filter.py @@ -91,9 +91,13 @@ class Filter: script.decompose() footer = soup.find('div', id='sfooter') - if footer is not None: + if footer: footer.decompose() + header = soup.find('header') + if header: + header.decompose() + return soup def remove_ads(self, soup): diff --git a/app/request.py b/app/request.py index 2b2e9ea..7ecd887 100644 --- a/app/request.py +++ b/app/request.py @@ -15,9 +15,7 @@ DESKTOP_UA = '{}/5.0 (X11; {} x86_64; rv:75.0) Gecko/20100101 {}/75.0' VALID_PARAMS = ['tbs', 'tbm', 'start', 'near'] -def gen_user_agent(normal_ua): - is_mobile = 'Android' in normal_ua or 'iPhone' in normal_ua - +def gen_user_agent(normal_ua, is_mobile): mozilla = random.choice(['Moo', 'Woah', 'Bro', 'Slow']) + 'zilla' firefox = random.choice(['Choir', 'Squier', 'Higher', 'Wire']) + 'fox' linux = random.choice(['Win', 'Sin', 'Gin', 'Fin', 'Kin']) + 'ux' @@ -66,8 +64,9 @@ def gen_query(query, args, config, near_city=None): class Request: def __init__(self, normal_ua, language='lang_en'): - self.modified_user_agent = gen_user_agent(normal_ua) self.language = language + self.mobile = 'Android' in normal_ua or 'iPhone' in normal_ua + self.modified_user_agent = gen_user_agent(normal_ua, self.mobile) def __getitem__(self, name): return getattr(self, name) diff --git a/app/routes.py b/app/routes.py index 348a352..bc6e01c 100644 --- a/app/routes.py +++ b/app/routes.py @@ -96,7 +96,7 @@ def autocomplete(): if not q: return jsonify({'results': []}) - return jsonify({'results': g.user_request.autocomplete(q)}) + return jsonify([q, g.user_request.autocomplete(q)]) @app.route('/search', methods=['GET', 'POST']) @@ -132,7 +132,14 @@ def search(): else: formatted_results = content_filter.clean(dirty_soup) - return render_template('display.html', query=urlparse.unquote(q), response=formatted_results) + return render_template( + 'display.html', + query=urlparse.unquote(q), + response=formatted_results, + search_header=render_template( + 'header.html', + q=urlparse.unquote(q), + mobile=g.user_request.mobile)) @app.route('/config', methods=['GET', 'POST']) diff --git a/app/static/css/header.css b/app/static/css/header.css new file mode 100644 index 0000000..c3eebf8 --- /dev/null +++ b/app/static/css/header.css @@ -0,0 +1,55 @@ +header { + font-family: Roboto,HelveticaNeue,Arial,sans-serif; + font-size: 14px; + line-height: 20px; + color: #3C4043; + word-wrap: break-word; +} + +.logo-link, .logo-letter { + text-decoration: none !important; + letter-spacing: -1px; + text-align: center; + border-radius: 2px 0 0 0; +} + +.mobile-logo { + font: 22px/36px Futura, Arial, sans-serif; + padding-left: 5px; +} + +.logo-div { + letter-spacing: -1px; + text-align: center; + font: 22pt Futura, Arial, sans-serif; + padding: 10px 0 5px 0; + height: 37px; + font-smoothing: antialiased; +} + +.search-div { + border-radius: 8px 8px 0 0; + box-shadow: 0 1px 6px rgba(32, 33, 36, 0.18); + margin-top: 10px; +} + +.search-form { + height: 39px; + display: flex; + width: 100%; +} + +.search-input { + background: none; + margin: 2px 4px 2px 8px; + display: block; + font-size: 16px; + padding: 0 0 0 8px; + flex: 1; + height: 35px; + outline: none; + border: none; + width: 100%; + -webkit-tap-highlight-color: rgba(0,0,0,0); + overflow: hidden; +} \ No newline at end of file diff --git a/app/static/js/autocomplete.js b/app/static/js/autocomplete.js index f65dd77..c5e2774 100644 --- a/app/static/js/autocomplete.js +++ b/app/static/js/autocomplete.js @@ -1,11 +1,29 @@ -function autocomplete(searchInput, autocompleteResults) { +const handleUserInput = searchBar => { + let xhrRequest = new XMLHttpRequest(); + xhrRequest.open("POST", "/autocomplete"); + xhrRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + xhrRequest.onload = function() { + if (xhrRequest.readyState === 4 && xhrRequest.status !== 200) { + alert("Error fetching autocomplete results"); + return; + } + + // Fill autocomplete with fetched results + let autocompleteResults = JSON.parse(xhrRequest.responseText); + autocomplete(searchBar, autocompleteResults[1]); + }; + + xhrRequest.send('q=' + searchBar.value); +}; + +const autocomplete = (searchInput, autocompleteResults) => { let currentFocus; searchInput.addEventListener("input", function () { let autocompleteList, autocompleteItem, i, val = this.value; closeAllLists(); - if (!val) { + if (!val || !autocompleteResults) { return false; } @@ -47,7 +65,7 @@ function autocomplete(searchInput, autocompleteResults) { } }); - function addActive(suggestion) { + const addActive = suggestion => { if (!suggestion || !suggestion[currentFocus]) return false; removeActive(suggestion); @@ -55,25 +73,26 @@ function autocomplete(searchInput, autocompleteResults) { if (currentFocus < 0) currentFocus = (suggestion.length - 1); suggestion[currentFocus].classList.add("autocomplete-active"); - } + }; - function removeActive(suggestion) { + const removeActive = suggestion => { for (let i = 0; i < suggestion.length; i++) { suggestion[i].classList.remove("autocomplete-active"); } - } + }; - function closeAllLists(el) { + const closeAllLists = el => { let suggestions = document.getElementsByClassName("autocomplete-items"); for (let i = 0; i < suggestions.length; i++) { if (el !== suggestions[i] && el !== searchInput) { suggestions[i].parentNode.removeChild(suggestions[i]); } } - } + }; // Close lists and search when user selects a suggestion document.addEventListener("click", function (e) { closeAllLists(e.target); + document.getElementById("search-form").submit(); }); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/app/static/js/controller.js b/app/static/js/controller.js index 6dbfc66..4817195 100644 --- a/app/static/js/controller.js +++ b/app/static/js/controller.js @@ -1,21 +1,3 @@ -const handleUserInput = searchBar => { - let xhrRequest = new XMLHttpRequest(); - xhrRequest.open("POST", "/autocomplete"); - xhrRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - xhrRequest.onload = function() { - if (xhrRequest.readyState === 4 && xhrRequest.status !== 200) { - alert("Error fetching autocomplete results"); - return; - } - - // Fill autocomplete with fetched results - let autocompleteResults = JSON.parse(xhrRequest.responseText); - autocomplete(searchBar, autocompleteResults["results"]); - }; - - xhrRequest.send('q=' + searchBar.value); -}; - const setupSearchLayout = () => { // Setup search field const searchBar = document.getElementById("search-bar"); diff --git a/app/templates/display.html b/app/templates/display.html index 03ed151..e66de6f 100644 --- a/app/templates/display.html +++ b/app/templates/display.html @@ -5,9 +5,13 @@ + + + {{ query }} - Whoogle Search + {{ search_header|safe }} {{ response|safe }} diff --git a/app/templates/header.html b/app/templates/header.html new file mode 100644 index 0000000..e106ffe --- /dev/null +++ b/app/templates/header.html @@ -0,0 +1,53 @@ +{% if mobile %} +
+
+
+ +
+
+ +
+
+
+
+
+
+{% else %} +
+
+ + Whoogle + +
+
+
+
+
+ +
+
+
+
+
+
+{% endif %} + + \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html index aab6a19..ab46526 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -28,7 +28,7 @@
-
+