From 19c26becbf89a400097e73f4a4ea70a42af6f6be Mon Sep 17 00:00:00 2001 From: birna dam Date: Mon, 19 Dec 2022 12:20:36 -0800 Subject: [PATCH 1/9] Send automated email when a project is successful --- shared/package-lock.json | 115 +++++++++++++++++++++++++++++++++++++++ shared/package.json | 1 + shared/scripts/advocu.ts | 36 ++++++++++++ 3 files changed, 152 insertions(+) diff --git a/shared/package-lock.json b/shared/package-lock.json index 9f816ab6c..d8486020c 100644 --- a/shared/package-lock.json +++ b/shared/package-lock.json @@ -10,6 +10,7 @@ "license": "Apache-2.0", "devDependencies": { "@google-cloud/pubsub": "^2.8.0", + "@sendgrid/mail": "^7.7.0", "@types/node": "^16.3.1", "@types/node-fetch": "^2.5.11", "@types/open-graph-scraper": "^4.8.1", @@ -421,6 +422,41 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "dev": true }, + "node_modules/@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "dependencies": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "dependencies": { + "deepmerge": "^4.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "dependencies": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -1151,6 +1187,14 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2427,6 +2471,14 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -3611,6 +3663,25 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -9010,6 +9081,32 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "dev": true }, + "@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "requires": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + } + }, + "@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "requires": { + "deepmerge": "^4.2.2" + } + }, + "@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "requires": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -9602,6 +9699,14 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -10620,6 +10725,11 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -11636,6 +11746,11 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "dev": true }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", diff --git a/shared/package.json b/shared/package.json index e0b6ed67a..667985f9e 100644 --- a/shared/package.json +++ b/shared/package.json @@ -19,6 +19,7 @@ "license": "Apache-2.0", "devDependencies": { "@google-cloud/pubsub": "^2.8.0", + "@sendgrid/mail": "^7.7.0", "@types/node": "^16.3.1", "@types/node-fetch": "^2.5.11", "@types/open-graph-scraper": "^4.8.1", diff --git a/shared/scripts/advocu.ts b/shared/scripts/advocu.ts index a2fa2e34b..1110a97b8 100644 --- a/shared/scripts/advocu.ts +++ b/shared/scripts/advocu.ts @@ -17,6 +17,7 @@ import * as fs from "fs"; import fetch from "node-fetch"; import * as path from "path"; +import sendgrid from "@sendgrid/mail"; import { BlogMetadata } from "../types/BlogMetadata"; import { RepoMetadata } from "../types/RepoMetadata"; @@ -43,6 +44,8 @@ const API_HOST = "https://api-devlibrary.advocu.com"; // API path to get applications const PATH_GET_APPLICATIONS = "/public/applications"; +const SENDGRID_API_KEY = "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"; + function exitWithError(msg: string, code = 1) { console.error(msg); process.exit(code); @@ -90,6 +93,36 @@ interface Application { tags: string[]; } +const sendAutomatedEmail = (email: string, firstName: string, lastName: string) => { + sendgrid.setApiKey(SENDGRID_API_KEY) + + const text = "Dear " + firstName + ", Congratulations, your content has been published" + + " on the Google Dev Library platform. You can view it in your Dev Library author profile" + + "https://devlibrary.withgoogle.com/authors/" + firstName + lastName + + " As next steps, you can also: Subscribe to our newsletter to stay updated with the latest" + + "projects added to Dev Library. Join the Dev Library authors' channel Google Developers" + + " Online Discord public server to connect with other Dev Library authors." + + " Share your success on social media using the hashtag #GoogleDevLibrary" + + const html = `

Dear ${firstName},


Congratulations, your content has been publish on the Google Dev Library platform. You can view it in your Dev Library author profile: https://devlibrary.withgoogle.com/authors/${firstName}${lastName}


As next steps, you can also:



Happy contributing!


Regards,

Google Dev Library Team

` + + const finalEmail = { + from: "library-google-dev@google.com", + to: email, + subject: "[Google Dev Library] Congratulations your content is live", + text: text, + html: html + } + + sendgrid.send(finalEmail) + .then((response) => { + console.log('SendGrid Email sent: ' + response) + }) + .catch((error) => { + console.error(error) + }) +} + function assertNonEmpty(arr: T[]): arr is NonEmptyArray { return arr.length > 0; } @@ -184,6 +217,7 @@ export async function main() { console.log(`Adding ${product} repo ${projectUrl}`); await addRepo(product, projectUrl, /* projectId= */ undefined, metadata); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); } if (a.blogPost) { @@ -199,6 +233,7 @@ export async function main() { /* projectId= */ undefined, metadata ); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); } else { await addOtherBlog( product, @@ -206,6 +241,7 @@ export async function main() { /* projectId= */ undefined, metadata ); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); } } catch (e) { console.error(`Problem occurred when adding a project: ${e}`); From 1355ed07535441c7227aa7ac13420d61b99663df Mon Sep 17 00:00:00 2001 From: birna dam Date: Mon, 19 Dec 2022 12:51:49 -0800 Subject: [PATCH 2/9] Hide sendgrid API key --- shared/.gitignore | 1 + shared/scripts/advocu.ts | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/shared/.gitignore b/shared/.gitignore index 1521c8b76..c327b9d9f 100644 --- a/shared/.gitignore +++ b/shared/.gitignore @@ -1 +1,2 @@ dist +.env \ No newline at end of file diff --git a/shared/scripts/advocu.ts b/shared/scripts/advocu.ts index 1110a97b8..67904a249 100644 --- a/shared/scripts/advocu.ts +++ b/shared/scripts/advocu.ts @@ -44,8 +44,6 @@ const API_HOST = "https://api-devlibrary.advocu.com"; // API path to get applications const PATH_GET_APPLICATIONS = "/public/applications"; -const SENDGRID_API_KEY = "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"; - function exitWithError(msg: string, code = 1) { console.error(msg); process.exit(code); @@ -94,7 +92,11 @@ interface Application { } const sendAutomatedEmail = (email: string, firstName: string, lastName: string) => { - sendgrid.setApiKey(SENDGRID_API_KEY) + const sendGridKey = process.env.SENDGRID_API_KEY; + if (!sendGridKey) { + exitWithError("Error: must set 'SENDGRID_API_KEY' environment variable"); + } + sendgrid.setApiKey(sendGridKey || ""); const text = "Dear " + firstName + ", Congratulations, your content has been published" + " on the Google Dev Library platform. You can view it in your Dev Library author profile" From e6b055f8d90a6ac95202c23a31c6a69cbdf3198c Mon Sep 17 00:00:00 2001 From: birna dam Date: Tue, 20 Dec 2022 10:13:30 -0800 Subject: [PATCH 3/9] target the key placed within our environment --- shared/.gitignore | 3 +-- shared/scripts/advocu.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/shared/.gitignore b/shared/.gitignore index c327b9d9f..53c37a166 100644 --- a/shared/.gitignore +++ b/shared/.gitignore @@ -1,2 +1 @@ -dist -.env \ No newline at end of file +dist \ No newline at end of file diff --git a/shared/scripts/advocu.ts b/shared/scripts/advocu.ts index 9b9679ddb..a9d7c4cdb 100644 --- a/shared/scripts/advocu.ts +++ b/shared/scripts/advocu.ts @@ -92,7 +92,7 @@ interface Application { } const sendAutomatedEmail = (email: string, firstName: string, lastName: string) => { - const sendGridKey = process.env.SENDGRID_API_KEY; + const sendGridKey = process.env.DEVLIBRARYKEY; if (!sendGridKey) { exitWithError("Error: must set 'SENDGRID_API_KEY' environment variable"); } From 5694e70938b6e17f247b89423bad32ecc4138fa2 Mon Sep 17 00:00:00 2001 From: birna dam Date: Thu, 22 Dec 2022 06:20:00 -0800 Subject: [PATCH 4/9] updates to config files after advocu was run --- config/advocu.json | 2 +- .../blogs/p-getting-to-know-cloud-spanner.json | 14 ++++++++++++++ .../cloud/repos/doitintl-QuickQuickstarts.json | 17 +++++++++++++++++ config/firebase/repos/Lessify-localess.json | 18 ++++++++++++++++++ ...2022-12-dev-library-letters-16th-issue.json | 14 ++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 config/cloud/blogs/p-getting-to-know-cloud-spanner.json create mode 100644 config/cloud/repos/doitintl-QuickQuickstarts.json create mode 100644 config/firebase/repos/Lessify-localess.json create mode 100644 config/ml/blogs/2022-12-dev-library-letters-16th-issue.json diff --git a/config/advocu.json b/config/advocu.json index 364208758..e6606dbf3 100644 --- a/config/advocu.json +++ b/config/advocu.json @@ -1,3 +1,3 @@ { - "lastPullTime": 1671526652638 + "lastPullTime": 1671717282122 } \ No newline at end of file diff --git a/config/cloud/blogs/p-getting-to-know-cloud-spanner.json b/config/cloud/blogs/p-getting-to-know-cloud-spanner.json new file mode 100644 index 000000000..7efb683ad --- /dev/null +++ b/config/cloud/blogs/p-getting-to-know-cloud-spanner.json @@ -0,0 +1,14 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Mustapha Adekunle", + "title": "Getting to know Cloud Spanner", + "link": "https://dataengineeringgcp.substack.com/p/getting-to-know-cloud-spanner", + "tags": [ + "databases", + "data-analytics", + "storage" + ] +} diff --git a/config/cloud/repos/doitintl-QuickQuickstarts.json b/config/cloud/repos/doitintl-QuickQuickstarts.json new file mode 100644 index 000000000..7c4b36362 --- /dev/null +++ b/config/cloud/repos/doitintl-QuickQuickstarts.json @@ -0,0 +1,17 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "github", + "authorIds": [], + "owner": "doitintl", + "repo": "QuickQuickstarts", + "name": "QuickQuickstarts", + "shortDescription": "This project spins up a new deployment of GCP App Engine Standard Env, Flexible Env, Cloud Run, Functions, GKE, or 4 different AWS technonologies. This gives an easy way to experiment and learn each.", + "longDescription": "This project spins up a new deployment of GCP App Engine Standard Env, Flexible Env, Cloud Run, Functions, GKE, or 4 different AWS technonologies. This gives an easy way to experiment and learn each.", + "content": "README.md", + "pages": [], + "tags": [ + "serverless-computing", + "compute" + ] +} diff --git a/config/firebase/repos/Lessify-localess.json b/config/firebase/repos/Lessify-localess.json new file mode 100644 index 000000000..79d74d3e7 --- /dev/null +++ b/config/firebase/repos/Lessify-localess.json @@ -0,0 +1,18 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [], + "owner": "Lessify", + "repo": "localess", + "name": "Localess", + "shortDescription": "Translation Management Tools and Content Management Systems with the possibility to collaborate.\nEntirely written in TypeScript and Angular and deployable in Firebase.", + "longDescription": "Translation Management Tools and Content Management Systems with the possibility to collaborate.\nEntirely written in TypeScript and Angular and deployable in Firebase.", + "content": "README.md", + "pages": [], + "tags": [ + "web", + "node", + "admin" + ] +} diff --git a/config/ml/blogs/2022-12-dev-library-letters-16th-issue.json b/config/ml/blogs/2022-12-dev-library-letters-16th-issue.json new file mode 100644 index 000000000..2f3094b09 --- /dev/null +++ b/config/ml/blogs/2022-12-dev-library-letters-16th-issue.json @@ -0,0 +1,14 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Swathi Dharshna", + "title": "Dev Library Letters: 16th Issue", + "link": "https://developers.googleblog.com/2022/12/dev-library-letters-16th-issue.html", + "tags": [ + "web", + "face", + "segmentation" + ] +} From 6e83c16e4bfb6c5372b7694609251770f3dc0607 Mon Sep 17 00:00:00 2001 From: Vishal Das <106949139+gkindavishal@users.noreply.github.com> Date: Fri, 23 Dec 2022 13:15:19 +0530 Subject: [PATCH 5/9] Delete advocu.ts --- shared/scripts/advocu.ts | 273 --------------------------------------- 1 file changed, 273 deletions(-) delete mode 100644 shared/scripts/advocu.ts diff --git a/shared/scripts/advocu.ts b/shared/scripts/advocu.ts deleted file mode 100644 index a9d7c4cdb..000000000 --- a/shared/scripts/advocu.ts +++ /dev/null @@ -1,273 +0,0 @@ -/** - * Copyright 2021 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as fs from "fs"; -import fetch from "node-fetch"; -import * as path from "path"; -import sendgrid from "@sendgrid/mail"; - -import { BlogMetadata } from "../types/BlogMetadata"; -import { RepoMetadata } from "../types/RepoMetadata"; - -import { - addMediumBlog, - addOtherBlog, - addRepo, - parseGithubUrl, -} from "./addproject"; -import { getConfigDir } from "./util"; - -const ADVOCU_METADATA_FILE_NAME = "advocu.json"; - -// Advocu API Staging -// For usage, see: -// https://api-devlibrary-stage.k8s01.nexo.zone/swagger-ui/index.htm const -// API_HOST = "https://api-devlibrary-stage.k8s01.nexo.zone"; - -// Advodu API Prod -// For usage, see: https://api-devlibrary.advocu.com/swagger-ui/index.html -const API_HOST = "https://api-devlibrary.advocu.com"; - -// API path to get applications -const PATH_GET_APPLICATIONS = "/public/applications"; - -function exitWithError(msg: string, code = 1) { - console.error(msg); - process.exit(code); -} - -type NonEmptyArray = [T, ...T[]]; - -interface AdvocuMetadata { - lastPullTime: number; -} - -enum ApplicationStatus { - SUBMITTED = "SUBMITTED", - CONTENT_VERIFICATION_REJECTED = "CONTENT_VERIFICATION_REJECTED", - CONTENT_VERIFICATION_APPROVED = "CONTENT_VERIFICATION_APPROVED", -} - -interface Application { - expertise: string; - id: string; - firstName: string; - lastName: string; - email: string; - avatar: string; - steps: { - contentVerification: { - status: "pending" | "approved"; - dates: { - start: string | null; - review: string | null; - overdue: string | null; - }; - }; - }; - productCategory: string; - blogPost: { url: string; description: string } | null; - github: { - repositoryUrl: string; - profileUrls: string[]; - projectName: string; - licenseConfirmation: boolean; - description: string; - linkToReadme: string; - } | null; - tags: string[]; -} - -const sendAutomatedEmail = (email: string, firstName: string, lastName: string) => { - const sendGridKey = process.env.DEVLIBRARYKEY; - if (!sendGridKey) { - exitWithError("Error: must set 'SENDGRID_API_KEY' environment variable"); - } - sendgrid.setApiKey(sendGridKey || ""); - - const text = "Dear " + firstName + ", Congratulations, your content has been published" - + " on the Google Dev Library platform. You can view it in your Dev Library author profile" - + "https://devlibrary.withgoogle.com/authors/" + firstName + lastName + - " As next steps, you can also: Subscribe to our newsletter to stay updated with the latest" - + "projects added to Dev Library. Join the Dev Library authors' channel Google Developers" - + " Online Discord public server to connect with other Dev Library authors." - + " Share your success on social media using the hashtag #GoogleDevLibrary" - - const html = `

Dear ${firstName},


Congratulations, your content has been publish on the Google Dev Library platform. You can view it in your Dev Library author profile: https://devlibrary.withgoogle.com/authors/${firstName}${lastName}


As next steps, you can also:


  • Subscribe to our newsletter to stay updated with the latest projects added to Dev Library.
  • Join the Dev Library authors’ channel Google Developers Online Discord public server to connect with other Dev Library authors.
  • Share your success on social media using the hashtag #GoogleDevLibrary

Happy contributing!


Regards,

Google Dev Library Team

` - - const finalEmail = { - from: "library-google-dev@google.com", - to: email, - subject: "[Google Dev Library] Congratulations your content is live", - text: text, - html: html - } - - sendgrid.send(finalEmail) - .then((response) => { - console.log('SendGrid Email sent: ' + response) - }) - .catch((error) => { - console.error(error) - }) -} - -function assertNonEmpty(arr: T[]): arr is NonEmptyArray { - return arr.length > 0; -} - -function applicationToRepoMetadata(a: Application): RepoMetadata { - if (!a.github) { - throw new Error(`Application ${a.id} does not have 'github' field`); - } - - if (!assertNonEmpty(a.tags)) { - throw new Error(`Application ${a.id} has empty 'tags' field`); - } - - const { owner, repo } = parseGithubUrl(a.github.repositoryUrl); - - return { - owner, - repo, - name: a.github.projectName, - shortDescription: a.github.description, - longDescription: a.github.description, - content: a.github.linkToReadme, - tags: a.tags, - expertise: a.expertise, // "INTERMEDIATE", - }; -} - -function applicationToBlogMetadata(a: Application): BlogMetadata { - if (!a.blogPost) { - throw new Error(`Application ${a.id} does not have 'blogPost' field`); - } - - if (!assertNonEmpty(a.tags)) { - throw new Error(`Application ${a.id} has empty 'tags' field`); - } - - return { - author: `${a.firstName} ${a.lastName}`, - title: a.blogPost.description, - link: a.blogPost.url, - tags: a.tags, - expertise: a.expertise, //"INTERMEDIATE", - }; -} - -export async function main() { - const advocuToken = process.env.ADVOCU_TOKEN; - if (!advocuToken) { - exitWithError("Error: must set 'ADVOCU_TOKEN' environment variable"); - } - - const advocuMetadataPath = path.join( - getConfigDir(), - ADVOCU_METADATA_FILE_NAME - ); - const advocuMetadata = JSON.parse( - fs.readFileSync(advocuMetadataPath).toString() - ) as AdvocuMetadata; - - const nowDate = new Date(); - const lastPullDate = new Date(advocuMetadata.lastPullTime); - console.log(`Last pull: ${lastPullDate.toISOString()}`); - - const params = { - status: ApplicationStatus.CONTENT_VERIFICATION_APPROVED, - from: lastPullDate.toISOString(), - }; - const encodedParams = Object.entries(params) - .map((entry) => { - return `${encodeURIComponent(entry[0])}=${encodeURIComponent(entry[1])}`; - }) - .join("&"); - - const url = `${API_HOST}${PATH_GET_APPLICATIONS}?${encodedParams}`; - const res = await fetch(url, { - headers: { - Authorization: `Bearer ${advocuToken}`, - }, - }); - - const applications = (await res.json()) as Application[]; - console.log(`New items: ${applications.length}`); - - // For each new application, add the project and the author files - for (const a of applications) { - console.log(); - const product = a.productCategory; - - if (a.github) { - const projectUrl = a.github.repositoryUrl; - const metadata = applicationToRepoMetadata(a); - - console.log(`Adding ${product} repo ${projectUrl}`); - await addRepo(product, projectUrl, /* projectId= */ undefined, metadata); - await sendAutomatedEmail(a.email, a.firstName, a.lastName); - } - - if (a.blogPost) { - const projectUrl = a.blogPost.url; - const metadata = applicationToBlogMetadata(a); - - console.log(`Adding ${product} blog ${projectUrl}`); - try { - if (projectUrl.includes("medium.com")) { - await addMediumBlog( - product, - projectUrl, - /* projectId= */ undefined, - metadata - ); - await sendAutomatedEmail(a.email, a.firstName, a.lastName); - } else { - await addOtherBlog( - product, - projectUrl, - /* projectId= */ undefined, - metadata - ); - await sendAutomatedEmail(a.email, a.firstName, a.lastName); - } - } catch (e) { - console.error(`Problem occurred when adding a project: ${e}`); - console.error(e); - } - } - } - - // Update the advocu metadata file - const newAdvocuMetadata: AdvocuMetadata = { - lastPullTime: nowDate.getTime(), - }; - fs.writeFileSync( - advocuMetadataPath, - JSON.stringify(newAdvocuMetadata, undefined, 2) - ); - - console.log(); - console.log( - "Success! Please 'git commit' any changes and push the new config files." - ); - console.log(); -} - -if (require.main === module) { - main(); -} From 0e35dd846eb9904cfa76ad1cb3ced4700f830c96 Mon Sep 17 00:00:00 2001 From: gkindavishal <106949139+gkindavishal@users.noreply.github.com> Date: Fri, 23 Dec 2022 13:17:50 +0530 Subject: [PATCH 6/9] Create advocu.ts --- shared/scripts/advocu.ts | 273 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 shared/scripts/advocu.ts diff --git a/shared/scripts/advocu.ts b/shared/scripts/advocu.ts new file mode 100644 index 000000000..a9d7c4cdb --- /dev/null +++ b/shared/scripts/advocu.ts @@ -0,0 +1,273 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as fs from "fs"; +import fetch from "node-fetch"; +import * as path from "path"; +import sendgrid from "@sendgrid/mail"; + +import { BlogMetadata } from "../types/BlogMetadata"; +import { RepoMetadata } from "../types/RepoMetadata"; + +import { + addMediumBlog, + addOtherBlog, + addRepo, + parseGithubUrl, +} from "./addproject"; +import { getConfigDir } from "./util"; + +const ADVOCU_METADATA_FILE_NAME = "advocu.json"; + +// Advocu API Staging +// For usage, see: +// https://api-devlibrary-stage.k8s01.nexo.zone/swagger-ui/index.htm const +// API_HOST = "https://api-devlibrary-stage.k8s01.nexo.zone"; + +// Advodu API Prod +// For usage, see: https://api-devlibrary.advocu.com/swagger-ui/index.html +const API_HOST = "https://api-devlibrary.advocu.com"; + +// API path to get applications +const PATH_GET_APPLICATIONS = "/public/applications"; + +function exitWithError(msg: string, code = 1) { + console.error(msg); + process.exit(code); +} + +type NonEmptyArray = [T, ...T[]]; + +interface AdvocuMetadata { + lastPullTime: number; +} + +enum ApplicationStatus { + SUBMITTED = "SUBMITTED", + CONTENT_VERIFICATION_REJECTED = "CONTENT_VERIFICATION_REJECTED", + CONTENT_VERIFICATION_APPROVED = "CONTENT_VERIFICATION_APPROVED", +} + +interface Application { + expertise: string; + id: string; + firstName: string; + lastName: string; + email: string; + avatar: string; + steps: { + contentVerification: { + status: "pending" | "approved"; + dates: { + start: string | null; + review: string | null; + overdue: string | null; + }; + }; + }; + productCategory: string; + blogPost: { url: string; description: string } | null; + github: { + repositoryUrl: string; + profileUrls: string[]; + projectName: string; + licenseConfirmation: boolean; + description: string; + linkToReadme: string; + } | null; + tags: string[]; +} + +const sendAutomatedEmail = (email: string, firstName: string, lastName: string) => { + const sendGridKey = process.env.DEVLIBRARYKEY; + if (!sendGridKey) { + exitWithError("Error: must set 'SENDGRID_API_KEY' environment variable"); + } + sendgrid.setApiKey(sendGridKey || ""); + + const text = "Dear " + firstName + ", Congratulations, your content has been published" + + " on the Google Dev Library platform. You can view it in your Dev Library author profile" + + "https://devlibrary.withgoogle.com/authors/" + firstName + lastName + + " As next steps, you can also: Subscribe to our newsletter to stay updated with the latest" + + "projects added to Dev Library. Join the Dev Library authors' channel Google Developers" + + " Online Discord public server to connect with other Dev Library authors." + + " Share your success on social media using the hashtag #GoogleDevLibrary" + + const html = `

Dear ${firstName},


Congratulations, your content has been publish on the Google Dev Library platform. You can view it in your Dev Library author profile: https://devlibrary.withgoogle.com/authors/${firstName}${lastName}


As next steps, you can also:


  • Subscribe to our newsletter to stay updated with the latest projects added to Dev Library.
  • Join the Dev Library authors’ channel Google Developers Online Discord public server to connect with other Dev Library authors.
  • Share your success on social media using the hashtag #GoogleDevLibrary

Happy contributing!


Regards,

Google Dev Library Team

` + + const finalEmail = { + from: "library-google-dev@google.com", + to: email, + subject: "[Google Dev Library] Congratulations your content is live", + text: text, + html: html + } + + sendgrid.send(finalEmail) + .then((response) => { + console.log('SendGrid Email sent: ' + response) + }) + .catch((error) => { + console.error(error) + }) +} + +function assertNonEmpty(arr: T[]): arr is NonEmptyArray { + return arr.length > 0; +} + +function applicationToRepoMetadata(a: Application): RepoMetadata { + if (!a.github) { + throw new Error(`Application ${a.id} does not have 'github' field`); + } + + if (!assertNonEmpty(a.tags)) { + throw new Error(`Application ${a.id} has empty 'tags' field`); + } + + const { owner, repo } = parseGithubUrl(a.github.repositoryUrl); + + return { + owner, + repo, + name: a.github.projectName, + shortDescription: a.github.description, + longDescription: a.github.description, + content: a.github.linkToReadme, + tags: a.tags, + expertise: a.expertise, // "INTERMEDIATE", + }; +} + +function applicationToBlogMetadata(a: Application): BlogMetadata { + if (!a.blogPost) { + throw new Error(`Application ${a.id} does not have 'blogPost' field`); + } + + if (!assertNonEmpty(a.tags)) { + throw new Error(`Application ${a.id} has empty 'tags' field`); + } + + return { + author: `${a.firstName} ${a.lastName}`, + title: a.blogPost.description, + link: a.blogPost.url, + tags: a.tags, + expertise: a.expertise, //"INTERMEDIATE", + }; +} + +export async function main() { + const advocuToken = process.env.ADVOCU_TOKEN; + if (!advocuToken) { + exitWithError("Error: must set 'ADVOCU_TOKEN' environment variable"); + } + + const advocuMetadataPath = path.join( + getConfigDir(), + ADVOCU_METADATA_FILE_NAME + ); + const advocuMetadata = JSON.parse( + fs.readFileSync(advocuMetadataPath).toString() + ) as AdvocuMetadata; + + const nowDate = new Date(); + const lastPullDate = new Date(advocuMetadata.lastPullTime); + console.log(`Last pull: ${lastPullDate.toISOString()}`); + + const params = { + status: ApplicationStatus.CONTENT_VERIFICATION_APPROVED, + from: lastPullDate.toISOString(), + }; + const encodedParams = Object.entries(params) + .map((entry) => { + return `${encodeURIComponent(entry[0])}=${encodeURIComponent(entry[1])}`; + }) + .join("&"); + + const url = `${API_HOST}${PATH_GET_APPLICATIONS}?${encodedParams}`; + const res = await fetch(url, { + headers: { + Authorization: `Bearer ${advocuToken}`, + }, + }); + + const applications = (await res.json()) as Application[]; + console.log(`New items: ${applications.length}`); + + // For each new application, add the project and the author files + for (const a of applications) { + console.log(); + const product = a.productCategory; + + if (a.github) { + const projectUrl = a.github.repositoryUrl; + const metadata = applicationToRepoMetadata(a); + + console.log(`Adding ${product} repo ${projectUrl}`); + await addRepo(product, projectUrl, /* projectId= */ undefined, metadata); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); + } + + if (a.blogPost) { + const projectUrl = a.blogPost.url; + const metadata = applicationToBlogMetadata(a); + + console.log(`Adding ${product} blog ${projectUrl}`); + try { + if (projectUrl.includes("medium.com")) { + await addMediumBlog( + product, + projectUrl, + /* projectId= */ undefined, + metadata + ); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); + } else { + await addOtherBlog( + product, + projectUrl, + /* projectId= */ undefined, + metadata + ); + await sendAutomatedEmail(a.email, a.firstName, a.lastName); + } + } catch (e) { + console.error(`Problem occurred when adding a project: ${e}`); + console.error(e); + } + } + } + + // Update the advocu metadata file + const newAdvocuMetadata: AdvocuMetadata = { + lastPullTime: nowDate.getTime(), + }; + fs.writeFileSync( + advocuMetadataPath, + JSON.stringify(newAdvocuMetadata, undefined, 2) + ); + + console.log(); + console.log( + "Success! Please 'git commit' any changes and push the new config files." + ); + console.log(); +} + +if (require.main === module) { + main(); +} From 1b999ea5340eb95367b5c28947a254ab3c3d7174 Mon Sep 17 00:00:00 2001 From: birna dam Date: Tue, 3 Jan 2023 12:47:01 -0800 Subject: [PATCH 7/9] sync w/ main and run advocu --- config/advocu.json | 2 +- config/android/blogs/android-kernel-dev.json | 14 +++++++++++++ ...for-a-legacy-application-3bf256df2ebe.json | 14 +++++++++++++ ...tate-restoration-compose-c80c18344f94.json | 16 +++++++++++++++ .../repos/RhymezxCode-SimpleStore.json | 19 ++++++++++++++++++ .../SimformSolutionsPvtLtd-SSImagePicker.json | 20 +++++++++++++++++++ config/authors/aayushkedawat.json | 6 ++++++ config/authors/fluttergems.json | 6 ++++++ config/authors/pgollangi.json | 6 ++++++ ...utomatically-using-google-apps-script.json | 12 +++++++++++ .../blogs/dq-with-dataplex-c1f42195435d.json | 14 +++++++++++++ .../p-getting-to-know-cloud-firestore.json | 14 +++++++++++++ ...sts-deploy-webserver-compute-instance.json | 13 ++++++++++++ .../blogs/posts-gke-workload-identity.json | 14 +++++++++++++ .../blogs/posts-google-secret-manager.json | 13 ++++++++++++ .../cloud/repos/doitintl-ClusterCloner.json | 17 ++++++++++++++++ config/cloud/repos/pgollangi-FireQL.json | 18 +++++++++++++++++ ...gollangi-firestore-grafana-datasource.json | 18 +++++++++++++++++ ...sword-in-jetpack-compose-bd70ca56ea91.json | 13 ++++++++++++ config/flutter/blogs/0SVyAdWNcwb.json | 15 ++++++++++++++ ...on-animations-in-flutter-8886a04fea3c.json | 16 +++++++++++++++ ...in-flutter-with-riverpod-bbde21c187dc.json | 16 +++++++++++++++ ...installation-part-1-of-8-4f703a8cfcc8.json | 14 +++++++++++++ ...mformSolutionsPvtLtd-flutter_chatview.json | 20 +++++++++++++++++++ config/flutter/repos/cfug-diox.json | 18 +++++++++++++++++ ...ssification-2022-12-26-Zero_Shot_CLIP.json | 13 ++++++++++++ ...4-Stable_Diffusion_interpolation_Flax.json | 13 ++++++++++++ ...le_Diffusion_in_Flax_Deep_Dive_Part_I.json | 13 ++++++++++++ ...e_Diffusion_in_Flax_Deep_Dive_Part_II.json | 13 ++++++++++++ ...-Stable_Diffusion_Image2Image_in_Flax.json | 13 ++++++++++++ ...24-Stable_Diffusion_Textual_Inversion.json | 14 +++++++++++++ ...stering-2022-12-15-MeanShift_with_Jax.json | 12 +++++++++++ ...fusion-2022-12-30-Simple_diffusion_TF.json | 14 +++++++++++++ config/ml/repos/radi-cho-create-tf-app.json | 20 +++++++++++++++++++ 34 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 config/android/blogs/android-kernel-dev.json create mode 100644 config/android/blogs/migration-to-jetpack-compose-for-a-legacy-application-3bf256df2ebe.json create mode 100644 config/android/blogs/testing-state-restoration-compose-c80c18344f94.json create mode 100644 config/android/repos/RhymezxCode-SimpleStore.json create mode 100644 config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json create mode 100644 config/authors/aayushkedawat.json create mode 100644 config/authors/fluttergems.json create mode 100644 config/authors/pgollangi.json create mode 100644 config/cloud/blogs/blog-bulk-share-google-drive-file-access-automatically-using-google-apps-script.json create mode 100644 config/cloud/blogs/dq-with-dataplex-c1f42195435d.json create mode 100644 config/cloud/blogs/p-getting-to-know-cloud-firestore.json create mode 100644 config/cloud/blogs/posts-deploy-webserver-compute-instance.json create mode 100644 config/cloud/blogs/posts-gke-workload-identity.json create mode 100644 config/cloud/blogs/posts-google-secret-manager.json create mode 100644 config/cloud/repos/doitintl-ClusterCloner.json create mode 100644 config/cloud/repos/pgollangi-FireQL.json create mode 100644 config/cloud/repos/pgollangi-firestore-grafana-datasource.json create mode 100644 config/firebase/blogs/how-to-authenticate-to-firebase-using-email-and-password-in-jetpack-compose-bd70ca56ea91.json create mode 100644 config/flutter/blogs/0SVyAdWNcwb.json create mode 100644 config/flutter/blogs/adding-page-transition-animations-in-flutter-8886a04fea3c.json create mode 100644 config/flutter/blogs/handle-internet-connectivity-in-flutter-with-riverpod-bbde21c187dc.json create mode 100644 config/flutter/blogs/mastering-dart-flutter-devtools-series-introduction-installation-part-1-of-8-4f703a8cfcc8.json create mode 100644 config/flutter/repos/SimformSolutionsPvtLtd-flutter_chatview.json create mode 100644 config/flutter/repos/cfug-diox.json create mode 100644 config/ml/blogs/notebooks-flax-vision-classification-2022-12-26-Zero_Shot_CLIP.json create mode 100644 config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-14-Stable_Diffusion_interpolation_Flax.json create mode 100644 config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-16-Stable_Diffusion_in_Flax_Deep_Dive_Part_I.json create mode 100644 config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-17-Stable_Diffusion_in_Flax_Deep_Dive_Part_II.json create mode 100644 config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-18-Stable_Diffusion_Image2Image_in_Flax.json create mode 100644 config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-24-Stable_Diffusion_Textual_Inversion.json create mode 100644 config/ml/blogs/notebooks-jax-clustering-2022-12-15-MeanShift_with_Jax.json create mode 100644 config/ml/blogs/notebooks-tensorflow-vision-diffusion-2022-12-30-Simple_diffusion_TF.json create mode 100644 config/ml/repos/radi-cho-create-tf-app.json diff --git a/config/advocu.json b/config/advocu.json index e6606dbf3..0c0025ad8 100644 --- a/config/advocu.json +++ b/config/advocu.json @@ -1,3 +1,3 @@ { - "lastPullTime": 1671717282122 + "lastPullTime": 1672778649448 } \ No newline at end of file diff --git a/config/android/blogs/android-kernel-dev.json b/config/android/blogs/android-kernel-dev.json new file mode 100644 index 000000000..f2929a360 --- /dev/null +++ b/config/android/blogs/android-kernel-dev.json @@ -0,0 +1,14 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Aryan Sinha", + "title": "Introduction to Android Kernel Development", + "link": "https://techyminati.hashnode.dev/android-kernel-dev", + "tags": [ + "modern-android-development", + "build-tools", + "architecture" + ] +} diff --git a/config/android/blogs/migration-to-jetpack-compose-for-a-legacy-application-3bf256df2ebe.json b/config/android/blogs/migration-to-jetpack-compose-for-a-legacy-application-3bf256df2ebe.json new file mode 100644 index 000000000..9f316f90e --- /dev/null +++ b/config/android/blogs/migration-to-jetpack-compose-for-a-legacy-application-3bf256df2ebe.json @@ -0,0 +1,14 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Abhishek Saxena", + "title": "Jetpack Compose Migration: Best Practices and Strategies", + "link": "https://proandroiddev.com/migration-to-jetpack-compose-for-a-legacy-application-3bf256df2ebe#5a6d-3dc64cafdbdf", + "tags": [ + "compose", + "kotlin", + "architecture" + ] +} diff --git a/config/android/blogs/testing-state-restoration-compose-c80c18344f94.json b/config/android/blogs/testing-state-restoration-compose-c80c18344f94.json new file mode 100644 index 000000000..fb2be39e4 --- /dev/null +++ b/config/android/blogs/testing-state-restoration-compose-c80c18344f94.json @@ -0,0 +1,16 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "medium", + "authorIds": [ + "navczydev" + ], + "author": "Nav Singh", + "title": "Testing State restoration - Compose", + "link": "https://navczydev.medium.com/testing-state-restoration-compose-c80c18344f94", + "tags": [ + "compose", + "modern-android-development", + "ui" + ] +} diff --git a/config/android/repos/RhymezxCode-SimpleStore.json b/config/android/repos/RhymezxCode-SimpleStore.json new file mode 100644 index 000000000..427543358 --- /dev/null +++ b/config/android/repos/RhymezxCode-SimpleStore.json @@ -0,0 +1,19 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [ + "rhymezxcode" + ], + "owner": "RhymezxCode", + "repo": "SimpleStore", + "name": "SimpleStore Android Library", + "shortDescription": "A library to create either a shared preference or data store. it has the ability to encrypt on a go, by just signifying on the builder class.", + "longDescription": "A library to create either a shared preference or data store. it has the ability to encrypt on a go, by just signifying on the builder class.", + "content": "https://github.com/RhymezxCode/SimpleStore#readme", + "pages": [], + "tags": [ + "kotlin", + "modern-android-development" + ] +} diff --git a/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json b/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json new file mode 100644 index 000000000..06172b6d9 --- /dev/null +++ b/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json @@ -0,0 +1,20 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [ + "simformsolutionspvtltd" + ], + "owner": "SimformSolutionsPvtLtd", + "repo": "SSImagePicker", + "name": "SSImagePicker", + "shortDescription": "SSImagePicker is easy to use and configurable library to Pick multiple images from the Gallery or Capture an image using Camera with maximum size, extension, crop, rotate, zoom and compress features.", + "longDescription": "SSImagePicker is easy to use and configurable library to Pick multiple images from the Gallery or Capture an image using Camera with maximum size, extension, crop, rotate, zoom and compress features.", + "content": "https://github.com/SimformSolutionsPvtLtd/SSImagePicker/blob/main/README.md", + "pages": [], + "tags": [ + "ui", + "kotlin", + "modern-android-development" + ] +} diff --git a/config/authors/aayushkedawat.json b/config/authors/aayushkedawat.json new file mode 100644 index 000000000..47f97e47e --- /dev/null +++ b/config/authors/aayushkedawat.json @@ -0,0 +1,6 @@ +{ + "name": "Aayush Kedawat", + "bio": "", + "photoURL": "https://miro.medium.com/max/512/0*cKliG3rUww9p66sU.jpg", + "mediumURL": "https://medium.com/@aayushkedawat" +} diff --git a/config/authors/fluttergems.json b/config/authors/fluttergems.json new file mode 100644 index 000000000..1db2f5aaa --- /dev/null +++ b/config/authors/fluttergems.json @@ -0,0 +1,6 @@ +{ + "name": "Flutter Gems", + "bio": "", + "photoURL": "https://miro.medium.com/max/512/0*KnoGsNZD5Ug7uC8x", + "mediumURL": "https://medium.com/@fluttergems" +} diff --git a/config/authors/pgollangi.json b/config/authors/pgollangi.json new file mode 100644 index 000000000..c0304f427 --- /dev/null +++ b/config/authors/pgollangi.json @@ -0,0 +1,6 @@ +{ + "name": "Prasanna Kumar", + "bio": "Programmer 👨‍💻", + "photoURL": "https://avatars.githubusercontent.com/pgollangi", + "githubURL": "https://github.com/pgollangi" +} diff --git a/config/cloud/blogs/blog-bulk-share-google-drive-file-access-automatically-using-google-apps-script.json b/config/cloud/blogs/blog-bulk-share-google-drive-file-access-automatically-using-google-apps-script.json new file mode 100644 index 000000000..f7810cccc --- /dev/null +++ b/config/cloud/blogs/blog-bulk-share-google-drive-file-access-automatically-using-google-apps-script.json @@ -0,0 +1,12 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Aryan Irani", + "title": "Share Google Drive File Access Automatically using Google Apps Script", + "link": "https://chartmat.com/blog/bulk-share-google-drive-file-access-automatically-using-google-apps-script", + "tags": [ + "developer-tools" + ] +} diff --git a/config/cloud/blogs/dq-with-dataplex-c1f42195435d.json b/config/cloud/blogs/dq-with-dataplex-c1f42195435d.json new file mode 100644 index 000000000..c250383bc --- /dev/null +++ b/config/cloud/blogs/dq-with-dataplex-c1f42195435d.json @@ -0,0 +1,14 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "medium", + "authorIds": [ + "mchaphalkar" + ], + "author": "Mandar Chaphalkar", + "title": "Data Governance with Dataplex — A sneak peak into the latest launches", + "link": "https://medium.com/@mchaphalkar/dq-with-dataplex-c1f42195435d", + "tags": [ + "data-analytics" + ] +} diff --git a/config/cloud/blogs/p-getting-to-know-cloud-firestore.json b/config/cloud/blogs/p-getting-to-know-cloud-firestore.json new file mode 100644 index 000000000..f42295a33 --- /dev/null +++ b/config/cloud/blogs/p-getting-to-know-cloud-firestore.json @@ -0,0 +1,14 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Mustapha Adekunle", + "title": "Getting to know Cloud Firestore.", + "link": "https://dataengineeringgcp.substack.com/p/getting-to-know-cloud-firestore", + "tags": [ + "databases", + "serverless-computing", + "storage" + ] +} diff --git a/config/cloud/blogs/posts-deploy-webserver-compute-instance.json b/config/cloud/blogs/posts-deploy-webserver-compute-instance.json new file mode 100644 index 000000000..a24b7c8ec --- /dev/null +++ b/config/cloud/blogs/posts-deploy-webserver-compute-instance.json @@ -0,0 +1,13 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Pradeep Bhadani", + "title": "Deploy Web Server on Google Compute Engine (GCE) with Terraform", + "link": "https://pbhadani.com/posts/deploy-webserver-compute-instance/", + "tags": [ + "compute", + "developer-tools" + ] +} diff --git a/config/cloud/blogs/posts-gke-workload-identity.json b/config/cloud/blogs/posts-gke-workload-identity.json new file mode 100644 index 000000000..0857ee4eb --- /dev/null +++ b/config/cloud/blogs/posts-gke-workload-identity.json @@ -0,0 +1,14 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Pradeep Bhadani", + "title": "Enabling GKE Workload Identity", + "link": "https://pbhadani.com/posts/gke-workload-identity/", + "tags": [ + "containers", + "developer-tools", + "security-identity" + ] +} diff --git a/config/cloud/blogs/posts-google-secret-manager.json b/config/cloud/blogs/posts-google-secret-manager.json new file mode 100644 index 000000000..a12401695 --- /dev/null +++ b/config/cloud/blogs/posts-google-secret-manager.json @@ -0,0 +1,13 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Pradeep Bhadani", + "title": "Let Google do Secret Management", + "link": "https://pbhadani.com/posts/google-secret-manager/", + "tags": [ + "security-identity", + "developer-tools" + ] +} diff --git a/config/cloud/repos/doitintl-ClusterCloner.json b/config/cloud/repos/doitintl-ClusterCloner.json new file mode 100644 index 000000000..8bed3d131 --- /dev/null +++ b/config/cloud/repos/doitintl-ClusterCloner.json @@ -0,0 +1,17 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "github", + "authorIds": [], + "owner": "doitintl", + "repo": "ClusterCloner", + "name": "Cluster Cloner", + "shortDescription": "Kubernetes offers a standard model for orchestrating containers. But the models for infra on which K8s runs are highly nonstandard. This project clones clusters across clouds, exploring these models.", + "longDescription": "Kubernetes offers a standard model for orchestrating containers. But the models for infra on which K8s runs are highly nonstandard. This project clones clusters across clouds, exploring these models.", + "content": "README.md", + "pages": [], + "tags": [ + "compute", + "containers" + ] +} diff --git a/config/cloud/repos/pgollangi-FireQL.json b/config/cloud/repos/pgollangi-FireQL.json new file mode 100644 index 000000000..13268e163 --- /dev/null +++ b/config/cloud/repos/pgollangi-FireQL.json @@ -0,0 +1,18 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "github", + "authorIds": [ + "pgollangi" + ], + "owner": "pgollangi", + "repo": "FireQL", + "name": "FireQL - Query Google Firestore database using SQL", + "shortDescription": "FireQL is a library built on top of the official Google Firestore Client SDK that will allow running queries Cloud Firestore database using SQL syntax", + "longDescription": "FireQL is a library built on top of the official Google Firestore Client SDK that will allow running queries Cloud Firestore database using SQL syntax", + "content": "README.md", + "pages": [], + "tags": [ + "databases" + ] +} diff --git a/config/cloud/repos/pgollangi-firestore-grafana-datasource.json b/config/cloud/repos/pgollangi-firestore-grafana-datasource.json new file mode 100644 index 000000000..118b0340b --- /dev/null +++ b/config/cloud/repos/pgollangi-firestore-grafana-datasource.json @@ -0,0 +1,18 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [ + "pgollangi" + ], + "owner": "pgollangi", + "repo": "firestore-grafana-datasource", + "name": "Google Firestore data source plugin for Grafana", + "shortDescription": "Google Firestore Data Source Plugin for Grafana.\n\nGrafana Firestore Data Source Plugin enables integrating data on Firestore on to Grafana dashboards.", + "longDescription": "Google Firestore Data Source Plugin for Grafana.\n\nGrafana Firestore Data Source Plugin enables integrating data on Firestore on to Grafana dashboards.", + "content": "README.md", + "pages": [], + "tags": [ + "databases" + ] +} diff --git a/config/firebase/blogs/how-to-authenticate-to-firebase-using-email-and-password-in-jetpack-compose-bd70ca56ea91.json b/config/firebase/blogs/how-to-authenticate-to-firebase-using-email-and-password-in-jetpack-compose-bd70ca56ea91.json new file mode 100644 index 000000000..e206d0d42 --- /dev/null +++ b/config/firebase/blogs/how-to-authenticate-to-firebase-using-email-and-password-in-jetpack-compose-bd70ca56ea91.json @@ -0,0 +1,13 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "medium", + "authorIds": [], + "author": "Alex Mamo", + "title": "How to authenticate to Firebase using email and password in Jetpack Compose?", + "link": "https://medium.com/firebase-tips-tricks/how-to-authenticate-to-firebase-using-email-and-password-in-jetpack-compose-bd70ca56ea91", + "tags": [ + "android", + "node" + ] +} diff --git a/config/flutter/blogs/0SVyAdWNcwb.json b/config/flutter/blogs/0SVyAdWNcwb.json new file mode 100644 index 000000000..ab8dbad11 --- /dev/null +++ b/config/flutter/blogs/0SVyAdWNcwb.json @@ -0,0 +1,15 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "medium", + "authorIds": [ + "link" + ], + "author": "BAIMAM BOUKAR JEAN JACQUES", + "title": "Add dynamic theming support to your flutter apps with no stress", + "link": "https://link.medium.com/0SVyAdWNcwb", + "tags": [ + "mobile", + "widgets" + ] +} diff --git a/config/flutter/blogs/adding-page-transition-animations-in-flutter-8886a04fea3c.json b/config/flutter/blogs/adding-page-transition-animations-in-flutter-8886a04fea3c.json new file mode 100644 index 000000000..6c1603b7c --- /dev/null +++ b/config/flutter/blogs/adding-page-transition-animations-in-flutter-8886a04fea3c.json @@ -0,0 +1,16 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "medium", + "authorIds": [ + "aayushkedawat" + ], + "author": "Aayush Kedawat", + "title": "Adding Page Transition Animations in Flutter", + "link": "https://medium.com/@aayushkedawat/adding-page-transition-animations-in-flutter-8886a04fea3c", + "tags": [ + "mobile", + "plugins", + "widgets" + ] +} diff --git a/config/flutter/blogs/handle-internet-connectivity-in-flutter-with-riverpod-bbde21c187dc.json b/config/flutter/blogs/handle-internet-connectivity-in-flutter-with-riverpod-bbde21c187dc.json new file mode 100644 index 000000000..10e266e68 --- /dev/null +++ b/config/flutter/blogs/handle-internet-connectivity-in-flutter-with-riverpod-bbde21c187dc.json @@ -0,0 +1,16 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "medium", + "authorIds": [ + "shreebhagwat94" + ], + "author": "Shree Bhagwat", + "title": "Handle Internet Connectivity In Flutter With Riverpod", + "link": "https://medium.com/@shreebhagwat94/handle-internet-connectivity-in-flutter-with-riverpod-bbde21c187dc", + "tags": [ + "mobile", + "general", + "samples" + ] +} diff --git a/config/flutter/blogs/mastering-dart-flutter-devtools-series-introduction-installation-part-1-of-8-4f703a8cfcc8.json b/config/flutter/blogs/mastering-dart-flutter-devtools-series-introduction-installation-part-1-of-8-4f703a8cfcc8.json new file mode 100644 index 000000000..f5cd2ef32 --- /dev/null +++ b/config/flutter/blogs/mastering-dart-flutter-devtools-series-introduction-installation-part-1-of-8-4f703a8cfcc8.json @@ -0,0 +1,14 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "medium", + "authorIds": [ + "fluttergems" + ], + "author": "Ashita Prasad", + "title": "Mastering Dart & Flutter DevTools — Series Introduction & Installation [Part 1 of 8]", + "link": "https://medium.com/@fluttergems/mastering-dart-flutter-devtools-series-introduction-installation-part-1-of-8-4f703a8cfcc8", + "tags": [ + "general" + ] +} diff --git a/config/flutter/repos/SimformSolutionsPvtLtd-flutter_chatview.json b/config/flutter/repos/SimformSolutionsPvtLtd-flutter_chatview.json new file mode 100644 index 000000000..dd2320262 --- /dev/null +++ b/config/flutter/repos/SimformSolutionsPvtLtd-flutter_chatview.json @@ -0,0 +1,20 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [ + "simformsolutionspvtltd" + ], + "owner": "SimformSolutionsPvtLtd", + "repo": "flutter_chatview", + "name": "flutter_chatview", + "shortDescription": "A Flutter package that allows you to integrate Chat View with highly customization options.", + "longDescription": "A Flutter package that allows you to integrate Chat View with highly customization options.", + "content": "https://github.com/SimformSolutionsPvtLtd/flutter_chatview/blob/main/README.md", + "pages": [], + "tags": [ + "mobile", + "widgets", + "samples" + ] +} diff --git a/config/flutter/repos/cfug-diox.json b/config/flutter/repos/cfug-diox.json new file mode 100644 index 000000000..38ca89be0 --- /dev/null +++ b/config/flutter/repos/cfug-diox.json @@ -0,0 +1,18 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "github", + "authorIds": [], + "owner": "cfug", + "repo": "diox", + "name": "diox", + "shortDescription": "A powerful HTTP client for Dart/Flutter, which supports global configuration, interceptors, FormData, request cancellation, file uploading/downloading, timeout, custom adapters, etc.", + "longDescription": "A powerful HTTP client for Dart/Flutter, which supports global configuration, interceptors, FormData, request cancellation, file uploading/downloading, timeout, custom adapters, etc.", + "content": "https://github.com/cfug/diox/blob/main/README.md", + "pages": [], + "tags": [ + "mobile", + "web", + "plugins" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-classification-2022-12-26-Zero_Shot_CLIP.json b/config/ml/blogs/notebooks-flax-vision-classification-2022-12-26-Zero_Shot_CLIP.json new file mode 100644 index 000000000..0128c4455 --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-classification-2022-12-26-Zero_Shot_CLIP.json @@ -0,0 +1,13 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Zero-Shot image classification with CLIP and Flax", + "link": "https://dzlab.github.io/notebooks/flax/vision/classification/2022/12/26/Zero_Shot_CLIP.html", + "tags": [ + "vision", + "nlp" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-14-Stable_Diffusion_interpolation_Flax.json b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-14-Stable_Diffusion_interpolation_Flax.json new file mode 100644 index 000000000..a39bc9aa8 --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-14-Stable_Diffusion_interpolation_Flax.json @@ -0,0 +1,13 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Interpolation with Stable Diffusion in Flax", + "link": "https://dzlab.github.io/notebooks/flax/vision/diffusion/2022/12/14/Stable_Diffusion_interpolation_Flax.html", + "tags": [ + "vision", + "gan" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-16-Stable_Diffusion_in_Flax_Deep_Dive_Part_I.json b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-16-Stable_Diffusion_in_Flax_Deep_Dive_Part_I.json new file mode 100644 index 000000000..1b9002a51 --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-16-Stable_Diffusion_in_Flax_Deep_Dive_Part_I.json @@ -0,0 +1,13 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Deep Dive into Stable Diffusion - Part I", + "link": "https://dzlab.github.io/notebooks/flax/vision/diffusion/2022/12/16/Stable_Diffusion_in_Flax_Deep_Dive_Part_I.html", + "tags": [ + "vision", + "gan" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-17-Stable_Diffusion_in_Flax_Deep_Dive_Part_II.json b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-17-Stable_Diffusion_in_Flax_Deep_Dive_Part_II.json new file mode 100644 index 000000000..07bfa2c9c --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-17-Stable_Diffusion_in_Flax_Deep_Dive_Part_II.json @@ -0,0 +1,13 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Deep Dive into Stable Diffusion - Part II", + "link": "https://dzlab.github.io/notebooks/flax/vision/diffusion/2022/12/17/Stable_Diffusion_in_Flax_Deep_Dive_Part_II.html", + "tags": [ + "vision", + "gan" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-18-Stable_Diffusion_Image2Image_in_Flax.json b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-18-Stable_Diffusion_Image2Image_in_Flax.json new file mode 100644 index 000000000..863a3725a --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-18-Stable_Diffusion_Image2Image_in_Flax.json @@ -0,0 +1,13 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Image2Image with Stable Diffusion in Flax", + "link": "https://dzlab.github.io/notebooks/flax/vision/diffusion/2022/12/18/Stable_Diffusion_Image2Image_in_Flax.html", + "tags": [ + "vision", + "gan" + ] +} diff --git a/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-24-Stable_Diffusion_Textual_Inversion.json b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-24-Stable_Diffusion_Textual_Inversion.json new file mode 100644 index 000000000..3044af3ac --- /dev/null +++ b/config/ml/blogs/notebooks-flax-vision-diffusion-2022-12-24-Stable_Diffusion_Textual_Inversion.json @@ -0,0 +1,14 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Textual Inversion inference with diffusers and Flax", + "link": "https://dzlab.github.io/notebooks/flax/vision/diffusion/2022/12/24/Stable_Diffusion_Textual_Inversion.html", + "tags": [ + "vision", + "gan", + "nlp" + ] +} diff --git a/config/ml/blogs/notebooks-jax-clustering-2022-12-15-MeanShift_with_Jax.json b/config/ml/blogs/notebooks-jax-clustering-2022-12-15-MeanShift_with_Jax.json new file mode 100644 index 000000000..f32f40a30 --- /dev/null +++ b/config/ml/blogs/notebooks-jax-clustering-2022-12-15-MeanShift_with_Jax.json @@ -0,0 +1,12 @@ +{ + "expertise": "ADVANCED", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Mean Shift clustering with JAX", + "link": "https://dzlab.github.io/notebooks/jax/clustering/2022/12/15/MeanShift_with_Jax.html", + "tags": [ + "python" + ] +} diff --git a/config/ml/blogs/notebooks-tensorflow-vision-diffusion-2022-12-30-Simple_diffusion_TF.json b/config/ml/blogs/notebooks-tensorflow-vision-diffusion-2022-12-30-Simple_diffusion_TF.json new file mode 100644 index 000000000..e14f84897 --- /dev/null +++ b/config/ml/blogs/notebooks-tensorflow-vision-diffusion-2022-12-30-Simple_diffusion_TF.json @@ -0,0 +1,14 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Bachir Chihani", + "title": "Simple diffusion in TensorFlow", + "link": "https://dzlab.github.io/notebooks/tensorflow/vision/diffusion/2022/12/30/Simple_diffusion_TF.html", + "tags": [ + "vision", + "gan", + "tf" + ] +} diff --git a/config/ml/repos/radi-cho-create-tf-app.json b/config/ml/repos/radi-cho-create-tf-app.json new file mode 100644 index 000000000..840700470 --- /dev/null +++ b/config/ml/repos/radi-cho-create-tf-app.json @@ -0,0 +1,20 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "github", + "authorIds": [ + "radi-cho" + ], + "owner": "radi-cho", + "repo": "create-tf-app", + "name": "create-tf-app", + "shortDescription": "Set up and maintain a machine learning project in Tensorflow with a single script", + "longDescription": "Set up and maintain a machine learning project in Tensorflow with a single script", + "content": "README.md", + "pages": [], + "tags": [ + "mlops", + "tf", + "python" + ] +} From 84a8bcee4154acf27d81e35079a76904bed49a6f Mon Sep 17 00:00:00 2001 From: birna dam Date: Tue, 3 Jan 2023 13:05:00 -0800 Subject: [PATCH 8/9] sync and fix errors --- config/advocu.json | 2 +- config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/advocu.json b/config/advocu.json index 0c0025ad8..3bc2fd7b7 100644 --- a/config/advocu.json +++ b/config/advocu.json @@ -1,3 +1,3 @@ { - "lastPullTime": 1672778649448 + "lastPullTime": 1672779867016 } \ No newline at end of file diff --git a/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json b/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json index 06172b6d9..e30bc46c6 100644 --- a/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json +++ b/config/android/repos/SimformSolutionsPvtLtd-SSImagePicker.json @@ -10,7 +10,7 @@ "name": "SSImagePicker", "shortDescription": "SSImagePicker is easy to use and configurable library to Pick multiple images from the Gallery or Capture an image using Camera with maximum size, extension, crop, rotate, zoom and compress features.", "longDescription": "SSImagePicker is easy to use and configurable library to Pick multiple images from the Gallery or Capture an image using Camera with maximum size, extension, crop, rotate, zoom and compress features.", - "content": "https://github.com/SimformSolutionsPvtLtd/SSImagePicker/blob/main/README.md", + "content": "README.md", "pages": [], "tags": [ "ui", From 146b83e1736d59ab209680c03a5e0ac5c780124c Mon Sep 17 00:00:00 2001 From: birna dam Date: Thu, 5 Jan 2023 13:27:50 -0800 Subject: [PATCH 9/9] add files after advocu script was run --- config/advocu.json | 2 +- config/angular/blogs/audience.json | 15 +++++++++++++++ .../blogs/how-to-become-a-react-developer.json | 12 ++++++++++++ config/angular/blogs/test.json | 12 ++++++++++++ config/authors/garima_mehra.json | 6 ++++++ config/cloud/blogs/@DEVELOPERDIGEST.json | 13 +++++++++++++ ...ow-to-build-a-developer-resume-in-english.json | 12 ++++++++++++ 7 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 config/angular/blogs/audience.json create mode 100644 config/angular/blogs/how-to-become-a-react-developer.json create mode 100644 config/angular/blogs/test.json create mode 100644 config/authors/garima_mehra.json create mode 100644 config/cloud/blogs/@DEVELOPERDIGEST.json create mode 100644 config/cloud/blogs/how-to-build-a-developer-resume-in-english.json diff --git a/config/advocu.json b/config/advocu.json index 3bc2fd7b7..76055b2ef 100644 --- a/config/advocu.json +++ b/config/advocu.json @@ -1,3 +1,3 @@ { - "lastPullTime": 1672779867016 + "lastPullTime": 1672811450906 } \ No newline at end of file diff --git a/config/angular/blogs/audience.json b/config/angular/blogs/audience.json new file mode 100644 index 000000000..f1692588a --- /dev/null +++ b/config/angular/blogs/audience.json @@ -0,0 +1,15 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "medium", + "authorIds": [ + "garima_mehra" + ], + "author": "garima mehra", + "title": "Test", + "link": "https://medium.com/@garima_mehra/audience", + "tags": [ + "nlp", + "performance" + ] +} diff --git a/config/angular/blogs/how-to-become-a-react-developer.json b/config/angular/blogs/how-to-become-a-react-developer.json new file mode 100644 index 000000000..94ddb6011 --- /dev/null +++ b/config/angular/blogs/how-to-become-a-react-developer.json @@ -0,0 +1,12 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "other", + "authorIds": [], + "author": "S Swathi Dharshna", + "title": "How to become a REACT developer", + "link": "https://devdigest.hashnode.dev/how-to-become-a-react-developer", + "tags": [ + "performance" + ] +} diff --git a/config/angular/blogs/test.json b/config/angular/blogs/test.json new file mode 100644 index 000000000..cb01d0399 --- /dev/null +++ b/config/angular/blogs/test.json @@ -0,0 +1,12 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Garima Mehra", + "title": "Google Dev Library | What will you build?", + "link": "https://devlibrary.withgoogle.com/test", + "tags": [ + "performance" + ] +} diff --git a/config/authors/garima_mehra.json b/config/authors/garima_mehra.json new file mode 100644 index 000000000..aaed3e263 --- /dev/null +++ b/config/authors/garima_mehra.json @@ -0,0 +1,6 @@ +{ + "name": "Garima Mehra", + "bio": "", + "photoURL": "https://miro.medium.com/max/512/1*_JRKHW74BAXM0709iUIN0g.jpeg", + "mediumURL": "https://medium.com/@garima_mehra" +} diff --git a/config/cloud/blogs/@DEVELOPERDIGEST.json b/config/cloud/blogs/@DEVELOPERDIGEST.json new file mode 100644 index 000000000..fd21207e2 --- /dev/null +++ b/config/cloud/blogs/@DEVELOPERDIGEST.json @@ -0,0 +1,13 @@ +{ + "expertise": "BEGINNER", + "version": 1, + "source": "other", + "authorIds": [], + "author": "Swathi Dharshna", + "title": "Developer Digest — Hashnode", + "link": "https://hashnode.com/@DEVELOPERDIGEST", + "tags": [ + "containers", + "data-analytics" + ] +} diff --git a/config/cloud/blogs/how-to-build-a-developer-resume-in-english.json b/config/cloud/blogs/how-to-build-a-developer-resume-in-english.json new file mode 100644 index 000000000..208729154 --- /dev/null +++ b/config/cloud/blogs/how-to-build-a-developer-resume-in-english.json @@ -0,0 +1,12 @@ +{ + "expertise": "INTERMEDIATE", + "version": 1, + "source": "other", + "authorIds": [], + "author": "S Swathi Dharshna", + "title": "How to Build a Developer Resume (in English)", + "link": "https://devdigest.hashnode.dev/how-to-build-a-developer-resume-in-english", + "tags": [ + "databases" + ] +}