Ejemplo n.º 1
0
    def clear(self, path, older=None, signal=True):
        """
        Remove all files and dirs in ``path`` directory.
        ``older`` takes seconds for max age from created_time, only top sub dirs checked.
        On not exist raise :class:`~limited.core.files.storage.FileNotExist`.
        On not directory raise :class:`~limited.core.files.storage.FileError`.
        """
        path = self.check(path)
        if signal:
            file_pre_change.send(self, basedir=FilePath.dirname(path))

        if not self.fs.exists(path):
            raise FileNotExist(u"'%s' not found" % path)
        if not self.fs.isdir(path):
            raise FileError(u"'%s' not directory" % path)
        if signal:
            file_pre_change.send(self, basedir=FilePath.dirname(path))
        if older == None:
            for item in self.fs.list(path):
                file = FilePath.join(path, item)
                self.fs.remove(file)
        else:
            for item in self.fs.list(path):
                file = FilePath.join(path, item)
                chenaged = self.fs.created_time(file)
                if datetime.now() - chenaged > timedelta(seconds=older):
                    self.fs.remove(file)
Ejemplo n.º 2
0
    def zip(self, path, file=None, override=None, signal=False):
        """
        Zip file or directory ``path`` to ``file`` or to ``path + '.zip'``.
        On not exist raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        path = self.check(path)
        if not self.fs.exists(path):
            raise FileNotExist(u"'%s' not found" % path)

        if file == None:
            file = self.available_name(path + u".zip", override=override)
        if signal:
            file_pre_change.send(self, basedir=FilePath.dirname(path))

        newfile = file + u".part"
        try:
            zfile = self.fs.open(newfile, mode='wb')
            archive = zipfile.ZipFile(zfile, 'w', zipfile.ZIP_DEFLATED)
            if self.fs.isdir(path):
                dirname = FilePath.name(path)
                for abspath, name in self.fs.listfiles(path).items():
                    name = FilePath.join(dirname, name)
                    archive.write(abspath, name)
            elif self.fs.isfile(path):
                archive.write(self.fs.abspath(path), FilePath.name(path))

            archive.close()
            zfile.seek(0)
            self.fs.rename(newfile, FilePath.name(file))
        except EnvironmentError as e:
            if e.errno == errno.EACCES:
                raise FileError(u"IOError, zip. Permission denied '%s'" % path)
        finally:
            if self.fs.exists(newfile):
                self.fs.remove(newfile)
Ejemplo n.º 3
0
 def rename(self, path, name):
     """
     Rename file or dir path ``path`` to name ``name``.
     On '/' in ``name`` raise :class:`~limited.core.files.storage.FileError`.
     On not exist or already exist raise :class:`~limited.core.files.storage.FileNotExist`.
     """
     new_path = FilePath.join(FilePath.dirname(path), name)
     try:
         os.rename(self.abspath(path), self.abspath(new_path))
     except EnvironmentError as e:
         if e.errno == errno.EACCES:
             raise FileError(u"IOError, rename. Permission denied '%s'" %
                             path)
Ejemplo n.º 4
0
 def check(path):
     """
     Return norm path or raise FileError
     if path is hidden raise FileNotExist
     """
     path = FilePath.norm( path )
     if not FilePath.check(path):
         raise FileError( u"IOError, Permission denied" )
         #TODO: TRASH and CACHE are visible, is is not good.
     if path.startswith( u'.' ) or u'/.' in path:
         if settings.LIMITED_TRASH_PATH not in path and settings.LIMITED_CACHE_PATH not in path:
             raise FileNotExist( u"path '%s' doesn't exist or it isn't a directory" % path )
     return path
Ejemplo n.º 5
0
    def move(self, src, dst):
        """
        Move file or dir from ``src`` to ``dst``.
        On the same directory raise :class:`~limited.core.files.storage.FileError`.
        On not exist for both paths raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        name = FilePath.name(src)

        dst = FilePath.join(dst, name)
        dst = self.available_name(dst)
        try:
            shutil.move(self.abspath(src), self.abspath(dst))
        except EnvironmentError as e:
            if e.errno == errno.EACCES:
                raise FileError(u"IOError, move. Permission denied '%s'" % src)
