]> Sergey Matveev's repositories - meta4ra.git/blobdiff - cmd/meta4-create/main.go
meta4-check
[meta4ra.git] / cmd / meta4-create / main.go
index 2289e8a26f4216e47f79441e7efeea8669887cf1..f11fa70754b1f7be6c0ee19ee92909fc4519318b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-meta4a -- Metalink 4.0 utility
+meta4a -- Metalink 4.0 creator
 Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
@@ -15,10 +15,11 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-// Metalink 4.0 utility
+// Metalink 4.0 creator
 package main
 
 import (
+       "bufio"
        "crypto/sha256"
        "crypto/sha512"
        "encoding/hex"
@@ -30,64 +31,21 @@ import (
        "os"
        "path/filepath"
        "time"
-)
 
-const (
-       Generator       = "meta4ra/0.1.0"
-       GPGSigMediaType = "application/pgp-signature"
+       "go.stargrave.org/meta4ra"
 )
 
-type Metalink struct {
-       XMLName   xml.Name  `xml:"urn:ietf:params:xml:ns:metalink metalink"`
-       Files     []File    `xml:"file"`
-       Generator string    `xml:"generator,,omitempty"`
-       Published time.Time `xml:"published,,omitempty"`
-}
-
-type File struct {
-       XMLName     xml.Name   `xml:"file"`
-       Name        string     `xml:"name,attr"`
-       Description string     `xml:"description,,omitempty"`
-       Hashes      []Hash     `xml:"hash,,omitempty"`
-       MetaURLs    []MetaURL  `xml:"metaurl,,omitempty"`
-       Signature   *Signature `xml:"signature"`
-       Size        uint64     `xml:"size,,omitempty"`
-       URLs        []URL      `xml:"url,,omitempty"`
-}
-
-type URL struct {
-       XMLName xml.Name `xml:"url"`
-       URL     string   `xml:",chardata"`
-}
-
-type Signature struct {
-       XMLName   xml.Name `xml:"signature"`
-       MediaType string   `xml:"mediatype,attr"`
-       Signature string   `xml:",cdata"`
-}
-
-type Hash struct {
-       XMLName xml.Name `xml:"hash"`
-       Type    string   `xml:"type,attr"`
-       Hash    string   `xml:",chardata"`
-}
-
-type MetaURL struct {
-       XMLName   xml.Name `xml:"metaurl"`
-       MediaType string   `xml:"mediatype,attr"`
-       URL       string   `xml:",chardata"`
-}
-
 func main() {
        file := flag.String("file", "", "Path to file")
+       mtime := flag.String("mtime", "", "Take that file's mtime as a Published date")
        desc := flag.String("desc", "", "Description")
        sig := flag.String("sig", "", "Path to signature file")
        torrent := flag.String("torrent", "", "Torrent URL")
        log.SetFlags(log.Lshortfile)
        flag.Parse()
-       urls := make([]URL, 0, len(flag.Args()))
+       urls := make([]meta4ra.URL, 0, len(flag.Args()))
        for _, u := range flag.Args() {
-               urls = append(urls, URL{URL: u})
+               urls = append(urls, meta4ra.URL{URL: u})
        }
        fd, err := os.Open(*file)
        if err != nil {
@@ -99,18 +57,21 @@ func main() {
        }
        sha256Hasher := sha256.New()
        sha512Hasher := sha512.New()
-       _, err = io.Copy(io.MultiWriter(sha256Hasher, sha512Hasher), fd)
+       _, err = io.Copy(
+               io.MultiWriter(sha256Hasher, sha512Hasher),
+               bufio.NewReader(fd),
+       )
        if err != nil {
                log.Fatalln(err)
        }
-       f := File{
+       f := meta4ra.File{
                Name:        filepath.Base(*file),
                Description: *desc,
                Size:        uint64(fi.Size()),
                URLs:        urls,
-               Hashes: []Hash{
-                       {Type: "sha-256", Hash: hex.EncodeToString(sha256Hasher.Sum(nil))},
-                       {Type: "sha-512", Hash: hex.EncodeToString(sha512Hasher.Sum(nil))},
+               Hashes: []meta4ra.Hash{
+                       {Type: meta4ra.HashSHA256, Hash: hex.EncodeToString(sha256Hasher.Sum(nil))},
+                       {Type: meta4ra.HashSHA512, Hash: hex.EncodeToString(sha512Hasher.Sum(nil))},
                },
        }
        if *sig != "" {
@@ -118,18 +79,29 @@ func main() {
                if err != nil {
                        log.Fatalln(err)
                }
-               f.Signature = &Signature{
-                       MediaType: GPGSigMediaType,
+               f.Signature = &meta4ra.Signature{
+                       MediaType: meta4ra.GPGSigMediaType,
                        Signature: "\n" + string(sigData),
                }
        }
        if *torrent != "" {
-               f.MetaURLs = []MetaURL{{MediaType: "torrent", URL: *torrent}}
+               f.MetaURLs = []meta4ra.MetaURL{{MediaType: "torrent", URL: *torrent}}
+       }
+       var published time.Time
+       if *mtime == "" {
+               published = time.Now()
+       } else {
+               fi, err := os.Stat(*mtime)
+               if err != nil {
+                       log.Fatalln(err)
+               }
+               published = fi.ModTime()
        }
-       m := Metalink{
-               Files:     []File{f},
-               Generator: Generator,
-               Published: time.Now().UTC().Truncate(time.Second),
+       published = published.UTC().Truncate(time.Second)
+       m := meta4ra.Metalink{
+               Files:     []meta4ra.File{f},
+               Generator: meta4ra.Generator,
+               Published: published,
        }
        out, err := xml.MarshalIndent(&m, "", "  ")
        if err != nil {