<commit_before>import synapseclient
from synapseclient import File, Project, Folder, Table, Schema, Link, Wiki, Entity, Activity, exceptions
import time
from synapseclient.exceptions import *
import tempfile
import re
############################################################
##                 Copy Functions                         ##
############################################################
def copyFileHandles(syn, fileHandles, associateObjectTypes, associateObjectIds, newContentTypes=None, newFileNames=None):
    """
    Given a list of fileHandle Objects, copy the fileHandles

    :param fileHandles:          List of fileHandle Objects

    :param associateObjectTypes: List of associated object types: FileEntity, TableEntity, WikiAttachment, UserProfileAttachment, MessageAttachment, TeamAttachment, SubmissionAttachment, VerificationSubmission (Must be the same length as fileHandles)
    
    :param associateObjectIds:   List of associated object Ids: If copying a file, the objectId is the synapse id, and if copying a wiki attachment, the object id is the wiki subpage id. (Must be the same length as fileHandles)
    
    :param newContentTypes:      List of new content types (Can change a filetype of a filehandle). Defaults to None, keeping the old filetype

    :param newFileNames:         List of new filenames (Can change a filename of a filehandle). Defaults to None, keeping the old filename
    
    :return:                     List of batch filehandle copy results
    """

    newContentTypes = [None]*len(fileHandles) if newContentTypes is None else newContentTypes
    newFileNames = [None]*len(fileHandles) if newFileNames is None else newFileNames
    if (len(fileHandles) != len(associateObjectTypes) or len(fileHandles) != len(associateObjectIds) or
        len(fileHandles) != len(newContentTypes) or len(fileHandles) != len(newFileNames)):
        raise ValueError("Length of fileHandles, associateObjectTypes, and associateObjectIds must be the same")
    copyFileHandleRequest = {"copyRequests":[]}
    for filehandle, newContentType, newFileName, associateObjectType, associateObjectId in zip(fileHandles, newContentTypes, newFileNames, associateObjectTypes, associateObjectIds):
        if newContentType is not None:
            filehandle['contentType'] = newContentType
        if newFileName is not None:
            filehandle['fileName'] = newFileName
        copyFileHandleRequest['copyRequests'].append({"newContentType":filehandle['contentType'],
                                                      "newFileName":filehandle['fileName'],
                                                      "originalFile":{"associateObjectType":associateObjectType,
                                                                      "fileHandleId":filehandle['id'],
                                                                      "associateObjectId":associateObjectId}})
    copiedFileHandle = syn.restPOST('/filehandles/copy',body=json.dumps(copyFileHandleRequest),endpoint=syn.fileHandleEndpoint)
    return(copiedFileHandle)

