diff --git a/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-12.md b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-12.md index cb8771e..306f6f9 100644 --- a/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-12.md +++ b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-12.md @@ -3,7 +3,7 @@ date: 2019-09-12 tags: post name: APIdays Barcelona url: https://www.apidays.co/barcelona2019/ -type: conference +type: webinar title: 'Consumer-Driven Contracts: A better approach for API Testing' slides_url: https://slides.com/lirantal/consumer-driven-contracts recording_url: https://www.youtube.com/watch?v=zfGKX5iKSis&list=PLmEaqnTJ40Oqo9VlbcUakVmFZgx5weLrs&index=25&t=141s&ab_channel=apidays diff --git a/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-15.md b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-15.md new file mode 100644 index 0000000..a1ed207 --- /dev/null +++ b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-15.md @@ -0,0 +1,20 @@ +--- +date: 2019-09-15 +tags: post +name: JSConf Budapest +url: https://2019.jsconfbp.com/ +type: podcast +title: 'StrangerDanger: Finding Security Vulnerabilities Before They Find You!' +slides_url: +recording_url: https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf +city: Budapest +country: Hungary +country_code: HU +language: English +recognitions: + twitter: + - https://twitter.com/panay_georgiou/status/1177572765664194560 +image_header: https://pbs.twimg.com/media/EFeULhIW4AARwZa?format=jpg&name=large +images: + - https://pbs.twimg.com/media/EFeULhIW4AARwZa?format=jpg&name=large +--- diff --git a/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-27.md b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-27.md index 0afc09b..e4c89eb 100644 --- a/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-27.md +++ b/__tests__/__fixtures__/main-datafiles/myapp/pages/2019/2019-09-27.md @@ -3,7 +3,7 @@ date: 2019-09-27 tags: post name: JSConf Budapest url: https://2019.jsconfbp.com/ -type: conference +type: meetup title: 'StrangerDanger: Finding Security Vulnerabilities Before They Find You!' slides_url: recording_url: https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf diff --git a/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-01-01.md b/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-01-01.md new file mode 100644 index 0000000..5ac2464 --- /dev/null +++ b/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-01-01.md @@ -0,0 +1,20 @@ +--- +date: 2021-01-01 +tags: post +name: Cyber Week +url: https://cw2021.b2b-wizard.com/expo +type: other +title: Are We Forever Doomed By Software Supply Chain Risks? +slides_url: +recording_url: https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk +city: Tel Aviv +country: Israel +country_code: IL +language: English +recognitions: + twitter: + - https://twitter.com/liran_tal/status/1417874639859109894 +image_header: +images: + - +--- diff --git a/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-06-13.md b/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-06-13.md new file mode 100644 index 0000000..f813a7c --- /dev/null +++ b/__tests__/__fixtures__/main-datafiles/myapp/pages/2021/2021-06-13.md @@ -0,0 +1,20 @@ +--- +date: 2021-06-13 +tags: post +name: Cyber Week +url: https://cw2021.b2b-wizard.com/expo +type: article +title: Are We Forever Doomed By Software Supply Chain Risks? +slides_url: +recording_url: https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk +city: Tel Aviv +country: Israel +country_code: IL +language: English +recognitions: + twitter: + - https://twitter.com/liran_tal/status/1417874639859109894 +image_header: +images: + - +--- diff --git a/__tests__/__snapshots__/main.test.js.snap b/__tests__/__snapshots__/main.test.js.snap index 3c389b8..e76b5f4 100644 --- a/__tests__/__snapshots__/main.test.js.snap +++ b/__tests__/__snapshots__/main.test.js.snap @@ -1,30 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`given a directory of markdown files a full document is rendered 1`] = ` -"# Table of Contents +"

\\"Total \\"Total \\"Total \\"Total \\"Total \\"Total

