Skip to content

Commit

Permalink
Merge pull request #177 from rabilrbl/feat/web-epg
Browse files Browse the repository at this point in the history
feat: Web EPG support and minor optimizations

Add new poster route for epg episode posters

optimize constants
  • Loading branch information
rabilrbl authored Nov 30, 2023
2 parents 6d4ce7f + 41d64b3 commit 62f3238
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ web/node_modules/

# Logs
jiotv_go.log
jiotv_go*.log

# EPG
epg.xml.gz
2 changes: 2 additions & 0 deletions cmd/jiotv_go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ func main() {
app.Get("/favicon.ico", handlers.FaviconHandler)
app.Get("/jtvimage/:file", handlers.ImageHandler)
app.Get("/epg.xml.gz", handlers.EPGHandler)
app.Get("/epg/:channelID/:offset", handlers.WebEPGHandler)
app.Get("/jtvposter/:date/:file", handlers.PosterHandler)

addr := "localhost:5001"

Expand Down
50 changes: 50 additions & 0 deletions internal/handlers/epg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package handlers

import (
"fmt"
"strconv"

"github.com/rabilrbl/jiotv_go/v2/pkg/epg"

"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/proxy"
)

const (
EPG_POSTER_URL = "https://jiotv.catchup.cdn.jio.com/dare_images/shows/"
)

// WebEPGHandler responds to requests for EPG data for individual channels.
func WebEPGHandler(c *fiber.Ctx) error {
// Get channel ID from URL
channelID, err := strconv.Atoi(c.Params("channelID"))
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid channel ID")
}

// Get offset from URL
offset, err := strconv.Atoi(c.Params("offset"))
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid offset")
}

url := fmt.Sprintf(epg.EPG_URL, offset, channelID)
if err := proxy.Do(c, url, TV.Client); err != nil {
return err
}

c.Response().Header.Del(fiber.HeaderServer)
return nil
}

// PosterHandler loads image from JioTV server
func PosterHandler(c *fiber.Ctx) error {
// catch all params
fmt.Println(c.Params("*"))
url := EPG_POSTER_URL + c.Params("date") + "/" + c.Params("file")
if err := proxy.Do(c, url, TV.Client); err != nil {
return err
}
c.Response().Header.Del(fiber.HeaderServer)
return nil
}
7 changes: 6 additions & 1 deletion internal/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ var (
Title string
)

const (
REFRESH_TOKEN_URL = "https://auth.media.jio.com/tokenservice/apis/v1/refreshtoken?langId=6"

)

