Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: TV-skripti

Sivun loppuun

khaani [12.01.2005 09:53:26]

#

demo täällä: http://kotinetti.suomi.net/home.keranen/tv/

Skripti yrittää viisaasti cachettaa ohjelmatiedot ilman, että se näkyy käyttäjän selaimen hidasteluina. Tämä ominaisuus
ei kuitenkaan toimi esimerkiksi mbnetissä, syytä en tiedä. Ohjelmatietojen lähteenä toimii ohjelmat.info. Bugeja ja purkkaa varmasti löytyy. Parannusehdotuksia otetaan vastaan.

Tuota tv-luokkaa voi helposti käyttää myös tästä skriptistä irrallaan. Käyttö on suht yksinkertaista: $tv->getPrograms(<tähän kanavan tunniste>, <päivämäärä muodossa Ymd>);

<?php
// korjaa tähän hakemisto missä skripti sijaitsee, mikäli getcwd:llä ei tule oikeaa dirriä
$dir = getcwd();

class tv
{
	var $channels = array
	(
		"TV1" => "TV1",
		"TV2" => "TV2",
		"MTV" => "MTV3",
		"NEL" => "Nelonen",
		"TVT" => "SubTV",
		"CAP" => "Canal+",
		"CAK" => "Canal Film 1",
		"CAS" => "Canal Film 2",
		"TUH" => "TV1000",
		"TUC" => "TV1000 Family",
		"UR1" => "Urheilukanava",
		"MTN" => "MTV Nordic",
		"EUR" => "Eurosport",
		"Y24" => "Yle24",
		"YTE" => "YleTeema",
		"BBC" => "BBC World",
		"DIS" => "Discovery Channel"
	);
	var $host = "ohjelmat.info";
	var $path = "/tv/kanava.tv";
	var $cache_dir;

	function tv($dir)
	{
		$this->cache_dir = $dir . "/" . "cache";

		if( !file_exists($this->cache_dir) && !mkdir($this->cache_dir) )
			die("Hakemiston {$this->cache_dir} luonti epäonnistui, luo hakemisto käsin.");
		if( !is_writable($this->cache_dir) && !chmod($this->cache_dir, 0777) )
			die("Hakemiston {$this->cache_dir} kirjoitusoikeuksia ei voitu muuttaa. Aseta hakemistolle oikeudet 0777.");
	}

	function checkParams($k, $pvm)
	{
		if( preg_match("/([\d]{4})([\d]{2})([\d]{2})/",$pvm,$matches) != 1 )
			return false;
		else
		{
			$time = mktime(0, 0, 0, $matches[2], $matches[3], $matches[1]) - mktime(0, 0, 0, date("m"), date("d"), date("Y"));
			if($time > 518400 || $time < -86400)
				return false;
			elseif(isset($this->channels[$k]) )
				return array("month" => $matches[2], "day" => $matches[3], "year" => $matches[1]);
		}
	}

	function getPrograms($k, $pvm)
	{
		if( !$date = $this->checkParams($k, $pvm) )
			die("Antamasi parametrit olivat virheelliset.");

		$programs = array();

		if( !file_exists("{$this->cache_dir}/{$pvm}_{$k}.dat") )
		{
			$contents = NULL;
			$dayChange = false;

			$fp = fsockopen($this->host, 80, $errno, $errstr, 10);
			if (!$fp)
				die("Kanavan {$this->channels[$k]} tietojen haku päivälle {$pvm} epäonnistui.");

			$out = "GET {$this->path}?k={$k}&pvm={$pvm} HTTP/1.1\r\n";
			$out .= "Host: {$this->host}\r\n";
			$out .= "Referer: {$this->host}\r\n";
			$out .= "Connection: Close\r\n\r\n";

			fwrite($fp, $out);
			while ( !feof($fp) )
				$contents .= fgets($fp);
			fclose($fp);

			preg_match_all("/<td class=\"boldtext\">([\d]{2})\.([\d]{2})<\/td>.*<td class=\"boldtext\">(.*)<\/td>/Us",$contents,$matches,PREG_SET_ORDER);
			foreach($matches as $key => $value)
			{
				$time = mktime($value[1], $value[2], 0, $date["month"], $date["day"], $date["year"]);
				if(isset($matches[$key-1]) && $matches[$key-1][1] > $value[1])
					$dayChange = true;

				$programs[] = array
				(
					($dayChange == true) ? $time += 86400 : $time,
					trim($value[3])
				);
			}

			$fp = fopen("{$this->cache_dir}/{$pvm}_{$k}.dat","wb");
			if (!$fp)
				die("Cachetiedoston {$pvm}_{$k}.dat avaaminen kirjoittamista varten epäonnistui.");
			fwrite($fp, serialize( $this->array_walk_mdimensional("addslashes",$programs) ) );
			fclose($fp);
		}
		else
		{
			$fp = fopen("{$this->cache_dir}/{$pvm}_{$k}.dat","rb");
			if (!$fp)
				die("Cachetiedoston {$pvm}_{$k}.dat avaaminen lukemista varten epäonnistui.");
			$programs = fread($fp, filesize("{$this->cache_dir}/{$pvm}_{$k}.dat") );
			fclose($fp);

			$programs = $this->array_walk_mdimensional("stripslashes",unserialize($programs));
		}

		return $programs;
	}

