# This file is part of stov, written by Helmut Pozimski in 2012. # # stov is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 2 of the License. # # stov is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with stov. If not, see . # -*- coding: utf8 -*- import os import gettext import sys import sqlite3 import subprocess from outputhelper import printf class conf(object): def __init__(self): """Constructor Constructs the conf object with some reasonable default values which should work on most systems, existence of a local mail server is assumed. """ self.values = { "database": "stov.sqlite", "downloaddir": str(os.environ['HOME']) + "/stov", "maxvideos": "25", "mailhost": "localhost", "mailto": "root", "mailfrom": "stov@localhost", "smtpport": "25", "auth_needed": "no", "user_name": "", "password": "", "youtube-dl": "", "notify": "yes", "config_version": "6", "db_version": "2", "videocodec": "h264", "maxresolution": "1080p", "maxfails": "50" } self.__explanations = { "database": _("the name of your database file"), "downloaddir": _("the directory where downloaded videos are saved"), "maxvideos": _("the maximum number of videos to retrieve for each " "subscription"), "mailhost": _("the host of your mail server"), "mailto": _("the address used for notifications"), "mailfrom": _("the sender address of notification e-mails"), "smtpport": _("the port to use on your mail server"), "auth_needed": _("if your mail server requires authentication"), "user_name": _("the user name used to authenticate to your mail server"), "password": _("the password used to authenticate to your mail server"), "youtube-dl": _("the path to your youtube-dl installation"), "notify": _("if you want to be notified via e-mail about new videos"), "videocodec": _("which video codec you prefer (h264, webm or flv)"), "maxresolution": _("which resolution you prefer (360p, 480p, 720p " "or 1080p)"), } self.dbpath = str(os.environ['HOME']) + "/.stov/" + self.values["database"] self.outputlevel = "default" def WriteConfig(self): """Writes the configuration from the dictionary into the configuration file for stov. The configuration is written into the home directory of the user by default. """ try: printf(_("Opening configuration file"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.configfile = open(str(os.environ['HOME']) + "/.stov/stov.config", "w") except IOError, os.error: printf(_("Configuration could not be written, please" " check that the configuration directory exists and is writable"), outputlevel="default", level=self.outputlevel, descriptor="stderr") else: for key in self.values.iterkeys(): printf(_("Writing value for %s") % key.upper(), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.configfile.write(key.upper() + "=" + self.values[key] + "\n") self.configfile.close() def CreateDB(self): """Creates the database structure if it doesn't exist already.""" try: self.__database = sqlite3.connect(self.dbpath) except sqlite3.OperationalError: printf(_("The database could not be created, please " "check that the configuration directory exists and is writable"), outputlevel="default", level=self.outputlevel, descriptor="stderr") else: self.__dbcursor = self.__database.cursor() printf(_("Creating table subscriptions"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.__dbcursor.execute("""CREATE TABLE subscriptions ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title TEXT, name TEXT, type TEXT, searchstring TEXT, directory TEXT );""") printf(_("Creating table videos"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.__dbcursor.execute("""CREATE TABLE videos ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, title TEXT, description TEXT, ytid TEXT, subscription_id INTEGER, downloaded INT, failcnt INT DEFAULT 0 );""") self.__database.commit() self.__database.close() def Initialize(self): """Creates the necessary directory for the stov configuration and calls the internal methods to create the database and the configuration file. """ try: printf(_("Creating hidden directory in home for configuration and " "database"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") os.mkdir(str(os.environ['HOME']) + "/.stov", 0750) except os.error: printf(_("Configuration directory could not be created, " "please check that your home directory exists and is writable"), outputlevel="default", level=self.outputlevel, descriptor="stderr") else: printf(_("Looking for youtube-dl file"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.values["youtube-dl"] = subprocess.Popen(["which", "youtube-dl"], stdout=subprocess.PIPE).communicate()[0].strip() self.WriteConfig() self.CreateDB() def ReadConfig(self): """Reads the existing configuration file and places the values in the dictionary. Existing values (such as default values) are overwritten. """ try: printf(_("Opening config file for reading"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.configfile = open(str(os.environ['HOME']) + "/.stov/stov.config", "r") except IOError: printf(_("Configuration could not be " "read, please check that the configuration file exists and is readable"), outputlevel="default", level=self.outputlevel, descriptor="stderr") for lines in self.configfile: printf(_("Reading line %s") % lines.strip(), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.tmpline = lines.strip() self.tmplist = self.tmpline.split("=") self.values[self.tmplist[0].lower()] = self.tmplist[1] self.configfile.close() self.dbpath = str(os.environ['HOME']) + "/.stov/" + self.values["database"] def CheckConfig(self): """Checks if the configuration is up-to-date with the running stov version. """ printf(_("Checking current and running configuration version"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") try: self.__currentversion = int(self.values["config_version"]) except ValueError: printf(_("Invalid config version read"), outputlevel="default", level=self.outputlevel, descriptor="stderr") self.values["config_version"] = "0" self.__currentdbversion = self.values["db_version"] self.ReadConfig() printf(_("Found running version: ") + self.values["config_version"] + "\n" + _("Current version: ") + str(self.__currentversion)), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") if self.values["config_version"] == "0" \ or int(self.values["config_version"]) < self.__currentversion: self.values["config_version"] = str(self.__currentversion) return False else: self.values["config_version"] = str(self.__currentversion) return True def UpdateConfig(self): """Update the configuration to the latest version""" self.__versionbuffer = self.values["config_version"] self.ReadConfig() self.values["config_version"] = self.__versionbuffer self.WriteConfig() def CheckDB(self): """Checks the database if it is up-to-date""" printf(_("Checking current and running database version."), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") self.values["db_version"] = "0" self.ReadConfig() printf(_("Found running database version: ") + self.values["db_version"] + "\n" + _("Current version: ") + str(self.__currentversion)), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") if self.values["db_version"] == "0" or \ int(self.values["db_version"]) < int(self.__currentdbversion): self.values["db_version"] = str(self.__currentversion) return False else: self.values["db_version"] = str(self.__currentversion) return True def UpdateDB(self): """Performs database changes that need to be done""" self.ReadConfig() if int(self.values["db_version"]) == 1: try: self.__database = sqlite3.connect(self.dbpath) except sqlite3.OperationalError: printf(_("The database could not be updated, please " "check that the configuration directory exists and is writable"), outputlevel="default", level=self.outputlevel, descriptor="stderr") else: self.__dbcursor = self.__database.cursor() self.__dbcursor.execute("ALTER TABLE videos add column failcnt int \ DEFAULT 0;") self.__database.commit() self.__database.close() self.ReadConfig() self.values["db_version"] = "2" self.WriteConfig() else: pass def GetYoutubeParameter(self): """Determines which itag value results from codec and resolution settings and returns it """ printf(_("Trying to determine the itag value for youtube-dl from your" " quality and codec settings"), outputlevel="verbose", level=self.outputlevel, descriptor="stderr") itag_value = 0 if self.values["videocodec"] == "flv": if self.values["maxresolution"] == "240p": itag_value = 5 elif self.values["maxresolution"] == "270p": itag_value = 6 elif self.values["maxresolution"] == "360p": itag_value = 34 elif self.values["maxresolution"] == "480p": itag_value = 35 elif self.values["videocodec"] == "webm": if self.values["maxresolution"] == "360p": itag_value = 43 elif self.values["maxresolution"] == "480p": itag_value = 44 elif self.values["maxresolution"] == "720p": itag_value = 45 elif self.values["maxresolution"] == "1080p": itag_value = 46 elif self.values["videocodec"] == "h264": if self.values["maxresolution"] == "360p": itag_value = 18 elif self.values["maxresolution"] == "720p": itag_value = 22 elif self.values["maxresolution"] == "1080p": itag_value = 37 elif self.values["maxresolution"] == "3072p": itag_value = 38 printf(_("Found value: %s") % itag_value, outputlevel="verbose", level=self.outputlevel, descriptor="stderr") return itag_value def assist(self): """ Ask the user to set all required configuration parameters """ printf(_("This assistant will help you to perform the initial configuration" " of stov. \nThe default value will be displayed in brackets.\n" "Please specify now :\n"), outputlevel="default", level=self.outputlevel, descriptor="stdout") for value in self.__explanations: printf(self.__explanations[value] + " [" + self.values[value] + "]: ", outputlevel="default", level=self.outputlevel, descriptor="stdout") self.__user_input = raw_input() if self.__user_input != "": self.values[value] = self.__user_input self.dbpath = str(os.environ['HOME']) + "/.stov/" + self.values["database"] self.Initialize() printf(_("Writing initial configuration according to your input, have fun!"), outputlevel="default", level=self.outputlevel, descriptor="stdout")