setting up remote server capabilities

main
lza_menace 3 years ago
parent 80d74af7a3
commit 3fa904df64

@ -0,0 +1,35 @@
"""add remote servers
Revision ID: 92b2ce4b6c87
Revises: f6f695a38339
Create Date: 2022-01-03 01:20:39.066496
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '92b2ce4b6c87'
down_revision = 'f6f695a38339'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('remotes',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('create_date', sa.DateTime(), nullable=True),
sa.Column('last_sync_date', sa.DateTime(), nullable=True),
sa.Column('paused', sa.Boolean(), nullable=True),
sa.Column('endpoint', sa.String(length=120), nullable=True),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('remotes')
# ### end Alembic commands ###

@ -4,7 +4,7 @@ from secrets import token_urlsafe
from suchwowx.factory import db from suchwowx.factory import db
from suchwowx.helpers import get_eth_contract from suchwowx.helpers import get_eth_contract
from suchwowx.models import Meme, User from suchwowx.models import Meme, User, Remote
from suchwowx import config from suchwowx import config
@ -72,3 +72,55 @@ def sync_avax():
print(f'[+] Added new meme {meme.id}') print(f'[+] Added new meme {meme.id}')
except Exception as e: except Exception as e:
print(e) print(e)
# @bp.cli.command('sync-remotes')
# def sync_remotes():
# """
# Sync remote servers with local database.
# """
# remotes = Remote.query.filter(Remote.paused == False)
# for remote in remotes:
# deets = request.get(remote.endpoint + '/api/v1/memes').json()
# meme_exists = Meme.query.filter(Meme.meta_ipfs_hash == deets['meta_ipfs_hash']).first() # noqa
# user_exists = User.query.filter(User.public_address == deets[4].lower()).first() # noqa
# if meme_exists:
# if not meme_exists.minted:
# meme_exists.minted = True
# db.session.commit()
# print(f'[+] Marked existing meme {meme_exists.id} as minted')
# else:
# print(deets)
# if not user_exists:
# user_exists = User(
# public_address=deets[4].lower()
# )
# db.session.add(user_exists)
# db.session.commit()
# user_exists.handle = f'anon{user_exists.id}-{token_urlsafe(6)}'
# db.session.commit()
# print(f'[+] Created user {user_exists.handle}')
# res = requests.get(f'{config.IPFS_SERVER}/ipfs/{deets[5]}', timeout=30).json()
# if not 'image' in res:
# print('No image IPFS hash, skipping')
# continue
# meme_ipfs_hash = res['image'].split('ipfs://')[1]
# filename = token_urlsafe(24)
# print(f'[+] Downloading image hash {meme_ipfs_hash} as {filename}')
# r = requests.get(f'{config.IPFS_SERVER}/ipfs/{meme_ipfs_hash}', stream=True)
# with open(f'{config.DATA_FOLDER}/uploads/{filename}', 'wb') as f:
# for chunk in r.iter_content(chunk_size = 16*1024):
# f.write(chunk)
# meme = Meme(
# title=res['name'],
# file_name=filename,
# description=res['description'],
# user_id=user_exists.id,
# meta_ipfs_hash=deets[5],
# meme_ipfs_hash=meme_ipfs_hash,
# minted=True,
# synced=True
# )
# db.session.add(meme)
# db.session.commit()
# print(f'[+] Added new meme {meme.id}')

@ -16,6 +16,8 @@ def shorten_address(a):
@bp.app_template_filter('humanize') @bp.app_template_filter('humanize')
def humanize(d): def humanize(d):
if not d:
return 'never'
return arrow_get(d).humanize() return arrow_get(d).humanize()
@bp.app_template_filter() @bp.app_template_filter()

