use flit packaging tool, write simple test

This commit is contained in:
cristoffel 2023-11-06 18:58:32 +01:00
parent 79c7c2f060
commit bb5eb5445e
15 changed files with 195 additions and 209 deletions

5
.gitignore vendored
View file

@ -2,7 +2,10 @@
.idea
/dist
/.eggs
/venv
venv
*.pyc
*.egg
*.egg-info
*.coverage
*.swp
*.swo

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# Python Markdown Plugin for oEmbed
## Install flit
```
pip install flit
```
## Build needed packages for project
```
flit install
```

27
flake.lock Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1698611440,
"narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0cbe9f69c234a7700596e943bfae7ef27a31b735",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

29
flake.nix Normal file
View file

@ -0,0 +1,29 @@
{
description = "Oembed plugin flake";
inputs = {
nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
};
outputs = { self, nixpkgs }:
let
pkgs = import nixpkgs {
inherit system;
overlays = [];
};
pythonPackages = pkgs.python3Packages;
system = "x86_64-linux";
in rec {
devShell.x86_64-linux = pkgs.mkShell {
buildInputs = [
pkgs.python3
pkgs.python3Packages.pip
];
shellHook = ''
export PS1='\u@md-oembed \$ '
export PIP_PREFIX=$(pwd)/venv/pip_packages
export PYTHONPATH="$PIP_PREFIX/${pkgs.python3.sitePackages}:$PYTHONPATH"
export PATH="$PIP_PREFIX/bin:$PATH"
unset SOURCE_DATE_EPOCH
'';
};
};
}

View file

@ -1,9 +0,0 @@
# -*- coding: utf-8 -*-
from mdx_oembed.extension import OEmbedExtension
VERSION = '0.2.1'
def makeExtension(**kwargs):
return OEmbedExtension(**kwargs)

46
pyproject.toml Normal file
View file

