2022-12-17 14:39:42 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
import os
|
2023-05-29 01:12:26 +00:00
|
|
|
import time
|
2022-12-17 14:39:42 +00:00
|
|
|
import json
|
2023-05-22 09:10:51 +00:00
|
|
|
import logging
|
2023-05-28 00:38:04 +00:00
|
|
|
import random
|
2022-12-17 14:39:42 +00:00
|
|
|
|
|
|
|
from typing import Optional
|
2023-05-28 21:23:51 +00:00
|
|
|
from datetime import datetime, timedelta
|
2022-12-17 14:39:42 +00:00
|
|
|
from functools import partial
|
|
|
|
|
|
|
|
import trio
|
|
|
|
import click
|
2023-05-22 09:10:51 +00:00
|
|
|
import docker
|
|
|
|
import asyncio
|
2023-05-27 20:50:47 +00:00
|
|
|
import requests
|
2023-05-22 09:10:51 +00:00
|
|
|
|
|
|
|
from leap.cleos import CLEOS, default_nodeos_image
|
2023-05-27 20:50:47 +00:00
|
|
|
from leap.sugar import get_container, collect_stdout
|
2023-05-28 21:23:51 +00:00
|
|
|
from leap.hyperion import HyperionAPI
|
2022-12-24 13:54:33 +00:00
|
|
|
|
2023-05-22 09:10:51 +00:00
|
|
|
from .db import open_new_database
|
2023-05-28 21:23:51 +00:00
|
|
|
from .ipfs import IPFSDocker
|
2023-01-22 15:12:33 +00:00
|
|
|
from .config import *
|
2023-05-27 20:50:47 +00:00
|
|
|
from .nodeos import open_cleos, open_nodeos
|
2023-05-22 09:10:51 +00:00
|
|
|
from .constants import ALGOS
|
2022-12-19 15:36:02 +00:00
|
|
|
from .frontend.telegram import run_skynet_telegram
|
2022-12-17 14:39:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
@click.group()
|
|
|
|
def skynet(*args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
2022-12-19 15:36:02 +00:00
|
|
|
|
|
|
|
@click.command()
|
|
|
|
@click.option('--model', '-m', default='midj')
|
2022-12-17 14:39:42 +00:00
|
|
|
@click.option(
|
2022-12-19 15:36:02 +00:00
|
|
|
'--prompt', '-p', default='a red old tractor in a sunny wheat field')
|
2022-12-17 14:39:42 +00:00
|
|
|
@click.option('--output', '-o', default='output.png')
|
|
|
|
@click.option('--width', '-w', default=512)
|
|
|
|
@click.option('--height', '-h', default=512)
|
|
|
|
@click.option('--guidance', '-g', default=10.0)
|
|
|
|
@click.option('--steps', '-s', default=26)
|
|
|
|
@click.option('--seed', '-S', default=None)
|
2022-12-19 15:36:02 +00:00
|
|
|
def txt2img(*args, **kwargs):
|
2023-05-27 20:50:47 +00:00
|
|
|
from . import utils
|
2023-01-22 15:12:33 +00:00
|
|
|
_, hf_token, _, cfg = init_env_from_config()
|
|
|
|
utils.txt2img(hf_token, **kwargs)
|
2022-12-19 15:36:02 +00:00
|
|
|
|
2023-01-16 02:42:45 +00:00
|
|
|
@click.command()
|
|
|
|
@click.option('--model', '-m', default='midj')
|
|
|
|
@click.option(
|
|
|
|
'--prompt', '-p', default='a red old tractor in a sunny wheat field')
|
|
|
|
@click.option('--input', '-i', default='input.png')
|
|
|
|
@click.option('--output', '-o', default='output.png')
|
2023-01-17 22:01:31 +00:00
|
|
|
@click.option('--strength', '-Z', default=1.0)
|
2023-01-16 02:42:45 +00:00
|
|
|
@click.option('--guidance', '-g', default=10.0)
|
|
|
|
@click.option('--steps', '-s', default=26)
|
|
|
|
@click.option('--seed', '-S', default=None)
|
2023-01-17 22:01:31 +00:00
|
|
|
def img2img(model, prompt, input, output, strength, guidance, steps, seed):
|
2023-05-27 20:50:47 +00:00
|
|
|
from . import utils
|
2023-01-22 15:12:33 +00:00
|
|
|
_, hf_token, _, cfg = init_env_from_config()
|
2023-01-16 02:42:45 +00:00
|
|
|
utils.img2img(
|
2023-01-22 15:12:33 +00:00
|
|
|
hf_token,
|
2023-01-16 02:42:45 +00:00
|
|
|
model=model,
|
|
|
|
prompt=prompt,
|
|
|
|
img_path=input,
|
|
|
|
output=output,
|
2023-01-17 22:01:31 +00:00
|
|
|
strength=strength,
|
2023-01-16 02:42:45 +00:00
|
|
|
guidance=guidance,
|
|
|
|
steps=steps,
|
|
|
|
seed=seed
|
|
|
|
)
|
|
|
|
|
2022-12-19 15:36:02 +00:00
|
|
|
@click.command()
|
|
|
|
@click.option('--input', '-i', default='input.png')
|
|
|
|
@click.option('--output', '-o', default='output.png')
|
2022-12-24 13:39:40 +00:00
|
|
|
@click.option('--model', '-m', default='weights/RealESRGAN_x4plus.pth')
|
|
|
|
def upscale(input, output, model):
|
2023-05-27 20:50:47 +00:00
|
|
|
from . import utils
|
2022-12-19 15:36:02 +00:00
|
|
|
utils.upscale(
|
|
|
|
img_path=input,
|
|
|
|
output=output,
|
2022-12-24 13:39:40 +00:00
|
|
|
model_path=model)
|
2022-12-19 15:36:02 +00:00
|
|
|
|
2022-12-17 14:39:42 +00:00
|
|
|
|
2023-03-20 13:58:35 +00:00
|
|
|
@skynet.command()
|
|
|
|
def download():
|
2023-05-27 20:50:47 +00:00
|
|
|
from . import utils
|
2023-03-20 13:58:35 +00:00
|
|
|
_, hf_token, _, cfg = init_env_from_config()
|
|
|
|
utils.download_all_models(hf_token)
|
|
|
|
|
2023-05-27 20:50:47 +00:00
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
2023-05-28 00:38:04 +00:00
|
|
|
'--account', '-A', default=None)
|
2023-05-27 20:50:47 +00:00
|
|
|
@click.option(
|
2023-05-28 21:23:51 +00:00
|
|
|
'--permission', '-P', default=None)
|
2023-05-27 20:50:47 +00:00
|
|
|
@click.option(
|
|
|
|
'--key', '-k', default=None)
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
2023-05-28 00:38:04 +00:00
|
|
|
@click.option(
|
|
|
|
'--reward', '-r', default='20.0000 GPU')
|
2023-05-27 20:50:47 +00:00
|
|
|
@click.option('--algo', '-a', default='midj')
|
|
|
|
@click.option(
|
|
|
|
'--prompt', '-p', default='a red old tractor in a sunny wheat field')
|
|
|
|
@click.option('--output', '-o', default='output.png')
|
|
|
|
@click.option('--width', '-w', default=512)
|
|
|
|
@click.option('--height', '-h', default=512)
|
|
|
|
@click.option('--guidance', '-g', default=10)
|
|
|
|
@click.option('--step', '-s', default=26)
|
2023-05-28 00:38:04 +00:00
|
|
|
@click.option('--seed', '-S', default=None)
|
2023-05-27 20:50:47 +00:00
|
|
|
@click.option('--upscaler', '-U', default='x4')
|
|
|
|
def enqueue(
|
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
2023-05-28 00:38:04 +00:00
|
|
|
reward: str,
|
2023-05-27 20:50:47 +00:00
|
|
|
**kwargs
|
|
|
|
):
|
2023-05-28 00:38:04 +00:00
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
2023-05-27 20:50:47 +00:00
|
|
|
with open_cleos(node_url, key=key) as cleos:
|
2023-05-28 00:38:04 +00:00
|
|
|
if not kwargs['seed']:
|
|
|
|
kwargs['seed'] = random.randint(0, 10e9)
|
|
|
|
|
2023-05-27 20:50:47 +00:00
|
|
|
req = json.dumps({
|
|
|
|
'method': 'diffuse',
|
|
|
|
'params': kwargs
|
|
|
|
})
|
|
|
|
binary = ''
|
|
|
|
|
|
|
|
ec, out = cleos.push_action(
|
2023-05-28 00:38:04 +00:00
|
|
|
'telos.gpu', 'enqueue', [account, req, binary, reward], f'{account}@{permission}'
|
2023-05-27 20:50:47 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
print(collect_stdout(out))
|
2023-05-28 00:38:04 +00:00
|
|
|
assert ec == 0
|
2023-05-27 20:50:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
|
|
|
def queue(node_url: str):
|
|
|
|
resp = requests.post(
|
|
|
|
f'{node_url}/v1/chain/get_table_rows',
|
|
|
|
json={
|
|
|
|
'code': 'telos.gpu',
|
|
|
|
'table': 'queue',
|
|
|
|
'scope': 'telos.gpu',
|
|
|
|
'json': True
|
|
|
|
}
|
|
|
|
)
|
|
|
|
print(json.dumps(resp.json(), indent=4))
|
|
|
|
|
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
|
|
|
@click.argument('request-id')
|
|
|
|
def status(node_url: str, request_id: int):
|
|
|
|
resp = requests.post(
|
|
|
|
f'{node_url}/v1/chain/get_table_rows',
|
|
|
|
json={
|
|
|
|
'code': 'telos.gpu',
|
|
|
|
'table': 'status',
|
|
|
|
'scope': request_id,
|
|
|
|
'json': True
|
|
|
|
}
|
|
|
|
)
|
|
|
|
print(json.dumps(resp.json(), indent=4))
|
|
|
|
|
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
|
|
|
'--account', '-a', default='telegram1')
|
|
|
|
@click.option(
|
|
|
|
'--permission', '-p', default='active')
|
|
|
|
@click.option(
|
|
|
|
'--key', '-k', default=None)
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
|
|
|
@click.argument('request-id')
|
|
|
|
def dequeue(
|
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
|
|
|
request_id: int
|
|
|
|
):
|
2023-05-28 00:38:04 +00:00
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
2023-05-27 20:50:47 +00:00
|
|
|
with open_cleos(node_url, key=key) as cleos:
|
|
|
|
ec, out = cleos.push_action(
|
|
|
|
'telos.gpu', 'dequeue', [account, request_id], f'{account}@{permission}'
|
|
|
|
)
|
2023-05-28 00:38:04 +00:00
|
|
|
|
|
|
|
print(collect_stdout(out))
|
|
|
|
assert ec == 0
|
|
|
|
|
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
|
|
|
'--account', '-a', default='telegram1')
|
|
|
|
@click.option(
|
|
|
|
'--permission', '-p', default='active')
|
|
|
|
@click.option(
|
|
|
|
'--key', '-k', default=None)
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
|
|
|
@click.option(
|
|
|
|
'--verifications', '-v', default=1)
|
|
|
|
@click.option(
|
|
|
|
'--token-contract', '-c', default='eosio.token')
|
|
|
|
@click.option(
|
|
|
|
'--token-symbol', '-S', default='4,GPU')
|
|
|
|
def config(
|
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
|
|
|
verifications: int,
|
|
|
|
token_contract: str,
|
|
|
|
token_symbol: str
|
|
|
|
):
|
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
|
|
|
with open_cleos(node_url, key=key) as cleos:
|
|
|
|
ec, out = cleos.push_action(
|
|
|
|
'telos.gpu', 'config', [verifications, token_contract, token_symbol], f'{account}@{permission}'
|
|
|
|
)
|
|
|
|
|
|
|
|
print(collect_stdout(out))
|
|
|
|
assert ec == 0
|
|
|
|
|
|
|
|
@skynet.command()
|
|
|
|
@click.option(
|
|
|
|
'--account', '-a', default='telegram1')
|
|
|
|
@click.option(
|
|
|
|
'--permission', '-p', default='active')
|
|
|
|
@click.option(
|
|
|
|
'--key', '-k', default=None)
|
|
|
|
@click.option(
|
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
|
|
|
@click.argument('quantity')
|
|
|
|
def deposit(
|
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
|
|
|
quantity: str
|
|
|
|
):
|
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
|
|
|
with open_cleos(node_url, key=key) as cleos:
|
|
|
|
ec, out = cleos.transfer_token(account, 'telos.gpu', quantity)
|
|
|
|
|
|
|
|
print(collect_stdout(out))
|
2023-05-27 20:50:47 +00:00
|
|
|
assert ec == 0
|
2023-03-20 13:58:35 +00:00
|
|
|
|
2022-12-17 14:39:42 +00:00
|
|
|
@skynet.group()
|
|
|
|
def run(*args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
2022-12-19 15:36:02 +00:00
|
|
|
@run.command()
|
2023-05-22 09:10:51 +00:00
|
|
|
def db():
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
with open_new_database(cleanup=False) as db_params:
|
|
|
|
container, passwd, host = db_params
|
|
|
|
logging.info(('skynet', passwd, host))
|
2022-12-19 15:36:02 +00:00
|
|
|
|
2023-05-22 09:10:51 +00:00
|
|
|
@run.command()
|
|
|
|
def nodeos():
|
2023-05-28 21:23:51 +00:00
|
|
|
logging.basicConfig(filename='skynet-nodeos.log', level=logging.INFO)
|
2023-05-22 09:10:51 +00:00
|
|
|
with open_nodeos(cleanup=False):
|
|
|
|
...
|
2022-12-19 15:36:02 +00:00
|
|
|
|
2022-12-17 14:39:42 +00:00
|
|
|
@run.command()
|
|
|
|
@click.option('--loglevel', '-l', default='warning', help='Logging level')
|
2022-12-19 15:36:02 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--account', '-a', default='testworker1')
|
2022-12-17 14:39:42 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--permission', '-p', default='active')
|
2022-12-17 14:39:42 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--key', '-k', default=None)
|
2022-12-24 14:10:49 +00:00
|
|
|
@click.option(
|
2023-05-27 20:50:47 +00:00
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
2023-05-28 21:23:51 +00:00
|
|
|
@click.option(
|
|
|
|
'--ipfs-url', '-n', default='/ip4/169.197.142.4/tcp/4001/p2p/12D3KooWKHKPFuqJPeqYgtUJtfZTHvEArRX2qvThYBrjuTuPg2Nx')
|
2022-12-24 14:10:49 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--algos', '-A', default=json.dumps(['midj']))
|
2022-12-17 14:39:42 +00:00
|
|
|
def dgpu(
|
|
|
|
loglevel: str,
|
2023-05-22 09:10:51 +00:00
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
2023-05-28 21:23:51 +00:00
|
|
|
ipfs_url: str,
|
2023-05-22 09:10:51 +00:00
|
|
|
algos: list[str]
|
2022-12-17 14:39:42 +00:00
|
|
|
):
|
2023-05-27 20:50:47 +00:00
|
|
|
from .dgpu import open_dgpu_node
|
2023-05-28 00:38:04 +00:00
|
|
|
|
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
|
|
|
|
2023-05-27 20:50:47 +00:00
|
|
|
vtestnet = None
|
|
|
|
try:
|
|
|
|
dclient = docker.from_env()
|
|
|
|
vtestnet = get_container(
|
|
|
|
dclient,
|
|
|
|
default_nodeos_image(),
|
|
|
|
force_unique=True,
|
|
|
|
detach=True,
|
|
|
|
network='host',
|
|
|
|
remove=True)
|
|
|
|
|
|
|
|
cleos = CLEOS(dclient, vtestnet, url=node_url, remote=node_url)
|
|
|
|
|
|
|
|
trio.run(
|
|
|
|
partial(
|
|
|
|
open_dgpu_node,
|
|
|
|
account, permission,
|
2023-05-28 21:23:51 +00:00
|
|
|
cleos,
|
|
|
|
ipfs_url,
|
|
|
|
key=key, initial_algos=json.loads(algos)
|
2023-05-27 20:50:47 +00:00
|
|
|
))
|
2022-12-19 15:36:02 +00:00
|
|
|
|
2023-05-27 20:50:47 +00:00
|
|
|
finally:
|
|
|
|
if vtestnet:
|
|
|
|
vtestnet.stop()
|
2023-05-22 09:10:51 +00:00
|
|
|
|
2022-12-19 15:36:02 +00:00
|
|
|
|
|
|
|
@run.command()
|
2023-05-28 23:17:55 +00:00
|
|
|
@click.option('--loglevel', '-l', default='INFO', help='logging level')
|
2023-05-22 09:10:51 +00:00
|
|
|
@click.option(
|
2023-05-28 21:23:51 +00:00
|
|
|
'--account', '-a', default='telegram')
|
2022-12-19 15:36:02 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--permission', '-p', default='active')
|
2022-12-19 15:36:02 +00:00
|
|
|
@click.option(
|
2023-05-22 09:10:51 +00:00
|
|
|
'--key', '-k', default=None)
|
2023-05-28 21:23:51 +00:00
|
|
|
@click.option(
|
|
|
|
'--hyperion-url', '-n', default='http://test1.us.telos.net:42001')
|
2022-12-24 14:10:49 +00:00
|
|
|
@click.option(
|
2023-05-27 20:50:47 +00:00
|
|
|
'--node-url', '-n', default='http://skynet.ancap.tech')
|
2023-05-22 09:10:51 +00:00
|
|
|
@click.option(
|
|
|
|
'--db-host', '-h', default='localhost:5432')
|
|
|
|
@click.option(
|
|
|
|
'--db-user', '-u', default='skynet')
|
|
|
|
@click.option(
|
|
|
|
'--db-pass', '-u', default='password')
|
2022-12-19 15:36:02 +00:00
|
|
|
def telegram(
|
|
|
|
loglevel: str,
|
2023-05-22 09:10:51 +00:00
|
|
|
account: str,
|
|
|
|
permission: str,
|
|
|
|
key: str | None,
|
|
|
|
node_url: str,
|
2023-05-28 21:23:51 +00:00
|
|
|
hyperion_url: str,
|
2023-05-22 09:10:51 +00:00
|
|
|
db_host: str,
|
|
|
|
db_user: str,
|
|
|
|
db_pass: str
|
2022-12-19 15:36:02 +00:00
|
|
|
):
|
2023-05-28 23:17:55 +00:00
|
|
|
logging.basicConfig(level=loglevel)
|
2023-05-28 00:38:04 +00:00
|
|
|
|
|
|
|
key, account, permission = load_account_info(
|
|
|
|
key, account, permission)
|
|
|
|
|
2023-01-22 15:12:33 +00:00
|
|
|
_, _, tg_token, cfg = init_env_from_config()
|
2023-05-22 09:10:51 +00:00
|
|
|
asyncio.run(
|
|
|
|
run_skynet_telegram(
|
2023-01-22 15:12:33 +00:00
|
|
|
tg_token,
|
2023-05-22 09:10:51 +00:00
|
|
|
account,
|
|
|
|
permission,
|
|
|
|
node_url,
|
2023-05-28 21:23:51 +00:00
|
|
|
hyperion_url,
|
2023-05-22 09:10:51 +00:00
|
|
|
db_host, db_user, db_pass,
|
|
|
|
key=key
|
2022-12-19 15:36:02 +00:00
|
|
|
))
|
2023-05-28 21:23:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
@run.command()
|
2023-05-29 01:12:26 +00:00
|
|
|
@click.option('--loglevel', '-l', default='INFO', help='logging level')
|
2023-05-28 21:23:51 +00:00
|
|
|
@click.option(
|
|
|
|
'--container', '-c', default='ipfs_host')
|
|
|
|
@click.option(
|
|
|
|
'--hyperion-url', '-n', default='http://127.0.0.1:42001')
|
2023-05-29 01:12:26 +00:00
|
|
|
def pinner(loglevel, container, hyperion_url):
|
|
|
|
logging.basicConfig(level=loglevel)
|
2023-05-28 21:23:51 +00:00
|
|
|
dclient = docker.from_env()
|
|
|
|
|
2023-05-29 01:12:26 +00:00
|
|
|
container = dclient.containers.get(container)
|
2023-05-28 21:23:51 +00:00
|
|
|
ipfs_node = IPFSDocker(container)
|
2023-05-29 01:12:26 +00:00
|
|
|
hyperion = HyperionAPI(hyperion_url)
|
2023-05-28 21:23:51 +00:00
|
|
|
|
|
|
|
last_pinned: dict[str, datetime] = {}
|
|
|
|
|
|
|
|
def cleanup_pinned(now: datetime):
|
2023-05-29 01:12:26 +00:00
|
|
|
for cid in set(last_pinned.keys()):
|
2023-05-28 21:23:51 +00:00
|
|
|
ts = last_pinned[cid]
|
|
|
|
if now - ts > timedelta(minutes=1):
|
|
|
|
del last_pinned[cid]
|
|
|
|
|
|
|
|
try:
|
|
|
|
while True:
|
|
|
|
# get all submits in the last minute
|
2023-05-29 01:12:26 +00:00
|
|
|
now = datetime.now()
|
2023-05-28 21:23:51 +00:00
|
|
|
half_min_ago = now - timedelta(seconds=30)
|
|
|
|
submits = hyperion.get_actions(
|
|
|
|
account='telos.gpu',
|
|
|
|
filter='telos.gpu:submit',
|
|
|
|
sort='desc',
|
|
|
|
after=half_min_ago.isoformat()
|
|
|
|
)
|
|
|
|
|
|
|
|
# filter for the ones not already pinned
|
|
|
|
actions = [
|
|
|
|
action
|
|
|
|
for action in submits['actions']
|
|
|
|
if action['act']['data']['ipfs_hash']
|
|
|
|
not in last_pinned
|
|
|
|
]
|
|
|
|
|
|
|
|
# pin and remember
|
|
|
|
for action in actions:
|
|
|
|
cid = action['act']['data']['ipfs_hash']
|
|
|
|
last_pinned[cid] = now
|
|
|
|
|
|
|
|
ipfs_node.pin(cid)
|
|
|
|
|
2023-05-29 01:12:26 +00:00
|
|
|
logging.info(f'pinned {cid}')
|
|
|
|
|
2023-05-28 21:23:51 +00:00
|
|
|
cleanup_pinned(now)
|
2023-05-28 23:17:55 +00:00
|
|
|
|
2023-05-29 01:12:26 +00:00
|
|
|
time.sleep(1)
|
|
|
|
|
2023-05-28 23:17:55 +00:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
...
|