/* * Iptv-Proxy is a project to proxyfie an m3u file and to proxyfie an Xtream iptv service (client API). * Copyright (C) 2020 Pierre-Emmanuel Jacquier * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package xtreamproxy import ( "context" "fmt" "net/http" "net/url" "strconv" "github.com/pierre-emmanuelJ/iptv-proxy/pkg/config" xtream "github.com/tellytv/go.xtream-codes" ) const ( getLiveCategories = "get_live_categories" getLiveStreams = "get_live_streams" getVodCategories = "get_vod_categories" getVodStreams = "get_vod_streams" getVodInfo = "get_vod_info" getSeriesCategories = "get_series_categories" getSeries = "get_series" getSerieInfo = "get_series_info" getShortEPG = "get_short_epg" getSimpleDataTable = "get_simple_data_table" ) // Client represent an xtream client type Client struct { *xtream.XtreamClient } // New new xtream client func New(user, password, baseURL, userAgent string) (*Client, error) { cli, err := xtream.NewClientWithUserAgent(context.Background(), user, password, baseURL, userAgent) if err != nil { return nil, err } return &Client{cli}, nil } type login struct { UserInfo xtream.UserInfo `json:"user_info"` ServerInfo xtream.ServerInfo `json:"server_info"` } // Login xtream login func (c *Client) login(proxyUser, proxyPassword, proxyURL string, proxyPort int, protocol string) (login, error) { req := login{ UserInfo: xtream.UserInfo{ Username: proxyUser, Password: proxyPassword, Message: c.UserInfo.Message, Auth: c.UserInfo.Auth, Status: c.UserInfo.Status, ExpDate: c.UserInfo.ExpDate, IsTrial: c.UserInfo.IsTrial, ActiveConnections: c.UserInfo.ActiveConnections, CreatedAt: c.UserInfo.CreatedAt, MaxConnections: c.UserInfo.MaxConnections, AllowedOutputFormats: c.UserInfo.AllowedOutputFormats, }, ServerInfo: xtream.ServerInfo{ URL: proxyURL, Port: proxyPort, HTTPSPort: proxyPort, Protocol: protocol, RTMPPort: proxyPort, Timezone: c.ServerInfo.Timezone, TimestampNow: c.ServerInfo.TimestampNow, TimeNow: c.ServerInfo.TimeNow, }, } return req, nil } // Action execute an xtream action. func (c *Client) Action(config *config.ProxyConfig, action string, q url.Values) (respBody interface{}, httpcode int, err error) { protocol := "http" if config.HTTPS { protocol = "https" } switch action { case getLiveCategories: respBody, err = c.GetLiveCategories() case getLiveStreams: respBody, err = c.GetLiveStreams("") case getVodCategories: respBody, err = c.GetVideoOnDemandCategories() case getVodStreams: respBody, err = c.GetVideoOnDemandStreams("") case getVodInfo: if len(q["vod_id"]) < 1 { err = fmt.Errorf(`bad body url query parameters: missing "vod_id"`) httpcode = http.StatusBadRequest return } respBody, err = c.GetVideoOnDemandInfo(q["vod_id"][0]) case getSeriesCategories: respBody, err = c.GetSeriesCategories() case getSeries: respBody, err = c.GetSeries("") case getSerieInfo: if len(q["series_id"]) < 1 { err = fmt.Errorf(`bad body url query parameters: missing "series_id"`) httpcode = http.StatusBadRequest return } respBody, err = c.GetSeriesInfo(q["series_id"][0]) case getShortEPG: if len(q["stream_id"]) < 1 { err = fmt.Errorf(`bad body url query parameters: missing "stream_id"`) httpcode = http.StatusBadRequest return } limit := 0 if len(q["limit"]) > 0 { limit, err = strconv.Atoi(q["limit"][0]) if err != nil { httpcode = http.StatusInternalServerError return } } respBody, err = c.GetShortEPG(q["stream_id"][0], limit) case getSimpleDataTable: if len(q["stream_id"]) < 1 { err = fmt.Errorf(`bad body url query parameters: missing "stream_id"`) httpcode = http.StatusBadRequest return } respBody, err = c.GetEPG(q["stream_id"][0]) default: respBody, err = c.login(config.User.String(), config.Password.String(), protocol+"://"+config.HostConfig.Hostname, config.AdvertisedPort, protocol) } return }