@@ -88,6 +88,59 @@ def __init__(
88
88
warn (f"found unknown problem.yaml key: { key } in credits" )
89
89
90
90
91
+ class ProblemSource :
92
+ def __init__ (self , name : str , url : Optional [str ] = None ):
93
+ self .name = name
94
+ self .url = url
95
+
96
+ def __repr__ (self ) -> str :
97
+ return self .name + (f" ({ self .url } )" if self .url else "" )
98
+
99
+
100
+ class ProblemSources (list [ProblemSource ]):
101
+ def __init__ (
102
+ self ,
103
+ yaml_data : dict [str , Any ],
104
+ problem_settings : "ProblemSettings" ,
105
+ ):
106
+ # If problem.yaml uses the legacy version, do not support the new type of the `source` key.
107
+ # If problem.yaml uses 2023-07-draft, prefer `source`, but also support `source_url` and warn for it.
108
+ legacy_source_url = parse_optional_setting (yaml_data , "source_url" , str )
109
+ if problem_settings .is_legacy ():
110
+ source_name = parse_setting (yaml_data , "source" , "" )
111
+ if legacy_source_url :
112
+ self .append (ProblemSource (source_name , legacy_source_url ))
113
+ else :
114
+ if legacy_source_url is not None :
115
+ warn ("problem.yaml: source_url is removed in 2023-07-draft, please use source.url" )
116
+ if "source" not in yaml_data :
117
+ return
118
+ if isinstance (yaml_data ["source" ], str ):
119
+ self .append (ProblemSource (parse_setting (yaml_data , "source" , "" )))
120
+ return
121
+ if isinstance (yaml_data ["source" ], dict ):
122
+ source = parse_setting (yaml_data , "source" , dict [str , str ]())
123
+ self .append (
124
+ ProblemSource (
125
+ parse_setting (source , "name" , "" ),
126
+ parse_optional_setting (source , "url" , str ),
127
+ )
128
+ )
129
+ return
130
+ if isinstance (yaml_data ["source" ], list ):
131
+ sources = parse_setting (yaml_data , "source" , list [dict [str , str ]]())
132
+ for raw_source in sources :
133
+ source = parse_setting (raw_source , "source" , dict [str , str ]())
134
+ self .append (
135
+ ProblemSource (
136
+ parse_setting (source , "name" , "" ),
137
+ parse_optional_setting (source , "url" , str ),
138
+ )
139
+ )
140
+ return
141
+ warn ("problem.yaml key 'source' does not have the correct type" )
142
+
143
+
91
144
class ProblemLimits :
92
145
def __init__ (
93
146
self ,
@@ -237,8 +290,7 @@ def __init__(
237
290
self .uuid : str = parse_setting (yaml_data , "uuid" , "" )
238
291
self .version : str = parse_setting (yaml_data , "version" , "" )
239
292
self .credits = ProblemCredits (yaml_data , self )
240
- self .source : str = parse_setting (yaml_data , "source" , "" )
241
- self .source_url : str = parse_setting (yaml_data , "source_url" , "" )
293
+ self .source = ProblemSources (yaml_data , self )
242
294
self .license : str = parse_setting (yaml_data , "license" , "unknown" )
243
295
self .rights_owner : str = parse_setting (yaml_data , "rights_owner" , "" )
244
296
# Not implemented in BAPCtools. Should be a date, but we don't do anything with this anyway.
0 commit comments