예제 #1
0
    def add_metadata(self, size=0, rev=None, client_modified=None, is_dir=0, content_hash=None):
        in_dic = {}
        in_dic['poolid'] = self.poolid
        in_dic['path'] = self.db_path

        in_dic['rev'] = rev
        in_dic['size'] = size
        if client_modified is None:
            client_modified = utils.get_timestamp()
        in_dic['client_modified'] = client_modified
        in_dic['is_dir'] = is_dir
        in_dic['content_hash'] = content_hash
        in_dic['editor'] = self.account
        in_dic['owner'] = self.account

        check_metadata = self.get_path()
        if not check_metadata is None:
            # [TODO]: handle special case: same path insert twice, it is conflict.
            ret = self.delete_metadata(current_metadata=check_metadata)

        ret, current_metadata, errorMessage = self.dbo_metadata.insert(in_dic)
        if not current_metadata is None:
            current_metadata = self.convert_for_dropboxlike_dict(current_metadata)
            if current_metadata['type']=="file":
                tornado.ioloop.IOLoop.instance().add_callback(self.add_thumbnail,current_metadata)

        return ret, current_metadata, errorMessage
예제 #2
0
    def delete_path(self, poolid=0, path='', account='', autocommit=True):
        ret = False
        errorMessage = ""

        update_time = utils.get_timestamp()
        try:
            sql = "UPDATE delta set tag='deleted', update_time=?, account=? WHERE poolid=? and path=?"
            cursor = self.conn.execute(sql, (
                update_time,
                account,
                poolid,
                path,
            ))

            sql = "UPDATE delta set tag='deleted', update_time=?, account=? WHERE poolid=? and path like ?"
            cursor = self.conn.execute(sql, (
                update_time,
                account,
                poolid,
                path + '/%',
            ))

            if autocommit:
                self.conn.commit()

            ret = True
        except Exception as error:
            #except sqlite3.IntegrityError:
            #except sqlite3.OperationalError, msg:
            #print("Error: {}".format(error))
            errorMessage = "{}".format(error)
            logging.info("sqlite error: %s", errorMessage)
            #raise
        return ret, errorMessage
예제 #3
0
 def create_folder(self, poolid, path, owner):
     out_dic = {}
     out_dic['poolid'] = poolid
     out_dic['path'] = path
     out_dic['content_hash'] = None
     out_dic['rev'] = None
     out_dic['size'] = 0
     out_dic['client_modified'] = utils.get_timestamp()
     out_dic['is_dir'] = 1
     out_dic['editor'] = owner
     out_dic['owner'] = owner
     return self.insert(out_dic)
예제 #4
0
    def post(self):
        self.set_header('Content-Type', 'application/json')

        is_pass_check = True
        errorMessage = ""
        errorCode = 0

        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

        #[TODO]:
        # query delta for the last cursor on path.
        query_result = {'cursor': utils.get_timestamp()}

        if is_pass_check:
            self.write(query_result)
        else:
            self.set_status(400)
            self.write(dict(error=dict(message=errorMessage, code=errorCode)))
예제 #5
0
 def _updateMtimeToFile(self, real_path, client_modified):
     # update access and modify time.
     #<Modified time#Created time#Accessed time>
     is_pass_check = False
     errorMessage = ""
     try:
         # update modify time.
         #st = os.stat(real_path)
         #atime = st[ST_ATIME]
         atime = utils.get_timestamp()
         if client_modified is None:
             client_modified = atime
         os.utime(real_path, (atime, client_modified))
         is_pass_check = True
     except Exception as error:
         errorMessage = "{}".format(error)
         logging.error(errorMessage)
         pass
     return is_pass_check, errorMessage
예제 #6
0
    def add_path(self,
                 tag='file',
                 poolid=0,
                 path='',
                 doc_id=0,
                 account='',
                 autocommit=True):

        update_time = utils.get_timestamp()
        ret = False
        errorMessage = ""
        try:
            sql = "DELETE FROM delta WHERE poolid=? and path=?"
            cursor = self.conn.execute(sql, (
                poolid,
                path,
            ))

            sql = "INSERT INTO delta (tag,poolid,path,doc_id,account,update_time) VALUES (?, ?, ?, ?, ?, ?)"
            cursor = self.conn.execute(sql, (
                tag,
                poolid,
                path,
                doc_id,
                account,
                update_time,
            ))
            if autocommit:
                self.conn.commit()
            ret = True
        except Exception as error:
            #except sqlite3.IntegrityError:
            #except sqlite3.OperationalError, msg:
            #print("Error: {}".format(error))
            errorMessage = "{}".format(error)
            logging.info("sqlite error: %s", errorMessage)
            #raise
        return ret, errorMessage
