From fff8120daa27727b5597a8cf55ae7b3dcf5187ed Mon Sep 17 00:00:00 2001 From: softsimon Date: Sun, 18 Oct 2020 17:14:35 +0700 Subject: [PATCH] Backend API to load sponsor profile photos. --- backend/src/api/donations.ts | 25 ++++++++++++++++--- backend/src/index.ts | 1 + backend/src/routes.ts | 16 +++++++++++- .../app/components/about/about.component.html | 2 +- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/backend/src/api/donations.ts b/backend/src/api/donations.ts index 195f5db30..6800f2dd3 100644 --- a/backend/src/api/donations.ts +++ b/backend/src/api/donations.ts @@ -13,7 +13,18 @@ class Donations { }, }; + sponsorsCache: any[] = []; + constructor() { + this.$updateCache(); + } + + async $updateCache() { + try { + this.sponsorsCache = await this.$getDonationsFromDatabase('handle, image'); + } catch (e) { + logger.warn('Setting sponsorsCache failed ' + e.message || e); + } } setNotfyDonationStatusCallback(fn: any): void { @@ -73,17 +84,25 @@ class Donations { const imageBlob = await this.$downloadProfileImageBlob(imageUrl); logger.debug('Creating database entry for donation with invoice id: ' + response.id); - this.$addDonationToDatabase(response.btcPaid, userData.screen_name, userData.id, response.id, imageUrl, imageBlob); + await this.$addDonationToDatabase(response.btcPaid, userData.screen_name, userData.id, response.id, imageUrl, imageBlob); + this.$updateCache(); } catch (e) { logger.err(`Error fetching twitter data for handle ${response.orderId}: ${e.message}`); } } } - async $getDonationsFromDatabase(): Promise { + getSponsorImage(id: string): any | undefined { + const sponsor = this.sponsorsCache.find((s) => s.handle === id); + if (sponsor) { + return sponsor.image; + } + } + + async $getDonationsFromDatabase(fields: string): Promise { try { const connection = await DB.pool.getConnection(); - const query = `SELECT handle, imageUrl, TO_BASE64(image) AS image_64 FROM donations WHERE handle != '' ORDER BY id DESC`; + const query = `SELECT ${fields} FROM donations ORDER BY id DESC`; const [rows] = await connection.query(query); connection.release(); return rows; diff --git a/backend/src/index.ts b/backend/src/index.ts index 727a2811d..61da6c764 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -174,6 +174,7 @@ class Server { if (config.BTCPAY_URL) { this.app .get(config.API_ENDPOINT + 'donations', routes.getDonations.bind(routes)) + .get(config.API_ENDPOINT + 'donations/images/:id', routes.getSponsorImage.bind(routes)) .post(config.API_ENDPOINT + 'donations', routes.createDonationRequest.bind(routes)) .post(config.API_ENDPOINT + 'donations-webhook', routes.donationWebhook.bind(routes)) ; diff --git a/backend/src/routes.ts b/backend/src/routes.ts index c07cd2fd7..552c9daec 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -143,13 +143,27 @@ class Routes { public async getDonations(req: Request, res: Response) { try { - const result = await donations.$getDonationsFromDatabase(); + const result = await donations.$getDonationsFromDatabase('handle, imageUrl'); res.json(result); } catch (e) { res.status(500).send(e.message); } } + public async getSponsorImage(req: Request, res: Response) { + try { + const result = await donations.getSponsorImage(req.params.id); + if (result) { + res.set('Content-Type', 'image/jpeg'); + res.send(result); + } else { + res.status(404).end(); + } + } catch (e) { + res.status(500).send(e.message); + } + } + public async donationWebhook(req: Request, res: Response) { try { donations.$handleWebhookRequest(req.body); diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index e84bc3768..86e00d00c 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -54,7 +54,7 @@
- +