[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-79975":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":12,"contributorsCount":12,"subscribersCount":12,"size":12,"stars1d":12,"stars7d":12,"stars30d":13,"stars90d":12,"forks30d":12,"starsTrendScore":12,"compositeScore":12,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":14,"fork":14,"defaultBranch":15,"hasWiki":16,"hasPages":14,"topics":17,"createdAt":9,"pushedAt":9,"updatedAt":18,"readmeContent":19,"aiSummary":20,"trendingCount":12,"starSnapshotCount":12,"syncStatus":21,"lastSyncTime":22,"discoverSource":23},79975,"cms-image-gallery","ishant025\u002Fcms-image-gallery","ishant025","Content मंच — Cloud-based CMS Image\u002FGIF Gallery built with Flask, AWS S3, and Tailwind CSS",null,"Python",81,0,1,false,"main",true,[],"2026-06-12 02:03:56","\u003Cdiv align=\"center\">\n\n\u003Cimg src=\"static\u002Flogo.png\" alt=\"Content मंच\" width=\"180\"\u002F>\n\n# Content मंच\n\n### *Content को दें नई पहचान*\n\nA modern, cloud-powered Image & GIF Gallery — built with Flask, AWS S3, Neon PostgreSQL, and Tailwind CSS.\n\n\n### 🌐 [Live Demo → content-manch.onrender.com](https:\u002F\u002Fcontent-manch.onrender.com)\n\n[![Python](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPython-3.11-3776AB?style=flat&logo=python&logoColor=white)](https:\u002F\u002Fwww.python.org\u002F)\n[![Flask](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FFlask-3.0-000000?style=flat&logo=flask&logoColor=white)](https:\u002F\u002Fflask.palletsprojects.com\u002F)\n[![AWS S3](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAWS-S3-FF9900?style=flat&logo=amazonaws&logoColor=white)](https:\u002F\u002Faws.amazon.com\u002Fs3\u002F)\n[![Neon](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNeon-PostgreSQL-00E599?style=flat&logo=postgresql&logoColor=white)](https:\u002F\u002Fneon.tech\u002F)\n[![Tailwind CSS](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTailwind-3-06B6D4?style=flat&logo=tailwindcss&logoColor=white)](https:\u002F\u002Ftailwindcss.com\u002F)\n[![Render](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDeployed_on-Render-46E3B7?style=flat&logo=render&logoColor=white)](https:\u002F\u002Fcontent-manch.onrender.com)\n[![Tests](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTests-174%20passed-success?style=flat)](#testing)\n\n\u003C\u002Fdiv>\n\n---\n\n## ✨ Features\n\n### Core Features\n- 🔐 **Secure Authentication** — Sign up, log in, and log out with hashed passwords (Werkzeug + Flask-Login)\n- ☁️ **Cloud Storage** — Images uploaded directly to AWS S3 with public-read URLs\n- 🏷️ **Tag System** — Add up to 20 tags per image for easy discovery\n- 🔍 **Live Search** — Dynamic, case-insensitive partial tag search without page reloads\n- 👍 **Like \u002F Dislike** — One reaction per user per image with smart toggle logic\n- 🗑️ **Owner-Only Deletion** — Only the uploader can delete an image, with a confirmation modal\n- 👑 **Admin Role** — Admin can delete any user's image for moderation\n- 🌓 **Dark \u002F Light Mode** — Persistent theme toggle via `localStorage`\n- 📱 **Fully Responsive** — Pinterest-style masonry grid that adapts from mobile to desktop\n- ⚡ **Fast** — Search returns results in under 2 seconds for up to 10,000 records\n\n\n---\n\n## 🖼️ Screenshots\n\n\u003Cdiv align=\"center\">\n\n\u003Cimg width=\"1600\" height=\"850\" alt=\"IMG-20260519-WA0024\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fcf185f06-873a-424b-90ea-e73a5eae46d6\" \u002F>\n\u003Cimg width=\"1600\" height=\"843\" alt=\"IMG-20260519-WA0025\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F5efea754-1b73-4dad-bdec-9dee69246382\" \u002F>\n\u003Cimg width=\"1897\" height=\"866\" alt=\"Screenshot 2026-05-20 201632\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F956fdc7a-7eb5-4566-bf77-4d73aa826fd9\" \u002F>\n\u003Cimg width=\"1901\" height=\"871\" alt=\"Screenshot 2026-05-20 201602\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Ff4dc6134-3366-4e43-83a9-1fa0a555ef23\" \u002F>\n\n\u003C\u002Fdiv>\n\n---\n\n## 🛠️ Tech Stack\n\n| Layer | Technology |\n|---|---|\n| **Backend** | Python 3.11, Flask 3.0, SQLAlchemy 2.0 |\n| **Database** | Neon PostgreSQL (production) \u002F SQLite (local dev) |\n| **Storage** | Amazon AWS S3 (Boto3) |\n| **Auth** | Flask-Login + Werkzeug password hashing |\n| **Frontend** | HTML5, Tailwind CSS (CDN), Vanilla JavaScript |\n| **Hosting** | Render (Web Service) |\n| **Testing** | pytest, Hypothesis (property-based tests) |\n| **Production Server** | Gunicorn |\n\n---\n\n## 📋 Prerequisites\n\n- Python **3.10** or higher\n- An **AWS account** with an S3 bucket (configured for public read access)\n- An **IAM user** with `s3:PutObject`, `s3:DeleteObject`, `s3:GetObject` permissions\n- `pip3` (Python package manager)\n\n---\n\n## 🚀 Quick Start\n\n### 1. Clone the repository\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002FYOUR_USERNAME\u002Fcms-image-gallery.git\ncd cms-image-gallery\n```\n\n### 2. Install dependencies\n\n```bash\npip3 install -r requirements.txt\n```\n\n### 3. Configure environment variables\n\nCreate a `.env` file in the project root with the following keys:\n\n```bash\n# Flask secret key — generate with: python3 -c \"import secrets; print(secrets.token_hex(32))\"\nSECRET_KEY=your-secret-key\n\n# AWS S3 credentials\nAWS_ACCESS_KEY_ID=your-aws-access-key-id\nAWS_SECRET_ACCESS_KEY=your-aws-secret-access-key\nAWS_S3_BUCKET_NAME=your-bucket-name\nAWS_S3_REGION=us-east-1\n```\n\n| Variable | Description |\n|---|---|\n| `SECRET_KEY` | Flask session signing key — generate one with the command below |\n| `AWS_ACCESS_KEY_ID` | Your AWS IAM access key ID |\n| `AWS_SECRET_ACCESS_KEY` | Your AWS IAM secret access key |\n| `AWS_S3_BUCKET_NAME` | Name of your S3 bucket |\n| `AWS_S3_REGION` | AWS region (e.g. `us-east-1`) |\n\n**Generate a secret key:**\n```bash\npython3 -c \"import secrets; print(secrets.token_hex(32))\"\n```\n\n### 4. Run the application\n\n```bash\npython3 app.py\n```\n\n\nTo enable debug mode:\n```bash\nFLASK_DEBUG=1 python3 app.py\n```\n\n---\n\n## ☁️ AWS S3 Setup\n\n### Bucket configuration\n\n| Setting | Value |\n|---|---|\n| **Object Ownership** | ACLs enabled |\n| **Block Public Access** | Disabled (all 4 unchecked) |\n| **Versioning** | Disabled |\n| **Encryption** | SSE-S3 (default) |\n\n### Bucket policy\n\nAllow public read for uploaded images:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [{\n    \"Sid\": \"PublicReadGetObject\",\n    \"Effect\": \"Allow\",\n    \"Principal\": \"*\",\n    \"Action\": \"s3:GetObject\",\n    \"Resource\": \"arn:aws:s3:::YOUR_BUCKET_NAME\u002F*\"\n  }]\n}\n```\n\n### CORS configuration\n\n```json\n[{\n  \"AllowedHeaders\": [\"*\"],\n  \"AllowedMethods\": [\"GET\", \"PUT\", \"POST\", \"DELETE\"],\n  \"AllowedOrigins\": [\"*\"],\n  \"ExposeHeaders\": [\"ETag\"]\n}]\n```\n\n### IAM policy (for the app's access key)\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\"s3:PutObject\", \"s3:PutObjectAcl\", \"s3:GetObject\", \"s3:DeleteObject\"],\n      \"Resource\": \"arn:aws:s3:::YOUR_BUCKET_NAME\u002F*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"s3:ListBucket\",\n      \"Resource\": \"arn:aws:s3:::YOUR_BUCKET_NAME\"\n    }\n  ]\n}\n```\n\n---\n\n## 🧪 Testing\n\nRun the full test suite (174 tests covering services, routes, and edge cases):\n\n```bash\npython3 -m pytest -v\n```\n\nRun with coverage:\n```bash\npython3 -m pytest --cov=. --cov-report=html\n```\n\n### Test Coverage\n- **174 passing tests** with 100% pass rate\n- **Unit tests**: All backend services (bulk operations, filters, image processing, search, undo queue)\n- **Integration tests**: API routes, template integration, progressive loading\n- **Property-based tests**: Tag validation, upload handling, like\u002Fdislike logic\n- **End-to-end tests**: Complete user workflows and feature interactions\n\n---\n\n## 🌐 Deployment (Render + Neon)\n\nThis app is deployed on **Render** (hosting) + **Neon** (PostgreSQL database) + **AWS S3** (image storage).\n\n### Production setup:\n\n1. Push this repo to GitHub\n2. Create a free **Neon** project at [neon.tech](https:\u002F\u002Fneon.tech) → copy the pooled connection string\n3. Create a **Render Web Service** at [render.com](https:\u002F\u002Frender.com) → connect this repo\n4. Configure Render:\n   - **Build Command**: `pip install -r requirements.txt`\n   - **Start Command**: `gunicorn app:application --workers 1 --timeout 120`\n   - **Instance Type**: Free\n5. Add Environment Variables in Render:\n   - `DATABASE_URL` = your Neon connection string\n   - `SECRET_KEY` = a random 64-char hex string\n   - `AWS_ACCESS_KEY_ID` = your AWS key\n   - `AWS_SECRET_ACCESS_KEY` = your AWS secret\n   - `AWS_S3_BUCKET_NAME` = your bucket name\n   - `AWS_S3_REGION` = your bucket region\n   - `RENDER` = `1`\n6. Deploy — your app goes live in ~3 minutes\n\n\nOther supported platforms: **Railway**, **Fly.io**, **PythonAnywhere**, **AWS Elastic Beanstalk**\n\n---\n\n## 📁 Project Structure\n\n```\ncms-image-gallery\u002F\n├── app.py                      # Flask app factory + entry point\n├── models.py                   # SQLAlchemy models (User, Image, Tag, Likes)\n├── routes.py                   # All HTTP routes + API endpoints\n├── auth_service.py             # Registration + login\n├── upload_service.py           # File validation + S3 upload + tag parsing\n├── s3_service.py               # Boto3 S3 integration\n├── search_service.py           # Tag-based search + query builder\n├── like_service.py             # Like\u002Fdislike toggle logic\n├── delete_service.py           # Authorized deletion with cascade\n├── bulk_service.py             # Bulk delete and download operations\n├── filter_service.py           # Real-time image filter processing\n├── image_service.py            # Thumbnail generation and upload\n├── query_builder.py            # Advanced search query construction\n├── undo_queue.py               # Undo delete queue management\n├── templates\u002F                  # Jinja2 HTML templates\n│   ├── base.html               # Base template with mobile navigation\n│   ├── index.html              # Gallery homepage with all features\n│   ├── login.html\n│   ├── register.html\n│   ├── upload.html\n│   └── error.html\n├── static\u002F                     # Static assets\n│   ├── js\u002F\n│   │   ├── gallery.js          # Core gallery functionality\n│   │   ├── image-viewer.js     # Lightbox image viewer\n│   │   └── progressive-loading.js  # Blur-up image loading\n│   ├── css\u002F\n│   │   └── (Tailwind CSS via CDN)\n│   └── logo.png\n├── tests\u002F                      # pytest test suite (174 tests)\n│   ├── test_like.py            # Like\u002Fdislike tests\n│   ├── test_search.py          # Search and query builder tests\n│   ├── test_upload.py          # Upload validation tests\n│   ├── test_bulk_service.py    # Bulk operations tests\n│   ├── test_filter_service.py  # Image filter tests\n│   ├── test_image_service.py   # Thumbnail generation tests\n│   ├── test_undo_queue.py      # Undo queue tests\n│   ├── test_query_builder.py   # Advanced search tests\n│   └── test_progressive_loading*.py  # Progressive loading tests\n├── requirements.txt            # Python dependencies (pinned)\n├── Procfile                    # Production start command\n└── README.md\n```\n\n---\n\n## 🔒 Security Notes\n\n- ✅ Passwords are hashed using Werkzeug's `generate_password_hash` (PBKDF2-SHA256)\n- ✅ AWS credentials are loaded from environment variables only — **never hardcoded**\n- ✅ `.env` is excluded from version control via `.gitignore`\n- ✅ Owner-only authorization on all destructive operations\n- ✅ Generic error messages on login to prevent user enumeration\n- ✅ Unique S3 keys (UUID-based) prevent overwrite attacks\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Please:\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature\u002Famazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature\u002Famazing-feature`)\n5. Open a Pull Request\n\n---\n\n## 👥 Contributors\n\n\u003Ctable>\n  \u003Ctr>\n    \u003Ctd align=\"center\">\n      \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fishant025\">\n        \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fishant025.png\" width=\"80\" style=\"border-radius:50%;\" alt=\"Ishant Sahu\"\u002F>\u003Cbr\u002F>\n        \u003Csub>\u003Cb>Ishant Sahu\u003C\u002Fb>\u003C\u002Fsub>\n      \u003C\u002Fa>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\">\n      \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Frootmelody\">\n        \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Frootmelody.png\" width=\"80\" style=\"border-radius:50%;\" alt=\"Nitin Nirmalkar\"\u002F>\u003Cbr\u002F>\n        \u003Csub>\u003Cb>Nitin Nirmalkar\u003C\u002Fb>\u003C\u002Fsub>\n      \u003C\u002Fa>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\">\n      \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FRAKESH-PARATE\">\n        \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002FRAKESH-PARATE.png\" width=\"80\" style=\"border-radius:50%;\" alt=\"Rakesh Parate\"\u002F>\u003Cbr\u002F>\n        \u003Csub>\u003Cb>Rakesh Parate\u003C\u002Fb>\u003C\u002Fsub>\n      \u003C\u002Fa>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\">\n      \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fsageverse-tech\">\n        \u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fsageverse-tech.png\" width=\"80\" style=\"border-radius:50%;\" alt=\"Khushraj Varghat\"\u002F>\u003Cbr\u002F>\n        \u003Csub>\u003Cb>Khushraj Varghat\u003C\u002Fb>\u003C\u002Fsub>\n      \u003C\u002Fa>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n---\n\n\n\n## 🙏 Acknowledgements\n\n- Built as a Cloud Computing college project\n- Logo represents a **lotus** (creativity) opening into a **book** (content)\n- Color palette inspired by traditional Indian aesthetics\n\n---\n\n\u003Cdiv align=\"center\">\n\n### Made with ❤️ for the love of content \n\n⭐ **Star this repo if you found it useful!**\n\n\u003C\u002Fdiv>\n","Content मंच 是一个基于云端的内容管理系统，特别设计用于管理和展示图片及GIF。它利用Flask框架构建后端逻辑，通过AWS S3存储用户上传的媒体文件，并采用Tailwind CSS来保证前端界面美观且响应式。该项目支持安全认证、云存储、标签系统、实时搜索等功能，同时提供点赞\u002F点踩互动机制以及管理员权限控制等特性。适用于需要高效组织和分享大量视觉内容的个人或团队，如摄影师的作品集网站、小型企业的在线商品目录等场景。",2,"2026-06-11 03:58:46","CREATED_QUERY"]