예제 #7
0
    def get_delta(self, cursor):

        # start to get metadata (owner)
        poolid = self.current_user['poolid']
        #self.open_metadata(poolid)
        #query_result = self.metadata_manager.query(path)
        query_result = None
        if not query_result is None:
            #self.write(query_result)
            #self.write("[]")
            pass
        else:
            # todo:
            # real path exist, but database not exist.
            # reture error or sync database from real path.
            pass

        dict_delta = {
'entries':[],
'cursor': utils.get_timestamp(),
'quota': 0,
'has_more': False
}
        self.write(dict_delta)
예제 #8
0
    def insert(self, in_dic, autocommit=True):
        out_dic = {}
        errorMessage = ""
        ret = True

        if ret:
            for param in ['is_dir']:
                if in_dic[param] != 0 and in_dic[param] != 1:
                    errorMessage = param + ' value must be 0 or 1 for boolean in integer.'
                    ret = False

        if ret:
            for param in ['size']:
                if in_dic[param] == '':
                    errorMessage = param + ' value cannot be null.'
                    ret = False

        if ret:
            if in_dic.get('owner', '') == '':
                errorMessage = 'owner value cannot be empty.'
                ret = False

        poolid = in_dic.get('poolid', 0)
        if poolid < 1:
            errorMessage = 'poolid value wrong.'
            ret = False

        path = in_dic.get('path', '')

        if ret:
            # skip parent's commit.
            if self.last_transaction_path is None:
                self.last_transaction_path = path

            # get parent node by path
            parent_node = None
            item_name = path
            if len(path) > 0:
                parent_node, item_name = os.path.split(path)
                #print "parent_node, item_name:", parent_node, item_name

                if not parent_node is None:
                    if parent_node == "/":
                        parent_node = ""
                    #print "parent_node, check_and_create_parent:", parent_node
                    self.check_and_create_parent(poolid, parent_node,
                                                 in_dic['owner'])

            #logging.info("start to insert '%s' to metadata database ...", item_name)

            current_metadata = None
            try:
                sql = 'insert into metadata (poolid, path, content_hash, rev, size, is_dir, parent, name, client_modified, server_modified, editor, owner)'
                sql = sql + ' values(?,?,?,?,?,?,?,?,?,?,?,?) '
                #logging.info("sql: %s", sql)
                cursor = self.conn.execute(sql, (
                    poolid,
                    path,
                    in_dic['content_hash'],
                    in_dic['rev'],
                    in_dic['size'],
                    in_dic['is_dir'],
                    parent_node,
                    item_name,
                    in_dic['client_modified'],
                    utils.get_timestamp(),
                    in_dic['editor'],
                    in_dic['owner'],
                ))

                current_metadata = self.get_metadata(poolid, path)
                if not current_metadata is None:
                    self.add_metadata_to_delta(current_metadata,
                                               in_dic['editor'],
                                               autocommit=False)
                else:
                    ret = False
                    errorMessage = "data is lost after move metadata in database"

                if self.last_transaction_path != path:
                    #logging.info("insert commit at path: {}".format(path))
                    #out_dic['lastrowid'] = cursor.lastrowid
                    # force skip commit.
                    autocommit = False

                if autocommit:
                    self.conn.commit()
                    self.last_transaction_path = None

            except sqlite3.IntegrityError:
                ret = False
                errorMessage = "insert metadata same path twice: {}".format(
                    in_dic['path'].encode('utf-8').strip())
                logging.error(errorMessage)
            except Exception as error:
                ret = False
                errorMessage = "insert metadata table Error: {}".format(error)
                logging.error(errorMessage)

        return ret, current_metadata, errorMessage
