Compare commits

...

2 Commits

2 changed files with 28 additions and 27 deletions

View File

@ -3,7 +3,7 @@
This allows you to host custom (known as 3rd party) App Market repositories of WebDesk applications. This allows you to host custom (known as 3rd party) App Market repositories of WebDesk applications.
## Features ## Features
- Listing currently uploaded apps (/apps endpoint) - Listing currently uploaded apps (/apps endpoint and root of web server)
- Showing app source code (under /uploads/app_name/index.js) - Showing app source code (under /uploads/app_name/index.js)
- Uploading new apps (/apps endpoint with Bearer token) - Uploading new apps (/apps endpoint with Bearer token)
- Editing app info (/editapp endpoint with Bearer token) - Editing app info (/editapp endpoint with Bearer token)

53
main.go
View File

@ -46,7 +46,7 @@ func init() {
} }
websrvport := os.Getenv("PORT") websrvport := os.Getenv("PORT")
if websrvport == "" { if websrvport == "" {
websrvport = "8080" websrvport = "8080"
} }
fmt.Printf("Starting web server on port %s\n", websrvport) fmt.Printf("Starting web server on port %s\n", websrvport)
} }
@ -77,20 +77,26 @@ func main() {
// Serve static files // Serve static files
r.Static("/apps/files", "./apps/files") r.Static("/apps/files", "./apps/files")
// Handler function for getting apps list
getAppsHandler := func(c *gin.Context) {
data, err := ioutil.ReadFile("apps.json")
if err != nil {
c.JSON(http.StatusOK, []App{})
return
}
var apps []App
json.Unmarshal(data, &apps)
c.JSON(http.StatusOK, apps)
}
// Serve apps list on root path
r.GET("/", getAppsHandler)
// Group routes for /apps // Group routes for /apps
apps := r.Group("/apps") apps := r.Group("/apps")
{ {
apps.GET("", func(c *gin.Context) { apps.GET("", getAppsHandler)
data, err := ioutil.ReadFile("apps.json")
if err != nil {
c.JSON(http.StatusOK, []App{})
return
}
var apps []App
json.Unmarshal(data, &apps)
c.JSON(http.StatusOK, apps)
})
// Handle other methods for /apps // Handle other methods for /apps
apps.Handle("POST", "", methodNotAllowedHandler("GET")) apps.Handle("POST", "", methodNotAllowedHandler("GET"))
apps.Handle("PUT", "", methodNotAllowedHandler("GET")) apps.Handle("PUT", "", methodNotAllowedHandler("GET"))
@ -109,17 +115,21 @@ func main() {
return return
} }
var metadata AppMetadata var metadata struct {
AppMetadata
AppID string `json:"appid,omitempty"`
}
if err := json.Unmarshal([]byte(metadataStr), &metadata); err != nil { if err := json.Unmarshal([]byte(metadataStr), &metadata); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid metadata"}) c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid metadata"})
return return
} }
// Generate 12-digit app ID appID := metadata.AppID
rand.Seed(time.Now().UnixNano()) if appID == "" {
appID := fmt.Sprintf("%012d", rand.Intn(1000000000000)) rand.Seed(time.Now().UnixNano())
appID = fmt.Sprintf("%012d", rand.Intn(1000000000000))
}
// Create new app entry
newApp := App{ newApp := App{
Name: metadata.Name, Name: metadata.Name,
Ver: metadata.Ver, Ver: metadata.Ver,
@ -129,7 +139,6 @@ func main() {
Path: fmt.Sprintf("/apps/files/%s_%s%s", metadata.Name, metadata.Ver, filepath.Ext(file.Filename)), Path: fmt.Sprintf("/apps/files/%s_%s%s", metadata.Name, metadata.Ver, filepath.Ext(file.Filename)),
} }
// Save file
if err := os.MkdirAll("apps/files", 0755); err != nil { if err := os.MkdirAll("apps/files", 0755); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create directory"}) c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create directory"})
return return
@ -140,7 +149,6 @@ func main() {
return return
} }
// Update apps.json
var apps []App var apps []App
data, _ := ioutil.ReadFile("apps.json") data, _ := ioutil.ReadFile("apps.json")
json.Unmarshal(data, &apps) json.Unmarshal(data, &apps)
@ -160,7 +168,6 @@ func main() {
editapp := r.Group("/editapp") editapp := r.Group("/editapp")
{ {
editapp.PUT("", authMiddleware(), func(c *gin.Context) { editapp.PUT("", authMiddleware(), func(c *gin.Context) {
// Get metadata from form
metadataStr := c.PostForm("metadata") metadataStr := c.PostForm("metadata")
if metadataStr == "" { if metadataStr == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Metadata is required"}) c.JSON(http.StatusBadRequest, gin.H{"error": "Metadata is required"})
@ -189,17 +196,13 @@ func main() {
apps[i].Ver = updateData.App.Ver apps[i].Ver = updateData.App.Ver
apps[i].Info = updateData.App.Info apps[i].Info = updateData.App.Info
// Handle file update if provided
if file, err := c.FormFile("file"); err == nil { if file, err := c.FormFile("file"); err == nil {
// Delete old file
os.Remove(oldFilePath) os.Remove(oldFilePath)
// Generate new path
newPath := fmt.Sprintf("/apps/files/%s_%s%s", newPath := fmt.Sprintf("/apps/files/%s_%s%s",
apps[i].Name, apps[i].Ver, filepath.Ext(file.Filename)) apps[i].Name, apps[i].Ver, filepath.Ext(file.Filename))
apps[i].Path = newPath apps[i].Path = newPath
// Save new file
if err := c.SaveUploadedFile(file, "."+newPath); err != nil { if err := c.SaveUploadedFile(file, "."+newPath); err != nil {
c.JSON(http.StatusInternalServerError, c.JSON(http.StatusInternalServerError,
gin.H{"error": "Failed to save new file"}) gin.H{"error": "Failed to save new file"})
@ -260,10 +263,8 @@ func main() {
return return
} }
// Delete the file
os.Remove(filePath) os.Remove(filePath)
// Update apps.json
appsJSON, _ := json.Marshal(apps) appsJSON, _ := json.Marshal(apps)
ioutil.WriteFile("apps.json", appsJSON, 0644) ioutil.WriteFile("apps.json", appsJSON, 0644)
c.JSON(http.StatusOK, gin.H{"message": "App deleted successfully"}) c.JSON(http.StatusOK, gin.H{"message": "App deleted successfully"})