+
+ # Table of Contents - - [Events in 2021](#2021) - - [Events in 2019](#2019) + - [Year of 2021](#2021) - total events 3 + - [Year of 2019](#2019) - total events 3 # 2021 -[1] total events for 2021 +![Total Events](https://img.shields.io/badge/total-3-blue?style=flat-square) ![Total Conferences](https://img.shields.io/badge/conferences-1-red?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/articles-1-green?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | | 2021-7-21 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | +| 2021-6-13 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | +| 2021-1-1 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | # 2019 -[2] total events for 2019 +![Total Events](https://img.shields.io/badge/total-3-blue?style=flat-square) ![Total Meetups](https://img.shields.io/badge/meetups-1-violet?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/podcasts-1-yellow?style=flat-square) ![Total Webinars](https://img.shields.io/badge/webinars-1-lightgrey?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | | 2019-9-27 | JSConf Budapest | StrangerDanger: Finding Security Vulnerabilities Before They Find You! | | [Recording](https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf) | HU | English | +| 2019-9-15 | JSConf Budapest | StrangerDanger: Finding Security Vulnerabilities Before They Find You! | | [Recording](https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf) | HU | English | | 2019-9-12 | APIdays Barcelona | Consumer-Driven Contracts: A better approach for API Testing | [Slides](https://slides.com/lirantal/consumer-driven-contracts) | [Recording](https://www.youtube.com/watch?v=zfGKX5iKSis&list=PLmEaqnTJ40Oqo9VlbcUakVmFZgx5weLrs&index=25&t=141s&ab_channel=apidays) | ES | English | @@ -32,34 +39,41 @@ exports[`given a directory of markdown files a full document is rendered 1`] = ` `; exports[`given a directory of markdown files a full document is rendered along with pre and post content 1`] = ` -"

actual html is allowed too

+"

\\"Total \\"Total \\"Total \\"Total \\"Total \\"Total

+
+

actual html is allowed too