@ -33,9 +33,8 @@ def upload_to_ipfs(meme_id: str):
if not meme: if not meme:
return False return False
try: try:
full_path = f'{config.DATA_FOLDER}/uploads/{meme.file_name}'
client = ipfsApi.Client('127.0.0.1', 5001) client = ipfsApi.Client('127.0.0.1', 5001)
artwork_hashes = client.add(full_path) artwork_hashes = client.add(meme.get_fs_path())
artwork_hash = artwork_hashes[0]['Hash'] artwork_hash = artwork_hashes[0]['Hash']
print(f'[+] Uploaded artwork to IPFS: {artwork_hash}') print(f'[+] Uploaded artwork to IPFS: {artwork_hash}')
meta = { meta = {

@ -117,3 +117,16 @@ class Meme(db.Model):
def get_fs_path(self): def get_fs_path(self):
return f'{config.DATA_FOLDER}/uploads/{self.file_name}' return f'{config.DATA_FOLDER}/uploads/{self.file_name}'
class Remote(db.Model):
__tablename__ = 'remotes'
id = db.Column(db.Integer, primary_key=True)
create_date = db.Column(db.DateTime, default=datetime.utcnow)
last_sync_date = db.Column(db.DateTime, nullable=True)
paused = db.Column(db.Boolean, default=False)
endpoint = db.Column(db.String(120))
def __repr__(self):
return str(f'remote-{self.id}')

@ -44,7 +44,6 @@ def publish():
flash('You need to connect your wallet first.', 'warning') flash('You need to connect your wallet first.', 'warning')
return redirect(url_for('meme.index')) return redirect(url_for('meme.index'))
meme = None meme = None
form_err = False
try: try:
client = ipfsApi.Client('127.0.0.1', 5001) client = ipfsApi.Client('127.0.0.1', 5001)
client.add_json({}) client.add_json({})
@ -56,8 +55,6 @@ def publish():
return '<script>window.history.back()</script>' return '<script>window.history.back()</script>'
return redirect(url_for('meme.index') + '?ipfs_error=1') return redirect(url_for('meme.index') + '?ipfs_error=1')
if "file" in request.files: if "file" in request.files:
if form_err:
return '<script>window.history.back()</script>'
title = request.form.get('title') title = request.form.get('title')
description = request.form.get('description') description = request.form.get('description')
file = request.files["file"] file = request.files["file"]

@ -1,7 +1,9 @@
from flask import Blueprint, render_template, send_from_directory from flask import Blueprint, render_template, send_from_directory
from flask import redirect, url_for from flask import redirect, url_for, flash, request
from flask_login import logout_user from flask_login import logout_user, current_user
from suchwowx.models import User, Remote
from suchwowx.factory import db
from suchwowx import config from suchwowx import config
@ -25,3 +27,39 @@ def about():
def disconnect(): def disconnect():
logout_user() logout_user()
return redirect(url_for('meme.index')) return redirect(url_for('meme.index'))
@bp.route('/remotes', methods=['GET', 'POST'])
def remotes():
if not current_user.is_authenticated or not current_user.is_moderator():
flash('You need to be moderator to access that page.', 'warning')
return redirect(url_for('meme.index'))
remotes = Remote.query.filter().order_by(Remote.create_date.asc())
ep = request.form.get('endpoint')
if ep:
if ep.startswith('http'):
if not Remote.query.filter(Remote.endpoint == ep).first():
r = Remote(endpoint=ep)
db.session.add(r)
db.session.commit()
flash('Added new remote server.', 'success')
else:
flash('That remote server already exists.', 'warning')
else:
flash('Incorrect endpoint provided, must start with http or https', 'warning') # noqa
return render_template('remotes.html', remotes=remotes)
@bp.route('/remotes/delete/<int:remote_id>')
def delete_remote(remote_id):
existing = Remote.query.get(remote_id)
if not current_user.is_authenticated or not current_user.is_moderator():
flash('You need to be moderator to access that page.', 'warning')
return redirect(url_for('meme.index'))
if not existing:
flash('That remote does not exist', 'warning')
return redirect(url_for('meme.mod'))
db.session.delete(existing)
db.session.commit()
flash(f'Deleted remote server {existing}', 'success')
return redirect(url_for('meta.remotes'))

@ -20,4 +20,11 @@
{% else %} {% else %}
<a class="button" href="{{ url_for('meme.index') }}" up-preload up-follow=".container">Go Home</a> <a class="button" href="{{ url_for('meme.index') }}" up-preload up-follow=".container">Go Home</a>
{% endif %} {% endif %}
{% if request.path == '/remotes' %}
<a class="button is-warning" href="{{ url_for('meme.mod') }}" up-preload up-follow=".container">Mod</a>
{% endif %}
{% if request.path == '/mod' %}
<a class="button is-warning" href="{{ url_for('meta.remotes') }}" up-preload up-follow=".container">Remotes</a>
{% endif %}
</div> </div>

@ -4,14 +4,9 @@
<body> <body>
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1 class="title"> {% include 'includes/navbar.html' %}
SuchWowX.
</h1>
<p class="subtitle">
Memes. <strong>Interplanetary</strong>!
</p>
<a class="button" href="{{ url_for('meme.index') }}" up-preload up-follow=".container">Go Back</a>
<div class="screen">
<form method="POST" enctype="multipart/form-data" class="site-form" id="memeUpload" action="{{ url_for('meme.publish') }}" style="padding-top:1.5em;"> <form method="POST" enctype="multipart/form-data" class="site-form" id="memeUpload" action="{{ url_for('meme.publish') }}" style="padding-top:1.5em;">
<div class="field"> <div class="field">
<label class="label">File</label> <label class="label">File</label>
@ -21,16 +16,16 @@
</div> </div>
<div class="field"> <div class="field">
<label class="label">Title</label> <label class="label">Poster Address</label>
<div class="control"> <div class="control">
<input class="input" type="text" placeholder="Title of your meme" name="title"> <p>{{ current_user.public_address }}</p>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Poster Address</label> <label class="label">Title</label>
<div class="control"> <div class="control">
<p>{{ current_user.public_address }}</p> <input class="input" type="text" placeholder="Title of your meme" name="title">
</div> </div>
</div> </div>
@ -56,7 +51,7 @@
</div> </div>
</div> </div>
</form> </form>
</div>
</div> </div>
</section> </section>
</body> </body>

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
{% include 'includes/head.html' %}
<body>
<section class="section">
<div class="container">
{% include 'includes/navbar.html' %}
<div class="screen">
<form method="POST" enctype="multipart/form-data" class="site-form" action="{{ url_for('meta.remotes') }}" style="padding-top:1.5em;">
<div class="field">
<label class="label">Remote Server</label>
<div class="control">
<input class="input" type="text" placeholder="https://suchwowx.xyz" name="endpoint">
</div>
</div>
<div class="field is-grouped">
<div class="control">
<button class="button is-primary">Submit</button>
</div>
</div>
</form>
{% if remotes %}
<hr>
{% for remote in remotes %}
<p>{{ remote.endpoint }} - last synced: {{ remote.last_sync_date | humanize }} <a href="{{ url_for('meta.delete_remote', remote_id=remote.id) }}">x</a></p>
{% endfor %}
{% endif %}
</div>
</div>
</section>
{% include 'includes/footer.html' %}
</body>
</html>
Loading…
Cancel
Save