Skip to content

Commit

Permalink
Support xbmcvfs
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus Ehrnsperger committed Mar 11, 2019
1 parent 3abf568 commit 06ec668
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 99 deletions.
4 changes: 3 additions & 1 deletion addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.vdr.recordings" name="VDR Recordings" version="0.2.4" provider-name="Markus Ehrnsperger">
<addon id="plugin.video.vdr.recordings" name="VDR Recordings" version="0.3.0" provider-name="Markus Ehrnsperger">
<requires>
<import addon="xbmc.python" version="2.25.0"/>
</requires>
Expand All @@ -18,6 +18,8 @@
<email></email>
<source>https://github.com/MarkusEh/plugin.video.vdr.recordings</source>
<news>
v0.3.0
- support xbmcvfs
v0.2.4
- ignore missing index files
v0.2.3
Expand Down
5 changes: 3 additions & 2 deletions resources/lib/bookmarks.py
Expand Up @@ -6,15 +6,16 @@
import sqlite3
import xbmc
import os
import xbmcvfs

class bookmarks:
def __init__(self):
self.dbKnown = False
dbFileMyVideos = xbmc.translatePath("special://database/MyVideos112.db")
if os.path.isfile(dbFileMyVideos): self.dbKnown = True
if xbmcvfs.exists(dbFileMyVideos): self.dbKnown = True
if self.dbKnown == False:
dbFileMyVideos = xbmc.translatePath("special://database/MyVideos107.db")
if os.path.isfile(dbFileMyVideos): self.dbKnown = True
if xbmcvfs.exists(dbFileMyVideos): self.dbKnown = True
if self.dbKnown == True:
# Connect to database
self.conn = sqlite3.connect(dbFileMyVideos)
Expand Down
8 changes: 4 additions & 4 deletions resources/lib/constants.py
Expand Up @@ -19,9 +19,9 @@
SEARCH = "Search"

LIBRARY_BASEPATH = xbmc.translatePath(
"special://userdata/addon_data/plugin.video.vdr.recordings")
LIBRARY_MOVIES = os.path.join(LIBRARY_BASEPATH, "Movies")
LIBRARY_TV_SHOWS = os.path.join(LIBRARY_BASEPATH, "TV shows")
LIBRARY_MUSIC_VIDEOS = os.path.join(LIBRARY_BASEPATH, "Music videos")
"special://userdata/addon_data/plugin.video.vdr.recordings/")
LIBRARY_MOVIES = os.path.join(LIBRARY_BASEPATH, "Movies/")
LIBRARY_TV_SHOWS = os.path.join(LIBRARY_BASEPATH, "TV shows/")
LIBRARY_MUSIC_VIDEOS = os.path.join(LIBRARY_BASEPATH, "Music videos/")


42 changes: 29 additions & 13 deletions resources/lib/contextMenu.py
Expand Up @@ -11,6 +11,7 @@
import xbmc
import xbmcaddon
import xbmcgui
import xbmcvfs
import kfolder
import vdrrecordingfolder
import constants
Expand All @@ -23,6 +24,18 @@ def GUIEditExportName(name):
else:
return None

def recursive_delete_dir(fullpath):
'''helper to recursively delete a directory'''
success = True
dirs, files = xbmcvfs.listdir(fullpath)
for file in files:
success = xbmcvfs.delete(os.path.join(fullpath, file))
for directory in dirs:
success = recursive_delete_dir(os.path.join(fullpath, directory))
success = xbmcvfs.rmdir(fullpath)
return success


