| Conditions | 8 |
| Total Lines | 81 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 3 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | ''' |
||
| 138 | def prepare_working_directory(job, submission_path, validator_path): |
||
| 139 | ''' |
||
| 140 | Based on two downloaded files in the working directory, |
||
| 141 | the student submission and the validation package, |
||
| 142 | the working directory is prepared. |
||
| 143 | |||
| 144 | We unpack student submission first, so that teacher files overwrite |
||
| 145 | them in case. |
||
| 146 | |||
| 147 | When the student submission is a single directory, we change the |
||
| 148 | working directory and go directly into it, before dealing with the |
||
| 149 | validator stuff. |
||
| 150 | |||
| 151 | If unrecoverable errors happen, such as an empty student archive, |
||
| 152 | a JobException is raised. |
||
| 153 | ''' |
||
| 154 | # Safeguard for fail-fast in disk full scenarios on the executor |
||
| 155 | |||
| 156 | dusage = shutil.disk_usage(job.working_dir) |
||
| 157 | if dusage.free < 1024 * 1024 * 50: # 50 MB |
||
| 158 | info_student = "Internal error with the validator. Please contact your course responsible." |
||
| 159 | info_tutor = "Error: Execution cancelled, less then 50MB of disk space free on the executor." |
||
| 160 | logger.error(info_tutor) |
||
| 161 | raise JobException(info_student=info_student, info_tutor=info_tutor) |
||
| 162 | |||
| 163 | submission_fname = os.path.basename(submission_path) |
||
| 164 | validator_fname = os.path.basename(validator_path) |
||
| 165 | |||
| 166 | # Un-archive student submission |
||
| 167 | single_dir, did_unpack = unpack_if_needed(job.working_dir, submission_path) |
||
| 168 | job.student_files = os.listdir(job.working_dir) |
||
| 169 | if did_unpack: |
||
| 170 | job.student_files.remove(submission_fname) |
||
| 171 | |||
| 172 | # Fail automatically on empty student submissions |
||
| 173 | if len(job.student_files) is 0: |
||
| 174 | info_student = "Your compressed upload is empty - no files in there." |
||
| 175 | info_tutor = "Submission archive file has no content." |
||
| 176 | logger.error(info_tutor) |
||
| 177 | raise JobException(info_student=info_student, info_tutor=info_tutor) |
||
| 178 | |||
| 179 | # Handle student archives containing a single directory with all data |
||
| 180 | if single_dir: |
||
| 181 | logger.warning( |
||
| 182 | "The submission archive contains only one directory. Changing working directory.") |
||
| 183 | # Set new working directory |
||
| 184 | job.working_dir = job.working_dir + single_dir + os.sep |
||
| 185 | # Move validator package there |
||
| 186 | shutil.move(validator_path, job.working_dir) |
||
| 187 | validator_path = job.working_dir + validator_fname |
||
| 188 | # Re-scan for list of student files |
||
| 189 | job.student_files = os.listdir(job.working_dir) |
||
| 190 | |||
| 191 | # The working directory now only contains the student data and the downloaded |
||
| 192 | # validator package. |
||
| 193 | # Update the file list accordingly. |
||
| 194 | job.student_files.remove(validator_fname) |
||
| 195 | logger.debug("Student files: {0}".format(job.student_files)) |
||
| 196 | |||
| 197 | # Unpack validator package |
||
| 198 | single_dir, did_unpack = unpack_if_needed(job.working_dir, validator_path) |
||
| 199 | if single_dir: |
||
| 200 | info_student = "Internal error with the validator. Please contact your course responsible." |
||
| 201 | info_tutor = "Error: Directories are not allowed in the validator archive." |
||
| 202 | logger.error(info_tutor) |
||
| 203 | raise JobException(info_student=info_student, info_tutor=info_tutor) |
||
| 204 | |||
| 205 | if not os.path.exists(job.validator_script_name): |
||
| 206 | if did_unpack: |
||
| 207 | # The download was an archive, but the validator was not inside. |
||
| 208 | # This is a failure of the tutor. |
||
| 209 | info_student = "Internal error with the validator. Please contact your course responsible." |
||
| 210 | info_tutor = "Error: Missing validator.py in the validator archive." |
||
| 211 | logger.error(info_tutor) |
||
| 212 | raise JobException(info_student=info_student, |
||
| 213 | info_tutor=info_tutor) |
||
| 214 | else: |
||
| 215 | # The download is already the script, but has the wrong name |
||
| 216 | logger.warning("Renaming {0} to {1}.".format( |
||
| 217 | validator_path, job.validator_script_name)) |
||
| 218 | shutil.move(validator_path, job.validator_script_name) |
||
| 219 | |||
| 223 |