Browse Source

Final softchroot

* *settings.py* file is modified. Now - it saves chrotted settings correctly.
* Code blocks swapped (softchroot <-> browser )
* Method `is_root_abs` was added
* Tests added and improved
pull/5859/head
maxkoryukov 9 years ago
parent
commit
d932a2691f
  1. 69
      couchpotato/core/plugins/browser.py
  2. 33
      couchpotato/core/plugins/test_browser.py
  3. 8
      couchpotato/core/settings.py
  4. 9
      couchpotato/core/softchroot.py
  5. 10
      couchpotato/core/test_softchroot.py

69
couchpotato/core/plugins/browser.py

@ -10,7 +10,7 @@ from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import sp, ss, toUnicode
from couchpotato.core.helpers.variable import getUserDir
from couchpotato.core.plugins.base import Plugin
from couchpotato.core.softchroot import SoftChroot
log = CPLog(__name__)
@ -33,13 +33,9 @@ autoload = 'FileBrowser'
class FileBrowser(Plugin):
def __init__(self):
self.soft_chroot_enabled = False
self.soft_chroot = Plugin.conf(self, 'soft_chroot', section='core')
if None != self.soft_chroot:
self.soft_chroot = self.soft_chroot.strip()
self.soft_chroot = self.soft_chroot.rstrip(os.path.sep) + os.path.sep
self.soft_chroot_enabled = True
# could be better way (#getsoftchroot)
soft_chroot_dir = Plugin.conf(self, 'soft_chroot', section='core')
self.soft_chroot = SoftChroot(soft_chroot_dir)
addApiView('directory.list', self.view, docs = {
'desc': 'Return the directory list of a given directory',
@ -85,51 +81,18 @@ class FileBrowser(Plugin):
return driveletters
def soft_chroot_is_subdir(self, path):
if None == path:
return False
if not path.endswith(os.path.sep):
path += os.path.sep
return path.startswith(self.soft_chroot)
def soft_chroot_add(self, path):
if None == path or len(path)==0:
return self.soft_chroot
if not path.startswith(os.path.sep):
raise ValueError("path must starts with '/'")
return self.soft_chroot[:-1] + path
def soft_chroot_cut(self, path):
if None == path or 0==len(path):
raise ValueError('path is empty')
if path == self.soft_chroot.rstrip(os.path.sep):
return '/'
if not path.startswith(self.soft_chroot):
raise ValueError("path must starts with soft_chroot")
l = len(self.soft_chroot)-1
return path[l:]
def view(self, path = '/', show_hidden = True, **kwargs):
home = getUserDir()
if self.soft_chroot_enabled:
if not self.soft_chroot_is_subdir(home):
home = self.soft_chroot
if self.soft_chroot.enabled:
if not self.soft_chroot.is_subdir(home):
home = self.soft_chroot.chdir
if not path:
path = home
if path.endswith(os.path.sep):
path = path.rstrip(os.path.sep)
elif self.soft_chroot_enabled:
path = self.soft_chroot_add(path)
elif self.soft_chroot.enabled:
path = self.soft_chroot.add(path)
try:
dirs = self.getDirectories(path = path, show_hidden = show_hidden)
@ -137,8 +100,8 @@ class FileBrowser(Plugin):
log.error('Failed getting directory "%s" : %s', (path, traceback.format_exc()))
dirs = []
if self.soft_chroot_enabled:
dirs = map(self.soft_chroot_cut, dirs)
if self.soft_chroot.enabled:
dirs = map(self.soft_chroot.cut, dirs)
parent = os.path.dirname(path.rstrip(os.path.sep))
if parent == path.rstrip(os.path.sep):
@ -149,18 +112,18 @@ class FileBrowser(Plugin):
# TODO : check on windows:
is_root = path == '/'
if self.soft_chroot_enabled:
if self.soft_chroot.enabled:
# path could contain '/' on end, and could not contain..
# but in 'soft-chrooted' environment path could be included in chroot_dir only when it is root
is_root = self.soft_chroot.startswith(path)
is_root = self.soft_chroot.is_root_abs(path)
# fix paths:
if self.soft_chroot_is_subdir(parent):
parent = self.soft_chroot_cut(parent)
if self.soft_chroot.is_subdir(parent):
parent = self.soft_chroot.cut(parent)
else:
parent = os.path.sep
home = self.soft_chroot_cut(home)
home = self.soft_chroot.cut(home)
return {
'is_root': is_root,

33
couchpotato/core/plugins/test_browser.py

@ -6,6 +6,7 @@ from unittest import TestCase
#from mock import MagicMock
from couchpotato.core.plugins.browser import FileBrowser
from couchpotato.core.softchroot import SoftChroot
CHROOT_DIR = '/tmp/'
@ -14,8 +15,7 @@ class FileBrowserChrootedTest(TestCase):
self.b = FileBrowser()
# TODO : remove scrutch:
self.b.soft_chroot = CHROOT_DIR
self.b.soft_chroot_enabled = True
self.b.soft_chroot = SoftChroot(CHROOT_DIR)
# Logger
logger = logging.getLogger()
@ -27,34 +27,7 @@ class FileBrowserChrootedTest(TestCase):
#logger.addHandler(hdlr)
def test_soft_chroot_enabled(self):
self.assertTrue( self.b.soft_chroot_enabled)
def test_soft_chroot_is_subdir(self):
self.assertFalse( self.b.soft_chroot_is_subdir('') )
self.assertFalse( self.b.soft_chroot_is_subdir(None) )
self.assertTrue( self.b.soft_chroot_is_subdir(CHROOT_DIR) )
noslash = CHROOT_DIR[:-1]
self.assertTrue( self.b.soft_chroot_is_subdir(noslash) )
self.assertTrue( self.b.soft_chroot_is_subdir(CHROOT_DIR + 'come') )
def test_soft_chroot_add(self):
with self.assertRaises(ValueError):
self.b.soft_chroot_add('no_leading_slash')
self.assertEqual( self.b.soft_chroot_add(None), CHROOT_DIR )
self.assertEqual( self.b.soft_chroot_add(''), CHROOT_DIR )
self.assertEqual( self.b.soft_chroot_add('/asdf'), CHROOT_DIR + 'asdf' )
def test_soft_chroot_cut(self):
with self.assertRaises(ValueError): self.b.soft_chroot_cut(None)
with self.assertRaises(ValueError): self.b.soft_chroot_cut('')
self.assertEqual( self.b.soft_chroot_cut(CHROOT_DIR + 'asdf'), '/asdf' )
self.assertEqual( self.b.soft_chroot_cut(CHROOT_DIR), '/' )
self.assertEqual( self.b.soft_chroot_cut(CHROOT_DIR.rstrip(os.path.sep)), '/' )
self.assertTrue( self.b.soft_chroot.enabled)
def test_view__chrooted_path_none(self):
#def view(self, path = '/', show_hidden = True, **kwargs):

8
couchpotato/core/settings.py

@ -7,7 +7,7 @@ from couchpotato.api import addApiView
from couchpotato.core.event import addEvent, fireEvent
from couchpotato.core.helpers.encoding import toUnicode
from couchpotato.core.helpers.variable import mergeDicts, tryInt, tryFloat
from couchpotato.core.softchroot import SoftChroot
class Settings(object):
@ -210,6 +210,12 @@ class Settings(object):
option = kwargs.get('name')
value = kwargs.get('value')
if self.types[section][option] == 'directory':
# could be better way (#getsoftchroot)
soft_chroot_dir = self.get(option = 'soft_chroot', section = 'core', default = None )
soft_chroot = SoftChroot(soft_chroot_dir)
value = soft_chroot.add(str(value))
# See if a value handler is attached, use that as value
new_value = fireEvent('setting.save.%s.%s' % (section, option), value, single = True)

9
couchpotato/core/softchroot.py

@ -13,6 +13,15 @@ class SoftChroot:
self.chdir = self.chdir.rstrip(os.path.sep) + os.path.sep
self.enabled = True
def is_root_abs(self, abspath):
if not self.enabled:
raise Exception('chroot disabled')
if None == abspath:
return False
path = abspath.rstrip(os.path.sep) + os.path.sep
return self.chdir == path
def is_subdir(self, path):
if not self.enabled:
return True

10
couchpotato/core/test_softchroot.py

@ -26,6 +26,16 @@ class SoftChrootEnabledTest(TestCase):
self.assertTrue( self.b.is_subdir(CHROOT_DIR + 'come') )
def test_is_root_abs(self):
self.assertFalse( self.b.is_root_abs('') )
self.assertFalse( self.b.is_root_abs(None) )
self.assertTrue( self.b.is_root_abs(CHROOT_DIR) )
noslash = CHROOT_DIR[:-1]
self.assertTrue( self.b.is_root_abs(noslash) )
self.assertFalse( self.b.is_root_abs(CHROOT_DIR + 'come') )
def test_add(self):
with self.assertRaises(ValueError):
self.b.add('no_leading_slash')

Loading…
Cancel
Save