database.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. # This file is part of stov, written by Helmut Pozimski in 2014.
  2. #
  3. # stov is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, version 2 of the License.
  6. #
  7. # stov is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License
  13. # along with stov. If not, see <http://www.gnu.org/licenses/>.
  14. # -*- coding: utf8 -*-
  15. from __future__ import unicode_literals
  16. import sqlite3
  17. from lib_stov import stov_exceptions
  18. class db(object):
  19. def __init__(self, path, version):
  20. """Constructor of the db class, populates the object with the relevant
  21. attributes, connects to the database and creates it if asked to.
  22. """
  23. self.__path = path
  24. self.__version = version
  25. try:
  26. self.__connection = sqlite3.connect(self.__path)
  27. except sqlite3.OperationalError:
  28. raise stov_exceptions.DBConnectionFailedException()
  29. else:
  30. self.__cursor = self.__connection.cursor()
  31. def __del__(self):
  32. """Destructor, closes the connection to the database."""
  33. self.__connection.close()
  34. def __ExecuteStatement(self, statement, argument=None):
  35. """Executes a statement, works as a wrapper around cursor execute."""
  36. try:
  37. if argument is None:
  38. result = self.__cursor.execute(statement)
  39. else:
  40. result = self.__cursor.execute(statement, argument)
  41. except sqlite3.OperationalError:
  42. raise stov_exceptions.DBWriteAccessFailedException()
  43. else:
  44. self.__connection.commit()
  45. return result
  46. def Populate(self):
  47. """Populates the database with the initial structure."""
  48. self.__ExecuteStatement("""CREATE TABLE subscriptions (
  49. id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  50. title TEXT,
  51. name TEXT,
  52. type TEXT,
  53. searchstring TEXT,
  54. directory TEXT,
  55. disabled INTEGER DEFAULT 0
  56. );""")
  57. self.__ExecuteStatement("""CREATE TABLE videos (
  58. id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
  59. title TEXT,
  60. description TEXT,
  61. ytid TEXT,
  62. subscription_id INTEGER,
  63. downloaded INT,
  64. failcnt INTEGER DEFAULT 0
  65. );""")
  66. exit_message = _("Created initial database tables.")
  67. return exit_message
  68. def Update(self):
  69. """Updates the database structure to match the current version"""
  70. if int(self.__version) == 1:
  71. """Changes between version 1 and 2"""
  72. self.__ExecuteStatement("ALTER TABLE videos ADD COLUMN failcnt \
  73. INTEGER DEFAULT 0;")
  74. self.__version = 2
  75. if int(self.__version) == 2:
  76. """Changes between version 2 and 3"""
  77. self.__ExecuteStatement("ALTER TABLE subscriptions ADD COLUMN disabled \
  78. INTEGER DEFAULT 0;")
  79. self.__ExecuteStatement("UPDATE subscriptions SET disabled=0;")
  80. self.__version=3
  81. def GetVersion(self):
  82. """Simple getter method, returns the DB version"""
  83. return self.__version
  84. def DeleteSubscription(self, id):
  85. """Deletes a subscription and all associated videos from the database"""
  86. checkquery = "SELECT * FROM subscriptions WHERE id=?"
  87. checkresult = self.__ExecuteStatement(checkquery, (id,))
  88. if checkresult.fetchall() == []:
  89. raise stov_exceptions.SubscriptionNotFoundException()
  90. else:
  91. deletevideos = "DELETE FROM videos WHERE subscription_id=?"
  92. self.__ExecuteStatement(deletevideos, (id,))
  93. deletesubscription = "DELETE FROM subscriptions WHERE id=?"
  94. self.__ExecuteStatement(deletesubscription, (id,))
  95. message = "Subscription deleted successfully!"
  96. return message
  97. def GetVideos(self, id):
  98. """Gets all videos of a given subscription id from the database and returns them"""
  99. video_query = "SELECT id, title, description, ytid, downloaded, failcnt FROM videos WHERE subscription_id=?"
  100. cursor = self.__ExecuteStatement(video_query, (id,))
  101. result = cursor.fetchall()
  102. return result
  103. def VideoInDatabase(self, ytid):
  104. """Checks if the video with a given youtube id already exists in the database"""
  105. video_query = "SELECT id FROM videos WHERE ytid=?"
  106. cursor = self.__ExecuteStatement(video_query, (ytid,))
  107. result = cursor.fetchall()
  108. if result == []:
  109. return False
  110. else:
  111. return True
  112. def InsertVideo(self, video, subscription_id):
  113. """Inserts a video with the given data into the database"""
  114. video_insert = "INSERT INTO videos (title, description, ytid, \
  115. subscription_id, downloaded) VALUES \
  116. (?, ?, ?, ?, ?)"
  117. insert_data = (video.title, video.description, video.ytid,
  118. subscription_id, 0)
  119. self.__ExecuteStatement(video_insert, insert_data)
  120. message = "Video %s successfully inserted into database." % video.title
  121. return message
  122. def InsertSubscription(self, data):
  123. """Inserts a subscription with the given data into the database"""
  124. subscription_insert = "INSERT INTO subscriptions (title, type, searchstring, \
  125. directory, name, disabled) VALUES (?, ?, ?, ?, ?, ?)"
  126. self.__ExecuteStatement(subscription_insert, data)
  127. subscription_getid = "SELECT id from subscriptions where title=?"
  128. query_cursor = self.__ExecuteStatement(subscription_getid, (data[0],))
  129. subscription_id = query_cursor.fetchone()[0]
  130. message = "Subscription sucessfully inserted into database."
  131. return (message, subscription_id)
  132. def UpdateVideoDownloadStatus(self, id, status):
  133. """Updates the download status of a video in the database"""
  134. update_statement = "UPDATE videos SET downloaded = ? WHERE id = ?"
  135. result = self.__ExecuteStatement(update_statement, (status, id))
  136. def DisableFailedVideo(self, id):
  137. """Disables a video in the database"""
  138. update_statement = "UPDATE videos SET downloaded = -1 WHERE id = ?"
  139. self.__ExecuteStatement(update_statement, (id,))
  140. def UpdateVideoFailCount(self,count, id):
  141. """Updates the fail count of a video in the database"""
  142. update_statement = "UPDATE videos SET failcnt = ? WHERE id = ?"
  143. self.__ExecuteStatement(update_statement, (count, id))
  144. def DeleteVideo(self,id):
  145. """Deletes a video from the database"""
  146. delete_statement = "DELETE FROM videos where id = ?"
  147. self.__ExecuteStatement(delete_statement, (id,))
  148. def GetSubscription(self, id):
  149. """Retrieves a specific subscription from the database"""
  150. sub_query = "SELECT id,title,type,name,searchstring, directory," \
  151. "disabled FROM subscriptions where id=?"
  152. result_cursor = self.__ExecuteStatement(sub_query, (id,))
  153. result = result_cursor.fetchall()
  154. return result
  155. def GetSubscriptionTitle(self, id):
  156. """Retrieves only the title of a specified subscription from the
  157. database
  158. """
  159. title_query = "SELECT title from subscriptions where id=?"
  160. result_cursor = self.__ExecuteStatement(title_query, (id,))
  161. result = result_cursor.fetchall()
  162. return result
  163. def MarkVideosDownloaded(self, id):
  164. """ Marks all videos in a specified subscription as downloaded"""
  165. update_statement = "UPDATE videos SET downloaded = 1 WHERE subscription_id =?"
  166. self.__ExecuteStatement(update_statement, (id,))
  167. def GetSubscriptions(self):
  168. """Retrieves all subscriptions from the database"""
  169. subscriptions_query = "SELECT id,title,type,name,searchstring," \
  170. "directory,disabled FROM subscriptions"
  171. result_cursor = self.__ExecuteStatement(subscriptions_query)
  172. result = result_cursor.fetchall()
  173. return result
  174. def Vacuum(self):
  175. """Vacuums the database, shrinking it in size"""
  176. self.__ExecuteStatement("VACUUM")
  177. def ChangeSubscriptionState(self, id, state):
  178. """Enables or disables a subscription depending on the parameter
  179. state
  180. """
  181. update_statement = "UPDATE subscriptions SET disabled=? WHERE id=?"
  182. self.__ExecuteStatement(update_statement, (state,id))