	function array_walk_mdimensional($func, $arr)
	{
		foreach($arr as $k => $v)
		{
			if(is_array($v))
				$arr[$k] = $this->array_walk_mdimensional($func, $v);
			else
				$arr[$k] = $func($v);
		}
		return $arr;
	}
}

/*
	cachetuksen vuoksi kikkaillaan hiukan headereitten ja output bufferin kanssa,
	jotta käyttäjän selain ei näyttäisi jumittavan sillä aikaa kun ohjelmatietoja haetaan servulle talteen

	huom. ei toimi esimerkiksi mbnetissä. selain jää jumittamaan ja skriptin toiminta vaikuttaa käyttäjästä hitaalta
*/
header("Connection: close");
ob_start();


$tv = new tv($dir);
if(get_magic_quotes_gpc())
{
	$_POST = $tv->array_walk_mdimensional("stripslashes",$_POST);
	$_COOKIE = $tv->array_walk_mdimensional("stripslashes",$_COOKIE);
	$_GET = $tv->array_walk_mdimensional("stripslashes",$_GET);
}

if(isset($_POST["chans"]))
{
	$selected_chans = $_POST["chans"];
	setcookie("chans",serialize( $tv->array_walk_mdimensional("addslashes",$_POST["chans"]) ));
}
elseif(isset($_COOKIE["chans"]))
	$selected_chans = $tv->array_walk_mdimensional("stripslashes",unserialize($_COOKIE["chans"]) );
else
	$selected_chans = array("TV1", "TV2", "MTV", "NEL");

$date = isset($_GET["pvm"]) ? $_GET["pvm"] : date("Ymd",time()-14400);
$hide = ( isset($_GET["hide"]) && $_GET["hide"] == 1 ) ? 1 : 0;
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<title>TV</title>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
	<style type="text/css">
		body
		{
			margin: 0px 0px 0px 0px;
			padding: 0px 0px 0px 0px;
			background: white;
			width: 100%;
		}
		a:link
		{
			color: black;
			letter-spacing: 1pt;
			text-decoration: underline;
		}
		a:active
		{
			color: #c30;
			letter-spacing: 1pt;
			text-decoration: none;
		}
		a:visited
		{
			color: black;
			letter-spacing: 1pt;
			text-decoration: underline;
		}
		a:hover
		{
			color: #c30;
			letter-spacing: 1pt;
			text-decoration: none;
		}
		a.selected
		{
			color: #c30;
			font-weight: bold;
			letter-spacing: 1pt;
		}
		a.hide
		{
			color: #E9E9E9;
			letter-spacing: 1pt;
		}
		td.chan
		{
			font-weight: bold;
			font-family: arial, tahoma;
			font-size: 11pt;
			color: #c30;
			letter-spacing: 1pt;
			line-height: 1.2em;
		}
		td.time
		{
			padding: 4px 4px 4px 4px;
			background: #eee;
			font-family: arial, tahoma;
			font-size: 9pt;
			color: #333;
			border-right: 1px dotted #566;
			font-weight: bold;
		}
		td.prog
		{
			padding: 4px 4px 4px 4px;
			font-family: arial, tahoma;
			font-size: 9pt;
			color: #666;
			width: 100%;
		}
		td.progSel
		{
			font-weight: bold;
			padding: 4px 4px 4px 4px;
			font-family: arial, tahoma;
			font-size: 9pt;
			color: #c30;
			width: 100%;
		}
		table.head
		{
			background: #F9F9F9;
			border-bottom: 1px dotted #566;
			border-right: 1px dotted #566;
			height: 100px;
			padding: 10px 10px 10px 10px;
			font-family: arial, tahoma;
			font-size: 11pt;
			color: #c30;
			letter-spacing: 1pt;
			line-height: 1.2em;
		}
		td.chanSel
		{
			background: #E8E8E8;
		}
		td.chanSelName
		{
			padding: 4px 4px 4px 4px;
			background: #eee;
			font-family: arial, tahoma;
			font-size: 8pt;
			color: #333;
			border-right: 1px dotted #566;
		}
		td.selHead
		{
			font-family: arial, tahoma;
			font-size: 13pt;
			color: #F7F7F7;
			padding: 4px 4px 4px 4px;
			background: #d40;
			letter-spacing: 1pt;
			font-weight: bold;
		}
		td.selOption
		{
			font-family: arial, tahoma;
			font-size: 8pt;
			color: #F7F7F7;
			padding: 9px 9px 9px 9px;
			background: #d40;
			letter-spacing: 1pt;
		}
		.submit
		{
			padding: 2px 2px 2px 2px;
			background: #eee;
			font-family: arial, tahoma;
			font-size: 9pt;
			color: #333;
			border: 1px solid #ccc;
			font-weight: bold;
		}
	</style>