def copy(syn, entity, destinationId, skipCopyWikiPage=False, skipCopyAnnotations=False, **kwargs):
    """
    - This function will assist users in copying entities (Tables, Links, Files, Folders, Projects),
      and will recursively copy everything in directories.
    - A Mapping of the old entities to the new entities will be created and all the wikis of each entity
      will also be copied over and links to synapse Ids will be updated.

    :param syn:                 A synapse object: syn = synapseclient.login()- Must be logged into synapse

    :param entity:              A synapse entity ID

    :param destinationId:       Synapse ID of a folder/project that the copied entity is being copied to

    :param skipCopyWikiPage:    Skip copying the wiki pages
                                Default is False

    :param skipCopyAnnotations: Skips copying the annotations
                                Default is False

    Examples::                        
    import synapseutils
    import synapseclient
    syn = synapseclient.login()
    synapseutils.copy(syn, ...)<commit_msg>Update copyFileHandle function<commit_after>import synapseclient
from synapseclient import File, Project, Folder, Table, Schema, Link, Wiki, Entity, Activity, exceptions
import time
from synapseclient.exceptions import *
import tempfile
import re
import json
############################################################
##                 Copy Functions                         ##
############################################################
def copyFileHandles(syn, fileHandles, associateObjectTypes, associateObjectIds, newContentTypes=None, newFileNames=None, checkFileHandle=True):
    """
    Given a list of fileHandle Objects, copy the fileHandles

    :param fileHandles:          List of fileHandle Objects

    :param associateObjectTypes: List of associated object types: FileEntity, TableEntity, WikiAttachment, UserProfileAttachment, MessageAttachment, TeamAttachment, SubmissionAttachment, VerificationSubmission (Must be the same length as fileHandles)
    
    :param associateObjectIds:   List of associated object Ids: If copying a file, the objectId is the synapse id, and if copying a wiki attachment, the object id is the wiki subpage id. (Must be the same length as fileHandles)
    
    :param newContentTypes:      List of new content types (Can change a filetype of a filehandle). Defaults to None, keeping the old filetype

    :param newFileNames:         List of new filenames (Can change a filename of a filehandle). Defaults to None, keeping the old filename
    
    :return:                     List of batch filehandle copy results
    """
    print(fileHandles)
    print(associateObjectTypes)
    print(associateObjectIds)
    newContentTypes = [None]*len(fileHandles) if newContentTypes is None else newContentTypes
    newFileNames = [None]*len(fileHandles) if newFileNames is None else newFileNames
    if (len(fileHandles) != len(associateObjectTypes) or len(fileHandles) != len(associateObjectIds) or
        len(fileHandles) != len(newContentTypes) or len(fileHandles) != len(newFileNames)):
        raise ValueError("Length of fileHandles, associateObjectTypes, and associateObjectIds must be the same")
    copyFileHandleRequest = {"copyRequests":[]}
    for filehandle, newContentType, newFileName, associateObjectType, associateObjectId in zip(fileHandles, newContentTypes, newFileNames, associateObjectTypes, associateObjectIds):
        valid = True
        if checkFileHandle:
            try:
                check = syn._getFileHandleDownload(filehandle['id'], associateObjectId, associateObjectType)
                failureCode = check.get("failureCode")
                if failureCode is not None:
                    valid=False
                    print("%s dataFileHandleId: %s" % (failureCode,filehandle['id']))
            except SynapseHTTPError as e:
                valid = False
                print("%s, %s, %s combination is not correct.  This filehandle will not be copied" % (filehandle['id'], associateObjectId, associateObjectType))
        if newContentType is not None:
            filehandle['contentType'] = newContentType
        if newFileName is not None:
            filehandle['fileName'] = newFileName
        if valid:
            copyFileHandleRequest['copyRequests'].append({"newContentType":filehandle['contentType'],
                                                          "newFileName":filehandle['fileName'],
                                                          "originalFile":{"associateObjectType":associateObjectType,
                                                                          "fileHandleId":filehandle['id'],
                                                                          "associateObjectId":associateObjectId}})
    if len(copyFileHandleRequest['copyRequests']) > 0:
        copiedFileHandle = syn.restPOST('/filehandles/copy',body=json.dumps(copyFileHandleRequest),endpoint=syn.fileHandleEndpoint)
    else:
        copiedFileHandle = {'copyResults':[]}
    return(copiedFileHandle)

def copy(syn, entity, destinationId, skipCopyWikiPage=False, skipCopyAnnotations=False, **kwargs):
    """
    - This function will assist users in copying entities (Tables, Links, Files, Folders, Projects),
      and will recursively copy everything in directories.
    - A Mapping of the old entities to the new entities will be created and all the wikis of each entity
      will also be copied over and links to synapse Ids will be updated.

    :param syn:                 A synapse object: syn = synapseclient.login()- Must be logged into synapse

    :param entity:              A synapse entity ID

    :param destinationId:       Synapse ID of a folder/project that the copied entity is being copied to

    :param skipCopyWikiPage:    Skip copying the wiki pages
                                Default is False

    :param skipCopyAnnotations: Skips copying the annotations
                                Default is False

    Examples::                        
    import synapseutils
    import synapseclient
    syn = synapseclient.login()
    synapseutils.copy(syn, ...)
{'fraction_non_alphanumeric': 0.0923989218328841, 'fraction_numerical': 0.00010781671159029649, 'mean_word_length': 2.812577065351418, 'pattern_counts': {'":': 14, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 21, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6847066', 'n_tokens_mistral': 2194, 'n_tokens_neox': 2138, 'n_words': 761}