8
8
import os
9
9
import json
10
10
import sys
11
- import shutil
11
+ import time
12
12
import fnmatch
13
13
14
- CONFIG_PATH = os .path .join (os .path .dirname (os .path .realpath (__file__ )), '..' , '..' , 'config' )
15
- with open (os .path .join (CONFIG_PATH , 'submitty.json' )) as open_file :
16
- OPEN_JSON = json .load (open_file )
17
- SUBMITTY_DATA_DIR = OPEN_JSON ['submitty_data_dir' ]
18
- SUBMITTY_INSTALL_DIR = OPEN_JSON ['submitty_install_dir' ]
19
-
20
14
IGNORED_FILES = [
21
15
".submit.timestamp"
22
16
]
23
17
24
18
19
+ # returns a string containing the contents of the files which match the regex in the specified dir
20
+ def getConcatFilesInDir (input_dir , regex_patterns ):
21
+ result = ""
22
+ for my_dir , _dirs , my_files in os .walk (input_dir ):
23
+ # Determine if regex should be used (blank regex is equivalent to selecting all files)
24
+ files = sorted (my_files )
25
+ if regex_patterns [0 ] != "" :
26
+ files_filtered = []
27
+ for e in regex_patterns :
28
+ files_filtered .extend (fnmatch .filter (files , e .strip ()))
29
+ files = files_filtered
30
+
31
+ for my_file in files :
32
+ # exclude any files we have ignored for all submissions
33
+ if my_file in IGNORED_FILES :
34
+ continue
35
+ absolute_path = os .path .join (my_dir , my_file )
36
+ # print a separator & filename
37
+ with open (absolute_path , encoding = 'ISO-8859-1' ) as tmp :
38
+ result += f"=============== { my_file } ===============\n "
39
+ # append the contents of the file
40
+ result += tmp .read () + "\n "
41
+ return result
42
+
43
+
25
44
def parse_args ():
26
45
parser = argparse .ArgumentParser (description = "" )
27
- parser .add_argument ("config_path" )
46
+ parser .add_argument ("basepath" )
47
+ parser .add_argument ("datapath" )
28
48
return parser .parse_args ()
29
49
30
50
31
51
def main ():
52
+ start_time = time .time ()
32
53
args = parse_args ()
33
54
34
- sys .stdout .write ("CONCATENATE ALL..." )
55
+ sys .stdout .write ("CONCATENATE ALL..." ) # don't want a newline here so can't use print
35
56
sys .stdout .flush ()
36
57
37
- with open (args .config_path ) as lichen_config :
38
- lichen_config_data = json .load (lichen_config )
39
- semester = lichen_config_data ["semester" ]
40
- course = lichen_config_data ["course" ]
41
- gradeable = lichen_config_data ["gradeable" ]
42
- users_to_ignore = lichen_config_data ["ignore_submissions" ]
58
+ config_path = os .path .join (args .basepath , "config.json" )
59
+ if not os .path .isfile (config_path ):
60
+ print (f"Error: invalid config path provided ({ config_path } )" )
61
+ exit (1 )
62
+
63
+ with open (config_path ) as config_file :
64
+ config = json .load (config_file )
43
65
44
- # this assumes regex is seperated by a ','
45
- regex_expressions = lichen_config_data ["regex" ].split (',' )
46
- regex_dirs = lichen_config_data ["regex_dirs" ]
66
+ semester = config ["semester" ]
67
+ course = config ["course" ]
68
+ gradeable = config ["gradeable" ]
69
+ users_to_ignore = config ["ignore_submissions" ]
70
+ regex_patterns = config ["regex" ].split (',' )
71
+ regex_dirs = config ["regex_dirs" ]
47
72
48
73
# ==========================================================================
49
- # error checking
50
- course_dir = os .path .join (SUBMITTY_DATA_DIR , "courses" , semester , course )
51
- if not os .path .isdir (course_dir ):
52
- print ("ERROR! " , course_dir , " is not a valid course directory" )
53
- exit (1 )
74
+ # Error checking
54
75
55
- for e in regex_expressions :
56
- # Check for backwards crawling
76
+ # Check for backwards crawling
77
+ for e in regex_patterns :
57
78
if ".." in e :
58
79
print ('ERROR! Invalid path component ".." in regex' )
59
80
exit (1 )
@@ -64,99 +85,57 @@ def main():
64
85
exit (1 )
65
86
66
87
# ==========================================================================
67
- # create the directory
68
- concatenated_dir = os .path .join (course_dir , "lichen" , "concatenated" , gradeable )
69
- if not os .path .isdir (concatenated_dir ):
70
- os .makedirs (concatenated_dir )
71
-
72
- # ==========================================================================
73
- count_total_files = 0
88
+ # loop through and concatenate the selected files for each user in this gradeable
74
89
75
90
for dir in regex_dirs :
76
- submission_dir = os .path .join (course_dir , dir , gradeable )
77
-
78
- # more error checking
79
- if not os .path .isdir (submission_dir ):
80
- print ("ERROR! " , submission_dir , " is not a valid gradeable " , dir , " directory" )
81
- exit (1 )
82
-
83
- # =========================================================================
84
- # walk the subdirectories
85
- for user in sorted (os .listdir (submission_dir )):
86
- if not os .path .isdir (os .path .join (submission_dir , user )):
91
+ gradeable_path = os .path .join (args .datapath , semester , course , dir , gradeable )
92
+ # loop over each user
93
+ for user in sorted (os .listdir (gradeable_path )):
94
+ user_path = os .path .join (gradeable_path , user )
95
+ if not os .path .isdir (user_path ):
87
96
continue
88
97
elif user in users_to_ignore :
89
98
continue
90
- for version in sorted (os .listdir (os .path .join (submission_dir , user ))):
91
- if not os .path .isdir (os .path .join (submission_dir , user , version )):
99
+
100
+ # loop over each version
101
+ for version in sorted (os .listdir (user_path )):
102
+ version_path = os .path .join (user_path , version )
103
+ if not os .path .isdir (version_path ):
92
104
continue
93
105
94
- # -----------------------------------------------------------------
95
- # concatenate all files for this submissison into a single file
96
- my_concatenated_dir = os .path .join (concatenated_dir , user , version )
97
- if not os .path .isdir (my_concatenated_dir ):
98
- os .makedirs (my_concatenated_dir )
99
- my_concatenated_file = os .path .join (my_concatenated_dir , "submission.concatenated" )
100
-
101
- with open (my_concatenated_file , 'a' ) as my_cf :
102
- # loop over all files in all subdirectories
103
- base_path = os .path .join (submission_dir , user , version )
104
- for my_dir , _dirs , my_files in os .walk (base_path ):
105
- # Determine if regex should be used (no regex provided
106
- # is equivalent to selecting all files)
107
- files = sorted (my_files )
108
- if regex_expressions [0 ] != "" :
109
- files_filtered = []
110
- for e in regex_expressions :
111
- files_filtered .extend (fnmatch .filter (files , e .strip ()))
112
- files = files_filtered
113
-
114
- for my_file in files :
115
- # exclude any files we have ignored for all submissions
116
- if my_file in IGNORED_FILES :
117
- continue
118
- absolute_path = os .path .join (my_dir , my_file )
119
- # print a separator & filename
120
- my_cf .write (f"=============== { my_file } ===============\n " )
121
- with open (absolute_path , encoding = 'ISO-8859-1' ) as tmp :
122
- # append the contents of the file
123
- my_cf .write (tmp .read ())
124
- my_cf .write ("\n " )
125
- count_total_files += 1
106
+ output_file_path = os .path .join (args .basepath , "users" , user ,
107
+ version , "submission.concatenated" )
108
+
109
+ if not os .path .exists (os .path .dirname (output_file_path )):
110
+ os .makedirs (os .path .dirname (output_file_path ))
111
+
112
+ # append to concatenated file
113
+ with open (output_file_path , "a" ) as output_file :
114
+ concatenated_contents = getConcatFilesInDir (version_path , regex_patterns )
115
+ output_file .write (concatenated_contents )
116
+
126
117
# ==========================================================================
127
- # iterate over all of the created submissions, checking to see if they are
118
+ # iterate over all of the created submissions, checking to see if they are empty
128
119
# and adding a message to the top if so (to differentiate empty files from errors in the UI)
129
- for user in os .listdir (concatenated_dir ):
130
- for version in os .listdir (os .path .join (concatenated_dir , user )):
131
- my_concatenated_file = os .path .join (concatenated_dir ,
132
- user , version , "submission.concatenated" )
120
+ for user in os .listdir (os .path .join (args .basepath , "users" )):
121
+ user_path = os .path .join (args .basepath , "users" , user )
122
+ for version in os .listdir (user_path ):
123
+ version_path = os .path .join (user_path , version )
124
+ my_concatenated_file = os .path .join (version_path , "submission.concatenated" )
133
125
with open (my_concatenated_file , "r+" ) as my_cf :
134
126
if my_cf .read () == "" :
135
127
my_cf .write ("Error: No files matched provided regex in selected directories" )
136
128
137
129
# ==========================================================================
138
- # concatenate any files in the provided_code directory
139
- provided_code_path = os .path .join (course_dir , "lichen" , "provided_code" , gradeable )
140
- output_dir = os .path .join (course_dir , "lichen" , "concatenated" ,
141
- gradeable , "provided_code" , "provided_code" )
142
- output_file = os .path .join (output_dir , "submission.concatenated" )
143
-
144
- if os .path .isdir (provided_code_path ) and len (os .listdir (provided_code_path )) != 0 :
145
- # If the directory already exists, delete it and make a new one
146
- if os .path .isdir (output_dir ):
147
- shutil .rmtree (output_dir )
148
- os .makedirs (output_dir )
149
-
150
- with open (output_file , 'w' ) as of :
151
- # Loop over all of the provided files and concatenate them
152
- for file in sorted (os .listdir (provided_code_path )):
153
- with open (os .path .join (provided_code_path , file ), encoding = 'ISO-8859-1' ) as tmp :
154
- # append the contents of the file
155
- of .write (tmp .read ())
130
+ # concatenate provided code
131
+ with open (os .path .join (args .basepath , "provided_code" ,
132
+ "submission.concatenated" ), "w" ) as file :
133
+ provided_code_files = os .path .join (args .basepath , "provided_code" , "files" )
134
+ file .write (getConcatFilesInDir (provided_code_files , regex_patterns ))
156
135
157
136
# ==========================================================================
158
- print ( "done" )
159
- print (f" { count_total_files } files concatenated " )
137
+ end_time = time . time ( )
138
+ print ("done in " + "%.0f" % ( end_time - start_time ) + " seconds " )
160
139
161
140
162
141
if __name__ == "__main__" :
0 commit comments