Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion binaryunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, value, unit):
def power(self, number):
for power in range(len(PREFIXES)):
if number < MAX_NUMBER:
return power;
return power

number /= BASE

Expand Down
23 changes: 23 additions & 0 deletions context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Context(object):
@property
def drive(self):
raise NotImplementedError()

@property
def http(self):
raise NotImplementedError()

def logProgress(self,
path,
start,
bytesUploaded,
bytesTotal,
progress,
end):
raise NotImplementedError()

def addToBatch(self, request, callback = None):
raise NotImplementedError()

def addToBatchAndExecute(self, request):
raise NotImplementedError()
4 changes: 4 additions & 0 deletions date.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ def __str__(self):
dateTime = datetime.datetime.utcfromtimestamp(seconds)

return dateTime.strftime(DATE_TIME_FORMAT)

@property
def seconds(self):
return self._seconds
5 changes: 3 additions & 2 deletions driveutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

TIMEOUT = 60 # seconds

FIELDS = 'id, title, mimeType, createdDate, modifiedDate, md5Checksum, fileSize'
FIELDS = 'id, title, mimeType, createdDate, modifiedDate, md5Checksum, fileSize, description, downloadUrl'

DEFAULT_CLIENT_ID = '387402765904.apps.googleusercontent.com'
DEFAULT_CLIENT_SECRET = 'WTj0xKbLAFjDqUeT2HGDZHCi'
Expand All @@ -31,7 +31,8 @@ def drive(saveCredentials = None):
http = (credentials(saveCredentials)
.authorize(httplib2.Http(timeout = TIMEOUT)))

return apiclient.discovery.build('drive', 'v2', http = http)
return (apiclient.discovery.build('drive', 'v2', http = http),
http)

def credentials(save = None):
clientId = config.get('clientId')
Expand Down
10 changes: 8 additions & 2 deletions file.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

class File(object):
def __init__(self, path, name, folder = None):
# Never instantiate the base class.
assert self.__class__ != File
self._path = path
self._name = name
self._folder = utils.firstNonNone(folder, False)
Expand Down Expand Up @@ -38,7 +40,6 @@ def md5(self):
if self.folder:
md5 = hashlib.md5()
md5.update(self.name.encode('utf-8'))

return md5.hexdigest()

return self.contentMd5
Expand All @@ -49,4 +50,9 @@ def contentMd5(self):

@property
def exists(self):
return False
raise NotImplementedError()

# Select the first element of the tuple if the file is a local file, or the
# second element of the tuple if the file is a remote file.
def select(self, tuple):
raise NotImplementedError()
71 changes: 62 additions & 9 deletions folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
import file
import utils

import os

def empty(file):
return Folder(file)
import posixpath

class Folder(object):
def __init__(self, file, children = None, duplicate = None):
# Never instantiate the base class.
assert self.__class__ != Folder
self._file = file
self._children = utils.firstNonNone(children, {})
self._duplicate = utils.firstNonNone(duplicate, [])

def _newFolder(self, file, children = None, duplicate = None):
return self.__class__(file, children, duplicate)

def addChild(self, file):
if file.name in self._children:
self._duplicate.append(file)
Expand Down Expand Up @@ -49,12 +51,63 @@ def folders(self):
return filter(lambda f: f.folder, self._children.values())

def withoutChildren(self):
return Folder(self._file)
return self._newFolder(self._file)

def withoutDuplicate(self):
return Folder(self._file, self._children)
return self._newFolder(self._file, self._children)

def createFile(self, name, folder = None):
path = os.path.join(self._file.path, name)

return file.File(path, name, folder)
raise NotImplementedError()

import localfolder
import remotefolder

import urlparse

class Factory(object):
class VirtualFile(file.File):
def __init__(self):
super(Factory.VirtualFile, self).__init__(None, None, True)

class VirtualFolder(Folder):
def __init__(self):
super(Factory.VirtualFolder, self).__init__(Factory.VirtualFile())

def __init__(self, context):
self.remoteFolderFactory = remotefolder.Factory(context)
self.localFolderFactory = localfolder.Factory(context)

def createVirtual(self, paths):
virtualFolder = Factory.VirtualFolder()
for path in paths:
(head, tail) = posixpath.split(path)
if tail == '':
pathFolder = self.createFromURL(head)
virtualFolder.addChildren(pathFolder.children.values())
else:
realFolder = self.createFromURL(head)
# Virtual folder are sources, so the file must already exist.
virtualFolder.addChild(realFolder.children[tail])

return virtualFolder

def createFromURL(self, url):
parsed_url = urlparse.urlparse(url)
if parsed_url.scheme == 'gdrive':
return self.remoteFolderFactory.create(parsed_url.path)
elif not parsed_url.scheme or parsed_url.scheme == 'file':
return self.localFolderFactory.create(parsed_url.path)
raise RuntimeError('Unable to handle url: %s' % file_descriptor)

def create(self, file_descriptor):
return self._getFactoryForFileDescriptor(
file_descriptor).create(file_descriptor)

def createEmpty(self, file_descriptor):
return self._getFactoryForFileDescriptor(
file_descriptor).createEmpty(file_descriptor)

def _getFactoryForFileDescriptor(self, file_descriptor):
assert isinstance(file_descriptor, file.File)
return file_descriptor.select((self.localFolderFactory,
self.remoteFolderFactory))
Loading