Skip to content

Commit

Permalink
Merge pull request #7 from bneijt/issue-5
Browse files Browse the repository at this point in the history
Issue 5
  • Loading branch information
bneijt authored Apr 3, 2022
2 parents 52eab1c + 264e0a3 commit dccb8e6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 19 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
SOURCES=$(shell find . -name '*.py')
OUTPUT_PATH=build/plugin.video.ipfs

MY_VAR := $(shell echo whatever)

clean:
rm -rf build
rm -rf dist
Expand All @@ -11,8 +13,7 @@ build/plugin_video_ipfs.zip: build
cd build && zip -r plugin_video_ipfs.zip plugin.video.ipfs

build: $(SOURCES) fanart.jpg icon.png addon.xml resources/settings.xml
VERSION=$(poetry version --short)
sed -i 's/id="plugin.video.ipfs" version="[^"]*"/id="plugin.video.ipfs" version="'${VERSION}'"/' addon.xml
sed -i 's/id="plugin.video.ipfs" version="[^"]*"/id="plugin.video.ipfs" version="'$(shell poetry version --short)'"/' addon.xml
poetry build
mkdir -p $(OUTPUT_PATH)/ipfs
tar -xzf dist/ipfs-video-kodi-*.tar.gz -C dist --wildcards '*/ipfs_video_kodi'
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ The main branch in github is _not_ installable as a kodi package, please use the
# Viewing your own content

- Install IPFS on your media player
- Use `ipfs add -r -w yourdirectory` to insert your directory
- Use `ipfs add -r -w yourdirectory` to insert your directory, remember the resulting CID
- Configure plugin to have gateway point to `http://localhost:8080`
- Use the hash of the directory as the root CID in the plugin configuration
- Enter the CID of the directory as the root CID in the plugin configuration
- Optionally:
- Use `ipfs name publish <cid>` to create an [IPNS](https://docs.ipfs.io/concepts/ipns/#example-ipns-setup-with-cli) record
- Enter `ipfs/<resulting ipns url>` as the root CID in the plugin configuration

# Develop

- `make venv`
- `make test`
- `make build`
- Create venv for development: `poetry install`
- Run the tests: `poetry run pytest`
- Build a release package: `make build`

# License information

Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.video.ipfs" version="0.0.1" name="IPFS" provider-name="ipfs.video">
<addon id="plugin.video.ipfs" version="0.0.7" name="IPFS" provider-name="ipfs.video">
<requires>
<import addon="xbmc.python" version="3.0.0" />
<import addon="script.module.requests" version="2.22.0" />
Expand Down
39 changes: 29 additions & 10 deletions ipfs_video_kodi/ipfs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import random

import requests

MAX_CACHE_SIZE = 100


def via(gateway):
return IPFS(gateway)
Expand All @@ -17,7 +18,8 @@ def __init__(self, gateway):
self._gateway = gateway
self._cache = {}

def get_links(self, path, params):
def get_links(self, cid):
params = {"arg": cid}
url = self._gateway + "/api/v0/dag/get"
r = requests.get(url, params=params, timeout=20)
r.raise_for_status()
Expand All @@ -36,18 +38,35 @@ def get_links(self, path, params):
i["hash"] = i["cid"]
return link_list

def list(self, hash):
"""Get the directory content of the given hash"""
assert type(hash) == str
if hash in self._cache:
if len(self._cache) > 50:
def resolve_ipns(self, cid):
params = {"arg": cid}
url = self._gateway + "/api/v0/name/resolve"
print(params)
r = requests.get(url, params=params, timeout=20)
r.raise_for_status()
rjson = r.json()
path = rjson.get("Path") or rjson.get("path")
assert path.startswith("/ipfs/"), "Should resolve to ipfs path"
return path[len("/ipfs/") :]

def list(self, path):
"""Get the directory content of the given path (ipns/hash or plain cid)"""
assert type(path) == str, "Argument path must be a string"
cid = (
self.resolve_ipns(path[len("/ipns/") :])
if path.startswith("/ipns/")
else path
)

if cid in self._cache:
if len(self._cache) > MAX_CACHE_SIZE:
# Drop 10 keys
for k in random.sample(self._cache.keys(), 10):
del self._cache[k]
return self._cache[hash]
return self._cache[cid]

entries = self.get_links("/api/v0/dag/get", params={"arg": hash})
self._cache[hash] = entries
entries = self.get_links(cid)
self._cache[cid] = entries
return entries

def link(self, hash):
Expand Down
9 changes: 8 additions & 1 deletion tests/test_ipfs.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# -*- coding: utf-8 -*-
import pytest

import ipfs_video_kodi.ipfs as ipfs

test_gateway = ipfs.via("https://ipfs.io")


@pytest.mark.skip(reason="ipns link is not maintained")
def test_list_ipns_should_work():
a = test_gateway.list(
"/ipns/k51qzi5uqu5dhlmx2xfqsn7f94tq2gp1inr9yu7cm8dsmycdwk2xp6aykqzf5i"
)
assert len(a) == 3


def test_list_directory_should_work():
a = test_gateway.list("Qme4QjkyZQuFtN2SDhELfXVshMyAEec53jaFQ8kR4maLeV")
assert len(a) == 1
Expand Down

0 comments on commit dccb8e6

Please # to comment.