Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

69 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ SocialBlog

A modern social blogging platform built with Flask

Write, share, and discover stories β€” complete with user profiles, profile pictures, comments, and likes.

Python Flask Bootstrap SQLite License

Features β€’ Security β€’ Demo β€’ Try it β€’ Getting Started β€’ Configuration β€’ Project Structure β€’ Roadmap

Open in GitHub Codespaces

SocialBlog banner

✨ Overview

SocialBlog is a full-featured, multi-user blogging web app. Users can sign up, personalize their profile with an avatar, publish posts, and engage with the community through comments and likes. It's built with a clean, blueprint-based Flask architecture and a responsive Bootstrap 5 interface.


🎬 Demo

SocialBlog demo β€” browse the feed, register, log in, upload an avatar, publish a post, like and comment

Full walkthrough: browse the feed, register, log in, personalize your profile with an avatar, publish a post, then like and comment.


πŸš€ Try it in your browser

Don't want to clone anything? Run the full app in the cloud with GitHub Codespaces β€” nothing to download or install:

Open in GitHub Codespaces

  1. Click the badge above (or Code β†’ Codespaces β†’ Create codespace on main).
  2. Wait ~1 minute while it installs dependencies and seeds demo content.
  3. The app starts automatically and a browser tab opens on port 5000 β€” sign up and start posting.

Pre-seeded with sample users, posts, comments, and likes. Comment & post moderation runs with the built-in offline screen, so it works with no API key.


πŸš€ Features

  • πŸ” Authentication β€” register, log in, and log out with securely hashed passwords (Werkzeug)
  • πŸ§‘β€πŸŽ¨ User profiles β€” upload a profile picture that's automatically resized (Pillow); supports JPG, JPEG, PNG, WebP, and GIF
  • ✍️ Blog posts β€” full create, read, update, and delete (CRUD), restricted to each post's author
  • πŸ’¬ Comments β€” any logged-in user can comment; a comment can be removed by its author or the post owner
  • πŸ›‘οΈ Comment & post moderation β€” every post and comment is screened for toxicity before it's published via Google's free Perspective API, with an offline fallback so it works with zero setup
  • ❀️ Likes β€” one-click toggle like/unlike per user, with a live like count
  • βš›οΈ React interactivity β€” polished React "islands" enhance the server-rendered pages: live toxicity preview as you type, async likes and comments (no page reload), and toast notifications
  • πŸ“„ Pagination β€” clean, paginated feeds on the home page and user pages
  • 🎨 Modern UI β€” responsive Bootstrap 5 design with a styled confirmation modal for deletes
  • 🧭 Custom error pages β€” friendly 403 and 404 screens
  • πŸ—ƒοΈ Migrations β€” schema managed with Flask-Migrate (Alembic)

πŸ› οΈ Tech Stack

Layer Technology
Backend Flask, Flask-SQLAlchemy, Flask-Login, Flask-Migrate
Frontend React 18 islands (Vite build) over Jinja2 + Bootstrap 5
Forms Flask-WTF, WTForms, email-validator
Images Pillow
Database SQLite (dev) / PostgreSQL (production on Render)
Auth Werkzeug password hashing, session-based login
Moderation Google Perspective API (with offline keyword fallback)

πŸ”’ Security

Safety is built in at every layer β€” essential for a multi-user social app:

  • πŸ›‘οΈ Toxicity moderation β€” every post and comment is screened for toxic or abusive language before it's saved (see the Content Moderation section below).
  • πŸ”‘ Hashed passwords β€” credentials are never stored in plain text (Werkzeug password hashing).
  • πŸ›‘οΈ CSRF protection β€” every form is guarded with Flask-WTF CSRF tokens.
  • πŸ” Authorization checks β€” only a post's author can edit or delete it, and a comment can be removed only by its author or the post owner (otherwise a 403).
  • πŸ—οΈ No insecure defaults β€” SECRET_KEY is required (the app refuses to start without it) and secrets load from a git-ignored .env, never committed.
  • 🧯 Fails safe β€” if the moderation API is unavailable a local screen still runs, and moderation errors never break posting or commenting.

πŸ›‘οΈ Content Moderation

Posts and comments are screened before they're saved, so toxic or abusive content never reaches the page.

  • Primary engine β€” Google Perspective API: each comment is scored for TOXICITY, SEVERE_TOXICITY, INSULT, PROFANITY, THREAT, and IDENTITY_ATTACK. If any score crosses its threshold, the comment is rejected with a friendly message.
  • Zero-config fallback: with no PERSPECTIVE_API_KEY set (or if the API is unreachable), a lightweight offline keyword screen keeps the app safe by default β€” the feature works the moment you clone the repo.
  • Fails open: an unexpected moderation error never blocks commenting.

Enable the full API with a free key:

export PERSPECTIVE_API_KEY="your-key"   # https://developers.perspectiveapi.com

Logic lives in socialblog/moderation.py; the tests mock the API so they run offline:

python -m unittest tests.test_moderation

βš›οΈ Frontend (React islands)

The pages are server-rendered with Jinja2 + Bootstrap, then progressively enhanced with small React 18 "islands" built by Vite. This keeps the app fast and SEO-friendly while adding a modern, app-like feel:

  • Live toxicity preview β€” as you type a post or comment, a debounced call to /api/moderate shows a real-time "Looks respectful βœ“" / "May be flagged ⚠" pill.
  • Async likes β€” like/unlike updates instantly without a page reload.
  • Async comments β€” comments post and appear in place, no reload.
  • Toast notifications β€” server flash messages and client actions surface as elegant toasts.

