En modern bloggplattform byggd med Flask för webbutveckling, programmering och livslångt lärande.

Python

Flask

License

📖 Om projektet

CuriousPaths är en fullfjädrad bloggplattform som kombinerar kraftfull funktionalitet med en clean, användarvänlig design. Projektet utvecklades för att skapa en personlig kunskapsplattform för att dela tutorials, guider och insikter inom webbutveckling och programmering.

✨ Huvudfunktioner

Content Management

  • 📝 Blogg med rich text-editor (Quill.js)
  • 🎨 Kategorier & taggar för organisering av innehåll
  • ⚡ Snabbskapa kategori/tagg - Skapa nya kategorier och taggar direkt i blogginläggsformuläret, utan att lämna sidan
  • 💬 Kommentarssystem med godkännandefunktion
  • 🖼️ Media-bibliotek med bildhantering och återanvändning
  • 📋 Post-versionshantering - "Senast uppdaterad" visas automatiskt
  • 📅 Backdating & schemaläggning - Ange valfritt publiceringsdatum (bakåt eller framåt), inlägget blir automatiskt synligt när datumet passeras

Säkerhet & Autentisering

  • 🔐 Komplett autentiseringssystem med rollbaserad åtkomstkontroll
  • ✉️ Email-verifiering - Kräver verifierad email för nya användare
  • 🔒 2FA (Two-Factor Authentication) - TOTP med Google Authenticator + backup-koder
  • ⏱️ Rate limiting - Skydd mot brute-force attacker
  • 🛡️ Starka lösenordskrav - Automatisk validering
  • 🔐 Security headers - CSP, XSS-Protection, CSRF-skydd

Funktionalitet

  • 🔍 Full-text sökning med filter på kategori och datum
  • 🔗 Related posts - Automatisk förslag baserat på kategori/taggar
  • 🏷️ Popular tags - Dynamisk taggmoln
  • ⏱️ Reading time - Automatisk beräkning av lästid
  • 📊 Admin-panel med statistik och bulk-åtgärder
  • 🎯 SEO-optimerad med meta tags, sitemap.xml och RSS-feed
  • 📱 Responsiv design med custom färgschema (orange/grön)
  • 🌍 Svensk tidszon - Automatisk konvertering (Europe/Stockholm)

🚀 Teknisk stack

Backend

  • Flask 3.0 - Webbramverk
  • SQLAlchemy 2.0 - ORM
  • Flask-Login - Sessionshantering
  • Flask-WTF - Formulärhantering och CSRF-skydd
  • Flask-Migrate - Databasmigrering (Alembic)
  • Flask-Limiter - Rate limiting
  • Flask-Mail - Email-funktionalitet
  • Pillow - Bildbehandling (WebP-komprimering)
  • pyotp - TOTP för 2FA
  • qrcode - QR-kodgenerering för 2FA setup
  • pytz - Timezone-hantering

Frontend

  • Bootstrap 5.3 - UI-ramverk
  • Quill.js - Rich text-editor
  • Bootstrap Icons - Ikonbibliotek
  • Custom CSS - Personligt färgschema

Databas

  • SQLite (development)
  • MySQL/MariaDB (production via PyMySQL)

📦 Installation

Förutsättningar

  • Python 3.13+
  • pip
  • virtualenv (rekommenderas)

Steg-för-steg

  1. Klona repository
git clone https://github.com/Majsan-T/curiouspaths.git
cd curiouspaths


  1. Skapa virtuell miljö
python -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate     # Windows


  1. Installera dependencies
pip install -r requirements.txt


  1. Konfigurera environment variables
cp .env.example .env
# Redigera .env med dina värden


Viktiga environment variables:

FLASK_ENV=development
SECRET_KEY=din-super-hemliga-nyckel-här

# Email (för verifiering och notifications)
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=din-email@gmail.com
MAIL_PASSWORD=ditt-app-lösenord

# Production Database (MySQL)
PROD_DATABASE_URL=mysql+pymysql://user:pass@localhost/dbname


  1. Initiera databas
flask db upgrade


  1. Seed initial data
flask seed-categories
flask seed-tags
flask create-admin


  1. Starta utvecklingsserver
flask run


Öppna http://127.0.0.1:5000 i webbläsaren.


🎯 CLI-kommandon

Setup & Administration

# Skapa admin-användare
flask create-admin

# Skapa standardkategorier
flask seed-categories

# Skapa standardtaggar
flask seed-tags

# Publicera alla utkast
flask publish-all


Email Verification

# Verifiera alla befintliga användare (vid migrering)
flask verify-all-users