Ejemplo n.º 6
0
    def listdir(self, path, hidden=False):
        """
        Return list of files in directory.
        Each item is a dict with class:'file'|'dir', name: file name, url - url encode path,
        size: file size, time: modified_time.
        If ``hidden`` ``True`` than hidden files will be include.
        Data sorted first by name and than by directory.
        On not dir exist raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        tmp = self.list(path)
        files = []
        if not hidden:
            tmp = filter(lambda x: x.startswith('.') == 0, tmp)

        for item in tmp:
            fullpath = FilePath.join(path, item)
            if self.isfile(fullpath): ccl = 'file'
            if self.isdir(fullpath): ccl = 'dir'

            files.append({
                'class': ccl,
                'name': item,
                'url': self.url(fullpath),
                'size': self.size(fullpath),
                'time': self.modified_time(fullpath),
            })

        files = sorted(files, key=lambda strut: strut['name'])
        files = sorted(files, key=lambda strut: strut['class'], reverse=False)
        return files
Ejemplo n.º 7
0
    def size(self, name, dir=False, cached=True):
        """
        Return dir and files size. If ``dir`` ``True``, size will be sum recursive else return 0
        if ``cached``, dirs size will be cached.
        On not exist raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        if not self.exists(name):
            raise FileNotExist(u"'%s' not found" % name)

        if self.isfile(name):
            return os.path.getsize(self.abspath(name))

        if dir and self.isdir(name):
            key = md5("storage.size" + smart_str(name)).hexdigest()
            if cached:
                size = cache.get(key)
                if size != None:
                    return size

            size = 0
            for item in os.listdir(self.abspath(name)):
                file = FilePath.join(name, item)
                size += self.size(file, dir=True, cached=cached)

            if cached: cache.set(key, size, 120)
            return size
        return 0
Ejemplo n.º 8
0
def DownloadView( request, id ):
    """
    Download files, folders whit checked permissions
    GET 'h' - home id, 'p' - path
    """
    if request.user.is_anonymous( ) and not settings.LIMITED_ANONYMOUS:
        return HttpResponseRedirect( '%s?next=%s' % (settings.LOGIN_URL, request.path) )

    if request.method == u"GET":
        lib_id = int( id )
        path = request.GET.get( 'p', '' )
        if not FilePath.check(path, norm=True):
            logger.error( u"Files. Path check fail. home_id:{0}, path:{1}".format( lib_id, path ) )
            return RenderError( request, u"IOError, Permission denied" )

        try:
            home = get_home( request.user, lib_id )
            manager = DownloadManager( home.lib )
            if manager.is_need_processing( path ):
                manager.process( path )
                messages.info( request, u"File to big and need time to process. Try again a little bit later" )
                return HttpResponseReload( request )
            else:
                response = manager.build( path )

        except ObjectDoesNotExist:
            logger.error( u"Download. No such file lib or you don't have permissions. home_id:{0}".format( lib_id ) )
            return RenderError( request, u"No such file lib or you don't have permissions" )
        except FileNotExist as e:
            logger.error( u"Download. No file or directory find. home_id:{0}, path:{1}".format( lib_id, path ) )
            return RenderError( request, u"No file or directory find" )

        return response
Ejemplo n.º 9
0
 def open(self, path, mode='rb', signal=True):
     """
     Return open django :class:`~django.core.files.base.File` instance
     """
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(path))
     path = self.check(path)
     return self.fs.open(path, mode)
Ejemplo n.º 10
0
 def get_path(self, root=None):
     """
     Return absolute path.
     If root is None FileLib.path will be added to LIMITED_ROOT_PATH.
     """
     if root == None:
         root = settings.LIMITED_ROOT_PATH
     return FilePath.join(root, self.path)
