database.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. def Update(self):
  67. """Updates the database structure to match the current version"""
  68. if int(self.__version) == 1:
  69. """Changes between version 1 and 2"""
  70. self.__ExecuteStatement("ALTER TABLE videos ADD COLUMN failcnt \
  71. INTEGER DEFAULT 0;")
  72. self.__version = 2
  73. if int(self.__version) == 2:
  74. """Changes between version 2 and 3"""
  75. self.__ExecuteStatement("ALTER TABLE subscriptions ADD COLUMN"
  76. " disabled INTEGER DEFAULT 0;")
  77. self.__ExecuteStatement("UPDATE subscriptions SET disabled=0;")
  78. self.__version = 3
  79. def GetVersion(self):
  80. """Simple getter method, returns the DB version"""
  81. return self.__version
  82. def DeleteSubscription(self, sub_id):
  83. """Deletes a subscription and all associated videos from the
  84. database
  85. """
  86. checkquery = "SELECT * FROM subscriptions WHERE id=?"
  87. checkresult = self.__ExecuteStatement(checkquery, (sub_id,))
  88. if not checkresult.fetchall():
  89. raise stov_exceptions.SubscriptionNotFoundException()
  90. else:
  91. deletevideos = "DELETE FROM videos WHERE subscription_id=?"
  92. self.__ExecuteStatement(deletevideos, (sub_id,))
  93. deletesubscription = "DELETE FROM subscriptions WHERE id=?"
  94. self.__ExecuteStatement(deletesubscription, (sub_id,))
  95. def GetVideos(self, video_id):
  96. """Gets all videos of a given subscription id from the database and
  97. returns them
  98. """
  99. video_query = "SELECT id, title, description, ytid, downloaded, " \
  100. "failcnt FROM videos WHERE subscription_id=?"
  101. cursor = self.__ExecuteStatement(video_query, (video_id,))
  102. result = cursor.fetchall()
  103. return result
  104. def VideoInDatabase(self, ytid):
  105. """Checks if the video with a given youtube id already exists in the
  106. database
  107. """
  108. video_query = "SELECT id FROM videos WHERE ytid=?"
  109. cursor = self.__ExecuteStatement(video_query, (ytid,))
  110. result = cursor.fetchall()
  111. if not result:
  112. return False
  113. else:
  114. return True
  115. def InsertVideo(self, video, subscription_id):
  116. """Inserts a video with the given data into the database"""
  117. video_insert = "INSERT INTO videos (title, description, ytid, \
  118. subscription_id, downloaded) VALUES \
  119. (?, ?, ?, ?, ?)"
  120. insert_data = (video.title, video.description, video.ytid,
  121. subscription_id, 0)
  122. self.__ExecuteStatement(video_insert, insert_data)
  123. def InsertSubscription(self, data):
  124. """Inserts a subscription with the given data into the database"""
  125. subscription_insert = "INSERT INTO subscriptions (title, type, " \
  126. "searchstring, directory, name, disabled) " \
  127. "VALUES (?, ?, ?, ?, ?, ?)"
  128. self.__ExecuteStatement(subscription_insert, data)
  129. subscription_getid = "SELECT id from subscriptions where title=?"
  130. query_cursor = self.__ExecuteStatement(subscription_getid, (data[0],))
  131. subscription_id = query_cursor.fetchone()[0]
  132. return subscription_id
  133. def UpdateVideoDownloadStatus(self, video_id, status):
  134. """Updates the download status of a video in the database"""
  135. update_statement = "UPDATE videos SET downloaded = ? WHERE id = ?"
  136. self.__ExecuteStatement(update_statement, (status, video_id))
  137. def DisableFailedVideo(self, video_id):
  138. """Disables a video in the database"""
  139. update_statement = "UPDATE videos SET downloaded = -1 WHERE id = ?"
  140. self.__ExecuteStatement(update_statement, (video_id,))
  141. def UpdateVideoFailCount(self, count, video_id):
  142. """Updates the fail count of a video in the database"""
  143. update_statement = "UPDATE videos SET failcnt = ? WHERE id = ?"
  144. self.__ExecuteStatement(update_statement, (count, video_id))
  145. def DeleteVideo(self, video_id):
  146. """Deletes a video from the database"""
  147. delete_statement = "DELETE FROM videos where id = ?"
  148. self.__ExecuteStatement(delete_statement, (video_id,))
  149. def GetSubscription(self, sub_id):
  150. """Retrieves a specific subscription from the database"""
  151. sub_query = "SELECT id,title,type,name,searchstring, directory," \
  152. "disabled FROM subscriptions where id=?"
  153. result_cursor = self.__ExecuteStatement(sub_query, (sub_id,))
  154. result = result_cursor.fetchall()
  155. return result
  156. def GetSubscriptionTitle(self, sub_id):
  157. """Retrieves only the title of a specified subscription from the
  158. database
  159. """
  160. title_query = "SELECT title from subscriptions where id=?"
  161. result_cursor = self.__ExecuteStatement(title_query, (sub_id,))
  162. result = result_cursor.fetchall()
  163. return result
  164. def MarkVideosDownloaded(self, video_id):
  165. """ Marks all videos in a specified subscription as downloaded"""
  166. update_statement = "UPDATE videos SET downloaded = 1 " \
  167. "WHERE subscription_id =?"
  168. self.__ExecuteStatement(update_statement, (video_id,))
  169. def GetSubscriptions(self):
  170. """Retrieves all subscriptions from the database"""
  171. subscriptions_query = "SELECT id,title,type,name,searchstring," \
  172. "directory,disabled FROM subscriptions"
  173. result_cursor = self.__ExecuteStatement(subscriptions_query)
  174. result = result_cursor.fetchall()
  175. return result
  176. def Vacuum(self):
  177. """Vacuums the database, shrinking it in size"""
  178. self.__ExecuteStatement("VACUUM")
  179. def ChangeSubscriptionState(self, sub_id, state):
  180. """Enables or disables a subscription depending on the parameter
  181. state
  182. """
  183. update_statement = "UPDATE subscriptions SET disabled=? WHERE id=?"
  184. self.__ExecuteStatement(update_statement, (state, sub_id))