def get_not_conflict_poolname(self, account, path):
        ret = False
        new_path = path
        pool_dbo = DboPool(self.application.sql_client)
        current_user = {
            'account': account,
            'poolid': pool_dbo.get_root_pool(account)
        }
        metadata_manager = MetaManager(self.application.sql_client,
                                       current_user, new_path)
        if not metadata_manager.get_path() is None:
            for i in range(100000):
                new_path = "%s(%d)" % (path, i)
                metadata_manager.init_with_path(current_user, new_path)
                if metadata_manager.get_path() is None:
                    #bingo
                    ret = True
                    break
        else:
            #bingo
            ret = True

        return ret, new_path
示例#2
0
class GetTempLinkHandler(BaseHandler):
    def post(self):
        #self.set_header('Content-Type','application/json')

        dbo_temp_link = DboTempLink(self.application.sql_client)

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        _body = None
        if is_pass_check:
            #logging.info('%s' % (str(self.request.body)))
            is_pass_check = False
            try:
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        path = None
        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try:
                    if 'path' in _body:
                        path = _body['path']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            if path == "/":
                #PS: dropbox not all path='/''
                path = ""

            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if len(path) == 0:
                errorMessage = "path is empty"
                errorCode = 1011
                is_pass_check = False

        if is_pass_check:
            #logging.info('path %s' % (path))
            self.metadata_manager = MetaManager(self.application.sql_client,
                                                self.current_user, path)

            if not self.metadata_manager.real_path is None:
                if not os.path.isfile(self.metadata_manager.real_path):
                    errorMessage = "path on server not found"
                    errorCode = 1020
                    is_pass_check = False

        query_result = None
        if is_pass_check:
            query_result = self.metadata_manager.get_path()
            if query_result is None:
                errorMessage = "metadata not found"
                errorCode = 1021
                is_pass_check = False

        temp_link = None
        if is_pass_check:
            temp_link = "%ss-%s-%s" % (utils.get_token(),
                                       query_result['content_hash'],
                                       utils.get_token())
            while dbo_temp_link.pk_exist(temp_link):
                temp_link = "%ss-%-%s" % (utils.get_token(),
                                          query_result['content_hash'],
                                          utils.get_token())
            ret = False
            for i in range(3):
                # may conflict...
                ret = dbo_temp_link.add(temp_link,
                                        self.metadata_manager.poolid,
                                        query_result['id'],
                                        query_result['content_hash'],
                                        self.current_user['account'])
                if ret:
                    break
            if not ret:
                errorMessage = "add temp_link into database fail."
                errorCode = 1022
                is_pass_check = False

        ret_dict = {
            'metadata': query_result,
            'link': temp_link,
            'port': options.streaming_port
        }
        self.set_header('Content-Type', 'application/json')
        if is_pass_check:
            self.write(ret_dict)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
    def post(self):
        self.set_header('Content-Type', 'application/json')
        auth_dbo = self.db_account

        errorMessage = ""
        errorCode = 0
        is_pass_check = True

        if auth_dbo is None:
            errorMessage = "database return null"
            errorCode = 1001
            is_pass_check = False

        #logging.info("body:"+self.request.body)
        _body = None
        if is_pass_check:
            is_pass_check = False
            try:
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                #raise BadRequestError('Wrong JSON', 3009)
                errorMessage = "wrong json format"
                errorCode = 1003
                pass

        path = None
        if is_pass_check:
            is_pass_check = False
            if _body:
                try:
                    if 'path' in _body:
                        path = _body['path']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1004
                    pass

        if is_pass_check:
            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if path == "/":
                path = ""

            if len(path) == 0:
                # empty is not allow in this API.
                errorMessage = "path is empty"
                errorCode = 1013
                is_pass_check = False

        if is_pass_check:
            if self.current_user['poolid'] is None:
                errorMessage = "no unshare permission"
                errorCode = 1015
                is_pass_check = False

        old_real_path = None
        old_poolid = None
        if is_pass_check:
            self.metadata_manager = MetaManager(self.application.sql_client,
                                                self.current_user, path)

            old_real_path = self.metadata_manager.real_path
            old_poolid = self.metadata_manager.poolid
            if not old_real_path is None:
                if not os.path.exists(old_real_path):
                    # path not exist
                    errorMessage = "real path is not exist"
                    errorCode = 1020
                    is_pass_check = False
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        new_real_path = None
        new_poolid = None
        to_metadata_manager = None
        if is_pass_check:
            to_metadata_manager = MetaManager(self.application.sql_client,
                                              self.current_user, "")
            to_metadata_manager.init_with_path(self.current_user,
                                               path,
                                               check_shared_pool=False)

            new_real_path = to_metadata_manager.real_path
            new_poolid = to_metadata_manager.poolid
            if not new_real_path is None:
                if os.path.exists(new_real_path):
                    # path exist, conflict, @_@; delete or not?
                    self._deletePath(new_real_path)
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        if is_pass_check:
            is_pass_check, errorMessage, errorCode = self._revokeShareCode(
                old_poolid)

        if is_pass_check:
            current_metadata = None
            is_pass_check, current_metadata, errorMessage = to_metadata_manager.move_metadata(
                self.metadata_manager.poolid, self.metadata_manager.db_path)

        if is_pass_check:
            is_pass_check = self.move_shared_folder_back(
                old_poolid, new_real_path)
            if not is_pass_check:
                errorMessage = "pool folder not exist or target folder conflict"
                errorCode = 1040
                is_pass_check = False

        if is_pass_check:
            is_pass_check, current_metadata, errorMessage = self.remove_shared_folder_pool(
                old_poolid)

        ret_dict = {'path': path}

        if is_pass_check:
            # every thing is correct
            self.write(ret_dict)

            folder_id = 0
            current_metadata = to_metadata_manager.get_path()
            if not current_metadata is None:
                folder_id = current_metadata["id"]
            self.set_header("oid", folder_id)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
            logging.error(
                '%s' %
                (str(dict(error=dict(message=errorMessage, code=errorCode)))))
示例#4
0
class MetadataHandler(BaseHandler):
    mode = 'FILE'
    metadata_manager = None

    def post(self):
        self.set_header('Content-Type', 'application/json')

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        _body = None
        if is_pass_check:
            #logging.info('%s' % (str(self.request.body)))
            is_pass_check = False
            try:
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        path = None
        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try:
                    if 'path' in _body:
                        path = _body['path']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            if path == "/":
                #PS: dropbox not all path='/''
                path = ""

            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if self.mode == "FILE":
            if is_pass_check:
                if len(path) == 0:
                    errorMessage = "path is empty"
                    errorCode = 1011
                    is_pass_check = False

        if is_pass_check:
            #logging.info('path %s' % (path))
            self.metadata_manager = MetaManager(self.application.sql_client,
                                                self.current_user, path)

            if not self.metadata_manager.real_path is None:
                if not os.path.exists(self.metadata_manager.real_path):
                    pass
                    #[TODO]: rebuild path on server side from database?
                    #errorMessage = "path on server not found"
                    #errorCode = 1020
                    #is_pass_check = False

        query_result = None
        if is_pass_check:
            # start to get metadata (owner)
            if self.mode == "FILE":
                query_result = self.metadata_manager.get_path()
            else:
                folder_id = 0
                current_metadata = self.metadata_manager.get_path()
                if not current_metadata is None:
                    folder_id = current_metadata["id"]
                self.set_header("oid", folder_id)

                query_result = self.metadata_manager.list_folder(
                    show_share_folder=True)

            if query_result is None:
                errorMessage = "metadata not found"
                errorCode = 1021
                is_pass_check = False

                # [TODO]:
                # real path exist, but database not exist.
                # reture error or sync database from real path.
                pass

        if is_pass_check:
            self.write(query_result)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
