def serialize_VersionedFile(ffile, file=None):
    if file is None:
        file = VersionedFile()
    file.id = ffile.id
    serialize_VersionedFileData(ffile, file)
    return file
def commit_versioned_files(files, force=None):
    """
    commit_versioned_files
    Commit a fileset
    :param files: File list to commit
    :type files: list | bytes
    :param force: Force commit
    :type force: bool

    :rtype: List[VersionedFileStatus]
    """
    #print "===> commit_versioned_files----"
    commit_files = []
    conflict_files = []

    if connexion.request.is_json:
        files = [
            VersionedFile.from_dict(d) for d in connexion.request.get_json()
        ]
    #print "---", files
    if force is None:
        force = False

    print "***", files

    to_add = []
    to_change = []
    to_delete = []

    #  conflict_change
    #  conflict_del
    #  income_add
    #  income_change
    #  income_del
    #  outgo_add
    #  outgo_change
    #  outgo_del

    has_conflicts = False
    # check if given files are allowed to commit
    for file in files:
        raise_on_error(update_file_state(file))
        if force == True:
            if file.state == 'outgo_add':
                to_add.append(file)
            elif file.state == 'outgo_change':
                to_change.append(file)
            elif file.state == 'outgo_del':
                to_delete.append(file)
            elif file.state == 'conflict_add':
                to_change.append(file)
            elif file.state == 'conflict_change':
                to_change.append(file)
            elif file.state == 'conflict_del':
                to_delete.append(file)
            elif file.state == 'income_add' or file.state == 'income_change' or file.state == 'income_del':
                to_change.append(file)
        else:
            if file.state == 'conflict_change' or file.state == 'conflict_del' or file.state == 'conflict_add':
                has_conflicts = True
                conflict_files.append(file)
            elif file.state == 'outgo_add':
                to_add.append(file)
            elif file.state == 'outgo_change':
                to_change.append(file)
            elif file.state == 'outgo_del':
                to_delete.append(file)

    if has_conflicts and force == False:
        # in case of a conflict return conflicted files
        return conflict_files, 403

    storage = api.versioned_file_storage.VersionedFileStorage()
    for file in to_add:
        # add file to file storage
        if not file.content is None:
            commit_files.append(storage.add_file(file))
        else:
            return [file], 403

    for file in to_change:
        # modify file to file storage
        if not file.content is None:
            commit_files.append(storage.add_file(file))
        else:
            return [file], 403

    for file in to_delete:
        # delete file to file storage
        commit_files.append(storage.delete_file(file))

    #print "****", commit_files
    #print "------------------------------------"
    return commit_files
def update_versioned_files(files, force=None):
    """
    update_versioned_files
    Update a fileset
    :param files: File list to update
    :type files: list | bytes

    :rtype: List[VersionedFile]
    """
    update_files = []
    conflict_files = []

    if connexion.request.is_json:
        files = [
            VersionedFile.from_dict(d) for d in connexion.request.get_json()
        ]

    if force is None:
        force = False

    to_update = []
    to_delete = []

    #  conflict_change
    #  conflict_del
    #  income_add
    #  income_change
    #  income_del
    #  outgo_add
    #  outgo_change
    #  outgo_del

    has_conflicts = False
    # check if given files are allowed to commit
    for file in files:
        #print "*", file
        raise_on_error(update_file_state(file))
        #print "**", file
        if force:
            if file.state == 'conflict_add' or file.state == 'outgo_add':
                file.state = 'income_add'
                to_update.append(file)
            elif file.state == 'conflict_change' or file.state == 'outgo_change':
                file.state = 'income_change'
                to_update.append(file)
            elif file.state == 'conflict_del':
                file.state = 'income_del'
                to_delete.append(file)
            elif file.state == 'outgo_del':
                file.state = 'income_add'
                to_update.append(file)
            elif file.state == 'income_add':
                to_update.append(file)
            elif file.state == 'income_change':
                to_update.append(file)
            elif file.state == 'income_del':
                to_delete.append(file)
        else:
            if file.state == 'conflict_change' or file.state == 'conflict_del' or file.state == 'conflict_add':
                has_conflicts = True
                conflict_files.append(file)
            if file.state == 'income_add':
                to_update.append(file)
            elif file.state == 'income_change':
                to_update.append(file)
            elif file.state == 'income_del':
                to_delete.append(file)

    if has_conflicts and force == False:
        # in case of a conflict return conflicted files
        return conflict_files, 403

    storage = api.versioned_file_storage.VersionedFileStorage()
    for file in to_update:
        if file.id:
            ffile = api.models.VersionedFile.objects.filter(
                id=file.id).latest('id')
        else:
            ffile = api.models.VersionedFile.objects.filter(
                source_path=file.source_path).latest('id')
        file = serialize_VersionedFile(ffile, file)
        file.content = storage.get_file_content(file.id)
        file.id = ffile.id
        file.version = ffile.version

        update_files.append(file)

    for file in to_delete:
        file.storage_path = None
        update_files.append(file)

    #print "----", update_files
    return update_files
def synchronize_versioned_files(files, root_path=None, category=None):
    """
    synchronize_versioned_files
    Get synchronization status of a fileset
    :param files: File list to test synchronization
    :type files: list | bytes
    :param root_path: Path from which to synchronize
    :type root_path: str
    :param category: Category of files to see
    :type category: str

    :rtype: List[VersionedFile]
    """
    print "===> synchronize_versioned_files----"
    print "*", files
    sync_files = []

    if connexion.request.is_json:
        files = [
            VersionedFile.from_dict(d) for d in connexion.request.get_json()
        ]

    exclude_id = []
    exclude_path = []
    # check given files
    for file in files:
        if file.source_path:
            #print "---", file
            raise_on_error(update_file_state(file))
            #print "+++", file
            sync_files.append(file)
            if file.id:
                exclude_id.append(file.id)
            else:
                exclude_path.append(file.source_path)

    #print "*",   exclude_id,  exclude_path
    # check files not in list
    ffile_request = api.models.VersionedFile.objects
    # limit to category
    if category:
        ffile_request = ffile_request.filter(category=category)
    # limit to root_path
    if root_path:
        ffile_request = ffile_request.filter(source_path__startswith=root_path)
    # exclude files already given in input
    if len(exclude_id) > 0:
        ffile_request = ffile_request.filter(~Q(id__in=exclude_id))
    if len(exclude_path) > 0:
        ffile_request = ffile_request.filter(~Q(source_path__in=exclude_path))
    # exclude deleted files


#    ffile_request = ffile_request.filter(state=api.models.VersionedFileState.created)
    ffile_request = ffile_request.exclude(
        state=api.models.VersionedFileState.deleted)

    for ffile in ffile_request.all():
        file = serialize_VersionedFile(ffile)
        file.id = ffile.id
        file.version = ffile.version
        #file.id = None
        #file.version = None
        file.state = 'income_add'
        sync_files.append(file)

    #print "%%%", sync_files
    #print "------------------------------------"
    return sync_files