Documentation ¶
Index ¶
- Variables
- type Comment
- type CommentService
- type Feedback
- type FeedbackService
- type Like
- type Playlist
- type PlaylistImage
- type PlaylistSearchParams
- type PlaylistService
- type StereoDoseDB
- type StereodoseCommentService
- type StereodoseFeedbackService
- type StereodosePlaylistService
- func (s *StereodosePlaylistService) Comment(playlistID, text string, user User) (*Comment, error)
- func (s *StereodosePlaylistService) CreatePlaylistBySpotifyID(user User, playlistID, category, subCategory, image, thumbnail string) (*Playlist, error)
- func (s *StereodosePlaylistService) DeleteComment(commentID uint) error
- func (s *StereodosePlaylistService) DeletePlaylist(spotifyID string) error
- func (s *StereodosePlaylistService) GetByID(ID string) (*Playlist, error)
- func (s *StereodosePlaylistService) GetMyPlaylists(user User) ([]Playlist, error)
- func (s *StereodosePlaylistService) GetPlaylists(params *PlaylistSearchParams) ([]Playlist, error)
- func (s *StereodosePlaylistService) GetRandomPlaylist(category, subcategory string) (*Playlist, error)
- func (s *StereodosePlaylistService) Like(playlistID string, user User) (*Like, error)
- func (s *StereodosePlaylistService) Unlike(playlistID string, likeID uint) error
- type StereodoseUserService
- func (u *StereodoseUserService) ByID(ID uint) (*User, error)
- func (u *StereodoseUserService) BySpotifyID(ID string) (*User, error)
- func (u *StereodoseUserService) DeleteUser(user *User) error
- func (u *StereodoseUserService) FirstOrCreate(user *User, tok *oauth2.Token) (*User, error)
- func (u *StereodoseUserService) Update(user *User) error
- func (u *StereodoseUserService) UpdateAccessToken(user *User) error
- type Track
- type User
- type UserImage
- type UserService
Constants ¶
This section is empty.
Variables ¶
var Categories = categories{ { DisplayName: "Weed", Name: "weed", Subcategories: []string{"chill", "groovin", "thug life"}, }, { DisplayName: "Ecstacy", Name: "ecstacy", Subcategories: []string{"dance", "floored", "rolling balls"}, }, { DisplayName: "Shrooms", Name: "shrooms", Subcategories: []string{"matrix", "shaman", "space"}, }, { DisplayName: "LSD", Name: "LSD", Subcategories: []string{"calm", "trippy", "rockstar"}, }, }
Categories is where the music genres are defined We can use this to validate user input before performing database operations Since there are so few categories, there is no need to have this at the database layer
Functions ¶
This section is empty.
Types ¶
type Comment ¶
type Comment struct { gorm.Model Content string `json:"content" gorm:"type:varchar(10000);"` UserID uint `json:"userID"` PlaylistID string `json:"playlistID"` Playlist Playlist `json:"playlist" gorm:"foreignkey:PlaylistID"` DisplayName string `json:"displayName"` Permalink string `json:"permalink"` }
Comment is a struct that contains the text content for a comment a user made on a playlist There is a one-to-many relationship between playlists and comments There is a one-to-many relationship between users and comments
type CommentService ¶
CommentService is an interface for directly performing actions on the comments table
type Feedback ¶
type Feedback struct { gorm.Model UserID uint `json:"userID"` DetectedUserAgent string `json:"detectedUserAgent"` OtherComments string `json:"otherComments" gorm:"type:varchar(10000);"` GoodExperience bool `json:"goodExperience"` }
Feedback is the data structure that data submitted from user surveys The idea is that Stereodose applications like the web app and iOS app can provide views where we can survey the users and ask about their experience. GORM adds an "s" at the end of the table name even though the plural form of feedback is feedback
type FeedbackService ¶
FeedbackService is an interface used to describe all of the behavior of some kind of service that a "Feedback Service" should offer Useful for mocks/fakes when unit testing
type Like ¶
type Like struct { gorm.Model UserID uint `json:"userID"` PlaylistID string `json:"playlistID"` Playlist Playlist `json:"playlist" gorm:"foreignkey:PlaylistID"` PlaylistName string `json:"playlistName"` Permalink string `json:"permalink"` }
Like is a struct that contains data about how a user "liked" a playlist
type Playlist ¶
type Playlist struct { SpotifyID string `json:"spotifyID" gorm:"primary_key:true"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` Category string `json:"category"` CategoryDisplayName string `json:"categoryDisplayName"` SubCategory string `json:"subCategory"` Collaborative bool `json:"collaborative"` Endpoint string `json:"href"` Images []PlaylistImage `json:"images"` Name string `json:"name"` IsPublic bool `json:"public"` SnapshotID string `json:"snapshot_id"` Tracks []Track `json:"tracks" gorm:"many2many:playlist_tracks"` Comments []Comment `json:"comments" gorm:"ForeignKey:PlaylistID;AssociationForeignKey:spotify_id"` Likes []Like `json:"likes" gorm:"ForeignKey:PlaylistID;AssociationForeignKey:spotify_id"` LikesCount uint `json:"likesCount"` URI string `json:"URI"` UserID uint `json:"userID"` BucketImageURL string `json:"bucketImageURL"` BucketThumbnailURL string `json:"bucketThumbnailURL"` Permalink string `json:"permalink"` TotalTracks int `json:"totalTracks"` }
Playlist is the data structure that contains playlist metadata from Spotify It additionally has relations to users and tracks on Stereodose
type PlaylistImage ¶
PlaylistImage should contain a URL or reference to an image It originally comes from Spotify
type PlaylistSearchParams ¶
type PlaylistSearchParams struct { Offset string Limit string Category string Subcategory string SortKey string Order string SpotifyIDs []string }
PlaylistSearchParams can be created using URL query parameters
type PlaylistService ¶
type PlaylistService interface { GetPlaylists(params *PlaylistSearchParams) ([]Playlist, error) GetByID(ID string) (*Playlist, error) GetMyPlaylists(user User) ([]Playlist, error) GetRandomPlaylist(category, subcategory string) (*Playlist, error) // TODO: refactor this to take a Playlist struct instead of a ton of strings CreatePlaylistBySpotifyID(user User, playlistID, category, subCategory, image, thumbnail string) (*Playlist, error) DeletePlaylist(spotifyID string) error Comment(playlistID, text string, user User) (*Comment, error) DeleteComment(commentID uint) error Like(playlistID string, user User) (*Like, error) Unlike(playlistID string, likeID uint) error }
PlaylistService is an interface used to describe all of the behavior of some kind of service that a "Playlist Service" should offer Useful for mocks/fakes when unit testing
type StereoDoseDB ¶
type StereoDoseDB struct { DB *gorm.DB Users UserService Playlists PlaylistService Comments CommentService Feedback FeedbackService // contains filtered or unexported fields }
StereoDoseDB is a layer on top of Gorm It allows callers to easily use the structs relevant to the rest of the app
func NewStereodoseDB ¶
func NewStereodoseDB(c *config.Config, s *sessions.CookieStore) *StereoDoseDB
NewStereodoseDB takes a reference to gorm and returns an abstraction for use throughout the app
type StereodoseCommentService ¶
type StereodoseCommentService struct {
// contains filtered or unexported fields
}
StereodoseCommentService contains a db and several methods for acting on comments in the local database
type StereodoseFeedbackService ¶
StereodoseFeedbackService is an implementation of Feedback Service
func NewFeedbackService ¶
func NewFeedbackService(db *gorm.DB) *StereodoseFeedbackService
NewFeedbackService will create a new FeedBack service and return a pointer
func (*StereodoseFeedbackService) CreateFeedback ¶
func (s *StereodoseFeedbackService) CreateFeedback(feedback *Feedback) error
CreateFeedback will save feedback to the database It will also attempt to send a message to the Stereodose OPS SNS ARN. If it fails to send to SNS it will only log warnings. It will not report errors to end users
type StereodosePlaylistService ¶
type StereodosePlaylistService struct {
// contains filtered or unexported fields
}
StereodosePlaylistService contains a db and several methods for acting on playlists in the local database
func (*StereodosePlaylistService) Comment ¶
func (s *StereodosePlaylistService) Comment(playlistID, text string, user User) (*Comment, error)
Comment will save a comment to the specified playlist
func (*StereodosePlaylistService) CreatePlaylistBySpotifyID ¶
func (s *StereodosePlaylistService) CreatePlaylistBySpotifyID(user User, playlistID, category, subCategory, image, thumbnail string) (*Playlist, error)
CreatePlaylistBySpotifyID is given a user and playlistID It uses the information to call the Spotify API and save the information to the local db
func (*StereodosePlaylistService) DeleteComment ¶
func (s *StereodosePlaylistService) DeleteComment(commentID uint) error
DeleteComment will soft delete a comment from a playlist
func (*StereodosePlaylistService) DeletePlaylist ¶
func (s *StereodosePlaylistService) DeletePlaylist(spotifyID string) error
DeletePlaylist hard deletes the playlist (only from the StereodoseDB)
func (*StereodosePlaylistService) GetByID ¶
func (s *StereodosePlaylistService) GetByID(ID string) (*Playlist, error)
GetByID returns a playlist populated with all of its tracks
func (*StereodosePlaylistService) GetMyPlaylists ¶
func (s *StereodosePlaylistService) GetMyPlaylists(user User) ([]Playlist, error)
GetMyPlaylists returns all of the playlists that belong to a particular User
func (*StereodosePlaylistService) GetPlaylists ¶
func (s *StereodosePlaylistService) GetPlaylists(params *PlaylistSearchParams) ([]Playlist, error)
GetPlaylists takes search parameters and returns a subset of playlists callers of this method are responsible for checking the limit and offset
func (*StereodosePlaylistService) GetRandomPlaylist ¶
func (s *StereodosePlaylistService) GetRandomPlaylist(category, subcategory string) (*Playlist, error)
GetRandomPlaylist tells the database to grab a random set of playlists from the selected category then a random set of tracks is selected across those playlists to get a completely new playlist made up of randomly selected tracks Using the gorm.Expr somewhat breaks the compatibility with other databases as the random() function is supported in Postgres but it's rand() in MySQL
func (*StereodosePlaylistService) Like ¶
func (s *StereodosePlaylistService) Like(playlistID string, user User) (*Like, error)
Like will increment the like column for the respective playlist it also adds an entry in the likes table it is the responsibility of the caller to make sure the user has not liked the playlist already this method by itself is effectively Medium's "claps" TODO: need to refactor this so the Playlist struct "knows" about who owns the likes otherwise, if a playlist gets deleted/created again, the likes count can drop to negative numbers comments works like this could be problematic for very large number of likes
type StereodoseUserService ¶
type StereodoseUserService struct {
// contains filtered or unexported fields
}
StereodoseUserService contains a db and several methods for acting on users in the local database
func (*StereodoseUserService) ByID ¶
func (u *StereodoseUserService) ByID(ID uint) (*User, error)
ByID first checks to see if the user already exists if it doesn't it creates one, otherwise it returns a pointer to user
func (*StereodoseUserService) BySpotifyID ¶
func (u *StereodoseUserService) BySpotifyID(ID string) (*User, error)
BySpotifyID searches by the SpotifyID and returns a User
func (*StereodoseUserService) DeleteUser ¶
func (u *StereodoseUserService) DeleteUser(user *User) error
DeleteUser attempts to soft delete a User
func (*StereodoseUserService) FirstOrCreate ¶
FirstOrCreate finds the first matched User or creates a new one
func (*StereodoseUserService) Update ¶
func (u *StereodoseUserService) Update(user *User) error
Update runs a User update
func (*StereodoseUserService) UpdateAccessToken ¶
func (u *StereodoseUserService) UpdateAccessToken(user *User) error
UpdateAccessToken can be used on demand to update the user's access token in the database
type Track ¶
type Track struct { SpotifyID string `json:"spotifyID" gorm:"primary_key:true"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` Name string `json:"name"` Duration int `json:"duration"` PreviewURL string `json:"previewURL"` TrackNumber int `json:"trackNumber"` URI string `json:"URI"` Artists string `json:"artists"` SpotifyArtistIDs string `json:"spotifyArtistIDs"` }
Track is a data structure representing a particular song from Spotify
type User ¶
type User struct { gorm.Model Birthdate string `json:"birthDate"` DisplayName string `json:"displayName"` Email string `json:"email"` // TODO: may want to change this to not unique to handle soft delete cases SpotifyID string `json:"spotifyID" gorm:"unique;not null"` RefreshToken string `json:"-"` // Hide the RefreshToken in json responses AccessToken string `json:"accessToken"` Images []UserImage `json:"images"` Playlists []Playlist `json:"playlists"` Comments []Comment `json:"comments"` Likes []Like `json:"likes"` // Product is the user's subscription level: "premium, free etc..." Product string `json:"product"` Admin bool `json:"-"` }
User is the data structure that contains user metadata from Spotify It additionally a relation to playlists Stereodose
type UserImage ¶
UserImage should contain a URL or reference to an image It originally comes from Spotify, thus the embedded type
type UserService ¶
type UserService interface { ByID(ID uint) (*User, error) BySpotifyID(ID string) (*User, error) FirstOrCreate(user *User, tok *oauth2.Token) (*User, error) Update(user *User) error UpdateAccessToken(user *User) error }
UserService is an interface used to describe all of the behavior of some kind of service that a "User Service" should offer Useful for mocks/fakes when unit testing