Skip to content
This repository has been archived by the owner on Aug 9, 2024. It is now read-only.

Commit

Permalink
test: add initial unit tests and code cleanup (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher authored Dec 10, 2023
1 parent 0558bf9 commit 7c06806
Show file tree
Hide file tree
Showing 22 changed files with 388 additions and 49 deletions.
76 changes: 69 additions & 7 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
uses: LizardByte/setup-release-action@v2023.1207.150459
with:
github_token: ${{ secrets.GITHUB_TOKEN }}

build:
needs:
- setup_release
Expand Down Expand Up @@ -72,20 +73,21 @@ jobs:
python -m pip install --upgrade --target=./Contents/Libraries/Shared -r \
requirements.txt --no-warn-script-location
- name: Patch python deps
shell: bash
working-directory: PlexyGlass.bundle/Contents/Libraries/Shared
run: |
patch_dir=${{ github.workspace }}/PlexyGlass.bundle/patches
patch -p1 < "${patch_dir}/youtube_dl-compat.patch"
patch -p1 < "${patch_dir}/youtube_dl-extractor.patch"
- name: Build plist
working-directory: PlexyGlass.bundle
env:
BUILD_VERSION: ${{ needs.setup_release.outputs.release_tag }}
run: |
python ./scripts/build_plist.py
- name: Test Plex Plugin
# todo - replace with pytest
working-directory: PlexyGlass.bundle
run: |
python ./Contents/Code/__init__.py
python ./Contents/Services/URL/YouTube/ServiceCode.pys
- name: Package Release
shell: bash
run: |
Expand Down Expand Up @@ -125,3 +127,63 @@ jobs:
prerelease: ${{ needs.setup_release.outputs.publish_pre_release }}
tag: ${{ needs.setup_release.outputs.release_tag }}
token: ${{ secrets.GH_BOT_TOKEN }}

pytest:
needs: [build]
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]

runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download artifacts
uses: actions/download-artifact@v3
with:
name: PlexyGlass.bundle

- name: Extract artifacts zip
shell: bash
run: |
# extract zip
7z x PlexyGlass.bundle.zip -o.
# move all files from "PlexyGlass.bundle" to root, with no target directory
cp -r ./PlexyGlass.bundle/. .
# remove zip
rm PlexyGlass.bundle.zip
- name: Set up Python
uses: LizardByte/setup-python-action@v2023.1210.35516
with:
python-version: '2.7'

