Skip to content

Commit

Permalink
[FEATURE] Firebase storage file handling
Browse files Browse the repository at this point in the history
  • Loading branch information
matej-oliva committed May 23, 2023
1 parent ae75728 commit a881b5b
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 62 deletions.
63 changes: 3 additions & 60 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package api

import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/marhycz/strv-go-newsletter/environment"
"github.com/marhycz/strv-go-newsletter/repository/store"
)

type Rest struct {
Expand All @@ -26,7 +21,7 @@ func NewController(env *environment.Env) *Rest {
return c
}

func (rest *Rest) initRouter(){
func (rest *Rest) initRouter() {
r := chi.NewRouter()

// A good base middleware stack
Expand All @@ -40,60 +35,8 @@ func (rest *Rest) initRouter(){
// processing should be stopped.
r.Use(middleware.Timeout(60 * time.Second))

r.Route("/subscriptions", func(r chi.Router){
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
subscriptions := rest.env.Store.GetSubscriptions(ctx)
err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
})

r.Get("/{newsletter_id}/{email}", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
id, error := strconv.Atoi(chi.URLParam(r, "newsletter_id"))

if error != nil {
fmt.Println("Error during conversion")
return
}
subscriptions := rest.env.Store.GetSubscription(ctx, id, chi.URLParam(r, "email"))
err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
})

r.Post("/", func(w http.ResponseWriter, r *http.Request) {
var sub store.Subscription

json.NewDecoder(r.Body).Decode(&sub)
ctx := r.Context()

subscriptions := rest.env.Store.NewSubscription(ctx, sub.Newsletter_id, sub.Email)

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
})

r.Delete("/", func(w http.ResponseWriter, r *http.Request) {
var sub store.Subscription

json.NewDecoder(r.Body).Decode(&sub)
ctx := r.Context()

subscriptions := rest.env.Store.DeleteSubscription(ctx, sub.Id)

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
})
})

rest.routeEditor(r)
rest.routeSubscriptions(r)
rest.routeIssues(r)
rest.Mux = r
}
80 changes: 80 additions & 0 deletions api/issue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package api

import (
"encoding/json"
"io"
"log"
"net/http"
"os"

"github.com/go-chi/chi/v5"
)

func (rest *Rest) routeIssues(r *chi.Mux) {
r.Route("/issues", func(r chi.Router) {
r.Get("/", rest.listOfIssues)

r.Get("/issue", rest.getIssue)

r.Post("/issue", rest.publishIssue)
})
}

func (rest *Rest) listOfIssues(w http.ResponseWriter, r *http.Request) {
newsletter := r.URL.Query().Get("newsletter_id")

if newsletter != "" {
newsletter = newsletter + "/"
}

ctx := r.Context()
subscriptions := rest.env.Storage.GetIssuesList(ctx, os.Stdout, "/", newsletter)
err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}
func (rest *Rest) getIssue(w http.ResponseWriter, r *http.Request) {
newsletter := r.URL.Query().Get("newsletter_id")
name := r.URL.Query().Get("name")
path := newsletter + "/" + name

if newsletter == "" || name == "" {
w.WriteHeader(http.StatusForbidden)
}

ctx := r.Context()
subscriptions, downlFailure := rest.env.Storage.DownloadFileIntoMemory(ctx, os.Stdout, path)

if downlFailure != nil {
w.WriteHeader(http.StatusNoContent)
}

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}

func (rest *Rest) publishIssue(w http.ResponseWriter, r *http.Request) {
newsletter := r.URL.Query().Get("newsletter_id")
name := r.URL.Query().Get("name")
path := newsletter + "/" + name
body, bodyErr := io.ReadAll(r.Body)
if bodyErr != nil {
log.Fatalln(bodyErr)
}
data := string(body)

if newsletter == "" || name == "" || data == "" {
w.WriteHeader(http.StatusForbidden)
}

ctx := r.Context()
subscriptions := rest.env.Storage.StreamFileUpload(ctx, os.Stdout, path, data)

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}
77 changes: 77 additions & 0 deletions api/subscriptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package api

import (
"encoding/json"
"fmt"
"net/http"
"strconv"

"github.com/go-chi/chi/v5"
"github.com/marhycz/strv-go-newsletter/repository/store"
)

