1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00

147 lines
3.1 KiB
Go
Raw Normal View History

2017-08-13 17:12:35 -07:00
package feeds
2017-08-13 14:50:59 -07:00
import (
"net/url"
"strings"
2017-08-19 16:58:23 -07:00
"github.com/mxpv/podsync/pkg/api"
2017-11-03 16:04:33 -07:00
"github.com/mxpv/podsync/pkg/model"
2017-08-13 14:50:59 -07:00
"github.com/pkg/errors"
)
2017-11-03 16:04:33 -07:00
func parseURL(link string) (*model.Feed, error) {
2017-08-13 19:28:43 -07:00
if !strings.HasPrefix(link, "http") {
link = "https://" + link
}
2017-08-13 14:50:59 -07:00
parsed, err := url.Parse(link)
if err != nil {
err = errors.Wrapf(err, "failed to parse url: %s", link)
return nil, err
}
2017-11-03 16:04:33 -07:00
feed := &model.Feed{}
2017-08-13 14:50:59 -07:00
if strings.HasSuffix(parsed.Host, "youtube.com") {
kind, id, err := parseYoutubeURL(parsed)
if err != nil {
return nil, err
}
2017-11-03 15:04:33 -07:00
feed.Provider = api.ProviderYoutube
2017-08-13 14:50:59 -07:00
feed.LinkType = kind
2017-11-03 16:04:33 -07:00
feed.ItemID = id
2017-08-13 14:50:59 -07:00
return feed, nil
}
if strings.HasSuffix(parsed.Host, "vimeo.com") {
kind, id, err := parseVimeoURL(parsed)
if err != nil {
return nil, err
}
2017-11-03 15:04:33 -07:00
feed.Provider = api.ProviderVimeo
2017-08-13 14:50:59 -07:00
feed.LinkType = kind
2017-11-03 16:04:33 -07:00
feed.ItemID = id
2017-08-13 14:50:59 -07:00
return feed, nil
}
return nil, errors.New("unsupported URL host")
}
2019-01-07 20:47:59 -08:00
func parseYoutubeURL(parsed *url.URL) (api.LinkType, string, error) {
2017-08-13 14:50:59 -07:00
path := parsed.EscapedPath()
// https://www.youtube.com/playlist?list=PLCB9F975ECF01953C
// https://www.youtube.com/watch?v=rbCbho7aLYw&list=PLMpEfaKcGjpWEgNtdnsvLX6LzQL0UC0EM
if strings.HasPrefix(path, "/playlist") || strings.HasPrefix(path, "/watch") {
2019-01-07 20:47:59 -08:00
kind := api.LinkTypePlaylist
2017-08-13 14:50:59 -07:00
2019-01-07 20:47:59 -08:00
id := parsed.Query().Get("list")
2017-08-13 14:50:59 -07:00
if id != "" {
2019-01-07 20:47:59 -08:00
return kind, id, nil
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid playlist link")
2017-08-13 14:50:59 -07:00
}
// - https://www.youtube.com/channel/UC5XPnUk8Vvv_pWslhwom6Og
// - https://www.youtube.com/channel/UCrlakW-ewUT8sOod6Wmzyow/videos
if strings.HasPrefix(path, "/channel") {
2019-01-07 20:47:59 -08:00
kind := api.LinkTypeChannel
2017-08-13 14:50:59 -07:00
parts := strings.Split(parsed.EscapedPath(), "/")
if len(parts) <= 2 {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid youtube channel link")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
id := parts[2]
2017-08-13 14:50:59 -07:00
if id == "" {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid id")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return kind, id, nil
2017-08-13 14:50:59 -07:00
}
// - https://www.youtube.com/user/fxigr1
if strings.HasPrefix(path, "/user") {
2019-01-07 20:47:59 -08:00
kind := api.LinkTypeUser
2017-08-13 14:50:59 -07:00
parts := strings.Split(parsed.EscapedPath(), "/")
if len(parts) <= 2 {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid user link")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
id := parts[2]
2017-08-13 14:50:59 -07:00
if id == "" {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid id")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return kind, id, nil
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return "", "", errors.New("unsupported link format")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
func parseVimeoURL(parsed *url.URL) (api.LinkType, string, error) {
2017-08-13 14:50:59 -07:00
parts := strings.Split(parsed.EscapedPath(), "/")
if len(parts) <= 1 {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid vimeo link path")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
var kind api.LinkType
switch parts[1] {
case "groups":
2017-11-03 15:04:33 -07:00
kind = api.LinkTypeGroup
2019-01-07 20:47:59 -08:00
case "channels":
2017-11-03 15:04:33 -07:00
kind = api.LinkTypeChannel
2019-01-07 20:47:59 -08:00
default:
2017-11-03 15:04:33 -07:00
kind = api.LinkTypeUser
2017-08-13 14:50:59 -07:00
}
2017-11-03 15:04:33 -07:00
if kind == api.LinkTypeGroup || kind == api.LinkTypeChannel {
2017-08-13 14:50:59 -07:00
if len(parts) <= 2 {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid channel link")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
id := parts[2]
2017-08-13 14:50:59 -07:00
if id == "" {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid id")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return kind, id, nil
2017-08-13 14:50:59 -07:00
}
2017-11-03 15:04:33 -07:00
if kind == api.LinkTypeUser {
2019-01-07 20:47:59 -08:00
id := parts[1]
2017-08-13 14:50:59 -07:00
if id == "" {
2019-01-07 20:47:59 -08:00
return "", "", errors.New("invalid id")
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return kind, id, nil
2017-08-13 14:50:59 -07:00
}
2019-01-07 20:47:59 -08:00
return "", "", errors.New("unsupported link format")
2017-08-13 14:50:59 -07:00
}