Ticket #9534: mythchannel_sync

File mythchannel_sync, 7.4 KB (added by ligverd@…, 13 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}