├── .replit
├── static
└── star.png
├── .github
└── ISSUE_TEMPLATE
│ └── suggest-a-badge.md
├── package.json
├── LICENSE
├── .gitignore
├── README.md
├── memes.json
└── index.js
/.replit:
--------------------------------------------------------------------------------
1 | language = "nodejs"
2 | run = "node index.js"
--------------------------------------------------------------------------------
/static/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jaysmito101/dynamic-badges/HEAD/static/star.png
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/suggest-a-badge.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Suggest A Badge
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dynamic-badges",
3 | "version": "1.0.0",
4 | "description": "A bunch of dynamic cool badges for your GitHub profile and Readmes!",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/Jaysmito101/dynamic-badges.git"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "bugs": {
17 | "url": "https://github.com/Jaysmito101/dynamic-badges/issues"
18 | },
19 | "homepage": "https://github.com/Jaysmito101/dynamic-badges#readme",
20 | "dependencies": {
21 | "@replit/database": "^2.0.1",
22 | "cookie-parser": "^1.4.6",
23 | "express": "^4.19.2",
24 | "node-fetch": "^2.6.7",
25 | "sanitize": "^2.1.0",
26 | "validator": ">=13.7.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Jaysmito Mukherjee
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Badges
2 | A bunch of dynamic cool badges for your GitHub profile and Readmes!
3 |
4 | # Suggest A Badge
5 |
6 | [Suggest](https://github.com/Jaysmito101/dynamic-badges/issues/new/choose)
7 |
8 | ## Have an idea?
9 | Lets discuss : https://discord.gg/zdaCYfzFsZ
10 |
11 | # Star Rating Widget
12 |
13 | The Rating Input:
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | The Rating Display:
22 |
23 | 
24 |
25 | How to use:
26 |
27 | The Rating Input:
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | The Rating Display:
36 |
37 | 
38 |
39 | Optional Parameter : `tourl=http:\\google.com`
40 |
41 | How it works:
42 |
43 | Each star is a link which collects the rating. Also 1 person can rate only once in 1 hour to prevent spam.
44 |
45 | # View Badge
46 | This is a view counter badge!
47 |
48 | 
49 |
50 | How to use:
51 |
52 | 
53 |
54 | # Random Programming Meme
55 |
56 |
57 |
58 | How to use:
59 |
60 |
61 |
62 | # Github Trophy
63 |
64 | 
65 |
66 | How to use:
67 |
68 | 
69 |
70 | The score is calculated based on youe github profile!
71 |
72 | # Age Badge
73 |
74 | 
75 |
76 | How to use:
77 |
78 | 
79 |
80 | Parameters :
81 |
82 | color
83 | style
84 |
85 | # Animated SVG Text
86 |
87 | 
88 |
89 | How to use:
90 |
91 | 
92 |
93 | Parameters :
94 |
95 | duration
96 | font
97 | fontSize
98 | repeatCount
99 | color
100 | text
101 |
102 |
--------------------------------------------------------------------------------
/memes.json:
--------------------------------------------------------------------------------
1 | [
2 | "https://i.ibb.co/P6r7Nfb/7hax0aqh8r981.webp",
3 | "https://i.ibb.co/NSR59Pc/8y75uqg8rz981.webp",
4 | "https://i.ibb.co/YDgF1Gp/9hmvfy8plp981.webp",
5 | "https://i.ibb.co/4Vwdnt6/9t7qfs0gfx981.webp",
6 | "https://i.ibb.co/HH3N4nq/26ju25sgqt981.jpg",
7 | "https://i.ibb.co/Gv9gmKs/26o9hx46zr981.webp",
8 | "https://i.ibb.co/B6pVffL/71gtw2f6at981.webp",
9 | "https://i.ibb.co/DLqGsmT/966ye5vrqo981.jpg",
10 | "https://i.ibb.co/4Fxbmzg/accdbfn47q981.png",
11 | "https://i.ibb.co/m6ybyj2/ahoq4blc4s981.webp",
12 | "https://i.ibb.co/4W80V5s/bkza8erwmp981.webp",
13 | "https://i.ibb.co/48WdtvR/bl223easpx981.webp",
14 | "https://i.ibb.co/2sFS9my/chyvd0mhov981.webp",
15 | "https://i.ibb.co/WgC2BpW/cuhw65bdfy981.jpg",
16 | "https://i.ibb.co/mb4T4Yp/cw38udmxp0a81.webp",
17 | "https://i.ibb.co/smp0GbY/dhutuu1kfj981.jpg",
18 | "https://i.ibb.co/W06qsNc/drta72guzq981.jpg",
19 | "https://i.ibb.co/dcz078s/dthvulvxgp981.webp",
20 | "https://i.ibb.co/q00shR0/e9uxaeokfx981.webp",
21 | "https://i.ibb.co/LgvsrLy/ed7y67jcjq981.jpg",
22 | "https://i.ibb.co/tHcWCfp/ep4euxfl9w981.webp",
23 | "https://i.ibb.co/4RNrbdJ/fa1g0bsb0n981.webp",
24 | "https://i.ibb.co/X8L5SKd/fberoa1j8p981.webp",
25 | "https://i.ibb.co/n7bZkDd/fbi10wuzkp981.jpg",
26 | "https://i.ibb.co/b23T5Yk/hdubvkydqz981.png",
27 | "https://i.ibb.co/n1T41yp/hx67qwm2js981.png",
28 | "https://i.ibb.co/W3Wck7G/i2tupn6kwz981.webp",
29 | "https://i.ibb.co/MCRGsHR/irpntlxizt981.webp",
30 | "https://i.ibb.co/315wjhL/iwvub9jd0r981.png",
31 | "https://i.ibb.co/LknQXZQ/jeh4gs5mjw981.jpg",
32 | "https://i.ibb.co/98Vx59N/khabso7k1y981.png",
33 | "https://i.ibb.co/ZzpfFG8/kn3i59a4bu981.webp",
34 | "https://i.ibb.co/fXWH8d9/ky0osos0pq981.webp",
35 | "https://i.ibb.co/XYBfvWQ/l2ay0poyow981.jpg",
36 | "https://i.ibb.co/zxW965n/l2pam8x78y981.jpg",
37 | "https://i.ibb.co/SKpghDJ/lva5kstsvv981.webp",
38 | "https://i.ibb.co/pWCzXDr/m9zcak036q981.webp",
39 | "https://i.ibb.co/hfJBw8L/mrfohglejw981.webp",
40 | "https://i.ibb.co/5xKH7Zh/nkw9vm96bz981.webp",
41 | "https://i.ibb.co/s2ZP0g1/o2j0tixlrz981.webp",
42 | "https://i.ibb.co/QN1WDVB/ogntqxvp5p981.jpg",
43 | "https://i.ibb.co/3d6Fp6Q/omt8mfp8ry981.png",
44 | "https://i.ibb.co/8MvcLFC/p71g6refuo981.webp",
45 | "https://i.ibb.co/dfZgkYZ/pof99gsjis981.webp",
46 | "https://i.ibb.co/bFvBxzz/qjxl6t44ir981.webp",
47 | "https://i.ibb.co/VmTkCQZ/rgh7bg6umo981.webp",
48 | "https://i.ibb.co/9vFCdBm/rwi9uqryto981.jpg",
49 | "https://i.ibb.co/4NFTVG0/s77nf6k3dn981.jpg",
50 | "https://i.ibb.co/L0SH0ZC/sdtwoulk0r981.webp",
51 | "https://i.ibb.co/kJzzw0C/sp3bpzyjtx981.png",
52 | "https://i.ibb.co/T8Dz3Ms/syfbmwok3x981.webp",
53 | "https://i.ibb.co/1shzn1g/t8fjkbunop981.webp",
54 | "https://i.ibb.co/kGMVznC/tfw56cbuwn981.webp",
55 | "https://i.ibb.co/zVG2VJd/tm41l6bdzy981.jpg",
56 | "https://i.ibb.co/FHPDPSs/tossa5g1q0a81.jpg",
57 | "https://i.ibb.co/MstjqNp/u46fh5ip3z981.webp",
58 | "https://i.ibb.co/Kw4sZyc/uucdncrb2n981.webp",
59 | "https://i.ibb.co/RchbrNT/v17o87m04t981.webp",
60 | "https://i.ibb.co/dbJBsYd/v49rsvdjhy981.webp",
61 | "https://i.ibb.co/hWWt9X0/vbr0edupjp981.webp",
62 | "https://i.ibb.co/dQqZhmd/vdzgxjs8ix981.webp",
63 | "https://i.ibb.co/tC22Pq4/viv8td1cxw981.webp",
64 | "https://i.ibb.co/HDygbL4/vylh76eitq981.webp",
65 | "https://i.ibb.co/g9ndGTr/w3zdcjicpn981.jpg",
66 | "https://i.ibb.co/Mf8NRkp/wa2okzgzuz981.webp",
67 | "https://i.ibb.co/12cqzqK/wpn6s6gojw981.webp",
68 | "https://i.ibb.co/P9bJK4G/xmtc0wnl4t981.webp",
69 | "https://i.ibb.co/ZHmyvsr/z7osoan1kq981.webp",
70 | "https://i.ibb.co/9Y6HFrB/zkuyr93o6t981.webp",
71 | "https://i.ibb.co/mNW7p7h/zr9g4300av981.webp",
72 | "https://i.ibb.co/c6jVBRz/zrp0875mpo981.webp",
73 | "https://i.ibb.co/Kh2DwXF/0clqbxvsxx981.png",
74 | "https://i.ibb.co/mHY9kLc/0iq95pa3su981.webp",
75 | "https://i.ibb.co/qBvQ6xB/0na6q2vxlw981.webp",
76 | "https://i.ibb.co/18GBSN6/0rkngpsl4r981.webp",
77 | "https://i.ibb.co/ZGxBS4G/0spglmuy9o981.jpg",
78 | "https://i.ibb.co/Gcm42FJ/0tiriaseiy981.webp",
79 | "https://i.ibb.co/fpCGZ4X/1b3kfj4wgu981.jpg",
80 | "https://i.ibb.co/1qDWQWp/1gvddy9hgp981.webp",
81 | "https://i.ibb.co/hD5yk3q/1yymdvdnrv981.webp",
82 | "https://i.ibb.co/4PTbZps/2lwckawrq0a81.jpg",
83 | "https://i.ibb.co/jGGK0Vk/2xwvqqkjpr981.webp",
84 | "https://i.ibb.co/cF27KmG/3csi8k2viq981.webp",
85 | "https://i.ibb.co/vx9CZ52/3ehxlw3osw981.png",
86 | "https://i.ibb.co/Y81Sdhs/3f248u3a3q981.webp",
87 | "https://i.ibb.co/LCdqMH6/3pmup8253j981.webp",
88 | "https://i.ibb.co/PM4rB5V/4a1da4wjvq981.png",
89 | "https://i.ibb.co/vJ5Y7HF/4clm1u8o1r981.jpg",
90 | "https://i.ibb.co/VHxB8Bs/5qaofagy9u981.webp",
91 | "https://i.ibb.co/jGWF8zd/5qzdyk8d3u981.png",
92 | "https://i.ibb.co/Zz17wqy/5t03k9wmuu981.jpg",
93 | "https://i.ibb.co/1mwQXTg/6n4b0swc1w981.webp"
94 | ]
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const fetch = require('node-fetch');
3 | const cookieParser = require("cookie-parser");
4 | const fs = require('fs');
5 | const path = require("path");
6 | const app = express();
7 | const Database = require("@replit/database");
8 |
9 | app.use(cookieParser());
10 | const db = new Database();
11 |
12 | Array.prototype.random = function() {
13 | return this[Math.floor((Math.random() * this.length))];
14 | };
15 |
16 | const memesData = JSON.parse(fs.readFileSync('./memes.json', 'utf8'));
17 |
18 | app.get('/meme', (req, res) => {
19 | var w = "400";
20 | if (req.query.w)
21 | w = req.query.w;
22 | var h = "400";
23 | if (req.query.h)
24 | h = req.query.h;
25 | var expiryDate = new Date(Number(new Date()) - 100000);
26 |
27 | res.set({
28 | 'Cache-Control': 'no-cache,max-age=0,no-store,s-maxage=0,proxy-revalidate',
29 | 'Expires': expiryDate,
30 | 'etag': false
31 | });
32 | fetch(memesData.random())
33 | .then(response => {
34 | const contentType = response.headers.get("content-type");
35 | response.buffer().then((buffer) => {
36 | res.setHeader("Content-Type", contentType);
37 | res.status(200).send(buffer);
38 | });
39 | });
40 | /*res.send(
41 | `
42 |
46 | `
47 | );*/
48 | });
49 |
50 | app.get('/api/views', (req, res) => {
51 | var key = "views-data";
52 |
53 | db.get(key).then(value => {
54 | res.send(value);
55 | });
56 | });
57 |
58 | app.get('/views', (req, res) => {
59 |
60 | var key = "views-data"
61 | db.get(key).then(value => {
62 | var val = 0;
63 | if (value[encodeURIComponent(req.query.id)] == undefined) {
64 | value[encodeURIComponent(req.query.id)] = 0;
65 | db.set(key, value).then(() => { });
66 | }
67 | else {
68 | val = value[encodeURIComponent(req.query.id)] + 1;
69 | value[encodeURIComponent(req.query.id)] = val;
70 | }
71 |
72 | db.set(key, value).then(() => {
73 | var col = "rgb(60, 200, 60)";
74 | var fn = "Roboto";
75 | var st = "for-the-badge";
76 | if (req.query.color)
77 | col = req.query.color;
78 | if (req.query.font)
79 | st = req.query.font;
80 | var expiryDate = new Date(Number(new Date()) - 100000);
81 |
82 | res.set({
83 | 'Content-Type': 'image/svg+xml',
84 | 'Cache-Control': 'no-cache,max-age=0,no-store,s-maxage=0,proxy-revalidate',
85 | 'Expires': expiryDate,
86 | 'etag': false
87 | });
88 | res.send(
89 | `
90 |
99 | `
100 | );
101 |
102 | });
103 | });
104 | });
105 |
106 | app.get('/animated-svg', (req, res) => {
107 | res.set({
108 | 'Content-Type': 'image/svg+xml'
109 | });
110 | var duration = 5;
111 | if (req.query.duration)
112 | duration = req.query.duration;
113 | var color = "#9e4a44";
114 | if (req.query.color)
115 | color = req.query.color;
116 | var text = "Dynamic Badges/SVG Animated Text";
117 | if (req.query.text)
118 | text = req.query.text;
119 | var repeatCount = "indefinite";
120 | if (req.query.repeatCount)
121 | repeatCount = req.query.repeatCount;
122 | var font = "Montserrat";
123 | if (req.query.font)
124 | font = req.query.font;
125 | var fontSize = 26;
126 | if (req.query.fontSize)
127 | fontSize = req.query.fontSize;
128 | res.send(
129 | `
130 |
140 | `
141 | );
142 | });
143 |
144 | app.get('/api/age/:dd/:mm/:yyyy/:color/:style', (req, res) => {
145 | var day = req.params.dd;
146 | var month = req.params.mm;
147 | var year = req.params.yyyy;
148 | const rawMiliseconds = new Date() - new Date(`${day}/${month}/${year}`);
149 | const rawSeconds = Math.floor(rawMiliseconds / 1000);
150 | const rawMinutes = Math.floor(rawSeconds / 60);
151 | const rawHours = Math.floor(rawMinutes / 60);
152 | const rawDays = Math.floor(rawHours / 24);
153 | const rawMonths = Math.floor(rawDays / 30);
154 | const rawYears = Math.floor(rawDays / 365);
155 |
156 | const seconds = rawSeconds % 60;
157 | const minutes = rawMinutes % 60;
158 | const hours = rawHours % 24;
159 | const days = rawDays % 30;
160 | const months = rawMonths % 12;
161 | const years = rawYears;
162 | var col = "green";
163 | var st = "for-the-badge";
164 | if (req.params.color)
165 | col = req.params.color;
166 | if (req.params.style)
167 | st = req.params.style;
168 | var font = "Montserrat";
169 | if (req.query.font)
170 | font = req.query.font;
171 |
172 | var output = {
173 | "schemaVersion": 1,
174 | "label": "Age",
175 | "message": `${years} years, ${months} months, ${days} days`,
176 | "color": col,
177 | "style": st
178 | };
179 | res.json(output);
180 | });
181 |
182 | app.get('/age/:dd/:mm/:yyyy', (req, res) => {
183 | var day = req.params.dd;
184 | var month = req.params.mm;
185 | var year = req.params.yyyy;
186 | var col = "green";
187 | var st = "for-the-badge";
188 | if (req.query.color)
189 | col = req.query.color;
190 | var fn = "Montserrat";
191 | if (req.query.font)
192 | fn = req.query.font;
193 | if (req.query.style)
194 | st = req.query.style;
195 | const rawMiliseconds = new Date() - new Date(`${day}/${month}/${year}`);
196 | const rawSeconds = Math.floor(rawMiliseconds / 1000);
197 | const rawMinutes = Math.floor(rawSeconds / 60);
198 | const rawHours = Math.floor(rawMinutes / 60);
199 | const rawDays = Math.floor(rawHours / 24);
200 | const rawMonths = Math.floor(rawDays / 30);
201 | const rawYears = Math.floor(rawDays / 365);
202 |
203 | const seconds = rawSeconds % 60;
204 | const minutes = rawMinutes % 60;
205 | const hours = rawHours % 24;
206 | const days = rawDays % 30;
207 | const months = rawMonths % 12;
208 | const years = rawYears;
209 | var expiryDate = new Date(Number(new Date()) - 100000);
210 | var txt = `${years} years, ${months} months, ${days} days`;
211 | res.set({
212 | 'Content-Type': 'image/svg+xml',
213 | 'Cache-Control': 'no-cache,max-age=0,no-store,s-maxage=0,proxy-revalidate',
214 | 'Expires': expiryDate,
215 | 'etag': false
216 | });
217 |
218 | res.send(
219 | `
220 |
229 | `
230 | );
231 |
232 | });
233 |
234 | app.get('/api/star', (req, res) => {
235 |
236 | db.get("ratings").then(value => {
237 | res.json(value);
238 | });
239 | });
240 |
241 | app.get('/star', (req, res) => {
242 | if (req.query.image) {
243 | res.sendFile(path.join(__dirname, 'static/star.png'));
244 | return;
245 | }
246 |
247 | var uname = "Jaysmito101";
248 | var repo = "dynamic-badges";
249 | var id = 0;
250 | if (req.query.id)
251 | id = req.query.id;
252 | if (req.query.uname)
253 | uname = req.query.uname;
254 | if (req.query.repo)
255 | repo = req.query.repo;
256 | var key = encodeURIComponent(uname) + "-" + encodeURIComponent(repo);
257 |
258 | if (req.query.show) {
259 | var rat = 0;
260 | db.get("ratings").then(value => {
261 | if (value[key] != undefined) {
262 | rat = value[key].score / value[key].count;
263 | }
264 | res.set({
265 | 'Content-Type': 'image/svg+xml',
266 | 'Cache-Control': 'no-cache,max-age=0,no-store,s-maxage=0,proxy-revalidate',
267 | 'etag': false
268 | });
269 | res.send(
270 | `
271 |
276 | `
277 | );
278 | });
279 | return;
280 | }
281 |
282 | if (req.cookies["rated-" + key]) {
283 | if (req.query.tourl)
284 | res.redirect(req.query.tourl);
285 | res.redirect(`https://github.com/${uname}/${repo}`);
286 | return;
287 | }
288 | let options = {
289 | maxAge: 1000 * 60 * 30 // would expire after 30 minutes
290 | }
291 |
292 |
293 | db.get("ratings").then(value => {
294 | var val = 0;
295 | var count = 0;
296 | if (value[key] != undefined) {
297 | val = value[key].score;
298 | count = value[key].count;
299 | }
300 | else {
301 | value[key] = {};
302 | }
303 | value[key].score = (parseInt(val) + parseInt(id));
304 | value[key].count = count + 1;
305 | db.set("ratings", value).then(() => {
306 | res.cookie('rated-' + key, id, options);
307 | if (req.query.tourl)
308 | res.redirect(req.query.tourl);
309 | res.redirect(`https://github.com/${uname}/${repo}`);
310 | });
311 | });
312 | });
313 |
314 | function sendScore(res, score) {
315 | if (score == undefined || score == null || score == NaN)
316 | score = 0;
317 | var expiryDate = new Date(Number(new Date()) + 1000 * 60 * 10);
318 | res.set({
319 | 'Content-Type': 'image/svg+xml',
320 | 'Cache-Control': 'max-age=600,s-maxage=600'
321 | ,
322 | 'Expires': expiryDate
323 | });
324 | res.send(
325 | `
326 |
392 |
393 | `
394 | );
395 | }
396 |
397 |
398 | app.get('/api/score', (req, res) => {
399 |
400 | db.get("trophies").then(value => {
401 | res.json(value);
402 | });
403 | });
404 |
405 | app.get('/score/:user', (req, res) => {
406 |
407 | db.get("trophies").then(value => {
408 | if (value[req.params.user]) {
409 | if (Number(new Date()) - Number(new Date(value[req.params.user].time)) < 1000 * 60 * 60) {
410 | sendScore(res, value[req.params.user].score);
411 | return;
412 | }
413 | }
414 | var headers = {
415 | 'Authorization': 'token ' + process.env["PAT"]
416 | };
417 | fetch(`https://api.github.com/users/${req.params.user}/repos?per_page=100`, { method: 'GET', headers: headers })
418 | .then(ress => ress.text())
419 | .then(text => {
420 |
421 | var repos = JSON.parse(text);
422 | var data = {};
423 | data.st = 0;
424 | data.wt = 0;
425 | data.ft = 0;
426 | data.repos = [];
427 | data.count = 0;
428 | for (var i = 0; i < repos.length; i++) {
429 | var repo = {};
430 | repo.name = repos[i].name;
431 | repo.stars = repos[i].stargazers_count;
432 | repo.forks = repos[i].forks_count;
433 | repo.watchers = repos[i].watchers_count;
434 | data.repos.push(repo);
435 | data.st += repo.stars;
436 | data.wt += repo.watchers;
437 | data.ft += repo.forks;
438 | }
439 |
440 | fetch(`https://api.github.com/users/${req.params.user}`, { method: 'GET', headers: headers }).then(ress => ress.text()).then(text => {
441 | data.followers = JSON.parse(text).followers;
442 | data.following = JSON.parse(text).following;
443 | fetch(`https://api.github.com/users/${req.params.user}/events?per_page=10000`, { method: 'GET', headers: headers }).then(ress => ress.text()).then(text => {
444 | data.total = JSON.parse(text).length;
445 |
446 | var score = 0;
447 | score += data.st / data.repos.length;
448 | score += data.wt / data.repos.length * 10;
449 | score += data.wt / data.repos.length * 5;
450 | if (data.following == 0)
451 | data.following = 1;
452 | score += data.followers / data.following;
453 | score += data.total / 10;
454 |
455 | db.get("trophies").then(value => {
456 | if (value == undefined)
457 | value = {};
458 | value[req.params.user] = { "score": score, "time": new Date() };
459 |
460 | db.set("trophies", value).then(() => { });
461 | sendScore(res, score);
462 | });
463 | });
464 | });
465 | });
466 | });
467 |
468 | });
469 |
470 | app.get('/*', (req, res) => {
471 | res.redirect("https://github.com/Jaysmito101/dynamic-badges");
472 | });
473 |
474 |
475 | app.listen(process.env.PORT || 3000, () => {
476 | console.log("Server Started!");
477 | });
--------------------------------------------------------------------------------