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 5.01 KB
Newer Older
1
2
import mosspy
import argparse
scmalte's avatar
scmalte committed
3
4
# import logging
import pprint
5
6
7
8

DEFAULT_USER_ID="3795777", # Malte's Moss ID
DEFAULT_LANGUAGE="cc" # C++
DEFAULT_IGNORE_LIMIT=200 # -m in Moss
scmalte's avatar
scmalte committed
9
DEFAULT_NUMBER_OF_MATCHING_FILES=1000 # -n in Moss
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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):

scmalte's avatar
scmalte committed
28
29
30
31
32
33
34
35
36
37
  # Assemble Moss comment string, starting with functions (local) arguments
  comments = locals()
  comments["script"] = "mu-utils 0.0.1"

  comment_string = str(comments)

  # # A nicely formatted string representation requires a bit of hacking
  # comment_string = pprint.pformat(comments, indent=2)
  # comment_string = comment_string.replace("\n", "<br/>")
  # comment_string = comment_string.replace("  ", "&nbsp;&nbsp;")
38

39
40
41
42
43
44
45
46
47
  # 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))
scmalte's avatar
scmalte committed
48
  # logging.info("Comment: {}".format(comment_string))
49
  
50
51
  moss.setIgnoreLimit(ignore_limit)
  moss.setNumberOfMatchingFiles(number_of_matching_files)
scmalte's avatar
scmalte committed
52
  moss.setCommentString(comment_string)
53
54
55
56

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

57
58
  if template:
    moss.addBaseFile(template)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

  # 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()

145
  # See https://docs.python.org/3.8/library/logging.html#logging-levels
146
147
148
149
150
  log_levels = {
    "OFF": logging.NOTSET,
    "DEBUG": logging.DEBUG,
    "INFO": logging.INFO,
    "WARNING": logging.WARNING,
151
    "ERROR": logging.ERROR
152
153
  }

154
  log_level = log_levels[args.log_level]
155

156
157
158
159
  # See https://docs.python.org/3.8/library/logging.html#logrecord-attributes
  log_format = "%(message)s"

  logging.basicConfig(level=log_level, format=log_format)
160
161
162
163
164
165
166
167
168
169
170
171
172

  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()