From 2d144f4ba9d8fbd963373d9a443eb08818631a15 Mon Sep 17 00:00:00 2001 From: Matthew Stead Date: Sat, 27 Nov 2021 00:53:36 +0200 Subject: [PATCH] feat(plugins/community/poopmap): add `poopmap` plugin support (#675) --- source/app/mocks/api/axios/get/poopmap.mjs | 26 +++++++++ source/plugins/poopmap/README.md | 53 +++++++++++++++++++ source/plugins/poopmap/index.mjs | 36 +++++++++++++ source/plugins/poopmap/metadata.yml | 29 ++++++++++ source/plugins/poopmap/tests.yml | 5 ++ source/templates/classic/partials/_.json | 3 +- source/templates/classic/partials/poopmap.ejs | 32 +++++++++++ 7 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 source/app/mocks/api/axios/get/poopmap.mjs create mode 100644 source/plugins/poopmap/README.md create mode 100644 source/plugins/poopmap/index.mjs create mode 100644 source/plugins/poopmap/metadata.yml create mode 100644 source/plugins/poopmap/tests.yml create mode 100644 source/templates/classic/partials/poopmap.ejs diff --git a/source/app/mocks/api/axios/get/poopmap.mjs b/source/app/mocks/api/axios/get/poopmap.mjs new file mode 100644 index 00000000..2b1c23b5 --- /dev/null +++ b/source/app/mocks/api/axios/get/poopmap.mjs @@ -0,0 +1,26 @@ +/**Mocked data */ +export default function({faker, url, options, login = faker.internet.userName()}) { + //Wakatime api + if (/^https:..api.poopmap.net$/.test(url)) { + //Get user profile + if (/public_links\/MOCKED_TOKEN/.test(url)) { + console.debug(`metrics/compute/mocks > mocking poopmap api result > ${url}`) + return ({ + status:200, + data:{ + poops:new Array(12 + faker.datatype.number(6)).fill(null).map(_ => ({ + id:79744699, + latitude:faker.address.latitude(), + longitude:faker.address.longitude(), + created_at:faker.date.past().toISOString(), + note:"", + place:"", + rating:faker.datatype.number(5), + followers_count:faker.datatype.number(100), + comments_count:faker.datatype.number(12) + })) + }, + }) + } + } +} diff --git a/source/plugins/poopmap/README.md b/source/plugins/poopmap/README.md new file mode 100644 index 00000000..fd134eaa --- /dev/null +++ b/source/plugins/poopmap/README.md @@ -0,0 +1,53 @@ +### 💩 PoopMap plugin + +The *poopmap* plugin displays statistics from your [PoopMap](https://poopmap.net) account + + + +
+ + +
+ +
+ 💬 Obtaining a PoopMap token + +First, install the PoopMap app ([iOS](https://itunes.apple.com/us/app/poop-map/id1303269455?mt=8)/[Android](https://play.google.com/store/apps/details?id=net.poopmap)) and create an account. + +Navigate to your profile in the app + +
+ +
+ +Tap "Share Profile" in the top right + +
+ +
+ +Tap "Copy to Clipboard" the copy the link to your clipboard + +
+ +
+ +You should have something like `Haha, check out the places I've pooped on Poop Map https://api.poopmap.net/map?token=xxxxxxxxxx` copied. + +Extract the `token` query paramater from the link + +You now have your PoopMap token! This token will not expire and it can only access public details. +
+ +#### ℹ️ Examples workflows + +[➡️ Available options for this plugin](metadata.yml) + +```yaml +- uses: lowlighter/metrics@latest + with: + # ... other options + plugin_poopmap: yes + plugin_poopmap_token: ${{ secrets.POOPMAP_TOKEN }} # Required + plugin_poopmap_days: 7 # Display last week stats +``` diff --git a/source/plugins/poopmap/index.mjs b/source/plugins/poopmap/index.mjs new file mode 100644 index 00000000..77c41320 --- /dev/null +++ b/source/plugins/poopmap/index.mjs @@ -0,0 +1,36 @@ +//Setup +export default async function({q, imports, data, account}, {enabled = false, token = ""} = {}) { + //Plugin execution + try { + //Check if plugin is enabled and requirements are met + if ((!enabled)||(!q.poopmap)) + return null + + if (!token) return {poops:[], days:7} + + const {days} = imports.metadata.plugins.poopmap.inputs({data, account, q}) + const {data:{poops}} = await imports.axios.get(`https://api.poopmap.net/api/v1/public_links/${token}`) + + const filteredPoops = poops.filter(poop => { + const createdAt = new Date(poop.created_at) + poop.created_at = createdAt.toString() + return createdAt > new Date().getTime() - days * 24 * 60 * 60 * 1000 + }) + + const hours = {max:0} + for (let i = 0; i < filteredPoops.length; i++) { + const poop = filteredPoops[i] + const hour = new Date(poop.created_at).getHours() + hours[hour] = (hours[hour] ?? 0) + 1 + + hours.max = Math.max(hours[hour], hours.max) + } + + //Results + return {poops:hours, days} + } + //Handle errors + catch (error) { + throw {error:{message:"An error occured", instance:error}} + } +} \ No newline at end of file diff --git a/source/plugins/poopmap/metadata.yml b/source/plugins/poopmap/metadata.yml new file mode 100644 index 00000000..351fbe13 --- /dev/null +++ b/source/plugins/poopmap/metadata.yml @@ -0,0 +1,29 @@ +name: "💩 PoopMap plugin" +category: social +index: ~ +supports: + - user +inputs: + + # Enable or disable plugin + plugin_poopmap: + description: Display PoopMap stats + type: boolean + default: no + + # PoopMap API token + plugin_poopmap_token: + description: PoopMap API token + type: token + default: "" + + # Time range to use for displayed stats + plugin_poopmap_days: + description: PoopMap time range + type: string + values: + - 7 # Last week + - 30 # Last month + - 180 # Last 6 months + - 365 # Last year + default: 7 diff --git a/source/plugins/poopmap/tests.yml b/source/plugins/poopmap/tests.yml new file mode 100644 index 00000000..19915904 --- /dev/null +++ b/source/plugins/poopmap/tests.yml @@ -0,0 +1,5 @@ +- name: Poopmap plugin (default) + uses: lowlighter/metrics@latest + with: + token: MOCKED_TOKEN + plugin_poopmap: yes \ No newline at end of file diff --git a/source/templates/classic/partials/_.json b/source/templates/classic/partials/_.json index 96e20eed..5537703d 100644 --- a/source/templates/classic/partials/_.json +++ b/source/templates/classic/partials/_.json @@ -33,5 +33,6 @@ "achievements", "screenshot", "code", - "sponsors" + "sponsors", + "poopmap" ] diff --git a/source/templates/classic/partials/poopmap.ejs b/source/templates/classic/partials/poopmap.ejs new file mode 100644 index 00000000..5544e59a --- /dev/null +++ b/source/templates/classic/partials/poopmap.ejs @@ -0,0 +1,32 @@ +<% if (plugins.poopmap) { %> +
+
+ <% if (plugins.poopmap.error) { %> +
+
+ + <%= plugins.poopmap.error.message %> +
+
+ <% } else { %> +
+

Poops per hour of day

+ over the last <%- plugins.poopmap.days %> days +
+ <% let displayedValues = []; %> + <% let poops = plugins.poopmap.poops %> + <% for (let h = 0; h < 24; h++) { displayedValues.push([h, (poops[h] || 0)/(poops.max || 1), poops[h]]) } %> + + <% for(const [h, percentage, value] of displayedValues) { %> +
+ <%= value %> +
+ <%= `${h}`.padStart(2, 0) %> +
+ <% } %> +
+
+ <% } %> +
+
+<% } %> \ No newline at end of file