Cloned DMOJ
This commit is contained in:
parent
f623974b58
commit
49dc9ff10c
513 changed files with 132349 additions and 39 deletions
148
judge/utils/caniuse.py
Normal file
148
judge/utils/caniuse.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
import requests
|
||||
from ua_parser import user_agent_parser
|
||||
|
||||
_SUPPORT_DATA = requests.get('https://raw.githubusercontent.com/Fyrd/caniuse/master/data.json').json()['data']
|
||||
|
||||
SUPPORT = 'y'
|
||||
PARTIAL_SUPPORT = 'a'
|
||||
UNSUPPORTED = 'n'
|
||||
POLYFILL = 'p'
|
||||
UNKNOWN = 'u'
|
||||
PREFIX = 'x'
|
||||
DISABLED = 'd'
|
||||
|
||||
|
||||
def safe_int(string):
|
||||
try:
|
||||
return int(string)
|
||||
except (ValueError, TypeError):
|
||||
return 0
|
||||
|
||||
|
||||
class BrowserFamily(object):
|
||||
def __init__(self, data):
|
||||
self._data = data
|
||||
self._ranges = ranges = []
|
||||
self._versions = versions = {}
|
||||
max_version = ()
|
||||
max_support = UNKNOWN
|
||||
|
||||
for version, support in data.items():
|
||||
if version == 'all':
|
||||
self.max_support = support
|
||||
elif '-' in version:
|
||||
start, end = version.split('-')
|
||||
start = tuple(map(int, start.split('.')))
|
||||
end = tuple(map(int, end.split('.'))) + (1e3000,)
|
||||
ranges.append((start, end, support))
|
||||
if end > max_version:
|
||||
max_version = end
|
||||
max_support = support
|
||||
else:
|
||||
try:
|
||||
version = tuple(map(int, version.split('.')))
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
if version > max_version:
|
||||
max_version = version
|
||||
max_support = support
|
||||
versions[version] = support
|
||||
|
||||
self.max_version = max_version
|
||||
self.max_support = max_support
|
||||
|
||||
def check(self, major, minor, patch):
|
||||
int_major, int_minor, int_patch = map(safe_int, (major, minor, patch))
|
||||
|
||||
version = (int_major, int_minor, int_patch)
|
||||
if version > self.max_version:
|
||||
return self.max_support
|
||||
|
||||
for key in ((int_major, int_minor, int_patch), (int_major, int_minor), (int_major,), major):
|
||||
try:
|
||||
return self._versions[key]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for start, end, support in self._ranges:
|
||||
if start <= version < end:
|
||||
return support
|
||||
|
||||
return UNKNOWN
|
||||
|
||||
|
||||
class Feat(object):
|
||||
def __init__(self, data):
|
||||
self._data = data
|
||||
self._family = {name: BrowserFamily(data) for name, data in data['stats'].items()}
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self._family[item]
|
||||
|
||||
|
||||
class Database(object):
|
||||
def __init__(self, data):
|
||||
self._data = data
|
||||
self._feats = {feat: Feat(data) for feat, data in data.items()}
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self._feats[item]
|
||||
|
||||
|
||||
database = Database(_SUPPORT_DATA)
|
||||
|
||||
|
||||
class CanIUse(object):
|
||||
def __init__(self, ua):
|
||||
self._agent = user_agent_parser.Parse(ua)
|
||||
|
||||
os_family = self._agent['os']['family']
|
||||
browser_family = self._agent['user_agent']['family']
|
||||
|
||||
family = None
|
||||
|
||||
if os_family == 'Android':
|
||||
if 'Firefox' in browser_family:
|
||||
family = 'and_ff'
|
||||
elif 'Chrome' in browser_family:
|
||||
family = 'and_chr'
|
||||
elif 'Android' in browser_family:
|
||||
family = 'android'
|
||||
else:
|
||||
if 'Edge' in browser_family:
|
||||
family = 'edge'
|
||||
elif 'Firefox' in browser_family:
|
||||
family = 'firefox'
|
||||
elif 'Chrome' in browser_family:
|
||||
family = 'chrome'
|
||||
elif 'IE' in browser_family:
|
||||
family = 'ie'
|
||||
elif 'Opera' in browser_family:
|
||||
family = 'opera'
|
||||
elif 'Safari' in browser_family:
|
||||
family = 'safari'
|
||||
|
||||
self._family = family
|
||||
|
||||
def _check_feat(self, feat):
|
||||
if not self._family:
|
||||
return UNKNOWN
|
||||
|
||||
try:
|
||||
stats = feat[self._family]
|
||||
except KeyError:
|
||||
return UNKNOWN
|
||||
else:
|
||||
ua = self._agent['user_agent']
|
||||
return stats.check(ua['major'], ua['minor'], ua['patch'])[0]
|
||||
|
||||
def __getattr__(self, attr):
|
||||
try:
|
||||
feat = database[attr.replace('_', '-')]
|
||||
except KeyError:
|
||||
raise AttributeError(attr)
|
||||
else:
|
||||
result = self._check_feat(feat)
|
||||
setattr(self, attr, result)
|
||||
return result
|
Loading…
Add table
Add a link
Reference in a new issue