btamas86
8/2/2016 - 7:32 AM

CinemaCity oldalát figyelő script, ami értesít, ha az általad megadott filmre rendelhető már jegy.

CinemaCity oldalát figyelő script, ami értesít, ha az általad megadott filmre rendelhető már jegy.

<?php

/**********************************************************************************************************************
 * A script hasznalatahoz, hozz letre a fajl mellett egy cinemacity.ini nevu fajl.
 * A tartalmahoz egy pelda:
 *
 * emailToAddress="email-cimed-ahova-menjen@az-email.hu"
 * emailFromAddress="email-cimed-amirol-kuldi@az-email.hu"
 *
 * [cinemas]
 * name[]="WestEnd"
 * name[]="Duna Plaza"
 *
 * [movies]
 * code[]="1219D2R"
 * subject[]="A kis kedvencek titkos élete"
 *
 * Ezutan a scriptet tedd be cronba:
 * 0 * * * * php /ahol/van/a/script/cinemacity.php
 *
 * FONTOS, hogy a konyvtar irhato legyen, mert itt letrehozza majd a mukodeshez szukseges fajlokat!
 *
 * @author  Balku Tamas
 * @link    http://btamas.hu My Homepage
 * @version 0.2
 **********************************************************************************************************************/

$config = array_replace([
    'url'            => 'http://www.cinemacity.hu/featureInfo?featureCode=:code',
    'jsonUrl'        => 'http://www.cinemacity.hu/presentationsJSON?distribCode=:code',
    'storageFile'    => __DIR__ . '/cinemacity-tmp/:code.txt',
    'sentNotifyFile' => __DIR__ . '/cinemacity-tmp/sent-notifies.txt',
    'anyChanges'     => false,
], parse_ini_file('cinemacity.ini', true));

/**
 * Tartalom lekerdezese
 *
 * @param string $url
 *
 * @return string
 */
function getJSONContent($url)
{
    $ch    = curl_init();
    $agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13';
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    $content = curl_exec($ch);
    curl_close($ch);

    return $content;
}

/**
 * Ertesito email kikuldese
 *
 * @param string      $to
 * @param string      $subject
 * @param string      $body
 * @param string|null $from
 */
function utf8mail($to, $subject, $body, $from = null)
{
    $subject = "=?utf-8?b?" . base64_encode($subject) . "?=";
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= (strpos($from, '@') ? "From: {$from}\r\n" : '');
    $headers .= "Content-Type: text/html;charset=utf-8\r\n";
    $headers .= "X-Mailer: PHP/" . phpversion();
    mail($to, $subject, $body, $headers);
}

/**
 * Vetitesi idopontok kinyerese mozinkent
 *
 * @param object $cinemaSite
 *
 * @return array
 */
function getFormattedCinemaTimes($cinemaSite)
{
    $return = [];
    if (isset($cinemaSite->fe[0]->pr) && is_array($cinemaSite->fe[0]->pr)) {
        $now = new DateTime();
        foreach ($cinemaSite->fe[0]->pr as $pr) {
            $time     = clone $now;
            $time     = $time->setTimestamp($pr->dtticks);
            $diffDays = $now->diff($time)->format('%a');
            $return[] = "{$time->format('m-d H:i')} ({$diffDays} nap múlva)";
        }
    }

    return $return;
}

// Szukseges konyvtarak letrehozasa
foreach (['storageFile', 'sentNotifyFile'] as $makeDir) {
    $dir = dirname($config[$makeDir]);
    // Letrehozzuk a tarolo fajlt, amennyiben nem letezne
    if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
    }
}

// Ha nem akarunk allandoan ertesitest kapni
if ($config['anyChanges'] === false) {
    // Letrehozzuk a tarolo fajlt, amennyiben nem letezne
    if (!file_exists($config['sentNotifyFile'])) {
        touch($config['sentNotifyFile']);
    }

    $sentNotifies = json_decode(file_get_contents($config['sentNotifyFile']), true);
}

// Megadott filmek bejarasa a config alapjan
for ($i = 0, $max = count($config['movies']['code']); $i < $max; $i++) {
    $code        = $config['movies']['code'][$i];
    $subject     = $config['movies']['subject'][$i];
    $jsonUrl     = strtr($config['jsonUrl'], [':code' => $code]);
    $storageFile = strtr($config['storageFile'], [':code' => $code]);

    // Aktualis JSON lekerdezese
    $jsonResponse = getJSONContent($jsonUrl);
    if (empty($jsonResponse)) {
        continue;
    }

    // A filmhez tartozo tarolo letrehozasa
    if (!file_exists($storageFile)) {
        touch($storageFile);
    }

    // Tarolt adat betoltese
    $storageData = file_get_contents($storageFile);

    // Volt-e valtozas a legutobbi keres ota, hogy ne irjunk feleslegesen fajlba es ne keressunk valtozast
    if ($storageData === $jsonResponse) {
        continue;
    }

    // Ha volt valtozas, elmenjuk fajlba
    if ($storageData !== $jsonResponse) {
        $storageData = $jsonResponse;
        file_put_contents($storageFile, $jsonResponse);
    }

    // Beolvasott JSON feldolgozasa
    if (!empty($storageData)) {
        $cacheData = json_decode($storageData);
    }

    // Ha van megadva mozi, ahol rendelheto jegy, akkor azokat dolgozzuk fel
    if (!empty($cacheData->sites)) {
        $emailContent = [];

        // Configban megadott, elfogadhato mozik keresese
        $cinemaCount = count($config['cinemas']['name']);
        foreach ($cacheData->sites as $site) {
            for ($ci = 0; $ci < $cinemaCount; $ci++) {
                $cinemaName  = $config['cinemas']['name'][$ci];
                $sendNotify  = $config['anyChanges'];
                $isAvailable = (stripos($site->sn, $cinemaName) !== false);

                // Amennyiben nem kell mindig ertesites, elerheto a jegy es meg nem kuldtunk rola ertesitest, akkor
                // kimehet es elmentjuk melyik mozirol ment ki az ertesites, hogy legkozelebb mar ne tegye meg
                if (
                    $isAvailable &&
                    $config['anyChanges'] === false &&
                    (empty($sentNotifies[$code]['cinema']) || !in_array($cinemaName, $sentNotifies[$code]['cinema']))
                ) {
                    $sendNotify = true;

                    $sentNotifies[$code]['cinema'][] = $cinemaName;
                    $sentNotifies[$code]['sent'][]   = new DateTime();
                }

                // Ha elerheto a jegy es kuldheto az ertesites, akkor beirjuk a mailbe, melyik mozi elerheto
                if ($isAvailable && $sendNotify) {
                    $emailContent[] = "Mozi: {$site->sn}<br>" . implode(', ', getFormattedCinemaTimes($site));
                }
            }
        }

        // Ha vannak olyan mozik ahol mar rendelheto a jegy, azokrol email ertesites kikuldese
        if (!empty($emailContent)) {
            utf8mail(
                $config['emailToAddress'],
                sprintf('Rendelhető mozijegy: %s', $subject),
                "Foglalás leadható az alábbi mozikban:<br><br>" . implode('<hr>', $emailContent),
                $config['emailFromAddress']
            );
        }
    }
}

// Kikuldott ertesiteseket elmentjuk, ha szukseges
if ($config['anyChanges'] === false) {
    file_put_contents($config['sentNotifyFile'], json_encode($sentNotifies), LOCK_EX);
}