</head>
<body>

<table class="head" cellspacing="5">
	<tr>
		<td valign="top">

			<table cellpadding="0" cellspacing="1">
			<tr>
				<td colspan="2" class="selOption">Valitse päivämäärä</td>
			</tr>

<?php
for($i = -1; $i <= 6; $i++)
{
	$time = mktime(0, 0, 0, date("m"), date("d"), date("Y")) + $i * 86400;
	$new_date = date("Ymd", $time);
	$selected = $new_date == $date ? " class=\"selected\"" : NULL;
	if($i % 2 == 1) print "\t\t\t<tr>\n";
	print "\t\t\t\t<td class=\"chanSelName\"><a href=\"{$_SERVER["PHP_SELF"]}?pvm={$new_date}&amp;hide={$hide}\"{$selected}>" . date("Y-m-d", $time) . "</a></td>\n";
	if( ($i+1) % 2 == 1 ) print "\t\t\t</tr>\n";
}
?>
			</table>

		</td>
		<td valign="top">

			<form action="<?="{$_SERVER["PHP_SELF"]}?pvm=$date&amp;hide={$hide}"?>" method="post" enctype="multipart/form-data">
			<table cellpadding="0" cellspacing="1">
			<tr>
				<td colspan="4" class="selOption">
					<a href="<?="{$_SERVER["PHP_SELF"]}?pvm=$date&amp;hide=" . ($hide ? 0 : 1) . "\" class=\"hide\">" . ($hide ? "Näytä" : "Piilota")?> menneet ohjelmat</a>
				</td>
				<td colspan="6" class="selHead" align="right">
					<input name="submit" type="submit" value="submit" class="submit">
				</td>
			</tr>
<?php
$i = 0;
foreach($tv->channels as $k => $v)
{
	$selected = in_array($k,$selected_chans) ? " checked" : NULL;
	if($i % 5 == 0) print "\t\t\t<tr>\n";
	print "\t\t\t\t<td class=\"chanSel\"><input name=\"chans[]\" type=\"checkbox\" value=\"{$k}\"{$selected}></td>\n\t\t\t\t<td class=\"chanSelName\" nowrap>{$v}</td>\n";
	if( ($i+1) % 5 == 0 || $i+1 == count($tv->channels) ) print "\t\t\t</tr>\n";
	$i++;
}
?>
			</table>
			</form>

		</td>
	</tr>
</table>

<table>
<tr>
<?php
foreach($selected_chans as $k)
{
	if( isset($tv->channels[$k]) && $v = $tv->channels[$k])
	{
		$programs = $tv->getPrograms($k,$date);
		print "\t<td valign=\"top\">\n\t\t<table width=\"270\" cellpadding=\"0\" cellspacing=\"1\">\n\t\t<tr>\n\t\t\t<td colspan=\"2\" class=\"chan\">{$v}</td>\n\t\t</tr>\n";
		foreach($programs as $a => $p)
		{
			if( ( $hide && isset($programs[$a+1]) && time() > $programs[$a+1][0] ) || ( $hide && !isset($programs[$a+1]) && time()-14400 >= $p[0] )	)
				continue;
			if(	( isset($programs[$a+1]) && time() < $programs[$a+1][0] && time() >= $p[0] ) || ( !isset($programs[$a+1]) && (time() - $p[0] <= 14400 && time() - $p[0] > 0	) ) )
				$progClass = "progSel";
			else
				$progClass = "prog";

			$program = $p[1];
			$time = date("H:i",$p[0]);
			print "\t\t<tr>\n\t\t\t<td valign=\"top\" class=\"time\">{$time}</td>\n\t\t\t<td valign=\"top\" class=\"{$progClass}\">{$program}</td>\n\t\t</tr>\n";
		}
		print "\t\t</table>\n\t</td>\n";
	}
}
?>
</tr>
</table>

