Skip to content

Commit

Permalink
Support for Original Date, Release Date & splitting/grouping of album…
Browse files Browse the repository at this point in the history
… editions (navidrome#2162)

* Update AlbumGridView.js

* Update AlbumDetails.js

* Update AlbumDetails.js

* Create DoubleRangeField.js

* Update and rename DoubleRangeField.js to RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update AlbumGridView.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update index.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update en.json

* Update en.json

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update AlbumGridView.js

* Update AlbumDetails.js

* Update AlbumSongs.js

* Update ContextMenus.js

* Update SongDatagrid.js

* Update AlbumSongs.js

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update AlbumSongs.js

* Update SongList.js

* Update playlist_track_repository.go

* Update 20230113000000_release_year.go

* Update PlayButton.js

* Update mediafile_repository.go

* Update album.go

* Update playlist_track_repository.go

* Update playlist_track_repository.go

* Update SongDatagrid.js

* Update 20230113000000_release_year.go

* Update SongDatagrid.js

* Update AlbumSongs.js

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update AlbumDetails.js

* Update AlbumSongs.js

* Update AlbumSongs.js

* Update RangeFieldDouble.js

* Update SongDatagrid.js

* Update 20230113000000_release_year.go

* Update 20230113000000_release_year.go

* Update 20230113000000_release_year.go

* Update 20230113000000_release_year.go

* Update AlbumSongs.js

* Update AlbumSongs.js

* Update mapping.go

* Update RangeFieldDouble.js

* Update AlbumGridView.js

* Update AlbumSongs.js

* Update en.json

* Update SongDatagrid.js

* Update SongDatagrid.js

* Update metadata.go

* Update mapping.go

* Update AlbumDetails.js

* Update AlbumGridView.js

* Update RangeFieldDouble.js

* Update mapping.go

* Update metadata.go

* Update mapping.go

* Update AlbumDetails.js

* Update 20230113000000_release_year.go

* Update AlbumDetails.js

* Update en.json

* Update configuration.go

* Update mapping.go

* Update configuration.go

* Update mediafile.go

* Update metadata.go

* Update RangeFieldDouble.js

* Update 20230113000000_release_year.go

* Update configuration.go

* Update mapping.go

* Update mediafile.go

* Update mapping.go

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update RangeFieldDouble.js

* Update 20230113000000_release_year.go

* Update AlbumDetails.js

* Update RangeFieldDouble.js

* Update mapping.go

* Update metadata.go

* Update album.go

* Update mediafile.go

* Update mediafile.go

* Update album.go

* Update fields.go

* Update mediafile_repository.go

* Update playlist_track_repository.go

* Update AlbumSongs.js

* Update SongDatagrid.js

* Update PlayButton.js

* Update SongList.js

* Update ContextMenus.js

* Update SongDatagrid.js

* Update metadata.go

* Update ArtistShow.js

* Update mapping.go

* Update configuration.go

* Update mapping.go

* Update metadata.go

* Update metadata.go

* Update mapping.go

* Update metadata.go

* Update metadata.go

* Update mapping.go

* Update 20230113000000_release_year.go

* Update 20230113000000_release_year.go

* Update mapping.go

* Update metadata.go

* Update metadata.go

* Update album.go

* Update mediafile.go

* Update AlbumDetails.js

* Update AlbumSongs.js

* Update album.go

* Update mediafile.go

* Update metadata.go

* Update mediafile.go

* Update 20230113000000_release_year.go

* Update 20230113000000_release_year.go

* Update album.go

* Update mediafile.go

* Update RangeFieldDouble.js

* Update AlbumDetails.js

* Update AlbumGridView.js

* Update en.json

* Update AlbumGridView.js

* Update RangeFieldDouble.js

* Update and rename 20230113000000_release_year.go to 20230113000000_release_date.go

* Update album.go

* Update mediafile.go

* Update fields.go

* Update playlist_track_repository.go

* Update mediafile_repository.go

* Update mapping.go

* Update metadata.go

* Update mapping.go

* Update SongDatagrid.js

* Update RangeFieldDouble.js

* Update index.js

* Update ContextMenus.js

* Update PlayButton.js

* Create FormatDate.js

* Update SongList.js

* Update AlbumDetails.js

* Update AlbumSongs.js

* Update AlbumSongs.js

* Update en.json

* Update AlbumDetails.js

* Update album.go

fixed conflict I think?

* Update mediafile.go

fixed conflict

* Format with goimports

* Update SongDatagrid.js

only show Cat # in desktop view

* Update metadata_internal_test.go

* Update metadata_test.go

* Delete test.mp3

* Add files via upload

mp3 test file with Date, Original Date and Release Date

* Update metadata_test.go

* Update metadata_test.go

* Update metadata_test.go

* Update metadata_test.go

* Update taglib_test.go

* Delete test.mp3

* Add files via upload

file with replaygain & dates

* Update AlbumGridView.js

* Update AlbumDetails.js

* Update AlbumSongs.js

* Update ContextMenus.js

* Update FormatDate.js

* Update PlayButton.js

* Update RangeFieldDouble.js

* Update SongDatagrid.js

* Update AlbumSongs.js

* Update SongDatagrid.js

* Update AlbumSongs.js

* Fix formatting

* Update mapping.go

* Update AlbumSongs.js

* Update SongDatagrid.js

* Update SongDatagrid.js

prettier

* Create RangeDoubleField.js

rename of RangeFieldDouble.js

* Update AlbumGridView.js

RangeFieldDouble -> RangeDoubleField

* Update mediafile.go

AllOrNothing() -> allOrNothing()

* Update metadata_internal_test.go

getYear -> getDate

* Update AlbumDetails.js

wrote suggested changes

* Update en.json

Editions -> Releases & fixed the field name

* Update configuration.go

Rename Editions -> Releases

* Update 20230113000000_release_date.go

Editions -> Releases

* Update album.go

Editions -> Releases

* Update mediafile.go

Editions -> Releases

* Update AlbumDetails.js

Editions -> Releases

* Update AlbumSongs.js

Editions -> Releases

* Update RangeDoubleField.js

Editions -> Releases

* Update SongDatagrid.js

Editions -> Releases

* Update index.js

FormatFullDate and RangeDoubleField

* Rename FormatDate.js to FormatFullDate.js

* Delete RangeFieldDouble.js

* Update mediafile.go

AllOrNothing -> allOrNothing

* Update mapping.go

Editions -> Releases

* Update AlbumDetails.js

prettier

* Update SongDatagrid.js

showReleaseRow -> showReleaseDivider

* Update AlbumSongs.js

showReleaseRow -> showReleaseDivider for clarity

* Update and rename 20230113000000_release_date.go to 20230515184510_add_release_date.go

- rename the migration file
- fixed the import to goose/v3
- additional db fields for original date & year

* Update 20230515184510_add_release_date.go

* Update fields.go

* Update album.go

* Update mediafile.go

* Update mapping.go

* Update AlbumDetails.js

* Update en.json

* Update AlbumDetails.js

* Update AlbumDetails.js

now hopefully prettier

* Update mapping.go

---------

Co-authored-by: Deluan <[email protected]>
  • Loading branch information
certuna and deluan authored May 19, 2023
1 parent 010ba0d commit 52b77e4
Show file tree
Hide file tree
Showing 24 changed files with 511 additions and 78 deletions.
6 changes: 4 additions & 2 deletions conf/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ type configOptions struct {
}

type scannerOptions struct {
Extractor string
GenreSeparators string
Extractor string
GenreSeparators string
GroupAlbumReleases bool
}

type lastfmOptions struct {
Expand Down Expand Up @@ -297,6 +298,7 @@ func init() {

viper.SetDefault("scanner.extractor", consts.DefaultScannerExtractor)
viper.SetDefault("scanner.genreseparators", ";/,")
viper.SetDefault("scanner.groupalbumreleases", true)

viper.SetDefault("agents", "lastfm,spotify")
viper.SetDefault("lastfm.enabled", true)
Expand Down
49 changes: 49 additions & 0 deletions db/migration/20230515184510_add_release_date.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package migrations

import (
"database/sql"

"github.com/pressly/goose/v3"
)

func init() {
goose.AddMigration(upAddRelRecYear, downAddRelRecYear)
}

func upAddRelRecYear(tx *sql.Tx) error {
_, err := tx.Exec(`
alter table media_file
add date varchar(255) default '' not null;
alter table media_file
add original_year int default 0 not null;
alter table media_file
add original_date varchar(255) default '' not null;
alter table media_file
add release_year int default 0 not null;
alter table media_file
add release_date varchar(255) default '' not null;
alter table album
add date varchar(255) default '' not null;
alter table album
add min_original_year int default 0 not null;
alter table album
add max_original_year int default 0 not null;
alter table album
add original_date varchar(255) default '' not null;
alter table album
add release_date varchar(255) default '' not null;
alter table album
add releases integer default 0 not null;
`)
if err != nil {
return err
}

notice(tx, "A full rescan needs to be performed to import more tags")
return forceFullRescan(tx)
}

func downAddRelRecYear(tx *sql.Tx) error {
return nil
}
11 changes: 9 additions & 2 deletions model/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ type Album struct {
AllArtistIDs string `structs:"all_artist_ids" json:"allArtistIds" orm:"column(all_artist_ids)"`
MaxYear int `structs:"max_year" json:"maxYear"`
MinYear int `structs:"min_year" json:"minYear"`
Date string `structs:"date" json:"date,omitempty"`
MaxOriginalYear int `structs:"max_original_year" json:"maxOriginalYear"`
MinOriginalYear int `structs:"min_original_year" json:"minOriginalYear"`
OriginalDate string `structs:"original_date" json:"originalDate,omitempty"`
ReleaseDate string `structs:"release_date" json:"releaseDate,omitempty"`
Releases int `structs:"releases" json:"releases"`
Compilation bool `structs:"compilation" json:"compilation"`
Comment string `structs:"comment" json:"comment,omitempty"`
SongCount int `structs:"song_count" json:"songCount"`
Expand Down Expand Up @@ -55,8 +61,9 @@ func (a Album) CoverArtID() ArtworkID {
}

type DiscID struct {
AlbumID string `json:"albumId"`
DiscNumber int `json:"discNumber"`
AlbumID string `json:"albumId"`
ReleaseDate string `json:"releaseDate"`
DiscNumber int `json:"discNumber"`
}

type Albums []Album
Expand Down
5 changes: 5 additions & 0 deletions model/criteria/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ var fieldMap = map[string]*mappedField{
"tracknumber": {field: "media_file.track_number"},
"discnumber": {field: "media_file.disc_number"},
"year": {field: "media_file.year"},
"date": {field: "media_file.date"},
"originalyear": {field: "media_file.original_year"},
"originaldate": {field: "media_file.original_date"},
"releaseyear": {field: "media_file.release_year"},
"releasedate": {field: "media_file.release_date"},
"size": {field: "media_file.size"},
"compilation": {field: "media_file.compilation"},
"dateadded": {field: "media_file.created_at"},
Expand Down
60 changes: 50 additions & 10 deletions model/mediafile.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package model
import (
"mime"
"path/filepath"
"sort"
"strings"
"time"

Expand Down Expand Up @@ -32,6 +33,11 @@ type MediaFile struct {
DiscNumber int `structs:"disc_number" json:"discNumber"`
DiscSubtitle string `structs:"disc_subtitle" json:"discSubtitle,omitempty"`
Year int `structs:"year" json:"year"`
Date string `structs:"date" json:"date,omitempty"`
OriginalYear int `structs:"original_year" json:"originalYear"`
OriginalDate string `structs:"original_date" json:"originalDate,omitempty"`
ReleaseYear int `structs:"release_year" json:"releaseYear"`
ReleaseDate string `structs:"release_date" json:"releaseDate,omitempty"`
Size int64 `structs:"size" json:"size"`
Suffix string `structs:"suffix" json:"suffix"`
Duration float32 `structs:"duration" json:"duration"`
Expand Down Expand Up @@ -108,6 +114,11 @@ func (mfs MediaFiles) ToAlbum() Album {
var songArtistIds []string
var mbzAlbumIds []string
var comments []string
var years []int
var dates []string
var originalYears []int
var originalDates []string
var releaseDates []string
for _, m := range mfs {
// We assume these attributes are all the same for all songs on an album
a.ID = m.AlbumID
Expand All @@ -130,12 +141,11 @@ func (mfs MediaFiles) ToAlbum() Album {
// Calculated attributes based on aggregations
a.Duration += m.Duration
a.Size += m.Size
if a.MinYear == 0 {
a.MinYear = m.Year
} else if m.Year > 0 {
a.MinYear = number.Min(a.MinYear, m.Year)
}
a.MaxYear = number.Max(a.MaxYear, m.Year)
years = append(years, m.Year)
dates = append(dates, m.Date)
originalYears = append(originalYears, m.OriginalYear)
originalDates = append(originalDates, m.OriginalDate)
releaseDates = append(releaseDates, m.ReleaseDate)
a.UpdatedAt = newer(a.UpdatedAt, m.UpdatedAt)
a.CreatedAt = older(a.CreatedAt, m.CreatedAt)
a.Genres = append(a.Genres, m.Genres...)
Expand All @@ -151,11 +161,15 @@ func (mfs MediaFiles) ToAlbum() Album {
a.EmbedArtPath = m.Path
}
}

a.Paths = strings.Join(mfs.Dirs(), consts.Zwsp)
comments = slices.Compact(comments)
if len(comments) == 1 {
a.Comment = comments[0]
}
a.Date, _ = allOrNothing(dates)
a.OriginalDate, _ = allOrNothing(originalDates)
a.ReleaseDate, a.Releases = allOrNothing(releaseDates)
a.MinYear, a.MaxYear = minMax(years)
a.MinOriginalYear, a.MaxOriginalYear = minMax(originalYears)
a.Comment, _ = allOrNothing(comments)
a.Comment, _ = allOrNothing(comments)
a.Genre = slice.MostFrequent(a.Genres).Name
slices.SortFunc(a.Genres, func(a, b Genre) bool { return a.ID < b.ID })
a.Genres = slices.Compact(a.Genres)
Expand All @@ -169,6 +183,32 @@ func (mfs MediaFiles) ToAlbum() Album {
return a
}

func allOrNothing(items []string) (string, int) {
items = slices.Compact(items)
if len(items) == 1 {
return items[0], 1
}
if len(items) > 1 {
sort.Strings(items)
return "", len(slices.Compact(items))
}
return "", 0
}

func minMax(items []int) (int, int) {
var max int = items[0]
var min int = items[0]
for _, value := range items {
max = number.Max(max, value)
if min == 0 {
min = value
} else if value > 0 {
min = number.Min(min, value)
}
}
return min, max
}

func newer(t1, t2 time.Time) time.Time {
if t1.After(t2) {
return t1
Expand Down
4 changes: 2 additions & 2 deletions persistence/mediafile_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func NewMediaFileRepository(ctx context.Context, o orm.QueryExecutor) *mediaFile
r.ormer = o
r.tableName = "media_file"
r.sortMappings = map[string]string{
"artist": "order_artist_name asc, order_album_name asc, disc_number asc, track_number asc",
"album": "order_album_name asc, disc_number asc, track_number asc, order_artist_name asc, title asc",
"artist": "order_artist_name asc, order_album_name asc, release_date asc, disc_number asc, track_number asc",
"album": "order_album_name asc, release_date asc, disc_number asc, track_number asc, order_artist_name asc, title asc",
"random": "RANDOM()",
}
r.filterMappings = map[string]filterFunc{
Expand Down
4 changes: 2 additions & 2 deletions persistence/playlist_track_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (r *playlistTrackRepository) Add(mediaFileIds []string) (int, error) {
}

func (r *playlistTrackRepository) addMediaFileIds(cond Sqlizer) (int, error) {
sq := Select("id").From("media_file").Where(cond).OrderBy("album_artist, album, disc_number, track_number")
sq := Select("id").From("media_file").Where(cond).OrderBy("album_artist, album, release_date, disc_number, track_number")
var ids []string
err := r.queryAll(sq, &ids)
if err != nil {
Expand All @@ -147,7 +147,7 @@ func (r *playlistTrackRepository) AddDiscs(discs []model.DiscID) (int, error) {
}
var clauses Or
for _, d := range discs {
clauses = append(clauses, And{Eq{"album_id": d.AlbumID}, Eq{"disc_number": d.DiscNumber}})
clauses = append(clauses, And{Eq{"album_id": d.AlbumID}, Eq{"release_date": d.ReleaseDate}, Eq{"disc_number": d.DiscNumber}})
}
return r.addMediaFileIds(clauses)
}
Expand Down
26 changes: 23 additions & 3 deletions scanner/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ func newMediaFileMapper(rootFolder string, genres model.GenreRepository) *mediaF
func (s mediaFileMapper) toMediaFile(md metadata.Tags) model.MediaFile {
mf := &model.MediaFile{}
mf.ID = s.trackID(md)
mf.Year, mf.Date, mf.OriginalYear, mf.OriginalDate, mf.ReleaseYear, mf.ReleaseDate = s.mapDates(md)
mf.Title = s.mapTrackTitle(md)
mf.Album = md.Album()
mf.AlbumID = s.albumID(md)
mf.AlbumID = s.albumID(md, mf.ReleaseDate)
mf.Album = s.mapAlbumName(md)
mf.ArtistID = s.artistID(md)
mf.Artist = s.mapArtistName(md)
mf.AlbumArtistID = s.albumArtistID(md)
mf.AlbumArtist = s.mapAlbumArtistName(md)
mf.Genre, mf.Genres = s.mapGenres(md.Genres())
mf.Compilation = md.Compilation()
mf.Year = md.Year()
mf.TrackNumber, _ = md.TrackNumber()
mf.DiscNumber, _ = md.DiscNumber()
mf.DiscSubtitle = md.DiscSubtitle()
Expand Down Expand Up @@ -128,8 +128,13 @@ func (s mediaFileMapper) trackID(md metadata.Tags) string {
return fmt.Sprintf("%x", md5.Sum([]byte(md.FilePath())))
}

func (s mediaFileMapper) albumID(md metadata.Tags) string {
func (s mediaFileMapper) albumID(md metadata.Tags, releaseDate string) string {
albumPath := strings.ToLower(fmt.Sprintf("%s\\%s", s.mapAlbumArtistName(md), s.mapAlbumName(md)))
if !conf.Server.Scanner.GroupAlbumReleases {
if len(releaseDate) != 0 {
albumPath = fmt.Sprintf("%s\\%s", albumPath, releaseDate)
}
}
return fmt.Sprintf("%x", md5.Sum([]byte(albumPath)))
}

Expand Down Expand Up @@ -169,3 +174,18 @@ func (s mediaFileMapper) mapGenres(genres []string) (string, model.Genres) {
}
return result[0].Name, result
}

func (s mediaFileMapper) mapDates(md metadata.Tags) (int, string, int, string, int, string) {
year, date := md.Date()
originalYear, originalDate := md.OriginalDate()
releaseYear, releaseDate := md.ReleaseDate()

// MusicBrainz Picard writes the Release Date of an album to the Date tag, and leaves the Release Date tag empty
taggedLikePicard := (originalYear != 0) &&
(releaseYear == 0) &&
(year >= originalYear)
if taggedLikePicard {
return originalYear, originalDate, originalYear, originalDate, year, date
}
return year, date, originalYear, originalDate, releaseYear, releaseDate
}
56 changes: 39 additions & 17 deletions scanner/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,19 @@ func (t Tags) Artist() string { return t.getFirstTagValue("artist", "sort_artist
func (t Tags) AlbumArtist() string {
return t.getFirstTagValue("album_artist", "album artist", "albumartist")
}
func (t Tags) SortTitle() string { return t.getSortTag("", "title", "name") }
func (t Tags) SortAlbum() string { return t.getSortTag("", "album") }
func (t Tags) SortArtist() string { return t.getSortTag("", "artist") }
func (t Tags) SortAlbumArtist() string { return t.getSortTag("tso2", "albumartist", "album_artist") }
func (t Tags) Genres() []string { return t.getAllTagValues("genre") }
func (t Tags) Year() int { return t.getYear("date") }
func (t Tags) Comment() string { return t.getFirstTagValue("comment") }
func (t Tags) Lyrics() string { return t.getFirstTagValue("lyrics", "lyrics-eng") }
func (t Tags) Compilation() bool { return t.getBool("tcmp", "compilation") }
func (t Tags) TrackNumber() (int, int) { return t.getTuple("track", "tracknumber") }
func (t Tags) DiscNumber() (int, int) { return t.getTuple("disc", "discnumber") }
func (t Tags) SortTitle() string { return t.getSortTag("", "title", "name") }
func (t Tags) SortAlbum() string { return t.getSortTag("", "album") }
func (t Tags) SortArtist() string { return t.getSortTag("", "artist") }
func (t Tags) SortAlbumArtist() string { return t.getSortTag("tso2", "albumartist", "album_artist") }
func (t Tags) Genres() []string { return t.getAllTagValues("genre") }
func (t Tags) Date() (int, string) { return t.getDate("date") }
func (t Tags) OriginalDate() (int, string) { return t.getDate("originaldate") }
func (t Tags) ReleaseDate() (int, string) { return t.getDate("releasedate") }
func (t Tags) Comment() string { return t.getFirstTagValue("comment") }
func (t Tags) Lyrics() string { return t.getFirstTagValue("lyrics", "lyrics-eng") }
func (t Tags) Compilation() bool { return t.getBool("tcmp", "compilation") }
func (t Tags) TrackNumber() (int, int) { return t.getTuple("track", "tracknumber") }
func (t Tags) DiscNumber() (int, int) { return t.getTuple("disc", "discnumber") }
func (t Tags) DiscSubtitle() string {
return t.getFirstTagValue("tsst", "discsubtitle", "setsubtitle")
}
Expand Down Expand Up @@ -217,18 +219,38 @@ func (t Tags) getSortTag(originalTag string, tagNames ...string) string {

var dateRegex = regexp.MustCompile(`([12]\d\d\d)`)

func (t Tags) getYear(tagNames ...string) int {
func (t Tags) getDate(tagNames ...string) (int, string) {
tag := t.getFirstTagValue(tagNames...)
if tag == "" {
return 0
if len(tag) < 4 {
return 0, ""
}
// first get just the year
match := dateRegex.FindStringSubmatch(tag)
if len(match) == 0 {
log.Warn("Error parsing year date field", "file", t.filePath, "date", tag)
return 0
log.Warn("Error parsing "+tagNames[0]+" field for year", "file", t.filePath, "date", tag)
return 0, ""
}
year, _ := strconv.Atoi(match[1])
return year

if len(tag) < 5 {
return year, match[1]
}

//then try YYYY-MM-DD
if len(tag) > 10 {
tag = tag[:10]
}
layout := "2006-01-02"
_, err := time.Parse(layout, tag)
if err != nil {
layout = "2006-01"
_, err = time.Parse(layout, tag)
if err != nil {
log.Warn("Error parsing "+tagNames[0]+" field for month + day", "file", t.filePath, "date", tag)
return year, match[1]
}
}
return year, tag
}

func (t Tags) getBool(tagNames ...string) bool {
Expand Down
Loading

0 comments on commit 52b77e4

Please sign in to comment.