Skip to content

Commit a89623c

Browse files
authored
Merge pull request #145 from ContainerMaintainers/development
Report release
2 parents 0d1d79f + bc1e66f commit a89623c

20 files changed

+1077
-377
lines changed

.github/workflows/Automated-Testing.yml

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ on:
44
push:
55
branches:
66
- development
7-
workflow_run:
8-
workflows:
9-
- "Automated Testing"
10-
types:
11-
- completed
7+
- main
8+
pull_request:
129
branches:
1310
- development
11+
- main
1412

1513
jobs:
1614
cypress-test:
@@ -39,3 +37,43 @@ jobs:
3937
uses: cypress-io/github-action@v5.5.1
4038
with:
4139
wait-on: 'http://localhost:8080'
40+
41+
sim-api-test:
42+
runs-on: ubuntu-latest
43+
44+
steps:
45+
- name: Checkout
46+
uses: actions/checkout@v2
47+
48+
49+
- name: Create .env
50+
run: |
51+
touch .env
52+
echo SESSION_KEY="${{ secrets.SESSION_KEY }}" >> .env
53+
echo GIN_MODE="${{ vars.GIN_MODE }}" >> .env
54+
echo PORT="${{ vars.PORT }}" >> .env
55+
56+
- name: Set up Go
57+
uses: actions/setup-go@v4
58+
with:
59+
go-version: 1.19
60+
61+
- name: Run minitwit
62+
run: go run minitwit.go -t &
63+
64+
- name: Sleep for 2 minutes
65+
run: sleep 2m
66+
shell: bash
67+
68+
- name: Install test dependencies
69+
run: |
70+
python -m pip install --upgrade pip
71+
pip install pytest
72+
73+
- name: Site Health Check
74+
uses: pchalupa/site-health-check@v1.0.2
75+
with:
76+
url: 'http://127.0.0.1:8080/'
77+
78+
- name: Run pytest
79+
run: pytest minitwit_sim_api_test.py

CONTRIBUTING.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Branching
2+
There are 2 default branches, one for each environment; `development`
3+
for the `development` environment and `main` for the `production` environment.
4+
5+
The development branch is for testing our code. Here is where every newly developed feature is
6+
merged into as per default when creating a pull requests. This is also where we would discover if any
7+
new features were to introduce unforeseen bugs. It is also the branch that every new feature should
8+
branch out of.
9+
10+
The main branch is our production environment. This is our ”live” code and is what the current
11+
state of our product looks like. This is also to define what is ready to use for our users.
12+
Whenever a new feature is to be initiated, this should happen in a new branch. This new branch
13+
should be named after the new feature. Following this naming convention allows other developers to
14+
keep a track of what each branch is for.
15+
16+
# Workflow
17+
A centralized workflow is to be used for this project.
18+
19+
# Reviewing
20+
There must be at least 1 `approved` review for each pull request. The reviewer must not have contributed to the pull request. Once the pull request has been approved, the branch gets merged into the `development` branch

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 ContainerMaintainers
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
A Golang Gin refactor of the minitwit application.
44

5+
## Before running the application
6+
7+
Make sure docker is installed as well as docker compose.
8+
Furthermore, the docker drive for loki is also required. It can be installed via:
9+
`docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions`
10+
511
## How to run the application
612

713
1. Clone the repo

SLA.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
This Service Level Agreement ("SLA") is entered into by and between Minitwit ("the Service Provider") and the customer ("the Customer").
2+
3+
# Scope
4+
This SLA applies to the Minitwit web-service provided by the Service Provider to the Customer.
5+
6+
# Definitions
7+
- Downtime: Defined as the time where the Minitwit service returns a status code 500.
8+
- Uptime: Defined as the time where the Minitwit service is operational and not experiencing downtime.
9+
- External Factors: Defined as events outside of the Service Provider's control, including but not limited to, acts of nature, acts of terrorism, power failures, or Internet connectivity issues.
10+
- Scheduled Downtime: Any planned maintenance or upgrades to the Minitwit service that are communicated to the Customer at least 72 hours in advance via email or other forms of electronic communication.
11+
12+
# Service Level Objective
13+
The Service Provider guarantees 90% uptime per month for the Minitwit web-service.
14+
15+
# Remedy for Service Failure
16+
If the Service Provider fails to meet the Service Level Objective during any given month, the Customer is entitled to a full refund for that month.
17+
18+
# Exclusions
19+
This SLA does not apply in the event of downtime induced by External Factors or Scheduled Downtime.
20+
21+
# Service Availability Monitoring
22+
The Service Provider will monitor the availability of the Minitwit service 24 hours a day, 7 days a week.
23+
24+
# Availability Reports
25+
The Service Provider will provide monthly uptime and downtime reports to the Customer.
26+
27+
# Modification of SLA
28+
The Service Provider reserves the right to modify this SLA at any time. The Customer will be notified of any changes to this SLA.
29+
30+
# Termination
31+
The Customer may terminate this SLA if the Service Provider fails to meet the Service Level Objective for three consecutive months.
32+
33+
# Governing Law
34+
This SLA shall be governed by and construed in accordance with the laws of the jurisdiction where the Service Provider is located.
35+

controllers/timeline_controller.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,48 @@ import (
88
)
99

1010
// ENDPOINT: GET /
11-
func Timeline(c *gin.Context) {
11+
func IndexTimeline(c *gin.Context) {
12+
page := c.DefaultQuery("page", "0")
1213

13-
// if there is NO session user, show public timeline
1414
if user == -1 {
1515
c.HTML(http.StatusOK, "timeline.html", gin.H{
16-
"messages": GetMessages("public", user, 0),
16+
"messages": GetMessages("public", user, page),
1717
})
1818
} else {
1919
// if there exists a session user, show my timeline
2020
c.HTML(http.StatusOK, "timeline.html", gin.H{
21-
"messages": GetMessages("myTimeline", user, 0),
21+
"messages": GetMessages("myTimeline", user, page),
2222
"user": user,
2323
"username": user_name,
2424
})
2525
}
2626
}
2727

2828
// ENDPOINT: GET /public
29-
func Public(c *gin.Context) {
29+
func Timeline(c *gin.Context) {
30+
page := c.DefaultQuery("page", "0")
3031

3132
if user == -1 {
3233
c.HTML(http.StatusOK, "timeline.html", gin.H{
33-
"messages": GetMessages("public", user, 0),
34+
"messages": GetMessages("public", user, page),
3435
})
3536
} else {
36-
// if there exists a session user, show my timeline
3737
c.HTML(http.StatusOK, "timeline.html", gin.H{
38-
"messages": GetMessages("public", user, 0),
38+
"messages": GetMessages("public", user, page),
3939
"user": user,
4040
"username": user_name,
4141
})
4242
}
43+
4344
}
4445

4546
// ENDPOINT: GET /:username
46-
func Username(c *gin.Context) { // Displays an individual's timeline
47+
func UserTimeline(c *gin.Context) { // Displays an individual's timeline
4748

4849
username := c.Param("username") // gets the <username> from the url
4950
userID, err := getUserId(username)
51+
page := c.DefaultQuery("page", "0")
52+
5053
if err != nil {
5154
log.Print("Bad request during " + c.Request.RequestURI + ": " + " User " + username + " not found")
5255
c.Status(404)
@@ -67,7 +70,7 @@ func Username(c *gin.Context) { // Displays an individual's timeline
6770
"user": user,
6871
"private": true,
6972
"user_page": true,
70-
"messages": GetMessages("myTimeline", user, 0),
73+
"messages": GetMessages("myTimeline", user, page),
7174
"username": username,
7275
})
7376
} else {
@@ -81,7 +84,7 @@ func Username(c *gin.Context) { // Displays an individual's timeline
8184
"user": username,
8285
"followed": followed,
8386
"user_page": users_page,
84-
"messages": GetMessages("individual", int(userID), 0),
87+
"messages": GetMessages("individual", int(userID), page),
8588
})
8689
} else {
8790
// If not following
@@ -92,7 +95,7 @@ func Username(c *gin.Context) { // Displays an individual's timeline
9295
"private": true,
9396
"user": username,
9497
"user_page": users_page,
95-
"messages": GetMessages("individual", int(userID), 0),
98+
"messages": GetMessages("individual", int(userID), page),
9699
})
97100
}
98101
}
@@ -102,7 +105,7 @@ func Username(c *gin.Context) { // Displays an individual's timeline
102105
"title": username + "'s Timeline",
103106
"user_timeline": true,
104107
"private": true,
105-
"messages": GetMessages("individual", int(userID), 0),
108+
"messages": GetMessages("individual", int(userID), page),
106109
})
107110
}
108111
}