Ejemplo n.º 11
0
 def create(self, path, content, signal=True):
     """
     Write to file ``path`` same data ``content``
     """
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(path))
     newfile = self.fs.open(path, 'wb')
     newfile.write(content)
     newfile.close()
Ejemplo n.º 12
0
    def rename(self, path, name, signal=True):
        """
        Rename file or dir path ``path`` to name ``name``.
        On '/' in ``name`` raise :class:`~limited.core.files.storage.FileError`.
        On not exist or already exist raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        path = self.check(path)
        if '/' in name:
            raise FileError(u"'%s' contains not supported symbols" % name)
        if not self.exists(path):
            raise FileNotExist(u"'%s' not found" % path)

        new_path = FilePath.join(FilePath.dirname(path), name)
        if self.exists(new_path):
            raise FileError(u"'%s' already exist!" % name)
        if signal:
            file_pre_change.send(self, basedir=FilePath.dirname(path))
        self.fs.rename(path, name)
Ejemplo n.º 13
0
 def move(self, src, dst, signal=True):
     """
     Move file or dir from ``src`` to ``dst``.
     On the same directory raise :class:`~limited.core.files.storage.FileError`.
     On not exist for both paths raise :class:`~limited.core.files.storage.FileNotExist`.
     """
     src_dir = FilePath.dirname(src)
     if src == dst or src_dir == dst:
         raise FileError(u"Moving to the same directory")
     if not self.exists(src):
         raise FileNotExist(u"'%s' not found" % src)
     if not self.exists(dst):
         raise FileNotExist(u"'%s' not found" % dst)
     src = self.check(src)
     dst = self.check(dst)
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(src))
         file_pre_change.send(self, basedir=dst)
     self.fs.move(src, dst)
Ejemplo n.º 14
0
 def remove(self, path, signal=True):
     """
     Remove directory or file, on not exist raise :class:`~limited.core.files.storage.FileNotExist`
     """
     path = self.check(path)
     if not self.exists(path):
         raise FileNotExist(u"'%s' not found" % path)
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(path))
     self.fs.remove(path)
Ejemplo n.º 15
0
    def test_list_files(self):
        """
        Test listfiles
        """
        assert self.storage.fs.listfiles(u"Test Folder").__len__() == 0

        abs = self.lib.get_path()
        real = {
            FilePath.join(abs, u"content.txt"): u"content.txt",
            FilePath.join(abs, u"Фото 007.bin"): u"Фото 007.bin",
        }
        assert self.storage.fs.listfiles("") == real

        self.storage.extra.create(u"Test Folder/test.bin", u"Test")
        real.update({
            FilePath.join(abs, u'Test Folder/test.bin'):
            u'Test Folder/test.bin'
        })
        assert self.storage.fs.listfiles("") == real
Ejemplo n.º 16
0
 def save(self, path, file, override=True, signal=True):
     """
     Return path to the file, that can be another from ``path``.
     Copy to disk to ``path`` open :class:`~django.core.files.base.File` object ``file``.
     Also you need to close it yourself.
     """
     path = self.check(path)
     path = self.available_name(path, override)
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(path))
     return self.fs.save(path, file)
Ejemplo n.º 17
0
 def totrash(self, path, signal=True):
     """
     Shortcut for :func:`~limited.core.files.storage.FileStorage.move`
     where second var is :ref:`LIMITED_TRASH_PATH <SETTINGS_TRASH_PATH>`.
     """
     path = self.check(path)
     if signal:
         file_pre_change.send(self, basedir=FilePath.dirname(path))
     if not self.fs.exists(settings.LIMITED_TRASH_PATH):
         self.fs.mkdir(settings.LIMITED_TRASH_PATH)
     if not self.fs.exists(path):
         raise FileNotExist(u"'%s' not found" % path)
     self.fs.move(path, settings.LIMITED_TRASH_PATH)
Ejemplo n.º 18
0
 def download(self, url, path, signal=True):
     """
     Download file from ``url`` to file ``path``.
     The process goes to a file ``path + '.part'``.
     On error file will be remove.
     To get file name from url use :class:`~limited.core.utils.url_get_filename`.
     """
     path = self.check(path)
     path = self.fs.available_name(path)
     newfile = path + u".part"
     try:
         # simple hook to stop File proxy access field 'name'
         # that is no exists
         if signal:
             file_pre_change.send(self, basedir=FilePath.dirname(path))
         data = urllib.urlopen(iri_to_uri(url))
         data.size = int(data.info()['Content-Length'])
         self.fs.save(newfile, File(data))
         self.fs.rename(newfile, FilePath.name(path))
     except Exception:
         if self.fs.exists(newfile):
             self.fs.remove(newfile)
         raise
Ejemplo n.º 19
0
    def test_Clear(self):
        """
        Test ActionClear.

        test with not stuff user and with administrator
        """
        link_cache = urlbilder( u'clear', self.lib.id, u'cache' )
        link_trash = urlbilder( u'clear', self.lib.id, u'trash' )

        file_cache = FilePath.join( settings.LIMITED_CACHE_PATH, u"test.bin" )
        file_trash = FilePath.join( settings.LIMITED_TRASH_PATH, u"test.bin" )

        self.storage.extra.create( file_cache, u"Test" )
        self.storage.extra.create( file_trash, u"Test" )

        self.client.login( username='******', password='******' )

        resp = self.client.get( link_cache, follow=True )
        assert resp.status_code == 200
        assert escape( u"You have no permission to clear cache" ) in unicode( resp.content, errors='ignore' )
        assert self.storage.exists( file_cache ) == True

        resp = self.client.get( link_trash, follow=True )
        assert resp.status_code == 200
        assert escape( u"You have no permission to clear trash" ) in unicode( resp.content, errors='ignore' )
        assert self.storage.exists( file_trash ) == True

        self.client.login( username='******', password='******' )

        resp = self.client.get( link_cache )
        assert resp.status_code == 302
        assert self.storage.exists( file_cache ) == False

        resp = self.client.get( link_trash )
        assert resp.status_code == 302
        assert self.storage.exists( file_trash ) == False
Ejemplo n.º 20
0
    def unzip(self, path, override=True, signal=False):
        """
        Unzip file or directory ``path``.
        On not exist raise :class:`~limited.core.files.storage.FileNotExist`.
        """
        path = self.check(path)
        if not self.fs.exists(path):
            raise FileNotExist(u"'%s' not found" % path)

        file = self.fs.abspath(path)
        directory = FilePath.dirname(path)
        # To lazy to do converting
        # maybe chardet help later
        if signal:
            file_pre_change.send(self, basedir=FilePath.dirname(path))
        zip = None
        try:
            zip = zipfile.ZipFile(file, 'r')

            for name in zip.namelist():
                try:
                    unicode_name = unicode(name)
                except UnicodeDecodeError:
                    unicode_name = unicode(name.decode('cp866'))

                full_path = FilePath.join(directory, unicode_name)
                dir_path = FilePath.dirname(unicode_name)
                if dir_path != '':
                    tmp = directory
                    for item in FilePath.split(dir_path):
                        tmp = FilePath.join(tmp, item)
                        if not self.fs.exists(tmp):
                            self.fs.mkdir(tmp)

                if not unicode_name.endswith('/'):
                    with self.fs.open(full_path, 'w') as f:
                        f.write(zip.open(name).read())

        except UnicodeDecodeError as e:
            raise FileError(u"Unicode decode error '%s', try unzip yourself" %
                            path)
        except zipfile.BadZipfile as e:
            raise FileError(u"Bad zip file '%s'" % path)
        except EnvironmentError as e:
            if e.errno == errno.EACCES:
                raise FileError(u"IOError, unzip. Permission denied '%s'" %
                                path)
        finally:
            if zip:
                zip.close()
Ejemplo n.º 21
0
def split_path(path):
    """
    Split path for folders name
    with path fot this name

    Example::

        /root/path1/path2 ->
        root:/root, path1:/root/path2, path2:/root/path1/path2
    """
    def _split_path(path, data):
        name = os.path.basename(path)
        if name != '':
            newpath = os.path.dirname(path)
            data = _split_path(newpath, data)
            data.append((name, path))
            return data
        return data

    return _split_path(FilePath.norm(path), [])
Ejemplo n.º 22
0
def remove_cache( sender, **kwargs ):
    """
    Signal receiver function.
    It is delete cache files of all parent dirs
    if some files changed in directory.
    """
    HashBilder = FileUnicName( )
    lib = sender.lib
    dir = kwargs["basedir"]
    # if not system directories
    if not dir.startswith( settings.LIMITED_CACHE_PATH ) and dir != settings.LIMITED_TRASH_PATH:
        try:
            node = lib.cache.getName( *FilePath.split( dir ) )
            if node != None:
                node.setHash( HashBilder.time( ) )
                from limited.core.models import FileLib

                FileLib.objects.filter( id=lib.id ).update( cache=lib.cache )
        except Exception as e:
            logger.error( u"{0}. dir:{1}".format( e, dir ) )
Ejemplo n.º 23
0
 def homepath(self, path):
     """
     Return path from :ref:`LIMITED_ROOT_PATH <SETTINGS_ROOT_PATH>`
     """
     path = self.check( path )
     return FilePath.join( self.lib.path, path )
Ejemplo n.º 24
0
    def test_Anon_Action(self):
        """
        Test Action for Anonymous
        in  ID1: FileManager
        with  ID5: Edit False, Move False, Delete False, Create True, Upload False, Http_get False,
        """
        self.setAnonymous(True)

        storage = self.lib2.getStorage()
        # add True
        link = urlbilder('action', self.lib2.id, "add", p='', n='new dir')
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'created' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        storage.remove(FilePath.join('', 'new dir'))
        # delete False
        link = urlbilder('action', self.lib2.id, "delete", p=u"Фото 007.bin")
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'You have no permission' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        # trash False
        link = urlbilder('action', self.lib2.id, "trash", p=u"Фото 007.bin")
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'You have no permission' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        # rename False
        link = urlbilder('action',
                         self.lib2.id,
                         "rename",
                         p=u"Фото 007.bin",
                         n='Фото070.jpg')
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'You have no permission' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        # move False
        link = urlbilder('action',
                         self.lib2.id,
                         "move",
                         p=u"Фото 007.bin",
                         n='/')
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'You have no permission' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        # link True
        link = urlbilder('action', self.lib2.id, "link", p=u"Фото 007.bin")
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'link' in [m.message for m in list(resp.context['messages'])][0]
        # zip False
        link = urlbilder('action', self.lib2.id, "zip", p=u"Фото 007.bin")
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        assert resp.context['messages'].__len__() == 1
        assert 'You have no permission' in [
            m.message for m in list(resp.context['messages'])
        ][0]
        # size very simple dir test
        link = urlbilder('action', self.lib2.id, "size", p='docs')
        resp = self.client.get(link, follow=True)
        assert resp.status_code == 200
        size = filesizeformat(storage.size('docs', dir=True, cached=False))
        assert size == resp.content.strip()
Ejemplo n.º 25
0
 def abspath(self, name):
     """
     Return absolute filesystem path to file
     """
     return FilePath.join(self.root, name)
Ejemplo n.º 26
0
def FilesView( request, id ):
    """
    Main browser and history widget

    template :template:`limited/browser.html`
    """
    user = request.user
    if user.is_anonymous( ) and not settings.LIMITED_ANONYMOUS:
        return HttpResponseRedirect( '%s?next=%s' % (settings.LOGIN_URL, request.path) )

    lib_id = int( id )
    path = request.GET.get( 'p', '' )
    if not FilePath.check(path, norm=True):
        logger.error( u"Files. Path check fail. home_id:{0}, path:{1}".format( lib_id, path ) )
        return RenderError( request, u"IOError, Permission denied" )

    try:
        home = get_home( user, lib_id )

        history = History.objects.\
                  select_related( 'user' ).\
                  only( 'lib', 'type', 'files', 'path', 'extra', 'user__username' ).\
                  filter( lib=lib_id ).\
                  order_by( '-id' )[0:8]

        patharr = split_path( path )

        File = home.lib.getStorage( )
        files = File.listdir( path )

        # Check if iViewer is enable and there is at least 2 jpg
        lViewer = False
        if settings.LIMITED_LVIEWER:
            images = 0
            for file in files:
                tmp = file["name"].lower( )
                if tmp.endswith( ".jpg" ) or tmp.endswith( ".jpeg" ):
                    images += 1
            lViewer = images > 1

        allowed = {}
        allowed['only'] = '|'.join( settings.LIMITED_FILES_ALLOWED["ONLY"] ).replace( '\\', '\\\\' )
        allowed['except'] = '|'.join( settings.LIMITED_FILES_ALLOWED["EXCEPT"] ).replace( '\\', '\\\\' )
        allowed['message'] = settings.LIMITED_FILES_MESSAGE

        rss_token = None if user.is_anonymous() else Profile.objects.get(user=user).rss_token

    except ObjectDoesNotExist:
        logger.error( u"Files. No such file lib or you don't have permissions. home_id:{0}, path:{1}".format( lib_id, path ) )
        return RenderError( request, u"No such file lib or you don't have permissions" )
    except FileError as e:
        logger.error( u"Files. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
        return RenderError( request, e )

    return render( request, u"limited/files.html", {
        'pathname': request.path,
        'path': path,
        'patharr': patharr,
        'history': history,
        'home_id': lib_id,
        'home': home.lib.name,
        'permission': home.permission,
        'files': files,
        'allowed': allowed,
        'rss_token': rss_token,
        'lviewer': lViewer,
        } )
Ejemplo n.º 27
0
    def test_storage_path(self):
        """
        Test FilePath class
        """
        assert FilePath.join(u"path", "name") == u"path/name"
        assert FilePath.join(u"/path", "name") == u"/path/name"
        assert FilePath.join(u"/root/path", "name") == u"/root/path/name"
        assert FilePath.join(u"/path/", "name") == u"/path/name"
        assert FilePath.join(u"/path/", "/name") == u"/path/name"

        assert FilePath.name(u"/path/name") == u"name"
        assert FilePath.name(u"/path/name") == u"name"
        assert FilePath.name(u"/path/name/") == u""

        assert FilePath.dirname(u"/path/name/") == u"/path/name"
        assert FilePath.dirname(u"/path/name/file") == u"/path/name"
        assert FilePath.dirname(u"/path/name/file.ext") == u"/path/name"

        assert FilePath.norm(u"root/file.ext") == u"root/file.ext"
        assert FilePath.norm(u"root/base/../file.ext") == u"root/file.ext"
        assert FilePath.norm(u"root/base/.././file.ext") == u"root/file.ext"
        assert FilePath.norm(u"root/base/../../file.ext") == u"file.ext"
        assert FilePath.norm(u"root/./file.ext") == u"root/file.ext"
        assert FilePath.norm(u"root/././file.ext") == u"root/file.ext"
Ejemplo n.º 28
0
def UploadView( request, id ):
    """
    Files upload to
    POST 'h' - home id, 'p' - path, 'files'
    """
    if request.user.is_anonymous( ) and not settings.LIMITED_ANONYMOUS:
        return HttpResponseRedirect( '%s?next=%s' % (settings.LOGIN_URL, request.path) )

    lib_id = int( id )
    path = request.POST['p']
    if not FilePath.check(path, norm=True):
        logger.error( u"Files. Path check fail. home_id:{0}, path:{1}".format( lib_id, path ) )
        return RenderError( request, u"IOError, Permission denied" )

    if request.method == u"POST":
        file_paths = []
        try:
            # file paths to delete them after any Exception
            home = get_home( request.user, lib_id )
            if not home.permission.upload:
                raise PermissionError( u"You have no permission to upload" )

            user = get_user( request.user )
            storage = home.lib.getStorage( )

            files = request.FILES.getlist( u'files' )

            if not len( files ):
                messages.warning( request, u"No any files selected" )
                return HttpResponseReload( request )

            for file in files:
                if not check_file_name( file.name ):
                    raise PermissionError( settings.LIMITED_FILES_MESSAGE.format( file.name ) )

            history = History( user=user, lib=home.lib, type=History.UPLOAD, path=path )

            for file in files:
                fool_path = FilePath.join( path, file.name )
                name = storage.save( fool_path, file )
                file_paths.append( name )
            history.files = [FilePath.name( i ) for i in file_paths]
            history.save( )

            if settings.LIMITED_EMAIL_NOTIFY['ENABLE']:
                domain = Site.objects.get_current( ).domain
                link = urlbilder( u"browser", lib_id, p=history.path )
                libs = Home.objects.filter( lib_id=lib_id )
                users = [i.user_id for i in libs]

                notify = MailFileNotify( )
                notify.body = u"New files upload to '{0}' by user {1}\n".format(path or '/', history.user)
                notify.body += u"Link http://{0}{1}&hl={2}\n".format(domain, link, history.hash())
                notify.files = [i.name for i in files]
                notify.users = users
                # Hack to stay in one thread and test mail.outbox
                notify.run( ) if settings.TEST else notify.start( )

        except ObjectDoesNotExist:
            logger.error( u"Upload. No such file lib or you don't have permissions. home_id:{0}".format( lib_id ) )
            return RenderError( request, u"No such file lib or you don't have permissions" )
        except PermissionError as e:
            logger.info( u"Upload. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )
        except Exception:
            for file in file_paths:
                if storage.exists( file ):
                    storage.remove( file )
            raise

    return HttpResponseReload( request )
Ejemplo n.º 29
0
def ActionView( request, id, command ):
    """
    Action add, delete, rename, movem link
    GET 'h' - home id, 'p' - path
    than redirect back
    """
    if request.user.is_anonymous( ) and not settings.LIMITED_ANONYMOUS:
        return HttpResponseRedirect( '%s?next=%s' % (settings.LOGIN_URL, request.path) )

    lib_id = int( id )
    path = request.GET.get( 'p', '' )
    if not FilePath.check(path, norm=True):
        logger.error( u"Files. Path check fail. home_id:{0}, path:{1}".format( lib_id, path ) )
        return RenderError( request, u"IOError, Permission denied" )

    home = get_home( request.user, lib_id )
    user = get_user( request.user )
    Storage = home.lib.getStorage( )

    history = History( lib=home.lib )
    history.path = FilePath.dirname( path )
    # GET 'n' - folder name
    if command == u"add":
        try:
            if not home.permission.create:
                raise PermissionError( u"You have no permission to create new directory" )
            name = request.GET['n']
            # If it link - download it
            # No any messages on success
            if name.startswith( u"http://" ) or name.startswith( u"https://" ):
                if not home.permission.http_get:
                    raise PermissionError( u"You have no permission to upload from url" )
                filename = url_get_filename( name )
                path = FilePath.join( path, filename )
                #TODO: F*****g TransactionManagementError don't now how to fix
                # In a Thread we set signal=False to not update DB
                T = Thread( )
                T.setView( Storage.extra.download, name, path, signal=False )
                T.run( ) if settings.TEST else T.start( )
                messages.success( request, u"file '%s' added for upload" % filename )
            # Just create new directory
            else:
                if u'/' in name or u'\\' in name:
                    raise FileError( u"Not supported symbols" )
                if not check_file_name( name ):
                    raise PermissionError( u"This name of directory '{0}' is not allowed for creating!".format( name ) )
                dir = FilePath.join( path, name )
                Storage.mkdir( dir )
                messages.success( request, u"directory '%s' successfully created" % name )
                #history.message = "dir '%s' created" % name
                #history.type = History.CREATE
                #history.path = dir
                #history.save( )

        except ( PermissionError, FileError ) as e:
            logger.error( u"Action add. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    # Delete from FS
    elif command == u"delete":
        try:
            if not home.permission.delete:
                raise PermissionError( u'You have no permission to delete' )
            Storage.remove( path )
            messages.success( request, u"'%s' successfully deleted" % FilePath.name( path ) )
            history.user = user
            history.type = History.DELETE
            history.files = FilePath.name( path )
            history.save( )
        except ( PermissionError, FileError ) as e:
            logger.error( u"Action delete. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    # Move to special directory
    elif command == u"trash":
        try:
            if not home.permission.delete:
                raise PermissionError( u"You have no permission to delete" )
            Storage.trash.totrash( path )
            messages.success( request, u"'%s' successfully moved to trash" % FilePath.name( path ) )
            history.user = user
            history.type = History.TRASH
            history.files = FilePath.name( path )
            history.save( )
        except ( PermissionError, FileError ) as e:
            logger.error( u"Action trash. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    # GET 'n' - new file name
    elif command == u"rename":
        try:
            if not home.permission.edit:
                raise PermissionError( u"You have no permission to rename" )
            name = request.GET['n']
            if not check_file_name( name ):
                raise PermissionError( u"This name '{0}' is invalided!".format( name ) )
            Storage.rename( path, name )
            messages.success( request, u"'%s' successfully rename to '%s'" % ( FilePath.name( path ), name) )
            history.user = user
            history.type = History.RENAME
            history.files = name
            history.save( )
        except ( PermissionError, FileError ) as e:
            logger.error( u"Action rename. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    # GET 'p2' - new directory path
    elif command == u"move":
        try:
            if not home.permission.move:
                raise PermissionError( u"You have no permission to move" )
            path2 = request.GET['p2']
            if path2[0] == u'/':
                path2 = path2[1:]
                Storage.move( path, path2 )
            elif path2[0] == u'.':
                tmp = FilePath.join( FilePath.dirname( path ), path2 )
                path2 = FilePath.norm( tmp )
                Storage.move( path, path2 )
            else:
                path2 = FilePath.join( FilePath.dirname( path ), path2 )
                Storage.move( path, path2 )
            messages.success( request, u"'%s' successfully moved to '%s'" % ( FilePath.name( path ), path2) )
            history.user = user
            history.type = History.MOVE
            history.files = FilePath.name( path )
            history.path = path2
            history.save( )
        except ( PermissionError, FileError ) as e:
            logger.error( u"Action move. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    elif command == u"link":
        try:
            domain = Site.objects.get_current( ).domain
            link = Link.objects.find( Link.get_hash( home.lib_id, path ) )
            # if exist and not expired
            if link:
                messages.success( request, u"link already exists <a href=\"http://{0}/link/{1}\">http://{0}/link/{1}<a>".format( domain, link.hash ) )
            # else create new one
            elif home.permission.create:
                link = Link.objects.add( home.lib, path )

                messages.success( request, u"link successfully created to '<a href=\"http://{0}/link/{1}\">http://{0}/link/{1}<a>'".format( domain, link.hash ) )
                history.user = user
                history.type = History.LINK
                history.files = FilePath.name( path )
                history.extra = link.hash
                history.path = FilePath.dirname( path )
                history.save( )
            else:
                logger.error( u"Action link. You have no permission to create links. home_id:{0}, path:{0}".format( lib_id, path ) )
                raise PermissionError( u"You have no permission to create links" )

        except ( PermissionError, FileError ) as e:
            logger.info( u"Action link. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    elif command == u"zip":
        try:
            if not home.permission.edit:
                raise PermissionError( u"You have no permission to zip" )

            if path.endswith( u".zip" ):
                Storage.extra.unzip( path )
            else:
                Storage.extra.zip( path )
        except ( PermissionError, FileError ) as e:
            logger.info( u"Action zip. {0}. home_id:{1}, path:{2}".format( e, lib_id, path ) )
            messages.error( request, e )

    elif command == u"size":
        size = Storage.size( path, dir=True, cached=True )
        size = filesizeformat( size )
        return HttpResponse( size )

    return HttpResponseReload( request )