From 011674b6bd9d1093401b961cbf61be6d401983a3 Mon Sep 17 00:00:00 2001 From: lza_menace Date: Thu, 30 Dec 2021 02:22:57 -0800 Subject: [PATCH] get dialed in with avax in configs and frontend --- alembic/env.py | 4 +- ..._add_profile_metadata_ipfs_and_wow_addy.py | 54 ++ suchwowx/config.py | 850 +++++++++--------- suchwowx/models.py | 2 + suchwowx/routes/api.py | 34 + suchwowx/static/js/main.js | 11 + suchwowx/templates/includes/navbar.html | 2 +- suchwowx/templates/includes/scripts.html | 3 +- suchwowx/templates/profile.html | 189 +++- 9 files changed, 704 insertions(+), 445 deletions(-) create mode 100644 alembic/versions/c548cc54ee17_add_profile_metadata_ipfs_and_wow_addy.py diff --git a/alembic/env.py b/alembic/env.py index 869c27a..c2a85cf 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -45,6 +45,7 @@ def run_migrations_offline(): target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, + render_as_batch=True ) with context.begin_transaction(): @@ -66,7 +67,8 @@ def run_migrations_online(): with connectable.connect() as connection: context.configure( - connection=connection, target_metadata=target_metadata + connection=connection, target_metadata=target_metadata, + render_as_batch=True ) with context.begin_transaction(): diff --git a/alembic/versions/c548cc54ee17_add_profile_metadata_ipfs_and_wow_addy.py b/alembic/versions/c548cc54ee17_add_profile_metadata_ipfs_and_wow_addy.py new file mode 100644 index 0000000..6cc8f9a --- /dev/null +++ b/alembic/versions/c548cc54ee17_add_profile_metadata_ipfs_and_wow_addy.py @@ -0,0 +1,54 @@ +"""add profile metadata ipfs and wow addy + +Revision ID: c548cc54ee17 +Revises: 40734564d415 +Create Date: 2021-12-30 01:35:12.774067 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'c548cc54ee17' +down_revision = '40734564d415' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('memes', schema=None) as batch_op: + batch_op.create_unique_constraint('memes_file_name_uniq', ['file_name']) + + with op.batch_alter_table('moderators', schema=None) as batch_op: + batch_op.alter_column('user_id', + existing_type=sa.INTEGER(), + nullable=True) + + with op.batch_alter_table('users', schema=None) as batch_op: + batch_op.add_column(sa.Column('ipfs_hash', sa.String(length=100), nullable=True)) + batch_op.add_column(sa.Column('wownero_address', sa.String(length=120), nullable=True)) + batch_op.drop_constraint('users_user_id_fkey', type_='foreignkey') + batch_op.drop_column('moderator_id') + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('users', schema=None) as batch_op: + batch_op.add_column(sa.Column('moderator_id', sa.INTEGER(), nullable=True)) + batch_op.create_foreign_key('users_user_id_fkey', 'moderators', ['moderator_id'], ['id']) + batch_op.drop_column('wownero_address') + batch_op.drop_column('ipfs_hash') + + with op.batch_alter_table('moderators', schema=None) as batch_op: + batch_op.alter_column('user_id', + existing_type=sa.INTEGER(), + nullable=False) + + with op.batch_alter_table('memes', schema=None) as batch_op: + batch_op.drop_constraint('memes_file_name_uniq', type_='unique') + + # ### end Alembic commands ### diff --git a/suchwowx/config.py b/suchwowx/config.py index a117779..157368b 100644 --- a/suchwowx/config.py +++ b/suchwowx/config.py @@ -20,655 +20,663 @@ MAX_CONTENT_LENGTH = 32 * 1024 * 1024 TEMPLATES_AUTO_RELOAD = getenv('TEMPLATES_AUTO_RELOAD', True) # Contract -CONTRACT_ADDRESS = '0xBAb68B24068D21Fa862908818054c7e4d921db5A' # rinkeby ETH +CONTRACT_ADDRESS = '0x9797afc5d0258704109f71109188fdcba19c24c2' # Fuji CONTRACT_ABI = [ { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" + 'inputs': [], + 'stateMutability': 'nonpayable', + 'type': 'constructor' }, { - "anonymous": False, - "inputs": [ + 'anonymous': False, + 'inputs': [ { - "indexed": True, - "internalType": "address", - "name": "owner", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'owner', + 'type': 'address' }, { - "indexed": True, - "internalType": "address", - "name": "approved", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'approved', + 'type': 'address' }, { - "indexed": True, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'indexed': True, + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "Approval", - "type": "event" + 'name': 'Approval', + 'type': 'event' }, { - "anonymous": False, - "inputs": [ + 'anonymous': False, + 'inputs': [ { - "indexed": True, - "internalType": "address", - "name": "owner", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'owner', + 'type': 'address' }, { - "indexed": True, - "internalType": "address", - "name": "operator", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'operator', + 'type': 'address' }, { - "indexed": False, - "internalType": "bool", - "name": "approved", - "type": "bool" + 'indexed': False, + 'internalType': 'bool', + 'name': 'approved', + 'type': 'bool' } ], - "name": "ApprovalForAll", - "type": "event" + 'name': 'ApprovalForAll', + 'type': 'event' }, { - "anonymous": False, - "inputs": [ + 'anonymous': False, + 'inputs': [ { - "indexed": True, - "internalType": "address", - "name": "previousOwner", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'previousOwner', + 'type': 'address' }, { - "indexed": True, - "internalType": "address", - "name": "newOwner", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'newOwner', + 'type': 'address' } ], - "name": "OwnershipTransferred", - "type": "event" + 'name': 'OwnershipTransferred', + 'type': 'event' }, { - "anonymous": False, - "inputs": [ + 'anonymous': False, + 'inputs': [ { - "indexed": True, - "internalType": "address", - "name": "from", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'from', + 'type': 'address' }, { - "indexed": True, - "internalType": "address", - "name": "to", - "type": "address" + 'indexed': True, + 'internalType': 'address', + 'name': 'to', + 'type': 'address' }, { - "indexed": True, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'indexed': True, + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "Transfer", - "type": "event" + 'name': 'Transfer', + 'type': 'event' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "to", - "type": "address" + 'internalType': 'address', + 'name': 'to', + 'type': 'address' }, { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'approve', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "owner", - "type": "address" + 'internalType': 'address', + 'name': 'owner', + 'type': 'address' } ], - "name": "balanceOf", - "outputs": [ + 'name': 'balanceOf', + 'outputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [], - "name": "contractCreator", - "outputs": [ + 'inputs': [], + 'name': 'contractCreator', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [], - "name": "contractVersion", - "outputs": [ + 'inputs': [], + 'name': 'contractTipCutPercent', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [], + 'name': 'contractVersion', + 'outputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "name": "creatorTips", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "creatorTokensMinted", - "outputs": [ + 'name': 'getApproved', + 'outputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'address', + 'name': '', + 'type': 'address' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'address', + 'name': 'owner', + 'type': 'address' + }, + { + 'internalType': 'address', + 'name': 'operator', + 'type': 'address' } ], - "name": "creatorWowneroAddress", - "outputs": [ + 'name': 'isApprovedForAll', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'bool', + 'name': '', + 'type': 'bool' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "name": "getApproved", - "outputs": [ + 'name': 'metadataTokenId', + 'outputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, + 'inputs': [], + 'name': 'name', + 'outputs': [ { - "internalType": "address", - "name": "operator", - "type": "address" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [], + 'name': 'owner', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'address', + 'name': '', + 'type': 'address' } ], - "name": "metadataTokenId", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [], - "name": "name", - "outputs": [ + 'inputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True - }, - { - "inputs": [], - "name": "owner", - "outputs": [ + 'name': 'ownerOf', + 'outputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'address', + 'name': '', + 'type': 'address' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ + 'inputs': [], + 'name': 'publisherTipCutPercent', + 'outputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'inputs': [], + 'name': 'renounceOwnership', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "from", - "type": "address" + 'internalType': 'address', + 'name': 'from', + 'type': 'address' }, { - "internalType": "address", - "name": "to", - "type": "address" + 'internalType': 'address', + 'name': 'to', + 'type': 'address' }, { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'safeTransferFrom', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "from", - "type": "address" + 'internalType': 'address', + 'name': 'from', + 'type': 'address' }, { - "internalType": "address", - "name": "to", - "type": "address" + 'internalType': 'address', + 'name': 'to', + 'type': 'address' }, { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' }, { - "internalType": "bytes", - "name": "_data", - "type": "bytes" + 'internalType': 'bytes', + 'name': '_data', + 'type': 'bytes' } ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'safeTransferFrom', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "operator", - "type": "address" + 'internalType': 'address', + 'name': 'operator', + 'type': 'address' }, { - "internalType": "bool", - "name": "approved", - "type": "bool" + 'internalType': 'bool', + 'name': 'approved', + 'type': 'bool' } ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'setApprovalForAll', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" + 'internalType': 'bytes4', + 'name': 'interfaceId', + 'type': 'bytes4' } ], - "name": "supportsInterface", - "outputs": [ + 'name': 'supportsInterface', + 'outputs': [ { - "internalType": "bool", - "name": "", - "type": "bool" + 'internalType': 'bool', + 'name': '', + 'type': 'bool' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [], - "name": "symbol", - "outputs": [ + 'inputs': [], + 'name': 'symbol', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "name": "tipperTips", - "outputs": [ + 'name': 'tokenMeme', + 'outputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'publisherTipsAVAX', + 'type': 'uint256' + }, + { + 'internalType': 'uint256', + 'name': 'creatorTipsAVAX', + 'type': 'uint256' + }, + { + 'internalType': 'uint256', + 'name': 'contractTipsAVAX', + 'type': 'uint256' + }, + { + 'internalType': 'address', + 'name': 'publisherAddress', + 'type': 'address' + }, + { + 'internalType': 'address', + 'name': 'creatorAddress', + 'type': 'address' + }, + { + 'internalType': 'string', + 'name': 'metadataIPFSHash', + 'type': 'string' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ + { + 'internalType': 'address', + 'name': 'from', + 'type': 'address' + }, { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'address', + 'name': 'to', + 'type': 'address' + }, + { + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "tokenCreator", - "outputs": [ + 'name': 'transferFrom', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' + }, + { + 'inputs': [ { - "internalType": "address", - "name": "", - "type": "address" + 'internalType': 'address', + 'name': 'newOwner', + 'type': 'address' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'name': 'transferOwnership', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'address', + 'name': '', + 'type': 'address' } ], - "name": "tokenMetadata", - "outputs": [ + 'name': 'userProfile', + 'outputs': [ + { + 'internalType': 'string', + 'name': 'wowneroAddress', + 'type': 'string' + }, + { + 'internalType': 'string', + 'name': 'userHandle', + 'type': 'string' + }, + { + 'internalType': 'string', + 'name': 'metadataIPFSHash', + 'type': 'string' + }, { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'uint256', + 'name': 'tippedAVAX', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [], + 'name': 'withdraw', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' + }, + { + 'inputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'percent', + 'type': 'uint256' } ], - "name": "tokenTips", - "outputs": [ + 'name': 'setContractTipCut', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' + }, + { + 'inputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'percent', + 'type': 'uint256' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'name': 'setPublisherTipCut', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [], + 'name': 'totalSupply', + 'outputs': [ { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256' } ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'stateMutability': 'view', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "address", - "name": "newOwner", - "type": "address" + 'internalType': 'string', + 'name': 'wowneroAddress', + 'type': 'string' } ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "withdraw", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'setUserWowneroAddress', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [], - "name": "totalSupply", - "outputs": [ + 'inputs': [ { - "internalType": "uint256", - "name": "", - "type": "uint256" + 'internalType': 'string', + 'name': 'handle', + 'type': 'string' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'name': 'setUserHandle', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "string", - "name": "wowneroAddress", - "type": "string" + 'internalType': 'string', + 'name': 'metadataIPFSHash', + 'type': 'string' } ], - "name": "set_wownero_address", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'setUserMetadata', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "string", - "name": "metadataIPFSHash", - "type": "string" + 'internalType': 'string', + 'name': 'metadataIPFSHash', + 'type': 'string' + }, + { + 'internalType': 'address', + 'name': 'creatorAddress', + 'type': 'address' } ], - "name": "mint", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + 'name': 'mint', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "tip", - "outputs": [], - "stateMutability": "payable", - "type": "function", - "payable": True + 'name': 'tipAVAX', + 'outputs': [], + 'stateMutability': 'payable', + 'type': 'function' }, { - "inputs": [ + 'inputs': [ { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" + 'internalType': 'uint256', + 'name': 'tokenId', + 'type': 'uint256' } ], - "name": "tokenURI", - "outputs": [ + 'name': 'tokenURI', + 'outputs': [ { - "internalType": "string", - "name": "", - "type": "string" + 'internalType': 'string', + 'name': '', + 'type': 'string' } ], - "stateMutability": "view", - "type": "function", - "constant": True + 'stateMutability': 'view', + 'type': 'function' } ] + # Logging LOGGING_CONFIG = { 'version': 1, diff --git a/suchwowx/models.py b/suchwowx/models.py index cdb55ef..c921084 100644 --- a/suchwowx/models.py +++ b/suchwowx/models.py @@ -36,6 +36,8 @@ class User(db.Model): handle = db.Column(db.String(40), unique=True) bio = db.Column(db.String(600), nullable=True) profile_image = db.Column(db.String(300), nullable=True) + ipfs_hash = db.Column(db.String(100), nullable=True) + wownero_address = db.Column(db.String(120), nullable=True) website_url = db.Column(db.String(120), nullable=True) moderator = db.relationship('Moderator', back_populates='user') memes = db.relationship('Meme', back_populates='user') diff --git a/suchwowx/routes/api.py b/suchwowx/routes/api.py index 859bf84..d598657 100644 --- a/suchwowx/routes/api.py +++ b/suchwowx/routes/api.py @@ -41,6 +41,40 @@ def user_exists(): }) +@bp.route('/update/user', methods=['POST']) +def update_user(): + if not current_user.is_authenticated: + return jsonify({ + 'success': False, + 'message': 'Must be authenticated in order to update.' + }) + + data = request.get_json() + _u = User.query.get(int(data['user_id'])) + + if _u: + if current_user.id == _u.id: + _u.wownero_address = data['wownero_address'] + _u.ipfs_hash = data['ipfs_hash'] + _u.handle = data['handle'] + db.session.commit() + return jsonify({ + 'success': True, + 'message': 'Updated user record.' + }) + else: + return jsonify({ + 'success': False, + 'message': 'Cannot edit another record.' + }) + + else: + return jsonify({ + 'success': False, + 'message': 'User does not exist.' + }) + + @bp.route('/authenticate/metamask', methods=['POST']) def authenticate_metamask(): """ diff --git a/suchwowx/static/js/main.js b/suchwowx/static/js/main.js index 11a0cb1..22461c2 100644 --- a/suchwowx/static/js/main.js +++ b/suchwowx/static/js/main.js @@ -7,6 +7,17 @@ async function getSignedData(publicAddress, jsonData) { return signedData } +async function notif(s, t) { + new Noty({ + type: t, + theme: 'relax', + layout: 'topCenter', + text: s, + timeout: 4500 + }).show(); + return +} + async function confirmAvalanche(){ let debug = true; let chainId; diff --git a/suchwowx/templates/includes/navbar.html b/suchwowx/templates/includes/navbar.html index 6a3eea6..d9af146 100644 --- a/suchwowx/templates/includes/navbar.html +++ b/suchwowx/templates/includes/navbar.html @@ -8,7 +8,7 @@ {% if request.path == '/' %} About {% if current_user.is_authenticated %} - Profile + Profile Disconnect {% if current_user.is_moderator() %} Mod diff --git a/suchwowx/templates/includes/scripts.html b/suchwowx/templates/includes/scripts.html index ef28c93..af6439d 100644 --- a/suchwowx/templates/includes/scripts.html +++ b/suchwowx/templates/includes/scripts.html @@ -1,7 +1,6 @@ - + {% if not current_user.is_authenticated %} - {% endif %} diff --git a/suchwowx/templates/profile.html b/suchwowx/templates/profile.html index 76e1048..f3fe682 100644 --- a/suchwowx/templates/profile.html +++ b/suchwowx/templates/profile.html @@ -1,3 +1,4 @@ +{% set is_user = current_user == user %} {% include 'includes/head.html' %} @@ -8,31 +9,179 @@ {% include 'includes/navbar.html' %} {% if user %} -
-
-

From Avax Chain

-

Handle: ?

- -

-

From Local Database

-

Handle:

-

Register Date: {{ user.register_date }}

-

Login Date: {{ user.last_login_date }}

-

Moderator: {{ user.is_moderator() }}

-

Verified: {{ user.verified }}

-

Memes Posted: {{ user.memes | length }}

- {% if user.bio %} -

Bio: {{ user.bio }}

- {% endif %} - {% if user.website %} -

Website: {{ user.website_url }}

- {% endif %} -
+
+
+
+ +
+
+

From Avax Chain

+

Handle: ?

+

Wownero Address: ?

+

Profile IPFS Hash: ?

+

Tipped AVAX: ?

+

Tipped WOWX: ?

+

Tipped WOW: ?

+ +

+

From Local Database

+

+ Handle: + {% if is_user %} + Publish AVAX + {% endif %} +

+

+ Wownero Address: + {% if is_user %} + Publish AVAX + {% endif %} +

+

+ Metadata IPFS Hash: + {% if is_user %} + Publish AVAX + {% endif %} +

+

Save DB

+

Register Date: {{ user.register_date }}

+

Login Date: {{ user.last_login_date }}

+

Moderator: {{ user.is_moderator() }}

+

Verified: {{ user.verified }}

+

Memes Posted: {{ user.memes | length }}

+ {% if user.bio %} +

Bio: {{ user.bio }}

+ {% endif %} + {% if user.website %} +

Website: {{ user.website_url }}

+ {% endif %} +
+
{% endif %}
+ {% include 'includes/footer.html' %} + + +