Repository: kmyk/online-judge-tools
Pull request #645 (2019-12-29 16:58:37)

allow {m1,m2,m3}.codeforces.com as URL
こどふぉの負荷対策の http://m1.codeforces.com/ のような URL を認識するようにします。
ただし内部のリクエストはすべて https://codeforces.com/ のままです。これはすこし混乱を招く仕様ですが http://m1.codeforces.com/ などは微妙に仕様が違ってて対応が無理なので仕方ないと考えています。


Patch:
diff --git a/onlinejudge/service/codeforces.py b/onlinejudge/service/codeforces.py
index bb8b5f1..25e8f50 100644
--- a/onlinejudge/service/codeforces.py
+++ b/onlinejudge/service/codeforces.py
@@ -21,6 +21,8 @@ import onlinejudge.dispatch
 import onlinejudge.type
 from onlinejudge.type import *
 
+_CODEFORCES_DOMAINS = ('codeforces.com', 'm1.codeforces.com', 'm2.codeforces.com', 'm3.codeforces.com')
+
 
 class CodeforcesService(onlinejudge.type.Service):
     def login(self, *, get_credentials: onlinejudge.type.CredentialsProvider, session: Optional[requests.Session] = None) -> None:
@@ -73,7 +75,7 @@ class CodeforcesService(onlinejudge.type.Service):
         # example: http://codeforces.com/
         result = urllib.parse.urlparse(url)
         if result.scheme in ('', 'http', 'https') \
-                and result.netloc == 'codeforces.com':
+                and result.netloc in _CODEFORCES_DOMAINS:
             return cls()
         return None
 
@@ -185,7 +187,7 @@ class CodeforcesContest(onlinejudge.type.Contest):
     def from_url(cls, url: str) -> Optional['CodeforcesContest']:
         result = urllib.parse.urlparse(url)
         if result.scheme in ('', 'http', 'https') \
-                and result.netloc == 'codeforces.com':
+                and result.netloc in _CODEFORCES_DOMAINS:
             table = {}
             table['contest'] = r'/contest/([0-9]+).*'.format()  # example: https://codeforces.com/contest/538
             table['gym'] = r'/gym/([0-9]+).*'.format()  # example: https://codeforces.com/gym/101021
@@ -399,7 +401,7 @@ class CodeforcesProblem(onlinejudge.type.Problem):
     def from_url(cls, url: str) -> Optional['CodeforcesProblem']:
         result = urllib.parse.urlparse(url)
         if result.scheme in ('', 'http', 'https') \
-                and result.netloc == 'codeforces.com':
+                and result.netloc in _CODEFORCES_DOMAINS:
             # "0" is needed. example: https://codeforces.com/contest/1000/problem/0
             # "[1-9]?" is sometime used. example: https://codeforces.com/contest/1133/problem/F2
             re_for_index = r'(0|[A-Za-z][1-9]?)'


Test patch:
diff --git a/tests/service_codeforces.py b/tests/service_codeforces.py
index 71a1713..239242c 100644
--- a/tests/service_codeforces.py
+++ b/tests/service_codeforces.py
@@ -18,6 +18,12 @@ class CodeforcesContestTest(unittest.TestCase):
         self.assertEqual(CodeforcesContest.from_url('http://codeforces.com/gym/101025').contest_id, 101025)
         self.assertIsNone(CodeforcesContest.from_url('https://atcoder.jp/contests/abc120'))
 
+    def test_from_url_mx(self):
+        self.assertEqual(CodeforcesContest.from_url('http://m1.codeforces.com/contest/1333').get_url(), CodeforcesContest.from_url('https://codeforces.com/contest/1333').get_url())
+        self.assertEqual(CodeforcesContest.from_url('http://m2.codeforces.com/contest/1333').get_url(), CodeforcesContest.from_url('https://codeforces.com/contest/1333').get_url())
+        self.assertEqual(CodeforcesContest.from_url('http://m3.codeforces.com/contest/1333').get_url(), CodeforcesContest.from_url('https://codeforces.com/contest/1333').get_url())
+        self.assertIsNone(CodeforcesContest.from_url('http://m4.codeforces.com/contest/1333'))
+
     def test_list_problems_data(self):
         contest = CodeforcesContest.from_url('https://codeforces.com/contest/1157')
         problems = contest.list_problem_data()