@ -0,0 +1,46 @@
[build-system]
build-backend = "flit_core.buildapi"
requires = ["flit_core >=3.8.0,<4"]
[project]
name = "python_markdown-oembed_extension"
version = "0.0.0"
authors = [
{name = "nmc", email = "contact-nmc@unibas.ch"},
]
description = "Detect inline pattern starting with '![', use the following data to request oembed data from the video hoster and create appropriate iframe html"
readme = "README.md"
requires-python = ">=3.7"
keywords = ["markdown", "html", "oembed"]
license = {text = "GPLv3"}
classifiers = [
"Programming Language :: Python :: 3",
]
dependencies = [
"python-oembed",
"markdown",
"requests",
]
[project.optional-dependencies]
dev = [
"pylint ~=2.14.0",
"toml ~=0.10.2",
"yapf ~=0.32.0",
]
test = [
"pytest-cov ~=3.0.0",
"requests_mock",
"pyyaml",
]
[project.scripts]
my-script = "my_package.module:function"
[tool.coverage.run]
source = ["src"]
[tool.pytest.ini_options]
addopts = "--cov --cov-report html --cov-report term-missing --cov-fail-under 15"
# ... other project metadata fields as specified in:
# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import oembed
YOUTUBE = oembed.OEmbedEndpoint('https://www.youtube.com/oembed', [

View file

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import logging
from markdown.inlinepatterns import Pattern
import oembed
@ -10,7 +9,6 @@ LOG = logging.getLogger(__name__)
OEMBED_LINK_RE = r'\!\[([^\]]*)\]\(((?:https?:)?//[^\)]*)' \
r'(?<!png)(?<!jpg)(?<!jpeg)(?<!gif)(?<!avif)(?<!webp)\)'
class OEmbedLinkPattern(Pattern):
def __init__(self, pattern, md=None, oembed_consumer=None):

View file

@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
from markdown import Extension
import oembed
from mdx_oembed.endpoints import DEFAULT_ENDPOINTS
from mdx_oembed.inlinepatterns import OEmbedLinkPattern, OEMBED_LINK_RE
from python_markdown_oembed_extension.endpoints import DEFAULT_ENDPOINTS
from python_markdown_oembed_extension.inlinepatterns import OEmbedLinkPattern, OEMBED_LINK_RE
class OEmbedExtension(Extension):
@ -28,7 +27,8 @@ class OEmbedExtension(Extension):
consumer = oembed.OEmbedConsumer()
if allowed_endpoints:
for endpoint in allowed_endpoints:
for endpoint in allowed_endpoints:
consumer.addEndpoint(endpoint)
return consumer

View file

@ -0,0 +1,9 @@
<p>In this video Jakob Zinsstag introduces the topic of the course. You will
discover that the relationship between humans and animals is manifold.
{.lead}</p>
<p><figure class="oembed ratio ratio-16x9"><iframe src="https://player.vimeo.com/video/734276368?h=f29c542352&amp;app_id=122963" width="426" height="240" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" title="One-Health_Tales_EN_1-02"></iframe></figure> </p>
<p>Have a look at the farm of Jakob Zinsstags cousin in the Canton of Jura,
Switzerland. Different animals create different feelings: there are those we
love, some provoke fears and others will be eaten. Jakob Zinsstag shares the
personal experiences he has had with animals. </p>
<p><strong>How do you categorise your own experience with animals?</strong></p>

View file

@ -0,0 +1,12 @@
In this video Jakob Zinsstag introduces the topic of the course. You will
discover that the relationship between humans and animals is manifold.
{.lead}
![embed](https://vimeo.com/734276368/f29c542352)
Have a look at the farm of Jakob Zinsstags cousin in the Canton of Jura,
Switzerland. Different animals create different feelings: there are those we
love, some provoke fears and others will be eaten. Jakob Zinsstag shares the
personal experiences he has had with animals.
**How do you categorise your own experience with animals?**

View file

@ -0,0 +1,21 @@
import markdown, yaml, requests_mock
from python_markdown_oembed_extension.oembedextension import OEmbedExtension
from python_markdown_oembed_extension.endpoints import VIMEO
def test_full():
with ( requests_mock.Mocker() as m
, open('./src/python_markdown_oembed_extension/tests/vimeoMock.yaml', 'r') as vm
, open('./src/python_markdown_oembed_extension/tests/test_markdown.md', 'r') as md
, open('./src/python_markdown_oembed_extension/tests/test_expectedHtml.html', 'r') as expectedHtml
):
yml = yaml.safe_load(vm)
m.get(yml['request'], json=yml['response'])
mdString = md.read()
htmlString = markdown.markdown(mdString, extensions=[OEmbedExtension()])
print(htmlString)
assert htmlString == expectedHtml.read().rstrip()

View file

@ -0,0 +1,30 @@
---
request: 'https://vimeo.com/734276368/f29c542352'
response:
account_type: 'live_premium'
author_name: 'NMC Universität Basel'
author_url: 'https://vimeo.com/newmediacenterunibasel'
description: ''
duration: 282
height: 240
html: >-
<iframe
src="https://player.vimeo.com/video/734276368?h=f29c542352&amp;app_id=122963"
width="426" height="240" frameborder="0" allow="autoplay; fullscreen; picture-in-picture"
title="One-Health_Tales_EN_1-02"
>
</iframe>
is_plus: '0'
provider_name: 'Vimeo'
provider_url: 'https://vimeo.com/'
thumbnail_height: 166
thumbnail_url: 'https://i.vimeocdn.com/video/1480489232-5ca2d723cadc09ae077c8b437581e84bd0485049780c60e218986fda60881110-d_295x166'
thumbnail_url_with_play_button: 'https://i.vimeocdn.com/filter/overlay?src0=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1480489232-5ca2d723cadc09ae077c8b437581e84bd0485049780c60e218986fda60881110-d_295x166&src1=http%3A%2F%2Ff.vimeocdn.com%2Fp%2Fimages%2Fcrawler_play.png'
thumbnail_width: 295
title: 'One-Health_Tales_EN_1-02'
type: 'video'
upload_date: '2022-07-28 04:16:03'
uri: '/videos/734276368:f29c542352'
version: '1.0'
video_id: 734276368
width: 426

192
tests.py
View file

@ -1,192 +0,0 @@
# -*- coding: utf-8 -*-
import re
import unittest
import markdown
from mock import patch
from nose.plugins.skip import SkipTest
from mdx_oembed.extension import OEMBED_LINK_RE
from mdx_oembed import endpoints
class OEmbedPatternRegexTestCase(unittest.TestCase):
def setUp(self):
self.re = re.compile(OEMBED_LINK_RE)
def test_ignore_relative_image_link(self):
text = '![image](/image.png)'
match = self.re.match(text)
self.assertIsNone(match)
def test_ignore_absolute_image_link(self):
text = '![Mumbo Jumbo](http://tannern.com/mumbo-jumbo.jpg)'
match = self.re.match(text)
self.assertIsNone(match)
def test_ignore_png_image_link(self):
text = '![Mumbo Jumbo](http://tannern.com/mumbo-jumbo.png)'
match = self.re.match(text)
self.assertIsNone(match)
def test_ignore_jpg_image_link(self):
text = '![Mumbo Jumbo](http://tannern.com/mumbo-jumbo.jpg)'
match = self.re.match(text)
self.assertIsNone(match)
def test_ignore_gif_image_link(self):
text = '![Mumbo Jumbo](http://tannern.com/mumbo-jumbo.gif)'
match = self.re.match(text)
self.assertIsNone(match)
def test_find_youtube_link(self):
text = '![video](http://www.youtube.com/watch?v=7XzdZ4KcI8Y)'
match = self.re.match(text)
self.assertIsNotNone(match)
def test_find_youtube_short_link(self):
text = '![video](http://youtu.be/7XzdZ4KcI8Y)'
match = self.re.match(text)
self.assertIsNotNone(match)
def test_find_youtube_http(self):
text = '![video](http://youtu.be/7XzdZ4KcI8Y)'
match = self.re.match(text)
self.assertIsNotNone(match)
def test_find_youtube_https(self):
text = '![video](https://youtu.be/7XzdZ4KcI8Y)'
match = self.re.match(text)
self.assertIsNotNone(match)
def test_find_youtube_auto(self):
text = '![video](//youtu.be/7XzdZ4KcI8Y)'
match = self.re.match(text)
self.assertIsNotNone(match)
class OEmbedExtensionTestCase(unittest.TestCase):
def setUp(self):
self.markdown = markdown.Markdown(extensions=['oembed'])
def assert_convert(self, text, expected):
with patch('oembed.OEmbedEndpoint') as MockOEmbedEndpoint:
MockOEmbedEndpoint.get.return_value = expected
output = self.markdown.convert(text)
self.assertEqual(output, expected)
class IgnoredTestCase(OEmbedExtensionTestCase):
"""
The OEmbedExtension should ignore these tags allowing markdown's image
processor to find and handle them.
"""
def test_relative(self):
text = '![alt](image.png)'
expected = '<p><img alt="alt" src="image.png" /></p>'
output = self.markdown.convert(text)
self.assertEqual(output, expected)
def test_slash_relative(self):
text = '![alt](/image.png)'
expected = '<p><img alt="alt" src="/image.png" /></p>'
output = self.markdown.convert(text)
self.assertEqual(output, expected)
def test_absolute(self):
text = '![Mumbo Jumbo](http://tannern.com/mumbo-jumbo.jpg)'
expected = '<p><img alt="Mumbo Jumbo" src="http://tannern.com/mumbo-jumbo.jpg" /></p>'
output = self.markdown.convert(text)
self.assertEqual(output, expected)
class ProtocolVarietyTestCase(OEmbedExtensionTestCase):
def test_http(self):
text = '![video](http://www.youtube.com/watch?v=7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
def test_https(self):
text = '![video](https://www.youtube.com/watch?v=7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
def test_auto(self):
raise SkipTest()
text = '![video](//www.youtube.com/watch?v=7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
class YoutubeTestCase(OEmbedExtensionTestCase):
"""
The OEmbedExtension should handle embedding for these cases.
"""
def test_youtube_link(self):
"""
YouTube video link.
"""
text = '![video](http://www.youtube.com/watch?v=7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
def test_youtube_short_link(self):
"""
Short format YouTube video link.
"""
text = '![video](http://youtu.be/7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
class VimeoTestCase(OEmbedExtensionTestCase):
def test_vimeo_link(self):
"""
Vimeo video link.
"""
text = '![link](http://vimeo.com/52970271)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
class SlideshareTestCase(OEmbedExtensionTestCase):
def test_slideshare_link(self):
"""
Slideshare Presentation link.
"""
text = '![slides](http://www.slideshare.net/anantshri/career-in-information-security)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
class LimitedOEmbedExtensionTestCase(OEmbedExtensionTestCase):
def setUp(self):
self.markdown = markdown.Markdown(
extensions=['oembed'],
extension_configs={
'oembed': {
'allowed_endpoints': [endpoints.YOUTUBE],
}
})
def test_youtube_link(self):
"""
YouTube video link.
"""
text = '![video](http://www.youtube.com/watch?v=7XzdZ4KcI8Y)'
output = self.markdown.convert(text)
self.assertIn('<iframe', output)
def test_vimeo_link(self):
"""
Vimeo video link.
"""
text = '![link](http://vimeo.com/52970271)'
output = self.markdown.convert(text)
self.assertNotIn('<iframe', output)
if __name__ == "__main__":
unittest.main()