From 6f30d477c6dfc584975a90e2812d67aab7f8963f Mon Sep 17 00:00:00 2001 From: Owen Kellogg Date: Tue, 19 Sep 2023 19:47:28 +0200 Subject: [PATCH] API to query content by author --- .../20230919173006-add-auth-to-contents.js | 14 +++++++++ src/models/content.js | 4 ++- src/server.ts | 26 ++++++++++++++++ src/server/handlers/authors.ts | 30 ++++++++++++++++++- 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/migrations/20230919173006-add-auth-to-contents.js diff --git a/src/migrations/20230919173006-add-auth-to-contents.js b/src/migrations/20230919173006-add-auth-to-contents.js new file mode 100644 index 0000000..63a829b --- /dev/null +++ b/src/migrations/20230919173006-add-auth-to-contents.js @@ -0,0 +1,14 @@ +'use strict'; + +/** @type {import('sequelize-cli').Migration} */ +module.exports = { + async up (queryInterface, Sequelize) { + await queryInterface.addColumn('Contents', 'author_paymail', { type: Sequelize.STRING, allowNull: true }); + await queryInterface.addColumn('Contents', 'author_pubkey', { type: Sequelize.STRING, allowNull: true }); + }, + + async down (queryInterface, Sequelize) { + await queryInterface.removeColumn('Contents', 'author_paymail'); + await queryInterface.removeColumn('Contents', 'author_pubkey'); + } +}; diff --git a/src/models/content.js b/src/models/content.js index 34823ea..286baf9 100644 --- a/src/models/content.js +++ b/src/models/content.js @@ -35,7 +35,9 @@ module.exports = (sequelize, DataTypes) => { bmap: DataTypes.JSON, bitchat_channel: DataTypes.STRING, chain: DataTypes.STRING, - context_txid: DataTypes.STRING + context_txid: DataTypes.STRING, + author_paymail: DataTypes.STRING, + author_pubkey: DataTypes.STRING, }, { sequelize, modelName: 'Content', diff --git a/src/server.ts b/src/server.ts index cb77130..1632cc9 100644 --- a/src/server.ts +++ b/src/server.ts @@ -277,6 +277,32 @@ export async function buildServer(): Server { } }) + server.route({ + method: 'GET', + path: '/api/v1/authors/{identity}/contents', + handler: handlers.Authors.listContent, + options: { + description: 'List Content Signed By a Given Author', + notes: 'Returns most recent results first', + tags: ['api', 'authors'], + response: { + failAction: 'log', + schema: Joi.object({ + job: schema.Job + }) + }, + validate: { + params: Joi.object({ + identity: Joi.string().required() + }), + query: Joi.object({ + limit: Joi.number().optional(), + offset: Joi.number().optional(), + }) + } + } + }) + server.route({ method: 'GET', diff --git a/src/server/handlers/authors.ts b/src/server/handlers/authors.ts index 2c6152b..26a5e29 100644 --- a/src/server/handlers/authors.ts +++ b/src/server/handlers/authors.ts @@ -1,5 +1,6 @@ -import models from '../../models' +import { Op } from 'sequelize' +import models, { sequelize } from '../../models' // list authors by difficulty of mined jobs purchased // returns {"address": "difficulty"} @@ -52,3 +53,30 @@ export async function show(req, h) { return { address, jobs } } + +export async function listContent(req, h) { + + if (!req.params.identity) return h.response({ error: 'no identity provided' }).code(400) + + const contents = await models.Content.findAll({ + where: { + [Op.or]: [ + sequelize.where( + sequelize.literal(`bmap#>>'{MAP, 0, paymail}'`), '=', req.params.identity + ), + sequelize.where( + sequelize.literal(`bmap#>>'{MAP, 0, pubkey}'`), '=', req.params.identity + ), + + ] + }, + order: [ + ['id', 'DESC'], + ], + limit: req.query.limit || 100, + offset: req.query.offset || 0 + }); + + return { contents: contents.map(c => c.toJSON()) } + +}