func (rest *Rest) routeSubscriptions(r *chi.Mux) {
r.Route("/subscriptions", func(r chi.Router) {
r.Get("/", rest.listOfSubscriptions)

r.Get("/{newsletter_id}/{email}", rest.getSubscription)

r.Post("/", rest.subscribe)

r.Delete("/", rest.unsubscribe)
})
}

func (rest *Rest) listOfSubscriptions(w http.ResponseWriter, r *http.Request) {

ctx := r.Context()
subscriptions := rest.env.Store.GetSubscriptions(ctx)
err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}

func (rest *Rest) getSubscription(w http.ResponseWriter, r *http.Request) {

ctx := r.Context()
id, error := strconv.Atoi(chi.URLParam(r, "newsletter_id"))

if error != nil {
fmt.Println("Error during conversion")
return
}
subscriptions := rest.env.Store.GetSubscription(ctx, id, chi.URLParam(r, "email"))
err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}
func (rest *Rest) subscribe(w http.ResponseWriter, r *http.Request) {

var sub store.Subscription

json.NewDecoder(r.Body).Decode(&sub)
ctx := r.Context()

subscriptions := rest.env.Store.NewSubscription(ctx, sub.Newsletter_id, sub.Email)

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}
func (rest *Rest) unsubscribe(w http.ResponseWriter, r *http.Request) {

var sub store.Subscription

json.NewDecoder(r.Body).Decode(&sub)
ctx := r.Context()

subscriptions := rest.env.Store.DeleteSubscription(ctx, sub.Id)

err := json.NewEncoder(w).Encode(subscriptions)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
}
2 changes: 2 additions & 0 deletions environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package environment

import (
"github.com/marhycz/strv-go-newsletter/repository/database"
"github.com/marhycz/strv-go-newsletter/repository/storage"
"github.com/marhycz/strv-go-newsletter/repository/store"
)

type Env struct {
Database *database.Database
Store *store.Store
Storage *storage.Storage
}
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ go 1.20
require github.com/jackc/pgx/v5 v5.3.1

require (
github.com/MicahParks/keyfunc v1.9.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/leodido/go-urn v1.2.3 // indirect
google.golang.org/appengine/v2 v2.0.2 // indirect
)

require (
Expand All @@ -19,11 +21,12 @@ require (
cloud.google.com/go/longrunning v0.4.1 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
firebase.google.com/go v3.13.0+incompatible
firebase.google.com/go/v4 v4.11.0
github.com/georgysavva/scany/v2 v2.0.0
github.com/go-chi/chi/v5 v5.0.8
github.com/go-playground/validator/v10 v10.13.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a
github.com/google/go-cmp v0.5.9 // indirect
Expand All @@ -43,7 +46,7 @@ require (
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.123.0
google.golang.org/appengine v1.6.7 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/o
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
firebase.google.com/go/v4 v4.11.0 h1:szjBoiF33A2FavRLIDZjW1mw+OsW/XAtHoYNIqWOjRk=
firebase.google.com/go/v4 v4.11.0/go.mod h1:60c36dWLK4+j05Vw5XMllek3b3PCynU3BfI46OSwsUE=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o=
github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand Down Expand Up @@ -50,11 +54,14 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -153,6 +160,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
Expand Down Expand Up @@ -191,6 +199,8 @@ golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand All @@ -209,6 +219,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine/v2 v2.0.2 h1:MSqyWy2shDLwG7chbwBJ5uMyw6SNqJzhJHNDwYB0Akk=
google.golang.org/appengine/v2 v2.0.2/go.mod h1:PkgRUWz4o1XOvbqtWTkBtCitEJ5Tp4HoVEdMMYQR/8E=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/marhycz/strv-go-newsletter/api"
"github.com/marhycz/strv-go-newsletter/environment"
"github.com/marhycz/strv-go-newsletter/repository/database"
"github.com/marhycz/strv-go-newsletter/repository/storage"
"github.com/marhycz/strv-go-newsletter/repository/store"
)

Expand All @@ -21,6 +22,7 @@ func main() {
env := &environment.Env{
Database: database.NewConnection(ctx),
Store: store.NewConnection(ctx),
Storage: storage.NewConnection(ctx),
}

controller := api.NewController(env)
Expand Down
7 changes: 7 additions & 0 deletions repository/storage/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package storage

type Issue struct {
Name string `json:"name"`
Id string `json:"id"`
Newsletter_id int `json:"newsletter_id"`
}
Loading

0 comments on commit a881b5b

Please sign in to comment.