forked from notBrad/bubo-rss
		
	Compare commits
	
		
			19 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6aa4dc80b3 | ||
|  | b9a7da4287 | ||
|  | 1b3f20379a | ||
|  | 89dbf2c17a | ||
|  | b429c213b8 | ||
|  | 1a9c60a4d6 | ||
|  | 57571db322 | ||
|  | 6fca9e15be | ||
|  | 6dbd6bfe02 | ||
|  | 29e2188b2e | ||
|  | 415bfb6c73 | ||
|  | a5ff96e449 | ||
|  | 1cd365e257 | ||
|  | d124194296 | ||
|  | 713a4eedaa | ||
|  | 53843e949e | ||
|  | 949bea60b3 | ||
|  | ceaad6c5b4 | ||
|  | fbfda83125 | 
							
								
								
									
										38
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,38 +0,0 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help us improve | ||||
| title: '' | ||||
| labels: '' | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Describe the bug** | ||||
| A clear and concise description of what the bug is. | ||||
|  | ||||
| **To Reproduce** | ||||
| Steps to reproduce the behavior: | ||||
| 1. Go to '...' | ||||
| 2. Click on '....' | ||||
| 3. Scroll down to '....' | ||||
| 4. See error | ||||
|  | ||||
| **Expected behavior** | ||||
| A clear and concise description of what you expected to happen. | ||||
|  | ||||
| **Screenshots** | ||||
| If applicable, add screenshots to help explain your problem. | ||||
|  | ||||
| **Desktop (please complete the following information):** | ||||
|  - OS: [e.g. iOS] | ||||
|  - Browser [e.g. chrome, safari] | ||||
|  - Version [e.g. 22] | ||||
|  | ||||
| **Smartphone (please complete the following information):** | ||||
|  - Device: [e.g. iPhone6] | ||||
|  - OS: [e.g. iOS8.1] | ||||
|  - Browser [e.g. stock browser, safari] | ||||
|  - Version [e.g. 22] | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context about the problem here. | ||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,20 +0,0 @@ | ||||
| --- | ||||
| name: Feature request | ||||
| about: Suggest an idea for this project | ||||
| title: '' | ||||
| labels: '' | ||||
| assignees: '' | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Is your feature request related to a problem? Please describe.** | ||||
| A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | ||||
|  | ||||
| **Describe the solution you'd like** | ||||
| A clear and concise description of what you want to happen. | ||||
|  | ||||
| **Describe alternatives you've considered** | ||||
| A clear and concise description of any alternative solutions or features you've considered. | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context or screenshots about the feature request here. | ||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| node_modules/* | ||||
| public/index.html | ||||
| dist/* | ||||
| .DS_Store | ||||
| .DS_Store | ||||
|   | ||||
							
								
								
									
										26
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,26 +0,0 @@ | ||||
| # Use an official Node.js runtime as a parent image | ||||
| FROM node:14 | ||||
|  | ||||
| # Set the working directory in the container | ||||
| WORKDIR /usr/src/app | ||||
|  | ||||
| # Copy package.json and package-lock.json | ||||
| COPY package*.json ./ | ||||
|  | ||||
| # Install any dependencies | ||||
| RUN npm install | ||||
|  | ||||
| # Bundle the source code inside the Docker container | ||||
| COPY . . | ||||
|  | ||||
| # Build the project | ||||
| RUN npm run build:bubo | ||||
|  | ||||
| # Install 'serve' to serve the static site | ||||
| RUN npm install -g serve | ||||
|  | ||||
| # Make port 5000 available to the world outside this container | ||||
| EXPOSE 5000 | ||||
|  | ||||
| # Run 'serve' to serve the static site on port 5000 | ||||
| CMD ["serve", "-s", "public", "-l", "5000"] | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| # 🦉 Bubo Reader | ||||
|  | ||||
| Bubo Reader is a hyper-minimalist feed reader (RSS, Atom, JSON) you can deploy on your own server, [Netlify](https://netlify.com) in a few steps or [Glitch](https://glitch.com) in even fewer steps! The goal of the project is to generate a webpage that shows a list of links from a collection of feeds organized by category and website. That's it. | ||||
| Bubo Reader is a hyper-minimalist <acronym title="Really Simple Syndication">RSS</acronym> and <acronym title="JavaScript Object Notation">JSON</acronym> feed reader you can deploy on your own server, [Netlify](https://netlify.com) in a few steps or [Glitch](https://glitch.com) in even fewer steps! The goal of the project is to generate a webpage that shows a list of links from a collection of feeds organized by category and website. That's it. | ||||
|  | ||||
| It is named after this [silly robot owl](https://www.youtube.com/watch?v=MYSeCfo9-NI) from Clash of the Titans (1981). | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,9 @@ | ||||
|     "https://george.mand.is/feed.xml", | ||||
|     "https://joy.recurse.com/feed.atom" | ||||
|   ], | ||||
|   "Social": [ | ||||
|     "https://social.mandis.dev/@georgemandis.rss" | ||||
|   ], | ||||
|   "My GitHub Projects": [ | ||||
|     "https://github.com/georgemandis.atom", | ||||
|     "https://github.com/georgemandis/bubo-rss/releases.atom", | ||||
|   | ||||
| @@ -1,4 +0,0 @@ | ||||
| [build]   | ||||
|   command = "npm run build:bubo" | ||||
|   publish = "./public/" | ||||
|  | ||||
							
								
								
									
										720
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										720
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										30
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "bubo-reader", | ||||
|   "version": "2.0.2", | ||||
|   "version": "2.0.1", | ||||
|   "description": "A simple but effective feed reader (RSS, JSON)", | ||||
|   "homepage": "https://github.com/georgemandis/bubo-rss", | ||||
|   "main": "src/index.js", | ||||
| @@ -10,7 +10,9 @@ | ||||
|     "clean": "rm -rf dist", | ||||
|     "build": "tsc", | ||||
|     "bubo": "node dist/index.js", | ||||
|     "build:bubo": "tsc && node dist/index.js" | ||||
|     "build:bubo": "tsc && node dist/index.js", | ||||
|     "start": "npm run build:bubo; node server.js",     | ||||
|     "test": "echo \"Error: no test specified\" && exit 1" | ||||
|   }, | ||||
|   "author": { | ||||
|     "name": "George Mandis", | ||||
| @@ -27,19 +29,21 @@ | ||||
|   }, | ||||
|   "license": "MIT", | ||||
|   "dependencies": { | ||||
|     "chalk": "^5.2.0", | ||||
|     "node-fetch": "^3.3.1", | ||||
|     "nunjucks": "^3.2.4", | ||||
|     "rss-parser": "^3.13.0" | ||||
|     "chalk": "^5.1.2", | ||||
|     "node-fetch": "^3.3.0", | ||||
|     "nunjucks": "^3.2.3", | ||||
|     "rss-parser": "^3.12.0", | ||||
|     "express": "^4.17.1" | ||||
|   }, | ||||
|   "engines": { "node": "16.x" }, | ||||
|   "devDependencies": { | ||||
|     "@types/node": "^20.2.5", | ||||
|     "@types/nunjucks": "^3.2.2", | ||||
|     "@types/node": "^16.18.4", | ||||
|     "@types/nunjucks": "^3.2.1", | ||||
|     "@types/xml2js": "^0.4.11", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.59.8", | ||||
|     "@typescript-eslint/parser": "^5.59.8", | ||||
|     "eslint": "^8.42.0", | ||||
|     "tslib": "^2.5.3", | ||||
|     "typescript": "^5.1.3" | ||||
|     "@typescript-eslint/eslint-plugin": "^5.45.0", | ||||
|     "@typescript-eslint/parser": "^5.45.0", | ||||
|     "eslint": "^8.29.0", | ||||
|     "tslib": "^2.4.1", | ||||
|     "typescript": "^4.9.3" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										24
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								server.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| // Bubo RSS (on Glitch!) | ||||
|  | ||||
| // init project | ||||
| import express from "express"; | ||||
| import { URL } from 'url'; | ||||
| const __dirname = new URL('.', import.meta.url).pathname; | ||||
|  | ||||
| const app = express(); | ||||
|  | ||||
| // we've started you off with Express, | ||||
| // but feel free to use whatever libs or frameworks you'd like through `package.json`. | ||||
|  | ||||
| // http://expressjs.com/en/starter/static-files.html | ||||
| app.use(express.static("public")); | ||||
|  | ||||
| // http://expressjs.com/en/starter/basic-routing.html | ||||
| app.get("/", function(request, response) { | ||||
|   response.sendFile(__dirname + "/public/index.html"); | ||||
| }); | ||||
|  | ||||
| // listen for requests :) | ||||
| const listener = app.listen(process.env.PORT, function() { | ||||
|   console.log("Your app is listening on port " + listener.address().port); | ||||
| }); | ||||
							
								
								
									
										35
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/index.ts
									
									
									
									
									
								
							| @@ -66,11 +66,7 @@ let completed = 0; | ||||
|  * and we want to build the static output. | ||||
|  */ | ||||
| const finishBuild: () => void = async () => { | ||||
|   completed++; | ||||
|   // if this isn't the last feed, just return early | ||||
|   if (completed !== feedListLength) return; | ||||
|  | ||||
|   process.stdout.write("\nDone fetching everything!\n"); | ||||
|   console.log("\nDone fetching everything!"); | ||||
|  | ||||
|   // generate the static HTML output from our template renderer | ||||
|   const output = render({ | ||||
| @@ -81,10 +77,10 @@ const finishBuild: () => void = async () => { | ||||
|  | ||||
|   // write the output to public/index.html | ||||
|   await writeFile("./public/index.html", output); | ||||
|   process.stdout.write( | ||||
|   console.log( | ||||
|     `\nFinished writing to output:\n- ${feedListLength} feeds in ${benchmark( | ||||
|       initTime | ||||
|     )}\n- ${errors.length} errors\n` | ||||
|     )}\n- ${errors.length} errors` | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| @@ -107,7 +103,8 @@ const processFeed = | ||||
|   }) => | ||||
|     async (response: Response): Promise<void> => { | ||||
|       const body = await parseFeed(response); | ||||
|       //skip to the next one if this didn't work out | ||||
|       completed++; | ||||
|       // skip to the next one if this didn't work out | ||||
|       if (!body) return; | ||||
|  | ||||
|       try { | ||||
| @@ -127,19 +124,20 @@ const processFeed = | ||||
|         }); | ||||
|  | ||||
|         contentFromAllFeeds[group].push(contents as object); | ||||
|         process.stdout.write( | ||||
|           `${success("Successfully fetched:")} ${feed} - ${benchmark(startTime)}\n` | ||||
|         console.log( | ||||
|           `${success("Successfully fetched:")} ${feed} - ${benchmark(startTime)}` | ||||
|         ); | ||||
|       } catch (err) { | ||||
|         process.stdout.write( | ||||
|         console.log( | ||||
|           `${error("Error processing:")} ${feed} - ${benchmark( | ||||
|             startTime | ||||
|           )}\n${err}\n` | ||||
|           )}\n${err}` | ||||
|         ); | ||||
|         errors.push(`Error processing: ${feed}\n\t${err}`); | ||||
|       } | ||||
|  | ||||
|       finishBuild(); | ||||
|       // if this is the last feed, go ahead and build the output | ||||
|       completed === feedListLength && finishBuild(); | ||||
|     }; | ||||
|  | ||||
| // go through each group of feeds and process | ||||
| @@ -152,16 +150,15 @@ const processFeeds = () => { | ||||
|     for (const feed of feeds) { | ||||
|       const startTime = Date.now(); | ||||
|       setTimeout(() => { | ||||
|         process.stdout.write(`Fetching: ${feed}...\n`); | ||||
|         console.log(`Fetching: ${feed}...`); | ||||
|  | ||||
|         fetch(feed) | ||||
|           .then(processFeed({ group, feed, startTime })) | ||||
|           .catch(err => { | ||||
|             process.stdout.write( | ||||
|               error(`Error fetching ${feed} ${benchmark(startTime)}\n`) | ||||
|             console.log( | ||||
|               error(`Error fetching ${feed} ${benchmark(startTime)}`) | ||||
|             ); | ||||
|             errors.push(`Error fetching ${feed} ${err.toString()}\n`); | ||||
|             finishBuild(); | ||||
|             errors.push(`Error fetching ${feed} ${err.toString()}`); | ||||
|           }); | ||||
|       }, (idx % (feedListLength / MAX_CONNECTIONS)) * DELAY_MS); | ||||
|       idx++; | ||||
| @@ -169,4 +166,4 @@ const processFeeds = () => { | ||||
|   } | ||||
| }; | ||||
|  | ||||
| processFeeds(); | ||||
| processFeeds(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user