import os
from apiclient.http import MediaFileUpload

class GFile:
    '''
    File on google drive
    '''
    def __init__(self, driveService, file_id):
        self.__id = file_id


class GFolder:
    '''
    Folder on google drive
    '''
    def __init__(self, driveService, fullpath=None, idpath=None):
        '''
        Specified one of fullpath or idpath of drive folder, but not both.

        :Args:
            - drive
            - fullpath: a list of folder name start from root,
                        empty list refer to root
        '''
        assert (fullpath is None) != (idpath is None), "Specified either fullpath or idpath"
        self.__ds = driveService
        if idpath is None:
            idpath = ['root']
            for f in fullpath:
                fid = self.__openFromPidName(idpath[-1], f)
                assert fid is not None
                idpath += [fid]
        self.__idPath= idpath

    def __openFromPidName(self, pid, name):
        '''
        :Returns:
            - folder id if exist else None
        '''
        response = self.__ds.files().list(
            q="'%s' in parents and name = '%s' and mimeType='application/vnd.google-apps.folder'"%(pid, name),
            fields="files(id)"
        ).execute()
        f = (response.get('files') or [None])[0]
        return f and f.get('id')

    def List(self):
        '''
        :Returns:
            - (GFiles, GFolders)
        '''
        assert False

    def Create(self, name="", LocalPath="", isFolder=False):
        '''
        Create file/folder under this folder

        :Args:
            - name: str, name of created file/folder
            - LocalPath: str, if upload from local file
            - isFolder: boolean, True if folder created else file created

        :Returns:
            - GFolder object or GFile object
        '''
        name = name or (os.path.split(LocalPath)[1] if LocalPath else "")
        assert name, "Create without filename"

        folder_id = self.__idPath[-1]
        metadata = {
          'name' : name,
          'parents': [folder_id]
        }
        http_args = {
            'body': metadata,
            'fields': 'id'
        }
        if isFolder:
            metadata['mimeType'] = 'application/vnd.google-apps.folder'
        if LocalPath and not isFolder:
            # try read LocalPath
            assert os.path.exists(LocalPath) and os.path.isfile(LocalPath)
            http_args['media_body'] = MediaFileUpload(LocalPath, resumable=True)

        response = self.__ds.files().create(**http_args).execute()
        fid = response.get('id')
        if isFolder:
            return GFolder(self.__ds, idpath=self.__idPath+[fid])
        else:
            return GFile(self.__ds, fid)

    def Open(self, folderName):
        '''
        Get GFolder object under current folder
        
        :Returns:
            - GFolder if exists else None
        '''
        fid = self.__openFromPidName(self.__idPath[-1], folderName)
        return fid and GFolder(self.__ds, idpath=self.__idPath+[fid])

    def Download(self, filename, LocalPath=None):
        '''
        Download file from google drive
        '''
        LocalPath = LocalPath or filename
        assert False

@@ -1471,552 +1471,62 @@
 def 
-Create(self, name=%22%22, LocalPath=%22%22, isFolder=False):%0A        '''%0A        Create file/folder under this folder%0A%0A        :Args:%0A            - name: str, name of created file/folder%0A            - LocalPath: str, if upload from local file%0A            - isFolder: boolean, True if folder created else file created%0A%0A        :Returns:%0A            - GFolder object or GFile object%0A        '''%0A        name = name or (os.path.split(LocalPath)%5B1%5D if LocalPath else %22%22)%0A        assert name, %22Create without filename%22%0A%0A        folder_id = self.__idPath%5B-1%5D
+__prepareHttpArgs(self, name, isFolder, LocalPath=%22%22):
 %0A   
@@ -1594,17 +1594,25 @@
 ': %5B
-folder_id
+self.__idPath%5B-1%5D
 %5D%0A  
@@ -1825,59 +1825,9 @@
 Path
- and not isFolder:%0A            # try read LocalPath
+:
 %0A   
@@ -1979,16 +1979,1158 @@
 e=True)%0A
+        return http_args%0A%0A    def Upload(self, LocalPath, name=%22%22, progressCallback=None):%0A        '''%0A        Upload file to GFolder%0A%0A        :Args:%0A            - LocalPath: str, path to upload file on local file system%0A            - name: str, upload name%0A            - progressCallback: callable, call with upload progress(percent) argument%0A        '''%0A        name = name or (os.path.split(LocalPath)%5B1%5D if LocalPath else %22%22)%0A%0A        http_args = self.__prepareHttpArgs(name, False, LocalPath)%0A        request = self.__ds.files().create(**http_args)%0A%0A        response = None%0A        while response is None:%0A            status, response = request.next_chunk()%0A            if progressCallback and status:%0A                progressCallback(status.progress()*100)%0A%0A    def Create(self, name, isFolder=False):%0A        '''%0A        Create file/folder under this folder%0A%0A        :Args:%0A            - name: str, name of created file/folder%0A            - isFolder: boolean, True if folder created else file created%0A%0A        :Returns:%0A            - GFolder object or GFile object%0A        '''%0A        http_args = self.__prepareHttpArgs(name, isFolder)
 %0A       

Add Upload method to GFolder