chore: init monorepo

This commit is contained in:
2025-06-21 12:42:09 +03:00
commit 1874ae3ac1
103 changed files with 23946 additions and 0 deletions
@@ -0,0 +1,51 @@
package reaper
type Person struct {
FirstName string `xml:"first-name"`
MiddleName *string `xml:"middle-name"`
LastName *string `xml:"last-name"`
}
type Sequences struct {
Name *string `xml:"name,attr"`
Number *int `xml:"number,attr"`
}
type FB2Read struct {
Title string `xml:"title-info>book-title"`
Genres []string `xml:"title-info>genre"`
Authors []Person `xml:"title-info>author"`
Lang string `xml:"title-info>lang"`
SrcLang *string `xml:"title-info>src-lang"`
Translators *[]Person `xml:"title-info>translator"`
Sequence Sequences `xml:"title-info>sequence"`
Year *int `xml:"publish-info>year"`
ISBN *string `xml:"publish-info>isbn"`
Publisher *string `xml:"publish-info>publisher"`
Cover struct {
Id *string `xml:"href,attr"`
} `xml:"title-info>coverpage>image"`
Annotation struct {
Html string `xml:",innerxml"`
} `xml:"title-info>annotation"`
}
type FB2 struct {
SrcFile string
Bookcase *string
Title string
Genres []string
Authors []Person
HasCover bool
Lang string
SrcLang *string
Translators *[]Person
Sequence Sequences
Year *int
ISBN *string
Publisher *string
Annotation *string
SymbolsCount int
Size uint64
Hash *string
}
+150
View File
@@ -0,0 +1,150 @@
package reaper
import (
"encoding/xml"
"io"
"golang.org/x/net/html/charset"
"gorm.io/gorm"
)
func Parse(filereader io.Reader) *FB2Read {
// legacy, but normal algo
bookXML := new(FB2Read)
decoder := xml.NewDecoder(filereader)
decoder.CharsetReader = charset.NewReaderLabel
for t, _ := decoder.Token(); t != nil; t, _ = decoder.Token() {
if se, ok := t.(xml.StartElement); ok {
if se.Name.Local == "description" {
decoder.DecodeElement(&bookXML, &se)
break
}
}
}
if bookXML.Title == "" {
return nil
}
return bookXML
}
func RawToFB2(
reaped FB2Read,
filename string,
bookcase *string,
size uint64,
hash *string,
) FB2 {
return FB2{
SrcFile: filename,
Bookcase: bookcase,
Title: reaped.Title,
Genres: reaped.Genres,
Authors: reaped.Authors,
HasCover: reaped.Cover.Id != nil,
Lang: reaped.Lang,
SrcLang: reaped.SrcLang,
Translators: reaped.Translators,
Sequence: reaped.Sequence,
Year: reaped.Year,
ISBN: reaped.ISBN,
Publisher: reaped.Publisher,
Annotation: &reaped.Annotation.Html,
SymbolsCount: 0,
Size: size,
Hash: hash,
}
}
// omg legacy here ->
func nilCheck(nilString *string) string {
if nilString == nil {
return ""
}
return *nilString
}
func FB2toDB(tx *gorm.DB, book FB2) uint64 {
var genres *[]Genre
//book.Genres = nil
if book.Genres != nil {
var genresNN []Genre
for _, genre := range book.Genres {
genresNN = append(genresNN, Genre{
RawTag: genre,
})
}
genres = &genresNN
}
var authors []Author
for _, author := range book.Authors {
var dbAuthor Author
tx.FirstOrCreate(&dbAuthor, Author{
Key: author.FirstName + nilCheck(author.MiddleName) + nilCheck(author.LastName),
FirstName: author.FirstName,
MiddleName: author.MiddleName,
LastName: author.LastName,
})
authors = append(authors, dbAuthor)
}
var translators []Translator
if book.Translators != nil {
for _, translator := range *book.Translators {
var dbTranslator Translator
tx.FirstOrCreate(&dbTranslator, Translator{
Key: translator.FirstName + nilCheck(translator.MiddleName) + nilCheck(translator.LastName),
FirstName: translator.FirstName,
MiddleName: translator.MiddleName,
LastName: translator.LastName,
})
translators = append(translators, dbTranslator)
}
}
var sequence *Sequence
if book.Sequence.Name != nil {
sequence = &Sequence{
Name: *book.Sequence.Name,
}
}
var publisher *Publisher
if book.Publisher != nil {
publisher = &Publisher{
Name: *book.Publisher,
}
}
// var filetype schemas.Filetype
// tx.FirstOrCreate(&filetype, schemas.Filetype{
// Filetype: "fb2",
// Name: "FB2",
// })
//fmt.Println(book.Lang)
dbBook := Book{
Title: book.Title,
Authors: authors,
Language: Language{
Code: book.Lang,
},
Genre: genres,
Description: book.Annotation,
HasCover: book.HasCover,
SequenceID: sequence,
SequenceBook: book.Sequence.Number,
IsTranslated: book.Translators != nil,
Translators: &translators,
SrcLanguage: Language{
Code: book.Lang,
},
Year: book.Year,
Isbn: book.ISBN,
PublisherID: publisher,
SymbolsCount: &book.SymbolsCount,
Size: int(book.Size),
Hash: book.Hash,
Bookcase: book.Bookcase,
Filename: book.SrcFile,
Filetype: "fb2",
}
tx.Create(&dbBook)
return dbBook.ID
}
+122
View File
@@ -0,0 +1,122 @@
package reaper
import "time"
type Language struct {
ID uint `gorm:",unique;autoIncrement:true"`
Code string `gorm:"primaryKey;index:,unique"`
ISO *string
}
type Genre struct {
ID uint `gorm:",unique;autoIncrement:true"`
RawTag string `gorm:"index:,unique"`
Tag *string
Name *string
}
type Author struct {
ID uint `gorm:"primaryKey;index:,unique;autoIncrement:true"`
Key string `gorm:",unique"`
FirstName string
MiddleName *string
LastName *string
IsBanned *bool
BanReason *string
Books []Book `gorm:"many2many:BookAuthor"`
}
type User struct {
ID uint `gorm:"primaryKey"`
Username string `gorm:"autoIncrement:false;index:,unique"`
Avatar *string
Name *string
Admin bool
Lang *string
Language *Language `gorm:"foreignKey:Lang"`
LastSeen time.Time
Created time.Time
Password string
OTPToken *string
//Favorites []Book `gorm:"many2many:FavoriteBook;ForeignKey:username"`
BookShelf []ReaderBook
}
type Translator struct {
ID uint `gorm:"primaryKey;index:,unique;autoIncrement:true"`
Key string `gorm:",unique"`
FirstName string
MiddleName *string
LastName *string
}
type Sequence struct {
ID uint `gorm:",unique;autoIncrement:true"`
Name string `gorm:"primaryKey;index:,unique"`
}
type Publisher struct {
ID uint `gorm:",unique;autoIncrement:true"`
Name string `gorm:"primaryKey;index:,unique"`
}
type Book struct {
ID uint64 `gorm:"primaryKey"`
Title string
Authors []Author `gorm:"many2many:BookAuthor;References:ID"`
Lang *string
Language Language `gorm:"foreignKey:Lang"`
Genre *[]Genre `gorm:"many2many:BookGenre;References:RawTag"`
Description *string `gorm:"type:text"`
HasCover bool
IsTranslated bool
Translators *[]Translator `gorm:"many2many:BookTranslator;References:ID"`
SrcLang *string
SrcLanguage Language `gorm:"foreignKey:SrcLang"`
Sequence *string
SequenceID *Sequence `gorm:"foreignKey:Sequence"`
SequenceBook *int
Year *int
Publisher *string
PublisherID *Publisher `gorm:"foreignKey:Publisher"`
Isbn *string
Downloads int `gorm:"default:0"`
Views int `gorm:"default:0"`
SymbolsCount *int
PagesCount *int // pdf
Size int
Hash *string
Bookcase *string
Filename string
// FiletypeID uint
Filetype string
UploadedByID *uint
UploadedBy *User
UploadedAt *time.Time
Collections []Collection `gorm:"many2many:CollectionBook;"`
ExternalCover *string
}
// type Filetype struct {
// ID uint `gorm:"primaryKey"`
// Filetype string `gorm:"uniqueIndex"`
// Name string
// }
type ReaderBook struct {
ID uint `gorm:"primaryKey"`
UserID uint
BookID uint
Book Book `gorm:"foreignKey:BookID"`
Progress float64
LastRead time.Time
}
type Collection struct {
ID uint `gorm:"primaryKey"`
Link string `gorm:"uniqueIndex"`
Name string
UserID uint
Creator User `gorm:"foreignKey:UserID"`
Books []Book `gorm:"many2many:CollectionBook;"`
Created time.Time
Modified time.Time
}