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