mirror of
				https://github.com/KevinMidboe/miljobilen-rss.git
				synced 2025-10-29 17:50:23 +00:00 
			
		
		
		
	Some refactoring into separate files
This commit is contained in:
		
							
								
								
									
										101
									
								
								rss.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								rss.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | const fs = require('fs') | ||||||
|  | const { uuidv4 } = require('./utils') | ||||||
|  |  | ||||||
|  | class RSS { | ||||||
|  |  | ||||||
|  |   constructor(name) { | ||||||
|  |     this.name = name; | ||||||
|  |     this.filename = 'rss.xml'; | ||||||
|  |     this.feed = null; | ||||||
|  |  | ||||||
|  |     this.read() | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // reads RSS file | ||||||
|  |   read() { | ||||||
|  |     fs.readFile(this.filename, 'utf8', (err, content) => { | ||||||
|  |       if (err) { | ||||||
|  |         console.error("Unable to read file:", this.filename) | ||||||
|  |         console.error(err); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       this.feed = content; | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // writes RSS file | ||||||
|  |   write(content=this.feed) { | ||||||
|  |     fs.writeFile(this.filename, content, (err) => { | ||||||
|  |       if (err) { | ||||||
|  |           console.error(`Error writing to ${this.filename}:`, err); | ||||||
|  |       } else { | ||||||
|  |           console.log(`Successfully wrote to ${this.filename}`); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   itemTemplate(times, date, url, n) { | ||||||
|  |     const relativeDate = new Date().getTime() - (n * 100000000) | ||||||
|  |     const time = this.formatDate(new Date(relativeDate)) | ||||||
|  |     // const currentRSSDate = this.formatDate(new Date()); | ||||||
|  |  | ||||||
|  |     return ` | ||||||
|  |  <item> | ||||||
|  |   <title></title> | ||||||
|  |   <description>Vi minner om miljøbilen fra FolloRen besøker oss på ${this.name} kl ${times.from}-${times.to} den ${date}.</description> | ||||||
|  |   <link>${url}</link> | ||||||
|  |   <guid isPermaLink="false">${uuidv4()}</guid> | ||||||
|  |   <pubDate>${time}</pubDate> | ||||||
|  |  </item> | ||||||
|  |  | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   getRSSItems() { | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   generate(times, dates, url) { | ||||||
|  |     const description = "Viser hentetider for miljøbilen fra folloren.no"; | ||||||
|  |     const currentRSSDate = this.formatDate(new Date()) | ||||||
|  |  | ||||||
|  |     const blocks = dates.reverse().map((date, n) => this.itemTemplate(times, date, url, n)) | ||||||
|  |     this.feed = ` | ||||||
|  | <?xml version="1.0" encoding="UTF-8" ?> | ||||||
|  | <rss version="2.0"> | ||||||
|  | <channel> | ||||||
|  |  <title>Miljøbilen hentetider ${this.name}</title> | ||||||
|  |  <description>${description}</description> | ||||||
|  |  <link>https://github.com/kevinmidboe/miljobilen-rss</link> | ||||||
|  |  <copyright>2020 Example.com All rights reserved</copyright> | ||||||
|  |  <lastBuildDate>${currentRSSDate}</lastBuildDate> | ||||||
|  |  <pubDate>${currentRSSDate}</pubDate> | ||||||
|  |  <ttl>1800</ttl> | ||||||
|  |  | ||||||
|  |   ${blocks.join('')} | ||||||
|  |  | ||||||
|  | </channel> | ||||||
|  | </rss> | ||||||
|  |     `; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   formatDate(date) { | ||||||
|  |     const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | ||||||
|  |     const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; | ||||||
|  |  | ||||||
|  |     const day = days[date.getUTCDay()]; | ||||||
|  |     const dayOfMonth = date.getUTCDate(); | ||||||
|  |     const month = months[date.getUTCMonth()]; | ||||||
|  |     const year = date.getUTCFullYear(); | ||||||
|  |     const hours = String(date.getUTCHours()).padStart(2, '0'); | ||||||
|  |     const minutes = String(date.getUTCMinutes()).padStart(2, '0'); | ||||||
|  |     const seconds = String(date.getUTCSeconds()).padStart(2, '0'); | ||||||
|  |  | ||||||
|  |     return `${day}, ${dayOfMonth} ${month} ${year} ${hours}:${minutes}:${seconds} +0000`; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | module.exports = RSS | ||||||
							
								
								
									
										93
									
								
								run.js
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								run.js
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| const fs = require('fs') | const RSS = require('./rss.js'); | ||||||
|  |  | ||||||
| const CURRENT_DATE = new Date() | const CURRENT_DATE = new Date() | ||||||
|  |  | ||||||
| @@ -20,22 +20,6 @@ const CURRENT_DATE = new Date() | |||||||
| // real date objects. It should include logic for look-ahead | // real date objects. It should include logic for look-ahead | ||||||
| // to adress rollover. | // to adress rollover. | ||||||
|  |  | ||||||
| function writeStringToFile(filePath, content) { |  | ||||||
|     fs.writeFile(filePath, content, (err) => { |  | ||||||
|         if (err) { |  | ||||||
|             console.error(`Error writing to ${filePath}:`, err); |  | ||||||
|         } else { |  | ||||||
|             console.log(`Successfully wrote to ${filePath}`); |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function uuidv4() { |  | ||||||
|   return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => |  | ||||||
|     (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16) |  | ||||||
|   ); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| async function getSite(url) { | async function getSite(url) { | ||||||
|   return fetch(url).then(async (resp) => { |   return fetch(url).then(async (resp) => { | ||||||
|     if (!resp.ok) { |     if (!resp.ok) { | ||||||
| @@ -74,16 +58,13 @@ function getTimeForLocation(text, location) { | |||||||
| function getDatesForLocation(text, location) { | function getDatesForLocation(text, location) { | ||||||
|   regexpDatesString = new RegExp(`${location}.*<br>((\\d+.\\d+).*)</p>`, "i"); |   regexpDatesString = new RegExp(`${location}.*<br>((\\d+.\\d+).*)</p>`, "i"); | ||||||
|   datesString = text.match(regexpDatesString)[0]; |   datesString = text.match(regexpDatesString)[0]; | ||||||
|   console.log(text.match(regexpDatesString)) |  | ||||||
|  |  | ||||||
|   // only care about first paragraph |   // only care about first paragraph | ||||||
|   console.log("datestring", datesString) |   // TODO make regex stop at first capture | ||||||
|   datesString = datesString.split('</p>')[0] |   datesString = datesString.split('</p>')[0] | ||||||
|  |  | ||||||
|   // TODO null check |   // TODO null check | ||||||
|  |  | ||||||
|   console.log("datestring", datesString) |  | ||||||
|  |  | ||||||
|   regexpDates = /(\d+\.\d+)+/g |   regexpDates = /(\d+\.\d+)+/g | ||||||
|   dates = datesString.match(regexpDates) |   dates = datesString.match(regexpDates) | ||||||
|  |  | ||||||
| @@ -100,59 +81,7 @@ function getSolberg(site, TITLE) { | |||||||
|   return { name, times: { from, to }, dates }; |   return { name, times: { from, to }, dates }; | ||||||
| } | } | ||||||
|  |  | ||||||
| function formatRSSDate(date) { | // convert string DD.MM to JS date object | ||||||
|   const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; |  | ||||||
|   const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; |  | ||||||
|  |  | ||||||
|   const day = days[date.getUTCDay()]; |  | ||||||
|   const dayOfMonth = date.getUTCDate(); |  | ||||||
|   const month = months[date.getUTCMonth()]; |  | ||||||
|   const year = date.getUTCFullYear(); |  | ||||||
|   const hours = String(date.getUTCHours()).padStart(2, '0'); |  | ||||||
|   const minutes = String(date.getUTCMinutes()).padStart(2, '0'); |  | ||||||
|   const seconds = String(date.getUTCSeconds()).padStart(2, '0'); |  | ||||||
|  |  | ||||||
|   return `${day}, ${dayOfMonth} ${month} ${year} ${hours}:${minutes}:${seconds} +0000`; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function generateRSS(name, times, dates, URL) { |  | ||||||
|   const description = "Viser hentetider for miljøbilen fra folloren.no" |  | ||||||
|   const updatedDate = formatRSSDate(new Date()) |  | ||||||
|  |  | ||||||
|   const blocks = dates.reverse().map((date, n) => { |  | ||||||
|     const relativeDate = new Date().getTime() - (n * 100000000) |  | ||||||
|     const time = formatRSSDate(new Date(relativeDate)) |  | ||||||
|  |  | ||||||
|     return ` |  | ||||||
|  <item> |  | ||||||
|   <title></title> |  | ||||||
|   <description>Vi minner om miljøbilen fra FolloRen besøker oss på ${name} kl ${times.from}-${times.to} den ${date}.</description> |  | ||||||
|   <link>${URL}</link> |  | ||||||
|   <guid isPermaLink="false">${uuidv4()}</guid> |  | ||||||
|   <pubDate>${time}</pubDate> |  | ||||||
|  </item> |  | ||||||
|     ` |  | ||||||
|   }) |  | ||||||
|  |  | ||||||
|   return ` |  | ||||||
| <?xml version="1.0" encoding="UTF-8" ?> |  | ||||||
| <rss version="2.0"> |  | ||||||
| <channel> |  | ||||||
|  <title>Miljøbilen hentetider ${name}</title> |  | ||||||
|  <description>${description}</description> |  | ||||||
|  <link>https://github.com/kevinmidboe/miljobilen-rss</link> |  | ||||||
|  <copyright>2020 Example.com All rights reserved</copyright> |  | ||||||
|  <lastBuildDate>${updatedDate}</lastBuildDate> |  | ||||||
|  <pubDate>${updatedDate}</pubDate> |  | ||||||
|  <ttl>1800</ttl> |  | ||||||
|  |  | ||||||
|   ${blocks.join('')} |  | ||||||
|  |  | ||||||
| </channel> |  | ||||||
| </rss> |  | ||||||
|   ` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function websiteDateToTime(dateString) { | function websiteDateToTime(dateString) { | ||||||
|   const date = new Date() |   const date = new Date() | ||||||
|   let [_, day, month] = dateString.match(/(\d+).(\d+)/) |   let [_, day, month] = dateString.match(/(\d+).(\d+)/) | ||||||
| @@ -168,6 +97,7 @@ function websiteDateToTime(dateString) { | |||||||
|   return date |   return date | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // convert JS date object to DD.MM string | ||||||
| function timeToWebsiteDate(date) { | function timeToWebsiteDate(date) { | ||||||
|   const day = date.getDate() |   const day = date.getDate() | ||||||
|   const month = date.getMonth() + 1 |   const month = date.getMonth() + 1 | ||||||
| @@ -182,6 +112,8 @@ function relevantDates(allDates) { | |||||||
|   let index = 0; |   let index = 0; | ||||||
|   let date = 0 |   let date = 0 | ||||||
|  |  | ||||||
|  |   // this selects all dates before current date AND the | ||||||
|  |   // next one since index incrementation is after push | ||||||
|   while (date <= CURRENT_DATE) { |   while (date <= CURRENT_DATE) { | ||||||
|     date = websiteDateToTime(allDates[index]) |     date = websiteDateToTime(allDates[index]) | ||||||
|  |  | ||||||
| @@ -192,6 +124,14 @@ function relevantDates(allDates) { | |||||||
|   return relevantDates |   return relevantDates | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // fetch websites | ||||||
|  | // parse for name, time and dates | ||||||
|  | // convert to JS dates | ||||||
|  | // parse RSS feed | ||||||
|  | // convert to JS dates | ||||||
|  | // add dates not in feed | ||||||
|  | // write feed | ||||||
|  |  | ||||||
| async function main() { | async function main() { | ||||||
|   const URL = "https://folloren.no/levering-av-avfall/miljobilen" |   const URL = "https://folloren.no/levering-av-avfall/miljobilen" | ||||||
|   site = await getSite(URL); |   site = await getSite(URL); | ||||||
| @@ -212,8 +152,9 @@ async function main() { | |||||||
|   // todo relevant dates elsewhere |   // todo relevant dates elsewhere | ||||||
|   dates = relevantDates(dates) |   dates = relevantDates(dates) | ||||||
|   console.log("rel dates:", dates) |   console.log("rel dates:", dates) | ||||||
|   rss = generateRSS(name, times, dates, URL) |   const rss = new RSS(name); | ||||||
|   writeStringToFile('rss.xml', rss) |   rss.generate(times, dates, URL) | ||||||
|  |   rss.write() | ||||||
| } | } | ||||||
|  |  | ||||||
| try { | try { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user