コード例 #1
0
ファイル: artist.go プロジェクト: yeison/musicrawler
func (self *ControllerArtist) Show(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if err := self.Env.Db.BeginTransaction(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	defer self.Env.Db.EndTransaction()

	// retreive artist by id
	var artist artist.Artist

	err = query.New(self.Env.Db, "artist").Find(id).Exec(&artist)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// retreive albums of artist
	var albums []album.Album

	err = artist.AlbumsQuery(self.Env.Db).Order("name").Exec(&albums)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// prepare data for template
	for i := 0; i < len(albums); i++ {
		url, err := self.URL("album", controller.Pairs{"id": albums[i].Id})

		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		albums[i].Link = url
	}

	self.Tmpl.AddDataToTemplate("artist_show", "Artist", &artist)
	self.Tmpl.AddDataToTemplate("artist_show", "Albums", &albums)

	backlink, _ := self.URL("artist_base", nil)

	// render the website
	self.Tmpl.RenderPage(
		w,
		"artist_show",
		&tmpl.Page{Title: artist.Name, BackLink: backlink},
	)
}
コード例 #2
0
ファイル: content.go プロジェクト: yeison/musicrawler
// Serving a audio file that has an entry in the database.
func (self *ControllerContent) Show(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	var track trackPathId

	err = query.New(self.Env.Db, "track").Find(id).Exec(&track)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	http.ServeFile(w, r, track.Path)
}
コード例 #3
0
ファイル: track.go プロジェクト: yeison/musicrawler
func (self *RawTrack) AlbumQuery(db *Database) *query.Query {
	return query.New(db, "album").Where("ID =", self.AlbumID)
}
コード例 #4
0
ファイル: artist.go プロジェクト: yeison/musicrawler
// Implementation of SelectHandler.
func (self *ControllerArtist) Index(w http.ResponseWriter, r *http.Request) {
	al, nal, err := artist.FirstLetters(self.Env.Db)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	letters := al

	// use zero to represent non alphabetic letters
	if len(nal) != 0 {
		letters = "0" + al
	}

	page := r.URL.Query().Get("page")

	switch {
	case page == "":
		// just go to the first page by default
		page = string(letters[0])
	case len(page) != 1:
		// No request should contain more than 1 letter.
		http.NotFound(w, r)
		return
	}

	// url validation
	if !strings.ContainsAny(letters, page) {
		http.NotFound(w, r)
		return
	}

	// populating data
	var artists []artist.Artist

	if string(page) == "0" {
		err = artist.NonAlphaArtists(self.Env.Db).Exec(&artists)
	} else {
		err = query.New(self.Env.Db, "artist").
			Like("name", page+"%").Exec(&artists)
	}

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// prepare data for template
	for i := 0; i < len(artists); i++ {
		url, err := self.URL("artist", controller.Pairs{"id": artists[i].Id})

		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		artists[i].Link = url
	}

	url, err := self.URL("artist_base", nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	pager := helper.NewPager(url, strings.Split(letters, ""), page)

	self.Tmpl.AddDataToTemplate("artist_index", "Artists", artists)
	self.Tmpl.AddDataToTemplate("artist_index", "Pager", pager)

	// render the website
	self.Tmpl.RenderPage(
		w,
		"artist_index",
		&tmpl.Page{Title: "Artists starting with " + string(page)},
	)
}
コード例 #5
0
ファイル: album.go プロジェクト: yeison/musicrawler
// Tracks returns a prepared Query reference
func (self *Album) TracksQuery(db *Database) *query.Query {
	return query.New(db, "track").Where("album_id =", self.Id)
}
コード例 #6
0
ファイル: album.go プロジェクト: yeison/musicrawler
func (self *Album) ArtistQuery(db *Database) *query.Query {
	return query.New(db, "artist").Where("ID =", self.ArtistID)
}
コード例 #7
0
ファイル: database_update.go プロジェクト: yeison/musicrawler
// Updates or adds tracks that are received at the tracks channel.
//
// For every track a status update UpdateStatus is emitted to the status
// channel. If the method finishes, the overall result is emitted on the result
// channel.
func updateDatabase(db *database.Database, tracks <-chan source.TrackInfo,
	status chan<- *UpdateStatus) *UpdateResult {

	err := db.BeginTransaction()
	if err != nil {
		close(status)
		return &UpdateResult{Err: err}
	}
	defer db.EndTransaction()

	var trackAction uint8

	tm := &trackMtime{}

	martists := mod.New(db, "artist")
	malbums := mod.New(db, "album")
	mtracks := mod.New(db, "track")

	// traverse all catched pathes and update or add database entries
	for ti := range tracks {
		var statusErr error

		trackAction = TRACK_NOUPDATE

		// check if mtime has changed and decide what to do
		err := query.New(db, "track").Where("path =", ti.Path()).Exec(tm)
		switch {
		case err == nil: // track is in database
			// check if track has changed since the last time
			if ti.Mtime() != tm.Mtime {
				trackAction = TRACK_UPDATE

			} else {
				tdbm := &trackDBMtime{db.Mtime()}
				statusErr = mtracks.Update(tm.ID, tdbm)
			}
		case err == sql.ErrNoRows: // track is not in database
			trackAction = TRACK_ADD
			tag, err := ti.Tags()
			if err != nil {
				statusErr = err
				break
			}

			artist := &artist.Artist{
				Name: tag.Artist,
			}

			res, err := martists.InsertIgnore(artist)
			if err != nil {
				statusErr = err
				break
			}

			aff, _ := res.RowsAffected()

			var artist_id int64

			// if entry exists
			if aff == 0 {
				err = query.New(db, "artist").
					Where("name =", tag.Artist).Limit(1).Exec(artist)
				if err != nil {
					statusErr = err
					break
				}

				artist_id = artist.Id
			} else {
				artist_id, _ = res.LastInsertId()
			}

			album := &album.Album{
				Name:     tag.Album,
				ArtistID: artist_id,
			}

			res, err = malbums.InsertIgnore(album)
			if err != nil {
				statusErr = err
				break
			}

			aff, _ = res.RowsAffected()

			var album_id int64

			// if entry exists
			if aff == 0 {
				err = query.New(db, "album").
					Where("name =", tag.Album).
					Where("artist_id =", artist_id).
					Limit(1).Exec(album)
				if err != nil {
					statusErr = err
					break
				}

				album_id = album.Id
			} else {
				album_id, _ = res.LastInsertId()
			}

			track := &track.RawTrack{
				Path:        ti.Path(),
				Title:       tag.Title,
				Tracknumber: tag.Track,
				Year:        tag.Year,
				Length:      tag.Length,
				Genre:       tag.Genre,
				AlbumID:     album_id,
				Filemtime:   ti.Mtime(),
				DBMtime:     db.Mtime(),
			}

			_, err = mtracks.Insert(track)
			if err != nil {
				statusErr = err
				break
			}
			statusErr = nil

		default:
			// if something is wrong update timestamp, so track is not
			// deleted the next time
			tdbm := &trackDBMtime{db.Mtime()}
			mtracks.Update(tm.ID, tdbm)
			statusErr = err
		}

		status <- &UpdateStatus{
			Path:   ti.Path(),
			Action: trackAction,
			Err:    statusErr}
	}

	// clean up
	del, err := deleteDanglingEntries(db)

	close(status)
	return &UpdateResult{Err: err, Deleted: del}
}