The Guru Site

Years ago a friend created a dummy search engine in the name of another friend as a bit of a prank. As vague as this statement is, I had the idea a while ago that it would be fun to recreate this site and restart the prank.

With a few different sites up and running I thought that I’d be in a position to be able to replicate it reasonably quickly and set myself the target of completing this within a week.

The project would give me the opportunity (in later versions) to play around with actual search engine coding, but for now I would just use some libraries to replicate a Google search. This wasn’t ideal given my De-Googling article, but let me get it up and running within my week target.

Scope

The approximate scope of this project was:

  • Create a website that could be used as an internet search site
  • Allow customised ‘splash text’ messages to be displayed with each search (randomly selected)
  • Allow for a customised search result bias (part of the prank, definitely not a good idea for a proper search engine!)

The following sections show only some parts of the process as there were some personal additions to the code in order to customise it for the friend.

Creating the site

The site was written using Python and, since I was already familiar, using the Flask web application framework.

After looking through a couple of tutorials and available packages I settled on using the Python google which offered a few simple configuration options and returned the search results as a list.

Flask layout

I created the Flask application using Blueprints (I always do this now, no matter if it’s a simple site or not) with a single blueprint called main. Once the app.__init__.py was set up for this, the latest Bootstrap version was cloned into the static folder and I then added in my custom scss into this and updated it for the latest version of Bootstrap.

This gave the following general layout:

..\guru-site\
│
├── app\
│   ├── main\
│   │   ├── routes.py
│   │   └── __init__.py
│   │
│   ├── static\
│   │   ├── bootstrap\
│   │   │   ├── css\
│   │   │   └── js\
│   │   │
│   │   └── scss\
│   │
│   ├── templates\
│   │   ├── base.html
│   │   └── index.html
│   │
│   └── __init__.py
│
├── logs\
│
├── .flaskenv
├── .gitignore
├── config.py
├── guru-site.py
└── requirements.txt

Search functionality

Within the main.py file there are two routes defined:

  • index()
  • search_result()

index

The index route renders the index page along with a WTForm that was given just two components:

  • search_query: a simple StringField component with the DataRequired() validator
  • submit: a SubmitField component

Within this route the Flask url_for method was given an additional argument q with the data from the search_query field to generate a URL like “https://search.mysite.com/search_result?q=myquery". This allowed the URL to be the source of the data, rather than passing data along with the request, keeping it cleaner and easier to read.

search_result

The search_result route was set up with no parameters input but instead uses the get args method from the request package to get the search query:

query = request.args.get('q', None, type=str)

The route then passes the query result into the google method and the search results list generate then gets passed to the search_result.html template.

Splash text

I wanted to be able to display a random message as splash text, chosen at random for each search query and displayed at the top of the page.

I created a separate file within the app folder that contained a list object (I found this easier to work with than a dict) with a list of different snippets to select at random from:

// splash_text.py

splash_text = [
    "Splash text 1",
    "Splash text 2",
    "Splash text n"
]

In the search_result route I then added the following code to the search_result route to select a random snippet from the splash_text object:

splash = splash_text[random.randrange(0, len(splash_text)-1)]

This splash object was then passed to the search_result.html template.

Search results bias

As part of the prank the search site had to be able to add a bias to the results and I wanted to do this be adding a configurable string to every search query.

This was done via an .env file that was added to the project which would have a variable that could be called when required.

This variable was appended to the query variable shown in the search_result section above and then passed onto a different call of the search method from the google package. This would be saved as a separate variable to the other search results so that it could be given prominence at the top of the search_result.html page.

Project completion

With the scope of the project covered, the final project was completed within a few days but was just the bare bones of a website. I spent a bit of time adding some flair to the page (and more prominence to the top_result!) so that it could be launched and used by the group of friends!

The final layout of the project is below:

..\guru-site\
│
├── app\
│   ├── main\
│   │   ├── forms.py
│   │   ├── routes.py
│   │   └── __init__.py
│   │
│   ├── static\
│   │   ├── bootstrap\
│   │   │   ├── css\
│   │   │   └── js\
│   │   │
│   │   └── scss\
│   │
│   ├── templates\
│   │   ├── base.html
│   │   ├── index.html
│   │   └── search_result.html
│   │
│   ├── splash_text.py
│   └── __init__.py
│
├── logs\
│
├── .env
├── .flaskenv
├── .gitignore
├── config.py
├── guru-site.py
└── requirements.txt

I will add a sanitised version of this search site to my website but it probably doesn’t make a whole lot of sense outwith the specific scope it started with!