Post Management

# Nollställ "updated_at" för alla inlägg (vid migrering)
flask reset-updated-at


Admin-panel

Logga in med admin-kontot och navigera till /admin för att:

  • Hantera blogginlägg (skapa, redigera, radera)
  • Hantera kategorier och taggar
  • Moderera kommentarer
  • Hantera användare och roller
  • Se statistik och analytics
  • Administrera media-bibliotek

📂 Projektstruktur

CuriousPaths/
├── app/
│   ├── __init__.py           # App factory
│   ├── models.py             # Databasmodeller
│   ├── extensions.py         # Flask-extensions
│   ├── commands.py           # CLI-kommandon
│   ├── auth/                 # Autentisering & 2FA
│   │   ├── routes.py         # Login, register, 2FA
│   │   └── forms.py          # WTForms
│   ├── blog/                 # Bloggfunktionalitet
│   │   ├── routes.py         # CRUD för posts
│   │   └── forms.py          # Post-formulär
│   ├── admin/                # Admin-panel
│   │   ├── routes.py         # Admin-funktionalitet
│   │   └── forms.py          # Admin-formulär
│   ├── pages/                # Statiska sidor
│   ├── utils/                # Hjälpfunktioner
│   │   ├── filters.py        # Jinja2-filters
│   │   ├── image_utils.py    # Bildhantering
│   │   ├── seo.py            # SEO meta tags
│   │   ├── timezone.py       # Svensk tidszon
│   │   └── decorators.py     # Custom decorators
│   ├── templates/            # Jinja2-templates
│   │   ├── auth/             # Login, register, 2FA
│   │   ├── blog/             # Bloggvyer
│   │   ├── admin/            # Admin-vyer
│   │   └── email/            # Email-templates
│   └── static/               # CSS, JS, bilder
│       ├── css/
│       ├── js/
│       ├── images/
│       └── uploads/          # Uppladdade bilder
├── migrations/                # Databasmigrationer
├── instance/                  # Instansspecifik data
├── config.py                  # Konfiguration
├── run.py                     # Development entry point
├── wsgi.py                    # Production entry point (Passenger/WSGI)
├── .htaccess                  # Apache/Passenger config
├── requirements.txt           # Python-dependencies
├── .env.example                # Environment variables template
├── CHANGELOG.md                # Historik över ändringar
├── DEPLOYMENT.md               # Deployment-guide
├── PRODUCTION_CHECKLIST.md     # Pre/post deployment checklist
└── README.md                   # Denna fil


🔒 Säkerhetsfunktioner

Autentisering

  • Email-verifiering - Nya användare måste verifiera sin email innan inloggning
  • 2FA (TOTP) - Google Authenticator, Authy, Microsoft Authenticator
  • Backup-koder - 10 engångskoder om telefon förloras
  • Password hashing - Werkzeug PBKDF2
  • Session-säkerhet - HTTP-only cookies, SameSite

Skydd

  • Rate limitingLogin: 5 försök per 15 minuter
  • Registrering: 5 försök per timme
  • Password reset: 3 försök per timme
  • Starka lösenordskrav - Minst 8 tecken, stor/liten bokstav, siffror
  • Security headers - CSP, X-Frame-Options, XSS-Protection
  • CSRF-skydd - Flask-WTF CSRF-tokens på alla formulär

🌐 Deployment

Förberedelser för produktion

Se DEPLOYMENT.md för detaljerad deployment-guide till Oderland.

