Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 329 lines (250 sloc) 11.179 kb
357a78ac »
2009-11-07 Added GPL stuff
1 # Author: Nic Wolfe <nic@wolfeden.ca>
2 # URL: http://code.google.com/p/sickbeard/
3 #
e46eb09e »
2009-11-10 Fixed some comments
4 # This file is part of Sick Beard.
357a78ac »
2009-11-07 Added GPL stuff
5 #
e46eb09e »
2009-11-10 Fixed some comments
6 # Sick Beard is free software: you can redistribute it and/or modify
357a78ac »
2009-11-07 Added GPL stuff
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
e46eb09e »
2009-11-10 Fixed some comments
11 # Sick Beard is distributed in the hope that it will be useful,
357a78ac »
2009-11-07 Added GPL stuff
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
e46eb09e »
2009-11-10 Fixed some comments
17 # along with Sick Beard. If not, see <http://www.gnu.org/licenses/>.
357a78ac »
2009-11-07 Added GPL stuff
18
19
20
7c9aaa87 »
2009-11-06 Initial commit
21 import os
22 import shutil
23 import sys
24
25 import contactXBMC
26 import exceptions
27 import helpers
28 import sickbeard
16e5b92f »
2009-11-16 * Fixed issue 20
29 import sqlite3
30 import db
6274df88 »
2009-11-20 Added history, fixed sabProcessTV
31 import history
7c9aaa87 »
2009-11-06 Initial commit
32
33 from logging import *
34 from common import *
35
36 from sickbeard import classes
16e5b92f »
2009-11-16 * Fixed issue 20
37 from lib.tvdb_api import tvnamer, tvdb_api, tvdb_exceptions
7c9aaa87 »
2009-11-06 Initial commit
38
39 #from tvdb_api.nfogen import createXBMCInfo
40
41 sample_ratio = 0.3
42
9863a54d »
2009-11-26 Fixed a rename problem
43 def renameFile(curFile, newName):
44
45 filePath = os.path.split(curFile)
46 oldFile = os.path.splitext(filePath[1])
47
48 newFilename = os.path.join(filePath[0], helpers.sanitizeFileName(newName) + oldFile[1])
49 Logger().log("Renaming from " + curFile + " to " + newFilename)
50
51 try:
52 os.rename(curFile, newFilename)
53 except (OSError, IOError) as e:
54 Logger().log("Failed renaming " + curFile + " to " + os.path.basename(newFilename) + ": " + str(e), ERROR)
55 return False
56
57 return newFilename
58
59
7c9aaa87 »
2009-11-06 Initial commit
60 # #########################
61 # Find the file we're dealing with
62 # #########################
63 def findMainFile (show_dir):
64 # init vars
65 biggest_file = None
66 biggest_file_size = 0
67 next_biggest_file_size = 0
68
69 # find the biggest file in the folder
70 for file in filter(helpers.isMediaFile, os.listdir(show_dir)):
71 cur_size = os.path.getsize(os.path.join(show_dir, file))
72 if cur_size > biggest_file_size:
73 biggest_file = file
74 next_biggest_file_size = biggest_file_size
75 biggest_file_size = cur_size
76
77 if biggest_file == None:
78 return biggest_file
79
80 # it should be by far the biggest file in the folder. If it isn't, we have a problem (multi-show nzb or something, not going to deal with it)
81 if float(next_biggest_file_size) / float(biggest_file_size) > sample_ratio:
82 Logger().log("Multiple files in the folder are comparably large, giving up", ERROR)
83 return None
84
85 return os.path.join(show_dir, biggest_file)
86
87
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
88 def _checkForExistingFile(newFile, oldFile):
89
90 # if the new file exists, return the appropriate code depending on the size
91 if os.path.isfile(newFile):
7c9aaa87 »
2009-11-06 Initial commit
92
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
93 # see if it's bigger than our old file
94 if os.path.getsize(newFile) > os.path.getsize(oldFile):
95 return 1
7c9aaa87 »
2009-11-06 Initial commit
96
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
97 else:
98 return -1
99
7c9aaa87 »
2009-11-06 Initial commit
100 else:
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
101 return 0
102
103
104
9ea20374 »
2009-11-26 * Refactored sabProcessTV to be generic and added adapters for SAB a…
105 def doIt(downloadDir, nzbName=None):
7c9aaa87 »
2009-11-06 Initial commit
106
107 returnStr = ""
108
109 if not os.path.isdir(downloadDir):
110 return "Uh, this is not a directory: " + str(downloadDir)
111
112 # pretty up the path, just in case
113 downloadDir = os.path.abspath(downloadDir)
114 logStr = "Pretty'd up folder is " + downloadDir
115 Logger().log(logStr, DEBUG)
116 returnStr += logStr + "\n"
117
118 # TODO: check if it's failed and deal with it if it is
119 if downloadDir.startswith('_FAILED_'):
120 logStr = "The directory name indicates it failed to extract, cancelling"
121 Logger().log(logStr, DEBUG)
122 returnStr += logStr + "\n"
123 return returnStr
124
125 # find the file we're dealing with
126 biggest_file = findMainFile(downloadDir)
127 if biggest_file == None:
128 logStr = "Unable to find the biggest file - is this really a TV download?"
129 Logger().log(logStr, DEBUG)
130 returnStr += logStr + "\n"
131 return returnStr
132
133 logStr = "The biggest file in the dir is: " + biggest_file
134 Logger().log(logStr, DEBUG)
135 returnStr += logStr + "\n"
136
9ea20374 »
2009-11-26 * Refactored sabProcessTV to be generic and added adapters for SAB a…
137 # use file name, folder name, and NZB name (in that order) to try to figure out the episode info
7c9aaa87 »
2009-11-06 Initial commit
138 result = None
284c3265 »
2009-11-27 Fixed some bugs introduced with all the recent refactoring
139 nameList = [biggest_file, downloadDir.split(os.path.sep)[-1]]
9ea20374 »
2009-11-26 * Refactored sabProcessTV to be generic and added adapters for SAB a…
140 if nzbName != None:
141 nameList.append(nzbName)
142
143 for curName in nameList:
7c9aaa87 »
2009-11-06 Initial commit
144
145 result = tvnamer.processSingleName(curName)
146 logStr = curName + " parsed into: " + str(result)
147 Logger().log(logStr, DEBUG)
148 returnStr += logStr + "\n"
149
150 # if this one doesn't work try the next one
151 if result == None:
152 logStr = "Unable to parse this name"
153 Logger().log(logStr, DEBUG)
154 returnStr += logStr + "\n"
155 continue
16e5b92f »
2009-11-16 * Fixed issue 20
156
157 try:
158 t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, lastTimeout=sickbeard.LAST_TVDB_TIMEOUT)
159 showObj = t[result["file_seriesname"]]
160 showInfo = (int(showObj["id"]), showObj["seriesname"])
9863a54d »
2009-11-26 Fixed a rename problem
161 except (tvdb_exceptions.tvdb_exception, IOError) as e:
16e5b92f »
2009-11-16 * Fixed issue 20
162
163 logStr = "TVDB didn't respond, trying to look up the show in the DB instead"
164 Logger().log(logStr, DEBUG)
165 returnStr += logStr + "\n"
166
0f4c429d »
2009-11-16 Tons of untested changes, fun.
167 showInfo = helpers.searchDBForShow(result["file_seriesname"])
16e5b92f »
2009-11-16 * Fixed issue 20
168
0f4c429d »
2009-11-16 Tons of untested changes, fun.
169 # if we didn't get anything from TVDB or the DB then try the next option
170 if showInfo == None:
171 continue
172
7c9aaa87 »
2009-11-06 Initial commit
173 # find the show in the showlist
174 try:
9ea20374 »
2009-11-26 * Refactored sabProcessTV to be generic and added adapters for SAB a…
175 showResults = helpers.findCertainShow(sickbeard.showList, showInfo[0])
7c9aaa87 »
2009-11-06 Initial commit
176 except exceptions.MultipleShowObjectsException:
177 raise #TODO: later I'll just log this, for now I want to know about it ASAP
178
179 if showResults != None:
180 logStr = "Found the show in our list, continuing"
181 Logger().log(logStr, DEBUG)
182 returnStr += logStr + "\n"
183 break
16e5b92f »
2009-11-16 * Fixed issue 20
184
185 # end for
7c9aaa87 »
2009-11-06 Initial commit
186
187 if result == None:
188 logStr = "Unable to figure out what this episode is, giving up"
189 Logger().log(logStr, DEBUG)
190 returnStr += logStr + "\n"
191 return returnStr
192
193 if showResults == None:
194 logStr = "The episode doesn't match a show in my list - bad naming?"
195 Logger().log(logStr, DEBUG)
196 returnStr += logStr + "\n"
197 return returnStr
198
199
200 # get or create the episode (should be created probably, but not for sure)
201 season = int(result["seasno"])
202
203 rootEp = None
204 for curEpisode in result["epno"]:
205 episode = int(curEpisode)
206
16e5b92f »
2009-11-16 * Fixed issue 20
207 logStr = "TVDB thinks the file is " + showInfo[1] + str(season) + "x" + str(episode)
7c9aaa87 »
2009-11-06 Initial commit
208 Logger().log(logStr, DEBUG)
209 returnStr += logStr + "\n"
210
211 # now that we've figured out which episode this file is just load it manually
bff86ee7 »
2009-11-30 * Fixed issue 45
212 curEp = showResults.getEpisode(season, episode)
7c9aaa87 »
2009-11-06 Initial commit
213
214 if rootEp == None:
215 rootEp = curEp
216 rootEp.relatedEps = []
217 else:
218 rootEp.relatedEps.append(curEp)
219
6274df88 »
2009-11-20 Added history, fixed sabProcessTV
220 # log it to history
221 history.logDownload(rootEp, biggest_file)
222
27179529 »
2009-11-19 Fixed some pathing mistakes in the new template
223 # wait for the copy to finish
224
7c9aaa87 »
2009-11-06 Initial commit
225 if sickbeard.XBMC_NOTIFY_ONDOWNLOAD == True:
226 contactXBMC.notifyXBMC(rootEp.prettyName(), "Download finished")
227
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
228
229 # figure out the new filename
230 biggestFileName = os.path.basename(biggest_file)
231 biggestFileExt = os.path.splitext(biggestFileName)[1]
232
233 # figure out the right folder
234 if rootEp.show.seasonfolders == True:
235 seasonFolder = 'Season ' + str(rootEp.season)
236 else:
237 seasonFolder = ''
238 logStr = "Seasonfolders were " + str(rootEp.show.seasonfolders) + " which gave " + seasonFolder
239 Logger().log(logStr, DEBUG)
240 returnStr += logStr + "\n"
241
242 destDir = os.path.join(rootEp.show.location, seasonFolder)
243
a2623df8 »
2009-11-22 Worked on issue 16
244 newFile = os.path.join(destDir, helpers.sanitizeFileName(rootEp.prettyName())+biggestFileExt)
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
245 logStr = "The ultimate destination for " + biggest_file + " is " + newFile
246 Logger().log(logStr, DEBUG)
247 returnStr += logStr + "\n"
248
249 existingResult = _checkForExistingFile(newFile, biggest_file)
250
251 # see if the existing file is bigger - if it is, bail
252 if existingResult == 1:
253 logStr = "There is already a file that's bigger at "+newFile+" - not processing this episode."
7c9aaa87 »
2009-11-06 Initial commit
254 Logger().log(logStr, DEBUG)
255 returnStr += logStr + "\n"
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
256 return returnStr
257
258 # if the dir doesn't exist (new season folder) then make it
259 if not os.path.isdir(destDir):
260 logStr = "Season folder didn't exist, creating it"
261 Logger().log(logStr, DEBUG)
262 returnStr += logStr + "\n"
263 os.mkdir(destDir)
264
265 Logger().log("Moving from " + biggest_file + " to " + destDir, DEBUG)
266 try:
267 shutil.move(biggest_file, destDir)
268
269 logStr = "File was moved successfully"
7c9aaa87 »
2009-11-06 Initial commit
270 Logger().log(logStr, DEBUG)
271 returnStr += logStr + "\n"
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
272
273 except IOError as e:
274 logStr = "Unable to move the file: " + str(e)
275 Logger().log(logStr, ERROR)
276 returnStr += logStr + "\n"
7c9aaa87 »
2009-11-06 Initial commit
277 return returnStr
278
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
279 # if the file existed and was smaller then lets delete it
280 if existingResult == -1:
281 os.remove(newFile)
282
283 curFile = os.path.join(destDir, biggestFileName)
27179529 »
2009-11-19 Fixed some pathing mistakes in the new template
284
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
285 try:
286 os.rename(curFile, newFile)
287 logStr = "Renaming the file " + curFile + " to " + newFile
27179529 »
2009-11-19 Fixed some pathing mistakes in the new template
288 Logger().log(logStr, DEBUG)
289 returnStr += logStr + "\n"
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
290 except (OSError, IOError) as e:
291 logStr = "Failed renaming " + curFile + " to " + newFile + ": " + str(e)
292 Logger().log(logStr, ERROR)
293 returnStr += logStr + "\n"
294 return returnStr
295
296 for curEp in [rootEp] + rootEp.relatedEps:
297 with curEp.lock:
298 curEp.location = newFile
299
300 # don't mess up the status - if this is a legit download it should be SNATCHED
301 if curEp.status != PREDOWNLOADED:
302 curEp.status = DOWNLOADED
303 curEp.saveToDB()
27179529 »
2009-11-19 Fixed some pathing mistakes in the new template
304
305
7c9aaa87 »
2009-11-06 Initial commit
306 # generate nfo/tbn
27179529 »
2009-11-19 Fixed some pathing mistakes in the new template
307 rootEp.createMetaFiles()
308 rootEp.saveToDB()
7c9aaa87 »
2009-11-06 Initial commit
309
310 # we don't want to put predownloads in the library until we can deal with removing them
311 if sickbeard.XBMC_UPDATE_LIBRARY == True and rootEp.status != PREDOWNLOADED:
312 contactXBMC.updateLibrary(rootEp.show.location)
313
9e6fb004 »
2009-11-20 Fixed a bug with dealing with malformed TVRage data
314 logStr = "Deleting folder " + downloadDir
315 Logger().log(logStr, DEBUG)
316 returnStr += logStr + "\n"
317
7c9aaa87 »
2009-11-06 Initial commit
318 # delete the old folder full of useless files
319 try:
320 shutil.rmtree(downloadDir)
321 except (OSError, IOError) as e:
322 logStr = "Warning: unable to remove the folder " + downloadDir + ": " + str(e)
323 Logger().log(logStr, ERROR)
324 returnStr += logStr + "\n"
325
326 return returnStr
327
328 if __name__ == "__main__":
329 doIt(sys.argv[1])
Something went wrong with that request. Please try again.