- name: Install python dependencies
shell: bash
run: |
python -m pip --no-python-version-warning --disable-pip-version-check install --upgrade \
pip setuptools wheel
python -m pip --no-python-version-warning --disable-pip-version-check install -r requirements-dev.txt
- name: Test with pytest
id: test
shell: bash
run: |
python -m pytest \
-rxXs \
--tb=native \
--verbose \
--cov=Contents/Code \
--cov=Contents/Services \
tests
- name: Upload coverage
# any except canceled or skipped
if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure')
uses: codecov/codecov-action@v3
with:
flags: ${{ runner.os }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,6 @@ plexhints-temp

# Remove python modules
Contents/Libraries/Shared/

# Remove plex service file cache
*.pys[cod]
23 changes: 6 additions & 17 deletions Contents/Code/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-

# standard imports
import sys

# plex debugging
try:
import plexhints # noqa: F401
Expand All @@ -19,13 +16,10 @@
from plexhints.prefs_kit import Prefs # prefs kit

# local imports
if sys.version_info.major < 3:
from default_prefs import default_prefs
else:
from .default_prefs import default_prefs
from default_prefs import default_prefs


def validate_prefs():
def ValidatePrefs():
# type: () -> MessageContainer
"""
Validate plug-in preferences.
Expand All @@ -44,7 +38,7 @@ def validate_prefs():
Examples
--------
>>> validate_prefs()
>>> ValidatePrefs()
...
"""
# todo - validate values are proper type of data, same as retroarcher
Expand Down Expand Up @@ -79,7 +73,7 @@ def validate_prefs():
return MessageContainer(header='Success', message='RetroArcher - Provided preference values are ok')


def start():
def Start():
# type: () -> None
"""
Start the plug-in.
Expand All @@ -92,11 +86,11 @@ def start():
Examples
--------
>>> start()
>>> Start()
...
"""
# validate prefs
prefs_valid = validate_prefs()
prefs_valid = ValidatePrefs()
if prefs_valid.header == 'Error':
Log.Warn('PlexyGlass plug-in preferences are not valid.')

Expand All @@ -112,8 +106,3 @@ def main():
and since Plex removed menu's from plug-ins, this method does not need to perform any other function.
"""
pass


# remap plex predefined functions... function names should be lowercase
Start = start
ValidatePrefs = validate_prefs
21 changes: 6 additions & 15 deletions Contents/Services/URL/YouTube/ServiceCode.pys
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# standard imports
Expand Down Expand Up @@ -104,8 +103,6 @@ def extract_youtube_data(url):
Log.Error('%s :: %s %s Service :: error: %s' % (plugin_name, service_name, service_type, e))
raise Ex.MediaNotAvailable
except youtube_dl.utils.DownloadError as e:
print('----------')
print(e)
if 'Sign in to confirm your age' in str(e):
Log.Error('%s :: %s %s Service :: error: %s' % (plugin_name, service_name, service_type, e))
raise Ex.MediaNotAuthorized
Expand All @@ -125,7 +122,7 @@ def extract_youtube_data(url):
return


def normalize_url(url):
def NormalizeURL(url):
# type: (str) -> Optional[str]
"""
Get the video webpage url from `youtube-dl`.
Expand All @@ -142,7 +139,7 @@ def normalize_url(url):

Examples
--------
>>> normalize_url(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
>>> NormalizeURL(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
"""
Log.Info('%s :: %s %s Service :: normalizing url: %s' % (plugin_name, service_name, service_type, url))
Expand All @@ -162,7 +159,7 @@ def normalize_url(url):
return webpage_url


def metadata_object_for_url(url):
def MetadataObjectForURL(url):
# type: (str) -> Optional[VideoClipObject]
"""
Get YouTube metadata for a given URL.
Expand All @@ -179,7 +176,7 @@ def metadata_object_for_url(url):

Examples
--------
>>> metadata_object_for_url(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
>>> MetadataObjectForURL(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
...
"""
Log.Info('%s :: %s %s Service :: collecting metadata for url: %s' % (plugin_name, service_name, service_type, url))
Expand Down Expand Up @@ -247,7 +244,7 @@ def metadata_object_for_url(url):
)


def media_objects_for_url(url):
def MediaObjectsForURL(url):
# type: (str) -> Optional[list]
"""
Build the Plex media objects for a given URL.
Expand All @@ -264,7 +261,7 @@ def media_objects_for_url(url):

Examples
--------
>>> media_objects_for_url(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
>>> MediaObjectsForURL(url='https://www.youtube.com/watch?v=dQw4w9WgXcQ')
[...]
"""
Log.Info('%s :: %s %s Service :: attempting to create media object for url: %s' % (
Expand Down Expand Up @@ -339,9 +336,3 @@ def play_video(url=None, default_fmt=None, **kwargs):
return IndirectResponse(VideoClipObject, key=final_url)

return


# remap plex predefined functions... function names should be lowercase
NormalizeURL = normalize_url
MetadataObjectForURL = metadata_object_for_url
MediaObjectsForURL = media_objects_for_url
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Integrations
:alt: Read the Docs
:target: http://plexyglass.readthedocs.io/

.. image:: https://img.shields.io/codecov/c/gh/LizardByte/PlexyGlass?token=X8WDZVM33W&style=for-the-badge&logo=codecov&label=codecov
:alt: Codecov
:target: https://codecov.io/gh/LizardByte/PlexyGlass

Downloads
---------

Expand Down
15 changes: 15 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
codecov:
branch: master

coverage:
status:
project:
default:
target: auto
threshold: 10%

comment:
layout: "diff, flags, files"
behavior: default
require_changes: false # if true: only post the comment if coverage changes
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXOPTS ?= -W --keep-going
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
Expand Down
5 changes: 3 additions & 2 deletions docs/make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ if "%SPHINXBUILD%" == "" (
)
set SOURCEDIR=source
set BUILDDIR=build
set "SPHINXOPTS=-W --keep-going"

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
Expand All @@ -25,11 +26,11 @@ if errorlevel 9009 (

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% || exit /b %ERRORLEVEL%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% || exit /b %ERRORLEVEL%

:end
popd
4 changes: 1 addition & 3 deletions docs/source/contributing/testing.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
:github_url: https://github.com/RetroArcher/RetroArcher.bundle/blob/master/docs/source/contributing/testing.rst
:github_url: https://github.com/LizardByte/PlexyGlass/blob/master/docs/source/contributing/testing.rst

Testing
=======
Expand Down Expand Up @@ -41,8 +41,6 @@ Test with Sphinx
pytest
------
.. Todo:: PyTest is not yet implemented.

PlexyGlass uses `pytest <https://pypi.org/project/pytest/>`__ for unit testing. pytest is included in the
``requirements-dev.txt``.

Expand Down
38 changes: 38 additions & 0 deletions patches/youtube_dl-compat.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
diff --git a/youtube_dl/compat.py b/youtube_dl/compat.py
index 3c526a78d..6e2a92d92 100644
--- a/youtube_dl/compat.py
+++ b/youtube_dl/compat.py
@@ -58,18 +58,22 @@ except ImportError: # Python 2

# Also fix up lack of method arg in old Pythons
try:
- _req = compat_urllib_request.Request
- _req('http://127.0.0.1', method='GET')
+ type(compat_urllib_request.Request('http://127.0.0.1', method='GET'))
except TypeError:
- class _request(object):
- def __new__(cls, url, *args, **kwargs):
- method = kwargs.pop('method', None)
- r = _req(url, *args, **kwargs)
- if method:
- r.get_method = types.MethodType(lambda _: method, r)
- return r
-
- compat_urllib_request.Request = _request
+ def _add_init_method_arg(cls):
+ init = cls.__init__
+
+ def wrapped_init(self, *args, **kwargs):
+ method = kwargs.pop('method', 'GET')
+ init(self, *args, **kwargs)
+ if self.has_data() and method == 'GET':
+ method = 'POST'
+ self.get_method = types.MethodType(lambda _: method, self)
+
+ cls.__init__ = wrapped_init
+
+ _add_init_method_arg(compat_urllib_request.Request)
+ del _add_init_method_arg


try:
25 changes: 25 additions & 0 deletions patches/youtube_dl-extractor.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py
index 9c419c002..3bf483c1c 100644
--- a/youtube_dl/extractor/youtube.py
+++ b/youtube_dl/extractor/youtube.py
@@ -260,16 +260,10 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
cookies = self._get_cookies('https://www.youtube.com/')
if cookies.get('__Secure-3PSID'):
return
- consent_id = None
- consent = cookies.get('CONSENT')
- if consent:
- if 'YES' in consent.value:
- return
- consent_id = self._search_regex(
- r'PENDING\+(\d+)', consent.value, 'consent', default=None)
- if not consent_id:
- consent_id = random.randint(100, 999)
- self._set_cookie('.youtube.com', 'CONSENT', 'YES+cb.20210328-17-p0.en+FX+%s' % consent_id)
+ socs = cookies.get('SOCS')
+ if socs and not socs.value.startswith('CAA'): # not consented
+ return
+ self._set_cookie('.youtube.com', 'SOCS', 'CAI', secure=True) # accept all (required for mixes)

def _real_initialize(self):
self._initialize_consent()
Loading

0 comments on commit 7c06806

Please sign in to comment.