Random Motivational Quotes - Linux Mint Fortunes

From this article you can learn how to use Fortune for random quotes on your desktop - scrap quotes, create multiple fortune databases and select from random database each day.

Fortune is Linux (Unix) program which display "random" messages from a local database. In most cases the program is used to show random quotations and show them on your Desktop or on your shell. For Linux Mint there is a desklet which can show quotes on your desktop - Quote of the Day Cinnamon Desklet.

Personally I'm using it for motivational and favorite quotes from my recently read books. Another use case is when I need to force myself doing something which I don't like or constantly forget. In this way it will be always in front of my eyes.

Example of this morning cookie:

linux_mint_fortunes_random_quote

Add Custom Fortunes to Linux Mint desktop

In order to add Quote of the Day Cinnamon Desklet to Linux Mint you need to follow these steps:

  • Right click on your desktop
  • Add desklets
  • Tab Download
  • Search for Quote
  • Download Quote of the Day Cinnamon Desklet

Once the program is added to your system you need to configure it. The configuration is simple enough and straight forward but I'll cover some steps:

  1. Input file - In order to prepare fortune file you need to get the quotes. You can get them either manually or by scraping the information (check next section). Once you have the quotes you need to save them in next format:

    Action brings clarity.
    %
    Just do it!

Quotations should be divided by percentage sign.

Let say that the file above is named action.txt. Next step is to create .dat file which is required by the program:

strfile -c % action.txt action.txt.dat

Now you have both files action.txt and action.txt.dat.

  • Right click the program window
  • select configure
  • Click File: and find file: action.txt

After this change text from the cookies should appear in the window otherwise there is a problem with you files.

  1. Update every: (minutes) - I prefer update on every 30 minutes. Some people report problems related to frequently changing quotes. On Linux Mint 19.2 I don't have such problem.
  2. Font - I prefer bigger font sizes like 15
  3. Font Color - White
  4. Shadow Color - Black

linux_mint_fortunes_example

How to collect cookie fortunes

There many different ways of collecting fortune cookies from the web and sources. I'll cover the most basic ones.

Quick remainder for web scraping - respect web sites, their restrictions and data. Don't do anything which is not legal.

Using browser based scraper

Let say that you want to extract quotes from this page: Popular Quotes

You can do it very quickly by using chrome extension: Scraper

  • Add the extension to Chrome (from the above link)
  • Restart Chrome if needed
  • Open the page in the browser
  • Right click on the quote ( from the page with quotes )
  • Select Scrape similar...
  • Enter for XPath
    • //div[contains(@class, 'quoteText')]
  • Press button Scrape (bottom left)
  • Copy to clipboard

collect_fortune_quotes_goodreads

As you can see some quotes have bad data inside so you may need to work furher on the quality or collect quotes by hand.

Using Python scraper - scrapy

Another very popular way is by using python scraper. There are plenty of options for scraping data from the web with python and also projects. Below you can find example of scrapy code (it's very basic one and needs many improvements):


class QuotesSpider(scrapy.Spider):
    name = "quotes_spider"
    start_urls = [        "https://www.goodreads.com/quotes"    ]

    def parse(self, response):
        list_selector = "//div[contains(@class, 'quoteText')]"
        for article in response.xpath(list_selector):

            quote = "::text"

            if article.extract():
                yield {
                    "quote": article.css(quote).extract()[0],
                    "author": article.css(quote).extract()[2]
                }

result:

{'quote': '\n      “Be yourself; everyone else is already taken.”\n  ', 'author': '\n    Oscar Wilde\n  '}
{'quote': "\n      “Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.”\n  ", 'author': '\n    Albert Einstein\n  '}

Fortunes with beautiful soup

This is another simplified option for good reads with beautiful soup:

import requests
from bs4 import BeautifulSoup

website_url = requests.get("https://www.goodreads.com/quotes").text
soup = BeautifulSoup(website_url, 'html.parser')

quotes = soup.find_all('div', {'class': 'quoteText'})

for quote in quotes:
    if quote.text is not None:
        strings = [string for string in quote.stripped_strings]
        quote_body = strings[0]
        quote_author = strings[2]
        print(quote_body)
        print(quote_author)

result:

“I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.”
Marilyn Monroe
%
“Be yourself; everyone else is already taken.”
Oscar Wilde
%
Fortunes with Java/Groovy
pages = [
		"https://www.goodreads.com/author/quotes/58.Frank_Herbert?page=1",
]


def all_quotes = []
pages.each {page->
	def quotes = s.articleScrapper(page, "div", "quoteText")
	all_quotes += quotes
}

Where articleScrapper method is something like:

def articleScrapper(def page, def tag, def cssClass) {

		def listOut = []

		System.setProperty("webdriver.gecko.driver","/home/user/webdriver/geckodriver-v0.18.0-win64/geckodriver");
		Browser.drive {
			def selector
			if (cssClass == "") {
				selector = tag
			} else {
				selector = tag + "." + cssClass
			}
			go "${page}"
            
            $("${selector}").findAll { it1 ->
				listOut << it1.text()
			}

		}
		return listOut
	}

result:

“There is no real ending. It’s just the place where you stop the story.”― Frank Herbert
%
“Seek freedom and become captive of your desires. Seek discipline and find your liberty.”― Frank Herbert, Chapterhouse: Dune
%

Create .dat files for several fortune files

In order to create .dat files for multiple fortune text files you can use the script below(you must be in the same folder as the text files:

find . -type f -name '*.txt' |     while IFS= read file_name; do         strfile -c % "$file_name" "$file_name".dat;     done    

or pretty printed script:

find . -type f -name '*.txt' |
    while IFS= read file_name; do
        strfile -c % "$file_name" "$file_name".dat;
    done

Explanation how it works:

  • List all text files in the current folder with find:
find "$(pwd)" -name "*.txt"
  • Convert one file with strfile
strfile -c % zen.txt zen.txt.dat
  • Pipe two commands and do something in the second with the output of the first:
find . -type f -name 'file*' -print0 | strfile -c % print0 print0

Select Random Fortune database each day

The final step in this article is for people who really like the random and chaos like he. So let say that you have several different topics for fortunes or several text files with quotes like:

  • action.txt
  • dune.txt
  • zen.txt

If you want to choose randomly from this pool with fortunes then you can use the next script:

Assumptions:

  • fortunes are placed in folder - /home/user/Documents/Fortunes/
  • all files ends with .txt extension
  • dat files are created for all files (previous section)
  • default folder for configs is not changed: /home/user/.cinnamon/configs/quoteOfTheDay@tinnu

script:

#!/bin/bash
FORTUNES=/home/user/Documents/Fortunes/
cd $FORTUNES
ls *.txt |sort -R |tail -1 |while read file; do
	echo "file:///$FORTUNES$file"
	FORTUNE_DAY=file:///$FORTUNES$file
	cd /home/user/.cinnamon/configs/quoteOfTheDay@tinnu
	jq -r ".file.value |= \"$FORTUNE_DAY\"" quoteOfTheDay@tinnu.json_bak > quoteOfTheDay@tinnu.json
done
  • Create random_fortunes_day.sh file with the above content
  • Make it executable ( by right click on the file or with termnial)
  • Add this line to your cron job:
    • crontab -e - in terminal
    • add this line at the end: @reboot /home/user/ScriptS/cron/random_fortunes_day.sh

Related Article