-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fa97f7d
Showing
8 changed files
with
302 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
name: Publish Python Package | ||
|
||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- uses: actions/cache@v2 | ||
name: Configure pip caching | ||
with: | ||
path: ~/.cache/pip | ||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} | ||
restore-keys: | | ||
${{ runner.os }}-pip- | ||
- name: Install dependencies | ||
run: | | ||
pip install -e '.[test]' | ||
- name: Run tests | ||
run: | | ||
pytest | ||
deploy: | ||
runs-on: ubuntu-latest | ||
needs: [test] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: "3.10" | ||
- uses: actions/cache@v2 | ||
name: Configure pip caching | ||
with: | ||
path: ~/.cache/pip | ||
key: ${{ runner.os }}-publish-pip-${{ hashFiles('**/setup.py') }} | ||
restore-keys: | | ||
${{ runner.os }}-publish-pip- | ||
- name: Install dependencies | ||
run: | | ||
pip install setuptools wheel twine build | ||
- name: Publish | ||
env: | ||
TWINE_USERNAME: __token__ | ||
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} | ||
run: | | ||
python -m build | ||
twine upload dist/* | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: Test | ||
|
||
on: [push] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- uses: actions/cache@v2 | ||
name: Configure pip caching | ||
with: | ||
path: ~/.cache/pip | ||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} | ||
restore-keys: | | ||
${{ runner.os }}-pip- | ||
- name: Install dependencies | ||
run: | | ||
pip install -e '.[test]' | ||
- name: Run tests | ||
run: | | ||
pytest | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.venv | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
venv | ||
.eggs | ||
.pytest_cache | ||
*.egg-info | ||
.DS_Store | ||
.vscode | ||
dist | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# datasette-hovercards | ||
|
||
[![PyPI](https://img.shields.io/pypi/v/datasette-hovercards.svg)](https://pypi.org/project/datasette-hovercards/) | ||
[![Changelog](https://img.shields.io/github/v/release/simonw/datasette-hovercards?include_prereleases&label=changelog)](https://github.com/simonw/datasette-hovercards/releases) | ||
[![Tests](https://github.com/simonw/datasette-hovercards/workflows/Test/badge.svg)](https://github.com/simonw/datasette-hovercards/actions?query=workflow%3ATest) | ||
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/simonw/datasette-hovercards/blob/main/LICENSE) | ||
|
||
Add preview hovercards to links in Datasette | ||
|
||
## Installation | ||
|
||
Install this plugin in the same environment as Datasette. | ||
|
||
$ datasette install datasette-hovercards | ||
|
||
## Usage | ||
|
||
Usage instructions go here. | ||
|
||
## Development | ||
|
||
To set up this plugin locally, first checkout the code. Then create a new virtual environment: | ||
|
||
cd datasette-hovercards | ||
python3 -mvenv venv | ||
source venv/bin/activate | ||
|
||
Or if you are using `pipenv`: | ||
|
||
pipenv shell | ||
|
||
Now install the dependencies and test dependencies: | ||
|
||
pip install -e '.[test]' | ||
|
||
To run the tests: | ||
|
||
pytest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from datasette import hookimpl | ||
|
||
|
||
@hookimpl | ||
def extra_js_urls(datasette, table): | ||
if table: | ||
return [ | ||
datasette.urls.static_plugins( | ||
"datasette-hovercards", "datasette-hovercards.js" | ||
) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
let hovercardOuterAnimation = null; | ||
let hovercardInnerAnimation = null; | ||
let hovercard = document.createElement("div"); | ||
hovercard.setAttribute("id", "datasette-hovercard") | ||
hovercard.style.width = '300px'; | ||
hovercard.style.height = '200px'; | ||
hovercard.style.overflow = 'auto'; | ||
hovercard.style.backgroundColor = 'white'; | ||
hovercard.style.border = '1px solid #ccc'; | ||
hovercard.style.padding = '10px'; | ||
hovercard.style.position = 'absolute'; | ||
hovercard.style.display = 'none'; | ||
hovercard.style.boxShadow = '1px 2px 8px 2px rgba(0,0,0,0.08)'; | ||
|
||
const hovercardEscape = (s) => { | ||
return (s || "").toString() | ||
.replace(/&/g, "&") | ||
.replace(/</g, "<") | ||
.replace(/>/g, ">") | ||
.replace(/"/g, """) | ||
.replace(/'/g, "'"); | ||
}; | ||
|
||
document.addEventListener("mouseover", async (ev) => { | ||
const a = ev.target; | ||
if (a.nodeName != 'A') { | ||
return; | ||
} | ||
// TODO: Respect base_url and suchlike | ||
if (a.pathname.split("/").length != 4) { | ||
return; // Definitely not a row | ||
} | ||
// OK, it might be a row! Try a fetch | ||
let row; | ||
if (a.hovercardRowData) { | ||
row = a.hovercardRowData; | ||
} else { | ||
const response = await fetch(a.pathname + ".json?_shape=array"); | ||
if (response.status == 200) { | ||
const data = await response.json(); | ||
row = data[0]; | ||
a.hovercardRowData = row; | ||
} | ||
} | ||
if (row) { | ||
// Cancel any existing animations | ||
if (hovercardOuterAnimation) { | ||
clearTimeout(hovercardOuterAnimation); | ||
} | ||
if (hovercardInnerAnimation) { | ||
clearTimeout(hovercardInnerAnimation); | ||
} | ||
hovercard.style.top = (ev.pageY + 5) + 'px'; | ||
hovercard.style.left = (ev.pageX - 15) + 'px'; | ||
let html = ['<dl>']; | ||
for (const [key, value] of Object.entries(row)) { | ||
html.push(` | ||
<dt style="font-weight: bold">${hovercardEscape(key)}</dt> | ||
<dd style="margin: 0px 0 0 0.7em;"> | ||
<span style="color: #999; font-size: 0.9em;">${hovercardEscape(value) || ' '}</span> | ||
</dd> | ||
`); | ||
} | ||
html.push("</dl>") | ||
hovercard.innerHTML = html.join(""); | ||
hovercard.style.display = 'block'; | ||
hovercard.style.opacity = 100; | ||
hovercard.style.transition = 'none'; | ||
} | ||
}); | ||
|
||
document.addEventListener("mouseout", (ev) => { | ||
if (ev.target.id != "datasette-hovercard") { | ||
return; | ||
} | ||
hovercardOuterAnimation = setTimeout(() => { | ||
hovercard.style.transition = 'opacity 0.4s ease-in-out'; | ||
hovercard.style.opacity = 0; | ||
hovercardInnerAnimation = setTimeout(() => { | ||
hovercard.style.transition = 'none'; | ||
hovercard.style.display = "none"; | ||
hovercard.style.opacity = 100; | ||
}, 800) | ||
}, 400); | ||
}) | ||
|
||
document.addEventListener("DOMContentLoaded", () => { | ||
document.body.appendChild(hovercard); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from setuptools import setup | ||
import os | ||
|
||
VERSION = "0.1" | ||
|
||
|
||
def get_long_description(): | ||
with open( | ||
os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"), | ||
encoding="utf8", | ||
) as fp: | ||
return fp.read() | ||
|
||
|
||
setup( | ||
name="datasette-hovercards", | ||
description="Add preview hovercards to links in Datasette", | ||
long_description=get_long_description(), | ||
long_description_content_type="text/markdown", | ||
author="Simon Willison", | ||
url="https://github.com/simonw/datasette-hovercards", | ||
project_urls={ | ||
"Issues": "https://github.com/simonw/datasette-hovercards/issues", | ||
"CI": "https://github.com/simonw/datasette-hovercards/actions", | ||
"Changelog": "https://github.com/simonw/datasette-hovercards/releases", | ||
}, | ||
license="Apache License, Version 2.0", | ||
classifiers=[ | ||
"Framework :: Datasette", | ||
"License :: OSI Approved :: Apache Software License", | ||
], | ||
version=VERSION, | ||
packages=["datasette_hovercards"], | ||
entry_points={"datasette": ["hovercards = datasette_hovercards"]}, | ||
install_requires=["datasette"], | ||
extras_require={"test": ["pytest", "pytest-asyncio"]}, | ||
package_data={"datasette_hovercards": ["static/*"]}, | ||
python_requires=">=3.6", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from datasette.app import Datasette | ||
import pytest | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_static_asset(): | ||
datasette = Datasette([], memory=True) | ||
response = await datasette.client.get( | ||
"/-/static-plugins/datasette-hovercards/datasette-hovercards.js" | ||
) | ||
assert response.status_code == 200 | ||
|
||
|
||
@pytest.mark.asyncio | ||
@pytest.mark.parametrize("path,expected", (("/db/t", True), ("/db", False))) | ||
async def test_included_on_table_page(path, expected): | ||
datasette = Datasette([], memory=True) | ||
db = datasette.add_memory_database("db") | ||
if not await db.table_exists("t"): | ||
await db.execute_write("create table t (id integer primary key)", block=True) | ||
response = await datasette.client.get(path) | ||
if expected: | ||
assert "datasette-hovercards.js" in response.text | ||
else: | ||
assert "datasette-hovercards.js" not in response.text |