Esempio n. 1
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)
Esempio n. 2
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"
Esempio n. 3
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)
Esempio n. 4
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
Esempio n. 5
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 )
Esempio n. 6
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 )