controllers/tweets_controller.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"log"
55
"net/http"
66
"time"
7+
"strconv"
78

89
"github.com/ContainerMaintainers/MiniTwit-Golang/database"
910
"github.com/ContainerMaintainers/MiniTwit-Golang/infrastructure/entities"
@@ -22,17 +23,30 @@ type JoinedMessage struct {
2223
FormattedDate string // new variable to hold the formatted date string
2324
}
2425

25-
func GetMessages(timelineType string, user int, pagenum int) []JoinedMessage {
26+
func LimitMessages(page string) (int, int) {
27+
messagesPerPage := 50
28+
p, err := strconv.Atoi(page)
29+
if err != nil {
30+
panic("Failed to parse page number")
31+
}
32+
offset := (p - 1) * messagesPerPage
33+
return offset, messagesPerPage
34+
}
35+
36+
func GetMessages(timelineType string, user int, page string) []JoinedMessage {
37+
38+
//offset:= 1
39+
//messagesPerPage := 1
2640

41+
offset, messagesPerPage := LimitMessages(page)
2742
var joinedMessages []JoinedMessage
2843

2944
if timelineType == "public" {
3045
// Join messages and users tables for public timeline
3146
database.DB.Table("messages").
3247
Select("messages.Author_id", "users.Username", "messages.Text", "messages.Pub_Date").
3348
Joins("left join users on users.id = messages.Author_id").
34-
Offset(pagenum * Per_page).
35-
Limit(Per_page).
49+
Offset(offset).Limit(messagesPerPage).
3650
Order("messages.Pub_Date desc").
3751
Scan(&joinedMessages)
3852

@@ -43,8 +57,7 @@ func GetMessages(timelineType string, user int, pagenum int) []JoinedMessage {
4357
Joins("left join followers on messages.author_id = followers.whom_id").
4458
Joins("left join users on users.id = messages.Author_id").
4559
Where("messages.flagged = ? AND (messages.author_id = ? OR followers.who_id = ?)", false, user, user).
46-
Offset(pagenum * Per_page).
47-
Limit(Per_page).
60+
Offset(offset).Limit(messagesPerPage).
4861
Order("messages.Pub_Date desc").
4962
Scan(&joinedMessages)
5063

@@ -54,8 +67,7 @@ func GetMessages(timelineType string, user int, pagenum int) []JoinedMessage {
5467
Select("messages.Author_id", "users.Username", "messages.Text", "messages.Pub_Date").
5568
Joins("left join users on users.id = messages.Author_id").
5669
Where("messages.flagged = ? AND (messages.author_id = ?)", false, user).
57-
Offset(pagenum * Per_page).
58-
Limit(Per_page).
70+
Offset(offset).Limit(messagesPerPage).
5971
Order("messages.Pub_Date desc").
6072
Scan(&joinedMessages)
6173
}
@@ -105,7 +117,7 @@ func AddMessage(c *gin.Context) { // Registers a new message for the user.
105117
"user": user,
106118
"private": true,
107119
"user_page": true,
108-
"messages": GetMessages("myTimeline", user, 0),
120+
"messages": GetMessages("myTimeline", user, "0"),
109121
"username": username,
110122
})
111123
}

deploy.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ echo "Pulling latest version"
2121
docker pull $1/minitwit:latest
2222
echo "Stopping current minitwit"
2323
docker stop minitwit || true
24+
docker rm minitwit || true
2425
echo "Deploying $DOCKER_USERNAME/minitwit:latest to $PORT"
2526
docker run -d \
2627
-p $2:$2 \

docker-compose.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ services:
7272

7373
grafana:
7474
image: grafana/grafana:9.4.7
75+
container_name: grafana
76+
volumes:
77+
- ./grafana/dashboards:/var/lib/grafana/dashboards
78+
- ./grafana/provisioning:/etc/grafana/provisioning
7579
ports:
7680
- "3000:3000"
7781
networks:

0 commit comments

Comments
 (0)