Skip to content

Commit

Permalink
Change form of module imports
Browse files Browse the repository at this point in the history
- For re module, explicitly compile patterns that are re-used
  - dont rely on re module pattern cache
  - compile when module is loaded or when function is defined for frequently used regexps
  - compile when function is called for rarely used regexps and/or when used in inner loop
- Use import alias to remove runtime attribute lookups
  • Loading branch information
MoojMidge committed Dec 7, 2024
1 parent a7b9cac commit 5e14932
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 63 deletions.
7 changes: 5 additions & 2 deletions resources/lib/youtube_plugin/kodion/abstract_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

from __future__ import absolute_import, division, unicode_literals

import re
from re import (
UNICODE as re_UNICODE,
compile as re_compile,
)

from .constants import (
CHECK_SETTINGS,
Expand Down Expand Up @@ -110,7 +113,7 @@ def wrapper(command):
if not callable(func):
return None

cls._dict_path[re.compile(re_path, re.UNICODE)] = func
cls._dict_path[re_compile(re_path, re_UNICODE)] = func
return command

if command:
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/youtube_plugin/kodion/items/media_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

from __future__ import absolute_import, division, unicode_literals

import re
from datetime import date
from re import compile as re_compile

from . import BaseItem
from ..compatibility import datetime_infolabel, to_str, unescape, urlencode
Expand Down Expand Up @@ -369,7 +369,7 @@ class VideoItem(MediaItem):
'tvshow', 'season', 'episode',
'musicvideo'}
_DEFAULT_MEDIATYPE = CONTENT.VIDEO_TYPE
_RE_IMDB = re.compile(
_RE_IMDB = re_compile(
r'(http(s)?://)?www.imdb.(com|de)/title/(?P<imdbid>[t0-9]+)(/)?'
)

Expand Down
13 changes: 7 additions & 6 deletions resources/lib/youtube_plugin/kodion/utils/datetime_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,37 @@

from __future__ import absolute_import, division, unicode_literals

import re
from datetime import date, datetime, time as dt_time, timedelta
from importlib import import_module
from re import compile as re_compile
from sys import modules
from threading import Condition, Lock

from ..exceptions import KodionException
from ..logger import Logger


try:
from datetime import timezone
except ImportError:
timezone = None


__RE_MATCH_TIME_ONLY__ = re.compile(
__RE_MATCH_TIME_ONLY__ = re_compile(
r'^(?P<hour>[0-9]{2})(:?(?P<minute>[0-9]{2})(:?(?P<second>[0-9]{2}))?)?$'
)
__RE_MATCH_DATE_ONLY__ = re.compile(
__RE_MATCH_DATE_ONLY__ = re_compile(
r'^(?P<year>[0-9]{4})[-/.]?(?P<month>[0-9]{2})[-/.]?(?P<day>[0-9]{2})$'
)
__RE_MATCH_DATETIME__ = re.compile(
__RE_MATCH_DATETIME__ = re_compile(
r'^(?P<year>[0-9]{4})[-/.]?(?P<month>[0-9]{2})[-/.]?(?P<day>[0-9]{2})'
r'["T ](?P<hour>[0-9]{2}):?(?P<minute>[0-9]{2}):?(?P<second>[0-9]{2})'
)
__RE_MATCH_PERIOD__ = re.compile(
__RE_MATCH_PERIOD__ = re_compile(
r'P((?P<years>\d+)Y)?((?P<months>\d+)M)?((?P<days>\d+)D)?'
r'(T((?P<hours>\d+)H)?((?P<minutes>\d+)M)?((?P<seconds>\d+)S)?)?'
)
__RE_MATCH_ABBREVIATED__ = re.compile(
__RE_MATCH_ABBREVIATED__ = re_compile(
r'\w+, (?P<day>\d+) (?P<month>\w+) (?P<year>\d+)'
r' (?P<hour>\d+):(?P<minute>\d+):(?P<second>\d+)'
)
Expand Down
43 changes: 22 additions & 21 deletions resources/lib/youtube_plugin/kodion/utils/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import json
import os
import re
import shutil
from datetime import timedelta
from math import floor, log
Expand All @@ -24,6 +23,7 @@
lt as op_lt,
le as op_le,
)
from re import compile as re_compile

from ..compatibility import byte_string_type, string_type, xbmc, xbmcvfs
from ..logger import Logger
Expand Down Expand Up @@ -143,13 +143,14 @@ def _stream_sort(_stream):
return stream_list[selected_stream]


def strip_html_from_text(text):
def strip_html_from_text(text, tag_re=re_compile('<[^<]+?>')):
"""
Removes html tags
:param text: html text
:param tag_re: RE pattern object used to match html tags
:return:
"""
return re.sub('<[^<]+?>', '', text)
return tag_re.sub('', text)


def print_items(items):
Expand Down Expand Up @@ -208,9 +209,11 @@ def rm_dir(path):
return False


def find_video_id(plugin_path):
match = re.search(r'.*video_id=(?P<video_id>[a-zA-Z0-9_\-]{11}).*',
plugin_path)
def find_video_id(plugin_path,
video_id_re=re_compile(
r'.*video_id=(?P<video_id>[a-zA-Z0-9_\-]{11}).*'
)):
match = video_id_re.search(plugin_path)
if match:
return match.group('video_id')
return ''
Expand All @@ -229,26 +232,24 @@ def friendly_number(value, precision=3, scale=('', 'K', 'M', 'B'), as_str=True):
return output if as_str else (output, value)


_RE_PERIODS = re.compile(r'([\d.]+)(d|h|m|s|$)')
_SECONDS_IN_PERIODS = {
'': 1, # 1 second for unitless period
's': 1, # 1 second
'm': 60, # 1 minute
'h': 3600, # 1 hour
'd': 86400, # 1 day
}


def duration_to_seconds(duration):
def duration_to_seconds(duration,
periods_seconds_map={
'': 1, # 1 second for unitless period
's': 1, # 1 second
'm': 60, # 1 minute
'h': 3600, # 1 hour
'd': 86400, # 1 day
},
periods_re=re_compile(r'([\d.]+)(d|h|m|s|$)')):
if ':' in duration:
seconds = 0
for part in duration.split(':'):
seconds = seconds * 60 + (float(part) if '.' in part else int(part))
return seconds
return sum(
(float(number) if '.' in number else int(number))
* _SECONDS_IN_PERIODS.get(period, 1)
for number, period in re.findall(_RE_PERIODS, duration.lower())
* periods_seconds_map.get(period, 1)
for number, period in periods_re.findall(duration.lower())
)


Expand Down Expand Up @@ -332,8 +333,8 @@ def wait(timeout=None):
return xbmc.Monitor().waitForAbort(timeout)


def redact_ip(url):
return re.sub(r'([?&/])ip([=/])[^?&/]+', r'\g<1>ip\g<2><redacted>', url)
def redact_ip(url, ip_re=re_compile(r'([?&/])ip([=/])[^?&/]+')):
return ip_re.sub(r'\g<1>ip\g<2><redacted>', url)


_STR_OP_MAP = {
Expand Down
34 changes: 19 additions & 15 deletions resources/lib/youtube_plugin/youtube/helper/stream_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

from __future__ import absolute_import, division, unicode_literals

import json
import os
import random
import re
from json import loads as json_loads
from os import path as os_path
from random import choice as random_choice
from re import compile as re_compile
from traceback import format_stack

from .ratebypass import ratebypass
Expand Down Expand Up @@ -875,7 +875,7 @@ def _generate_cpn():
cpn_alphabet = ('abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'0123456789-_')
return ''.join(random.choice(cpn_alphabet) for _ in range(16))
return ''.join(random_choice(cpn_alphabet) for _ in range(16))

def _get_stream_format(self, itag, info=None, max_height=None, **kwargs):
yt_format = self.FORMAT.get(itag)
Expand Down Expand Up @@ -998,10 +998,9 @@ def _get_player_config(page_text):
# pattern source is from youtube-dl
# https://github.com/ytdl-org/youtube-dl/blob/master/youtube_dl/extractor/youtube.py#L313
# LICENSE: The Unlicense
found = re.search(r'ytcfg\.set\s*\(\s*({.+?})\s*\)\s*;', page_text)

if found:
return json.loads(found.group(1))
match = re_compile(r'ytcfg\.set\s*\(\s*({.+?})\s*\)\s*;').search(page_text)
if match:
return json_loads(match.group(1))
return None

def _get_player_js(self):
Expand Down Expand Up @@ -1149,7 +1148,7 @@ def _update_from_hls(self,
# The playlist might include a #EXT-X-MEDIA entry, but it's usually
# for a default stream with itag 133 (240p) and can be ignored.
# Capture the URL of a .m3u8 playlist and the itag from that URL.
re_playlist_data = re.compile(
re_playlist_data = re_compile(
r'#EXT-X-STREAM-INF[^#]+'
r'(?P<url>http\S+/itag/(?P<itag>\d+)\S+)'
)
Expand Down Expand Up @@ -1326,7 +1325,7 @@ def _process_signature_cipher(self, stream_map):
return url
return None

def _process_url_params(self, url):
def _process_url_params(self, url, digits_re=re_compile(r'\d+')):
if not url:
return url, None

Expand Down Expand Up @@ -1362,7 +1361,7 @@ def _process_url_params(self, url):
if primary and secondary:
update_url = {
'netloc': separator.join((
re.sub(r'\d+', fvip, prefix),
digits_re.sub(fvip, prefix),
server.replace(primary, secondary),
)),
}
Expand Down Expand Up @@ -1848,7 +1847,12 @@ def load_stream_info(self, video_id):

return stream_list.values()

def _process_stream_data(self, stream_data, default_lang_code='und'):
def _process_stream_data(self,
stream_data,
default_lang_code='und',
codec_re=re_compile(
r'codecs="([a-z0-9]+([.\-][0-9](?="))?)'
)):
context = self._context
settings = context.get_settings()
audio_only = self._audio_only
Expand Down Expand Up @@ -1896,7 +1900,7 @@ def _process_stream_data(self, stream_data, default_lang_code='und'):
continue

mime_type, codecs = unquote(mime_type).split('; ')
codec = re.match(r'codecs="([a-z0-9]+([.\-][0-9](?="))?)', codecs)
codec = codec_re.match(codecs)
if codec:
codec = codec.group(1)
if codec.startswith('vp9'):
Expand Down Expand Up @@ -2443,7 +2447,7 @@ def _filter_group(previous_group, previous_stream, item):
main_stream['multi_audio'] = True

filename = '.'.join((self.video_id, 'mpd'))
filepath = os.path.join(self.BASE_PATH, filename)
filepath = os_path.join(self.BASE_PATH, filename)
try:
with xbmcvfs.File(filepath, 'w') as mpd_file:
success = mpd_file.write(output)
Expand Down
6 changes: 3 additions & 3 deletions resources/lib/youtube_plugin/youtube/helper/url_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from __future__ import absolute_import, division, unicode_literals

import re
from re import compile as re_compile

from ...kodion.compatibility import parse_qsl, unescape, urlencode, urlsplit
from ...kodion.network import BaseRequestsClass
Expand Down Expand Up @@ -53,10 +53,10 @@ def resolve(self, url, url_components):


class YouTubeResolver(AbstractResolver):
_RE_CHANNEL_URL = re.compile(r'<meta property="og:url" content="'
_RE_CHANNEL_URL = re_compile(r'<meta property="og:url" content="'
r'(?P<channel_url>[^"]+)'
r'">')
_RE_CLIP_DETAILS = re.compile(r'(<meta property="og:video:url" content="'
_RE_CLIP_DETAILS = re_compile(r'(<meta property="og:video:url" content="'
r'(?P<video_url>[^"]+)'
r'">)'
r'|("startTimeMs":"(?P<start_time>\d+)")'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

from __future__ import absolute_import, division, unicode_literals

import re
from re import (
IGNORECASE as re_IGNORECASE,
compile as re_compile,
)

from . import utils
from ...kodion.compatibility import parse_qsl, urlsplit
Expand All @@ -20,7 +23,7 @@


class UrlToItemConverter(object):
RE_PATH_ID = re.compile(r'/[^/]+/(?P<id>[^/?#]+)', re.I)
RE_PATH_ID = re_compile(r'/[^/]+/(?P<id>[^/?#]+)', re_IGNORECASE)
VALID_HOSTNAMES = {
'youtube.com',
'www.youtube.com',
Expand Down
9 changes: 5 additions & 4 deletions resources/lib/youtube_plugin/youtube/helper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

from __future__ import absolute_import, division, unicode_literals

import re

import time
from math import log10
from re import compile as re_compile

from ...kodion.compatibility import unquote, urlsplit
from ...kodion.constants import CONTENT, PATHS
Expand All @@ -24,15 +25,15 @@
)


__RE_PLAYLIST = re.compile(
__RE_PLAYLIST = re_compile(
r'^(/channel/(?P<channel_id>[^/]+))/playlist/(?P<playlist_id>[^/]+)/?$'
)

__RE_SEASON_EPISODE = re.compile(
__RE_SEASON_EPISODE = re_compile(
r'\b(?:Season\s*|S)(\d+)|(?:\b(?:Part|Ep.|Episode)\s*|#|E)(\d+)'
)

__RE_URL = re.compile(r'(https?://\S+)')
__RE_URL = re_compile(r'(https?://\S+)')


def extract_urls(text):
Expand Down
Loading

0 comments on commit 5e14932

Please sign in to comment.