reskinning for tubbycats

main
lza_menace 2 years ago
parent 7b50895212
commit fca8ed8176

@ -7,6 +7,7 @@ shell:
bash manage.sh shell
init:
mkdir -p data
.venv/bin/alembic upgrade head
dev:
@ -40,4 +41,4 @@ sync-remotes:
./manage.sh sync-remotes
kill:
pkill -e -f suchwowx
pkill -e -f tubbymemes

@ -1,6 +1,10 @@
# SuchWowX
# tubbymemes
This service is a continuation of SuchWow for the Wownero cryptocurrency project. It has been revamped to use Interplanetary Filesystem, server federation / content sharing, and optionally Avalanche network via a smart contract with some useful features (if you're into that). It's a decentralized application (dApp); it's preferred you run it locally and bootstrap the services on your own machine.
Meme site dedicated to the best project on the Etherium network ;)
https://tubbycats.xyz/about
Memes are backed by Interplanetary Filesystem, server federation / content sharing, and optionally Avalanche network via a smart contract with some useful features (if you're into that). It's a decentralized application (dApp); it's preferred you run it locally and bootstrap the services on your own machine.
## Setup
@ -18,6 +22,9 @@ I have provided a `Makefile` with some helpful stuff...make sure to install `mak
# install python virtual environment and install application dependencies
make setup
# setup secrets
cp env-example .env && vim .env
# install ipfs
sudo make install-ipfs
@ -64,7 +71,7 @@ openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
cp conf/nginx-ssl.conf /etc/nginx/conf.d/ssl.conf
# setup nginx site config from this repo
cp conf/nginx-site.conf /etc/nginx/sites-enabled/suchwowx.conf
cp conf/nginx-site.conf /etc/nginx/sites-enabled/tubbymemes.conf
# generate TLS certificates
service nginx stop
@ -82,24 +89,24 @@ systemctl daemon-reload
systemctl enable ipfs
systemctl start ipfs
# setup suchwowx service account and storage location
useradd -m suchwowx
mkdir -p /opt/suchwowx
# setup tubbymemes service account and storage location
useradd -m tubbymemes
mkdir -p /opt/tubbymemes
# setup suchwowx application
git clone https://github.com/lalanza808/suchwowx /opt/suchwowx
cp /opt/suchwowx/env-example /opt/suchwowx/.env
vim /opt/suchwowx/.env
chown -R suchwowx:suchwowx /opt/suchwowx
# setup tubbymemes application
git clone https://github.com/lalanza808/tubbymemes /opt/tubbymemes
cp /opt/tubbymemes/env-example /opt/tubbymemes/.env
vim /opt/tubbymemes/.env
chown -R tubbymemes:tubbymemes /opt/tubbymemes
# setup suchwowx service daemon
cp conf/suchwowx.service /etc/systemd/system/suchwowx.service
# setup tubbymemes service daemon
cp conf/tubbymemes.service /etc/systemd/system/tubbymemes.service
systemctl daemon-reload
systemctl enable suchwowx
systemctl start suchwowx
systemctl enable tubbymemes
systemctl start tubbymemes
# setup ongoing syncing with remote servers and Avalanche network
crontab -u suchwowx conf/crontab
crontab -u tubbymemes conf/crontab
```
At this point you should have Nginx web server running with TLS certificates generated with Letsencrypt/Certbot, Systemd services for IPFS daemon for serving files and Gunicorn for serving the Flask application.

@ -4,9 +4,9 @@ from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from suchwowx.factory import db
from suchwowx.models import *
from suchwowx import config as swx_config
from tubbymemes.factory import db
from tubbymemes.models import *
from tubbymemes import config as c
# this is the Alembic Config object, which provides
@ -15,7 +15,7 @@ config = context.config
# this will overwrite the ini-file sqlalchemy.url path
# with secrets from our .env file (pulled via config.py)
sqlalchemy_url = f'sqlite:///{swx_config.DATA_FOLDER}/sqlite.db'
sqlalchemy_url = f'sqlite:///{c.DATA_FOLDER}/sqlite.db'
config.set_main_option('sqlalchemy.url', sqlalchemy_url)
# Interpret the config file for Python logging.

@ -1,4 +1,4 @@
"""init suchwowx
"""init tubbymemes
Revision ID: 53c117fcef3f
Revises:

@ -1,5 +1,5 @@
# Sync with remote servers specified by operator
0 * * * * sh -c "cd /opt/suchwowx; ./manage.sh sync-remotes"
0 * * * * sh -c "cd /opt/tubbymemes; ./manage.sh sync-remotes"
# Sync with Avalanche blockchain to import minted memes
30 * * * * sh -c "cd /opt/suchwowx; ./manage.sh sync-avax"
30 * * * * sh -c "cd /opt/tubbymemes; ./manage.sh sync-avax"

@ -1,16 +1,16 @@
# Redirect inbound http to https
server {
listen 80;
server_name suchwowx.xyz;
return 301 https://suchwowx.xyz$request_uri;
server_name tubbymemes.xyz;
return 301 https://tubbymemes.xyz$request_uri;
}
# Load SSL configs and serve SSL site
server {
listen 443 ssl;
server_name suchwowx.xyz;
error_log /var/log/nginx/suchwowx.xyz-error.log warn;
access_log /var/log/nginx/suchwowx.xyz-access.log;
server_name tubbymemes.xyz;
error_log /var/log/nginx/tubbymemes.xyz-error.log warn;
access_log /var/log/nginx/tubbymemes.xyz-access.log;
client_body_in_file_only clean;
client_body_buffer_size 32K;
# set max upload size
@ -39,6 +39,6 @@ server {
}
include conf.d/ssl.conf;
ssl_certificate /etc/letsencrypt/live/suchwowx.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/suchwowx.xyz/privkey.pem;
ssl_certificate /etc/letsencrypt/live/tubbymemes.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tubbymemes.xyz/privkey.pem;
}

@ -1,24 +1,24 @@
[Unit]
Description=SuchWowX meme service
Documentation=https://suchwowx.xyz
Description=tubbymemes meme service
Documentation=https://tubbymemes.xyz
After=network.target
[Service]
PermissionsStartOnly = true
PIDFile = /opt/suchwowx/data/gunicorn/suchwowx.pid
User = suchwowx
Group = suchwowx
WorkingDirectory = /opt/suchwowx
ExecStartPre = /bin/mkdir -p /opt/suchwowx/data/gunicorn
ExecStartPre = /bin/chown -R suchwowx:suchwowx /opt/suchwowx/data/gunicorn
Environment = FLASK_APP=suchwowx/app.py
PIDFile = /opt/tubbymemes/data/gunicorn/tubbymemes.pid
User = tubbymemes
Group = tubbymemes
WorkingDirectory = /opt/tubbymemes
ExecStartPre = /bin/mkdir -p /opt/tubbymemes/data/gunicorn
ExecStartPre = /bin/chown -R tubbymemes:tubbymemes /opt/tubbymemes/data/gunicorn
Environment = FLASK_APP=tubbymemes/app.py
Environment = FLASK_SECRETS=config.py
Environment = FLASK_ENV=production
Environment = FLASK_DEBUG=0
ExecStart = /opt/suchwowx/.venv/bin/gunicorn --bind 127.0.0.1:4000 "suchwowx.app:app" --log-file /opt/suchwowx/data/gunicorn/gunicorn.log --pid /opt/suchwowx/data/gunicorn/suchwowx.pid --reload
ExecReload = /bin/kill -s HUP /opt/suchwowx/data/gunicorn/suchwowx.pid
ExecStop = /bin/kill -s TERM /opt/suchwowx/data/gunicorn/suchwowx.pid
ExecStopPost = /bin/rm -rf /opt/suchwowx/data/gunicorn/suchwowx.pid
ExecStart = /opt/tubbymemes/.venv/bin/gunicorn --bind 127.0.0.1:4000 "tubbymemes.app:app" --log-file /opt/tubbymemes/data/gunicorn/gunicorn.log --pid /opt/tubbymemes/data/gunicorn/tubbymemes.pid --reload
ExecReload = /bin/kill -s HUP /opt/tubbymemes/data/gunicorn/tubbymemes.pid
ExecStop = /bin/kill -s TERM /opt/tubbymemes/data/gunicorn/tubbymemes.pid
ExecStopPost = /bin/rm -rf /opt/tubbymemes/data/gunicorn/tubbymemes.pid
PrivateTmp = true
[Install]

@ -1,6 +1,6 @@
# Production env - delete this line and unused config
SECRET_KEY=vrBWMR2$nCdPuZ27
DATA_FOLDER=/opt/suchwowx/data
DATA_FOLDER=/opt/tubbymemes/data
SERVER_NAME=myservername.com
AVAX_RPC=https://api.avax.network/ext/bc/C/rpc
TESTNET=0
@ -8,5 +8,5 @@ WEB3_PROVIDER_URI=https://api.avax.network/ext/bc/C/rpc
# Test env - delete this line and unused config
SECRET_KEY=vrBWMR2$nCdPuZ27
DATA_FOLDER=/opt/suchwowx/data
DATA_FOLDER=/opt/tubbymemes/data
WEB3_PROVIDER_URI=https://api.avax-test.network/ext/bc/C/rpc

@ -1,7 +1,7 @@
#!/bin/bash
source .venv/bin/activate
export FLASK_APP=suchwowx/app.py
export FLASK_APP=tubbymemes/app.py
export FLASK_SECRETS=config.py
export FLASK_DEBUG=1
export FLASK_ENV=development
@ -18,7 +18,7 @@ then
pgrep -F $BASE/gunicorn.pid
if [[ $? != 0 ]]; then
gunicorn \
--bind 127.0.0.1:4000 "suchwowx.app:app" \
--bind 127.0.0.1:4000 "tubbymemes.app:app" \
--daemon \
--log-file $BASE/gunicorn.log \
--pid $BASE/gunicorn.pid \

@ -1,7 +1,7 @@
from logging.config import dictConfig
from suchwowx.factory import create_app
from suchwowx import config
from tubbymemes.factory import create_app
from tubbymemes import config
app = create_app()

@ -3,10 +3,10 @@ from flask import Blueprint
from secrets import token_urlsafe
from datetime import datetime
from suchwowx.factory import db
from suchwowx.helpers import get_eth_contract
from suchwowx.models import Meme, User, Remote
from suchwowx import config
from tubbymemes.factory import db
from tubbymemes.helpers import get_eth_contract
from tubbymemes.models import Meme, User, Remote
from tubbymemes import config
bp = Blueprint('cli', 'cli', cli_group=None)

@ -1,8 +1,8 @@
import click
from flask import Blueprint
from suchwowx.models import Moderator, User
from suchwowx.factory import db
from tubbymemes.models import Moderator, User
from tubbymemes.factory import db
bp = Blueprint('mod', 'mod')

@ -6,7 +6,7 @@ from flask_sqlalchemy import SQLAlchemy
from flask_mobility import Mobility
from web3 import Web3
from suchwowx import config
from tubbymemes import config
db = SQLAlchemy()
@ -39,14 +39,14 @@ def create_app():
@login_manager.user_loader
def load_user(user_id):
from suchwowx.models import User
from tubbymemes.models import User
user = User.query.get(user_id)
return user
with app.app_context():
from suchwowx import filters
from suchwowx.routes import api, meme, meta, user
from suchwowx.cli import mod, cli
from tubbymemes import filters
from tubbymemes.routes import api, meme, meta, user
from tubbymemes.cli import mod, cli
app.register_blueprint(filters.bp)
app.register_blueprint(api.bp)
app.register_blueprint(meme.bp)

@ -1,7 +1,7 @@
from flask import Blueprint
from arrow import get as arrow_get
from suchwowx import config
from tubbymemes import config
bp = Blueprint('filters', 'filters')

@ -1,15 +1,15 @@
import ipfsApi
from eth_account.messages import encode_defunct
from suchwowx.models import Meme
from suchwowx.factory import w3
from suchwowx import config
from tubbymemes.models import Meme
from tubbymemes.factory import w3
from tubbymemes import config
def get_eth_contract():
"""
Return a web3 contract object with the currently
deployed SuchWowX smart contract.
deployed tubbymemes smart contract.
"""
contract_abi = config.CONTRACT_ABI
contract_address = w3.toChecksumAddress(config.CONTRACT_ADDRESS)

@ -5,8 +5,8 @@ from flask import url_for
from flask_login import login_user
from sqlalchemy import inspect
from suchwowx.factory import db
from suchwowx import config
from tubbymemes.factory import db
from tubbymemes import config
def rand_id():

@ -3,9 +3,9 @@ from secrets import token_urlsafe
from flask import Blueprint, request, jsonify
from flask_login import current_user
from suchwowx.factory import db
from suchwowx.helpers import verify_signature
from suchwowx.models import User, Meme
from tubbymemes.factory import db
from tubbymemes.helpers import verify_signature
from tubbymemes.models import User, Meme
bp = Blueprint('api', 'api', url_prefix='/api/v1')

@ -7,10 +7,10 @@ from flask import redirect, flash, url_for
from flask_login import current_user
from web3 import Web3
from suchwowx.models import Meme
from suchwowx.helpers import upload_to_ipfs
from suchwowx.factory import db
from suchwowx import config
from tubbymemes.models import Meme
from tubbymemes.helpers import upload_to_ipfs
from tubbymemes.factory import db
from tubbymemes import config
bp = Blueprint('meme', 'meme')

@ -2,9 +2,9 @@ from flask import Blueprint, render_template, send_from_directory
from flask import redirect, url_for, flash, request
from flask_login import logout_user, current_user
from suchwowx.models import User, Remote
from suchwowx.factory import db
from suchwowx import config
from tubbymemes.models import User, Remote
from tubbymemes.factory import db
from tubbymemes import config
bp = Blueprint('meta', 'meta')

@ -1,7 +1,7 @@
from flask import Blueprint, render_template
from flask import redirect, url_for
from suchwowx.models import User
from tubbymemes.models import User
bp = Blueprint('user', 'user')

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@ -1,7 +1,7 @@
from huey import RedisHuey
from suchwowx.factory import create_app_huey
from suchwowx import config
from tubbymemes.factory import create_app_huey
from tubbymemes import config
huey = RedisHuey(

@ -12,7 +12,7 @@
Welcome. </br>
</br>
This service is a continuation of <a href="https://suchwow.xyz">SuchWow</a> for the <a href="https://wownero.org">Wownero</a> cryptocurrency project.
It has been revamped to use <a href="https://ipfs.io">Interplanetary Filesystem</a>, server federation / content sharing, and optionally <a href="https://www.avax.network/">Avalanche network</a> via a smart contract with some useful features (if you're into memes). It's a decentralized application (dApp); it's preferred you run it locally and bootstrap the services on your own machine. Here's the source code and instructions to run: <a href="https://github.com/lalanza808/suchwowx/" target="_blank">SuchWowX</a>
It has been revamped to use <a href="https://ipfs.io">Interplanetary Filesystem</a>, server federation / content sharing, and optionally <a href="https://www.avax.network/">Avalanche network</a> via a smart contract with some useful features (if you're into memes). It's a decentralized application (dApp); it's preferred you run it locally and bootstrap the services on your own machine. Here's the source code and instructions to run: <a href="https://github.com/lalanza808/tubbymemes/" target="_blank">tubbymemes</a>
</p>
</br>
<p>

@ -1,15 +1,15 @@
<head>
<title>SuchWowX Interplanetary Memes</title>
<title>tubbymemes Interplanetary Memes</title>
<meta property="og:description" content="Interplanetary meme platform powered by IPFS, Wownero, Avalanche, and degeneracy.">
<meta property="og:image" content="https://suchwowx.xyz/static/img/logo.png">
<meta property="og:title" content="SuchWowX">
<meta property="og:image" content="https://tubbymemes.xyz/static/img/logo.png">
<meta property="og:title" content="tubbymemes">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@lza_menace">
<meta name="twitter:title" content="SuchWowX">
<meta name="twitter:title" content="tubbymemes">
<meta name="twitter:description" content="Interplanetary meme platform powered by IPFS, Wownero, Avalanche, and degeneracy.">
<meta name="twitter:creator" content="@lza_menace">
<meta name="twitter:image" content="https://suchwowx.xyz/static/img/logo.png">
<meta name="twitter:domain" content="https://suchwowx.xyz">
<meta name="twitter:image" content="https://tubbymemes.xyz/static/img/logo.png">
<meta name="twitter:domain" content="https://tubbymemes.xyz">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/static/js/vendor/unpoly-2.5.0.min.js"></script>

@ -1,6 +1,6 @@
<div class="screen">
<h1 class="title">
SuchWowX.
tubbymemes.
</h1>
<p class="subtitle">
Memes. <strong>Interplanetary</strong>!

@ -80,7 +80,7 @@
nonce = data['nonce'];
})
const msg = 'Authentication request from SuchWowX app! Verifying message with nonce ' + nonce
const msg = 'Authentication request from tubbymemes app! Verifying message with nonce ' + nonce
const signedData = await window.ethereum.request({
method: 'personal_sign',
params: [msg, allAccounts[0]]

@ -122,7 +122,7 @@
</header>
<section class="modal-card-body">
<p>
Sending a tip via the <a href="{{ config.CONTRACT_ADDRESS | show_snowtrace }}" target="_blank">SuchWowX smart contract</a> will send a small amount to the
Sending a tip via the <a href="{{ config.CONTRACT_ADDRESS | show_snowtrace }}" target="_blank">tubbymemes smart contract</a> will send a small amount to the
publisher (the address that minted the meme) and the contract owner ({{ config.CONTRACT_OWNER }}), and the remainder is sent to the meme creator (whoever uploaded it). Everyone gets tipped for their contribution, but primarily the meme creator.
</p>
</br>

@ -11,7 +11,7 @@
<div class="field">
<label class="label">Remote Server</label>
<div class="control">
<input class="input" type="text" placeholder="https://suchwowx.xyz" name="endpoint">
<input class="input" type="text" placeholder="https://tubbymemes.xyz" name="endpoint">
</div>
</div>
<div class="field is-grouped">
Loading…
Cancel
Save