mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-13 12:33:25 +02:00
Download squeaks with custom params (#1108)
* Add rpc method for subscribe squeak entry * Download squeak without reloading page using squeak entry subscription * Fix stream termination of component unmount for subscribe squeak entry * Update frontend build
This commit is contained in:
parent
c38b177340
commit
a0d78844da
17 changed files with 147 additions and 41 deletions
|
|
@ -86,7 +86,9 @@ export default function SqueakDetailItem({
|
|||
event.preventDefault();
|
||||
console.log('Handling download click...');
|
||||
downloadSqueakRequest(hash, (response) => {
|
||||
reloadSqueak();
|
||||
// TODO: Nothing for now. This will eventually show something
|
||||
// when downloadSqueakRequest becomes a streaming method.
|
||||
// reloadSqueak();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import SqueakReplies from '../../components/SqueakReplies';
|
|||
|
||||
import {
|
||||
getSqueakDisplayRequest,
|
||||
subscribeSqueakDisplayRequest,
|
||||
getAncestorSqueakDisplaysRequest,
|
||||
getReplySqueakDisplaysRequest,
|
||||
getNetworkRequest,
|
||||
|
|
@ -44,6 +45,9 @@ export default function SqueakPage() {
|
|||
const getSqueak = (hash) => {
|
||||
getSqueakDisplayRequest(hash, setSqueak);
|
||||
};
|
||||
const subscribeSqueak = (hash) => {
|
||||
return subscribeSqueakDisplayRequest(hash, setSqueak);
|
||||
};
|
||||
const getAncestorSqueaks = (hash) => {
|
||||
getAncestorSqueakDisplaysRequest(hash, setAncestorSqueaks);
|
||||
};
|
||||
|
|
@ -69,6 +73,10 @@ export default function SqueakPage() {
|
|||
useEffect(() => {
|
||||
getSqueak(hash);
|
||||
}, [hash]);
|
||||
useEffect(() => {
|
||||
const stream = subscribeSqueak(hash);
|
||||
return () => stream.cancel();
|
||||
}, [hash]);
|
||||
useEffect(() => {
|
||||
getAncestorSqueaks(hash);
|
||||
}, [hash]);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import {
|
|||
GetContactProfilesRequest,
|
||||
MakeSqueakRequest,
|
||||
GetSqueakDisplayRequest,
|
||||
SubscribeSqueakDisplayRequest,
|
||||
GetAncestorSqueakDisplaysRequest,
|
||||
GetReplySqueakDisplaysRequest,
|
||||
GetSqueakProfileByAddressRequest,
|
||||
|
|
@ -625,3 +626,20 @@ export function subscribeBuyOffersRequest(hash, handleResponse) {
|
|||
alert(`Stream ended: ${end}`);
|
||||
});
|
||||
}
|
||||
|
||||
export function subscribeSqueakDisplayRequest(hash, handleResponse) {
|
||||
const request = new SubscribeSqueakDisplayRequest();
|
||||
request.setSqueakHash(hash);
|
||||
const stream = client.subscribeSqueakDisplay(request);
|
||||
stream.on('data', (response) => {
|
||||
handleResponse(response.getSqueakDisplayEntry());
|
||||
});
|
||||
stream.on('end', (end) => {
|
||||
// stream end signal
|
||||
console.log(end);
|
||||
alert(`Stream ended: ${end}`);
|
||||
});
|
||||
console.log("Stream object:");
|
||||
console.log(stream);
|
||||
return stream;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ from tests.util import make_squeak
|
|||
from tests.util import open_channel
|
||||
from tests.util import open_peer_connection
|
||||
from tests.util import subscribe_connected_peers
|
||||
from tests.util import subscribe_squeak_entry
|
||||
|
||||
|
||||
def test_get_network(admin_stub):
|
||||
|
|
@ -684,41 +685,49 @@ def test_download_single_squeak(
|
|||
signing_profile_id,
|
||||
saved_squeak_hash,
|
||||
):
|
||||
# Get the squeak display item (should be empty)
|
||||
squeak_display_entry = get_squeak_display(
|
||||
other_admin_stub, saved_squeak_hash)
|
||||
assert squeak_display_entry is None
|
||||
|
||||
# Get buy offers for the squeak hash (should be empty)
|
||||
get_buy_offers_response = other_admin_stub.GetBuyOffers(
|
||||
squeak_admin_pb2.GetBuyOffersRequest(
|
||||
squeak_hash=saved_squeak_hash,
|
||||
with subscribe_squeak_entry(other_admin_stub, saved_squeak_hash) as subscription_queue:
|
||||
|
||||
# Get the squeak display item (should be empty)
|
||||
squeak_display_entry = get_squeak_display(
|
||||
other_admin_stub, saved_squeak_hash)
|
||||
assert squeak_display_entry is None
|
||||
|
||||
# Get buy offers for the squeak hash (should be empty)
|
||||
get_buy_offers_response = other_admin_stub.GetBuyOffers(
|
||||
squeak_admin_pb2.GetBuyOffersRequest(
|
||||
squeak_hash=saved_squeak_hash,
|
||||
)
|
||||
)
|
||||
)
|
||||
# print(get_buy_offers_response)
|
||||
assert len(get_buy_offers_response.offers) == 0
|
||||
# print(get_buy_offers_response)
|
||||
assert len(get_buy_offers_response.offers) == 0
|
||||
|
||||
# Download squeak
|
||||
download_squeak(other_admin_stub, saved_squeak_hash)
|
||||
time.sleep(5)
|
||||
# Download squeak
|
||||
download_squeak(other_admin_stub, saved_squeak_hash)
|
||||
time.sleep(5)
|
||||
|
||||
# Get the squeak display item
|
||||
squeak_display_entry = get_squeak_display(
|
||||
other_admin_stub, saved_squeak_hash)
|
||||
assert squeak_display_entry is not None
|
||||
# Get the squeak display item
|
||||
squeak_display_entry = get_squeak_display(
|
||||
other_admin_stub, saved_squeak_hash)
|
||||
assert squeak_display_entry is not None
|
||||
|
||||
# Download offer
|
||||
download_offers(other_admin_stub, saved_squeak_hash)
|
||||
time.sleep(5)
|
||||
# Download offer
|
||||
download_offers(other_admin_stub, saved_squeak_hash)
|
||||
time.sleep(5)
|
||||
|
||||
# Get the buy offer
|
||||
get_buy_offers_response = other_admin_stub.GetBuyOffers(
|
||||
squeak_admin_pb2.GetBuyOffersRequest(
|
||||
squeak_hash=saved_squeak_hash,
|
||||
# Get the buy offer
|
||||
get_buy_offers_response = other_admin_stub.GetBuyOffers(
|
||||
squeak_admin_pb2.GetBuyOffersRequest(
|
||||
squeak_hash=saved_squeak_hash,
|
||||
)
|
||||
)
|
||||
)
|
||||
# print(get_buy_offers_response)
|
||||
assert len(get_buy_offers_response.offers) > 0
|
||||
# print(get_buy_offers_response)
|
||||
assert len(get_buy_offers_response.offers) > 0
|
||||
|
||||
item = subscription_queue.get()
|
||||
print("item:")
|
||||
print(item)
|
||||
assert item.squeak_hash == saved_squeak_hash
|
||||
|
||||
|
||||
def test_get_squeak_details(admin_stub, saved_squeak_hash):
|
||||
|
|
|
|||
|
|
@ -326,3 +326,23 @@ def delete_profile(node_stub, profile_id):
|
|||
profile_id=profile_id,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def subscribe_squeak_entry(node_stub, squeak_hash):
|
||||
q = queue.Queue()
|
||||
subscribe_squeak_entry_response = node_stub.SubscribeSqueakDisplay(
|
||||
squeak_admin_pb2.SubscribeSqueakDisplayRequest(
|
||||
squeak_hash=squeak_hash,
|
||||
)
|
||||
)
|
||||
|
||||
def enqueue_results():
|
||||
for result in subscribe_squeak_entry_response:
|
||||
q.put(result.squeak_display_entry)
|
||||
|
||||
threading.Thread(
|
||||
target=enqueue_results,
|
||||
).start()
|
||||
yield q
|
||||
subscribe_squeak_entry_response.cancel()
|
||||
|
|
|
|||
|
|
@ -280,6 +280,10 @@ service SqueakAdmin {
|
|||
*/
|
||||
rpc SubscribeBuyOffers (SubscribeBuyOffersRequest) returns (stream GetBuyOfferReply) {}
|
||||
|
||||
/** sqkadmin: `subscribesqueakdisplay`
|
||||
*/
|
||||
rpc SubscribeSqueakDisplay (SubscribeSqueakDisplayRequest) returns (stream GetSqueakDisplayReply) {}
|
||||
|
||||
}
|
||||
|
||||
message CreateSigningProfileRequest {
|
||||
|
|
@ -1002,3 +1006,8 @@ message SubscribeBuyOffersRequest {
|
|||
/// Hash of the squeak.
|
||||
string squeak_hash = 1;
|
||||
}
|
||||
|
||||
message SubscribeSqueakDisplayRequest {
|
||||
/// Hash of the squeak.
|
||||
string squeak_hash = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -797,3 +797,24 @@ class SqueakAdminServerHandler(object):
|
|||
yield squeak_admin_pb2.GetBuyOfferReply(
|
||||
offer=offer_msg,
|
||||
)
|
||||
|
||||
def handle_subscribe_squeak_display(self, request, stopped):
|
||||
squeak_hash_str = request.squeak_hash
|
||||
squeak_hash = bytes.fromhex(squeak_hash_str)
|
||||
logger.info(
|
||||
"Handle subscribe squeak display for hash: {}".format(squeak_hash_str))
|
||||
squeak_display_stream = self.squeak_controller.subscribe_squeak_entry(
|
||||
squeak_hash,
|
||||
stopped,
|
||||
)
|
||||
for squeak_display in squeak_display_stream:
|
||||
if squeak_display is None:
|
||||
yield squeak_admin_pb2.GetSqueakDisplayReply(
|
||||
squeak_display_entry=None
|
||||
)
|
||||
else:
|
||||
display_message = squeak_entry_to_message(
|
||||
squeak_display)
|
||||
yield squeak_admin_pb2.GetSqueakDisplayReply(
|
||||
squeak_display_entry=display_message
|
||||
)
|
||||
|
|
|
|||
|
|
@ -300,3 +300,15 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
|
|||
request,
|
||||
stopped,
|
||||
)
|
||||
|
||||
def SubscribeSqueakDisplay(self, request, context):
|
||||
stopped = threading.Event()
|
||||
|
||||
def on_rpc_done():
|
||||
logger.info("Stopping SubscribeSqueakDisplay.")
|
||||
stopped.set()
|
||||
context.add_callback(on_rpc_done)
|
||||
return self.handler.handle_subscribe_squeak_display(
|
||||
request,
|
||||
stopped,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/main.c99c3d4f.chunk.js",
|
||||
"main.js.map": "/static/js/main.c99c3d4f.chunk.js.map",
|
||||
"main.js": "/static/js/main.a67fc880.chunk.js",
|
||||
"main.js.map": "/static/js/main.a67fc880.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.9f0ba400.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.9f0ba400.js.map",
|
||||
"static/css/2.ea4ba2f0.chunk.css": "/static/css/2.ea4ba2f0.chunk.css",
|
||||
"static/js/2.ae9e5f97.chunk.js": "/static/js/2.ae9e5f97.chunk.js",
|
||||
"static/js/2.ae9e5f97.chunk.js.map": "/static/js/2.ae9e5f97.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"precache-manifest.8de724ab18db303eb642bebb45add2c3.js": "/precache-manifest.8de724ab18db303eb642bebb45add2c3.js",
|
||||
"precache-manifest.d67005e2e73ac40adcbc8e355616292e.js": "/precache-manifest.d67005e2e73ac40adcbc8e355616292e.js",
|
||||
"service-worker.js": "/service-worker.js",
|
||||
"static/css/2.ea4ba2f0.chunk.css.map": "/static/css/2.ea4ba2f0.chunk.css.map",
|
||||
"static/js/2.ae9e5f97.chunk.js.LICENSE.txt": "/static/js/2.ae9e5f97.chunk.js.LICENSE.txt",
|
||||
|
|
@ -20,6 +20,6 @@
|
|||
"static/js/runtime-main.9f0ba400.js",
|
||||
"static/css/2.ea4ba2f0.chunk.css",
|
||||
"static/js/2.ae9e5f97.chunk.js",
|
||||
"static/js/main.c99c3d4f.chunk.js"
|
||||
"static/js/main.a67fc880.chunk.js"
|
||||
]
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.ae9e5f97.chunk.js"></script><script src="/static/js/main.c99c3d4f.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.ae9e5f97.chunk.js"></script><script src="/static/js/main.a67fc880.chunk.js"></script></body></html>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
{
|
||||
"revision": "f04c018404e00f36d08b7a800568d90c",
|
||||
"revision": "5fc503e15ce3e6c9a33a90edac407ae8",
|
||||
"url": "/index.html"
|
||||
},
|
||||
{
|
||||
|
|
@ -16,8 +16,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
|||
"url": "/static/js/2.ae9e5f97.chunk.js.LICENSE.txt"
|
||||
},
|
||||
{
|
||||
"revision": "2e3182f3f6d47fff0214",
|
||||
"url": "/static/js/main.c99c3d4f.chunk.js"
|
||||
"revision": "fee5a9e403984952b91e",
|
||||
"url": "/static/js/main.a67fc880.chunk.js"
|
||||
},
|
||||
{
|
||||
"revision": "cc9816de5a8639d377ea",
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
|
||||
|
||||
importScripts(
|
||||
"/precache-manifest.8de724ab18db303eb642bebb45add2c3.js"
|
||||
"/precache-manifest.d67005e2e73ac40adcbc8e355616292e.js"
|
||||
);
|
||||
|
||||
self.addEventListener('message', (event) => {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -48,6 +48,7 @@ from squeaknode.core.sent_payment_summary import SentPaymentSummary
|
|||
from squeaknode.core.squeak_entry import SqueakEntry
|
||||
from squeaknode.core.squeak_peer import SqueakPeer
|
||||
from squeaknode.core.squeak_profile import SqueakProfile
|
||||
from squeaknode.core.util import get_hash
|
||||
from squeaknode.core.util import is_address_valid
|
||||
from squeaknode.core.util import squeak_matches_interest
|
||||
from squeaknode.network.peer import Peer
|
||||
|
|
@ -594,6 +595,7 @@ class SqueakController:
|
|||
)
|
||||
|
||||
def download_squeaks(self):
|
||||
# TODO: Don't use get interested locator, instead use params from request.
|
||||
locator = self.get_interested_locator()
|
||||
getsqueaks_msg = msg_getsqueaks(
|
||||
locator=locator,
|
||||
|
|
@ -671,3 +673,8 @@ class SqueakController:
|
|||
for received_offer in self.new_received_offer_listener.yield_items(stopped):
|
||||
if received_offer.squeak_hash == squeak_hash:
|
||||
yield received_offer
|
||||
|
||||
def subscribe_squeak_entry(self, squeak_hash: bytes, stopped: threading.Event):
|
||||
for item in self.new_squeak_listener.yield_items(stopped):
|
||||
if squeak_hash == get_hash(item):
|
||||
yield self.get_squeak_entry(squeak_hash)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue