stov.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #! /usr/bin/env python
  2. # -*- coding: utf8 -*-
  3. """stov - a program to subscribe to channels and users from online video portals and download
  4. the videos automatically
  5. written by Helmut Pozimski in 2012
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; version 2
  9. of the License.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."""
  17. import sys
  18. import gettext
  19. import os
  20. import subscription
  21. import youtube
  22. import configuration
  23. import sqlite3
  24. import email
  25. import smtplib
  26. from email.mime.multipart import MIMEMultipart
  27. from email.mime.text import MIMEText
  28. from optparse import OptionParser
  29. """Initialize gettext to support translation of the program"""
  30. trans = gettext.translation("stov", "locale", ["de"])
  31. trans.install()
  32. """Process the given options and parameters,
  33. add: Add a new subscription (which can be a search, channel or playlist)
  34. lssubs: List the currently available subscriptions
  35. remove: remove a subscription
  36. update: update the information about the available videos
  37. download: download all available videos which haven't already been downloaded
  38. search: optionally add a search string to a new subscription"""
  39. parser = OptionParser(usage=_("stov.py option1 parameter1 [option2] [parameter2] ..."))
  40. parser.add_option("-a", "--add", dest="add", help=_("Add a new channel subscription"))
  41. parser.add_option("-p", "--playlist", dest="playlist", help=_("Add a new Playlist subscription"))
  42. parser.add_option("-l", "--lssubs", action="store_true", dest="list", help=_("List the currently available subscriptions"))
  43. parser.add_option("-r", "--remove", dest="delete", help=_("remove a subscription"))
  44. parser.add_option("-u", "--update", action="store_true", dest="update", help=_("update the information about the available videos"))
  45. parser.add_option("-d", "--download", action="store_true", dest="download", help=_("download all available videos which haven't already been downloaded"))
  46. parser.add_option("-s", "--search", dest="search", help=_("optionally add a search string to a new channel subscription or create a new search subscription"))
  47. parser.add_option("-x", "--listvids", dest="lsv", help=_("Print all videos from a subscription"))
  48. (options, arguments) = parser.parse_args()
  49. """Create the lock file which is used to determine if another instance is already running by chance, the program shouldn't be run in this case
  50. since we want to prevent concurent access to the database"""
  51. if os.access("/tmp/stov.lock", os.F_OK):
  52. print >> sys.stderr, _("The lock file already exists, probably another instance of this program is already running\n \
  53. if you are sure this is not the case, delete it manually and try again!")
  54. sys.exit(1)
  55. else:
  56. try:
  57. lockfile = open("/tmp/stov.lock", "w")
  58. lockfile.write(str(os.getpid()))
  59. lockfile.close()
  60. except IOError:
  61. print _("Lock file could not be created, please check that /tmp is writable and properly configured, ending now")
  62. sys.exit(1)
  63. """youtube-dl is really a dependency but the program will run with limited functionality without it so we need to check that here"""
  64. if os.system("which youtube-dl > /dev/null") != 0:
  65. print >> sys.stderr, _("Could not find youtube-dl. Please note that youtube-dl is not needed for the program to run but is needed to use the download option which won't work otherwise")
  66. if os.access(os.environ['HOME'] + "/.stov", os.F_OK & os.W_OK) != True:
  67. print _("This seems to be the first time you run the programm, it will now create the default configuration for you")
  68. conf = configuration.conf()
  69. conf.Initialize()
  70. else:
  71. conf = configuration.conf()
  72. conf.ReadConfig()
  73. MailContent = []
  74. if options.add != None:
  75. if options.search != None:
  76. NewSubscription = subscription.sub(type = "channel", name = options.add, search = options.search, conf = conf)
  77. else:
  78. NewSubscription = subscription.sub(type = "channel", name = options.add, conf = conf)
  79. NewSubscription.AddSub()
  80. NewSubscription.GetVideos()
  81. print _("New subscription ") + NewSubscription.GetTitle() + _(" successfully added")
  82. elif options.playlist != None:
  83. if options.search != None:
  84. print _("Playlists do not support searching, search option will be ignored!")
  85. NewSubscription = subscription.sub(type = "playlist", name = options.playlist, conf = conf)
  86. NewSubscription.AddSub()
  87. NewSubscription.GetVideos()
  88. print _("New playlist subscription successfully added")
  89. elif options.search != None:
  90. NewSubscription = subscription.sub(type = "search", name = _("Search_"), search = options.search, conf = conf)
  91. NewSubscription.AddSub()
  92. NewSubscription.GetVideos()
  93. print _("New search subscription successfully added")
  94. elif options.list == True:
  95. try:
  96. database = sqlite3.connect(conf.dbpath)
  97. cursor = database.cursor()
  98. cursor.execute("SELECT id, title FROM subscriptions")
  99. ListofSubscriptions = cursor.fetchall()
  100. except sqlite3.OperationalError:
  101. print _("Could not access the database, please check path and permissions and try again!")
  102. print _("ID Title")
  103. for subscription in ListofSubscriptions:
  104. if subscription[0] != None:
  105. print str(subscription[0]) + " " + subscription[1]
  106. database.close()
  107. elif options.delete != None:
  108. try:
  109. DeleteId = int(options.delete)
  110. Subscription = subscription.sub(type = "", name = "delete", id = DeleteId, conf = conf)
  111. except ValueError:
  112. print _("Invalid Option, please use the ID of the subscription you want to delete as parameter for the remove option")
  113. Subscription.Delete()
  114. elif options.update == True:
  115. ListofSubscriptions = []
  116. try:
  117. database = sqlite3.connect(conf.dbpath)
  118. cursor = database.cursor()
  119. cursor.execute("SELECT id,title,type,name,searchstring,directory FROM subscriptions")
  120. Subscriptions = cursor.fetchall()
  121. except sqlite3.OperationalError:
  122. print _("Could not access the database, please check path and permissions and try again!")
  123. for element in Subscriptions:
  124. ListofSubscriptions.append(subscription.sub(id = element[0], title = element[1], type = element[2], name = element[3], search = element[4], directory = element[5], conf = conf))
  125. for element in ListofSubscriptions:
  126. element.GetVideos()
  127. elif options.download == True:
  128. ListofSubscriptions = []
  129. try:
  130. database = sqlite3.connect(conf.dbpath)
  131. cursor = database.cursor()
  132. cursor.execute("SELECT id,title,type,name,searchstring,directory FROM subscriptions")
  133. Subscriptions = cursor.fetchall()
  134. except sqlite3.OperationalError:
  135. print _("Could not access the database, please check path and permissions and try again!")
  136. for element in Subscriptions:
  137. ListofSubscriptions.append(subscription.sub(id = element[0], title = element[1], type = element[2], name = element[3], search = element[4], directory = element[5], conf = conf))
  138. VideosDownloaded = 0
  139. for element in ListofSubscriptions:
  140. element.GetVideos()
  141. element.DownloadVideos()
  142. for entry in element.DownloadedVideos:
  143. MailContent.append(entry)
  144. VideosDownloaded = len(MailContent)
  145. if VideosDownloaded > 0:
  146. MailText = u""
  147. msg = MIMEMultipart()
  148. msg["Subject"] = _("Downloaded %i new videos") %VideosDownloaded
  149. msg["From"] = "stov <%s>" %conf.values["mailfrom"]
  150. msg["To"] = "<%s>" %conf.values["mailto"]
  151. MailText = _("The following episodes have been downloaded by stov: \n\n")
  152. for line in MailContent:
  153. MailText += line + "\n"
  154. msgtext = MIMEText(MailText.encode("utf8"), _charset="utf8")
  155. msg.attach(msgtext)
  156. Mail = smtplib.SMTP(conf.values["mailhost"], conf.values["smtpport"])
  157. try:
  158. Mail = smtplib.SMTP(conf.values["mailhost"], conf.values["smtpport"])
  159. except SMTPHeloError:
  160. _("Could not connect to the smtp server, please check your settings!")
  161. Mail.sendmail(conf.values["mailfrom"],conf.values["mailto"],msg.as_string())
  162. Mail.quit()
  163. elif options.lsv != None:
  164. try:
  165. database = sqlite3.connect(conf.dbpath)
  166. cursor = database.cursor()
  167. cursor.execute("SELECT id,title,type,name,searchstring,directory FROM subscriptions where id=%s" %options.lsv)
  168. Data = cursor.fetchall()
  169. except sqlite3.OperationalError:
  170. print _("Could not access the database, please check path and permissions and try again!")
  171. Subscription = subscription.sub(id = Data[0][0], title = Data[0][1], type = Data[0][2], name = Data[0][3], search = Data[0][4], directory = Data[0][5], conf = conf)
  172. Subscription.GetVideos()
  173. Subscription.PrintVideos()
  174. """Remove the lock file and end the program so it can be run again"""
  175. try:
  176. os.remove("/tmp/stov.lock")
  177. sys.exit(0)
  178. except os.error:
  179. print >> sys.stderr, _("Could not delete the lock file. Please check what went wrong and clean up manually!")