To receive notifications about scheduled maintenance, please subscribe to the mailing-list gitlab-operations@sympa.ethz.ch. You can subscribe to the mailing-list at https://sympa.ethz.ch

moss.py 4.46 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import mosspy
import argparse
import logging

DEFAULT_USER_ID="3795777", # Malte's Moss ID
DEFAULT_LANGUAGE="cc" # C++
DEFAULT_IGNORE_LIMIT=200 # -m in Moss
DEFAULT_NUMBER_OF_MATCHING_FILES=10 # -n in Moss
DEFAULT_TEMPLATE=None
DEFAULT_FILE_PATTERN="./*/main.cpp"
DEFAULT_REPORT_FILE="moss-report.html"
DEFAULT_REPORT_SUBDIR="_moss-report"
DEFAULT_CONNECTIONS=8
DEFAULT_LOGGING_LEVEL="INFO"

def run_moss(
    user_id=DEFAULT_USER_ID,
    language=DEFAULT_LANGUAGE,
    ignore_limit=DEFAULT_IGNORE_LIMIT,
    number_of_matching_files=DEFAULT_NUMBER_OF_MATCHING_FILES,
    template=DEFAULT_TEMPLATE,
    file_pattern=DEFAULT_FILE_PATTERN,
    report_file=DEFAULT_REPORT_FILE,
    report_subdir=DEFAULT_REPORT_SUBDIR,
    connections=DEFAULT_CONNECTIONS):

  # Initialisation
  logging.info("User id: {}".format(user_id))
  logging.info("Language: {}".format(language))

  moss = mosspy.Moss(user_id, language)

  # Configure
  logging.info("Ignore limit: {}".format(ignore_limit))
  logging.info("Matches: {}".format(number_of_matching_files))
  
37
38
  moss.setIgnoreLimit(ignore_limit)
  moss.setNumberOfMatchingFiles(number_of_matching_files)
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

  # Add template file(s)
  logging.info("Template: {}".format(template))

  moss.addBaseFile(template)

  # Add submission file
  logging.info("File pattern: {}".format(file_pattern))

  moss.addFilesByWildcard(file_pattern)

  logging.info("Sending files to Moss")
  url = moss.send() # Submission Report URL

  logging.info("Moss report URL: {}".format(url))

  # Save report file
  logging.info("Downloading report to: {}".format(report_file))

  moss.saveWebPage(url, report_file)

  # Download whole report locally including code diff links
  logging.info("Downloading individual report files to: {}".format(report_subdir))

  mosspy.download_report(url, report_subdir, connections=connections)

  # TODO: Transform moss-report.html and replace remote links to match<n>.html
  #       with local ones to _moss-report/match<n>.html.
  #       Check that Mossum still correctly works on the transformed file!

def configure_cli_parser(parser):
  parser.add_argument(
    "-u", "--user-id",
    type=int,
    help="Moss user ID",
    required=True)

  parser.add_argument(
    "-l", "--language",
    type=str,
    default=DEFAULT_LANGUAGE,
    help="Programming language (default: {})".format(DEFAULT_LANGUAGE))

  parser.add_argument(
    "-m", "--ignore-limit",
    type=int,
    default=DEFAULT_IGNORE_LIMIT,
    help="Passages occurring in at least this many submissions is ignored (default: {})".format(DEFAULT_IGNORE_LIMIT))

  parser.add_argument(
    "-n", "--matches",
    type=int,
    default=DEFAULT_NUMBER_OF_MATCHING_FILES,
    help="Number of matches returned from Moss (default: {})".format(DEFAULT_NUMBER_OF_MATCHING_FILES))

  parser.add_argument(
    "-t", "--template",
    type=str,
    default=DEFAULT_TEMPLATE,
    help="Student template (default: {})".format(DEFAULT_TEMPLATE))

  parser.add_argument(
    "-rf", "--report-file",
    type=str,
    default=DEFAULT_REPORT_FILE,
    help="Summary report file (default: {})".format(DEFAULT_REPORT_FILE))

  parser.add_argument(
    "-rd", "--report-dir",
    type=str,
    default=DEFAULT_REPORT_SUBDIR,
    help="Directory for individual report files (default: {})".format(DEFAULT_REPORT_SUBDIR))
  
  parser.add_argument(
    "--log-level",
    type=str,
    choices=("OFF", "DEBUG", "INFO", "WARNING", "ERROR"),
    default=DEFAULT_LOGGING_LEVEL,
    help="Log level (default: {})".format(DEFAULT_LOGGING_LEVEL))

  parser.add_argument(
    "pattern",
    type=str,
    default=DEFAULT_FILE_PATTERN,
    help="Pattern for files to send to Moss (e.g.: {})".format(DEFAULT_FILE_PATTERN))

def main():
  parser = argparse.ArgumentParser()
  configure_cli_parser(parser)
  args = parser.parse_args()

130
  # See https://docs.python.org/3.8/library/logging.html#logging-levels
131
132
133
134
135
  log_levels = {
    "OFF": logging.NOTSET,
    "DEBUG": logging.DEBUG,
    "INFO": logging.INFO,
    "WARNING": logging.WARNING,
136
    "ERROR": logging.ERROR
137
138
  }

139
  log_level = log_levels[args.log_level]
140

141
142
143
144
  # See https://docs.python.org/3.8/library/logging.html#logrecord-attributes
  log_format = "%(message)s"

  logging.basicConfig(level=log_level, format=log_format)
145
146
147
148
149
150
151
152
153
154
155
156
157

  run_moss(
    user_id=args.user_id,
    language=args.language,
    ignore_limit=args.ignore_limit,
    number_of_matching_files=args.matches,
    template=args.template,
    file_pattern=args.pattern,
    report_file=args.report_file,
    report_subdir=args.report_dir)

if __name__ == '__main__':
  main()