Each island mounts onto a data-island="…" element, so pages still work if JavaScript is disabled (forms fall back to normal submits). Flask injects the hashed bundle via a manifest (socialblog/vite.py).

Develop / rebuild the frontend:

cd frontend
npm install
npm run build      # outputs to socialblog/static/dist/ (committed so Render needs no Node)
npm run dev        # optional: Vite dev server with HMR

The built bundle in socialblog/static/dist/ is committed, so the deployed app (and Codespaces) serves it directly β€” no Node step required in production.


🏁 Getting Started

Prerequisites

  • Python 3.10 or newer
  • pip and venv

Installation

# 1. Clone the repository
git clone https://github.com/<your-username>/Social_Blog_Flask.git
cd Social_Blog_Flask

# 2. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

# 3. Install dependencies
pip install -r requirements.txt

# 4. Configure your environment (SECRET_KEY is required; auto-loaded from .env)
cp .env.example .env
python -c "import secrets; print(secrets.token_hex(32))"   # paste as SECRET_KEY in .env

# 5. Create the database tables
flask --app app.py db upgrade

# 6. Run the app
python app.py

Then open https://social-blog-dmrg.onrender.com/ in your browser. πŸŽ‰

πŸ’‘ macOS note: port 5000 is used by AirPlay Receiver. If the server won't start, disable it in System Settings β†’ General β†’ AirDrop & Handoff β†’ AirPlay Receiver, or run on another port with flask --app app.py run --port 5001.


βš™οΈ Configuration

Configuration is read from environment variables. A .env file at the project root is auto-loaded on startup (via python-dotenv), so the easiest setup is to copy the template and fill it in:

cp .env.example .env      # then edit .env
Variable Description Default
SECRET_KEY Flask secret key used for sessions & CSRF required (no default)
DATABASE_URL SQLAlchemy database URI sqlite:///socialblog/data.sqlite
PERSPECTIVE_API_KEY Google Perspective API key that enables toxicity moderation offline fallback if unset
MODERATION_OFFLINE_FALLBACK Set to 0 to disable the offline keyword screen 1 (enabled)

Generate a strong secret with:

python -c "import secrets; print(secrets.token_hex(32))"

πŸ”’ SECRET_KEY is required β€” the app refuses to start without it. Never commit your real .env.


🧭 Pages & Routes

Method Route Description
GET / Home feed (paginated posts)
GET /info About page
GET/POST /register Create an account
GET/POST /login Log in
GET /logout Log out
GET/POST /account Edit profile & upload picture
GET /<username> A user's posts
GET/POST /create Create a new post
GET /<int:id> View a post (likes & comments)
GET/POST /<int:id>/update Edit a post (author only)
POST /<int:id>/delete Delete a post (author only)
POST /<int:id>/like Like / unlike a post
POST /<int:id>/comment Add a comment
POST /comment/<int:id>/delete Delete a comment (author/owner)

πŸ“‚ Project Structure

Social_Blog_Flask/
β”œβ”€β”€ app.py                       # Application entry point
β”œβ”€β”€ requirements.txt             # Python dependencies
β”œβ”€β”€ migrations/                  # Alembic database migrations
β”œβ”€β”€ frontend/                    # React islands source (Vite)
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ vite.config.js
β”‚   └── src/                     # main.jsx + components (LikeButton, etc.)
β”œβ”€β”€ docs/screenshots/            # πŸ“Έ Put your README images here
└── socialblog/
    β”œβ”€β”€ __init__.py              # App setup, config & blueprint registration
    β”œβ”€β”€ models.py                # User, BlogPost, Comment, Like models
    β”œβ”€β”€ moderation.py            # Perspective API toxicity screening
    β”œβ”€β”€ vite.py                  # Injects the built React bundle into templates
    β”œβ”€β”€ core/                    # Home & info pages
    β”‚   └── views.py
    β”œβ”€β”€ users/                   # Auth, profiles & picture upload
    β”‚   β”œβ”€β”€ forms.py
    β”‚   β”œβ”€β”€ views.py
    β”‚   └── picture_handler.py
    β”œβ”€β”€ blog_posts/              # Posts, comments, likes & JSON API
    β”‚   β”œβ”€β”€ forms.py
    β”‚   β”œβ”€β”€ views.py
    β”‚   └── api.py
    β”œβ”€β”€ error_pages/             # 403 / 404 handlers
    β”‚   └── handlers.py
    β”œβ”€β”€ templates/               # Jinja2 templates (Bootstrap 5)
    └── static/
        β”œβ”€β”€ dist/                # Built React bundle (committed)
        └── profile_pics/        # Uploaded profile images

πŸ—ΊοΈ Roadmap

Ideas for future improvements:

  • Edit comments
  • Show who liked a post
  • Tags & categories for posts
  • Search and filtering
  • Rich-text / Markdown post editor
  • Email verification & password reset

🀝 Contributing

Contributions are welcome! Feel free to open an issue or submit a pull request.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

Distributed under the MIT License.


πŸ‘©β€πŸ’» Author

Tania Tatis

GitHub Β· LinkedIn

⭐️ If you like this project, consider giving it a star!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages