Skip to content

Commit e576c7e

Browse files
authored
Merge pull request #43 from badging/event-badging-table
API routes for event badging
2 parents 6fd8dbf + f79a6f1 commit e576c7e

File tree

13 files changed

+258
-34
lines changed

13 files changed

+258
-34
lines changed

CONTRIBUTING.md

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Configure MySQL and make sure it is running on your machine before you proceed w
3636

3737
1. You'll need to [create a GitHub OAuth App](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) on your personal GitHub account. Creating a GitHub OAuth App will automatically generate a `Client_ID` and will also enable you to generate a `Client_Secret` for your OAuth App. Store these values safely because they will be needed while generating a `.env` file for the first time.
3838

39-
2. Create your personal [Augur Application](https://projectbadge.chaoss.io/account/settings?section=application) in order to generate an 'augur_client_secret'. Following the link, you will click on "register" and then fill in a couple of fields as required which will set up an account which you will log into. Click on your username(the one you filled in for the "user ID") at the top left and select "profile" which will take you to account settings. Under the account settings, in the left sidebar, click on "applications" and create a new application by entering an App name and a Redirect URL which will generate the `augur_client_secret` which will be listed in the last column of **_Your Apps_** table. Store the `augur_client_secret` together with the above GitHub OAuth credentials since it will be needed too while generating a `.env` file for the first time. The `augur_client_secret` which is the `AUGUR_CLIENT_SECRET` key is used to connect to the Augur API to submit repositories to the Augur Library for further badging.
39+
2. Create your personal [Augur Application](https://projectbadge.chaoss.io/account/settings?section=application) in order to generate an 'augur*client_secret'. Following the link, you will click on "register" and then fill in a couple of fields as required which will set up an account which you will log into. Click on your username(the one you filled in for the "user ID") at the top left and select "profile" which will take you to account settings. Under the account settings, in the left sidebar, click on "applications" and create a new application by entering an App name and a Redirect URL which will generate the `augur_client_secret` which will be listed in the last column of \*\*\_Your Apps*\*\* table. Store the `augur_client_secret` together with the above GitHub OAuth credentials since it will be needed too while generating a `.env` file for the first time. The `augur_client_secret` which is the `AUGUR_CLIENT_SECRET` key is used to connect to the Augur API to submit repositories to the Augur Library for further badging.
4040

4141
After generating those values,
4242

@@ -57,7 +57,7 @@ After generating those values,
5757
npm install # installs packages and dependencies
5858
```
5959

60-
2. **Make sure project is running**: This starts a *.env* configuration process if the *.env* file is missing.
60+
2. **Make sure project is running**: This starts a _.env_ configuration process if the _.env_ file is missing.
6161

6262
```bash
6363
npm run dev # this command will trigger a series of configuration questions in order setup your environmental variables
@@ -98,39 +98,43 @@ BadgingAPI follows a specific code style and coding standards. Please make sure
9898

9999
- **Variables and functions**: camelCase
100100

101-
````markdown
102-
myVariable = 10;
103-
104-
function exampleFunction() {
105-
return "Hello, World!"
106-
};
101+
```markdown
102+
myVariable = 10;
103+
104+
function exampleFunction() {
105+
return "Hello, World!"
106+
};
107+
```
107108

108109
- **Classes and constructors**: PascalCase
109110

110-
````markdown
111-
class MyClass {
112-
constructor(value) {
113-
this.value = value;
114-
}
115-
};
111+
```markdown
112+
class MyClass {
113+
constructor(value) {
114+
this.value = value;
115+
}
116+
};
117+
```
116118

117119
- **Filenames, constants, and environment variables**: Snake_case
118120

119-
````markdown
120-
my_file_name.txt
121+
```markdown
122+
my_file_name.txt
121123

122-
const MAX_ATTEMPTS = 5;
124+
const MAX_ATTEMPTS = 5;
123125

124-
DATABASE_URL = "localhost:3000"
126+
DATABASE_URL = "localhost:3000"
127+
```
125128

126129
- **HTML attributes and CSS class names**: Kebab-case
127130

128-
````markdown
129-
<div class="my-element"></div>
131+
```markdown
132+
<div class="my-element"></div>
130133

131-
.my-element {
132-
color: red;
133-
};
134+
.my-element {
135+
color: red;
136+
};
137+
```
134138

135139
### Issue Tracking
136140

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const Event = require("../models/event.model");
2+
3+
const createEvent = async (event) => {
4+
try {
5+
const { event_name, event_URL, badge, reviewers, application } = event;
6+
7+
const newEvent = await Event.create({
8+
event_name,
9+
event_URL,
10+
badge,
11+
reviewers,
12+
application,
13+
});
14+
15+
console.log(`Event ${newEvent.event_name} created successfully`);
16+
} catch (error) {
17+
console.error(error);
18+
}
19+
};
20+
21+
// Get all Events
22+
const getAllEvents = async (req, res) => {
23+
try {
24+
const events = await Event.findAll();
25+
res.status(200).json(events);
26+
} catch (error) {
27+
res.status(500).json({ error: error.message });
28+
}
29+
};
30+
31+
// Get event by ID
32+
const getEventById = async (req, res) => {
33+
const { id } = req.params;
34+
try {
35+
const event = await Event.findByPk(id);
36+
if (!event) {
37+
return res.status(404).json({ message: "Event not found" });
38+
}
39+
res.status(200).json(event);
40+
} catch (error) {
41+
res.status(500).json({ error: error.message });
42+
}
43+
};
44+
45+
module.exports = {
46+
createEvent,
47+
getAllEvents,
48+
getEventById,
49+
};

database/models/event.model.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const { DataTypes } = require("sequelize");
2+
const sequelize = require("../helpers/sequelize");
3+
4+
const Event = sequelize.define("events", {
5+
date: {
6+
type: DataTypes.DATE,
7+
defaultValue: DataTypes.NOW,
8+
allowNull: false,
9+
},
10+
event_name: {
11+
type: DataTypes.STRING,
12+
allowNull: false,
13+
},
14+
event_URL: {
15+
type: DataTypes.STRING,
16+
allowNull: false,
17+
},
18+
badge: {
19+
type: DataTypes.JSON,
20+
allowNull: false,
21+
},
22+
reviewers: {
23+
type: DataTypes.JSON,
24+
allowNull: false,
25+
validate: {
26+
isValidReviewers(value) {
27+
if (!Array.isArray(value)) {
28+
throw new Error("Reviewers must be an array.");
29+
}
30+
for (const reviewer of value) {
31+
if (typeof reviewer.name !== "string" || reviewer.name.length > 255) {
32+
throw new Error(
33+
"Reviewer name must be a string with max length 255."
34+
);
35+
}
36+
if (!isValidURL(reviewer.github_profile_link)) {
37+
throw new Error("Invalid GitHub profile link format.");
38+
}
39+
}
40+
},
41+
},
42+
},
43+
application: {
44+
type: DataTypes.JSON,
45+
allowNull: false,
46+
},
47+
});
48+
49+
// Helper function to validate URL format
50+
function isValidURL(url) {
51+
try {
52+
new URL(url);
53+
return true;
54+
} catch (error) {
55+
return false;
56+
}
57+
}
58+
59+
module.exports = Event;

event_badging/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
endReview,
66
assignChecklist,
77
updateReadme,
8+
saveEvent,
89
} = require("./logic/index.js");
910

1011
const eventBadging = async (name, octokit, payload) => {
@@ -35,6 +36,7 @@ const eventBadging = async (name, octokit, payload) => {
3536

3637
// when issue is closed, update the readme with the event
3738
if (name === "issues" && payload.action === "closed") {
39+
saveEvent(octokit, payload);
3840
updateReadme(octokit, payload);
3941
}
4042
} else if (

event_badging/logic/calculate.badge.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ const calculateBadge = async (octokit, payload) => {
8989
htmlBadgeImage: htmlBadgeImage,
9090
reviewResult: reviewResult,
9191
reviewerCount: reviewerCount,
92-
assignedBadge: badgeAssigned[0],
92+
assigned_badge: badgeAssigned[0],
93+
badge_URL: url,
9394
};
9495

9596
return messageObj;

event_badging/logic/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ const help = require("./help");
44
const welcome = require("./welcome");
55
const assignChecklist = require("./assignChecklist");
66
const updateReadme = require("./updateReadme");
7+
const saveEvent = require("./saveEvent");
78

89
module.exports = {
910
welcome,
1011
help,
1112
getResults,
1213
endReview,
1314
assignChecklist,
15+
saveEvent,
1416
updateReadme,
1517
};

event_badging/logic/saveEvent.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const { createEvent } = require("../../database/controllers/event.controller");
2+
const calculateBadge = require("./calculate.badge.js");
3+
4+
const saveEvent = async (octokit, payload) => {
5+
let { assigned_badge, badge_URL } = await calculateBadge(octokit, payload); // get badge name
6+
7+
const event_name = payload.issue.title.replace(/\[(.*?)\] /gi, "");
8+
let event_URL;
9+
if (payload.issue.title.includes("[Virtual Event]")) {
10+
event_URL = await payload.issue.body
11+
.slice(
12+
payload.issue.body.indexOf("- Link to the Event Website: "),
13+
payload.issue.body.indexOf(
14+
"- Provide verification that you are an event organizer: "
15+
) - 2
16+
)
17+
.replace("- Link to the Event Website: ", "");
18+
}
19+
20+
if (payload.issue.title.includes("[In-Person Event]")) {
21+
event_URL = await payload.issue.body
22+
.slice(
23+
payload.issue.body.indexOf("- Link to the Event Website: "),
24+
payload.issue.body.indexOf("- Are you an organizer ") - 2
25+
)
26+
.replace("- Link to the Event Website: ", "");
27+
}
28+
// get badge name
29+
const badge = {
30+
name: assigned_badge,
31+
badgeURL: badge_URL,
32+
};
33+
34+
// get array of assignees
35+
const reviewers = await payload.issue.assignees.map((assignee) => {
36+
return {
37+
name: assignee.login,
38+
github_profile_link: assignee.html_url,
39+
};
40+
});
41+
42+
const application = {
43+
app_no: payload.issue.number,
44+
app_URL: payload.issue.html_url,
45+
};
46+
47+
try {
48+
const newEvent = {
49+
event_name,
50+
event_URL,
51+
badge,
52+
reviewers,
53+
application,
54+
};
55+
56+
const event = await createEvent(newEvent);
57+
if (event) {
58+
return event;
59+
} else {
60+
return "";
61+
}
62+
} catch (error) {
63+
console.error(error);
64+
return "";
65+
}
66+
};
67+
68+
module.exports = saveEvent;

event_badging/logic/updateReadme.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const updateReadme = async (octokit, payload) => {
4242
const event = `[${eventName}](${eventLink})`;
4343

4444
// get badge name
45-
const badge = `![${resultsObj.assignedBadge}]`;
45+
const badge = `![${resultsObj.assigned_badge}]`;
4646

4747
// get array of assignees
4848
const reviewers = await payload.issue.assignees.map((assignee) => {

index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ routes.setupRoutes(app);
4242
* The smee.io service is started using the smee.start() method.
4343
*
4444
*/
45+
const SmeeClient = require("smee-client");
4546
if (process.env.NODE_ENV === "development") {
46-
const SmeeClient = require("smee-client");
47-
4847
const smee = new SmeeClient({
4948
source: `${process.env.SMEECLIENT_URL}`,
5049
target: `http://localhost:${process.env.PORT}/api/event_badging`,

package-lock.json

Lines changed: 34 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)