Resolves MediaFire share IDs into direct links.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 

98 lines
2.2 KiB

package main
import (
"errors"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/PuerkitoBio/goquery"
)
var shareRe = regexp.MustCompile(`^[a-z0-9]+$`)
func getDirectLink(shareID string) (string, error) {
if !shareRe.MatchString(shareID) {
return "", errNoSuchShare.Errorf("invalid share id")
}
req, err := http.NewRequest("GET", fmt.Sprintf("https://www.mediafire.com/file/%s", shareID), nil)
if err != nil {
return "", err
}
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
break
case http.StatusNotFound:
return "", errNoSuchShare
default:
return "", errUnknownMediaFireError.Errorf("unexpected status %s", resp.Status)
}
u := resp.Request.URL.String()
switch {
case strings.HasPrefix(resp.Request.URL.Path, req.URL.Path):
break
case strings.Contains(u, "download_status.php"):
return "", errFileStillUploading
case strings.Contains(u, "error.php"):
return "", errUnknownMediaFireError.Errorf("%s", u)
default:
return "", errUnknownMediaFireError.Errorf("unexpected redirect to %s", u)
}
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return "", err
}
sel := doc.Find("#download_link a[aria-label='Download file'][href]").First()
if sel.Length() < 1 {
return "", fmt.Errorf("could not parse download page link")
}
return sel.AttrOr("href", ""), nil
}
type errMessage string
const (
errUnknownMediaFireError errMessage = "unknown mediafire error"
errNoSuchShare errMessage = "no such share"
errFileStillUploading errMessage = "file still uploading"
)
func (e errMessage) Errorf(format string, a ...interface{}) error {
if len(format) > 0 {
return fmt.Errorf("%s: %s", e, fmt.Sprintf(format, a...))
}
return errors.New(string(e))
}
func (e errMessage) Wrap(err error) error {
if err != nil {
return e.Errorf("%s", err.Error())
}
return nil
}
func (e errMessage) Error() string {
return string(e)
}
func (e errMessage) Is(err error) bool {
if err != nil {
return strings.HasPrefix(err.Error(), string(e))
}
return false
}