</body>
</html>

<?php

/*
	näytetään sivu käyttäjälle ja valehdellaan selaimelle, että koko sivu oli siinä
*/
ignore_user_abort(true);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();

// haetaan valmiiksi servulle talteen ohjelmatietoja
for($i = -86400; $i <= 518400; $i += 86400)
{
	$cached = false;
	$time = mktime(0, 0, 0, date("m"), date("d"), date("Y")) + $i;
	$date = date("Ymd",$time);
	foreach($tv->channels as $k => $v)
	{
		if( !file_exists("{$tv->cache_dir}/{$date}_{$k}.dat") )
		{
			$tv->getPrograms($k,$date);
			$cached = true;
		}
	}
	if($cached == true)
		break;
}
?>

Bill Keltanen [13.01.2005 15:34:55]

#

Hmm samanlainen ku kuhassa.. :o

str4nd [13.01.2005 15:35:29]

#

Very Good. Tästä on hyötyä!

EDIT: ...mutta en saanut toimimaan.

khaani [13.01.2005 15:45:03]

#

lainaus:

Hmm samanlainen ku kuhassa.. :o

Johtunee siitä, että minä olen sen sinne pistänyt. :)

lainaus:

Very Good. Tästä on hyötyä!

EDIT: ...mutta en saanut toimimaan.

Jos ei toimi, niin luo käsin sinne skriptin hakemistoon tuo cache dirri ja aseta sille tarpeelliset kirjotusoikeudet. Ja tuo getcwd() ei välttämättä anna oikeaa hakemistoa, joten joudut ehkä käsin määrittelemään oikean polun skriptille.

chiqu [13.01.2005 16:48:11]

#

siis täähän on nätimpi kun telkku.com.
Jos mä onnistuisin noin nätissä ni menis äkkii suunnitelmat koodivinkiks pastettamisenkaa uusiks ;)

Mistäs tää kerää infonsa ?

khaani [13.01.2005 16:55:15]

#

lainaus:

siis täähän on nätimpi kun telkku.com.
Jos mä onnistuisin noin nätissä ni menis äkkii suunnitelmat koodivinkiks pastettamisenkaa uusiks ;)

Mistäs tää kerää infonsa ?

Ohjelmat.infosta kuten tuossa kuvauksessa jo sanoin :)

MysteriO [13.01.2005 23:35:51]

#

juu siis ihan hyvä koodi... ja käytännöllinen ;)

kayttaja-2791 [14.01.2005 09:09:34]

#

Tämänhän voisi ihan pistää omille sivuille... On kyllä omakin tv-skripti, mutta se ei ihan vielä yllä tämän käytettävyyteen :)

Vieläkö saat tehtyä että se hakisi kuvaukset ohjelmiin tuolta Ohjelmat.infosta tai Telkku.comista niin täydellisyyttä hipoisi.

Edit:
Btw. käsittääkseni syy miksi se ei toimi Mbnetissä on ihan se että sielä on päällä output_buffering, eli koko skripti suoritetaan ennen minkään headereiden lähetystä.

Ja sitten voisit muuttaa koodista seuraavat rivit:

        a:link
        {
            color: black;
            letter-spacing: 1pt;
            text-decoration: underline;
        }
        a:active
        {
            color: #c30;
            letter-spacing: 1pt;
            text-decoration: none;
        }
        a:visited
        {
            color: black;
            letter-spacing: 1pt;
            text-decoration: underline;
        }
        a:hover
        {
            color: #c30;
            letter-spacing: 1pt;
            text-decoration: none;
        }

muotoon

        table.head a:link
        {
            color: black;
            letter-spacing: 1pt;
            text-decoration: underline;
        }
        table.head a:active
        {
            color: #c30;
            letter-spacing: 1pt;
            text-decoration: none;
        }
        table.head a:visited
        {
            color: black;
            letter-spacing: 1pt;
            text-decoration: underline;
        }
        table.head a:hover
        {
            color: #c30;
            letter-spacing: 1pt;
            text-decoration: none;
        }

Niin se ei sotke integroitaessa sivustoon muuta layoutia.

