Compare commits
	
		
			2 Commits
		
	
	
		
			bfb1b8a21e
			...
			53cd3852aa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 53cd3852aa | |||
| f67f377be1 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -4,3 +4,4 @@ db.sqlite
 | 
			
		||||
flask_session
 | 
			
		||||
__pycache__
 | 
			
		||||
app.log
 | 
			
		||||
.vscode
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
#psycopg2-binary
 | 
			
		||||
psycopg2-binary
 | 
			
		||||
python-dotenv
 | 
			
		||||
flask-session
 | 
			
		||||
requests
 | 
			
		||||
 
 | 
			
		||||
@@ -20,10 +20,17 @@ log = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Create database instance
 | 
			
		||||
db = database.Database(db_name=env('DB_NAME', default='db.sqlite'))
 | 
			
		||||
db.execute('CREATE TABLE IF NOT EXISTS snake_scores (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, score INTEGER)')
 | 
			
		||||
db = database.Database(
 | 
			
		||||
    host=env('DB_HOST', default='localhost'),
 | 
			
		||||
    port=env('DB_PORT', default=5432),
 | 
			
		||||
    user=env('DB_USER', default='user'),
 | 
			
		||||
    password=env('DB_PASSWORD', default='password'),
 | 
			
		||||
    db_name=env('DB_NAME', default='db_name')
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
db.execute('CREATE TABLE IF NOT EXISTS snake_scores (id SERIAL PRIMARY KEY, name TEXT, score INTEGER)')
 | 
			
		||||
db.execute('''CREATE TABLE IF NOT EXISTS snake_tokens (
 | 
			
		||||
    id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
    id SERIAL PRIMARY KEY,
 | 
			
		||||
    token TEXT UNIQUE NOT NULL,
 | 
			
		||||
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
    ip TEXT UNIQUE NOT NULL
 | 
			
		||||
@@ -37,7 +44,7 @@ def valid_length(value, min_length=1, max_length=100):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def valid_score(score, game_token):
 | 
			
		||||
    start_time = db.execute('SELECT created_at FROM snake_tokens WHERE token = ?', (game_token,)).fetchone()
 | 
			
		||||
    start_time = db.execute('SELECT created_at FROM snake_tokens WHERE token = %s', (game_token,)).fetchone()
 | 
			
		||||
    if not start_time:
 | 
			
		||||
        log.error("Game token not found.")
 | 
			
		||||
        return False
 | 
			
		||||
@@ -59,7 +66,7 @@ def valid_score(score, game_token):
 | 
			
		||||
        return False
 | 
			
		||||
    
 | 
			
		||||
    # delete the token after score validation
 | 
			
		||||
    db.execute('DELETE FROM snake_tokens WHERE token = ?', (game_token,))
 | 
			
		||||
    db.execute('DELETE FROM snake_tokens WHERE token = %s', (game_token,))
 | 
			
		||||
    log.info(f"Score {score} validated successfully for token {game_token}.")
 | 
			
		||||
 | 
			
		||||
    return True
 | 
			
		||||
@@ -90,8 +97,8 @@ def submit_score():
 | 
			
		||||
        abort(400, "Score not vilid, so either you are trying to cheat the leaderboard or something is seriously wrong.")
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        db.execute('INSERT INTO snake_scores (name, score) VALUES (?, ?)', (name, int(score)))
 | 
			
		||||
        db.execute('DELETE FROM snake_tokens WHERE token = ?', (game_token,))
 | 
			
		||||
        db.execute('INSERT INTO snake_scores (name, score) VALUES (%s, %s)', (name, int(score)))
 | 
			
		||||
        db.execute('DELETE FROM snake_tokens WHERE token = %s', (game_token,))
 | 
			
		||||
        log.info(f"Score submitted: {name} - {score}")
 | 
			
		||||
        return redirect('/404')
 | 
			
		||||
    
 | 
			
		||||
@@ -106,13 +113,13 @@ def generate_start_token():
 | 
			
		||||
    token = urandom(16).hex()
 | 
			
		||||
    ip = request.headers.get('X-Forwarded-For', request.remote_addr)
 | 
			
		||||
 | 
			
		||||
    ip_token = db.execute('SELECT token FROM snake_tokens WHERE ip = ?', (ip,)).fetchone()
 | 
			
		||||
    ip_token = db.execute('SELECT token FROM snake_tokens WHERE ip = %s', (ip,)).fetchone()
 | 
			
		||||
    if ip_token:
 | 
			
		||||
        log.info(f"Token already exists for IP: {ip}, reusing token.")
 | 
			
		||||
        return ip_token[0]
 | 
			
		||||
 | 
			
		||||
    log.info(f"Generated start token: {token}")
 | 
			
		||||
    db.execute('INSERT INTO snake_tokens (token, ip) VALUES (?, ?)', (token, ip))
 | 
			
		||||
    db.execute('INSERT INTO snake_tokens (token, ip) VALUES (%s, %s)', (token, ip))
 | 
			
		||||
    return token
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +141,7 @@ def clear_old_tokens():
 | 
			
		||||
    while True:
 | 
			
		||||
        try:
 | 
			
		||||
            one_hour_ago = datetime.datetime.now() - datetime.timedelta(hours=1)
 | 
			
		||||
            db.execute('DELETE FROM snake_tokens WHERE created_at < ?', (one_hour_ago,))
 | 
			
		||||
            db.execute('DELETE FROM snake_tokens WHERE created_at < %s', (one_hour_ago,))
 | 
			
		||||
            log.info("Old tokens cleared.")
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            log.error(f"Error clearing old tokens: {e}")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,15 @@
 | 
			
		||||
# Imports
 | 
			
		||||
import sqlite3
 | 
			
		||||
import psycopg2
 | 
			
		||||
 | 
			
		||||
# Database class
 | 
			
		||||
class Database:
 | 
			
		||||
    def __init__(self, db_name='db.sqlite'):
 | 
			
		||||
        self.connection = sqlite3.connect(db_name, check_same_thread=False)
 | 
			
		||||
    def __init__(self, host, port, user, password, db_name):
 | 
			
		||||
        self.connection = psycopg2.connect(
 | 
			
		||||
            host=host,
 | 
			
		||||
            port=port,
 | 
			
		||||
            user=user,
 | 
			
		||||
            password=password,
 | 
			
		||||
            database=db_name
 | 
			
		||||
        )
 | 
			
		||||
        self.cursor = self.connection.cursor()
 | 
			
		||||
 | 
			
		||||
    def execute(self, query, params=None):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/8831.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/beeps.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/blinkiescafe.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 6.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/emmixis.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/insia.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/ne0nbandit.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/nekoweb.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/neocities.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/s1nez.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/thnlqd.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 965 B  | 
							
								
								
									
										
											BIN
										
									
								
								static/content/buttons/tuxedodragon.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 20 KiB  | 
| 
		 After Width: | Height: | Size: 4.4 MiB  | 
| 
		 After Width: | Height: | Size: 4.9 MiB  | 
| 
		 After Width: | Height: | Size: 5.1 MiB  | 
@@ -47,17 +47,18 @@
 | 
			
		||||
        <section id="buttons">
 | 
			
		||||
            <h1>BUTTONS</h1>
 | 
			
		||||
            <ul>
 | 
			
		||||
                <li><a href="https://dimden.dev/"><img src="https://dimden.dev/services/images/88x31.gif" alt="dimden"></a></li>
 | 
			
		||||
                <li><a href="https://ne0nbandit.neocities.org/"><img src="https://ne0nbandit.github.io/assets/img/btn/mine/nbbanner.png" alt="ne0nbandit"></a></li>
 | 
			
		||||
                <li><a href="https://thinliquid.dev"><img src="https://thinliquid.dev/thnlqd.png" alt="thinliquid"></a></li>
 | 
			
		||||
                <li><a href="https://nekoweb.org/"><img src="https://nekoweb.org/assets/buttons/button6.gif" alt="nekoweb"></a><!-- button by s1nez.nekoweb.org --></li>
 | 
			
		||||
                <li><a href="https://s1nez.nekoweb.org/"><img src="https://s1nez.nekoweb.org/BUTTON.gif" alt="s1nez"></a></li>
 | 
			
		||||
                <li><a href="https://beeps.website"><img src="https://beeps.website/assets/images/88x31-d.gif" alt="beeps"></a></li>
 | 
			
		||||
                <li><a href="https://itsnotstupid.com"><img src="https://itsnotstupid.com/pics/button1.gif" alt="itsnotstupid"></a></li>
 | 
			
		||||
                <li><a href='https://blinkies.cafe'><img src='https://blinkies.cafe/b/display/blinkiesCafe-badge.gif' alt='blinkies.cafe | make your own blinkies!'></a></li>
 | 
			
		||||
                <li><a href="https://eightyeightthirty.one"><img src="https://eightyeightthirty.one/88x31.png" alt="88x31"></a></li>
 | 
			
		||||
                <li><a href="https://neocities.org"><img src="https://cyber.dabamos.de/88x31/neocities-now.gif" alt="neocities"></a></li>
 | 
			
		||||
                <li><a href="https://tuxedodragon.art"><img src="https://tuxedodragon.art/tuxedodragon%2088x31.gif" alt="tuxedodragon"></a></li>
 | 
			
		||||
                <li><a href="https://emmixis.net/"><img src="/static/content/buttons/emmixis.gif" alt="emmixis"></a></li>
 | 
			
		||||
                <li><a href="https://dimden.dev/"><img src="https://dimden.dev/services/images/88x31.gif" alt="dimden"></a></li><!-- hotlink on purpose -->
 | 
			
		||||
                <li><a href="https://ne0nbandit.neocities.org/"><img src="/static/content/buttons/ne0nbandit.png" alt="ne0nbandit"></a></li>
 | 
			
		||||
                <li><a href="https://thinliquid.dev"><img src="/static/content/buttons/thnlqd.png" alt="thinliquid"></a></li>
 | 
			
		||||
                <li><a href="https://nekoweb.org/"><img src="/static/content/buttons/nekoweb.gif" alt="nekoweb"></a><!-- button by s1nez.nekoweb.org --></li>
 | 
			
		||||
                <li><a href="https://s1nez.nekoweb.org/"><img src="/static/content/buttons/s1nez.gif" alt="s1nez"></a></li>
 | 
			
		||||
                <li><a href="https://beeps.website"><img src="/static/content/buttons/beeps.gif" alt="beeps"></a></li>
 | 
			
		||||
                <li><a href="https://itsnotstupid.com"><img src="/static/content/buttons/insia.gif" alt="itsnotstupid"></a></li>
 | 
			
		||||
                <li><a href='https://blinkies.cafe'><img src='/static/content/buttons/blinkiescafe.gif' alt='blinkies.cafe | make your own blinkies!'></a></li>
 | 
			
		||||
                <li><a href="https://eightyeightthirty.one"><img src="/static/content/buttons/8831.png" alt="88x31"></a></li>
 | 
			
		||||
                <li><a href="https://neocities.org"><img src="/static/content/buttons/neocities.gif" alt="neocities"></a></li>
 | 
			
		||||
                <li><a href="https://tuxedodragon.art"><img src="/static/content/buttons/tuxedodragon.gif" alt="tuxedodragon"></a></li>
 | 
			
		||||
            </ul>
 | 
			
		||||
        </section>
 | 
			
		||||
        <section>
 | 
			
		||||
 
 | 
			
		||||
@@ -41,5 +41,11 @@ protogen v1.0, toaster v1.0
 | 
			
		||||
        <img src="/static/content/fur_meets/26-07-2025_critters_mk/PXL_20250726_155226274.jpg" alt="Critters MK">
 | 
			
		||||
        <img src="/static/content/fur_meets/26-07-2025_critters_mk/PXL_20250726_155434701.jpg" alt="Critters MK">
 | 
			
		||||
    </div>
 | 
			
		||||
    <h2 class="gallery-date">23rd Aug 2025</h2>
 | 
			
		||||
    <div class="gallery">
 | 
			
		||||
        <img src="/static/content/fur_meets/23-08-2025_critters_mk/PXL_20250823_130640362.jpg" alt="Critters MK">
 | 
			
		||||
        <img src="/static/content/fur_meets/23-08-2025_critters_mk/PXL_20250823_130648109.jpg" alt="Critters MK">
 | 
			
		||||
        <img src="/static/content/fur_meets/23-08-2025_critters_mk/PXL_20250823_130659800.jpg"" alt="Critters MK">
 | 
			
		||||
    </div>
 | 
			
		||||
</section>
 | 
			
		||||
{% endblock %}
 | 
			
		||||