138 lines
3.3 KiB
Go
138 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"golang.org/x/text/transform"
|
|
"golang.org/x/text/unicode/norm"
|
|
)
|
|
|
|
// An AlbumState describe the state of an Album
|
|
type AlbumState int
|
|
|
|
// An AlbumID uniquely identifies an Album both here and www.bedetheque.com
|
|
type AlbumID uint64
|
|
|
|
const (
|
|
// NEW is "État neuf" state
|
|
NEW AlbumState = iota // 0
|
|
// MINT is "Très bon état" state
|
|
MINT // 1
|
|
// GOOD is "Bon état" state
|
|
GOOD // 2
|
|
// AVERAGE is "État moyen" state
|
|
AVERAGE // 3
|
|
// BAD is "Mauvais état" state
|
|
BAD // 4
|
|
)
|
|
|
|
// An Album is the core object in our system
|
|
//
|
|
// This is basically the data we store on bdgest.com, and that we want
|
|
// in our system to be retrieve from
|
|
type Album struct {
|
|
ID AlbumID
|
|
ISBN string
|
|
Series string
|
|
Title string
|
|
Num int
|
|
NumA string
|
|
State AlbumState
|
|
|
|
Author string
|
|
Editor string
|
|
Collection string
|
|
SatID string
|
|
|
|
LegalDeposit time.Time
|
|
PrintDate time.Time
|
|
PurchaseDate time.Time
|
|
}
|
|
|
|
var endDelim = regexp.MustCompile(` \(.*\)\z`)
|
|
var wordBoundaries = regexp.MustCompile(`[^[:alnum:]]+`)
|
|
var punctuation = regexp.MustCompile(`[!?\.:;,]`)
|
|
|
|
func sanitizeTitleString(title string) string {
|
|
// first sanitize accuented characters.
|
|
isOk := func(r rune) bool {
|
|
return r < 32 || r >= 127
|
|
}
|
|
// The isOk filter is such that there is no need to chain to norm.NFC
|
|
t := transform.Chain(norm.NFKD, transform.RemoveFunc(isOk))
|
|
// This Transformer could also trivially be applied as an io.Reader
|
|
// or io.Writer filter to automatically do such filtering when reading
|
|
// or writing data anywhere.
|
|
title, _, _ = transform.String(t, title)
|
|
//Now we remove all punctuat
|
|
return strings.Trim(wordBoundaries.ReplaceAllString(punctuation.ReplaceAllString(title, ""), "-"), "-")
|
|
}
|
|
|
|
// GetBedethequeComURI tries to guess the URI used by bedetheque.com to reference an album, using reverse-engineered euristics
|
|
func (a *Album) GetBedethequeComURI() string {
|
|
// we check for determinant
|
|
matches := endDelim.FindString(a.Series)
|
|
series := a.Series
|
|
titleMatch := false
|
|
if len(matches) != 0 {
|
|
series = strings.TrimSuffix(series, matches)
|
|
det := strings.Trim(matches, " ()")
|
|
if det[len(det)-1] != '\'' {
|
|
det = det + " "
|
|
}
|
|
titleCompare := det + strings.ToLower(series[:1]) + series[1:]
|
|
titleMatch = (titleCompare == a.Title)
|
|
} else {
|
|
titleMatch = (a.Series == a.Title)
|
|
}
|
|
|
|
series = sanitizeTitleString(series)
|
|
title := sanitizeTitleString(a.Title)
|
|
//first we test if we have a tome identifier
|
|
tomeIdent := ""
|
|
if a.Num < 0 {
|
|
tomeIdent = a.NumA
|
|
} else {
|
|
tomeIdent = fmt.Sprintf("Tome-%d%s", a.Num, a.NumA)
|
|
}
|
|
|
|
if titleMatch {
|
|
if len(tomeIdent) == 0 {
|
|
return fmt.Sprintf("BD-%s-%d.html", series, a.ID)
|
|
}
|
|
return fmt.Sprintf("BD-%s-%s-%d.html", series, tomeIdent, a.ID)
|
|
}
|
|
if len(tomeIdent) == 0 {
|
|
return fmt.Sprintf("BD-%s-%s-%d.html", series, title, a.ID)
|
|
}
|
|
return fmt.Sprintf("BD-%s-%s-%s-%d.html",
|
|
series,
|
|
tomeIdent,
|
|
title,
|
|
a.ID)
|
|
}
|
|
|
|
// A Link represent a link to a ressource
|
|
type Link struct {
|
|
// Title of the link
|
|
Title string
|
|
// Target of the link
|
|
Target string
|
|
}
|
|
|
|
// An AlbumDescription is a more complete BD description
|
|
//
|
|
// It holds data that can be fetched from bedetheque.com
|
|
type AlbumDescription struct {
|
|
CoverExt string
|
|
Description string
|
|
Note float64
|
|
|
|
Scenarist []Link
|
|
Designer []Link
|
|
Colorist []Link
|
|
}
|