Liran Tal # Table of Contents - - [Events in 2021](#2021) - - [Events in 2019](#2019) + - [Year of 2021](#2021) - total events 3 + - [Year of 2019](#2019) - total events 3 # 2021 -[1] total events for 2021 +![Total Events](https://img.shields.io/badge/total-3-blue?style=flat-square) ![Total Conferences](https://img.shields.io/badge/conferences-1-red?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/articles-1-green?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | | 2021-7-21 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | +| 2021-6-13 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | +| 2021-1-1 | Cyber Week | Are We Forever Doomed By Software Supply Chain Risks? | | [Recording](https://www.youtube.com/watch?v=x74sMCaZKbg&ab_channel=Snyk) | IL | English | # 2019 -[2] total events for 2019 +![Total Events](https://img.shields.io/badge/total-3-blue?style=flat-square) ![Total Meetups](https://img.shields.io/badge/meetups-1-violet?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/podcasts-1-yellow?style=flat-square) ![Total Webinars](https://img.shields.io/badge/webinars-1-lightgrey?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | | 2019-9-27 | JSConf Budapest | StrangerDanger: Finding Security Vulnerabilities Before They Find You! | | [Recording](https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf) | HU | English | +| 2019-9-15 | JSConf Budapest | StrangerDanger: Finding Security Vulnerabilities Before They Find You! | | [Recording](https://www.youtube.com/watch?v=3H8pF6yoSgU&list=PL37ZVnwpeshEMCvdYDdZ09Sy-toTftWu0&index=15&ab_channel=JSConf) | HU | English | | 2019-9-12 | APIdays Barcelona | Consumer-Driven Contracts: A better approach for API Testing | [Slides](https://slides.com/lirantal/consumer-driven-contracts) | [Recording](https://www.youtube.com/watch?v=zfGKX5iKSis&list=PLmEaqnTJ40Oqo9VlbcUakVmFZgx5weLrs&index=25&t=141s&ab_channel=apidays) | ES | English | diff --git a/__tests__/__snapshots__/md-formatter.test.js.snap b/__tests__/__snapshots__/md-formatter.test.js.snap index 8f4c570..7a7e064 100644 --- a/__tests__/__snapshots__/md-formatter.test.js.snap +++ b/__tests__/__snapshots__/md-formatter.test.js.snap @@ -12,13 +12,14 @@ exports[`process events json data to provide a complete markdown document 1`] = "# Table of Contents - - [Events in 2016](#2016) - - [Events in 2021](#2021) + - [Year of 2016](#2016) - total events 1 + - [Year of 2021](#2021) - total events 6 # 2016 -[1] total events for 2016 +![Total Events](https://img.shields.io/badge/total-1-blue?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | @@ -28,12 +29,17 @@ exports[`process events json data to provide a complete markdown document 1`] = # 2021 -[2] total events for 2021 +![Total Events](https://img.shields.io/badge/total-6-blue?style=flat-square) ![Total Meetups](https://img.shields.io/badge/meetups-1-violet?style=flat-square) ![Total Conferences](https://img.shields.io/badge/conferences-1-red?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/podcasts-1-yellow?style=flat-square) ![Total Webinars](https://img.shields.io/badge/webinars-2-lightgrey?style=flat-square) ![Total Podcasts](https://img.shields.io/badge/articles-1-green?style=flat-square) + | Date | Event | Title | Slides | Recording | Location | Language | | ---- | ----- | ----- | ------ | --------- | -------- | -------- | | 2021-2-1 | name | title | [Slides](https://example.com) | | | English | | 2021-2-2 | name | title | | [Recording](https://example.com) | US | English | +| 2021-2-2 | name | title | | [Recording](https://example.com) | US | English | +| 2021-2-2 | name | title | | [Recording](https://example.com) | US | English | +| 2021-2-2 | name | title | | [Recording](https://example.com) | US | English | +| 2021-2-2 | name | title | | [Recording](https://example.com) | US | English | " diff --git a/__tests__/md-formatter.test.js b/__tests__/md-formatter.test.js index 6167e6b..030f014 100644 --- a/__tests__/md-formatter.test.js +++ b/__tests__/md-formatter.test.js @@ -29,7 +29,10 @@ test('process events json data to provide a complete markdown document', () => { language: null } } - ] + ], + stats: { + total: 1 + } }, { year: 2021, @@ -38,6 +41,7 @@ test('process events json data to provide a complete markdown document', () => { attributes: { date: new Date('2021-02-01'), title: 'title', + type: 'conference', name: 'name', slides_url: 'https://example.com', recording_url: null, @@ -49,6 +53,55 @@ test('process events json data to provide a complete markdown document', () => { attributes: { date: new Date('2021-02-02'), title: 'title', + type: 'meetup', + name: 'name', + slides_url: null, + recording_url: 'https://example.com', + country_code: 'US', + language: 'English' + } + }, + { + attributes: { + date: new Date('2021-02-02'), + title: 'title', + type: 'podcast', + name: 'name', + slides_url: null, + recording_url: 'https://example.com', + country_code: 'US', + language: 'English' + } + }, + { + attributes: { + date: new Date('2021-02-02'), + title: 'title', + type: 'article', + name: 'name', + slides_url: null, + recording_url: 'https://example.com', + country_code: 'US', + language: 'English' + } + }, + { + attributes: { + date: new Date('2021-02-02'), + title: 'title', + type: 'webinar', + name: 'name', + slides_url: null, + recording_url: 'https://example.com', + country_code: 'US', + language: 'English' + } + }, + { + attributes: { + date: new Date('2021-02-02'), + title: 'title', + type: 'webinar', name: 'name', slides_url: null, recording_url: 'https://example.com', @@ -56,7 +109,16 @@ test('process events json data to provide a complete markdown document', () => { language: 'English' } } - ] + ], + stats: { + total: 6, + total_podcast: 1, + total_conference: 1, + total_webinar: 2, + total_meetup: 1, + total_article: 1, + total_other: 0 + } } ] diff --git a/package-lock.json b/package-lock.json index 2193fbc..5af2faa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "ajv": "^8.6.3", "front-matter": "^4.0.2", - "json2md": "^1.12.0" + "json2md": "^1.12.0", + "marked": "^2.1.3" }, "bin": { "gigsboat": "bin/cli.js" @@ -8413,8 +8414,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", - "dev": true, - "peer": true, "bin": { "marked": "bin/marked" }, @@ -20592,9 +20591,7 @@ "marked": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", - "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", - "dev": true, - "peer": true + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==" }, "marked-terminal": { "version": "4.2.0", diff --git a/package.json b/package.json index 865858b..c55348c 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ "dependencies": { "ajv": "^8.6.3", "front-matter": "^4.0.2", - "json2md": "^1.12.0" + "json2md": "^1.12.0", + "marked": "^2.1.3" }, "devDependencies": { "@babel/core": "^7.15.8", diff --git a/src/main.js b/src/main.js index fa08959..5d873ac 100644 --- a/src/main.js +++ b/src/main.js @@ -1,9 +1,14 @@ import path from 'path' +import marked from 'marked' import { getAllFiles } from './utils/fs.js' import { convertToJson } from './utils/yaml-parser.js' -import { getEventsMd, formatToMarkdown } from './utils/md-formatter.js' -import { createYearBuckets } from './utils/content-manager.js' +import { + getEventsMd, + formatToMarkdown, + getStatsBadges +} from './utils/md-formatter.js' +import { createYearBuckets, getEventsStats } from './utils/content-manager.js' export { formatToMarkdown, generateGigs, generateDocument } @@ -12,23 +17,37 @@ async function generateDocument({ sourceDirectory, preContent, postContent }) { let markdownOutputPostContent = '' let document = '' - const eventsMarkdown = await generateGigs({ sourceDirectory }) + const { entriesForYearMarkdown, entriesByBucket } = await generateGigs({ + sourceDirectory + }) if (preContent) { - markdownOutputPreContent = processCustomContent(preContent) + markdownOutputPreContent = processCustomContent({ + contents: preContent + }) } if (postContent) { - markdownOutputPostContent = processCustomContent(postContent) + markdownOutputPostContent = processCustomContent({ + contents: postContent + }) } + const statsHeader = `
${marked.parse( + getStatsBadges(entriesByBucket) + )}
+ ` + document += - markdownOutputPreContent + eventsMarkdown + markdownOutputPostContent + statsHeader + + markdownOutputPreContent + + entriesForYearMarkdown + + markdownOutputPostContent return document } -function processCustomContent(contents) { +function processCustomContent({ contents }) { let markdownContent = '' for (const content of contents) { if (content.hasOwnProperty('raw')) { @@ -59,19 +78,22 @@ async function generateGigs({ sourceDirectory }) { const entriesByBucket = await getEntriesByBuckets(entries) const entriesForYearMarkdown = getEventsMd(entriesByBucket.bucketsByYear) - return entriesForYearMarkdown + return { + entriesForYearMarkdown, + entriesByBucket + } } async function getEntriesByBuckets(entries) { // @TODO these buckets: - // const bucketsAll = [] - // const bucketsType = {} // const bucketsLanguage = {} // const bucketsCountry = {} const bucketsByYear = createYearBuckets(entries) + const statsTotal = getEventsStats(entries) return { - bucketsByYear + bucketsByYear, + stats: statsTotal } } diff --git a/src/utils/content-manager.js b/src/utils/content-manager.js index 0195d63..354a23e 100644 --- a/src/utils/content-manager.js +++ b/src/utils/content-manager.js @@ -1,4 +1,4 @@ -export { createYearBuckets } +export { createYearBuckets, getEventsStats } function sortByDateOrYear(a, b) { if (a.hasOwnProperty('year') && b.hasOwnProperty('year')) { @@ -8,6 +8,39 @@ function sortByDateOrYear(a, b) { } } +function getEventsStats(entries) { + const stats = { + total: entries.length, + total_podcast: 0, + total_conference: 0, + total_webinar: 0, + total_meetup: 0, + total_article: 0, + total_other: 0 + } + + for (const entry of entries) { + const { attributes } = entry + const { type } = attributes + + if (type === 'podcast') { + stats.total_podcast += 1 + } else if (type === 'conference') { + stats.total_conference += 1 + } else if (type === 'webinar') { + stats.total_webinar += 1 + } else if (type === 'meetup') { + stats.total_meetup += 1 + } else if (type === 'article') { + stats.total_article += 1 + } else { + stats.total_other += 1 + } + } + + return stats +} + function createYearBuckets(entries) { const bucketsYear = {} @@ -30,6 +63,12 @@ function createYearBuckets(entries) { } } + // augment the yearlyItems with stats + for (const year of Object.keys(bucketsYear)) { + const { items } = bucketsYear[year] + bucketsYear[year].stats = getEventsStats(items) + } + // loop over the yearly buckets and sort those in yearly descending order const yearlyItems = Object.values(bucketsYear) yearlyItems.sort(sortByDateOrYear) diff --git a/src/utils/md-formatter.js b/src/utils/md-formatter.js index 5312b65..89a78ac 100644 --- a/src/utils/md-formatter.js +++ b/src/utils/md-formatter.js @@ -24,7 +24,7 @@ function getTableOfContents(events) { const markdownYearsItems = [] for (const yearlyItems of events) { markdownYearsItems.push( - `[Events in ${yearlyItems.year}](#${yearlyItems.year})` + `[Year of ${yearlyItems.year}](#${yearlyItems.year}) - total events ${yearlyItems.stats.total}` ) } @@ -35,14 +35,48 @@ function getTableOfContents(events) { return json2md(tableOfContents) } +export function getStatsBadges(events) { + const statsBadges = [] + + const badgeForTotalEvents = events.stats.total + ? `![Total Events](https://img.shields.io/badge/total-${events.stats.total}-blue?style=flat-square)` + : 0 + const badgeForTotalConferences = events.stats.total_conference + ? `![Total Conferences](https://img.shields.io/badge/conferences-${events.stats.total_conference}-red?style=flat-square)` + : 0 + const badgeForTotalPodcasts = events.stats.total_podcast + ? `![Total Podcasts](https://img.shields.io/badge/podcasts-${events.stats.total_podcast}-yellow?style=flat-square)` + : 0 + const badgeForTotalWebinars = events.stats.total_webinar + ? `![Total Webinars](https://img.shields.io/badge/webinars-${events.stats.total_webinar}-lightgrey?style=flat-square)` + : 0 + const badgeForTotalMeetups = events.stats.total_meetup + ? `![Total Meetups](https://img.shields.io/badge/meetups-${events.stats.total_meetup}-violet?style=flat-square)` + : 0 + const badgeForTotalArticles = events.stats.total_article + ? `![Total Podcasts](https://img.shields.io/badge/articles-${events.stats.total_article}-green?style=flat-square)` + : 0 + + statsBadges.push({ + p: `${badgeForTotalEvents ? badgeForTotalEvents : ''} ${ + badgeForTotalMeetups ? badgeForTotalMeetups : '' + } ${badgeForTotalConferences ? badgeForTotalConferences : ''} ${ + badgeForTotalPodcasts ? badgeForTotalPodcasts : '' + } ${badgeForTotalWebinars ? badgeForTotalWebinars : ''} ${ + badgeForTotalArticles ? badgeForTotalArticles : '' + }` + }) + + return json2md(statsBadges) + '\n' +} + function eventsListForYear(eventsOfYear) { const eventsByYear = [] + eventsByYear.push({ h1: eventsOfYear.year }) - eventsByYear.push({ - p: `[${eventsOfYear.items.length}] total events for ${eventsOfYear.year}` - }) + eventsByYear.push(getStatsBadges(eventsOfYear)) const eventsTableEntries = [] eventsOfYear.items.forEach((event) => {