CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
post.js288 linesDownload Raw Back to models
1const { MongoClient, ObjectId } = require('mongodb');2require('dotenv').config();3 4// MongoDB connection5const MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost:27017';6const DB_NAME = 'social_media_db';7const COLLECTION_NAME = 'posts';8const COMMENTS_COLLECTION = 'comments';9const SAVES_COLLECTION = 'saved_posts';10const SHARES_COLLECTION = 'shares';11 12let client = null;13let db = null;14let collection = null;15let commentsCollection = null;16let savesCollection = null;17let sharesCollection = null;18 19// Initialize MongoDB connection20async function initMongoDB() {21    if (client && client.topology && client.topology.isConnected()) {22        return collection;23    }24 25    try {26        client = new MongoClient(MONGO_URI);27        await client.connect();28        console.log('✓ Connected to MongoDB');29 30        db = client.db(DB_NAME);31        collection = db.collection(COLLECTION_NAME);32        commentsCollection = db.collection(COMMENTS_COLLECTION);33        savesCollection = db.collection(SAVES_COLLECTION);34        sharesCollection = db.collection(SHARES_COLLECTION);35 36        // Create indexes on post_id37        await collection.createIndex({ post_id: 1 }, { unique: true });38        await commentsCollection.createIndex({ post_id: 1 });39        await commentsCollection.createIndex({ user_id: 1 });40        await commentsCollection.createIndex({ created_at: -1 });41        await savesCollection.createIndex({ post_id: 1 });42        await savesCollection.createIndex({ user_id: 1 });43        await savesCollection.createIndex({ user_id: 1, saved_at: -1 });44        await savesCollection.createIndex({ user_id: 1, post_id: 1 }, { unique: true });45        await sharesCollection.createIndex({ post_id: 1 });46        await sharesCollection.createIndex({ shared_by: 1 });47        await sharesCollection.createIndex({ shared_by: 1, shared_at: -1 });48 49        return collection;50    } catch (error) {51        console.error('MongoDB connection error:', error);52        throw error;53    }54}55 56// Post class with static methods57class Post {58    static async getCollection() {59        if (!collection) {60            await initMongoDB();61        }62        return collection;63    }64 65    static async getAllPosts() {66        const coll = await this.getCollection();67        const posts = await coll.find({}).sort({ created_at: -1 }).toArray();68        return posts;69    }70 71    static async getPost(postId) {72        const coll = await this.getCollection();73        const post = await coll.findOne({ post_id: postId });74        return post;75    }76 77    static async createPost({ post_id, name, caption, media_url, media_type = 'image', category = 'unknown' }) {78        const coll = await this.getCollection();79 80        const postDoc = {81            post_id,82            name,83            caption,84            media_url,85            media_type,86            category,87            created_at: new Date(),88            updated_at: new Date()89        };90 91        const result = await coll.insertOne(postDoc);92        return { ...postDoc, _id: result.insertedId };93    }94 95    static async updatePost(postId, updateData) {96        const coll = await this.getCollection();97 98        const result = await coll.updateOne(99            { post_id: postId },100            {101                $set: {102                    ...updateData,103                    updated_at: new Date()104                }105            }106        );107 108        if (result.matchedCount === 0) {109            return null;110        }111 112        return await this.getPost(postId);113    }114 115    static async deletePost(postId) {116        const coll = await this.getCollection();117        const result = await coll.deleteOne({ post_id: postId });118        return result.deletedCount > 0;119    }120 121    static async searchPosts(query) {122        const coll = await this.getCollection();123        const posts = await coll.find({124            $or: [125                { name: { $regex: query, $options: 'i' } },126                { caption: { $regex: query, $options: 'i' } }127            ]128        }).toArray();129        return posts;130    }131 132    static async getPostCount() {133        const coll = await this.getCollection();134        return await coll.countDocuments();135    }136 137    static async syncMissingCategories(mapping) {138        const coll = await this.getCollection();139        console.log('Syncing categories in MongoDB...');140        for (const [postId, category] of Object.entries(mapping)) {141            await coll.updateOne(142                { post_id: postId, category: { $exists: false } },143                { $set: { category: category } }144            );145            // Also update "unknown" categories146            await coll.updateOne(147                { post_id: postId, category: "unknown" },148                { $set: { category: category } }149            );150        }151        console.log('✓ Category sync complete');152    }153 154    // ===== COMMENTS METHODS =====155    static async addComment(postId, userId, commentText) {156        await this.getCollection(); // Ensure DB is initialized157        const comment = {158            _id: new ObjectId(),159            post_id: postId,160            user_id: userId,161            text: commentText,162            created_at: new Date(),163            likes: 0164        };165        await commentsCollection.insertOne(comment);166        return comment;167    }168 169    static async getComments(postId) {170        await this.getCollection();171        return await commentsCollection.find({ post_id: postId })172            .sort({ created_at: -1 })173            .toArray();174    }175 176    static async deleteComment(commentId) {177        await this.getCollection();178        const result = await commentsCollection.deleteOne({ _id: new ObjectId(commentId) });179        return result.deletedCount > 0;180    }181 182    static async getCommentCount(postId) {183        await this.getCollection();184        return await commentsCollection.countDocuments({ post_id: postId });185    }186 187    // ===== SAVES METHODS =====188    static async savePost(postId, userId) {189        await this.getCollection();190        const savedPost = {191            _id: new ObjectId(),192            post_id: postId,193            user_id: userId,194            saved_at: new Date()195        };196        await savesCollection.insertOne(savedPost);197        return savedPost;198    }199 200    static async removeSavedPost(postId, userId) {201        await this.getCollection();202        const result = await savesCollection.deleteOne({203            post_id: postId,204            user_id: userId205        });206        return result.deletedCount > 0;207    }208 209    static async getSavedPosts(userId) {210        await this.getCollection();211        const saved = await savesCollection.find({ user_id: userId })212            .sort({ saved_at: -1 })213            .toArray();214 215        if (!saved.length) return [];216 217        const postIds = saved.map((item) => item.post_id);218        const posts = await collection219            .find({ post_id: { $in: postIds } })220            .toArray();221 222        const postMap = new Map(posts.map((post) => [post.post_id, post]));223        return saved224            .map((savedItem) => {225                const post = postMap.get(savedItem.post_id);226                return post ? { ...post, saved_at: savedItem.saved_at } : null;227            })228            .filter(Boolean);229    }230 231    static async isPostSaved(postId, userId) {232        await this.getCollection();233        const saved = await savesCollection.findOne({234            post_id: postId,235            user_id: userId236        });237        return !!saved;238    }239 240    static async getSaveCount(postId) {241        await this.getCollection();242        return await savesCollection.countDocuments({ post_id: postId });243    }244 245    // ===== SHARES METHODS =====246    static async sharePost(postId, sharedBy, platform = 'direct') {247        await this.getCollection();248        const share = {249            _id: new ObjectId(),250            post_id: postId,251            shared_by: sharedBy,252            platform: platform,253            shared_at: new Date()254        };255        await sharesCollection.insertOne(share);256        return share;257    }258 259    static async getShares(postId) {260        await this.getCollection();261        return await sharesCollection.find({ post_id: postId })262            .sort({ shared_at: -1 })263            .toArray();264    }265 266    static async getShareCount(postId) {267        await this.getCollection();268        return await sharesCollection.countDocuments({ post_id: postId });269    }270 271    static async getUserShares(userId) {272        await this.getCollection();273        return await sharesCollection.find({ shared_by: userId })274            .sort({ shared_at: -1 })275            .toArray();276    }277}278 279// Graceful shutdown280process.on('SIGINT', async () => {281    if (client) {282        await client.close();283        console.log('MongoDB connection closed');284    }285    process.exit(0);286});287 288module.exports = Post;