예제 #9
0
    def copy(self, in_dic, autocommit=True):
        errorMessage = ""
        current_metadata = None
        ret = True

        poolid = ''
        if ret:
            if in_dic.get('poolid', 0) == 0:
                errorMessage = 'poolid value cannot be empty.'
                ret = False
            else:
                poolid = in_dic['poolid']

        path = ''
        if ret:
            if in_dic.get('path', '') == '':
                errorMessage = 'path value cannot be empty.'
                ret = False
            else:
                path = in_dic['path']

        old_poolid = ''
        if ret:
            if in_dic.get('old_poolid', '') == '':
                errorMessage = 'old_poolid value cannot be empty.'
                ret = False
            else:
                old_poolid = in_dic['old_poolid']

        old_path = in_dic.get('old_path', '')

        if ret:
            if in_dic.get('editor', '') == '':
                errorMessage = 'editor value cannot be empty.'
                ret = False

        if ret:
            # skip parent's commit.
            if self.last_transaction_path is None:
                self.last_transaction_path = path

            # get parent node by path
            parent_node = None
            item_name = path
            if len(path) > 0:
                # get parent node by path
                parent_node, item_name = os.path.split(path)

                if not parent_node is None:
                    if parent_node == "/":
                        parent_node = ""
                    self.check_and_create_parent(poolid, parent_node,
                                                 in_dic['editor'])

            #logging.info("copy '%s' to metadata database ...", item_name)

            try:
                #[TODO]: generate new rev for new file.

                sql = "insert into metadata (poolid, path, content_hash, rev, size, is_dir, parent, name, client_modified, server_modified, editor, owner) "
                sql += "select ?, ?, content_hash, null, size, is_dir, ?, ?, client_modified, ?, ?, owner from metadata where poolid=? and path=?"
                self.conn.execute(sql, (
                    poolid,
                    path,
                    parent_node,
                    item_name,
                    utils.get_timestamp(),
                    in_dic['editor'],
                    old_poolid,
                    old_path,
                ))
                #logging.info("sql: %s", sql)

                # copy child node path.
                sql = "insert into metadata (poolid, path, content_hash, rev, size, is_dir, parent, name, client_modified, server_modified, editor, owner) "
                sql += "select ?, ? || substr(path, length(?)+1), content_hash, null, size, is_dir, ? || substr(parent, length(?)+1), name, client_modified, ?, ?, owner from metadata where poolid=? and path like ?"
                self.conn.execute(sql, (
                    poolid,
                    path,
                    old_path,
                    path,
                    old_path,
                    utils.get_timestamp(),
                    in_dic['editor'],
                    old_poolid,
                    old_path + '/%',
                ))
                #logging.info("sql: %s", sql)

                current_metadata = self.get_metadata(poolid, path)
                if not current_metadata is None:
                    self.add_metadata_to_delta(current_metadata,
                                               in_dic['editor'],
                                               autocommit=False)
                else:
                    ret = False
                    errorMessage = "data is lost after move metadata in database"

                # must commit at finish!
                if autocommit:
                    self.conn.commit()
                    self.last_transaction_path = None
            except Exception as error:
                ret = False
                errorMessage = "copy metadata table Error: {}".format(error)
                logging.error(errorMessage)

        return ret, current_metadata, errorMessage
예제 #10
0
    def update(self, in_dic, autocommit=True):
        errorMessage = ""
        current_metadata = None
        ret = True

        poolid = ''
        if ret:
            if in_dic.get('poolid', 0) == 0:
                errorMessage = 'poolid value cannot be empty.'
                ret = False
            else:
                poolid = in_dic['poolid']

        path = in_dic.get('path', '')

        old_poolid = ''
        if ret:
            if in_dic.get('old_poolid', '') == '':
                errorMessage = 'old_poolid value cannot be empty.'
                ret = False
            else:
                old_poolid = in_dic['old_poolid']

        old_path = in_dic.get('old_path', '')

        if ret:
            if in_dic.get('editor', '') == '':
                errorMessage = 'editor value cannot be empty.'
                ret = False
        #print "in_dic", in_dic

        if ret:
            # skip parent's commit.
            if self.last_transaction_path is None:
                self.last_transaction_path = path

            # get parent node by path
            parent_node = None
            item_name = path
            if len(path) > 0:
                # get parent node by path
                parent_node, item_name = os.path.split(path)

                if not parent_node is None:
                    if parent_node == "/":
                        parent_node = ""
                    self.check_and_create_parent(poolid, parent_node,
                                                 in_dic['editor'])
            #logging.info("update '%s' to metadata database ...", item_name)

            try:
                sql = 'update metadata set poolid=?, path = ?'
                if 'content_hash' in in_dic:
                    sql += ' , content_hash = \'%s\'' % str(
                        in_dic['content_hash']).replace("'", "''")
                #[TODO]: Revision
                #sql += ' , rev = ?'
                if 'size' in in_dic:
                    sql += ' , size = %d' % int(in_dic['size'])
                if 'client_modified' in in_dic:
                    sql += ' , client_modified = %d' % int(
                        in_dic['client_modified'])
                if 'is_dir' in in_dic:
                    sql += ' , is_dir = %d' % int(in_dic['is_dir'])
                sql += ' , parent=?, name = ? , server_modified = ?, editor = ? where poolid=? and path = ? '
                #logging.info('update sql:%s' % (sql))

                self.conn.execute(sql, (
                    poolid,
                    path,
                    parent_node,
                    item_name,
                    utils.get_timestamp(),
                    in_dic['editor'],
                    old_poolid,
                    old_path,
                ))

                # update child node path.
                # question: is need to update the editor/owner account?
                if not (old_poolid == poolid and old_path == path):
                    # skip for file revision.
                    sql = 'update metadata set  poolid=?, path = ? || substr(path, length(?)+1) , parent = ? || substr(parent, length(?)+1), editor=? where poolid=? and path like ? '
                    #logging.info('update subfolder sql:%s' % (sql))
                    self.conn.execute(sql, (
                        poolid,
                        path,
                        old_path,
                        path,
                        old_path,
                        in_dic['editor'],
                        old_poolid,
                        old_path + '/%',
                    ))
                #self.conn.commit()

                current_metadata = self.get_metadata(poolid, path)
                if not current_metadata is None:
                    self.dbo_delta.delete_path(poolid=old_poolid,
                                               path=old_path,
                                               account=in_dic['editor'],
                                               autocommit=False)

                    self.add_metadata_to_delta(current_metadata,
                                               in_dic['editor'],
                                               autocommit=False)
                else:
                    ret = False
                    errorMessage = "data is lost after move metadata in database"

                # must commit at finish!
                if autocommit:
                    self.conn.commit()
                    self.last_transaction_path = None
            except Exception as error:
                ret = False
                errorMessage = "update metadata table Error: {}".format(error)
                logging.error(errorMessage)

        return ret, current_metadata, errorMessage