Snabbversion:

  1. Skapa MySQL-databas på Oderland
  2. Ladda upp filer via FTP/SFTP
  3. Konfigurera .env för produktion:
   FLASK_ENV=production
   SECRET_KEY=...
   PROD_DATABASE_URL=mysql+pymysql://...
   SESSION_COOKIE_SECURE=True


  1. Installera dependencies: pip install -r requirements.txt
  2. Kör migrations: flask db upgrade
  3. Skapa admin: flask create-admin
  4. Seed data: flask seed-categories && flask seed-tags
  5. Verifiera befintliga users: flask verify-all-users
  6. Aktivera HTTPS (Let's Encrypt via Oderland)
Viktigt att komma ihåg: Passenger på Oderland läser inte om ändrade .py- eller .html-filer automatiskt. Rör tmp/restart.txt efter varje uppladdning för att tvinga fram en omstart av processen.

Production Checklist

Se PRODUCTION_CHECKLIST.md för komplett checklista.


📊 SEO-funktioner

  • Meta tags - Open Graph, Twitter Cards
  • Sitemap.xml - Dynamisk sitemap med alla sidor
  • robots.txt - Sökmotorinstruktioner
  • RSS feed - /rss eller /feed
  • Kanoniska URLs - Förhindrar duplicate content
  • Structured data - Article metadata
  • Reading time - Estimerad lästid per artikel

🎨 Anpassning

Färgschema

Redigera app/static/css/style.css:

:root {
    --primary-color: #d4915c;      /* Orange/terrakotta */
    --secondary-color: #4a7c59;    /* Skogsgrön */
    --accent-warm: #e8a574;        /* Ljus orange */
    --accent-brown: #6d5843;       /* Mörkbrun */
    /* ... */
}


Logotyp och favicon

Lägg dina bilder i app/static/images/:

  • favicon.ico (16x16, 32x32)
  • favicon.png (192x192)
  • og-default.png (1200x630) - Open Graph default image

🔧 Konfiguration

Email-konfiguration

För Gmail med 2FA:

  1. Aktivera 2-Step Verification
  2. Generera App Password: https://myaccount.google.com/apppasswords
  3. Använd App Password i .env:
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=din-email@gmail.com
MAIL_PASSWORD=genererat-app-lösenord


2FA Setup

När en användare aktiverar 2FA:

  1. QR-kod genereras för scanning
  2. Användaren scannar med Authenticator-app
  3. Verifierar setup med 6-siffrig kod
  4. Får 10 backup-koder att spara
  5. Vid inloggning krävs nu 2FA-kod

🧪 Testing

# Kör tester (när test-suite är implementerad)
pytest

# Coverage report
pytest --cov=app

# Linting
flake8 app/

# Formatera kod
black app/


📈 Roadmap

✅ Version 1.0 (Släppt)

  • Bloggfunktionalitet med rich-text editor
  • Kategorier och taggar
  • Kommentarssystem
  • Media-bibliotek
  • Full-text search
  • Admin-panel
  • SEO-optimering
  • Email-verifiering
  • 2FA-autentisering (TOTP + backup-koder)
  • Post-versionshantering
  • Svensk tidszon-stöd
  • Automatisk schemaläggning av publiceringsdatum
  • Snabbskapa kategori/tagg i blogginläggsformuläret

🚧 Version 1.1 (Planerat)

  • Dark mode toggle
  • Newsletter-funktionalitet med prenumeration
  • Email-notifications för nya kommentarer
  • Avancerad analytics dashboard
  • Export av innehåll (Markdown, JSON)

🔮 Version 1.2 (Framtida)

  • Multi-språkstöd (i18n) - Svenska/Engelska
  • API-endpoints (RESTful API)
  • GraphQL-support
  • Real-time notifications
  • Advanced media management (video, PDF)
  • Comment threading (svar på kommentarer)

📋 Changelog

Se CHANGELOG.md för en historik över ändringar och buggfixar.


🤝 Bidra

Contributions är välkomna! Om du vill bidra:

  1. Forka projektet
  2. Skapa en feature branch (git checkout -b feature/AmazingFeature)
  3. Commit dina ändringar (git commit -m 'Add some AmazingFeature')
  4. Push till branchen (git push origin feature/AmazingFeature)
  5. Öppna en Pull Request

Utvecklingsguide

# Sätt upp development environment
pip install -r requirements.txt

# Skapa test-data
flask seed-categories
flask seed-tags

# Kör utvecklingsserver med auto-reload
flask run --debug


📝 Licens

Detta projekt är licensierat under MIT License - se LICENSE filen för detaljer.


👤 Författare

Maria Tingvall

🙏 Acknowledgments

  • Flask - Det fantastiska webbramverket
  • Bootstrap - UI-komponenter
  • Quill - Rich text-editor
  • Bootstrap Icons - Ikonbibliotek
  • PyOTP - TOTP-implementation för 2FA
  • Anthropic Claude - För hjälp med kodgranskning och optimering

📸 Screenshots

Startsida

Startsida

Blogginlägg med versionshantering

Blogginlägg

Admin-panel

Admin

Media-bibliotek

Media

2FA Setup

2FA


💡 Support

Om du har frågor eller stöter på problem:

  1. Kolla DEPLOYMENT.md för deployment-hjälp
  2. Kolla PRODUCTION_CHECKLIST.md för checklista
  3. Öppna ett Issue
  4. Kontakta via email: maria@tingvall.nu

🔐 Säkerhetsinformation

Om du upptäcker en säkerhetsrisk, vänligen:

  1. INTE öppna ett publikt issue
  2. Maila maria@tingvall.nu med detaljer
  3. Ge oss tid att fixa problemet innan offentliggörande