I came up with the idea to use a good 'ole Raspberry Pi and I figured there must be some way to go on the internet, grab the appropriate TV schedule and then read it out through an amplified speaker, I decided that I also needed an easy to use and chunky control system, finally all of this would need to be in a nice enclosure.


Software Overview :-

I spent some time in a famous search engine and came across a couple of web services (and some inspiration from a couple of other projects) that would allow me to make my dream a reality!

I found a web service called "Atlas" which is provided by a UK company called Metabroadcast, it allows you to make a formatted request and then returns JSON formatted schedule data, another request then retrieves the appropriate content JSON data.

http://atlas.metabroadcast.com/#apiExplorer

So, given that I could get the content title, description, showing times etc. for a particular channel I figured all I needed to do now was get a text to speech service to read my formatted text aloud, I did look at some open source TTS programs for the RPi but then realised that I could just use the free Google Translate service to do the talking for me.

I've never written Python before but I'm a developer anyway so with a bit of web-reading I was able to cobble something together, it uses an SQLite database to store the settings and the JSON data that is retrieved from Atlas (I know storing JSON data in a database isn't exactly cool but it was easier for this purpose).

This JSON data is then parsed and a text phrase is sent to Google Translate. The audio from Google Translate is in turn saved as an MP3 and played using mpg123. I actually "cache" the audio files (I give them a unique filename and look for them before going to Google Translate) so that the system isn't constantly going online to get the phrase audio if it already exists.

All of this is controlled by the action of a keypress, when my main loop sees the number 1 it executes one function, when it sees number 2 it executes another etc. etc.

I came across a couple of projects that helped me to write the code for this project I've linked to them below and offer my heartfelt thanks to the authors for sharing their knowledge!


Hardware :-

- The CPU

- The Controller

To make the controller I took apart a USB keyboard and then used my meter (and eyes/patience) to follow the membrane traces back to the control board, by doing this I could deduce which 2 wires needed to be connected together to press a particular key. These were then in turn soldered to a button and mounted in a plastic enclosure.

I won't go into the construction it's pretty self-explanatory from the pictures and youtube video!


Linux Prerequisites :-

The following linux packages must be installed :-

sudo apt-get install python-pip
sudo apt-get install mpg123
sudo apt-get install ffmpeg
sudo pip install simplejson
sudo pip install python-dateutil
sudo apt-get install sqlite3

Folder Structure :-

The python files must be placed within a folder the path to which is set in the "EVA.py" script and is then passed as a parameter to the various functions, there must also be the following subfolders within the main folder :-


SQLite Database :-

You must create an SQLite database in the \data folder called "atlasdata.db" the table structures are as such :-

settings (settingid TEXT, settingvalue TEXT)

schedulelist (scheduleid TEXT, scheduletitle TEXT, scheduletype TEXT, listorder INTEGER, selected INTEGER)

timelist (timeid TEXT, timetitle TEXT, selected INTEGER)

daylist (dayid TEXT, daytitle TEXT, selected INTEGER)

These can be created from the SQLite command line.


Code :-

I got my inspiration for the Google Translate code from these 2 projects and would very much like to thank the authors -

http://www.daveconroy.com/turn-raspberry-pi-translator-speech-recognition-playback-60-languages/

https://github.com/hungtruong/Google-Translate-TTS

Here is my code, please be gentle I've never written Python before, sorry this isn't on Github I've not gotten around to creating an account, maybe i'll do it if I make a habit of sharing code...

"EVA.py" (the main program)

# My Modules
import GoogleTTS
import Atlas4API
import SettingsAndInit

# Python Modules
import os, sys, termios, tty
from datetime import datetime, timedelta

# Function that reads input characters
def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

# Function that gets a reads out schedule based on current settings
def readtheschedule():

    # Get Changeable Settings From The Database
        AtlasScheduleID = SettingsAndInit.GetSelectedScheduleID(Main_App_Path)
        AtlasScheduleDate = SettingsAndInit.GetSelectedDate(Main_App_Path)
        AtlasScheduleFrom = SettingsAndInit.GetSelectedFromTime(Main_App_Path, AtlasScheduleDate)
        AtlasScheduleTo =  SettingsAndInit.GetSelectedToTime(Main_App_Path, AtlasScheduleDate)
        ReadContentDescription = bool(int(SettingsAndInit.GetSetting(Main_App_Path, 'ReadContentDescription')))

        AtlasURL = "http://atlas.metabroadcast.com/4/schedules/" + AtlasScheduleID + ".json?"

     # Build the request
        AtlasRequest = "from=" + datetime.strftime(AtlasScheduleDate, "%Y-%m-%d") + "T" + datetime.strftime(AtlasScheduleFrom, "%H:%M") + ":00.000Z"
        AtlasRequest = AtlasRequest + "&to=" + datetime.strftime(AtlasScheduleDate, "%Y-%m-%d") + "T" + datetime.strftime(AtlasScheduleTo, "%H:%M") + ":00.000Z"
        AtlasRequest = AtlasRequest + "&source=pressassociation.com&annotations=channel,channels,channel_summary"

        # Build the schedule data file name
        AtlasScheduleUniqueID = AtlasScheduleID + "_"
        AtlasScheduleUniqueID = AtlasScheduleUniqueID + datetime.strftime(AtlasScheduleDate, "%y-%m-%d") + "_"
        AtlasScheduleUniqueID = AtlasScheduleUniqueID + datetime.strftime(AtlasScheduleFrom, "%H:%M") + ":00.000Z"
        AtlasScheduleUniqueID = AtlasScheduleUniqueID + datetime.strftime(AtlasScheduleTo, "%H:%M") + ":00.000Z"

     # Download the Atlas Schedule data if required
        # try 10 times in case of retrieval errors
        blnscheduleretrieved = False
        for getschedule in xrange(1, 10):
                print "Get schedule, attempt " + str(getschedule) + " of 10."
                if Atlas4API.getAtlasScheduleDataSQLDB(AtlasScheduleUniqueID, AtlasURL + AtlasRequest, AtlasAPIKey, Main_App_Path) == True:
                        blnscheduleretrieved = True
                        break
        # If we successfully get the schedule data try to get the content data
        if blnscheduleretrieved == True:
                # Download all the Atlas Schedule Content data if required
                # try 10 times in case of retrieval errors
                blncontentretrieved = False
                for getcontent in xrange(1, 10):
                        print "Get content, attempt " + str(getcontent) + " of 10."
                        if Atlas4API.getAtlasAllScheduleContentDataSQLDB(AtlasScheduleUniqueID, AtlasAPIKey, Main_App_Path, ReadContentDescription) == True:
                                blncontentretrieved = True
                                break
                if blncontentretrieved == True:
                        print "content ok????"
                        Atlas4API.readScheduleContentSQLDB(AtlasScheduleUniqueID, AtlasScheduleID, AtlasScheduleDate, Main_App_Path, ReadContentDescription)
                else:
                        GoogleTTS.speakPhrase(Main_App_Path, "There was an error retrieving the content data, please try again.", "general", "contentretrievalerror", False)
        else:
                GoogleTTS.speakPhrase(Main_App_Path, "There was an error retrieving the schedule data, please try again.", "general", "scheduleretrievalerror", False)

    

# Main Loop
if __name__ == "__main__":

    # Define/Get Constant Settings
    Main_App_Path = '/usbdrive/eva/'
    AtlasAPIKey = SettingsAndInit.GetSetting(Main_App_Path, 'AtlasAPIKey')

    #Say Welcome Message
    GoogleTTS.speakPhrase(Main_App_Path, "Hello George. I am your Electronic Voice Assistant. You can call me Eva for short.", "general", "welcome", False)
    
    # Main Loop
    while(True):
            char = getch()
            print 'the char pressed was - ' + char
            if char == 'q':
            GoogleTTS.speakPhrase(Main_App_Path, "Goodbye! Thank-you for using Eva.", "general", "goodbye", False)
            print 'QUIT'
                    break
        elif char == 'x':
            GoogleTTS.speakPhrase(Main_App_Path, "Initialsing Settings", "general", "initsettings", False)
            SettingsAndInit.initSettings(Main_App_Path)
            elif char == '1':
                    SettingsAndInit.toggleSelectedSchedule(Main_App_Path)
        elif char == '2':
            SettingsAndInit.toggleSelectedDay(Main_App_Path)
        elif char == '3':
                        SettingsAndInit.toggleSelectedTimeRange(Main_App_Path)
        elif char == '4':
                    SettingsAndInit.toggleReadContentDescription(Main_App_Path)
        elif char == '5':
                        SettingsAndInit.readCurrentSettings(Main_App_Path)
        elif char == '6':
            print 'CHANGEMODE'
        elif char == '9':
            GoogleTTS.speakPhrase(Main_App_Path, "Powering down. Thank-you for using EVA.", "general", "shutdown", False)
            print 'SHUTDOWN'
            os.system("sudo halt")
            break
        elif char == '0':
            readtheschedule()

"Atlas4API.py" (the Atlas comms code)

import GoogleTTS
import simplejson as json
import urllib
import urllib2
import dateutil.parser
import os
import sys
from datetime import datetime, timedelta
import sqlite3


# SQLite Functions
#----------------------------------------------------------------------------------------------------
def getAtlasScheduleDataSQLDB(uniqueScheduleID, AtlasScheduleRequestURL, AtlasAPIKey, app_path):
    # scheduledata (scheduleid TEXT, scheduledata TEXT);
    
    SQLDBFileName = app_path + "data/atlasdata.db"

    print uniqueScheduleID
    # Check to see if there is an Atlas Schedule data record
    # If not then Write the Atlas schedule request data to a new record
    conn = sqlite3.connect(SQLDBFileName)
    curs = conn.cursor()
    curs.execute("SELECT COUNT(rowid) FROM scheduledata WHERE scheduleid=?", (uniqueScheduleID,))
    data = curs.fetchone()

    if int(data[0]) <> 0:
        print "schedule data " + uniqueScheduleID + " exists in the database."
        return True
    else:
        print "schedule data " + uniqueScheduleID + " does not exist in the database."
        print AtlasScheduleRequestURL
        GoogleTTS.speakPhrase(app_path, "Please wait. Collecting schedule data.", "general", "collectingscheduledata", False)
        
        blncollectedschedule = True
        try: 
            response = json.load(urllib2.urlopen(AtlasScheduleRequestURL  + "&key=" + AtlasAPIKey))
        except urllib2.HTTPError, e:
            print 'HTTPError = ' + str(e.code)
            blncollectedschedule = False
        except urllib2.URLError, e:
            print 'URLError = ' + str(e.reason)
            blncollectedschedule = False
        except httplib.HTTPException, e:
            print 'HTTPException'
            blncollectedschedule = False
        except Exception:
            import traceback
            print 'generic exception: ' + traceback.format_exc()
            blncollectedschedule = False
        finally:
            if blncollectedschedule == True:
                jsondata = json.dumps(response)
                curs.execute("INSERT INTO scheduledata VALUES (?,?)", (uniqueScheduleID, jsondata))
                conn.commit()
    
    conn.close()                    
    return blncollectedschedule



#-----------------------------------------------------------------------------------------------------
def getAtlasAllScheduleContentDataSQLDB(uniqueScheduleID, AtlasAPIKey, app_path, blnDescription):
    # scheduledata (scheduleid TEXT, scheduledata TEXT);    
    # contentdata (contentid TEXT, contentdata TEXT);

    SQLDBFileName = app_path + "data/atlasdata.db"

    # Loop through the Atlas Schedule data checking for content
    # If they don't exists create then
    conn = sqlite3.connect(SQLDBFileName)
    curs = conn.cursor()
    curs.execute("SELECT scheduledata FROM scheduledata WHERE scheduleid=?", (uniqueScheduleID,))
    data = curs.fetchone()

    ScheduleData = json.loads(data[0])
    
    noofitems = len(ScheduleData['schedule']['entries'])
    noofexistingitems = 0
    
    
    # if blnDescription is true then delete all content data and re-fetch
    #  the data as content descriptions will change whereas content title won't
    # otherwise just check if they exist and fetch where they don't
    if blnDescription == True:
        for n in range(0, noofitems):
            AtlasContentID = ScheduleData['schedule']['entries'][n]['item']['id']
            curs.execute("DELETE FROM contentdata WHERE contentid=?", (AtlasContentID,))
            conn.commit()

        noofexistingitems = 0
    else:
        for n in range(0, noofitems):
            AtlasContentID = ScheduleData['schedule']['entries'][n]['item']['id']
            curs.execute("SELECT COUNT(rowid) FROM contentdata WHERE contentid=?", (AtlasContentID,))
            data = curs.fetchone()

            if int(data[0]) <> 0:
                noofexistingitems += 1

    if noofexistingitems != noofitems:
        GoogleTTS.speakPhrase(app_path, "Please wait. Collecting content data.", "general", "collectingcontentdata", False)

    
    # Now fetch the content and create a record
    blncollectedallcontent = True
    for n in range(0, noofitems):
        AtlasContentID = ScheduleData['schedule']['entries'][n]['item']['id']
        curs.execute("SELECT COUNT(rowid) FROM contentdata WHERE contentid=?", (AtlasContentID,))
        data = curs.fetchone()

        if int(data[0]) <> 0:
            print "content data " + AtlasContentID + " exists in the database."
        else:
            print "content data " + AtlasContentID + " does not exist in the database."
            # make an Atlas request for the content
            AtlasContentRequestURL = "http://atlas.metabroadcast.com/4/content/" + AtlasContentID + ".json?annotations=description&key=" + AtlasAPIKey
            print AtlasContentRequestURL
            
            try: 
                response = json.load(urllib2.urlopen(AtlasContentRequestURL))
            except urllib2.HTTPError, e:
                print 'HTTPError = ' + str(e.code)
                blncollectedallcontent = False
            except urllib2.URLError, e:
                print 'URLError = ' + str(e.reason)
                blncollectedallcontent = False
            except httplib.HTTPException, e:
                print 'HTTPException'
                blncollectedallcontent = False
            except Exception:
                import traceback
                print 'generic exception: ' + traceback.format_exc()
                blncollectedallcontent = False
            finally:
                if blncollectedallcontent == True:
                    jsondata = json.dumps(response)
                    curs.execute("INSERT INTO contentdata VALUES (?,?)", (AtlasContentID, jsondata))
                    conn.commit()                    
    

    conn.close()    
    return blncollectedallcontent



#------------------------------------------------------------------------------------------------------------
def readScheduleContentSQLDB(uniqueScheduleID, AtlasScheduleID, ScheduleDate, app_path, blnDescription):
    # scheduledata (scheduleid TEXT, scheduledata TEXT);    
    # contentdata (contentid TEXT, contentdata TEXT);

    SQLDBFileName = app_path + "data/atlasdata.db"

    # Load the Atlas schedule data from the database
    conn = sqlite3.connect(SQLDBFileName)
    curs = conn.cursor()
    curs.execute("SELECT scheduledata FROM scheduledata WHERE scheduleid=?", (uniqueScheduleID,))
    data = curs.fetchone()

    ScheduleData = json.loads(data[0])

    # Get no of content items, channel name, start and end times
    noofitems = len(ScheduleData['schedule']['entries'])

    # if there are no listings just say so
    if noofitems == 0:
        print "no listings :("
        GoogleTTS.speakPhrase(app_path, "There are no listings", "general", "nolistings", False)
    else:        
        channeltitle = ScheduleData['schedule']['channel']['title']
        schedulestarttime = datetime.strftime(dateutil.parser.parse(ScheduleData['schedule']['entries'][0]['broadcast']['transmission_time']), "%I:%M%p")
        scheduleendtime = datetime.strftime(dateutil.parser.parse(ScheduleData['schedule']['entries'][noofitems - 1]['broadcast']['transmission_end_time']), "%I:%M%p")

        strPhrase = "There are " + str(noofitems) + " programs for " + channeltitle
        strPhrase = strPhrase + " on " + datetime.strftime(ScheduleDate, "%A") + " the " + datetime.strftime(ScheduleDate, "%d %B") 
        strPhrase = strPhrase + " between " + schedulestarttime + " and " + scheduleendtime + "."

        print strPhrase
        GoogleTTS.speakPhrase(app_path, strPhrase, "schedule", uniqueScheduleID, False)

        # loop through the items (content)
        for n in range(0, noofitems):
            # Get content id and format the time
            AtlasContentID = ScheduleData['schedule']['entries'][n]['item']['id']
            contentstarttime = datetime.strftime(dateutil.parser.parse(ScheduleData['schedule']['entries'][n]['broadcast']['transmission_time']), "%I:%M%p")
         
            # Load Atlas content data from the database
            curs.execute("SELECT contentdata FROM contentdata WHERE contentid=?", (AtlasContentID,))
            data = curs.fetchone()

            ContentData = json.loads(data[0])

            # Loop through content data saying each phrase                
            for key, value in ContentData.iteritems():
                if str(key) == 'film':
                    strPhrase = contentstarttime + ", Movie.. " + value['title'] + "."
                    if blnDescription == True:
                        if value['description'] != 'None':
                            strPhrase = strPhrase + value['description']

                elif str(key) == 'episode':
                    strPhrase = contentstarttime + ", " + value['display_title']['title'] + "."
                    if blnDescription == True:
                        if str(value['description']) != 'None':
                            strPhrase = strPhrase + str(value['description'])
                else:
                    strPhrase = contentstarttime + ", " + value['title'] + "."
                    if blnDescription == True:
                        if value['description'] != 'None':
                            strPhrase = strPhrase + value['description']

                print AtlasContentID + " - " + strPhrase

                if blnDescription == True:
                    GoogleTTS.speakPhrase(app_path, strPhrase, "content", AtlasContentID + "_" + contentstarttime + "_desc", True)
                else:
                    GoogleTTS.speakPhrase(app_path, strPhrase, "content", AtlasContentID + "_" + contentstarttime, False)


        
        conn.close()        
        GoogleTTS.speakPhrase(app_path, "That concludes the listings.", "general", "listingsconcluded", False)

"GoogleTTS.py" (the Google Translate comms code)

import os
import sys
import re
import urllib, urllib2
import time
from collections import namedtuple
import subprocess


def speakPhrase(app_path, phrase, phrasetype, phraseid, forceoverwrite):

    # Build MP3 output filename
    MP3FileName = app_path + "audio/" + phrasetype + "/" + phraseid + ".mp3"
    #MP3FileName = os.path.realpath(__file__) 
    #MP3FileName = MP3FileName[:len(MP3FileName) - len(__file__)]
    #MP3FileName = MP3FileName + "audio/" + phrasetype + "/" + phraseid + ".mp3"

    
    if os.path.isfile(MP3FileName) and forceoverwrite == False:
        print "MP3 audio file " + MP3FileName + " exists"
    else:
        print "MP3 audio file " + MP3FileName + " does not exist or force overwrite"

        output=open(MP3FileName, 'w')

        #process phrase into chunks
        #Google TTS only accepts up to (and including) 100 characters long texts.
        #Split the text in segments of maximum 100 characters long.
        combined_text = split_text(phrase)

        #download chunks and write them to the output file
        for idx, val in enumerate(combined_text):
            mp3url = "http://translate.google.com/translate_tts?tl=%s&q=%s&total=%s&idx=%s" % (
                'en',
                urllib.quote(val),
                len(combined_text),
                idx)
            headers = {"Host": "translate.google.com",
                   "Referer": "http://www.gstatic.com/translate/sound_player2.swf",
                   "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) "
                         "AppleWebKit/535.19 (KHTML, like Gecko) "
                         "Chrome/18.0.1025.163 Safari/535.19"
            }
            req = urllib2.Request(mp3url, '', headers)
            sys.stdout.write('.')
            sys.stdout.flush()
        
            if len(val) > 0:
                try:
                    response = urllib2.urlopen(req)
                    output.write(response.read())
                    time.sleep(.5)
                except urllib2.URLError as e:
                    print ('%s' % e)
        output.close()
        print('MP3 audio file ' + MP3FileName + ' created.')
    
    subprocess.call(["mpg123", MP3FileName], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
   


def split_text(input_text, max_length=100):
    """
    Try to split between sentences to avoid interruptions mid-sentence.
    Failing that, split between words.
    See split_text_rec
    """
    def split_text_rec(input_text, regexps, max_length=max_length):
        """
        Split a string into substrings which are at most max_length.
        Tries to make each substring as big as possible without exceeding
        max_length.
        Will use the first regexp in regexps to split the input into
        substrings.
        If it it impossible to make all the segments less or equal than
        max_length with a regexp then the next regexp in regexps will be used
        to split those into subsegments.
        If there are still substrings who are too big after all regexps have
        been used then the substrings, those will be split at max_length.

        Args:
            input_text: The text to split.
            regexps: A list of regexps.
                If you want the separator to be included in the substrings you
                can add parenthesis around the regular expression to create a
                group. Eg.: '[ab]' -> '([ab])'

        Returns:
            a list of strings of maximum max_length length.
        """
        if(len(input_text) <= max_length): return [input_text]

        #mistakenly passed a string instead of a list
        if isinstance(regexps, basestring): regexps = [regexps]
        regexp = regexps.pop(0) if regexps else '(.{%d})' % max_length

        text_list = re.split(regexp, input_text)
        combined_text = []
        #first segment could be >max_length
        combined_text.extend(split_text_rec(text_list.pop(0), regexps, max_length))
        for val in text_list:
            current = combined_text.pop()
            concat = current + val
            if(len(concat) <= max_length):
                combined_text.append(concat)
            else:
                combined_text.append(current)
                #val could be >max_length
                combined_text.extend(split_text_rec(val, regexps, max_length))
        return combined_text

    return split_text_rec(input_text.replace('\n', ''),
                          ['([\,|\.|;]+)', '( )'])

"SettingsAndInit.py" (settings and initialisation functions)

import GoogleTTS

import os
import sqlite3
from datetime import datetime, timedelta


# TABLE STRUCTURES
# settings (settingid TEXT, settingvalue TEXT)
# schedulelist (scheduleid TEXT, scheduletitle TEXT, scheduletype TEXT, listorder INTEGER, selected INTEGER)
# timelist (timeid TEXT, timetitle TEXT, selected INTEGER);
# daylist (dayid TEXT, daytitle TEXT, selected  INTEGER);


# scheduledata (scheduleid TEXT, scheduledata TEXT);
# contentdata (contentid TEXT, contentdata TEXT);


#--------------------------
def initSettings(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()

	# Settings
	curs.execute("DELETE FROM settings")
	conn.commit()
	settings = [
		('AtlasAPIKey', 'c1e92985ec124202b7f07140bcde6e3f'),
		('ReadContentDescription', 0),
	]
	curs.executemany('INSERT INTO settings VALUES (?,?)', settings)
	conn.commit()


	# Schedule List
	curs.execute("DELETE FROM schedulelist")
	conn.commit()
	schedules = [
		('hkrd', 'BBC1', 'TV', 1),
		('hkrh', 'BBC2', 'TV', 0),
		('hkrr', 'BBC Four', 'TV', 0),
		('hkvz', 'ITV', 'TV', 0),
		('hkvb', 'Channel 4', 'TV', 0),
		('hkvh', 'Channel 5', 'TV', 0),
		('hkvd', 'Film 4', 'TV', 0),
		('hk7v', 'Al Jazeera', 'TV', 0),
		#('zzzz', 'All Channels', 'TV', 0),
	]
	curs.executemany('INSERT INTO schedulelist VALUES (?,?,?,?)', schedules)
	conn.commit()

	
	# Time Ranges
	curs.execute("DELETE FROM timelist")
	conn.commit()
	times = [
		('12amto6am', 'Midnight to 6AM.', 0),
		('6amto10am', '6AM to 10AM.', 1),
		('10amto2pm', '10AM to 2PM.', 0),
		('2pmto6pm', '2PM to 6PM.', 0),
		('6pmto10pm', '6PM to 10PM.', 0),
		('10pmto12am', '10PM to Midnight.', 0),
		('onnow', "What's on now.", 0),
	]
	curs.executemany('INSERT INTO timelist VALUES (?,?,?)', times)
	conn.commit()


	# Day List
	curs.execute("DELETE FROM daylist")
	conn.commit()
	days = [
		('today', 'Today.', 0),
		('today+1', 'Today +1.', 1),
		('today+2', 'Today +2.', 0),
		('today+3', 'Today +3.', 0),
		('today+4', 'Today +4.', 0),
		('today+5', 'Today +5.', 0),
	]
	curs.executemany('INSERT INTO daylist VALUES (?,?,?)', days)
	conn.commit()

	conn.close()

#-----------------------
def clearData(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()

	curs.execute("DELETE FROM scheduledata")
	conn.commit()
	
	curs.execute("DELETE FROM contentdata")
	conn.commit()
		
	conn.close()







#------------------------------------
def toggleSelectedSchedule(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()
	curs.execute("SELECT MAX(rowid) FROM schedulelist")
	data = curs.fetchone()
	maxschedulerowid = int(data[0])
	curs.execute("SELECT rowid FROM schedulelist WHERE selected = 1")
	data = curs.fetchone()
	currentschedulerowid = int(data[0])
	curs.execute("UPDATE schedulelist SET selected = 0")
	conn.commit()
	if currentschedulerowid == maxschedulerowid:
		curs.execute("UPDATE schedulelist SET selected = 1 WHERE rowid = 1")
	else:
		curs.execute("UPDATE schedulelist SET selected = 1 WHERE rowid = " + str((currentschedulerowid + 1)))
	conn.commit()

	curs.execute("SELECT rowid, * FROM schedulelist WHERE selected = 1")
	data = curs.fetchone()
	conn.close()
	GoogleTTS.speakPhrase(app_path, data[2], "schedule", data[1], False)



#-------------------------------------
def toggleSelectedTimeRange(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()
	curs.execute("SELECT MAX(rowid) FROM timelist")
	data = curs.fetchone()
	maxtimerowid = int(data[0])
	curs.execute("SELECT rowid FROM timelist WHERE selected = 1")
	data = curs.fetchone()
	currenttimerowid = int(data[0])
	curs.execute("UPDATE timelist SET selected = 0")
	conn.commit()
	if currenttimerowid == maxtimerowid:
		curs.execute("UPDATE timelist SET selected = 1 WHERE rowid = 1")
	else:
		curs.execute("UPDATE timelist SET selected = 1 WHERE rowid = " + str((currenttimerowid + 1)))
	conn.commit()

	curs.execute("SELECT rowid, * FROM timelist WHERE selected = 1")
	data = curs.fetchone()
	conn.close()
	GoogleTTS.speakPhrase(app_path, data[2], "general", data[1], False)



#-------------------------------
def toggleSelectedDay(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()
	curs.execute("SELECT MAX(rowid) FROM daylist")
	data = curs.fetchone()
	maxdayrowid = int(data[0])
	curs.execute("SELECT rowid FROM daylist WHERE selected = 1")
	data = curs.fetchone()
	currentdayrowid = int(data[0])
	curs.execute("UPDATE daylist SET selected = 0")
	conn.commit()
	if currentdayrowid == maxdayrowid:
		curs.execute("UPDATE daylist SET selected = 1 WHERE rowid = 1")
	else:
		curs.execute("UPDATE daylist SET selected = 1 WHERE rowid = " + str((currentdayrowid + 1)))
	conn.commit()

	curs.execute("SELECT rowid, * FROM daylist WHERE selected = 1")
	data = curs.fetchone()
	conn.close()

	if data[1] == 'today':
		DayDate = datetime.now()
		DayPhrase = 'Today'		
	elif data[1] == 'today+1':
		DayDate = datetime.now() + timedelta(days=1)
		DayPhrase = 'Tomorrow'
	elif data[1] == 'today+2':
		DayDate = datetime.now() + timedelta(days=2)
		DayPhrase = ''
	elif data[1] == 'today+3':
		DayDate = datetime.now() + timedelta(days=3)
		DayPhrase = ''
	elif data[1] == 'today+4':
		DayDate = datetime.now() + timedelta(days=4)
		DayPhrase = ''
	elif data[1] == 'today+5':
		DayDate = datetime.now() + timedelta(days=5)
		DayPhrase = ''
	else:
		DayDate = datetime.now()
		DayPhrase = ''


	if DayPhrase == '':
		mp3FileName = datetime.strftime(DayDate, "%A%B%d")
		DayPhrase = datetime.strftime(DayDate, "%A") + " the " + datetime.strftime(DayDate, "%d %B")
	else:
		mp3FileName = DayPhrase + datetime.strftime(DayDate, "%A%B%d")
		DayPhrase = DayPhrase + " the " + datetime.strftime(DayDate, "%d %B") 

	GoogleTTS.speakPhrase(app_path, DayPhrase, "general", mp3FileName, False)




#---------------------------------
def readCurrentSettings(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()

	# Schedule
	curs.execute("SELECT rowid, * FROM schedulelist WHERE selected = 1")
	data = curs.fetchone()
	SchedulePhrase = data[2]
	mp3filename = data[1]

	# Day
	curs.execute("SELECT rowid, * FROM daylist WHERE selected = 1")
	data = curs.fetchone()
	if data[1] == 'today':
		DayDate = datetime.now()
		DayPhrase = 'Today'
	elif data[1] == 'today+1':
		DayDate = datetime.now() + timedelta(days=1)
		DayPhrase = 'Tomorrow'
	elif data[1] == 'today+2':
		DayDate = datetime.now() + timedelta(days=2)
		DayPhrase = ''
	elif data[1] == 'today+3':
		DayDate = datetime.now() + timedelta(days=3)
		DayPhrase = ''
	elif data[1] == 'today+4':
		DayDate = datetime.now() + timedelta(days=4)
		DayPhrase = ''
	elif data[1] == 'today+5':
		DayDate = datetime.now() + timedelta(days=5)
		DayPhrase = ''
	else:
		DayDate = datetime.now()
		DayPhrase = ''
	if DayPhrase == '':
		DayPhrase = datetime.strftime(DayDate, "%A") + " the " + datetime.strftime(DayDate, "%d %B") 
	else:
		DayPhrase = DayPhrase + " the " + datetime.strftime(DayDate, "%d %B")
	mp3filename = mp3filename + datetime.strftime(DayDate, "%A%B%d")

	# Time
	curs.execute("SELECT rowid, * FROM timelist WHERE selected = 1")
	data = curs.fetchone()
	TimePhrase = data[2]
	mp3filename = mp3filename + data[1]

	# Descriptions
	curs.execute("SELECT settingvalue FROM settings WHERE settingid = 'ReadContentDescription'")
	data = curs.fetchone()
	if int(data[0]) == 0:
		DescriptionPhrase = "descriptions are off."
		mp3filename = mp3filename + "readcontentdescription_off"
	else:
		DescriptionPhrase = "descriptions are on."
		mp3filename = mp3filename + "readcontentdescription_on"


	conn.close()

	GoogleTTS.speakPhrase(app_path, SchedulePhrase + " for " + DayPhrase + " between the hours of " + TimePhrase + ". " + DescriptionPhrase, "general", mp3filename, False)


#------------------------------------------
def toggleReadContentDescription(app_path):

	DBFilename = app_path + "data/atlasdata.db"
	
	conn = sqlite3.connect(DBFilename)
	curs = conn.cursor()

	if int(GetSetting(app_path, 'ReadContentDescription')) == 0:
		blnReadContentDescription = True
		curs.execute("UPDATE settings SET settingvalue = 1 WHERE settingid = 'ReadContentDescription'")
	else:
		blnReadContentDescription = False
		curs.execute("UPDATE settings SET settingvalue = 0 WHERE settingid = 'ReadContentDescription'")

	conn.commit()
	conn.close()

	if blnReadContentDescription == True:
		GoogleTTS.speakPhrase(app_path, "Content description is on.", "general", "readcontentdescription_on", False)
	else:
		GoogleTTS.speakPhrase(app_path, "Content description is off!", "general", "readcontentdescription_off", False)
	



#-----------------------------------
<