├── .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 | ![Views](https://dynamic-badges.maxalpha.repl.co/views?id=Username.PageID&style=for-the-badge&color=blue) 49 | 50 | How to use: 51 | 52 | ![Views](https://dynamic-badges.maxalpha.repl.co/views?id=Username.RepositoryName&style=for-the-badge&color=blue) 53 | 54 | # Random Programming Meme 55 | 56 | 57 | 58 | How to use: 59 | 60 | 61 | 62 | # Github Trophy 63 | 64 | ![Trophy](https://dynamic-badges.maxalpha.repl.co/score/Jaysmito101) 65 | 66 | How to use: 67 | 68 | ![Trophy](https://dynamic-badges.maxalpha.repl.co/score/Jaysmito101) 69 | 70 | The score is calculated based on youe github profile! 71 | 72 | # Age Badge 73 | 74 | ![Age](https://dynamic-badges.maxalpha.repl.co/age/12/08/2004) 75 | 76 | How to use: 77 | 78 | ![Age](https://dynamic-badges.maxalpha.repl.co/age/12/08/2004) 79 | 80 | Parameters : 81 | 82 | color 83 | style 84 | 85 | # Animated SVG Text 86 | 87 | ![](https://dynamic-badges.maxalpha.repl.co/animated-svg?text=Dynamic-Badges&duration=3&color=%237d403c) 88 | 89 | How to use: 90 | 91 | ![](https://dynamic-badges.maxalpha.repl.co/animated-svg?text=I%20AM%20Jaysmito&duration=3&color=%237d403c) 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 | 44 | 45 | 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 | 91 | 92 | 93 | 94 | Views 95 | ${val} 96 | Sorry, your browser does not support inline SVG. 97 | 98 | 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 | 131 | 132 | 133 | 134 | 135 | 136 | ${text} 137 | 138 | 139 | 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 | 221 | 222 | 223 | 224 | Age 225 | ${txt} 226 | Sorry, your browser does not support inline SVG. 227 | 228 | 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 | 273 | ${rat.toFixed(2)} 275 | 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 | 327 | ${score.toFixed(2)} 328 | 329 | 333 | 334 | 336 | 337 | 339 | 340 | 343 | 346 | 351 | 352 | 353 | 374 | 391 | 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 | }); --------------------------------------------------------------------------------