// Init initializes the necessary operations required for the handlers to work.
func Init() {
DisableTSHandler = os.Getenv("JIOTV_DISABLE_TS_HANDLER") == "true"
Expand Down Expand Up @@ -558,7 +563,7 @@ func LoginRefreshAccessToken() error {

// Prepare the request
req := fasthttp.AcquireRequest()
req.SetRequestURI("https://auth.media.jio.com/tokenservice/apis/v1/refreshtoken?langId=6")
req.SetRequestURI(REFRESH_TOKEN_URL)
req.Header.SetMethod("POST")
req.Header.Set("devicetype", "phone")
req.Header.Set("versionCode", "315")
Expand Down
2 changes: 1 addition & 1 deletion pkg/epg/epg.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func Init() {

// NewProgramme creates a new Programme with the given parameters.
func NewProgramme(channelID int, start, stop, title, desc, iconSrc string) Programme {
iconURL := fmt.Sprintf("https://jiotv.catchup.cdn.jio.com/dare_images/shows/%s", iconSrc)
iconURL := fmt.Sprintf("/jtvposter/%s", iconSrc)
return Programme{
Channel: fmt.Sprint(channelID),
Start: start,
Expand Down
113 changes: 113 additions & 0 deletions web/static/epg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
function getCurrentAndNextTwoShows(epgData) {
const currentTime = new Date(); // Current date time
const shows = [];
let currentIndex = -1;

// Find the currently playing show
epgData.epg.some((show, index) => {
const showStartTime = new Date(show.startEpoch);
const showEndTime = new Date(show.endEpoch);

if (showStartTime <= currentTime && currentTime < showEndTime) {
const { showname, description, endEpoch, episodePoster, keywords } = show;
shows.push({ showname, description, endEpoch, episodePoster, keywords });
currentIndex = index;
return true; // Stop iterating after finding the current show
}
return false;
});

// Get the next two shows
if (currentIndex !== -1) {
const nextTwoShows = epgData.epg.slice(currentIndex + 1, currentIndex + 3);
nextTwoShows.forEach(show => {
const { showname, description, endEpoch, episodePoster, keywords } = show;
shows.push({ showname, description, endEpoch, episodePoster, keywords });
});
}

return shows;
}

const url = new URL(window.location.href);
// do regex to get channelID
const channelID = url.pathname.match(/\/play\/(.*)/)[1];
const offset = 0;


function updateEPG(epgData) {
const shows = getCurrentAndNextTwoShows(epgData);
const shownameElement = document.getElementById('showname');
const descriptionElement = document.getElementById('description');
const episodePosterElement = document.getElementById('episodePoster');
shownameElement.innerHTML = shows[0].showname + shownameElement.innerHTML;
descriptionElement.innerText = shows[0].description;
const posterUrl = new URL("/jtvposter/", window.location.href);
posterUrl.pathname += shows[0].episodePoster;
episodePosterElement.src = posterUrl.href;

const keywordsElement = document.getElementById('keywords');
const keywords = shows[0].keywords;
keywords.forEach((keyword) => {
const keywordElement = document.createElement('div');
keywordElement.className = 'badge badge-outline';
keywordElement.innerText = keyword;
keywordsElement.appendChild(keywordElement);
});

const e_hour = document.getElementById('e_hour');
const e_minute = document.getElementById('e_minute');
const e_second = document.getElementById('e_second');

const endEpochTime = shows[0].endEpoch;
function updateTimer() {
const currentTime = new Date().getTime();
const difference = endEpochTime - currentTime;

if (difference <= 0) {
clearInterval(timerInterval);
updateEPG();
return;
}

const differenceDate = new Date(difference);
const hours = differenceDate.getUTCHours();
const minutes = differenceDate.getUTCMinutes();
const seconds = differenceDate.getUTCSeconds();


if (hours === 0) {
document.getElementById('countdown_hour').style.display = 'none';
} else {
e_hour.setAttribute('style', `--value:${hours.toString().padStart(2, '0')};`);
}
if (hours === 0 && minutes === 0) {
document.getElementById('countdown_minute').style.display = 'none';
} else {
e_minute.setAttribute('style', `--value:${minutes.toString().padStart(2, '0')};`);
}
e_second.setAttribute('style', `--value:${seconds.toString().padStart(2, '0')};`);
}

// Initial call to update the timer
updateTimer();

// Set the interval to update the timer every second
const timerInterval = setInterval(updateTimer, 1000);
}

const epgParent = document.getElementById('epg_parent');
epgParent.style.display = 'none';

(async () => {
const epgResponse = await fetch(`/epg/${channelID}/${offset}`);

if (!epgResponse.ok) {
console.error('Failed to fetch EPG data');
return;
}

const epgData = await epgResponse.json();
epgParent.style.display = 'block';
updateEPG(epgData);
})();
2 changes: 1 addition & 1 deletion web/static/tailwind.css

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions web/views/play.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,38 @@
></iframe>
</div>
</div>
<div id="epg_parent" class="p-1 sm:p-2 md:p-4 md:mx-8 lg:p-8 lg:mx-52">
<h2 class="mt-4 sm:mt-0 mb-2 text-lg sm:text-xl font-bold text-center sm:text-left">Now Playing</h2>
<div id="epg" class="w-full">
<div class="card w-full sm:w-96 bg-base-200 shadow-xl">
<figure><img id="episodePoster" alt="Episode Poster" /></figure>
<div class="card-body">
<h2 id="showname" class="card-title">
</h2>
<div class="flex flex-row gap-2 items-center justify-between">
<div class="badge badge-error badge-outline">Live</div>
<div>
<span>Ends in </span>
<span id="countdown_hour" class="countdown">
<span id="e_hour" style="--value:0;"></span>h
</span>
<span id="countdown_minute" class="countdown">
<span id="e_minute" style="--value:0;"></span>m
</span>
<span id="countdown_second" class="countdown">
<span id="e_second" style="--value:0;"></span>s
</span>
</div>
</div>
<p id="description"></p>
<div id="keywords" class="card-actions justify-end">
<div class="hidden badge badge-outline"></div>
</div>
</div>
</div>
</div>
</div>
<script src="/static/common.js"></script>
<script src="/static/epg.js"></script>
</body>
</html>

0 comments on commit 62f3238

Please sign in to comment.