def submit_files(course_name, project, files, list='', gpg_key=''): """ Submits the files to the project. @type course_name: string @param course_name: course name @type project: TurninProject @param project: Project to which we should submit the files @type files: list @param files: Python list of files. @type list: TurninList @param list: list of submitted files @type gpg_key: string @param gpg_key: GnuPG public-key ID @rtype: list @return: Python list of submitted files @raise subprocess.CalledProcessError: GnuPG fails to sign """ if not list: list = os.path.join(os.path.expanduser('~'), '.turnin-ng', 'submissions') # We don't want something like /home/ryan/.turning-ng/submissions../ if not os.path.isdir(os.path.normpath(os.path.join(list, os.pardir))): os.makedirs(os.path.normpath(os.path.join(list, os.pardir))) list_file = TurninList(list) random_suffix = '' if list_file.config.has_key(project.course.name): if list_file.config[project.course.name].has_key( project.project['uuid']): random_suffix = list_file.config[project.course.name][ project.project['uuid']] if not random_suffix: chars = string.letters + string.digits for i in range(16): random_suffix += random.choice(chars) list_file.write(project, random_suffix) temparchive = tempfile.NamedTemporaryFile(suffix='.tar.gz') filename = '%(username)s-%(suffix)s.tar.gz' % \ {'username': pwd.getpwuid(os.getuid())[0], # This is the username that # that owns the process 'suffix': random_suffix} tempdir = tempfile.mkdtemp() for file in files: if os.path.isdir(file): shutil.copytree(file, os.path.join(tempdir, file)) else: shutil.copy(file, tempdir) tar = tarfile.open(temparchive.name, 'w:gz') # We want the uncompressed directory to have the username in it so the # professor can easily find a student's assignment. tar.add(tempdir, '%(projectname)s-%(username)s' % {'projectname': project.name, 'username': pwd.getpwuid(os.getuid())[0]}) submitted_files = tar.members tar.close() if gpg_key: cargs = ['gpg', '--sign', '-u ' + gpg_key, '-b', temparchive.name] retcode = subprocess.call(cargs) if retcode < 0: raise subprocess.CalledProcessError(retcode, ' '.join(cargs)) shutil.copy(temparchive.name, os.path.join(project.project['directory'], filename)) os.chmod(os.path.join(project.project['directory'], filename), 0666) # We want the signature's timestamp to be more recent than the archive's. if gpg_key: shutil.copy(temparchive.name + '.sig', os.path.join(project.project['directory'], filename + '.sig')) os.remove(temparchive.name + '.sig') temparchive.close() shutil.rmtree(tempdir, ignore_errors=True) for j, file in enumerate(submitted_files): submitted_files[j] = file.name return submitted_files
def submit_files(project, files, tlist='', gpg_key=''): """ Submits the files to the project. @type project: TurninProject @param project: Project to which we should submit the files @type files: list @param files: Python list of files. @type tlist: TurninList @param tlist: list of submitted files @type gpg_key: string @param gpg_key: GnuPG public-key ID @rtype: list @return: Python list of submitted files @raise subprocess.CalledProcessError: GnuPG fails to sign """ if not tlist: tlist = os.path.join(os.path.expanduser('~'), '.turnin-ng', 'submissions') # We don't want something like /home/ryan/.turning-ng/submissions../ if not os.path.isdir(os.path.normpath(os.path.join(tlist, os.pardir))): os.makedirs(os.path.normpath(os.path.join(tlist, os.pardir))) # We don't want other people to be able to read out submitted file # suffixes and messing with our files! os.chmod(tlist, 0600) list_file = TurninList(tlist) random_suffix = '' if list_file.config.has_key(project.course.name): if list_file.config[project.course.name].has_key( project.project['uuid']): random_suffix = list_file.config[project.course.name][ project.project['uuid']] if not random_suffix: chars = string.letters + string.digits for i in range(16): random_suffix += random.choice(chars) list_file.write(project, random_suffix) temparchive = tempfile.NamedTemporaryFile(suffix='.tar.gz') filename = '%(username)s-%(suffix)s.tar.gz' % \ {'username': pwd.getpwuid(os.getuid())[0], # This is the username that # that owns the process 'suffix': random_suffix} tempdir = tempfile.mkdtemp() for file in files: if os.path.isdir(file): shutil.copytree(file, os.path.join(tempdir, file)) else: shutil.copy(file, tempdir) tar = tarfile.open(temparchive.name, 'w:gz') # We want the uncompressed directory to have the username in it so the # professor can easily find a student's assignment. tar.add(tempdir, '%(projectname)s-%(username)s' % {'projectname': project.name, 'username': pwd.getpwuid(os.getuid())[0]}) submitted_files = tar.members tar.close() if gpg_key: cargs = ['gpg', '--sign', '-u ' + gpg_key, '-b', temparchive.name] retcode = subprocess.call(cargs) if retcode < 0: raise subprocess.CalledProcessError(retcode, ' '.join(cargs)) print "An error occured when calling GPG, not submitting signature" # It's important that we set gpg_key to False. Otherwise, # shutil.copy below will fail because it can't find the .sig file # and Turnin-NG will crash. gpg_key = False shutil.copyfile(temparchive.name, os.path.join(project.project['directory'], filename)) try: os.chmod(os.path.join(project.project['directory'], filename), 0666) except OSError, e: if e.errno == e.EPERM: # We've got an error on our hands: # OSError: [Errno 1] Operation not permitted # # Probable cause: # # We've previously submitted. A managing user has since # disabled/enabled the project and is now the owner of our archive. # Since we aren't the owner, we don't have permisisons to run chmod. # In any case, unless we have a malicious TA, since we've already # submitted, the permissions on our file should already be correct. pass
def submit_files(project, files, tlist='', gpg_key=''): """ Submits the files to the project. @type project: TurninProject @param project: Project to which we should submit the files @type files: list @param files: Python list of files. @type tlist: TurninList @param tlist: list of submitted files @type gpg_key: string @param gpg_key: GnuPG public-key ID @rtype: list @return: Python list of submitted files @raise subprocess.CalledProcessError: GnuPG fails to sign @raise EnvironmentError: tlist exists and is not a file """ if not tlist: tlist = os.path.join(os.path.expanduser('~'), '.turnin-ng', 'submissions') # We don't want something like /home/ryan/.turning-ng/submissions../ if not os.path.isdir(os.path.normpath(os.path.join(tlist, os.pardir))): os.makedirs(os.path.normpath(os.path.join(tlist, os.pardir))) # Create the TurninList if it doesn't exist: if not os.path.isfile(tlist): if os.path.exists(tlist): raise EnvironmentError( "Path for list of submissions %s exists " % tlist + "but is not a file.") else: open(tlist, 'w').close() # We don't want other people to be able to read out submitted file # suffixes and messing with our files! os.chmod(tlist, 0600) list_file = TurninList(tlist) random_suffix = '' if list_file.config.has_key(project.course.name): if list_file.config[project.course.name].has_key( project.project['uuid']): random_suffix = list_file.config[project.course.name][ project.project['uuid']] if not random_suffix: chars = string.letters + string.digits for i in range(16): random_suffix += random.choice(chars) list_file.write(project, random_suffix) temparchive = tempfile.NamedTemporaryFile(suffix='.tar.gz') filename = '%(username)s-%(suffix)s.tar.gz' % \ {'username': pwd.getpwuid(os.getuid())[0], # This is the username that # that owns the process 'suffix': random_suffix} tempdir = tempfile.mkdtemp() for file in files: if os.path.isdir(file): shutil.copytree(file, os.path.join(tempdir, file)) else: shutil.copy(file, tempdir) tar = tarfile.open(temparchive.name, 'w:gz') # We want the uncompressed directory to have the username in it so the # professor can easily find a student's assignment. tar.add( tempdir, '%(projectname)s-%(username)s' % { 'projectname': project.name, 'username': pwd.getpwuid(os.getuid())[0] }) submitted_files = tar.members tar.close() if gpg_key: cargs = ['gpg', '--sign', '-u ' + gpg_key, '-b', temparchive.name] retcode = subprocess.call(cargs) if retcode < 0: raise subprocess.CalledProcessError(retcode, ' '.join(cargs)) print "An error occured when calling GPG, not submitting signature" # It's important that we set gpg_key to False. Otherwise, # shutil.copy below will fail because it can't find the .sig file # and Turnin-NG will crash. gpg_key = False shutil.copyfile(temparchive.name, os.path.join(project.project['directory'], filename)) try: os.chmod(os.path.join(project.project['directory'], filename), 0666) except OSError, e: if e.errno == e.EPERM: # We've got an error on our hands: # OSError: [Errno 1] Operation not permitted # # Probable cause: # # We've previously submitted. A managing user has since # disabled/enabled the project and is now the owner of our archive. # Since we aren't the owner, we don't have permisisons to run chmod. # In any case, unless we have a malicious TA, since we've already # submitted, the permissions on our file should already be correct. pass