jhvisto [14.01.2005 22:57:14]

#

Warning: fopen(c:\inetpub\wwwroot/cache/20050114_TV1.dat): failed to open stream: Permission denied in c:\inetpub\wwwroot\tvohjelmat.php on line 95
Cachetiedoston 20050114_TV1.dat avaaminen kirjoittamista varten epäonnistui.

Tuollainen ilmoitus tuli, vaikka chmodin luvat on kirjoittaa.. onkos tässä jotain ovelaa takana?

makas [15.01.2005 13:43:30]

#

sripti toimii mutta nyt menossa olevat ohjelmat ovat 2 tuntia jäljessä. Miten sen saa korjattua?

khaani [15.01.2005 14:42:50]

#

lainaus:

sripti toimii mutta nyt menossa olevat ohjelmat ovat 2 tuntia jäljessä. Miten sen saa korjattua?

Olisiko palvelimen kello väärässä.

lainaus:

Warning: fopen(c:\inetpub\wwwroot/cache/20050114_TV1.dat): failed to open stream: Permission denied in c:\inetpub\wwwroot\tvohjelmat.php on line 95
Cachetiedoston 20050114_TV1.dat avaaminen kirjoittamista varten epäonnistui.

Tuollainen ilmoitus tuli, vaikka chmodin luvat on kirjoittaa.. onkos tässä jotain ovelaa takana?

Poista tuo cache hakemisto ja luo käsin se dirri ja sen jälkeen chmodaa oikat kuntoon.

makas [15.01.2005 17:49:28]

#

lainaus:

Olisiko palvelimen kello väärässä.

Palvelimen kelloaikaa ei voi muuttaa, mutta saisko sen koodiin ujutettua, että se osais siirtää kelloa kaks tuntia eteenpäin?

makas [16.01.2005 20:40:33]

#

Joo sain ite koodattu tuon aika ongelman... Erittäin hyvä sripti :)

T.M. [17.01.2005 14:48:18]

#

Entä jos laitatkin piilotettuun iframeen tuon cachetuksen?
Siten sen ei myöskään pitäisi hidastaa käyttäjän selainta :)

khaani [20.01.2005 14:33:16]

#

lainaus:

Entä jos laitatkin piilotettuun iframeen tuon cachetuksen?
Siten sen ei myöskään pitäisi hidastaa käyttäjän selainta :)

Käyttäjän selain jää silti odottamaan skriptin loppuun suorittamista. Sama asia ois vaan flushia selaimelle output bufferi ja jatkaa skriptin suorittamista.

T.M. [21.01.2005 15:11:28]

#

Siis? En tiedä muista selaimista, mutta ainakin IE:llä iframe latautuu viimeiseksi, eikä haittaa muun sivun latautumista lainkaan (jos sen laittaa viimeiseksi sivun lähdekoodiin).
Ja vaikka sivun sulkisi, scripti jää silti pyörimään. Ellei serverin asetuksia ole jotenkin sotkettu.

Niin ja tuo iframe hässäkkä toimisi myös mbnetissä.

MysteriO [25.01.2005 21:23:32]

#

kyllä tuon nyt jotenki saa mbnetissä toimimaan.. ;p mut kyl viel jotai bugittaa... :/

kayttaja-2791 [29.01.2005 23:16:22]

#

Cachetus tekee jokaiselle kanavalle joka päivälle oman tiedoston, eikä poista vanhentuneita tiedostoja. Lisäksi kaikki mahdolliset kanavat cachetetaan. Seurauksena aika hirveä tilankulutus. Itsellä pyörinyt skripti nyt jotain 2 viikkoa ja levytilaa cachet vievät n.700kt. Ihan varoituksena kaikille, jos pyöritättä skriptiä cachetuksella niin pahimmassa tapauksessa ikävä yllätys voi tulla laskun muodossa sivuja ylläpitävältä firmalta.

Mahjo [10.05.2005 15:06:27]

#

Ihan hyvä mutta voisiko joku sanoa miks ei näy kaikkien päivän ohjelmat on vaan tyhjää!

v0q [07.06.2005 21:04:03]

#

Saisko tätä mitenkään että ei näyttäis ohjelmia jotka on jo mennyt ? Ja sais sitte maksimi määrän monta se näyttä... Kun meinaan työpöydälle tuota soveltaa nii ei oikeen oo kiva jos menee noin :/ Loistava koodi muuten :)

Jorgga [04.12.2005 13:14:12]

#

ei näy kanava tiedot


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta