Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ type API interface {

type APIv1 struct {
engine *gin.Engine
apiGroup *gin.RouterGroup
host string
port string
ApiGroup *gin.RouterGroup
Host string
Port string
}

type APIRouteRegistrar interface {
Expand All @@ -33,19 +33,19 @@ type APIOption func(*APIv1)
func WithGroup(group string) APIOption {
// Expects '/v1' as the group
return func(a *APIv1) {
a.apiGroup = a.engine.Group(group)
a.ApiGroup = a.engine.Group(group)
}
}

func WithHost(host string) APIOption {
return func(a *APIv1) {
a.host = host
a.Host = host
}
}

func WithPort(port string) APIOption {
return func(a *APIv1) {
a.port = port
a.Port = port
}
}

Expand All @@ -56,8 +56,8 @@ func New(debug bool, options ...APIOption) *APIv1 {
once.Do(func() {
apiInstance = &APIv1{
engine: ConfigureRouter(debug),
host: "localhost",
port: "8080",
Host: "localhost",
Port: "8080",
}
for _, opt := range options {
opt(apiInstance)
Expand Down Expand Up @@ -87,7 +87,7 @@ func (a *APIv1) Engine() *gin.Engine {
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
func (a *APIv1) Start() error {
address := a.host + ":" + a.port
address := a.Host + ":" + a.Port
// Use buffered channel to not block goroutine
errChan := make(chan error, 1)

Expand Down Expand Up @@ -132,8 +132,8 @@ func (a *APIv1) AddRoute(method, path string, handler gin.HandlerFunc) {

// Check if a specific apiGroup is set
// If so, add the route to it. Otherwise, add to the main engine.
if a.apiGroup != nil {
addRouteToTarget(a.apiGroup)
if a.ApiGroup != nil {
addRouteToTarget(a.ApiGroup)
} else {
addRouteToTarget(a.engine)
}
Expand Down
2 changes: 1 addition & 1 deletion api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
)

func TestRouteRegistration(t *testing.T) {

// Initialize the API and set it to debug mode for testing
apiInstance := api.New(true)

// Check if Fcm implements APIRouteRegistrar and register its routes
// TODO: update this with actual plugin
pushPlugin := &push.PushOutput{}
if registrar, ok := interface{}(pushPlugin).(api.APIRouteRegistrar); ok {
registrar.RegisterRoutes()
Expand Down
2 changes: 1 addition & 1 deletion cmd/snek/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func main() {
}

// Create API instance with debug disabled
apiInstance := api.New(true,
apiInstance := api.New(false,
api.WithGroup("/v1"),
api.WithPort("8080"))

Expand Down
8 changes: 8 additions & 0 deletions output/push/api_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ func (p *PushOutput) RegisterRoutes() {
}

apiInstance := api.GetInstance()
var apiEndpoint string
if apiInstance.ApiGroup != nil {
apiEndpoint = apiInstance.Host + apiInstance.ApiGroup.BasePath() + "/fcm"
} else {
apiEndpoint = apiInstance.Host + "/fcm"
}

apiInstance.AddRoute("POST", "/fcm", storeFCMToken)
apiInstance.AddRoute("POST", "/fcm/", storeFCMToken)
Expand All @@ -37,5 +43,7 @@ func (p *PushOutput) RegisterRoutes() {
apiInstance.AddRoute("DELETE", "/fcm/:token", deleteFCMToken)
apiInstance.AddRoute("DELETE", "/fcm/:token/", deleteFCMToken)

apiInstance.AddRoute("GET", "/qrcode", generateQRPage(apiEndpoint))

routesRegistered = true
}
65 changes: 65 additions & 0 deletions output/push/qr_generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package push

import (
"encoding/json"
"fmt"
"net/http"
"text/template"

"github.com/gin-gonic/gin"
)

type QRValue struct {
ApiEndpoint string `json:"apiEndpoint"`
}

func generateQRPage(apiEndpoint string) gin.HandlerFunc {
return func(c *gin.Context) {
qrValue, err := json.Marshal(QRValue{
ApiEndpoint: apiEndpoint,
})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}

qrValueEscaped := template.JSEscapeString(string(qrValue))

htmlContent := fmt.Sprintf(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QR Code</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/qrious@latest/dist/qrious.min.js"></script>
</head>
<body class="bg-gray-100 h-screen flex items-center justify-center">
<!-- QR Code Container -->
<div class="bg-white p-8 rounded-lg shadow-md text-center">
<p class="text-xl mb-4">Scan QR code with Snek Mobile to connect to the Snek Server on <span class="font-semibold">%s</span></p>
<canvas id="qrCanvas" class="mx-auto"></canvas>
</div>

<!-- Generate QR Code using JavaScript -->
<script>
window.onload = function() {
const canvas = document.getElementById('qrCanvas');
const qrValue = "%s";
const qr = new QRious({
element: canvas,
value: qrValue,
size: 250
});
}
</script>
</body>
</html>
`, apiEndpoint, qrValueEscaped)

c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(htmlContent))
}
}