def getRootFolder():
rootFolder = xbmcaddon.Addon('plugin.video.vdr.recordings').getSetting("rootFolder")
lastChar = rootFolder[-1]
Expand All @@ -37,15 +50,15 @@ def getRootFolder():
if mode == constants.ADDALLTOLIBRARY:
rootFolder = sys.argv[2]
# xbmc.log("rootFolder=" + str(rootFolder), xbmc.LOGERROR)
try: shutil.rmtree(constants.LIBRARY_MOVIES)
try: recursive_delete_dir(constants.LIBRARY_MOVIES)
except: pass
try: shutil.rmtree(constants.LIBRARY_TV_SHOWS)
try: recursive_delete_dir(constants.LIBRARY_TV_SHOWS)
except: pass
try: shutil.rmtree(constants.LIBRARY_MUSIC_VIDEOS)
try: recursive_delete_dir(constants.LIBRARY_MUSIC_VIDEOS)
except: pass
os.makedirs(constants.LIBRARY_MOVIES)
os.makedirs(constants.LIBRARY_TV_SHOWS)
os.makedirs(constants.LIBRARY_MUSIC_VIDEOS)
xbmcvfs.mkdirs(constants.LIBRARY_MOVIES)
xbmcvfs.mkdirs(constants.LIBRARY_TV_SHOWS)
xbmcvfs.mkdirs(constants.LIBRARY_MUSIC_VIDEOS)
kfolder.kFolder(rootFolder).parseFolder(-10, '', rootFolder)

if mode == constants.TV_SHOWS:
Expand Down Expand Up @@ -108,7 +121,7 @@ def getRootFolder():
+ rf.title
+ '"?')
if d == True:
shutil.rmtree(recordingFolderPath, ignore_errors=True)
recursive_delete_dir(recordingFolderPath)
# os.rename(recordingFolderPath, ps[0] + '.del')
xbmc.executebuiltin("Container.Refresh")

Expand All @@ -126,12 +139,15 @@ def getRootFolder():
if dest != None:
d1 = fp + ".move"
dfin = os.path.join(dest, fn)
shutil.move(fp, d1 )

script = "special://home/addons/plugin.video.vdr.recordings/resources/lib/move.py"
xbmc.executebuiltin("XBMC.RunScript(" + xbmc.translatePath(script) + ", " + d1 + ", " + dest + ", " + dfin + ")")
xbmc.sleep(10)
xbmc.executebuiltin("Container.Refresh")
if xbmcvfs.rename(fp, d1) == False:
xbmc.log("constants.MOVE, fp = " + fp, xbmc.LOGERROR)
xbmc.log("constants.MOVE, d1 = " + d1, xbmc.LOGERROR)
else:

script = "special://home/addons/plugin.video.vdr.recordings/resources/lib/move.py"
xbmc.executebuiltin("XBMC.RunScript(" + xbmc.translatePath(script) + ", " + d1 + ", " + dest + ", " + dfin + ")")
xbmc.sleep(10)
xbmc.executebuiltin("Container.Refresh")

if mode == constants.SEARCH:
rootFolder = sys.argv[2]
Expand Down
78 changes: 43 additions & 35 deletions resources/lib/kfolder.py
Expand Up @@ -10,6 +10,7 @@
import xbmcplugin
import xbmcaddon
import xbmcgui
import xbmcvfs
import constants
import vdrrecordingfolder

Expand All @@ -26,23 +27,28 @@ def readKodiFile(self):
self.fileRead = True
self.kodiLines = {}
kodiFileName = os.path.join(self.path, "kodi")
if os.path.isfile(kodiFileName):
if xbmcvfs.exists(kodiFileName):
try:
f_kodi = open(kodiFileName, "r")
except:
# f_kodi = open(kodiFileName, "r")
f_kodi = xbmcvfs.File(kodiFileName, "r")
except IOError:
xbmc.log("Cannot open for read: " + str(kodiFileName), xbmc.LOGERROR)
pass
else:
# exists
kodi_content = f_kodi.readlines()
kodi_content = f_kodi.read()
f_kodi.close()
for kodi_line in kodi_content:
self.kodiLines[kodi_line[0]] = kodi_line[2:].strip()
for kodi_line in kodi_content.splitlines():
try:
self.kodiLines[kodi_line[0]] = kodi_line[2:].strip()
except:
pass

def writeKodiFile(self):
kodiFileName = os.path.join(self.path, "kodi")
try:
f_kodi = open(kodiFileName, "w")
except:
f_kodi = xbmcvfs.File(kodiFileName, "w")
except IOError:
# cannot open for write
xbmc.log("Cannot open for write: " + str(kodiFileName), xbmc.LOGERROR)
return -1
Expand Down Expand Up @@ -114,9 +120,10 @@ def selectFolder(self, rootFolder):
DELETE_FOLDER = "<delete this folder>"
self.subFolders = []
self.subFolders.append(THIS_FOLDER)
if os.access(self.path, os.W_OK):
self.subFolders.append(CREATE_FOLDER)
if len(os.listdir(self.path)) == 0:
# if os.access(self.path, os.W_OK):
self.subFolders.append(CREATE_FOLDER)
dirs, files = xbmcvfs.listdir(self.path)
if len(dirs) == 0 and len(files) == 0:
self.subFolders.append(DELETE_FOLDER)
if self.path != rootFolder:
self.subFolders.append(FOLDER_UP)
Expand All @@ -134,8 +141,8 @@ def selectFolder(self, rootFolder):
return self.path
if self.subFolders[d] == DELETE_FOLDER:
try:
os.rmdir(self.path)
except OSError:
xbmcvfs.rmdir(self.path)
except:
xbmc.log("Error deleting directory " + str(self.path), xbmc.LOGERROR)
return self.selectFolder(rootFolder)
return kFolder(os.path.split(self.path)[0]).selectFolder(rootFolder)
Expand All @@ -144,10 +151,10 @@ def selectFolder(self, rootFolder):
d2 = dialog.input("Enter name of new folder")
if d2 == "": return self.selectFolder(rootFolder)
newpath = os.path.join(self.path, d2)
if not os.path.exists(newpath):
if not xbmcvfs.exists(newpath + "/"):
try:
os.makedirs(newpath)
except OSError:
xbmcvfs.makedirs(newpath)
except:
xbmc.log("Error creating directory " + str(newpath), xbmc.LOGERROR)
return self.selectFolder(rootFolder)
return kFolder(newpath).selectFolder(rootFolder)
Expand All @@ -161,26 +168,27 @@ def parseFolder(self, addon_handle, base_url, rootFolder):
firstTitle = None
recordingsList = []
subfolderList = []
for fileN in os.listdir(self.path):
path = os.path.join(self.path, fileN)
if os.path.isdir(path):
if os.path.splitext(path)[1] == ".move": continue
subfolders = get_immediate_subdirectories(path)
if len(subfolders) == 1:
if os.path.splitext(subfolders[0])[1] == ".rec":
path = os.path.join(path, subfolders[0])
if os.path.splitext(path)[1] == ".rec":
vdrRecordingFolder = vdrrecordingfolder.VdrRecordingFolder(path)
if firstTitle == None:
firstTitle = vdrRecordingFolder.title
else:
if vdrRecordingFolder.title != firstTitle:
onlySameTitle = False
recordingsList.append(vdrRecordingFolder)
dirs, files = xbmcvfs.listdir(self.path)
for dir in dirs:
if os.path.splitext(dir)[1] == ".move": continue
path = os.path.join(self.path, dir)
subfolders = get_immediate_subdirectories(path)
if len(subfolders) == 1:
if os.path.splitext(subfolders[0])[1] == ".rec":
path = os.path.join(path, subfolders[0])
if os.path.splitext(path)[1] == ".rec":
vdrRecordingFolder = vdrrecordingfolder.VdrRecordingFolder(path)
if firstTitle == None:
firstTitle = vdrRecordingFolder.title
else:
if vdrRecordingFolder.title != firstTitle:
onlySameTitle = False
recordingsList.append(vdrRecordingFolder)
else:
if len(subfolders) > 0:
# onlySameTitle = False
subfolderList.append([path, fileN])
subfolderList.append([path, dir])

