Skip to content

Commit

Permalink
feat: add actions temp files
Browse files Browse the repository at this point in the history
  • Loading branch information
veaba committed Jul 26, 2022
1 parent a46eba5 commit 0ea992b
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/actions/actions-app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// 1. get the repo's contributors list
// 2. generate svg
// 3. save to local
// 4. 根据仓库地址,会保存头像在本地,如果通过actions 触发后,通过对比,本地存在头像则不会再更新
// 4.1 第4点中,bug:如果用户更新,则还是旧头像。出现用户头像,除非用头像生成 md5 存储作为指纹
// import { http } from 'node:http'

import {writeFile} from 'node:fs/promises';
import {chunk} from 'lodash';
import {svgStart, svgEnd, asyncHandleUsersSVG, asyncHandlerUserDefsSVG} from './svg';
import {UserConfig, UserItem} from '../types';
import {getOwnerRepo} from '../utils';

import config from '../../config'
import console from 'node:console';

// global constants
const SVG_WIDTH = 800;
const SVG_HEIGHT = 370;
const FONT_SIZE = 0
const BASE_SIZE = 100

export const generateUserListSVG = async (userList: UserItem[], config: UserConfig) => {

// split => two-dimensional array
let splitList: UserItem[] | UserItem[][] = userList

const svgWidth = config.width || SVG_WIDTH
const svgHeight = config.height || SVG_HEIGHT
const baseSize = config.size || BASE_SIZE
const fontSize = config.fontSize || FONT_SIZE

const isRadius = config.isRadius !== false // default need radius => 50%;
const outSize = fontSize + baseSize
const oneRowMax = Math.floor(svgWidth / outSize)

// split new array
if (userList.length > oneRowMax) {
splitList = chunk(userList, oneRowMax)
}

const svgConfig = {
baseSize,
fontSize,
oneRowMax,
outSize,
svgWidth,
svgHeight,
isRadius,
}

// radius
if (config.isRadius === undefined || config.isRadius === true) {
return `${svgStart(svgWidth, svgHeight)}
<defs>
${await asyncHandlerUserDefsSVG(splitList, svgConfig)}
</defs>
${await asyncHandleUsersSVG(splitList, svgConfig)}
${svgEnd()}
`
} else if (!config.isRadius) {
const userBlockData = await asyncHandleUsersSVG(splitList, svgConfig)
return `${svgStart(svgWidth, svgHeight)}
${userBlockData}
${svgEnd()}
`
}
return ''
}

export const saveSVG = async (ownerRepo: string, userConfig: UserConfig, repoUserList: UserItem[]) => {
console.log('saveSVG=>', ownerRepo, repoUserList.length)
const {owner, repo} = getOwnerRepo && getOwnerRepo(ownerRepo) || {}
if (!owner || !repo) {
console.error('Invalid repo address:', ownerRepo)
return
}
try {
const svgStr = await generateUserListSVG(repoUserList, userConfig)
const filename = `./repos/${owner}/${repo}.svg`
await writeFile(filename, svgStr, {encoding: 'utf-8'})
} catch (error) {
console.error('err=>', error)
}
}

// saveSVG('veaba/contributors',listTen)
// saveSVG('vuejs-translations/docs-zh-cn',listTen)
63 changes: 63 additions & 0 deletions src/actions/actions-github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import axios from "axios"

import { createWriteStream } from 'node:fs'
import { resolve } from 'path'
import { UserConfig, UserItem } from "../types"
import { sortBy } from 'lodash'
import { data } from '../../tests/mock'
import { getTotalList, getOwnerRepo } from "../utils"




/**
* get contributors avatar to public/avatars
*
* 1、TODO check local has been save ?
*
* 2、TODO 通过存在,则通过 md5 判断,一致则略过
*
* 3、TODO 不一致则拉取
*
* 4、TODO if not, get remote data and save to public/avatars
*
* 5、TODO 存储一份本地 avatars 映射的 md5 list
*
*/
export const getRepoData = async (repoKey: string, repoConfig: UserConfig): Promise<UserItem[]> => {
const { owner, repo } = getOwnerRepo(repoKey)

let repData = []
try {
const resp = await axios.get(`http://api.github.com/repos/${repoKey}/stats/contributors`)
if (resp?.data) {
repData = resp.data || []
}
} catch (err) {
console.error('get repo stats contributors err=>')
}
repData = getTotalList(data, repoConfig)

const sortList = sortBy(repData, (item) => -item.total)
return sortList
}


export const downloadAvatar = async (userItem: UserItem) => {
try {
const resp = await axios.get(`https://avatars.githubusercontent.com/u/${userItem.id}?v=4`, {
responseType: "stream"
})

if (resp?.status === 200) {
const writer = createWriteStream(resolve(__dirname, `../public/avatars/${userItem.id}.jpg`),)
resp.data.pipe(writer)
return new Promise((resolve, reject) => {
writer.on('finish', resolve)
writer.on('error', reject)
})
}
} catch (err) {
console.error('err=>', err)
}
}
5 changes: 5 additions & 0 deletions src/actions/actions-image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { readFile } from 'node:fs/promises'
export const imagePathToBase64 = async (imagePath: string) => {
const imageBuffer = await readFile(imagePath)
return imageBuffer.toString('base64')
}
47 changes: 47 additions & 0 deletions src/actions/actions-index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// import config from '../../config'
// import { resolve } from 'path'
// import { saveSVG } from './app';
// import { writeFile, access } from "node:fs/promises" // access
// import { downloadAvatar, getRepoData } from './github';
// import { MD5Item, UserItem } from '../types';
// // import { isHasFile, readMD5 } from "../utils"
//
// import md5JSON from '../../public/avatars/avatarsMD5.json'
//
// const md5s: any = md5JSON
//
// interface TypesContributors {
// repo: string;
// }
//
// const updateAvatars = async (sortList: UserItem[]) => {
// await Promise.all(sortList.map(async userItem => {
//
// const isHas = await isHasFile(resolve(__dirname, `../public/avatars/${userItem.id}.jpg`))
// if (!isHas) {
// return await downloadAvatar(userItem)
// }
// }))
// }
//
// // export const serverStart = async () => {
// // const now = Date.now()
// // console.log('开始=>', new Date())
// //
// // console.time('task=>')
// // const repos = Object.keys(config)
// // // const reposConfigs = Object.values(config)
// //
// // await Promise.all(repos.map(async repo => {
// // const repoConfig = config[repo]
// // const repoList = await getRepoData(repo, repoConfig)
// // await updateAvatars(repoList)
// // await saveSVG(repo, repoList)
// // }))
// //
// // console.timeEnd('task=>')
// // console.log('结束=>', new Date(), Date.now() - now)
// //
// // }
//
// // serverStart()

0 comments on commit 0ea992b

Please sign in to comment.