123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- # 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 <http://www.gnu.org/licenses/>.
- # -*- coding: utf8 -*-
- from __future__ import unicode_literals
- 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": "7",
- "db_version": "2",
- "videocodec": "h264",
- "maxresolution": "1080p",
- "maxfails": "50",
- "check_title": "no"
- }
- 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)"),
- "check_title": _("if you want to compare the title of a video with the "
- "subscription search string")
- }
- 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:
- 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", 0o750)
- 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")
|