예제 #11
0
    def list_folder(self, poolid=None, db_path=None, show_share_folder=False):
        if poolid is None:
            poolid = self.poolid
        if db_path is None:
            db_path = self.db_path
        if db_path is None:
            # unable found this path in database.
            db_path = self.query_path


        dic_children = None
        if not poolid is None:
            if not self.dbo_metadata is None:
                dic_children = self.dbo_metadata.list_folder(poolid, db_path)

        metadata_dic = {}
        contents = []

        # for small case used, use append for each item.
        if not dic_children is None:
            for item in dic_children:
                contents.append(self.convert_for_dropboxlike_dict(item))

        # add shared folder
        if show_share_folder and (self.poolname == "" or self.poolname is None):
            share_folder_array = self.dbo_pool_subscriber.list_share_poolid(self.account, db_path)
            for pool_dict in share_folder_array:
                doc_id = 0
                new_poolid = pool_dict['poolid']
                metadata_conn = self.open_metadata_db(new_poolid)
                dbo_share_folder_metadata = DboMetadata(metadata_conn)
                if not dbo_share_folder_metadata is None:
                    current_metadata = dbo_share_folder_metadata.get_metadata(new_poolid, "")
                    if not current_metadata is None:
                        doc_id = current_metadata['doc_id']
                
                share_folder_dict = {}
                share_folder_dict['id'] = doc_id
                share_folder_dict['path'] = pool_dict['poolname']
                parent_node, item_name = os.path.split(pool_dict['poolname'])
                share_folder_dict['name'] = item_name

                #out_dic['permission'] = "{"write": True}"ll
                share_folder_dict['permission'] = 'r'
                if pool_dict['can_edit'] == 1:
                    share_folder_dict['permission'] = 'rw'
                if pool_dict['status'] == dbconst.POOL_STATUS_SHARED:
                    share_folder_dict['permission'] = 'rwx'
                share_folder_dict['type'] = "folder"

                share_folder_dict['shared_folder'] = True
                contents.append(share_folder_dict)


        metadata_dic['entries']=contents
        
        metadata_dic['cursor']=utils.get_timestamp()
        #[TOOD]: paging metadata
        metadata_dic['has_more']=False

        #print 'dic_current:%s' % (metadata_dic)
        #self.write(metadata_dic)

        # for big data used. (but, seems speed the same.)
        '''
        metadata_dic['contents']=contents
        delimiter = '\"contents\": ['
        #body = "{}".format(metadata_dic)
        body = json.dumps(metadata_dic)
        body_item = body.split(delimiter)
        self.write(body_item[0]+delimiter)
        dic_children_count = len(dic_children)
        if dic_children_count > 0:
            iPos = 0
            for item in dic_children:
                iPos += 1
                self.write(json.dumps(self.convert_for_dropboxlike_dict(item)))
                if iPos < dic_children_count:
                    self.write(",")
        self.write(body_item[1])
        '''

        return metadata_dic