Ticket #9534: mythchannel_sync

File mythchannel_sync, 7.4 KB (added by ligverd@…, 15 years ago)
Line 
1#!/usr/bin/perl
2
3#
4# Upgrade database mysql for internal playlist sorage and dynamic update
5# 1. expanding field that is not used for iptv - SQL:alter table channel MODIFY freqid varchar(255);
6# 2. Add a new option (flag) to the table settings - SQL:insert into settings (value,data) VALUES('iptv_playlist_change','1');
7# 3. Choose the type of card - FREEBOX (Network Recorder) in the M3U URL prescribes intrenal:KEYWORD
8# option says that the internal library to take out the base, KEYWORD can be of any, this is usually the provider name
9# it must coincide with the set variable $ IPTV_SOURCE in mythchannel_sync
10#
11# ðÏÄÇÏÔÏ×ËÁ ÂÁÚÙ mysql ÄÌÑ ×ÎÕÔÒÅÎÎÅÇÏ ÈÒÁÎÅÎÉÑ ÐÌÅÊÌÉÓÔÁ É ÄÉÎÁÍÉÞÅÓËÏÇÏ ÏÂÎÏ×ÌÅÎÉÑ
12# 1. ÒÁÓÛÉÒÑÅÍ ÐÏÌÅ ËÏÔÏÒÏÅ ÎÅ ÉÓÐÏÌØÚØÕÅÔÓÑ × iptv - SQL:alter table channel MODIFY freqid varchar(255);
13# 2. äÏÂÁ×ÌÑÅÍ ÎÏ×ÕÀ ÏÐÃÉÀ (ÆÌÁÇ) × ÔÁÂÌÉÃÕ settings - SQL:insert into settings (value,data) VALUES('iptv_playlist_change','1');
14# 3. ÷ÙÂÉÒÁÅÍ ÔÉÐ ËÁÒÔÙ - FREEBOX (óÅÔÅ×ÏÊ ÒÅËÏÒÄÅÒ) × ÐÏÌÅ M3U URL ÐÒÏÐÉÓÙ×ÁÅÍ intrenal:KEYWORD
15# ÏÐÃÉÑ internal ÇÏ×ÏÒÉÔ ÞÔÏ ÐÌÅÊÌÉÓÔ ÂÒÁÔØ ÉÚ ÂÁÚÙ, KEYWORD ÍÏÖÅÔ ÂÙÔØ ÌÀÂÙÍ ÜÔÏ ÉÍÑ ÐÒÏ×ÁÊÄÅÒÁ ÏÎÏ ÄÏÌÖÎÏ ÓÏ×ÐÁÄÁÔØ
16# Ó ÕÓÔÁÎÏ×ÌÅÎÎÏÊ ÐÅÒÅÍÅÎÎÏÊ $IPTV_SOURCE × mythchannel_sync
17
18# Run this script periodically
19
20#
21# Playlist format:
22# csv
23# CHID\tCHNOMER\tXMLTVID\tURLICON\tCHNAME\tCHURL\n
24# ...
25
26# examlpe
27# 123\t1\t345\thttp://serv.com/image/img.gif\tSuper Channel\tudp://230.0.0.1:1234\n
28
29# PS You can easily modify
30
31use Socket;
32use DBI;
33use Encode;
34use encoding "utf8";
35
36$DEBUG=1;
37#######################################################
38$IPTV_SOURCE="myiptvisp";
39$PLAYLIST_URL="http://serv.com/playlist.php";
40#######################################################
41$DB_HOST="localhost";
42$DB_PORT="0";
43$DB_NAME="mythtv";
44$DB_USER="user";
45$DB_PASS="pass";
46$HOME_DIR="/home/localuser"; # dir .mythtv/channels
47#######################################################
48
49
50# ÚÁÂÉÒÁÅÍ playlist
51($type,$file,$buf)=http_get($PLAYLIST_URL);
52@chlist=split(/\n/,$buf);
53unless ($chlist[0] =~ /^csv/i) { exit; }
54
55
56# ÆÏÒÍÉÒÕÅÍ ÐÌÅÊÌÉÓÔ É ÚÁËÁÞÉ×ÁÅÍ ÏÔÓÕÔÓÔ×ÕÀÝÉÅ ÉËÏÎËÉ
57foreach $ch (@chlist)
58{
59 $ch=~s/[\r\n]//g;
60 $type='';
61 ($chid,$chno,$tvpid,$icon,$name,$url)=split(/\t/,$ch);
62
63 if ($url eq "") { next; }
64
65 if ($icon ne '')
66 {
67 ($a1,$a2,$a3,$file)=parse_url($icon);
68 $full_icon="$HOME_DIR/.mythtv/channels/$file";
69 unless (-e $full_icon)
70 {
71 ($type,$file,$buf)=http_get($icon);
72 }
73
74 if ($type=~/image/i)
75 {
76 open(F,">",$full_icon);
77 print F $buf;
78 close F;
79 }
80 #$icon=$file; # mythtv ÓÁÍ ÚÎÁÅÔ × ËÁËÏÊ ÄÉÒÅËÔÏÒÉÉ ÌÅÖÁÔ ÉËÏÎËÉ
81 $icon=$full_icon; # ÌÕÞÛÅ ÕËÁÚÁÔØ ÐÏÌÎÙÊ ÐÕÔØ ÎÅËÏÔÏÒÙÅ ÜÌÅÍÅÎÔÙ ÎÅ ×ÉÄÑÔ ÉËÏÎËÉ
82 }
83
84 $CHLIST_NEW{$chid}->{'chno'}=$chno;
85 $CHLIST_NEW{$chid}->{'tvpid'}=$tvpid;
86 $CHLIST_NEW{$chid}->{'icon'}=$icon;
87 $CHLIST_NEW{$chid}->{'name'}=$name;
88 $CHLIST_NEW{$chid}->{'url'}=$url;
89}
90
91# æÌÁÇ ÉÚÍÅÎÅÎÉÑ
92$DB_CHANGE=0;
93
94# ÐÏÄËÌÀÞÁÅÍÓÑ Ë âä
95my $dbh = DBI->connect("DBI:mysql:database=$DB_NAME;host=$DB_HOST",$DB_USER,$DB_PASS,{'RaiseError' => 0}) or die "Can`t connect to MySQL!\n";
96
97# ÕÓÔÁÎÁ×ÌÉ×ÁÅÍ ËÏÄÉÒÏ×ËÕ
98$dbh->{'mysql_enable_utf8'} = 1;
99$dbh->do("set character set utf8");
100$dbh->do("SET NAMES 'utf8'");
101
102# ÕÚÎÁÅÍ id ×ÉÄÅÏÉÓÔÏÞÎÉËÁ
103$hl=$dbh->prepare("SELECT i.sourceid FROM capturecard AS c,cardinput AS i WHERE c.cardtype='FREEBOX' AND c.videodevice='internal:$IPTV_SOURCE' AND c.cardid=i.cardid GROUP BY 1");
104$hl->execute();
105($SOURCE_ID)=$hl->fetchrow_array();
106$hl->finish();
107
108if ($SOURCE_ID eq "") { die "Can`t find cardtype: FREEBOX and/or videodevice(M3U URL): internal:$IPTV_SOURCE \n"; }
109
110print "Select sourceid: $SOURCE_ID\n";
111
112
113$CH_DELETE=0;
114$CH_UPDATE=0;
115$CH_INSERT=0;
116
117
118# ×Ù×ÏÄÉÍ ×ÓÅ ËÁÎÁÌÙ ÄÌÑ ÜÔÏÇÏ ×ÉÄÅÏ ÉÓÔÏÞÎÉËÁ
119$hl=$dbh->prepare("SELECT chanid,channum,freqid,callsign,name,icon,xmltvid,visible FROM channel WHERE sourceid='$SOURCE_ID'") or die "Can`t select 1\n";
120$hl->execute();
121do {
122while ( ($id,$chno,$url,$chid,$name,$icon,$tvpid,$visible)=$hl->fetchrow_array() )
123{
124# print "$id $name $icon\n";
125
126 # ËÁÎÁÌ ÂÙÌ ÕÄÁÌÅÎ
127 if ( !defined($CHLIST_NEW{$chid}) )
128 {
129 $dbh->do("DELETE FROM channel WHERE callsign='$chid'");
130 $CH_DELETE++;
131 $DB_CHANGE=1;
132print "- $url $name\n" if ($DEBUG);
133 next;
134 }
135
136 # ËÁÎÁÌ ÐÒÉÓÕÔÓÔ×ÕÅÔ, ÐÒÏ×ÅÒÑÅÍ ÎÁ ÉÚÍÅÎÅÎÉÑ ...
137 $CH=$CHLIST_NEW{$chid};
138 ($chno_n,$tvpid_n,$icon_n,$name_n,$url_n) = @{$CH}{ ('chno','tvpid','icon','name','url') };
139#print "$name_n\n";
140 # ÐÒÏ×ÅÒËÁ ÎÁ ÐÅÅÎÕÍÅÒÁÃÉÀ mythtv -> iptv
141 #if ( $chno_n ne $chno ) {} # ÐÏËÁ ÎÅ ÏÞÅÎØ ÑÓÎÏ ËÁË ÜÔÏ ÄÅÌÁÔØ ÐÏ ÉÄÅÅ ÎÁÄÏ ÚÁÒÁÎÉÅ ÐÅÒÅÄ ÜÔÉÍ ÃÉËÌÏÍ ÓÄÅÌÁÔØ ×ÓÅ ÉÚÍÅÎÅÎÉÑ Á ÐÏÔÏÍ × ÜÔÏÍ ÃÉËÌÅ ×ÓÅ ÐÒÉÎÑÔØ
142
143 if ( $url_n ne $url ) { $change=1; }
144 elsif ( $chno_n ne $chno ) { $change=1; }
145 elsif ( $tvpid_n ne $tvpid ) { $change=1; }
146 elsif ( $name_n ne $name ) { $change=1; }
147 elsif ( $icon_n ne $icon ) { $change=1; }
148 else { $change=0; }
149
150 # ÕÄÁÌÑÅÍ ÉÚ ÓÐÉÓËÁ ÜÔÏÔ ËÁÎÁÌ
151 delete($CHLIST_NEW{$chid});
152
153 # ÅÓÌÉ ÉÚÍÅÎÅÎÉÊ ÎÅÔ ÐÒÏÐÕÓËÁÅÍ ÏÂÒÁÂÏÔËÕ ÜÔÏÇÏ ËÁÎÁÌÁ
154 unless ($change) { next; }
155
156 $CH_UPDATE++;
157 $DB_CHANGE=1;
158print "! $url_n $name_n\n" if ($DEBUG);
159 $dbh->do("UPDATE channel SET channum='$chno_n',freqid='$url_n',name='$name_n',icon='$icon_n',xmltvid='$tvpid_n' WHERE chanid='$id'");
160}
161} while ($hl->more_results);
162$hl->finish();
163
164
165# ÕÚÎÁÅÍ ÍÁËÓÉÍÁÌØÎÙÊ id ËÁÎÁÌÁ
166$hl=$dbh->prepare("SELECT max(chanid) FROM channel");
167$hl->execute();
168($CHANID_LAST)=$hl->fetchrow_array();
169$hl->finish();
170
171
172# ×ÓÁ×ÌÑÅÍ ÏÓÔÁ×ÛÉÅÓÑ ËÁÎÁÌÙ × ÓÐÉÓËÅ, ÜÔÏ ÎÏ×ÙÅ ËÁÎÁÌÙ
173while ( ($chid,$CH) = each %CHLIST_NEW )
174{
175 $CH_INSERT++;
176 $DB_CHANGE=1;
177 $CHANID_LAST++;
178 ($chno_n,$tvpid_n,$icon_n,$name_n,$url_n) = @{$CH}{ ('chno','tvpid','icon','name','url') };
179print "+ $url_n $name_n\n" if ($DEBUG);
180
181 $dbh->do("INSERT INTO channel (chanid,channum,freqid,callsign,name,icon,xmltvid,sourceid) VALUES('$CHANID_LAST','$chno_n','$url_n','$chid','$name_n','$icon_n','$tvpid_n','$SOURCE_ID')");
182}
183
184# ÕÓÔÁÎÁ×ÌÉ×ÁÅÍ ÉÌÉ ÓÂÒÁÓÙ×ÁÅÍ ÆÌÁÇ ÉÚÍÅÎÅÎÉÊ
185$dbh->do("UPDATE settings SET data='$DB_CHANGE' WHERE value='iptv_playlist_change'");
186
187
188# ÏÔËÌÀÞÁÅÍÓÑ ÏÔ âä
189$dbh->disconnect();
190
191
192print "Channel update: $CH_UPDATE\n";
193print "Channel delete: $CH_DELETE\n";
194print "Channel insert: $CH_INSERT\n";
195print "Set flag iptv_playlist_change=$DB_CHANGE\n";
196
197
198
199#######################################################
200# æÕÎËÃÉÉ
201sub http_get
202{
203 my $url=shift;
204 my ($host,$port,$url,$file)=parse_url($url);
205
206 if ($host eq '') { return undef; }
207 socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
208
209 my $iaddr = inet_aton($host);
210 my $paddr = sockaddr_in($port, $iaddr);
211
212 connect(SOCK, $paddr) || return undef;;
213 send (SOCK, "GET /$url HTTP/1.0\nHOST:$host\n\n", 0) || return undef;;
214
215 my @data=<SOCK>;
216
217 close(SOCK);
218
219 my $skip=1;
220 my $str;
221 my $content_type;
222 my $buff;
223
224 foreach $str (@data)
225 {
226 if ($skip)
227 {
228 if ($str=~/^[\r\n]$/) { $skip=0; next; }
229 if ($str=~/Content-Type: (.+)$/i) { $content_type=$1; }
230 next;
231 }
232 $buff.=$str;
233 }
234
235 return ($content_type,$file,$buff);
236}
237
238
239# http://host[:port]/path/file[?args]
240sub parse_url
241{
242 my $url=shift;
243 my $host;
244 my $port;
245 my $file;
246
247 if ($url=~/^https\:\/\/(.*)$/) { $port=443; $url=$1; }
248 elsif ($url=~/^http\:\/\/(.*)$/) { $port=80; $url=$1; }
249 else { return undef; }
250
251 if ($url=~/^([^\/]+)(\/.*)$/) { $host=$1; $url=$2; } else { return undef; }
252 if ($host=~/^(.+):(.+)$/) { $host=$1; $port=$2; }
253 if ($url=~/\/([^\/]*)$/) { $file=$1; if ($file=~/^(.+)\?/) { $file=$1; } }
254
255 return ($host,$port,$url,$file);
256}