示例#1
0
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
示例#2
0
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