Stuff
This commit is contained in:
parent
8657d9c1eb
commit
3f7f858d03
180
compareID.go
Normal file
180
compareID.go
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package compareID
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/agext/levenshtein"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Anime contains the essentials for being able to compare anidb to meikan
|
||||||
|
type Anime struct {
|
||||||
|
ID int
|
||||||
|
Type string
|
||||||
|
Episodes int
|
||||||
|
Title string
|
||||||
|
StartDate time.Time
|
||||||
|
EndDate time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
//Result is the way the json received is structured
|
||||||
|
//It contains a collection of animes made up of AnimeRes
|
||||||
|
type Result struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Anime []AnimeRes `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//AnimeRes is how the search results from meikan are built up in the JSON
|
||||||
|
type AnimeRes struct {
|
||||||
|
EndDate string `json:"end_date"`
|
||||||
|
Episodes int `json:"episodes"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Rating string `json:"rating"`
|
||||||
|
StartDate string `json:"start_date"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//Animes is a collection of animes
|
||||||
|
type Animes []MatchedAnime
|
||||||
|
|
||||||
|
//MatchedAnime contains all the neccessary information after matching two animes
|
||||||
|
type MatchedAnime struct {
|
||||||
|
MeikanTitle string
|
||||||
|
AnidbTitle string
|
||||||
|
MeikanID int
|
||||||
|
AnidbID int
|
||||||
|
Score int
|
||||||
|
}
|
||||||
|
|
||||||
|
//check does a default error check
|
||||||
|
func check(e error) {
|
||||||
|
if e != nil {
|
||||||
|
panic(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//lessType makes types when comparing less specific
|
||||||
|
//So missmatches like OVA == Specials don't happen.
|
||||||
|
func LessType(Type string) string {
|
||||||
|
switch Type {
|
||||||
|
case "TV", "ONA":
|
||||||
|
return "Shows"
|
||||||
|
case "OVA", "Specials":
|
||||||
|
return "Extra"
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type
|
||||||
|
}
|
||||||
|
|
||||||
|
//fixType changes the types anidb uses to ones that match with meikan specifications.
|
||||||
|
func FixType(Type string) string {
|
||||||
|
switch Type {
|
||||||
|
case "TV Series":
|
||||||
|
return "TV"
|
||||||
|
case "TV Special":
|
||||||
|
return "Special"
|
||||||
|
case "Web":
|
||||||
|
return "ONA"
|
||||||
|
}
|
||||||
|
return Type
|
||||||
|
}
|
||||||
|
|
||||||
|
//fixMeikanDates takes two strings and tries to parse them returning two Time structs
|
||||||
|
func FixMeikanDates(Date, Date2 string) (date, date2 time.Time) {
|
||||||
|
if Date != "" {
|
||||||
|
date, _ = time.Parse(`2006-01-02`, Date)
|
||||||
|
}
|
||||||
|
if Date2 != "" {
|
||||||
|
date2, _ = time.Parse(`2006-01-02`, Date)
|
||||||
|
}
|
||||||
|
return date, date2
|
||||||
|
}
|
||||||
|
|
||||||
|
//subAnimeDates subtracts one date from the other.
|
||||||
|
//Returning an integer that is added onto the total score when comparing.
|
||||||
|
func SubAnimeDates(Date, Date2 time.Time) (total int) {
|
||||||
|
if Date.Year() == 1 && Date2.Year() == 1 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
diff := Date.Sub(Date2)
|
||||||
|
if diff < 0 {
|
||||||
|
diff = diff * -1
|
||||||
|
}
|
||||||
|
if diff <= 2190*time.Hour {
|
||||||
|
return 50
|
||||||
|
}
|
||||||
|
return -150
|
||||||
|
}
|
||||||
|
|
||||||
|
//checkResults takes an Anime struct and a channel.
|
||||||
|
//It compares the supplied anime to all the search results returned from searching the title.
|
||||||
|
//If the score is over 100 it should be a match.
|
||||||
|
func CheckResults(anime Anime, c chan MatchedAnime) {
|
||||||
|
fmt.Println(`Searching anime`, anime.ID)
|
||||||
|
var highest, hI int
|
||||||
|
var err error
|
||||||
|
anime.Title = strings.Replace(strings.Replace(anime.Title, `\`, `\\`, -1), `"`, `\"`, -1)
|
||||||
|
var search = bytes.NewBuffer([]byte(`{"title":"` + anime.Title + `", "show_r18": true}`))
|
||||||
|
resp, err := http.Post("https://api.meikan.moe/v1/anime?incl=start_date,end_date", "application/json", search)
|
||||||
|
check(err)
|
||||||
|
fmt.Println(`Completed meikan search for`, anime.ID)
|
||||||
|
// nolint: errcheck
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var result Result
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
check(err)
|
||||||
|
_ = json.NewDecoder(bytes.NewReader(body)).Decode(&result)
|
||||||
|
anime.Type = FixType(anime.Type)
|
||||||
|
if anime.Episodes < 1 {
|
||||||
|
anime.Episodes = 1
|
||||||
|
}
|
||||||
|
for i := 0; i < len(result.Anime); i++ {
|
||||||
|
var total int
|
||||||
|
meikan := result.Anime[i]
|
||||||
|
stDate, enDate := FixMeikanDates(meikan.StartDate, meikan.EndDate)
|
||||||
|
if meikan.Type == anime.Type {
|
||||||
|
total += 25
|
||||||
|
} else {
|
||||||
|
MType := LessType(meikan.Type)
|
||||||
|
AType := LessType(anime.Type)
|
||||||
|
if MType == AType {
|
||||||
|
total += 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
score := levenshtein.Match(meikan.Title, anime.Title, nil)
|
||||||
|
if score > 0.95 {
|
||||||
|
total += 50
|
||||||
|
}
|
||||||
|
if meikan.Episodes == anime.Episodes {
|
||||||
|
total += 25
|
||||||
|
}
|
||||||
|
total += SubAnimeDates(stDate, anime.StartDate)
|
||||||
|
if anime.Episodes != 1 {
|
||||||
|
total += SubAnimeDates(enDate, anime.EndDate)
|
||||||
|
}
|
||||||
|
if total > highest {
|
||||||
|
highest = total
|
||||||
|
hI = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//return highest, hI
|
||||||
|
if len(result.Anime) != 0 {
|
||||||
|
c <- MatchedAnime{
|
||||||
|
MeikanTitle: result.Anime[hI].Title,
|
||||||
|
AnidbTitle: anime.Title,
|
||||||
|
MeikanID: result.Anime[hI].ID,
|
||||||
|
AnidbID: anime.ID,
|
||||||
|
Score: highest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
http.DefaultTransport = &http.Transport{MaxIdleConnsPerHost: 50, MaxIdleConns: 50}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user