if onlySameTitle and len(recordingsList) > 1:
# xbmc.log("onlySameTitle: " + str(self.path), xbmc.LOGERROR)
contentType = self.getContentType(constants.TV_SHOWS)
Expand Down Expand Up @@ -308,8 +316,8 @@ def addContextMenuCommand(commands, name, mode, url, arg3 = ''):
commands.append(( str(name), runner, ))

def get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name))]
dirs, files = xbmcvfs.listdir(a_dir)
return dirs

def build_url(base_url, query):
return base_url + '?' + urllib.urlencode(query)
21 changes: 15 additions & 6 deletions resources/lib/main.py
Expand Up @@ -9,6 +9,7 @@
import xbmcgui
import xbmcplugin
import xbmc
import xbmcvfs
import xbmcaddon
import constants

Expand Down Expand Up @@ -37,7 +38,7 @@ def __init__(self, argv):
self.mode = self.args.get('mode', ['folder'])[0]
addon = xbmcaddon.Addon('plugin.video.vdr.recordings')
self.rootFolder = addon.getSetting("rootFolder")
if not os.path.isdir(self.rootFolder):
if not xbmcvfs.exists(self.rootFolder):
xbmc.executebuiltin('Notification(Folder ' + self.rootFolder +
' does not exist.,Please select correct video folder in stettings., 50000)')
lastChar = self.rootFolder[-1]
Expand All @@ -56,6 +57,16 @@ def modeFolder(self):
# xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url,
# listitem=li, isFolder=True)

def createSeachList(self, sPath, searchList):
dirs, files = xbmcvfs.listdir(sPath)
for dirName in dirs:
if dirName[-4:] == ".rec":
# xbmc.log("createSeachList, recDirName= " + dirName, xbmc.LOGERROR)
searchList.append(VdrRecordingFolder(os.path.join(sPath, dirName)))
else:
self.createSeachList(os.path.join(sPath, dirName), searchList)


def doSearch(self, searchString):
# currentFolder = self.args.get('currentFolder', [self.rootFolder])[0]
# Add special (search) folder
Expand All @@ -64,13 +75,11 @@ def doSearch(self, searchString):
# xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url,
# listitem=li, isFolder=True)
searchList = []
for dirName, subdirList, fileList in os.walk(self.rootFolder, followlinks = True):
if dirName[-4:] == ".rec":
searchList.append(VdrRecordingFolder(dirName))
self.createSeachList(self.rootFolder, searchList)

searchStringL = string.lower(searchString)
searchStringL = searchString.lower()
for vdrRecordingFolder in searchList:
if string.find(string.lower(vdrRecordingFolder.title), searchStringL) >= 0:
if vdrRecordingFolder.title.lower().find(searchStringL) >= 0:
relRecordingPath = os.path.split(vdrRecordingFolder.path)[0][len(self.rootFolder)+1:].replace('_', ' ')
vdrRecordingFolder.description = relRecordingPath + '\n' + vdrRecordingFolder.description
# add context menu
Expand Down
18 changes: 10 additions & 8 deletions resources/lib/move.py
Expand Up @@ -9,6 +9,7 @@
import threading
import xbmc
import xbmcgui
import xbmcvfs

src = sys.argv[1]
dest = sys.argv[2]
Expand All @@ -17,17 +18,18 @@

def GetFolderSize(path):
TotalSize = 0.0
for item in os.walk(path):
for file in item[2]:
try:
TotalSize = TotalSize + os.path.getsize(os.path.join(item[0], file))
except:
print("error with file: " + os.path.join(item[0], file))
dirs, files = xbmcvfs.listdir(path)
for dir in dirs:
TotalSize = TotalSize + GetFolderSize(os.path.join(path, dir))

for file in files:
TotalSize = TotalSize + xbmcvfs.Stat(os.path.join(path, file)).st_size
return TotalSize


def move(t1, t2, tz, t3):
shutil.move(t1, t2)
shutil.move(tz, t3)
xbmcvfs.rename(t1, tz)
xbmcvfs.rename(tz, t3)
xbmc.executebuiltin("Container.Refresh")


Expand Down

0 comments on commit 06ec668

Please sign in to comment.