database.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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"
  78. " disabled 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, sub_id):
  85. """Deletes a subscription and all associated videos from the
  86. database
  87. """
  88. checkquery = "SELECT * FROM subscriptions WHERE id=?"
  89. checkresult = self.__ExecuteStatement(checkquery, (sub_id,))
  90. if not checkresult.fetchall():
  91. raise stov_exceptions.SubscriptionNotFoundException()
  92. else:
  93. deletevideos = "DELETE FROM videos WHERE subscription_id=?"
  94. self.__ExecuteStatement(deletevideos, (sub_id,))
  95. deletesubscription = "DELETE FROM subscriptions WHERE id=?"
  96. self.__ExecuteStatement(deletesubscription, (sub_id,))
  97. message = "Subscription deleted successfully!"
  98. return message
  99. def GetVideos(self, video_id):
  100. """Gets all videos of a given subscription id from the database and
  101. returns them
  102. """
  103. video_query = "SELECT id, title, description, ytid, downloaded, " \
  104. "failcnt FROM videos WHERE subscription_id=?"
  105. cursor = self.__ExecuteStatement(video_query, (video_id,))
  106. result = cursor.fetchall()
  107. return result
  108. def VideoInDatabase(self, ytid):
  109. """Checks if the video with a given youtube id already exists in the
  110. database
  111. """
  112. video_query = "SELECT id FROM videos WHERE ytid=?"
  113. cursor = self.__ExecuteStatement(video_query, (ytid,))
  114. result = cursor.fetchall()
  115. if not result:
  116. return False
  117. else:
  118. return True
  119. def InsertVideo(self, video, subscription_id):
  120. """Inserts a video with the given data into the database"""
  121. video_insert = "INSERT INTO videos (title, description, ytid, \
  122. subscription_id, downloaded) VALUES \
  123. (?, ?, ?, ?, ?)"
  124. insert_data = (video.title, video.description, video.ytid,
  125. subscription_id, 0)
  126. self.__ExecuteStatement(video_insert, insert_data)
  127. message = "Video %s successfully inserted into database." % video.title
  128. return message
  129. def InsertSubscription(self, data):
  130. """Inserts a subscription with the given data into the database"""
  131. subscription_insert = "INSERT INTO subscriptions (title, type, " \
  132. "searchstring, directory, name, disabled) " \
  133. "VALUES (?, ?, ?, ?, ?, ?)"
  134. self.__ExecuteStatement(subscription_insert, data)
  135. subscription_getid = "SELECT id from subscriptions where title=?"
  136. query_cursor = self.__ExecuteStatement(subscription_getid, (data[0],))
  137. subscription_id = query_cursor.fetchone()[0]
  138. message = "Subscription sucessfully inserted into database."
  139. return (message, subscription_id)
  140. def UpdateVideoDownloadStatus(self, video_id, status):
  141. """Updates the download status of a video in the database"""
  142. update_statement = "UPDATE videos SET downloaded = ? WHERE id = ?"
  143. self.__ExecuteStatement(update_statement, (status, video_id))
  144. def DisableFailedVideo(self, video_id):
  145. """Disables a video in the database"""
  146. update_statement = "UPDATE videos SET downloaded = -1 WHERE id = ?"
  147. self.__ExecuteStatement(update_statement, (video_id,))
  148. def UpdateVideoFailCount(self, count, video_id):
  149. """Updates the fail count of a video in the database"""
  150. update_statement = "UPDATE videos SET failcnt = ? WHERE id = ?"
  151. self.__ExecuteStatement(update_statement, (count, video_id))
  152. def DeleteVideo(self, video_id):
  153. """Deletes a video from the database"""
  154. delete_statement = "DELETE FROM videos where id = ?"
  155. self.__ExecuteStatement(delete_statement, (video_id,))
  156. def GetSubscription(self, sub_id):
  157. """Retrieves a specific subscription from the database"""
  158. sub_query = "SELECT id,title,type,name,searchstring, directory," \
  159. "disabled FROM subscriptions where id=?"
  160. result_cursor = self.__ExecuteStatement(sub_query, (sub_id,))
  161. result = result_cursor.fetchall()
  162. return result
  163. def GetSubscriptionTitle(self, sub_id):
  164. """Retrieves only the title of a specified subscription from the
  165. database
  166. """
  167. title_query = "SELECT title from subscriptions where id=?"
  168. result_cursor = self.__ExecuteStatement(title_query, (sub_id,))
  169. result = result_cursor.fetchall()
  170. return result
  171. def MarkVideosDownloaded(self, video_id):
  172. """ Marks all videos in a specified subscription as downloaded"""
  173. update_statement = "UPDATE videos SET downloaded = 1 " \
  174. "WHERE subscription_id =?"
  175. self.__ExecuteStatement(update_statement, (video_id,))
  176. def GetSubscriptions(self):
  177. """Retrieves all subscriptions from the database"""
  178. subscriptions_query = "SELECT id,title,type,name,searchstring," \
  179. "directory,disabled FROM subscriptions"
  180. result_cursor = self.__ExecuteStatement(subscriptions_query)
  181. result = result_cursor.fetchall()
  182. return result
  183. def Vacuum(self):
  184. """Vacuums the database, shrinking it in size"""
  185. self.__ExecuteStatement("VACUUM")
  186. def ChangeSubscriptionState(self, sub_id, state):
  187. """Enables or disables a subscription depending on the parameter
  188. state
  189. """
  190. update_statement = "UPDATE subscriptions SET disabled=? WHERE id=?"
  191. self.__ExecuteStatement(update_statement, (state, sub_id))