class FileCopyMoveHandler(BaseHandler):
    from_metadata_manager = None
    to_metadata_manager = None
    to_shared_folder_metadata_array = []
    operation = None
    OPERATION_COPY = "FileCopy"
    OPERATION_MOVE = "FileMove"

    @tornado.web.asynchronous
    def post(self):
        self.set_header('Content-Type', 'application/json')

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        if is_pass_check:
            is_pass_check = False
            try:
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        from_path = None
        to_path = None
        allow_shared_folder = None
        autorename = False

        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try:
                    if 'from_path' in _body:
                        from_path = _body['from_path']
                    if 'to_path' in _body:
                        to_path = _body['to_path']
                    if 'allow_shared_folder' in _body:
                        allow_shared_folder = _body['allow_shared_folder']
                    if 'autorename' in _body:
                        autorename = _body['autorename']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            ret, errorMessage = self.check_path(from_path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if len(from_path) == 0:
                errorMessage = "from_path is empty"
                errorCode = 1011
                is_pass_check = False

        if is_pass_check:
            ret, errorMessage = self.check_path(to_path)
            if not ret:
                is_pass_check = False
                errorCode = 1012

        if is_pass_check:
            if len(to_path) == 0:
                errorMessage = "to_path is empty"
                errorCode = 1013
                is_pass_check = False

        if is_pass_check:
            if to_path == from_path:
                errorMessage = "conflict"
                errorCode = 1014
                is_pass_check = False

        if is_pass_check:
            if to_path.startswith(from_path + '/'):
                errorMessage = "duplicated_or_nested_paths"
                errorCode = 1014
                is_pass_check = False

        if is_pass_check:
            self.from_metadata_manager = MetaManager(
                self.application.sql_client, self.current_user, from_path)

            if not self.from_metadata_manager.real_path is None:
                if not os.path.exists(self.from_metadata_manager.real_path):
                    # [TODO]:
                    # create real folders from database.
                    #pass
                    # path not exist
                    errorMessage = "from_path:%s is not exist" % (from_path, )
                    errorCode = 1020
                    is_pass_check = False
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        if is_pass_check:
            self.to_metadata_manager = MetaManager(self.application.sql_client,
                                                   self.current_user, to_path)

            if not self.to_metadata_manager.real_path is None:
                if os.path.exists(self.to_metadata_manager.real_path):
                    # [TODO]:
                    # apply autorenename rule.
                    #pass
                    # path exist
                    if not autorename:
                        errorMessage = "conflict"
                        errorCode = 1021
                        is_pass_check = False
                    else:
                        # start auto rename
                        pass
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        if is_pass_check:
            if not self.to_metadata_manager.can_edit:
                errorMessage = "to_path no write permission"
                errorCode = 1022
                is_pass_check = False

        if is_pass_check:
            if self.operation is self.OPERATION_MOVE:
                if not self.from_metadata_manager.can_edit:
                    errorMessage = "from_path no write permission"
                    errorCode = 1023
                    is_pass_check = False

        query_result = None
        if is_pass_check:
            query_result = self.from_metadata_manager.get_path()
            if query_result is None:
                errorMessage = "from_path metadata not found"
                errorCode = 1024
                is_pass_check = False

        # handle special case: when database & storage is not synced!
        # real file deleted on server, but metadata exist.
        # for now, just delete server side metadata.
        current_metadata = None
        if is_pass_check:
            current_metadata = self.to_metadata_manager.get_path()
            if not current_metadata is None:
                # delete to_path metadata.
                is_pass_check = self.to_metadata_manager.delete_metadata()
                if not is_pass_check:
                    errorMessage = "delete to_path metadata in database fail"
                    errorCode = 1025
                    is_pass_check = False

        from_shared_folder_pool_array = []
        if is_pass_check:
            self.from_metadata_manager.contain_pool_array()

        #print "from_shared_folder_pool_array", from_shared_folder_pool_array
        #self.application.sql_client.isolation_level = None
        if is_pass_check:
            # rename shared folder under from_path
            if self.operation is self.OPERATION_MOVE:
                if len(from_shared_folder_pool_array) > 0:
                    is_pass_check = False
                    if not self.to_metadata_manager.poolname is None:
                        if len(self.to_metadata_manager.poolname) == 0:
                            # ONLY is allowed in this case.
                            is_pass_check = True
                    else:
                        # unkonw error
                        pass

                    if not is_pass_check:
                        errorMessage = "unable to move share folder under share folder"
                        errorCode = 1026
                        print errorMessage, errorCode

        # PS: need roolback, don't move variable into sub block.
        dbo_pool_sub = DboPoolSubscriber(self.application.sql_client)
        if self.operation is self.OPERATION_MOVE:
            if is_pass_check:
                user_account = self.current_user['account']

                for shared_folder_item in from_shared_folder_pool_array:
                    update_poolid = shared_folder_item['poolid']
                    old_localpoolname = shared_folder_item['poolname']
                    new_localpoolname = to_path + old_localpoolname[
                        len(from_path):]
                    #print "from [%s] to [%s]" % (shared_folder_item['poolname'], new_localpoolname)
                    dbo_pool_sub.update_localpoolname(user_account,
                                                      update_poolid,
                                                      new_localpoolname,
                                                      autocommit=False)

        if is_pass_check:
            logging.info(
                '%s real path from:%s' %
                (self.operation, self.from_metadata_manager.real_path))
            logging.info('%s real path to:%s' %
                         (self.operation, self.to_metadata_manager.real_path))

            # update metadata. (owner)
            if self.operation is self.OPERATION_COPY:
                if len(self.from_metadata_manager.db_path) > 0:
                    is_pass_check, current_metadata, errorMessage = self.to_metadata_manager.copy_metadata(
                        self.from_metadata_manager.poolid,
                        self.from_metadata_manager.db_path)
                    if current_metadata is None:
                        errorMessage = "metadata not found"
                        errorCode = 1040
                        is_pass_check = False
                else:
                    # shared folder root
                    pass
                current_metadata = self.to_metadata_manager.get_path()

                #self.to_metadata_manager.copy(from_path, to_path, is_dir=is_dir)
            if self.operation is self.OPERATION_MOVE:
                if len(self.from_metadata_manager.db_path) > 0:
                    is_pass_check, current_metadata, errorMessage = self.to_metadata_manager.move_metadata(
                        self.from_metadata_manager.poolid,
                        self.from_metadata_manager.db_path)
                    if current_metadata is None:
                        errorMessage = "metadata not found"
                        errorCode = 1040
                        is_pass_check = False
                else:
                    # shared folder root
                    pass
                current_metadata = self.to_metadata_manager.get_path()

        if self.operation is self.OPERATION_MOVE:
            if is_pass_check:
                # make sure all things are correct, start to write to database.
                dbo_pool_sub.conn.commit()
            else:
                dbo_pool_sub.conn.rollback()

        if is_pass_check:
            # must everyday is done, thus to move files.
            #self._copymove(self.from_metadata_manager.real_path,self.to_metadata_manager.real_path,self.operation)
            if not current_metadata is None:
                if self.operation is self.OPERATION_COPY:
                    tornado.ioloop.IOLoop.current().add_callback(
                        self._copymove, self.from_metadata_manager.real_path,
                        self.to_metadata_manager.real_path, self.operation,
                        self.to_metadata_manager.add_thumbnail,
                        current_metadata, True, from_path, to_path,
                        from_shared_folder_pool_array)
                    #tornado.ioloop.IOLoop.current().spawn_callback(self._copymove, self.from_metadata_manager.real_path, self.to_metadata_manager.real_path, self.operation, self.to_metadata_manager.add_thumbnail, current_metadata, True, from_path, to_path, from_shared_folder_pool_array)

                if self.operation is self.OPERATION_MOVE:
                    if len(self.from_metadata_manager.db_path) > 0:
                        tornado.ioloop.IOLoop.current().add_callback(
                            self._copymove,
                            self.from_metadata_manager.real_path,
                            self.to_metadata_manager.real_path, self.operation,
                            self.to_metadata_manager.add_thumbnail,
                            current_metadata, False, None, None, None)
                        #tornado.ioloop.IOLoop.current().spawn_callback(self._copymove, self.from_metadata_manager.real_path, self.to_metadata_manager.real_path, self.operation, self.to_metadata_manager.add_thumbnail, current_metadata, False, None, None, None)
                    else:
                        # shared folder root
                        pass

        if is_pass_check:
            if not current_metadata is None:
                self.set_header("oid", current_metadata["id"])
                self.write(current_metadata)
                logging.info(current_metadata)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
            logging.error(
                '%s' %
                (str(dict(error=dict(message=errorMessage, code=errorCode)))))
        self.finish()

    #@gen.coroutine
    def aferMainCopyJobDone(self, from_path, to_path,
                            from_shared_folder_pool_array):
        self.to_shared_folder_metadata_array = []
        # start to process shared folder copy.
        for shared_folder_item in from_shared_folder_pool_array:
            update_poolid = shared_folder_item['poolid']
            old_localpoolname = shared_folder_item['poolname']
            new_localpoolname = to_path + old_localpoolname[len(from_path):]
            from_shared_folder_metadata_manager = MetaManager(
                self.application.sql_client, self.current_user,
                old_localpoolname)
            to_shared_folder_metadata_manager = MetaManager(
                self.application.sql_client, self.current_user,
                new_localpoolname)
            self.to_shared_folder_metadata_array.append(
                to_shared_folder_metadata_manager)
            is_pass_check, copy_shared_folder_metadata, errorMessage = to_shared_folder_metadata_manager.copy_metadata(
                update_poolid, "")
            if is_pass_check and not copy_shared_folder_metadata is None:
                #tornado.ioloop.IOLoop.current().add_callback(self._copymove,from_shared_folder_metadata_manager.real_path, to_shared_folder_metadata_manager.real_path, self.OPERATION_COPY, to_shared_folder_metadata_manager.add_thumbnail, copy_shared_folder_metadata, False, None, None, None)
                #tornado.ioloop.IOLoop.current().spawn_callback(self._copymove,from_shared_folder_metadata_manager.real_path, to_shared_folder_metadata_manager.real_path, self.OPERATION_COPY, to_shared_folder_metadata_manager.add_thumbnail, copy_shared_folder_metadata, False, None, None, None)
                self._copymove(from_shared_folder_metadata_manager.real_path,
                               to_shared_folder_metadata_manager.real_path,
                               self.OPERATION_COPY,
                               to_shared_folder_metadata_manager.add_thumbnail,
                               copy_shared_folder_metadata, False, None, None,
                               None)

    def _createFolder(self, directory_name):
        if not os.path.exists(directory_name):
            try:
                os.makedirs(directory_name)
            except OSError as exc:
                pass

    #@gen.coroutine
    def _copymove(self, src, dst, operation, thumbnail_callback,
                  current_metadata, is_call_shared_folder_job, from_path,
                  to_path, from_shared_folder_pool_array):
        #yield gen.moment
        if os.path.isfile(src):
            # file to file copy/move
            head, tail = os.path.split(dst)
            self._createFolder(head)
            if operation is self.OPERATION_COPY:
                shutil.copy(src, dst)
                # no matter file or folder should scan sub-folder.
                #tornado.ioloop.IOLoop.current().add_callback(thumbnail_callback,current_metadata)
                #tornado.ioloop.IOLoop.current().spawn_callback(thumbnail_callback,current_metadata)
                thumbnail_callback(current_metadata)
            elif operation is self.OPERATION_MOVE:
                shutil.move(src, dst)
        else:
            # folder to folder copy/move.
            #logging.info("%s sub-folder from %s to %s.", operation, src, dst)
            if operation is self.OPERATION_COPY:
                self.copyrecursively(src, dst)
                # no matter file or folder should scan sub-folder.
                #tornado.ioloop.IOLoop.current().add_callback(thumbnail_callback,current_metadata)
                #tornado.ioloop.IOLoop.current().spawn_callback(thumbnail_callback,current_metadata)
                thumbnail_callback(current_metadata)

                if is_call_shared_folder_job:
                    if not from_shared_folder_pool_array is None:
                        if len(from_shared_folder_pool_array) > 0:
                            #tornado.ioloop.IOLoop.instance().add_callback(self.aferMainCopyJobDone,from_path, to_path, from_shared_folder_pool_array)
                            self.aferMainCopyJobDone(
                                from_path, to_path,
                                from_shared_folder_pool_array)
            elif operation is self.OPERATION_MOVE:
                shutil.move(src, dst)

    def copyrecursively(self, root_src_dir, root_target_dir):
        logging.info("copy from %s to %s.", root_src_dir, root_target_dir)
        for src_dir, dirs, files in os.walk(root_src_dir):
            db_path = os.path.abspath(
                src_dir)[len(os.path.abspath(root_src_dir)) + 1:]
            #print "db_path", db_path
            #dst_dir = src_dir.replace(root_src_dir, root_target_dir)
            dst_dir = os.path.join(root_target_dir, db_path)
            #print "dst_dir", dst_dir
            if not os.path.exists(dst_dir):
                self._createFolder(dst_dir)

            files = [self.decodeName(f) for f in files]
            for file_ in files:
                src_file = os.path.join(src_dir, file_)
                dst_file = os.path.join(dst_dir, file_)
                if os.path.exists(dst_file):
                    os.remove(dst_file)
                if os.path.exists(src_file):
                    shutil.copy(src_file, dst_dir)
                else:
                    logging.error(src_file)

    def decodeName(self, name):
        if type(name) == str:  # leave unicode ones alone
            try:
                name = name.decode('utf8')
            except:
                name = name.decode('windows-1252')
        return name
示例#6
0
class FileCreateFolderHandler(BaseHandler):
    metadata_manager = None

    def post(self):
        self.set_header('Content-Type', 'application/json')

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        if is_pass_check:
            is_pass_check = False
            try:
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        path = None
        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try:
                    if 'path' in _body:
                        path = _body['path']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if len(path) == 0:
                errorMessage = "path is empty"
                errorCode = 1013
                is_pass_check = False

        if is_pass_check:
            self.metadata_manager = MetaManager(self.application.sql_client,
                                                self.current_user, path)

            if not self.metadata_manager.real_path is None:
                if os.path.exists(self.metadata_manager.real_path):
                    # path exist
                    errorMessage = "path is exist"
                    errorCode = 1020
                    is_pass_check = False
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        current_metadata = None
        if is_pass_check:
            current_metadata = self.metadata_manager.get_path()
            if not current_metadata is None:
                errorMessage = "metadata exist"
                errorCode = 1021
                is_pass_check = False

                # handle special case: when database & storage is not synced!
                # [TODO]: create server side folders but not files!
                pass

        if is_pass_check:
            logging.info('Create real path at:%s' %
                         (self.metadata_manager.real_path))
            self._createFolder(self.metadata_manager.real_path)

            # update metadata. (owner)
            is_pass_check, current_metadata, errorMessage = self.metadata_manager.add_metadata(
                is_dir=1)
            if not is_pass_check:
                #errorMessage = "add metadata in database fail"
                errorCode = 1022

        if is_pass_check:
            if not current_metadata is None:
                self.set_header("oid", current_metadata["id"])
                self.write(current_metadata)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
            #logging.error('%s' % (str(dict(error=dict(message=errorMessage,code=errorCode)))))

    def _createFolder(self, directory_name):
        if not os.path.exists(directory_name):
            try:
                os.makedirs(directory_name)
            except OSError as exc:
                pass
示例#7
0
class DownloadHandler(BaseHandler):
    mode = "FILE"
    metadata_manager = None

    def get(self):
        self.post()

    #@gen.coroutine
    def post(self):
        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        apiArg = self.request.headers.get("Dropboxlike-API-Arg")
        #logging.info('apiArg:%s ', apiArg)

        if is_pass_check:
            if apiArg is None:
                is_pass_check = False
                errorMessage = "wrong json format"
                errorCode = 1001

        _body = None
        if is_pass_check:
            is_pass_check = False
            try:
                _body = json.loads(apiArg)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        path = None
        format = None
        size = "w64h64"
        start = None
        length = None
        rev = None
        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try:
                    if 'path' in _body:
                        path = _body['path']
                    if 'start' in _body:
                        start = _body['start']
                    if 'length' in _body:
                        length = _body['length']
                    if 'rev' in _body:
                        rev = _body['rev']

                    # for thumbnail.
                    if 'format' in _body:
                        format = _body['format']
                    if 'size' in _body:
                        size = _body['size']

                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if len(path) == 0:
                errorMessage = "path is empty"
                errorCode = 1013
                is_pass_check = False

        if is_pass_check:
            self.metadata_manager = MetaManager(self.application.sql_client,
                                                self.current_user, path)

        if is_pass_check:
            logging.info('download %s from real path at:%s' %
                         (self.mode, self.metadata_manager.real_path))

            if not self.metadata_manager.real_path is None:
                if not os.path.exists(self.metadata_manager.real_path):
                    errorMessage = "not_found"
                    errorCode = 1020
                    is_pass_check = False
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        query_result = None

        if is_pass_check:
            query_result = self.metadata_manager.get_path()
            if query_result is None:
                #[TODO]: handle special case: file exist, BUT metadata not found!
                errorMessage = "not_found"
                errorCode = 1020
                is_pass_check = False

        if is_pass_check:
            #self.write(query_result)
            head, filename = os.path.split(self.metadata_manager.real_path)
            download_path = self.metadata_manager.real_path
            if self.mode == "THUMBNAIL":
                doc_id = query_result['id']
                download_path = thumbnail._getThumbnailPath(
                    doc_id, size,
                    os.path.splitext(filename)[-1])

            is_pass_check = self._downloadData(download_path, filename)
            if not is_pass_check:
                for i in range(0):
                    logging.info(
                        "waiting thumbnail file to ready(%d): %s ... " %
                        (i, download_path))
                    #yield gen.sleep(2)
                    is_pass_check = self._downloadData(download_path, filename)
                    if is_pass_check:
                        break

            if not is_pass_check:
                errorMessage = "file not found"
                errorCode = 1030
                is_pass_check = False

        if is_pass_check:
            pass
        else:
            self.set_header('Content-Type', 'application/json')
            if errorCode != 1030:
                self.set_status(400)
            else:
                # only this case return 404.
                self.set_status(404)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
            logging.error(
                '%s' %
                (str(dict(error=dict(message=errorMessage, code=errorCode)))))
        self.finish()

    def _downloadData(self, real_path, filename):
        ret = False

        logging.info("download real file: %s ... " % (real_path))
        if os.path.isfile(real_path):
            with open(real_path, 'rb') as f:
                buf_size = 1024 * 200
                self.set_header('Content-Type', 'application/octet-stream')
                self.set_header('Content-Disposition',
                                'attachment; filename=' + filename)
                while True:
                    data = f.read(buf_size)
                    if not data:
                        break
                    self.write(data)
                ret = True
        return ret
示例#8
0
class FileDeleteHandler(BaseHandler):
    metadata_manager = None
    to_shared_folder_metadata_array = []

    @tornado.web.asynchronous
    def post(self):
        self.set_header('Content-Type','application/json')

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        if is_pass_check:
            is_pass_check = False
            try :
                _body = json.loads(self.request.body)
                is_pass_check = True
            except Exception:
                errorMessage = "wrong json format"
                errorCode = 1001
                pass

        path = None
        if is_pass_check:
            is_pass_check = False
            #logging.info('%s' % (str(_body)))
            if _body:
                try :
                    if 'path' in _body:
                        path = _body['path']
                    is_pass_check = True
                except Exception:
                    errorMessage = "parse json fail"
                    errorCode = 1002

        if is_pass_check:
            ret, errorMessage = self.check_path(path)
            if not ret:
                is_pass_check = False
                errorCode = 1010

        if is_pass_check:
            if len(path)==0:
                # not allow to do this action.
                errorMessage = "path is empty"
                errorCode = 1013
                is_pass_check = False
                    
        if is_pass_check:
            self.metadata_manager = MetaManager(self.application.sql_client, self.current_user, path)

            if not self.metadata_manager.real_path is None:
                if not os.path.exists(self.metadata_manager.real_path):
                    # ignore
                    pass
                    # path exist
                    #errorMessage = "path is not exist"
                    #errorCode = 1020
                    #is_pass_check = False
            else:
                errorMessage = "no permission"
                errorCode = 1030
                is_pass_check = False

        if is_pass_check:
            if not self.metadata_manager.can_edit:
                errorMessage = "no write premission"
                errorCode = 1020
                is_pass_check = False

        current_metadata = None
        if is_pass_check:
            current_metadata = self.metadata_manager.get_path()
            if current_metadata is None:
                errorMessage = "metadata not found"
                errorCode = 1021
                is_pass_check = False
        
        

        shared_folder_pool_array = self.metadata_manager.contain_pool_array()
        print "shared_folder_pool_array", shared_folder_pool_array
            
        #errorMessage = "test to breck"
        #errorCode = 1099
        #is_pass_check = False

        if is_pass_check:
            if len(self.metadata_manager.db_path) > 0:
                logging.info('user delete real path at:%s' % (self.metadata_manager.real_path))
                # update metadata in data.
                is_pass_check = self.metadata_manager.delete_metadata(current_metadata=current_metadata)
                if not is_pass_check:
                    errorMessage = "delete metadata fail"
                    errorCode = 1040
                    is_pass_check = False

                if is_pass_check:
                    if os.path.exists(self.metadata_manager.real_path):
                        tornado.ioloop.IOLoop.current().add_callback(self._deletePath,self.metadata_manager.real_path)
            else:
                # shared folder.
                pass

        if is_pass_check:
            if len(shared_folder_pool_array) > 0:
                tornado.ioloop.IOLoop.current().add_callback(self.aferMainDeleteJobDone,shared_folder_pool_array)

        if is_pass_check:
            if not current_metadata is None:
                self.set_header("oid",current_metadata["id"])
                self.write(current_metadata)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage,code=errorCode)))
            logging.error('%s' % (str(dict(error=dict(message=errorMessage,code=errorCode)))))
        self.finish()
            
    # [TODO]:
    # delete fail, but file locked.
    @gen.coroutine
    def _deletePath(self, real_path):
        import shutil
        if os.path.exists(real_path):
            if os.path.isfile(real_path):
                try:
                    os.unlink(real_path)
                except Exception as error:
                    errorMessage = "{}".format(error)
                    logging.error(errorMessage)
                    pass
            else:
                for root, dirs, files in os.walk(real_path):
                    yield gen.moment
                    for f in files:
                        os.unlink(os.path.join(root, f))
                    for d in dirs:
                        shutil.rmtree(os.path.join(root, d))
                shutil.rmtree(real_path)

    #@gen.coroutine
    def aferMainDeleteJobDone(self, shared_folder_pool_array):
        dbo_pool_sub = DboPoolSubscriber(self.application.sql_client)

        self.to_shared_folder_metadata_array = []
        # start to process shared folder copy.
        for shared_folder_item in shared_folder_pool_array:
            update_poolid = shared_folder_item['poolid']
            pool_ownerid = shared_folder_item['ownerid']
            old_localpoolname = shared_folder_item['poolname']
            to_shared_folder_metadata_manager = MetaManager(self.application.sql_client, self.current_user, old_localpoolname)
            self.to_shared_folder_metadata_array.append(to_shared_folder_metadata_manager)
            
            if pool_ownerid == self.current_user['account']:
                # owner delete
                logging.info('user delete share folder(%d) path at:%s' % (update_poolid, to_shared_folder_metadata_manager.real_path))
                # update metadata in data.
                is_pass_check = to_shared_folder_metadata_manager.delete_metadata()
                if not is_pass_check:
                    errorMessage = "delete metadata fail"
                    errorCode = 1040
                    is_pass_check = False

                if is_pass_check:
                    if os.path.exists(self.metadata_manager.real_path):
                        tornado.ioloop.IOLoop.current().add_callback(self._deletePath,to_shared_folder_metadata_manager.real_path)

                # subscriber delete.
                dbo_pool_sub.delete_pool(update_poolid)
            else:
                # subscriber delete.
                dbo_pool_sub.unscriber(self.current_user['account'], update_poolid)