The page you are looking for could not be found. Please check the URL or go back to the homepage. 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /assets/public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 |Please, share your observations with us!
7 | 12 | 62 |{ p.AuthorName }
25 |Sorry about that!
22 |Please try again a couple more times to drive the point home!
23 |Sorry about that! Please visit our hompage to get where you need to go.
25 | Take me there! 26 |Sorry about that!
24 |Please try again a couple more times to drive the point home!
25 |{ c.Count } artists
56 |85 | ARTIST 86 | | 87 |88 | BORN-DIED 89 | | 90 |91 | School(s) 92 | | 93 |94 | Profession 95 | | 96 |
---|---|---|---|
102 | 103 | 104 | @templ.Raw(HighlightArtistName(a.Name, query)) 105 | 106 | 107 | | 108 |{ a.BornDied } | 109 |{ a.Schools } | 110 |{ a.Profession } | 111 |
117 | ARTIST 118 | | 119 |120 | BORN-DIED 121 | | 122 |123 | PERIOD 124 | | 125 |126 | SCHOOL 127 | | 128 |
This is a random selection from the database to inspire you! If you need new inspiration, just hit refresh!
23 | @components.ImageGridComponent(c, true) 24 |{ p.Technique }
37 |17 | Please select one of the musical pieces from the list below. Please note that this is neither a comprehensive nor a representative musical collection. Its only aim is to provide a selection of matching classical music to listen while viewing and studying the old masters' works. The musical pieces were selected in such a way that visitors could find music matching the stylistic periods from the Renaissance to Romanticism. Whenever possible we call the visitors' attention to musical pieces (mainly operas) treating the same subject as a particular painting or sculpture. For this reason the suggested listenings include music from periods different from that of the creation of the artworks. 18 |
19 |20 | {{range .Centuries}} 21 | {{.}}th | 22 | {{end}} 23 | century 24 |
25 |
17 | Title: {{.Title}}
18 | from {{.Date}}
19 |
{{ .AwTechnique }}
21 |!!!
" 15 | // record.Set("content", content) 16 | 17 | return nil 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /mailpit.log: -------------------------------------------------------------------------------- 1 | time="2024/07/31 06:28:33" level=debug msg="[db] using temporary database: /tmp/nix-shell.g5ysBe/mailpit-1722400113006046905.db" 2 | time="2024/07/31 06:28:33" level=debug msg="[db] opening database /tmp/nix-shell.g5ysBe/mailpit-1722400113006046905.db" 3 | time="2024/07/31 06:28:33" level=info msg="[smtpd] starting on [::]:1025 (no encryption)" 4 | time="2024/07/31 06:28:33" level=error msg="listen tcp 0.0.0.0:1025: bind: address already in use" 5 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/blackfyre/wga/crontab" 8 | "github.com/blackfyre/wga/handlers" 9 | "github.com/blackfyre/wga/hooks" 10 | _ "github.com/blackfyre/wga/migrations" 11 | 12 | "github.com/blackfyre/wga/utils" 13 | "github.com/blackfyre/wga/utils/seed" 14 | "github.com/blackfyre/wga/utils/sitemap" 15 | "github.com/joho/godotenv" 16 | "github.com/pocketbase/pocketbase" 17 | "github.com/pocketbase/pocketbase/plugins/migratecmd" 18 | "github.com/spf13/cobra" 19 | ) 20 | 21 | func main() { 22 | 23 | _ = godotenv.Load() 24 | 25 | app := pocketbase.NewWithConfig(pocketbase.Config{ 26 | DefaultDataDir: "./wga_data", 27 | }) 28 | 29 | // app.OnBeforeServe().Add(func(e *core.ServeEvent) error { 30 | // e.Router.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{ 31 | // TokenLookup: "header:X-XSRF-TOKEN", 32 | // })) 33 | 34 | // return nil 35 | // }) 36 | 37 | handlers.RegisterHandlers(app) 38 | hooks.RegisterHooks(app) 39 | crontab.RegisterCronJobs(app) 40 | 41 | migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{ 42 | // enable auto creation of migration files when making collection changes in the Admin UI 43 | // (the isGoRun check is to enable it only during development) 44 | Automigrate: false, 45 | }) 46 | 47 | app.RootCmd.AddCommand(&cobra.Command{ 48 | Use: "generate-sitemap", 49 | Short: "Generate sitemap", 50 | Run: func(cmd *cobra.Command, args []string) { 51 | sitemap.GenerateSiteMap(app) 52 | }, 53 | }) 54 | 55 | app.RootCmd.AddCommand(&cobra.Command{ 56 | Use: "generate-music-urls", 57 | Short: "Generate music urls", 58 | Run: func(cmd *cobra.Command, args []string) { 59 | utils.ParseMusicListToUrls("./assets/reference/musics.json") 60 | }, 61 | }) 62 | 63 | if os.Getenv("WGA_ENV") == "development" { 64 | app.RootCmd.AddCommand(&cobra.Command{ 65 | Use: "seed:images", 66 | Short: "Seed images to the specified S3 bucket", 67 | Run: func(cmd *cobra.Command, args []string) { 68 | err := seed.SeedImages(app) 69 | 70 | if err != nil { 71 | log.Fatal(err) 72 | } 73 | 74 | log.Println("Done seeding images") 75 | 76 | }, 77 | }) 78 | } 79 | 80 | if err := app.Start(); err != nil { 81 | log.Fatal(err) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /migrations/1687801090_initial_settings.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/joho/godotenv" 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | ) 11 | 12 | func init() { 13 | 14 | _ = godotenv.Load() 15 | 16 | m.Register(func(db dbx.Builder) error { 17 | dao := daos.New(db) 18 | 19 | settings, _ := dao.FindSettings() 20 | settings.Meta.AppName = "Web Gallery of Art" 21 | settings.Logs.MaxDays = 30 22 | settings.Meta.SenderName = "Web Gallery of Art" 23 | settings.Meta.SenderAddress = "info@wga.hu" 24 | settings.S3.Enabled = true 25 | settings.S3.Endpoint = os.Getenv("WGA_S3_ENDPOINT") 26 | settings.S3.AccessKey = os.Getenv("WGA_S3_ACCESS_KEY") 27 | settings.S3.Bucket = os.Getenv("WGA_S3_BUCKET") 28 | settings.S3.Secret = os.Getenv("WGA_S3_ACCESS_SECRET") 29 | settings.S3.Region = os.Getenv("WGA_S3_REGION") 30 | settings.S3.ForcePathStyle = true 31 | 32 | return dao.SaveSettings(settings) 33 | }, nil) 34 | } 35 | -------------------------------------------------------------------------------- /migrations/1695117058_strings_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | "github.com/pocketbase/pocketbase/models" 11 | "github.com/pocketbase/pocketbase/models/schema" 12 | ) 13 | 14 | type PublicString struct { 15 | Name string `json:"name"` 16 | Content string `json:"content"` 17 | } 18 | 19 | func init() { 20 | m.Register(func(db dbx.Builder) error { 21 | dao := daos.New(db) 22 | 23 | collection := &models.Collection{} 24 | 25 | collection.Name = "Strings" 26 | collection.Type = models.CollectionTypeBase 27 | collection.System = false 28 | collection.Id = "strings" 29 | collection.MarkAsNew() 30 | collection.Schema = schema.NewSchema( 31 | &schema.SchemaField{ 32 | Id: "strings_name", 33 | Name: "name", 34 | Type: schema.FieldTypeText, 35 | Options: &schema.TextOptions{}, 36 | Presentable: true, 37 | }, 38 | &schema.SchemaField{ 39 | Id: "strings_content", 40 | Name: "content", 41 | Type: schema.FieldTypeEditor, 42 | Options: &schema.EditorOptions{}, 43 | }, 44 | ) 45 | 46 | err := dao.SaveCollection(collection) 47 | 48 | if err != nil { 49 | return err 50 | } 51 | 52 | data, err := assets.InternalFiles.ReadFile("reference/strings.json") 53 | 54 | if err != nil { 55 | return err 56 | } 57 | 58 | var c []PublicString 59 | 60 | err = json.Unmarshal(data, &c) 61 | 62 | if err != nil { 63 | return err 64 | } 65 | 66 | for _, i := range c { 67 | q := db.Insert("strings", dbx.Params{ 68 | "name": i.Name, 69 | "content": i.Content, 70 | }) 71 | 72 | _, err = q.Execute() 73 | 74 | if err != nil { 75 | return err 76 | } 77 | 78 | } 79 | 80 | return nil 81 | 82 | // add up queries... 83 | // columns := map[string]string{ 84 | // "id": "text", 85 | // "created": "text", 86 | // "updated": "text", 87 | // "field_name": "text", 88 | // "content": "text", 89 | // } 90 | 91 | // q := db.CreateTable("strings", columns) 92 | // _, err := q.Execute() 93 | 94 | // return err 95 | }, func(db dbx.Builder) error { 96 | 97 | q := db.DropTable("strings") 98 | _, err := q.Execute() 99 | 100 | return err 101 | }) 102 | } 103 | -------------------------------------------------------------------------------- /migrations/1695699035_add_schools_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/blackfyre/wga/utils" 8 | "github.com/pocketbase/dbx" 9 | "github.com/pocketbase/pocketbase/daos" 10 | m "github.com/pocketbase/pocketbase/migrations" 11 | "github.com/pocketbase/pocketbase/models" 12 | "github.com/pocketbase/pocketbase/models/schema" 13 | ) 14 | 15 | type School struct { 16 | Id string `json:"id"` 17 | Name string `json:"name"` 18 | } 19 | 20 | func init() { 21 | m.Register(func(db dbx.Builder) error { 22 | dao := daos.New(db) 23 | 24 | collection := &models.Collection{} 25 | 26 | collection.Name = "Schools" 27 | collection.Id = "schools" 28 | collection.Type = models.CollectionTypeBase 29 | collection.System = false 30 | collection.MarkAsNew() 31 | collection.Schema = schema.NewSchema( 32 | &schema.SchemaField{ 33 | Id: "schools_name", 34 | Name: "name", 35 | Type: schema.FieldTypeText, 36 | Options: &schema.TextOptions{}, 37 | Presentable: true, 38 | }, 39 | &schema.SchemaField{ 40 | Id: "schools_slug", 41 | Name: "slug", 42 | Type: schema.FieldTypeText, 43 | Options: &schema.TextOptions{}, 44 | }, 45 | ) 46 | 47 | err := dao.SaveCollection(collection) 48 | 49 | if err != nil { 50 | return err 51 | } 52 | 53 | data, err := assets.InternalFiles.ReadFile("reference/schools.json") 54 | 55 | if err != nil { 56 | return err 57 | } 58 | 59 | var c []School 60 | 61 | err = json.Unmarshal(data, &c) 62 | 63 | if err != nil { 64 | return err 65 | } 66 | 67 | for _, i := range c { 68 | q := db.Insert("schools", dbx.Params{ 69 | "id": i.Id, 70 | "name": i.Name, 71 | "slug": utils.Slugify(i.Name), 72 | }) 73 | 74 | _, err = q.Execute() 75 | 76 | if err != nil { 77 | return err 78 | } 79 | 80 | } 81 | 82 | return nil 83 | }, func(db dbx.Builder) error { 84 | // add down queries... 85 | 86 | return nil 87 | }) 88 | } 89 | -------------------------------------------------------------------------------- /migrations/1695699092_glossary_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | "github.com/pocketbase/pocketbase/models" 11 | "github.com/pocketbase/pocketbase/models/schema" 12 | ) 13 | 14 | type Glossary struct { 15 | Id string `db:"id" json:"id"` 16 | Expression string `db:"expression" json:"expression"` 17 | Definition string `db:"definition" json:"definition"` 18 | } 19 | 20 | func init() { 21 | m.Register(func(db dbx.Builder) error { 22 | dao := daos.New(db) 23 | 24 | collection := &models.Collection{} 25 | 26 | collection.Name = "Glossary" 27 | collection.Type = models.CollectionTypeBase 28 | collection.Id = "glossary" 29 | collection.System = false 30 | collection.MarkAsNew() 31 | collection.Schema = schema.NewSchema( 32 | &schema.SchemaField{ 33 | Id: "glossary_expression", 34 | Name: "expression", 35 | Type: schema.FieldTypeText, 36 | Options: &schema.TextOptions{}, 37 | Presentable: true, 38 | }, 39 | &schema.SchemaField{ 40 | Id: "glorssary_definition", 41 | Name: "definition", 42 | Type: schema.FieldTypeText, 43 | Options: &schema.TextOptions{}, 44 | }, 45 | ) 46 | 47 | err := dao.SaveCollection(collection) 48 | 49 | if err != nil { 50 | return err 51 | } 52 | 53 | // read the file at ../reference/glossary_stage_1.json 54 | // unmarshal the json into a []Glossary 55 | // loop through the []Glossary 56 | // create a up query for each Glossary 57 | // execute the up query 58 | 59 | data, err := assets.InternalFiles.ReadFile("reference/glossary_stage_1.json") 60 | 61 | if err != nil { 62 | return err 63 | } 64 | 65 | var glossary []Glossary 66 | 67 | err = json.Unmarshal(data, &glossary) 68 | 69 | if err != nil { 70 | return err 71 | } 72 | 73 | for _, g := range glossary { 74 | q := db.Insert("glossary", dbx.Params{ 75 | "id": g.Id, 76 | "expression": g.Expression, 77 | "definition": g.Definition, 78 | }) 79 | 80 | _, err = q.Execute() 81 | 82 | if err != nil { 83 | return err 84 | } 85 | 86 | } 87 | 88 | return nil 89 | }, func(db dbx.Builder) error { 90 | q := db.DropTable("glossary") 91 | _, err := q.Execute() 92 | 93 | return err 94 | }) 95 | } 96 | -------------------------------------------------------------------------------- /migrations/1695699127_guestbook_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | "github.com/pocketbase/pocketbase/models" 11 | "github.com/pocketbase/pocketbase/models/schema" 12 | ) 13 | 14 | type GuestbookRecord struct { 15 | Message string `json:"message"` 16 | Name string `json:"name"` 17 | Email string `json:"email"` 18 | Location string `json:"location"` 19 | Created string `json:"created"` 20 | Updated string `json:"updated"` 21 | } 22 | 23 | func init() { 24 | m.Register(func(db dbx.Builder) error { 25 | dao := daos.New(db) 26 | 27 | collection := &models.Collection{} 28 | 29 | collection.Name = "Guestbook" 30 | collection.Id = "guestbook" 31 | collection.Type = models.CollectionTypeBase 32 | collection.System = false 33 | collection.MarkAsNew() 34 | collection.Schema = schema.NewSchema( 35 | &schema.SchemaField{ 36 | Id: "guestbooks_message", 37 | Name: "message", 38 | Type: schema.FieldTypeText, 39 | Options: &schema.TextOptions{}, 40 | }, 41 | &schema.SchemaField{ 42 | Id: "guestbooks_name", 43 | Name: "name", 44 | Type: schema.FieldTypeText, 45 | Options: &schema.TextOptions{}, 46 | Presentable: true, 47 | }, 48 | &schema.SchemaField{ 49 | Id: "guestbooks_email", 50 | Name: "email", 51 | Type: schema.FieldTypeEmail, 52 | Options: &schema.EmailOptions{}, 53 | Presentable: true, 54 | }, 55 | &schema.SchemaField{ 56 | Id: "guestbooks_location", 57 | Name: "location", 58 | Type: schema.FieldTypeText, 59 | Options: &schema.TextOptions{}, 60 | }, 61 | ) 62 | 63 | err := dao.SaveCollection(collection) 64 | 65 | if err != nil { 66 | return err 67 | } 68 | 69 | data, err := os.ReadFile("./guestbook.json") 70 | if err != nil { 71 | return dao.SaveCollection(collection) 72 | } else { 73 | var c []GuestbookRecord 74 | 75 | err = json.Unmarshal(data, &c) 76 | 77 | if err != nil { 78 | return err 79 | } 80 | 81 | for _, g := range c { 82 | q := db.Insert("guestbook", dbx.Params{ 83 | "message": g.Message, 84 | "name": g.Name, 85 | "email": g.Email, 86 | "location": g.Location, 87 | "created": g.Created, 88 | "updated": g.Updated, 89 | }) 90 | 91 | _, err = q.Execute() 92 | 93 | if err != nil { 94 | return err 95 | } 96 | 97 | } 98 | 99 | return nil 100 | } 101 | }, func(db dbx.Builder) error { 102 | // add down queries... 103 | 104 | q := db.DropTable("guestbook") 105 | _, err := q.Execute() 106 | 107 | return err 108 | }) 109 | } 110 | -------------------------------------------------------------------------------- /migrations/1695700169_default_admin.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/pocketbase/dbx" 7 | "github.com/pocketbase/pocketbase/daos" 8 | m "github.com/pocketbase/pocketbase/migrations" 9 | "github.com/pocketbase/pocketbase/models" 10 | ) 11 | 12 | func init() { 13 | 14 | email := os.Getenv("WGA_ADMIN_EMAIL") 15 | password := os.Getenv("WGA_ADMIN_PASSWORD") 16 | 17 | m.Register(func(db dbx.Builder) error { 18 | 19 | if email != "" && password != "" { 20 | dao := daos.New(db) 21 | 22 | admin := &models.Admin{} 23 | admin.Email = email 24 | admin.SetPassword(password) 25 | 26 | return dao.SaveAdmin(admin) 27 | } 28 | 29 | return nil 30 | 31 | }, func(db dbx.Builder) error { 32 | if email != "" { 33 | dao := daos.New(db) 34 | 35 | admin, _ := dao.FindAdminByEmail(email) 36 | if admin != nil { 37 | return dao.DeleteAdmin(admin) 38 | } 39 | } 40 | 41 | // already deleted 42 | return nil 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /migrations/1696390260_add_art_periods_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/blackfyre/wga/utils" 8 | "github.com/pocketbase/dbx" 9 | "github.com/pocketbase/pocketbase/daos" 10 | m "github.com/pocketbase/pocketbase/migrations" 11 | "github.com/pocketbase/pocketbase/models" 12 | "github.com/pocketbase/pocketbase/models/schema" 13 | ) 14 | 15 | type ArtPeriod struct { 16 | ID string `json:"id"` 17 | Name string `json:"name"` 18 | Start int `json:"start"` 19 | End int `json:"end"` 20 | Description string `json:"description"` 21 | } 22 | 23 | func init() { 24 | tName := "Art_periods" 25 | tId := "art_periods" 26 | m.Register(func(db dbx.Builder) error { 27 | dao := daos.New(db) 28 | 29 | collection := &models.Collection{} 30 | 31 | collection.Name = tName 32 | collection.Id = tId 33 | collection.Type = models.CollectionTypeBase 34 | collection.System = false 35 | collection.MarkAsNew() 36 | collection.Schema = schema.NewSchema( 37 | &schema.SchemaField{ 38 | Id: tId + "_name", 39 | Name: "name", 40 | Type: schema.FieldTypeText, 41 | Options: &schema.TextOptions{}, 42 | Presentable: true, 43 | }, 44 | &schema.SchemaField{ 45 | Id: "schools_slug", 46 | Name: "slug", 47 | Type: schema.FieldTypeText, 48 | Options: &schema.TextOptions{}, 49 | }, 50 | &schema.SchemaField{ 51 | Id: tId + "_start", 52 | Name: "start", 53 | Type: schema.FieldTypeNumber, 54 | Options: &schema.NumberOptions{}, 55 | }, 56 | &schema.SchemaField{ 57 | Id: tId + "_end", 58 | Name: "end", 59 | Type: schema.FieldTypeNumber, 60 | Options: &schema.NumberOptions{}, 61 | }, 62 | &schema.SchemaField{ 63 | Id: tId + "_description", 64 | Name: "description", 65 | Type: schema.FieldTypeText, 66 | Options: &schema.TextOptions{}, 67 | }, 68 | ) 69 | 70 | err := dao.SaveCollection(collection) 71 | 72 | if err != nil { 73 | return err 74 | } 75 | 76 | data, err := assets.InternalFiles.ReadFile("reference/art_periods.json") 77 | 78 | if err != nil { 79 | return err 80 | } 81 | 82 | var c []ArtPeriod 83 | 84 | err = json.Unmarshal(data, &c) 85 | 86 | if err != nil { 87 | return err 88 | } 89 | 90 | for _, g := range c { 91 | q := db.Insert(tId, dbx.Params{ 92 | "id": g.ID, 93 | "start": g.Start, 94 | "end": g.End, 95 | "name": g.Name, 96 | "description": g.Description, 97 | "slug": utils.Slugify(g.Name), 98 | }) 99 | 100 | _, err = q.Execute() 101 | 102 | if err != nil { 103 | return err 104 | } 105 | 106 | } 107 | 108 | return nil 109 | }, func(db dbx.Builder) error { 110 | q := db.DropTable(tId) 111 | _, err := q.Execute() 112 | 113 | return err 114 | }) 115 | } 116 | -------------------------------------------------------------------------------- /migrations/1696400261_add_art_forms_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/blackfyre/wga/utils" 8 | "github.com/pocketbase/dbx" 9 | "github.com/pocketbase/pocketbase/daos" 10 | m "github.com/pocketbase/pocketbase/migrations" 11 | "github.com/pocketbase/pocketbase/models" 12 | "github.com/pocketbase/pocketbase/models/schema" 13 | ) 14 | 15 | type ArtForm struct { 16 | ID string `json:"id"` 17 | Name string `json:"name"` 18 | } 19 | 20 | func init() { 21 | tName := "Art_forms" 22 | tId := "art_forms" 23 | m.Register(func(db dbx.Builder) error { 24 | dao := daos.New(db) 25 | 26 | collection := &models.Collection{} 27 | 28 | collection.Name = tName 29 | collection.Id = tId 30 | collection.Type = models.CollectionTypeBase 31 | collection.System = false 32 | collection.MarkAsNew() 33 | collection.Schema = schema.NewSchema( 34 | &schema.SchemaField{ 35 | Id: tId + "_name", 36 | Name: "name", 37 | Type: schema.FieldTypeText, 38 | Options: &schema.TextOptions{}, 39 | Presentable: true, 40 | }, 41 | &schema.SchemaField{ 42 | Id: "schools_slug", 43 | Name: "slug", 44 | Type: schema.FieldTypeText, 45 | Options: &schema.TextOptions{}, 46 | }, 47 | ) 48 | 49 | err := dao.SaveCollection(collection) 50 | 51 | if err != nil { 52 | return err 53 | } 54 | 55 | data, err := assets.InternalFiles.ReadFile("reference/forms.json") 56 | 57 | if err != nil { 58 | return err 59 | } 60 | 61 | var c []ArtForm 62 | 63 | err = json.Unmarshal(data, &c) 64 | 65 | if err != nil { 66 | return err 67 | } 68 | 69 | for _, g := range c { 70 | q := db.Insert(tId, dbx.Params{ 71 | "id": g.ID, 72 | "name": g.Name, 73 | "slug": utils.Slugify(g.Name), 74 | }) 75 | 76 | _, err = q.Execute() 77 | 78 | if err != nil { 79 | return err 80 | } 81 | 82 | } 83 | 84 | return nil 85 | }, func(db dbx.Builder) error { 86 | q := db.DropTable(tId) 87 | _, err := q.Execute() 88 | 89 | return err 90 | }) 91 | } 92 | -------------------------------------------------------------------------------- /migrations/1696479339_add_complementary_artists.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | 7 | "github.com/blackfyre/wga/assets" 8 | "github.com/pocketbase/dbx" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | ) 11 | 12 | func init() { 13 | m.Register(func(db dbx.Builder) error { 14 | data, err := assets.InternalFiles.ReadFile("reference/complementary_artists.json") 15 | 16 | if err != nil { 17 | return err 18 | } 19 | 20 | var c []Artist 21 | 22 | err = json.Unmarshal(data, &c) 23 | 24 | if err != nil { 25 | return err 26 | } 27 | 28 | for _, i := range c { 29 | q := db.Insert("artists", dbx.Params{ 30 | "id": i.Id, 31 | "name": i.Name, 32 | "bio": i.Bio, 33 | "slug": i.Slug, 34 | "year_of_birth": i.Meta.YearOfBirth, 35 | "year_of_death": i.Meta.YearOfDeath, 36 | "place_of_birth": i.Meta.PlaceOfBirth, 37 | "place_of_death": i.Meta.PlaceOfDeath, 38 | "profession": i.Source.Profession, 39 | "school": i.School, 40 | "published": true, 41 | "exact_year_of_birth": i.Meta.ExactYearOfBirth, 42 | "exact_year_of_death": i.Meta.ExactYearOfDeath, 43 | }) 44 | 45 | _, err = q.Execute() 46 | 47 | if err != nil { 48 | errString := err.Error() 49 | 50 | // if errString contains "UNIQUE constraint failed: artists.slug" then ignore 51 | // otherwise return error 52 | 53 | if !strings.Contains(errString, "UNIQUE constraint failed: Artists.slug") { 54 | return err 55 | } 56 | 57 | } 58 | 59 | } 60 | 61 | return nil 62 | }, func(db dbx.Builder) error { 63 | // add down queries... 64 | 65 | return nil 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /migrations/1696479673_add_art_types.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/blackfyre/wga/utils" 8 | "github.com/pocketbase/dbx" 9 | "github.com/pocketbase/pocketbase/daos" 10 | m "github.com/pocketbase/pocketbase/migrations" 11 | "github.com/pocketbase/pocketbase/models" 12 | "github.com/pocketbase/pocketbase/models/schema" 13 | ) 14 | 15 | type ArtType struct { 16 | ID string `json:"id"` 17 | Name string `json:"name"` 18 | } 19 | 20 | func init() { 21 | tName := "Art_types" 22 | tId := "art_types" 23 | m.Register(func(db dbx.Builder) error { 24 | dao := daos.New(db) 25 | 26 | collection := &models.Collection{} 27 | 28 | collection.Name = tName 29 | collection.Id = tId 30 | collection.Type = models.CollectionTypeBase 31 | collection.System = false 32 | collection.MarkAsNew() 33 | collection.Schema = schema.NewSchema( 34 | &schema.SchemaField{ 35 | Id: tId + "_name", 36 | Name: "name", 37 | Type: schema.FieldTypeText, 38 | Options: &schema.TextOptions{}, 39 | Presentable: true, 40 | }, 41 | &schema.SchemaField{ 42 | Id: "schools_slug", 43 | Name: "slug", 44 | Type: schema.FieldTypeText, 45 | Options: &schema.TextOptions{}, 46 | }, 47 | ) 48 | 49 | err := dao.SaveCollection(collection) 50 | 51 | if err != nil { 52 | return err 53 | } 54 | 55 | data, err := assets.InternalFiles.ReadFile("reference/types.json") 56 | 57 | if err != nil { 58 | return err 59 | } 60 | 61 | var c []ArtType 62 | 63 | err = json.Unmarshal(data, &c) 64 | 65 | if err != nil { 66 | return err 67 | } 68 | 69 | for _, g := range c { 70 | q := db.Insert(tId, dbx.Params{ 71 | "id": g.ID, 72 | "name": g.Name, 73 | "slug": utils.Slugify(g.Name), 74 | }) 75 | 76 | _, err = q.Execute() 77 | 78 | if err != nil { 79 | return err 80 | } 81 | 82 | } 83 | 84 | return nil 85 | }, func(db dbx.Builder) error { 86 | q := db.DropTable(tId) 87 | _, err := q.Execute() 88 | 89 | return err 90 | }) 91 | } 92 | -------------------------------------------------------------------------------- /migrations/1697169726_update_settings.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | 7 | "github.com/joho/godotenv" 8 | "github.com/pocketbase/dbx" 9 | "github.com/pocketbase/pocketbase/daos" 10 | m "github.com/pocketbase/pocketbase/migrations" 11 | ) 12 | 13 | func init() { 14 | 15 | _ = godotenv.Load() 16 | 17 | m.Register(func(db dbx.Builder) error { 18 | dao := daos.New(db) 19 | 20 | settings, _ := dao.FindSettings() 21 | settings.Meta.SenderName = os.Getenv("WGA_SENDER_NAME") 22 | settings.Meta.SenderAddress = os.Getenv("WGA_SENDER_ADDRESS") 23 | settings.Smtp.Enabled = true 24 | settings.Smtp.Host = os.Getenv("WGA_SMTP_HOST") 25 | settings.Smtp.Port, _ = strconv.Atoi(os.Getenv("WGA_SMTP_PORT")) 26 | settings.Smtp.Username = os.Getenv("WGA_SMTP_USERNAME") 27 | settings.Smtp.Password = os.Getenv("WGA_SMTP_PASSWORD") 28 | 29 | return dao.SaveSettings(settings) 30 | }, nil) 31 | } 32 | -------------------------------------------------------------------------------- /migrations/1697514430_create_postcards_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | m "github.com/pocketbase/pocketbase/migrations" 7 | "github.com/pocketbase/pocketbase/models" 8 | "github.com/pocketbase/pocketbase/models/schema" 9 | ) 10 | 11 | func init() { 12 | m.Register(func(db dbx.Builder) error { 13 | dao := daos.New(db) 14 | 15 | collection := &models.Collection{} 16 | 17 | collection.Name = "Postcards" 18 | collection.Id = "postcards" 19 | collection.Type = models.CollectionTypeBase 20 | collection.System = false 21 | collection.MarkAsNew() 22 | collection.Schema = schema.NewSchema( 23 | &schema.SchemaField{ 24 | Id: "postcard_sender_name", 25 | Name: "sender_name", 26 | Type: schema.FieldTypeText, 27 | Options: &schema.TextOptions{}, 28 | Presentable: true, 29 | Required: true, 30 | }, 31 | &schema.SchemaField{ 32 | Id: "postcard_sender_email", 33 | Name: "sender_email", 34 | Type: schema.FieldTypeEmail, 35 | Options: &schema.EmailOptions{}, 36 | Required: true, 37 | }, 38 | &schema.SchemaField{ 39 | Id: "postcard_recipients", 40 | Name: "recipients", 41 | Type: schema.FieldTypeText, 42 | Options: &schema.TextOptions{}, 43 | Required: true, 44 | }, 45 | &schema.SchemaField{ 46 | Id: "postcard_message", 47 | Name: "message", 48 | Type: schema.FieldTypeEditor, 49 | Options: &schema.EditorOptions{}, 50 | Required: true, 51 | }, 52 | &schema.SchemaField{ 53 | Id: "postcard_image_id", 54 | Name: "image_id", 55 | Type: schema.FieldTypeRelation, 56 | Options: &schema.RelationOptions{ 57 | CollectionId: "artworks", 58 | MinSelect: Ptr(1), 59 | MaxSelect: Ptr(1), 60 | }, 61 | }, 62 | &schema.SchemaField{ 63 | Id: "postcard_notify_sender", 64 | Name: "notify_sender", 65 | Type: schema.FieldTypeBool, 66 | Options: schema.BoolOptions{}, 67 | }, 68 | &schema.SchemaField{ 69 | Id: "postcard_status", 70 | Name: "status", 71 | Type: schema.FieldTypeSelect, 72 | Options: &schema.SelectOptions{ 73 | Values: []string{"queued", "sent", "received"}, 74 | MaxSelect: 1, 75 | }, 76 | Presentable: true, 77 | }, 78 | &schema.SchemaField{ 79 | Id: "postcard_sent_at", 80 | Name: "sent_at", 81 | Type: schema.FieldTypeDate, 82 | Options: &schema.DateOptions{}, 83 | }, 84 | ) 85 | 86 | return dao.SaveCollection(collection) 87 | 88 | }, func(db dbx.Builder) error { 89 | q := db.DropTable("postcards") 90 | _, err := q.Execute() 91 | 92 | return err 93 | 94 | }) 95 | } 96 | -------------------------------------------------------------------------------- /migrations/1697713164_create_feedbacks_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/pocketbase/dbx" 7 | "github.com/pocketbase/pocketbase/daos" 8 | m "github.com/pocketbase/pocketbase/migrations" 9 | "github.com/pocketbase/pocketbase/models" 10 | "github.com/pocketbase/pocketbase/models/schema" 11 | ) 12 | 13 | func init() { 14 | 15 | tId := "feedbacks" 16 | tName := "Feedbacks" 17 | 18 | m.Register(func(db dbx.Builder) error { 19 | dao := daos.New(db) 20 | 21 | collection := &models.Collection{} 22 | 23 | collection.Name = tName 24 | collection.Id = tId 25 | collection.Type = models.CollectionTypeBase 26 | collection.System = false 27 | collection.MarkAsNew() 28 | 29 | collection.Schema = schema.NewSchema( 30 | &schema.SchemaField{ 31 | Id: tId + "_name", 32 | Name: "name", 33 | Type: schema.FieldTypeText, 34 | Options: &schema.TextOptions{}, 35 | Presentable: true, 36 | Required: true, 37 | }, 38 | &schema.SchemaField{ 39 | Id: tId + "_email", 40 | Name: "email", 41 | Type: schema.FieldTypeEmail, 42 | Options: &schema.EmailOptions{}, 43 | Required: true, 44 | }, 45 | &schema.SchemaField{ 46 | Id: tId + "_refer_to", 47 | Name: "refer_to", 48 | Type: schema.FieldTypeUrl, 49 | Options: &schema.UrlOptions{ 50 | OnlyDomains: []string{os.Getenv("WGA_HOSTNAME")}, 51 | }, 52 | Required: true, 53 | }, 54 | &schema.SchemaField{ 55 | Id: tId + "_message", 56 | Name: "message", 57 | Type: schema.FieldTypeEditor, 58 | Options: &schema.EditorOptions{ 59 | ConvertUrls: true, 60 | }, 61 | Required: true, 62 | }, 63 | &schema.SchemaField{ 64 | Id: tId + "_handled", 65 | Name: "handled", 66 | Type: schema.FieldTypeBool, 67 | Options: &schema.BoolOptions{}, 68 | Presentable: true, 69 | }, 70 | ) 71 | 72 | return dao.SaveCollection(collection) 73 | 74 | }, func(db dbx.Builder) error { 75 | q := db.DropTable(tId) 76 | _, err := q.Execute() 77 | 78 | return err 79 | }) 80 | } 81 | -------------------------------------------------------------------------------- /migrations/1698222668_create_static_pages_table.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/blackfyre/wga/assets" 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | "github.com/pocketbase/pocketbase/models" 11 | "github.com/pocketbase/pocketbase/models/schema" 12 | ) 13 | 14 | type staticPage struct { 15 | Title string `json:"title"` 16 | Slug string `json:"slug"` 17 | Content string `json:"content"` 18 | } 19 | 20 | func init() { 21 | 22 | tId := "static_pages" 23 | tName := "Static_pages" 24 | 25 | m.Register(func(db dbx.Builder) error { 26 | dao := daos.New(db) 27 | 28 | collection := &models.Collection{} 29 | 30 | collection.Name = tName 31 | collection.Id = tId 32 | collection.Type = models.CollectionTypeBase 33 | collection.System = false 34 | collection.MarkAsNew() 35 | 36 | collection.Schema = schema.NewSchema( 37 | &schema.SchemaField{ 38 | Id: tId + "_title", 39 | Name: "title", 40 | Type: schema.FieldTypeText, 41 | Options: &schema.TextOptions{}, 42 | Presentable: true, 43 | Required: true, 44 | }, 45 | &schema.SchemaField{ 46 | Id: tId + "_slug", 47 | Name: "slug", 48 | Type: schema.FieldTypeText, 49 | Options: &schema.TextOptions{}, 50 | }, 51 | &schema.SchemaField{ 52 | Id: tId + "_content", 53 | Name: "content", 54 | Type: schema.FieldTypeEditor, 55 | Options: &schema.EditorOptions{ 56 | ConvertUrls: true, 57 | }, 58 | Required: true, 59 | }, 60 | ) 61 | 62 | err := dao.SaveCollection(collection) 63 | 64 | if err != nil { 65 | return err 66 | } 67 | 68 | data, err := assets.InternalFiles.ReadFile("reference/static_content.json") 69 | 70 | if err != nil { 71 | return err 72 | } 73 | 74 | var c []staticPage 75 | 76 | err = json.Unmarshal(data, &c) 77 | 78 | if err != nil { 79 | return err 80 | } 81 | 82 | for _, g := range c { 83 | q := db.Insert(tId, dbx.Params{ 84 | "title": g.Title, 85 | "slug": g.Slug, 86 | "content": g.Content, 87 | }) 88 | 89 | _, err = q.Execute() 90 | 91 | if err != nil { 92 | return err 93 | } 94 | 95 | } 96 | 97 | return nil 98 | 99 | }, func(db dbx.Builder) error { 100 | q := db.DropTable(tId) 101 | _, err := q.Execute() 102 | 103 | return err 104 | }) 105 | } 106 | -------------------------------------------------------------------------------- /migrations/1698736507_add_music_tables.go: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/blackfyre/wga/handlers" 7 | "github.com/pocketbase/dbx" 8 | "github.com/pocketbase/pocketbase/daos" 9 | m "github.com/pocketbase/pocketbase/migrations" 10 | "github.com/pocketbase/pocketbase/models" 11 | "github.com/pocketbase/pocketbase/models/schema" 12 | ) 13 | 14 | func init() { 15 | m.Register(func(db dbx.Builder) error { 16 | dao := daos.New(db) 17 | 18 | collection := &models.Collection{} 19 | 20 | collection.Name = "Music_composer" 21 | collection.Type = models.CollectionTypeBase 22 | collection.System = false 23 | collection.Id = "music_composer" 24 | collection.MarkAsNew() 25 | collection.Schema = schema.NewSchema( 26 | &schema.SchemaField{ 27 | Id: "music_composer_id", 28 | Name: "id", 29 | Type: schema.FieldTypeText, 30 | Options: &schema.TextOptions{}, 31 | }, 32 | &schema.SchemaField{ 33 | Id: "music_composer_name", 34 | Name: "name", 35 | Type: schema.FieldTypeText, 36 | Options: &schema.TextOptions{}, 37 | Presentable: true, 38 | }, 39 | &schema.SchemaField{ 40 | Id: "music_composer_century", 41 | Name: "century", 42 | Type: schema.FieldTypeSelect, 43 | Options: &schema.SelectOptions{ 44 | Values: []string{"12", "13", "14", "15", "16", "17", "18", "19", "20", "21"}, 45 | MaxSelect: 1, 46 | }, 47 | Presentable: true, 48 | }, 49 | &schema.SchemaField{ 50 | Id: "music_composer_date", 51 | Name: "date", 52 | Type: schema.FieldTypeText, 53 | Options: &schema.TextOptions{}, 54 | Presentable: true, 55 | }, 56 | &schema.SchemaField{ 57 | Id: "music_composer_language", 58 | Name: "language", 59 | Type: schema.FieldTypeText, 60 | Options: &schema.TextOptions{}, 61 | Presentable: true, 62 | }, 63 | ) 64 | 65 | err := dao.SaveCollection(collection) 66 | if err != nil { 67 | // Handle the error, for example log it and return 68 | log.Printf("Error saving collection: %v", err) 69 | return err 70 | } 71 | 72 | collection.Name = "Music_song" 73 | collection.Type = models.CollectionTypeBase 74 | collection.System = false 75 | collection.Id = "music_song" 76 | collection.MarkAsNew() 77 | collection.Schema = schema.NewSchema( 78 | &schema.SchemaField{ 79 | Id: "composer_id", 80 | Name: "composer_id", 81 | Type: schema.FieldTypeText, 82 | Options: &schema.TextOptions{}, 83 | Presentable: true, 84 | }, 85 | &schema.SchemaField{ 86 | Id: "music_song_title", 87 | Name: "title", 88 | Type: schema.FieldTypeText, 89 | Options: &schema.TextOptions{}, 90 | Presentable: true, 91 | }, 92 | &schema.SchemaField{ 93 | Id: "music_song_url", 94 | Name: "url", 95 | Type: schema.FieldTypeText, 96 | Options: &schema.TextOptions{}, 97 | }, 98 | &schema.SchemaField{ 99 | Id: "music_song_source", 100 | Name: "source", 101 | Type: schema.FieldTypeFile, 102 | Options: &schema.FileOptions{}, 103 | Presentable: true, 104 | }, 105 | ) 106 | 107 | err = dao.SaveCollection(collection) 108 | 109 | if err != nil { 110 | return err 111 | } 112 | 113 | composers := handlers.GetParsedMusics() 114 | 115 | for _, composer := range composers { 116 | 117 | q := db.Insert("music_composer", dbx.Params{ 118 | "id": composer.ID, 119 | "name": composer.Name, 120 | "date": composer.Date, 121 | "century": composer.Century, 122 | "language": composer.Language, 123 | }) 124 | 125 | _, err = q.Execute() 126 | 127 | if err != nil { 128 | return err 129 | } 130 | 131 | for _, song := range composer.Songs { 132 | q := db.Insert("music_song", dbx.Params{ 133 | "composer_id": song.ComposerID, 134 | "title": song.Title, 135 | "url": song.URL, 136 | "source": song.Source, 137 | }) 138 | 139 | _, err = q.Execute() 140 | 141 | if err != nil { 142 | return err 143 | } 144 | } 145 | 146 | } 147 | 148 | return nil 149 | }, func(db dbx.Builder) error { 150 | q := db.DropTable("music_song") 151 | _, err := q.Execute() 152 | 153 | if err != nil { 154 | log.Printf("Error executing drop music_song query: %v", err) 155 | return err 156 | } 157 | 158 | q = db.DropTable("music_composer") 159 | _, err = q.Execute() 160 | 161 | if err != nil { 162 | log.Printf("Error executing drop music_composer query: %v", err) 163 | return err 164 | } 165 | 166 | return err 167 | }) 168 | } 169 | -------------------------------------------------------------------------------- /models/artforms.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | "github.com/pocketbase/pocketbase/models" 7 | ) 8 | 9 | type ArtForm struct { 10 | models.BaseModel 11 | Name string `db:"name" json:"name"` 12 | Slug string `db:"slug" json:"slug"` 13 | } 14 | 15 | var _ models.Model = (*ArtForm)(nil) 16 | 17 | func (m *ArtForm) TableName() string { 18 | return "art_forms" // the name of your collection 19 | } 20 | 21 | // ArtFormQuery returns a new dbx.SelectQuery for the ArtForm model. 22 | func ArtFormQuery(dao *daos.Dao) *dbx.SelectQuery { 23 | return dao.ModelQuery(&ArtForm{}) 24 | } 25 | 26 | // GetArtForms retrieves all art forms from the database and returns them as a slice of ArtForm pointers. 27 | // It takes a dao object as a parameter and returns the slice of ArtForm pointers and an error (if any). 28 | func GetArtForms(dao *daos.Dao) ([]*ArtForm, error) { 29 | var c []*ArtForm 30 | err := ArtFormQuery(dao).OrderBy("name asc").All(&c) 31 | return c, err 32 | } 33 | 34 | // GetArtFormBySlug retrieves an art form from the database by its slug. 35 | // It takes a dao object and a slug string as arguments and returns a pointer to the retrieved ArtForm object and an error (if any). 36 | func GetArtFormBySlug(dao *daos.Dao, slug string) (*ArtForm, error) { 37 | var c ArtForm 38 | err := ArtFormQuery(dao).AndWhere(dbx.NewExp("LOWER(slug)={:slug}", dbx.Params{ 39 | "slug": slug, 40 | })). 41 | Limit(1). 42 | One(&c) 43 | return &c, err 44 | } 45 | -------------------------------------------------------------------------------- /models/artist.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | "github.com/pocketbase/pocketbase/models" 7 | ) 8 | 9 | // WIP - this is a work in progress 10 | type Artist struct { 11 | models.BaseModel 12 | Id string `db:"id" json:"id"` 13 | Name string `db:"name" json:"name"` 14 | Slug string `db:"slug" json:"slug"` 15 | Bio string `db:"bio" json:"bio"` 16 | YearOfBirth int `db:"year_of_birth" json:"year_of_birth"` 17 | YearOfDeath int `db:"year_of_death" json:"year_of_death"` 18 | PlaceOfBirth string `db:"place_of_birth" json:"place_of_birth"` 19 | PlaceOfDeath string `db:"place_of_death" json:"place_of_death"` 20 | Published bool `db:"published" json:"published"` 21 | School string `db:"school" json:"school"` 22 | Profession string `db:"profession" json:"profession"` 23 | } 24 | 25 | var _ models.Model = (*Artist)(nil) 26 | 27 | func (m *Artist) TableName() string { 28 | return "artists" // the name of your collection 29 | } 30 | 31 | // ArtistQuery returns a new dbx.SelectQuery for the Artist model. 32 | func ArtistQuery(dao *daos.Dao) *dbx.SelectQuery { 33 | return dao.ModelQuery(&Artist{}) 34 | } 35 | 36 | // GetArtists retrieves all art forms from the database and returns them as a slice of Artist pointers. 37 | // It takes a dao object as a parameter and returns the slice of Artist pointers and an error (if any). 38 | func GetArtists(dao *daos.Dao) ([]*Artist, error) { 39 | var c []*Artist 40 | err := ArtistQuery(dao).OrderBy("name asc").All(&c) 41 | return c, err 42 | } 43 | 44 | // GetArtistBySlug retrieves an art form from the database by its slug. 45 | // It takes a dao object and a slug string as arguments and returns a pointer to the retrieved Artist object and an error (if any). 46 | func GetArtistBySlug(dao *daos.Dao, slug string) (*Artist, error) { 47 | var c Artist 48 | err := ArtistQuery(dao).AndWhere(dbx.NewExp("LOWER(slug)={:slug}", dbx.Params{ 49 | "slug": slug, 50 | })). 51 | Limit(1). 52 | One(&c) 53 | return &c, err 54 | } 55 | 56 | func GetArtistByNameLike(dao *daos.Dao, name string) ([]*Artist, error) { 57 | var c []*Artist 58 | err := ArtistQuery(dao).AndWhere(dbx.NewExp("LOWER(name) LIKE {:name}", dbx.Params{ 59 | "name": "%" + name + "%", 60 | })).All(&c) 61 | return c, err 62 | } 63 | 64 | func GetArtistById(dao *daos.Dao, id string) (*Artist, error) { 65 | var c Artist 66 | err := ArtistQuery(dao).AndWhere(dbx.NewExp("id={:id}", dbx.Params{ 67 | "id": id, 68 | })). 69 | Limit(1). 70 | One(&c) 71 | return &c, err 72 | } 73 | -------------------------------------------------------------------------------- /models/artperiods.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type ArtPeriod struct { 8 | models.BaseModel 9 | Name string `db:"name" json:"name"` 10 | Start int `db:"start" json:"start"` 11 | End int `db:"end" json:"end"` 12 | Description string `db:"description" json:"description"` 13 | } 14 | 15 | var _ models.Model = (*ArtPeriod)(nil) 16 | 17 | func (m *ArtPeriod) TableName() string { 18 | return "art_periods" // the name of your collection 19 | } 20 | -------------------------------------------------------------------------------- /models/arttypes.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | "github.com/pocketbase/pocketbase/models" 7 | ) 8 | 9 | type ArtType struct { 10 | models.BaseModel 11 | Name string `db:"name" json:"name"` 12 | Slug string `db:"slug" json:"slug"` 13 | } 14 | 15 | var _ models.Model = (*ArtType)(nil) 16 | 17 | func (m *ArtType) TableName() string { 18 | return "art_types" // the name of your collection 19 | } 20 | 21 | // ArtTypeQuery returns a new SelectQuery for the ArtType model. 22 | func ArtTypeQuery(dao *daos.Dao) *dbx.SelectQuery { 23 | return dao.ModelQuery(&ArtType{}) 24 | } 25 | 26 | // GetArtTypes retrieves all art types from the database and returns them as a slice of ArtType pointers. 27 | // It takes a pointer to a dao object as an argument and returns the slice of ArtType pointers and an error (if any). 28 | func GetArtTypes(dao *daos.Dao) ([]*ArtType, error) { 29 | var c []*ArtType 30 | err := ArtTypeQuery(dao).OrderBy("name asc").All(&c) 31 | return c, err 32 | } 33 | 34 | // GetArtTypeBySlug retrieves an ArtType from the database by its slug. 35 | // It takes a dao object and a slug string as parameters. 36 | // It returns a pointer to the retrieved ArtType and an error if any. 37 | func GetArtTypeBySlug(dao *daos.Dao, slug string) (*ArtType, error) { 38 | var c ArtType 39 | err := ArtTypeQuery(dao).AndWhere(dbx.NewExp("LOWER(slug)={:slug}", dbx.Params{ 40 | "slug": slug, 41 | })). 42 | Limit(1). 43 | One(&c) 44 | return &c, err 45 | } 46 | -------------------------------------------------------------------------------- /models/artworks.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | "github.com/pocketbase/pocketbase/models" 7 | ) 8 | 9 | type Artwork struct { 10 | models.BaseModel 11 | Title string `db:"title" json:"title"` 12 | Author string `db:"author" json:"author"` 13 | Form string `db:"form" json:"form"` 14 | Technique string `db:"technique" json:"technique"` 15 | School string `db:"school" json:"school"` 16 | Comment string `db:"comment" json:"comment"` 17 | Published bool `db:"published" json:"published"` 18 | Image string `db:"image" json:"image"` 19 | Type string `db:"type" json:"type"` 20 | } 21 | 22 | var _ models.Model = (*Artwork)(nil) 23 | 24 | func (m *Artwork) TableName() string { 25 | return "artworks" // the name of your collection 26 | } 27 | 28 | // ArtworkQuery returns a new dbx.SelectQuery for the Artwork model. 29 | func ArtworkQuery(dao *daos.Dao) *dbx.SelectQuery { 30 | return dao.ModelQuery(&Artwork{}) 31 | } 32 | 33 | // GetArtworks retrieves all artworks from the database. 34 | // It takes a dao object as a parameter and returns a slice of Artwork pointers and an error. 35 | // The artworks are ordered by title in ascending order. 36 | func GetArtworks(dao *daos.Dao) ([]*Artwork, error) { 37 | var c []*Artwork 38 | err := ArtworkQuery(dao).OrderBy("title asc").All(&c) 39 | return c, err 40 | } 41 | 42 | // GetRandomArtworks returns a slice of random Artwork objects from the database. 43 | // It takes a dao object and the number of items to retrieve as parameters. 44 | // It returns the slice of Artwork objects and an error, if any. 45 | func GetRandomArtworks(dao *daos.Dao, itemCount int64) ([]*Artwork, error) { 46 | var c []*Artwork 47 | err := ArtworkQuery(dao).Where(dbx.NewExp("author != \"\"")).OrderBy("RANDOM()").Limit(itemCount).All(&c) 48 | return c, err 49 | } 50 | -------------------------------------------------------------------------------- /models/composers.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type Music_composer struct { 8 | models.BaseModel 9 | ID string `db:"id" json:"id"` 10 | Name string `db:"name" json:"name"` 11 | Date string `db:"date" json:"date"` 12 | Language string `db:"language" json:"language"` 13 | Century string `db:"century" json:"century"` 14 | Songs []Music_song `db:"songs" json:"songs"` 15 | } 16 | 17 | var _ models.Model = (*Music_composer)(nil) 18 | 19 | func (m *Music_composer) TableName() string { 20 | return "music_composer" // the name of your collection 21 | } 22 | -------------------------------------------------------------------------------- /models/feedback.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type Feedback struct { 8 | models.BaseModel 9 | Name string `db:"name" json:"name"` 10 | Message string `db:"message" json:"message"` 11 | Email string `db:"email" json:"email"` 12 | ReferTo string `db:"refer_to" json:"refer_to"` 13 | Handled bool `db:"handled" json:"handled"` 14 | } 15 | 16 | var _ models.Model = (*Feedback)(nil) 17 | 18 | func (m *Feedback) TableName() string { 19 | return "feedbacks" // the name of your collection 20 | } 21 | -------------------------------------------------------------------------------- /models/glossary.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type GlossaryItem struct { 8 | models.BaseModel 9 | Expression string `db:"expression" json:"expression"` 10 | Definition string `db:"definition" json:"definition"` 11 | } 12 | 13 | var _ models.Model = (*GlossaryItem)(nil) 14 | 15 | func (m *GlossaryItem) TableName() string { 16 | return "glossary" // the name of your collection 17 | } 18 | -------------------------------------------------------------------------------- /models/guestbbok.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/dbx" 5 | "github.com/pocketbase/pocketbase/daos" 6 | "github.com/pocketbase/pocketbase/models" 7 | ) 8 | 9 | type GuestbookEntry struct { 10 | models.BaseModel 11 | Name string `db:"name" json:"name"` 12 | Message string `db:"message" json:"message"` 13 | Email string `db:"email" json:"email"` 14 | Location string `db:"location" json:"location"` 15 | Created string `db:"created" json:"created"` 16 | } 17 | 18 | var _ models.Model = (*GuestbookEntry)(nil) 19 | 20 | func (m *GuestbookEntry) TableName() string { 21 | return "Guestbook" // the name of your collection 22 | } 23 | 24 | func GuestbookQuery(dao *daos.Dao) *dbx.SelectQuery { 25 | return dao.ModelQuery(&GuestbookEntry{}) 26 | } 27 | 28 | func FindEntriesForYear(dao *daos.Dao, year string) ([]*GuestbookEntry, error) { 29 | var entries []*GuestbookEntry 30 | 31 | err := GuestbookQuery(dao).AndWhere(dbx.Like("created", year)).OrderBy("created DESC").All(&entries) 32 | 33 | return entries, err 34 | } 35 | -------------------------------------------------------------------------------- /models/postcards.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type Postcard struct { 8 | models.BaseModel 9 | SenderName string `db:"sender_name" json:"sender_name"` 10 | SenderEmail string `db:"sender_email" json:"sender_email"` 11 | Recipients string `db:"recipients" json:"recipients"` 12 | Message string `db:"message" json:"message"` 13 | } 14 | 15 | var _ models.Model = (*Postcard)(nil) 16 | 17 | func (m *Postcard) TableName() string { 18 | return "postcards" // the name of your collection 19 | } 20 | -------------------------------------------------------------------------------- /models/schools.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/pocketbase/dbx" 7 | "github.com/pocketbase/pocketbase/daos" 8 | "github.com/pocketbase/pocketbase/models" 9 | ) 10 | 11 | // School represents a school model with its name and slug. 12 | type School struct { 13 | models.BaseModel 14 | Name string `db:"name" json:"name"` 15 | Slug string `db:"slug" json:"slug"` 16 | } 17 | 18 | var _ models.Model = (*School)(nil) 19 | 20 | // TableName returns the name of the collection for School model. 21 | func (m *School) TableName() string { 22 | return "schools" // the name of your collection 23 | } 24 | 25 | // SchoolQuery returns a new dbx.SelectQuery for the School model. 26 | // It takes a dao object as a parameter and returns a pointer to the new query. 27 | func SchoolQuery(dao *daos.Dao) *dbx.SelectQuery { 28 | return dao.ModelQuery(&School{}) 29 | } 30 | 31 | // GetSchools retrieves all schools from the database and returns them as a slice of School structs. 32 | // The schools are sorted by name in ascending order. 33 | func GetSchools(dao *daos.Dao) ([]*School, error) { 34 | var c []*School 35 | err := SchoolQuery(dao).OrderBy("name asc").All(&c) 36 | return c, err 37 | } 38 | 39 | // GetSchoolBySlug retrieves a school by its slug from the database. 40 | // It takes a dao object and a string slug as input parameters. 41 | // It returns a pointer to a School object and an error object. 42 | func GetSchoolBySlug(dao *daos.Dao, slug string) (*School, error) { 43 | var c School 44 | err := SchoolQuery(dao).AndWhere(dbx.NewExp("LOWER(slug)={:slug}", dbx.Params{ 45 | "slug": strings.ToLower(slug), 46 | })). 47 | Limit(1). 48 | One(&c) 49 | return &c, err 50 | } 51 | -------------------------------------------------------------------------------- /models/songs.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "github.com/pocketbase/pocketbase/models" 5 | ) 6 | 7 | type Music_song struct { 8 | models.BaseModel 9 | Title string `db:"title" json:"title"` 10 | URL string `db:"url" json:"url"` 11 | Source string `db:"source" json:"source"` 12 | ComposerID string `db:"composer_id" json:"composer_id"` // foreign key 13 | } 14 | 15 | var _ models.Model = (*Music_song)(nil) 16 | 17 | 18 | func (m *Music_song) TableName() string { 19 | return "music_song" // the name of your collection 20 | } -------------------------------------------------------------------------------- /models/staticpage.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/pocketbase/dbx" 7 | "github.com/pocketbase/pocketbase/daos" 8 | "github.com/pocketbase/pocketbase/models" 9 | ) 10 | 11 | type StaticPage struct { 12 | models.BaseModel 13 | Title string `json:"title" db:"title"` 14 | Slug string `json:"slug" db:"slug"` 15 | Content string `json:"content" db:"content"` 16 | } 17 | 18 | var _ models.Model = (*StaticPage)(nil) 19 | 20 | // TableName returns the name of the collection associated with the StaticPage model. 21 | func (m *StaticPage) TableName() string { 22 | return "static_pages" 23 | } 24 | 25 | // StaticPageQuery returns a new dbx.SelectQuery for querying StaticPage models. 26 | func StaticPageQuery(dao *daos.Dao) *dbx.SelectQuery { 27 | return dao.ModelQuery(&StaticPage{}) 28 | } 29 | 30 | // FindStaticPageBySlug retrieves a StaticPage from the database by its slug. 31 | // It performs a case-insensitive match on the slug parameter. 32 | // Returns a pointer to the StaticPage and an error if any occurred. 33 | func FindStaticPageBySlug(dao *daos.Dao, slug string) (*StaticPage, error) { 34 | page := &StaticPage{} 35 | 36 | err := StaticPageQuery(dao). 37 | AndWhere(dbx.NewExp("LOWER(slug)={:slug}", dbx.Params{ 38 | "slug": strings.ToLower(slug), 39 | })). 40 | Limit(1). 41 | One(page) 42 | 43 | if err != nil { 44 | return nil, err 45 | } 46 | 47 | return page, nil 48 | } 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wga", 3 | "version": "1.0.0", 4 | "description": "Front-end build system for the Web Gallery of Art: Project Phoenix", 5 | "private": "true", 6 | "scripts": { 7 | "build": "bun run build:css && bun run build:js", 8 | "build:js": "bun build.js", 9 | "build:css": "postcss ./resources/css/style.pcss -o ./assets/public/css/style.css", 10 | "build:watch:css": "bun run build:css -- --watch", 11 | "build:watch:js": "bun run build:js -- --watch", 12 | "dev": "concurrently -n \"templ,serve,tailwind,ts,docker\" -c \"red,magenta,yellow,blue,cyan\" \"templ generate --watch\" \"air serve --dev\" \"bun run build:watch:css\" \"bun run build:js\" \"docker compose up\"" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/blackfyre/wga.git" 17 | }, 18 | "author": "Miklós Galicz