-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.js
123 lines (98 loc) · 3.47 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const express = require('express');
const axios = require('axios');
const dotenv = require('dotenv');
const ejs = require('ejs');
const path = require('path');
const compression = require('compression');
const morgan = require('morgan');
const NodeCache = require('node-cache');
dotenv.config();
const axiosInstance = axios.create({
baseURL: 'https://www.reddit.com/r/memes/',
headers: {
'User-Agent': process.env.REDDIT_USER_AGENT,
'Authorization': `Basic ${Buffer.from(`${process.env.REDDIT_CLIENT_ID}:${process.env.REDDIT_CLIENT_SECRET}`).toString('base64')}`
},
});
const cache = new NodeCache({ stdTTL: 600 }); // Cache for 10 minutes
const app = express();
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'templates'));
app.use(compression());
app.use(morgan('tiny'));
app.use(express.static('public', {
maxAge: '1d', // Set caching for 1 day
}));
const getMemesExactly = (memes, count) => {
const shuffled = memes.sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
};
app.get('/', (req, res) => {
res.render('index');
});
app.get('/docs', (req, res) => {
res.render('docs');
});
app.get('/give/:subreddit?/:count?', async (req, res) => {
let count = parseInt(req.params.count) || 1;
let subreddit = req.params.subreddit;
if (!isNaN(subreddit) && subreddit >= 1 && subreddit <= 100) {
count = subreddit;
subreddit = 'memes'; // Set to default subreddit
} else if (!subreddit) {
subreddit = 'memes'; // Default subreddit if none is provided
}
if (count < 1 || count > 100) {
return res.status(400).json({ error: 'Count must be between 1 and 100.' });
}
let memes = [];
let after = null;
// Loop to fetch memes until we reach the requested count
while (memes.length < count) {
try {
const response = await axiosInstance.get(`https://www.reddit.com/r/${subreddit}/hot.json`, {
params: {
limit: Math.min(count - memes.length, 100), // Limit to fetch only the remaining required memes
after: after
}
});
const posts = response.data.data.children;
const newMemes = posts.filter(post => post.data.url && /\.(jpg|jpeg|png|gif)$/.test(post.data.url));
if (newMemes.length === 0) {
break; // Exit if no more valid memes are found
}
memes = memes.concat(newMemes);
after = response.data.data.after;
if (!after) {
break; // Exit if there's no more data to fetch
}
} catch (error) {
console.error(`Error fetching memes from subreddit ${subreddit}:`, error);
return res.status(500).json({ error: `Failed to fetch memes from r/${subreddit}` });
}
}
// Cache the memes for future requests
cache.set('memes', memes);
// Ensure we return exactly the requested number of memes, or fewer if not available
const selectedMemes = getMemesExactly(memes, Math.min(count, memes.length));
return res.json({ count: selectedMemes.length, memes: selectedMemes.map(formatMemeResponse) });
});
// Function to format the meme response
const formatMemeResponse = (post) => {
const data = post.data; // Accessing the correct data
return {
postLink: `https://redd.it/${data.id}`,
subreddit: data.subreddit,
title: data.title,
url: data.url,
nsfw: data.over_18,
spoiler: data.spoiler,
author: data.author,
ups: data.ups,
};
};
// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});