mirror of
https://github.com/yzernik/squeaknode.git
synced 2026-08-13 12:33:25 +02:00
Updrage squeaklib to 0.7.1 (#1194)
* Updrage squeaklib to 0.7.1 * Add case to handle secret key msg in peer msg handler * Add fields for custom price and use custom price to profile table * Got itest working with new profile fields * Use default values for profile struct constructor * Fix db migration to use use profile columns * Got itest passing for set use custom price * Show custom price or default price in profile page * Change wording of selling with price in profile page * Got set use custom price toggle working in configure profile dialog
This commit is contained in:
parent
8c029040bf
commit
76ad744936
18 changed files with 206 additions and 19 deletions
|
|
@ -17,6 +17,7 @@ import useStyles from './styles';
|
|||
|
||||
import {
|
||||
setSqueakProfileFollowingRequest,
|
||||
setSqueakProfileUseCustomPriceRequest,
|
||||
} from '../../squeakclient/requests';
|
||||
|
||||
export default function ConfigureProfileDialog({
|
||||
|
|
@ -34,12 +35,24 @@ export default function ConfigureProfileDialog({
|
|||
});
|
||||
};
|
||||
|
||||
const setUseCustomPrice = (id, useCustomPrice) => {
|
||||
setSqueakProfileUseCustomPriceRequest(id, useCustomPrice, () => {
|
||||
reloadProfile();
|
||||
});
|
||||
};
|
||||
|
||||
const handleSettingsFollowingChange = (event) => {
|
||||
console.log(`Following changed for profile id: ${squeakProfile.getProfileId()}`);
|
||||
console.log(`Following changed to: ${event.target.checked}`);
|
||||
setFollowing(squeakProfile.getProfileId(), event.target.checked);
|
||||
};
|
||||
|
||||
const handleSettingsUseCustomPriceChange = (event) => {
|
||||
console.log(`UseCustomPrice changed for profile id: ${squeakProfile.getProfileId()}`);
|
||||
console.log(`UseCustomPrice changed to: ${event.target.checked}`);
|
||||
setUseCustomPrice(squeakProfile.getProfileId(), event.target.checked);
|
||||
};
|
||||
|
||||
function MakeCancelButton() {
|
||||
return (
|
||||
<Button
|
||||
|
|
@ -61,6 +74,10 @@ export default function ConfigureProfileDialog({
|
|||
control={<Switch checked={squeakProfile.getFollowing()} onChange={handleSettingsFollowingChange} />}
|
||||
label="Following"
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={squeakProfile.getUseCustomPrice()} onChange={handleSettingsUseCustomPriceChange} />}
|
||||
label="UseCustomPrice"
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormControl>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import CardHeader from '@material-ui/core/CardHeader';
|
|||
|
||||
import MoreVertIcon from '@material-ui/icons/MoreVert';
|
||||
import VpnKeyIcon from '@material-ui/icons/VpnKey';
|
||||
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
|
||||
|
||||
// styles
|
||||
import useStyles from './styles';
|
||||
|
|
@ -225,6 +226,19 @@ export default function SqueakProfileDetailItem({
|
|||
);
|
||||
}
|
||||
|
||||
function CustomPriceContent() {
|
||||
return (
|
||||
<Typography variant="body2" color="textSecondary" component="p">
|
||||
<LocalOfferIcon />
|
||||
{' '}
|
||||
{(squeakProfile.getUseCustomPrice()) ?
|
||||
<>Selling with custom price: {squeakProfile.getCustomPriceMsat()} msats</> :
|
||||
<>Selling with default price</>
|
||||
}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className={classes.root}>
|
||||
|
|
@ -271,6 +285,9 @@ export default function SqueakProfileDetailItem({
|
|||
<SqueakProfileFollowingIndicator
|
||||
squeakProfile={squeakProfile}
|
||||
/>
|
||||
<CustomPriceContent
|
||||
|
||||
/>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {
|
|||
GetSqueakProfileRequest,
|
||||
GetTimelineSqueakDisplaysRequest,
|
||||
SetSqueakProfileFollowingRequest,
|
||||
SetSqueakProfileUseCustomPriceRequest,
|
||||
GetPeersRequest,
|
||||
PayOfferRequest,
|
||||
GetBuyOffersRequest,
|
||||
|
|
@ -183,6 +184,15 @@ export function setSqueakProfileFollowingRequest(id, following, handleResponse)
|
|||
});
|
||||
}
|
||||
|
||||
export function setSqueakProfileUseCustomPriceRequest(id, useCustomPrice, handleResponse) {
|
||||
const request = new SetSqueakProfileUseCustomPriceRequest();
|
||||
request.setProfileId(id);
|
||||
request.setUseCustomPrice(useCustomPrice);
|
||||
client.setSqueakProfileUseCustomPrice(request, {}, (err, response) => {
|
||||
handleResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
export function renameSqueakProfileRequest(id, profileName, handleResponse) {
|
||||
const request = new RenameSqueakProfileRequest();
|
||||
request.setProfileId(id);
|
||||
|
|
|
|||
|
|
@ -309,6 +309,32 @@ def test_set_profile_following(admin_stub, contact_profile_id):
|
|||
assert not squeak_profile.following
|
||||
|
||||
|
||||
def test_set_profile_use_custom_price(admin_stub, contact_profile_id):
|
||||
# Set the profile to use_custom_price
|
||||
admin_stub.SetSqueakProfileUseCustomPrice(
|
||||
squeak_admin_pb2.SetSqueakProfileUseCustomPriceRequest(
|
||||
profile_id=contact_profile_id,
|
||||
use_custom_price=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Get the squeak profile again
|
||||
squeak_profile = get_squeak_profile(admin_stub, contact_profile_id)
|
||||
assert squeak_profile.use_custom_price
|
||||
|
||||
# Set the profile to not use custom price
|
||||
admin_stub.SetSqueakProfileUseCustomPrice(
|
||||
squeak_admin_pb2.SetSqueakProfileUseCustomPriceRequest(
|
||||
profile_id=contact_profile_id,
|
||||
use_custom_price=False,
|
||||
)
|
||||
)
|
||||
|
||||
# Get the squeak profile again
|
||||
squeak_profile = get_squeak_profile(admin_stub, contact_profile_id)
|
||||
assert not squeak_profile.use_custom_price
|
||||
|
||||
|
||||
def test_rename_profile(admin_stub, contact_profile_id, random_name):
|
||||
# Rename the profile to something new
|
||||
admin_stub.RenameSqueakProfile(
|
||||
|
|
|
|||
|
|
@ -104,6 +104,10 @@ service SqueakAdmin {
|
|||
*/
|
||||
rpc SetSqueakProfileFollowing (SetSqueakProfileFollowingRequest) returns (SetSqueakProfileFollowingReply) {}
|
||||
|
||||
/** sqkadmin: `setsqueakprofileusecustomprice`
|
||||
*/
|
||||
rpc SetSqueakProfileUseCustomPrice (SetSqueakProfileUseCustomPriceRequest) returns (SetSqueakProfileUseCustomPriceReply) {}
|
||||
|
||||
/** sqkadmin: `renamesqueakprofile`
|
||||
*/
|
||||
rpc RenameSqueakProfile (RenameSqueakProfileRequest) returns (RenameSqueakProfileReply) {}
|
||||
|
|
@ -411,6 +415,17 @@ message SetSqueakProfileFollowingRequest {
|
|||
message SetSqueakProfileFollowingReply {
|
||||
}
|
||||
|
||||
message SetSqueakProfileUseCustomPriceRequest {
|
||||
/// The profile id
|
||||
int32 profile_id = 1;
|
||||
|
||||
/// Use custom price
|
||||
bool use_custom_price = 2;
|
||||
}
|
||||
|
||||
message SetSqueakProfileUseCustomPriceReply {
|
||||
}
|
||||
|
||||
message RenameSqueakProfileRequest {
|
||||
/// The profile id
|
||||
int32 profile_id = 1;
|
||||
|
|
@ -475,11 +490,17 @@ message SqueakProfile {
|
|||
/// Following
|
||||
bool following = 5;
|
||||
|
||||
/// Following
|
||||
bool use_custom_price = 6;
|
||||
|
||||
/// The price in msats
|
||||
int64 custom_price_msat = 7;
|
||||
|
||||
/// The profile image
|
||||
string profile_image = 6;
|
||||
string profile_image = 8;
|
||||
|
||||
/// Has custom profile image
|
||||
bool has_custom_profile_image = 7;
|
||||
bool has_custom_profile_image = 9;
|
||||
}
|
||||
|
||||
message MakeSqueakRequest {
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ grpcio
|
|||
grpcio-tools
|
||||
importlib_resources==1.4.0
|
||||
pytest
|
||||
squeakpy==0.7.0
|
||||
squeakpy==0.7.1
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ psycopg2
|
|||
pyzmq
|
||||
requests
|
||||
SQLAlchemy
|
||||
squeakpy==0.7.0
|
||||
squeakpy==0.7.1
|
||||
typed-config
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -103,7 +103,7 @@ setup(
|
|||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=[
|
||||
'squeakpy>=0.7.0',
|
||||
'squeakpy>=0.7.1',
|
||||
'importlib_resources',
|
||||
'argparse',
|
||||
'googleapis-common-protos',
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ def squeak_profile_to_message(squeak_profile: SqueakProfile) -> squeak_admin_pb2
|
|||
has_private_key=has_private_key,
|
||||
address=squeak_profile.address,
|
||||
following=squeak_profile.following,
|
||||
use_custom_price=squeak_profile.use_custom_price,
|
||||
custom_price_msat=squeak_profile.custom_price_msat,
|
||||
profile_image=image_base64_str,
|
||||
has_custom_profile_image=has_custom_profile_image,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -223,6 +223,19 @@ class SqueakAdminServerHandler(object):
|
|||
profile_id, following)
|
||||
return squeak_admin_pb2.SetSqueakProfileFollowingReply()
|
||||
|
||||
def handle_set_squeak_profile_use_custom_price(self, request):
|
||||
profile_id = request.profile_id
|
||||
use_custom_price = request.use_custom_price
|
||||
logger.info(
|
||||
"Handle set squeak profile use_custom_price with profile id: {}, use_custom_price: {}".format(
|
||||
profile_id,
|
||||
use_custom_price,
|
||||
)
|
||||
)
|
||||
self.squeak_controller.set_squeak_profile_use_custom_price(
|
||||
profile_id, use_custom_price)
|
||||
return squeak_admin_pb2.SetSqueakProfileUseCustomPriceReply()
|
||||
|
||||
def handle_rename_squeak_profile(self, request):
|
||||
profile_id = request.profile_id
|
||||
profile_name = request.profile_name
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
|
|||
def SetSqueakProfileFollowing(self, request, context):
|
||||
return self.handler.handle_set_squeak_profile_following(request)
|
||||
|
||||
def SetSqueakProfileUseCustomPrice(self, request, context):
|
||||
return self.handler.handle_set_squeak_profile_use_custom_price(request)
|
||||
|
||||
def RenameSqueakProfile(self, request, context):
|
||||
return self.handler.handle_rename_squeak_profile(request)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@ from typing import Optional
|
|||
|
||||
class SqueakProfile(NamedTuple):
|
||||
"""Represents a user who can author squeaks."""
|
||||
profile_id: Optional[int]
|
||||
profile_name: str
|
||||
private_key: Optional[bytes]
|
||||
address: str
|
||||
following: bool
|
||||
profile_image: Optional[bytes]
|
||||
profile_id: Optional[int] = None
|
||||
private_key: Optional[bytes] = None
|
||||
following: bool = True
|
||||
use_custom_price: bool = False
|
||||
custom_price_msat: int = 0
|
||||
profile_image: Optional[bytes] = None
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2020 Jonathan Zernik
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
"""Add custom price and use custom price columns to profile
|
||||
|
||||
Revision ID: af0082f29c93
|
||||
Revises: 814be7653a69
|
||||
Create Date: 2021-09-05 09:45:54.290859
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.sql import expression
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'af0082f29c93'
|
||||
down_revision = '814be7653a69'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('profile', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('use_custom_price',
|
||||
sa.Boolean(), nullable=False, server_default=expression.false()))
|
||||
batch_op.add_column(sa.Column('custom_price_msat',
|
||||
sa.Integer(), nullable=False, server_default=text('0')))
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('profile', schema=None) as batch_op:
|
||||
batch_op.drop_column('custom_price_msat')
|
||||
batch_op.drop_column('use_custom_price')
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -106,6 +106,8 @@ class Models:
|
|||
Column("private_key", Binary, nullable=True),
|
||||
Column("address", String(35), unique=True, nullable=False),
|
||||
Column("following", Boolean, nullable=False),
|
||||
Column("use_custom_price", Boolean, nullable=False, default=False),
|
||||
Column("custom_price_msat", Integer, nullable=False, default=0),
|
||||
Column("profile_image", Binary, nullable=True),
|
||||
sqlite_autoincrement=True,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -757,6 +757,16 @@ class SqueakDb:
|
|||
with self.get_connection() as connection:
|
||||
connection.execute(stmt)
|
||||
|
||||
def set_profile_use_custom_price(self, profile_id: int, use_custom_price: bool) -> None:
|
||||
""" Set a profile use custom price. """
|
||||
stmt = (
|
||||
self.profiles.update()
|
||||
.where(self.profiles.c.profile_id == profile_id)
|
||||
.values(use_custom_price=use_custom_price)
|
||||
)
|
||||
with self.get_connection() as connection:
|
||||
connection.execute(stmt)
|
||||
|
||||
def set_profile_name(self, profile_id: int, profile_name: str) -> None:
|
||||
""" Set a profile name. """
|
||||
stmt = (
|
||||
|
|
@ -1270,6 +1280,8 @@ class SqueakDb:
|
|||
private_key=private_key,
|
||||
address=row["address"],
|
||||
following=row["following"],
|
||||
use_custom_price=row["use_custom_price"],
|
||||
custom_price_msat=row["custom_price_msat"],
|
||||
profile_image=row["profile_image"],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ class PeerMessageHandler:
|
|||
self.handle_notfound(msg)
|
||||
elif msg.command == b'offer':
|
||||
self.handle_offer(msg)
|
||||
elif msg.command == b'secretkey':
|
||||
self.handle_secret_key(msg)
|
||||
elif msg.command == b'subscribe':
|
||||
self.handle_subscribe(msg)
|
||||
else:
|
||||
|
|
@ -167,6 +169,12 @@ class PeerMessageHandler:
|
|||
self.peer.remote_address,
|
||||
)
|
||||
|
||||
def handle_secret_key(self, msg):
|
||||
self.squeak_controller.unlock_squeak(
|
||||
msg.hashSqk,
|
||||
msg.secretKey,
|
||||
)
|
||||
|
||||
def handle_subscribe(self, msg):
|
||||
self._send_reply_invs(msg.locator)
|
||||
self.peer.set_subscription(msg)
|
||||
|
|
|
|||
|
|
@ -205,12 +205,9 @@ class SqueakController:
|
|||
signing_key_str = str(signing_key)
|
||||
signing_key_bytes = signing_key_str.encode()
|
||||
squeak_profile = SqueakProfile(
|
||||
profile_id=None,
|
||||
profile_name=profile_name,
|
||||
private_key=signing_key_bytes,
|
||||
address=str(address),
|
||||
following=True,
|
||||
profile_image=None,
|
||||
)
|
||||
profile_id = self.squeak_db.insert_profile(squeak_profile)
|
||||
self.update_subscriptions()
|
||||
|
|
@ -223,12 +220,9 @@ class SqueakController:
|
|||
signing_key_str = str(signing_key)
|
||||
signing_key_bytes = signing_key_str.encode()
|
||||
squeak_profile = SqueakProfile(
|
||||
profile_id=None,
|
||||
profile_name=profile_name,
|
||||
private_key=signing_key_bytes,
|
||||
address=str(address),
|
||||
following=True,
|
||||
profile_image=None,
|
||||
)
|
||||
profile_id = self.squeak_db.insert_profile(squeak_profile)
|
||||
self.update_subscriptions()
|
||||
|
|
@ -246,12 +240,8 @@ class SqueakController:
|
|||
),
|
||||
)
|
||||
squeak_profile = SqueakProfile(
|
||||
profile_id=None,
|
||||
profile_name=profile_name,
|
||||
private_key=None,
|
||||
address=squeak_address,
|
||||
following=True,
|
||||
profile_image=None,
|
||||
)
|
||||
profile_id = self.squeak_db.insert_profile(squeak_profile)
|
||||
self.update_subscriptions()
|
||||
|
|
@ -279,6 +269,10 @@ class SqueakController:
|
|||
self.squeak_db.set_profile_following(profile_id, following)
|
||||
self.update_subscriptions()
|
||||
|
||||
def set_squeak_profile_use_custom_price(self, profile_id: int, use_custom_price: bool) -> None:
|
||||
self.squeak_db.set_profile_use_custom_price(
|
||||
profile_id, use_custom_price)
|
||||
|
||||
def rename_squeak_profile(self, profile_id: int, profile_name: str) -> None:
|
||||
self.squeak_db.set_profile_name(profile_id, profile_name)
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ def signing_profile():
|
|||
private_key=signing_key_bytes,
|
||||
address=str(address),
|
||||
following=False,
|
||||
use_custom_price=False,
|
||||
custom_price_msat=0,
|
||||
profile_image=None,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue