Add hashnode support for posts plugin and additional options (#165)

This commit is contained in:
Simon Lecoq
2021-03-02 10:17:00 +01:00
committed by GitHub
parent 4452fa36b5
commit df6638fc9e
8 changed files with 122 additions and 19 deletions

View File

@@ -0,0 +1,23 @@
/**Mocked data */
export default function({faker, url, body, login = faker.internet.userName()}) {
if (/^https:..api.hashnode.com.*$/.test(url)) {
console.debug(`metrics/compute/mocks > mocking hashnode result > ${url}`)
return ({
status:200,
data:{
data:{
user:{
publication:{
posts:new Array(30).fill(null).map(_ => ({
title:faker.lorem.sentence(),
brief:faker.lorem.paragraph(),
coverImage:null,
dateAdded:faker.date.recent(),
})),
},
},
},
},
})
}
}

View File

@@ -344,9 +344,13 @@
...(set.plugins.enabled.posts ? ({
posts:{
source:options["posts.source"],
descriptions:options["posts.descriptions"],
covers:options["posts.covers"],
list:new Array(Number(options["posts.limit"])).fill(null).map(_ => ({
title:faker.lorem.sentence(),
date:faker.date.recent().toString().substring(4, 10).trim()
description:faker.lorem.paragraph(),
date:faker.date.recent(),
image:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
}))
}
}) : null),

View File

@@ -1,5 +1,5 @@
//Setup
export default async function({login, data, imports, q, account}, {enabled = false} = {}) {
export default async function({login, data, imports, q, queries, account}, {enabled = false} = {}) {
//Plugin execution
try {
//Check if plugin is enabled and requirements are met
@@ -7,7 +7,7 @@
return null
//Load inputs
let {source, limit, user} = imports.metadata.plugins.posts.inputs({data, account, q})
let {source, descriptions, covers, limit, user} = imports.metadata.plugins.posts.inputs({data, account, q})
//Retrieve posts
console.debug(`metrics/compute/${login}/plugins > posts > processing with source ${source}`)
@@ -16,7 +16,12 @@
//Dev.to
case "dev.to":{
console.debug(`metrics/compute/${login}/plugins > posts > querying api`)
posts = (await imports.axios.get(`https://dev.to/api/articles?username=${user}&state=fresh`)).data.map(({title, readable_publish_date:date}) => ({title, date}))
posts = (await imports.axios.get(`https://dev.to/api/articles?username=${user}&state=fresh`)).data.map(({title, description, published_at:date, cover_image:image}) => ({title, description, date, image}))
break
}
//Hashnode
case "hashnode":{
posts = (await imports.axios.post("https://api.hashnode.com", {query:queries.posts.hashnode({user})}, {headers:{"Content-type":"application/json"}})).data.data.user.publication.posts.map(({title, brief:description, dateAdded:date, coverImage:image}) => ({title, description, date, image}))
break
}
//Unsupported
@@ -26,13 +31,18 @@
//Format posts
if (Array.isArray(posts)) {
//Limit tracklist
//Limit posts
if (limit > 0) {
console.debug(`metrics/compute/${login}/plugins > posts > keeping only ${limit} posts`)
posts.splice(limit)
}
//Cover images
if (covers) {
console.debug(`metrics/compute/${login}/plugins > posts > formatting cover images`)
posts = await Promise.all(posts.map(async({image, ...post}) => ({image:await imports.imgb64(image, {width:144, height:-1}), ...post})))
}
//Results
return {source, list:posts}
return {source, descriptions, covers, list:posts}
}
//Unhandled error

View File

@@ -19,6 +19,19 @@ inputs:
default: ""
values:
- dev.to # Dev.to
- hashnode
# Display a few lines about each posts
plugin_posts_descriptions:
description: Display posts descriptions
type: boolean
default: no
# Display posts cover images
plugin_posts_covers:
description: Display posts cover images
type: boolean
default: no
# Number of posts to display
plugin_posts_limit:

View File

@@ -0,0 +1,12 @@
query PostsHashnode {
user(username: "$user"){
publication{
posts(page: 1) {
title
brief
coverImage
dateAdded
}
}
}
}

View File

@@ -5,3 +5,11 @@
plugin_posts: yes
plugin_posts_source: dev.to
plugin_posts_user: lowlighter
- name: Posts plugin (hashnode)
uses: lowlighter/metrics@latest
with:
token: NOT_NEEDED
plugin_posts: yes
plugin_posts_source: hashnode
plugin_posts_user: lowlighter

View File

@@ -17,12 +17,22 @@
From <%= plugins.posts.source %>
</div>
<% if (plugins.posts.list.length) { %>
<% for (const {title, date} of plugins.posts.list) { %>
<% for (const {title, description, image, date} of plugins.posts.list) { %>
<div class="field post">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.75 0a.75.75 0 01.75.75V2h5V.75a.75.75 0 011.5 0V2h1.25c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0113.25 16H2.75A1.75 1.75 0 011 14.25V3.75C1 2.784 1.784 2 2.75 2H4V.75A.75.75 0 014.75 0zm0 3.5h8.5a.25.25 0 01.25.25V6h-11V3.75a.25.25 0 01.25-.25h2zm-2.25 4v6.75c0 .138.112.25.25.25h10.5a.25.25 0 00.25-.25V7.5h-11z"></path></svg>
<div class="infos">
<div class="date"><%= date %></div>
<div class="left">
<div class="date"><%= f.date(new Date(date), {dateStyle:"short"}) %></div>
<% if (plugins.posts.covers) { %>
<div class="cover" style="background-image: url(<%= image %>);"></div>
<% } %>
</div>
<div class="right">
<div class="title"><%= title %></div>
<% if (plugins.posts.descriptions) { %>
<div class="description"><%= description %></div>
<% } %>
</div>
</div>
</div>
<% } %>

View File

@@ -287,20 +287,43 @@
display: flex;
margin-bottom: 4px;
}
.post .infos .title {
font-size: 14px;
width: 380px;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
max-height: 40px;;
}
.post .infos .date {
.post .infos .left {
flex-shrink: 0;
font-size: 12px;
color: #666666;
width: 60px;
width: 72px;
padding-top: 1px;
text-align: center;
}
.post .infos .cover {
width: 100%;
height: 56px;
background-position: center;
background-size: cover;
border-radius: 6px;
overflow: hidden;
}
.post .infos .right {
width: 376px;
padding-left: 4px;
}
.post .infos .title, .post .infos .description {
font-size: 14px;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
max-height: 38px;
/* May not work in all browsers */
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.post .infos .description {
margin-top: 3px;
font-size: 12px;
max-height: 48px;
color: #666666;
-webkit-line-clamp: 3;
}
/* Topics */