xteve-project / xTeVe

M3U Proxy for Plex DVR and Emby Live TV
MIT License
1.87k stars 238 forks source link

New channels from IPTV provider reorder existing channel lineup. Requesting method to assign channel ranges to filters #235

Open ACiDGRiM opened 3 years ago

ACiDGRiM commented 3 years ago

Is your feature request related to a problem? Please describe. When ever channels are removed/changed by the IPTV provider, the lineup is changed and causes confusion when viewing the guide, such as in Plex. If News channels were channels 1000-1200 and the IPTV channels change, there will be documentary or drama channels among news channels

Describe the solution you'd like It would be very helpful to assign channel ranges to filters, so that channels that are a member of the "news" m3u group always are assigned to channels 1000-1200, Documentary to channels 2000-2400 etc...

Describe alternatives you've considered The current workaround is to delete my filters and recreate them so that channel types are contiguous.

Additional context This is particulary useful when re-freshing the mappings which sometimes don't automatically get associated with the epg data unless the m3u playlist is deleted and readded.

Rudder2 commented 3 years ago

I second this. I was going to open my own feature request but decided to read first and found this one. I couldn't of worded the problem better my self.

buroa commented 2 years ago

I made this script to sort channels, hope it helps you all :)

It does pretty much what you are saying... News is always in 1000... xyz. I then put all the deactivated channels at 10000 and below.


import collections
import time

# for xteve communication
from ws4py.client.threadedclient import WebSocketClient

# a fake websocket client
class Stupid(WebSocketClient):
    def opened(self):
        pass

    def closed(self, code, reason):
        print(("Closed", code, reason))

    def received_message(self, m):
        print(("Message", json.loads(m.data.decode('utf-8'))))

# grab the current xepg
xepg_dict = {}
with open('/root/.xteve/xepg.json','r', encoding='utf-8') as f:
  xepg_dict = json.load(f)

# list the categories
categories = {
    'REGIONAL LOCALS': 1000,
    'NETWORK TV': 2000,
    'PREMIUM MOVIE CHANNELS': 3000,
    'SPORTS NETWORKS': 4000,
    'NFL': 5000
}

inactive_channel_num = 10000
def sortChannelCategory(category):
    global xepg_dict
    global inactive_channel_num

    # issue the start of these channels
    start_channel_num = categories.get(category)
    current_channel_num = 0

    # sort the channel category by channel name
    channels = {k: v for k, v in xepg_dict.items() if xepg_dict[k].get('x-group-title') == category}
    channels = sorted(channels.items(), key=lambda x: x[1].get('name'))

    # for each channel
    for xepg_id, channel in channels:

        # set the new channel number
        active = channel.get('x-active')

        # add to the front
        if active:
            channel['x-channelID'] = str(start_channel_num + current_channel_num)
            current_channel_num = current_channel_num + 1
        else:
            channel['x-channelID'] = str(inactive_channel_num)
            inactive_channel_num = inactive_channel_num - 1

        # and now add it
        xepg_dict[xepg_id] = channel

for category in categories.keys():
    sortChannelCategory(category)

def save():
    ws = Stupid('ws://xteve/data/')
    ws.daemon = False
    ws.connect()
    data = {
        'epgMapping': xepg_dict,
        'cmd': 'saveEpgMapping',
    }
    ws.send(json.dumps(data))
    print('waiting...')
    ws.close()

save()
ACiDGRiM commented 2 years ago

@buroa

before I run this, can you give some info on how it determines the files?

hard coded config path to change: /root/.xteve/xepg.json

This is categories, but does it use the xteve filter name, or the "group title" from the playlist? categories = { 'REGIONAL LOCALS': 1000, 'NETWORK TV': 2000, 'PREMIUM MOVIE CHANNELS': 3000, 'SPORTS NETWORKS': 4000, 'NFL': 5000 }

Thank you for this, this is great once I understand more!

buroa commented 2 years ago

The categories are aligned with the group title inside the m3u playlist. I set the value to the starting channel number... basically any channel within 'REGIONAL LOCALS' will get assigned to 1000+ and sorted by the channel name. You also need to install this https://ws4py.readthedocs.io/en/latest/sources/install (pip install ws4py) ... it talks to the xTeVe websocket admin interface. Lastly, set this line ws = Stupid('ws://xteve/data/') to your endpoint... like ws://192.168.1.1:34400/data/. Once you run it, it will sort like so:

Active channels (that have EPG assigned):

Screen Shot 2022-02-04 at 4 32 55 PM

Deactivated channels get assigned 10000 and below:

Screen Shot 2022-02-04 at 4 33 05 PM
ACiDGRiM commented 2 years ago

Nice! Thank you, this suits the issue nicely.

Rudder2 commented 2 years ago

I run xTeVe from an auto updating docker. Is this implementable in this situation?

ACiDGRiM commented 2 years ago

@Rudder2 You would have to customize your docker container to run this as a cronjob and put this script where you can edit it outside of the container.

Rudder2 commented 1 year ago

I know it's been almost 2 years but I'm just starting to work on this. I'm running threw the errors and fixing them and I've gotten stuck. Google search brought me to a page and the code looks correct to me. Please help.

Error: root@d6306334178d:/config# ./Channel_Number_Update.sh Traceback (most recent call last): File "/config/./Channel_Number_Update.sh", line 22, in xepg_dict = json.load(f) NameError: name 'json' is not defined

The section in the script: # grab the current xepg xepg_dict = {} with open('/config/xepg.json', 'r', encoding='utf-8') as f: xepg_dict = json.load(f)

Thank you for any insight in advance.

Rudder2 commented 1 year ago

Never mind, After lots more searching I figured out the script was missing some things.

To whom ever might be trying this them selves.

set this line ws = Stupid('ws://xteve/data/') to your endpoint... like ws://192.168.1.1:34400/data/

Problem 1: Figure out how to install discrepancies in a docker container, my container had apt in it so that was easy Install all dependencies: 'apt install pip' 'apt install git' 'git clone git@github.com:Lawouach/WebSocket-for-Python.git' 'pip install ws4py'

Problem 2: Add to top of script: #!/usr/bin/env python3

Problem 3: Add after import time: import json

Problem 4: Categories are case sensitive!

Problem 5: The cron calls can be performed from the host computer with command: docker exec [docker container name] '/config/[name of script].sh'

It works with my xTeVe Docker!! Now, I just have to figure out how to make my discrepancies stick across updates.

Thank you so much @buroa for your work on this script! It is EXACTLY what I needed!

buroa commented 1 year ago

Thank you so much @buroa for your work on this script! It is EXACTLY what I needed!

Glad you figured it out & thank you for providing examples for others to follow! Sorry for the later reply, was quite busy today :-)