This commit is contained in:
2020-12-19 23:02:07 +01:00
parent 66aa4f957c
commit d71659e50d
16 changed files with 168 additions and 161 deletions

View File

@@ -1,6 +1,6 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Location from "App/Models/Location";
import StoreValidator from "App/Validators/locations/StoreValidator";
import LocationValidator from "App/Validators/location/LocationValidator";
export default class LocationsController {
@@ -20,8 +20,8 @@ export default class LocationsController {
})
}
public async set ({ request, response }: HttpContextContract) {
const data = await request.validate(StoreValidator)
public async add ({ request, response }: HttpContextContract) {
const data = await request.validate(LocationValidator)
await Location.create(data)
return response.status(200).send({
message: 'Location successfully added !'

View File

@@ -0,0 +1,47 @@
import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext";
export default class MeController {
public me ({ response }: HttpContextContract) {
return response.status(200).send({
pronouns: "Arthur",
home: ["Paris", "France"],
passions: [
"Dev",
"DevOps",
"New technologies",
"Gaming"
],
code: [
"Javascript",
"Typescript",
"HTML",
"CSS",
"GoLang",
"Python",
"Java"
],
askMeAbout: [
"Web dev",
"Tech",
"Consulting",
"Cloud native",
"Software dev"
],
technologies: {
webApp: ["VueJs", "NuxtJs", "Sass", "Tailwind"],
desktopApp: ["ElectronJs"],
mobileApp: ["React Native"],
backEnd: {
typescript: ["AdonisJs"],
java: ["Spring"]
},
databases: ["MongoDB", "MariaDB", "Redis"],
messaging: ["RabbitMq"],
other: ["Docker", "Git"],
architecture: ["microservices", "event-driven", "design system pattern"],
operating_systems: ['Windows', 'Linux']
},
})
}
}

View File

@@ -0,0 +1,22 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Project from "App/Models/Project";
import ProjectValidator from "App/Validators/project/ProjectValidator";
export default class ProjectsController {
public async get ({ response }: HttpContextContract) {
const projects = await Project.query().orderBy('progress', 'desc')
return response.status(200).send({
projects
})
}
public async add ({ request, response}: HttpContextContract) {
const data = await request.validate(ProjectValidator)
await Project.create(data)
return response.status(200).send({
message: 'Project successfully created'
})
}
}

View File

@@ -1,5 +1,5 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {getTotalStats, getWeeklyStats, getMonthlyStats, getOtherStats, getDailyStats} from 'App/Helpers/StatsHelper'
import {getTotalStats, getWeeklyStats, getMonthlyStats, getDailyStats} from 'App/Helpers/StatsHelper'
import DockerBuild from "App/Models/DockerBuild"
import DockerCommand from "App/Models/DockerCommand"
@@ -10,13 +10,11 @@ export default class StatsController {
const weekly = await getWeeklyStats()
const monthly = await getMonthlyStats()
const total = await getTotalStats()
const other = await getOtherStats()
return response.status(200).send({
daily: daily,
weekly: weekly,
monthly: monthly,
total: total,
other : other
})
}

View File

@@ -1,15 +1,11 @@
import DockerCommand from "App/Models/DockerCommand";
import axios from "axios";
import DockerBuild from "App/Models/DockerBuild";
async function getDailyStats() {
const commands = await DockerCommand.query().where('created_at', '>', new Date().getTime())
const {data} = await axios.get('https://wakatime.com/api/v1/users/arthurdanjou/stats/last_7_days')
const builds = await DockerBuild.query().where('created_at', '>', new Date().getTime())
console.log('daily : ' + data.data)
return {
development_hours: data.data[0].grand_total.total_seconds / 60 / 60,
docker_commands_run: commands.length,
docker_build_count: builds.length,
}
@@ -17,60 +13,33 @@ async function getDailyStats() {
async function getWeeklyStats() {
const commands = await DockerCommand.query().where('created_at', '>', new Date().getTime() - 1000 * 60 * 60 * 24 * 7)
const {data} = await axios.get('https://wakatime.com/api/v1/users/arthurdanjou/stats/last_7_days')
const builds = await DockerBuild.query().where('created_at', '>', new Date().getTime() - 1000 * 60 * 60 * 24 * 7)
console.log('weekly : ' + data)
return {
development_hours: data.data.total_seconds / 60 / 60,
docker_commands_run: commands.length,
docker_build_count: builds.length,
best_project: data.data.projects
}
}
async function getMonthlyStats() {
const commands = await DockerCommand.query().where('created_at', '>', new Date().getMonth() - 1)
const {data} = await axios.get('https://wakatime.com/api/v1/users/arthurdanjou/stats/last_30_days')
const builds = await DockerBuild.query().where('created_at', '>', new Date().getMonth() - 1)
console.log('monthly : ' + data)
return {
development_hours: data.data.total_seconds / 60 / 60,
docker_commands_run: commands.length,
docker_build_count: builds.length,
best_project: data.data.projects
}
}
async function getTotalStats() {
const commands = await DockerCommand.query()
const {data} = await axios.get('https://wakatime.com/api/v1/users/arthurdanjou/all_time_since_today')
const builds = await DockerBuild.query()
console.log('total : ' + data)
return {
development_hours: data.data.seconds,
docker_commands_run: commands.length,
docker_build_count: builds.length
}
}
async function getOtherStats() {
const {data} = await axios.get('https://wakatime.com/api/v1/users/arthurdanjou/stats/last_year')
console.log('other : ' + data)
return {
daily_average: data.data.daily_average / 60 / 60,
editors: [
'WebStorm',
'Intellij Idea',
'PyCharm',
'GoLang',
'DataGrip'
],
operating_systems: 'Windows'
}
}
export {getMonthlyStats, getTotalStats, getWeeklyStats, getOtherStats, getDailyStats}
export {getMonthlyStats, getTotalStats, getWeeklyStats, getDailyStats}

View File

@@ -1,17 +0,0 @@
import axios from "axios";
import Env from '@ioc:Adonis/Core/Env'
async function login() {
await axios.post("https://wakatime.com/oauth/token",
{
client_id: Env.get('WAKATIME_USERNAME'),
client_secret: Env.get('WAKATIME_PASSWORD')
},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
}
export { login }

25
app/Models/Project.ts Normal file
View File

@@ -0,0 +1,25 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class Project extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public name: string
@column()
public description: string
@column()
public progress: number
@column()
public url: string
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}

View File

@@ -1,7 +1,7 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {schema} from '@ioc:Adonis/Core/Validator'
export default class StoreValidator {
export default class LocationValidator {
constructor (private ctx: HttpContextContract) {
}

View File

@@ -1,25 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class StoreValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string(),
content: schema.string(),
description: schema.string(),
readingTime: schema.number(),
coverId: schema.number([rules.exists({ table: 'files', column: 'id' })]),
tags: schema.array().members(
schema.number()
),
lightBackGround: schema.boolean()
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !',
}
}

View File

@@ -1,25 +0,0 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import {rules, schema} from '@ioc:Adonis/Core/Validator'
export default class UpdateValidator {
constructor (private ctx: HttpContextContract) {
}
public schema = schema.create({
title: schema.string.optional(),
content: schema.string.optional(),
description: schema.string.optional(),
readingTime: schema.number.optional(),
coverId: schema.number.optional([rules.exists({ table: 'files', column: 'id' })]),
tags: schema.array.optional().members(
schema.number()
),
lightBackGround: schema.boolean.optional()
})
public cacheKey = this.ctx.routeKey
public messages = {
required: 'Le champ {{field}} doit être valide !'
}
}

View File

@@ -0,0 +1,19 @@
import { schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class ProjectValidator {
constructor (protected ctx: HttpContextContract) {
}
public schema = schema.create({
name: schema.string(),
description: schema.string(),
progress: schema.number(),
url: schema.string()
})
public messages = {
required: 'Le champ {{field}} doit être valide !',
}
}

View File

@@ -1,23 +0,0 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class DeezerSongs extends BaseSchema {
protected tableName = 'deezer_songs'
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('author')
table.string('title')
table.string('album')
table.string('type')
table.string('device')
table.integer('duration')
table.date('release_date')
table.timestamps(true)
})
}
public async down () {
this.schema.dropTable(this.tableName)
}
}

View File

@@ -0,0 +1,20 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class Projects extends BaseSchema {
protected tableName = 'projects'
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id').primary()
table.string('name')
table.string('description')
table.string('url')
table.integer('progress')
table.timestamps(true)
})
}
public async down () {
this.schema.dropTable(this.tableName)
}
}

View File

@@ -5,66 +5,63 @@ import HealthCheck from "@ioc:Adonis/Core/HealthCheck";
const BASE_URL = "https://api.arthurdanjou.fr"
Route.get('/health', async ({ response }) => {
const report = await HealthCheck.getReport()
return report.healthy ? response.ok(report) : response.badRequest(report)
})
Route.get('/', async ({response}: HttpContextContract) => {
response.status(200).send({
return response.status(200).send({
domain: BASE_URL,
version: "1.0",
source: `${BASE_URL}/source`,
healthCheck: `${BASE_URL}/health`,
routes: {
deezer_data: `${BASE_URL}/deezer`,
arthur_data: `${BASE_URL}/me`,
stats_data: `${BASE_URL}/stats`,
state_data: `${BASE_URL}/state`,
locations_data: `${BASE_URL}/location`,
locations_history: `${BASE_URL}/location/history`,
health: `${BASE_URL}/health`
}
state_data: `${BASE_URL}/states`,
locations_data: `${BASE_URL}/locations`,
locations_history: `${BASE_URL}/locations/history`,
projects: `${BASE_URL}/projects`
},
})
})
/*
TODO
Deezer Songs:
Tasks: kernel : setTimeout or cron
Deezer songs: 1min
*/
Route.get('/source', async ({response}: HttpContextContract) => {
return response.redirect('https://github.com/arthurdanjou/artapi')
})
Route.get('/location', 'LocationsController.get')
Route.get('/location/history', 'LocationsController.history')
Route.get('health', async ({response}: HttpContextContract) => {
const report = await HealthCheck.getReport()
return report.healthy ? response.ok(report) : response.badRequest(report)
})
Route.get('/me', 'MeController.me')
Route.get('/locations', 'LocationsController.get')
Route.get('/locations/history', 'LocationsController.history')
Route.get('/stats', 'StatsController.get')
Route.get('/state', 'StatesController.get')
Route.get('/states', 'StatesController.get')
Route.get('/projects', 'ProjectsController.get')
Route.resource('users', 'UsersController').only(['index', 'show'])
Route.get('/posts/:slug', 'PostsController.getLikes')
Route.get('/posts/is/:slug', 'PostsController.isLiked')
Route.post('/posts/:slug/like', 'PostsController.like')
Route.post('/posts/:slug/unlike', 'PostsController.unlike')
Route.resource('subscribers', 'SubscribersController').only(['index', 'show'])
Route.resource('files', 'FileController').only(['index'])
Route.get('/files/:filename', async ({ response, params }) => {
response.download(Application.makePath('storage', params.filename))
})
Route.group(() => {
Route.get('/', 'FileController.index')
Route.get('/:filename', async ({ response, params }) => {
response.download(Application.makePath('storage', params.filename))
})
}).prefix('/files')
Route.group(() => {
Route.resource('users', 'UsersController').only(['store', 'update', 'destroy'])
Route.resource('posts', 'PostsController').only(['store', 'update', 'destroy'])
Route.resource('subscribers', 'SubscribersController').only(['store', 'update', 'destroy'])
Route.resource('files', 'FileController').only(['store', 'destroy'])
Route.post('/state', 'StatesController.set')
Route.post('/states', 'StatesController.set')
Route.post('/stats/build', 'StatesController.incrementBuild')
Route.post('/stats/command', 'StatesController.incrementCommand')
Route.post('/location', 'StatesController.set')
Route.post('/locations', 'StatesController.add')
Route.post('/projects', 'ProjectsController.add')
}).middleware('auth')
Route.group(() => {