Fixing the Magic Mirror Calendar

November 24th, 20144 min read

This week I received some reports that the Magic Mirror calendar section stopped working. Since the mirror gracefully hides the calendar data, I didn’t really notice it on my own Magic Mirror. Of course, this must be fixed. 

Read the previous post in this series here:
MagicMirror: Production of the Interface

To figure out what was wrong, I started with the feed url. When I entered this in my browser, the .ical file was correctly downloaded, and after opening, it seems to look fine …

image

The next step in the calendar display process is the proxy script: calendar.php, since an Ajax request direct to the iCloud servers is not permitted. After opening this calendar.php file in my browser, the issue was visible: it only shows some useless coded garbish.

image

Somehow, the feed could not be correctly downloaded by the calendar.php. Till now, this was done, using the following line: 

echo file_get_contents($url);

Since, the file_get_contents isn’t very sophisticated, I tried switching to curl:

<?php

// Set the url of the calendar feed.
$url = 'https://p01-calendarws.icloud.com/ca/subscribe/1/...';

// Initialize the curl request.
$ch = curl_init();

// Set the CURL url.
curl_setopt ($ch, CURLOPT_URL, $url);

// Make sure redirects are followed.
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

// Execute the request and echo the response.
echo curl_exec($ch);

// Close the CURL request.
curl_close($ch);

Unfortunately, this still gave the same result. So time to dive in the CURL documentation. CURL has a lots of options that can be set by above used curl_setopt() function. So chances are, a solution is hidden within these options.

After some reading, I found the CURLOPT_ENCODING option:

The contents of the “Accept-Encoding: ” header. This enables decoding of the response. Supported encodings are “identity”, “deflate”, and “gzip”. If an empty string, “”, is set, a header containing all supported encoding types is sent.

After setting this flag to true, the script outputted the desired format. Setting the flag before the echo was simple: 

curl_setopt ($ch, CURLOPT_ENCODING, true);

It seems Apple recently turned on gzip compression on their iCal webservers.

Unfortunately, after testing it on my actual Raspberry Pi, I found out that my PHP installation on my RPi does not support CURL. But since I now found the reason and solution, some googling brought me to a post on BinaryTides which shows a file_get_contents()way to use decoding. Using this solution, I now got my calendar up and running again, using the following code:

<?php

// Set the url of the calendar feed.
$url = 'https://p01-calendarws.icloud.com/ca/subscribe/...';

/*****************************************/

// Run the helper function with the desired URL and echo the contents.
echo get_url($url);

// Define the helper function that retrieved the data and decodes the content.
function get_url($url)
{
    //user agent is very necessary, otherwise some websites like google.com wont give zipped content
    $opts = array(
        'http'=>array(
            'method'=>"GET",
            'header'=>"Accept-Language: en-US,en;q=0.8rn" .
                        "Accept-Encoding: gzip,deflate,sdchrn" .
                        "Accept-Charset:UTF-8,*;q=0.5rn" .
                        "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0 FirePHP/0.4rn"
        )
    );

    $context = stream_context_create($opts);
    $content = file_get_contents($url ,false,$context);

    //If http response header mentions that content is gzipped, then uncompress it
    foreach($http_response_header as $c => $h)
    {
        if(stristr($h, 'content-encoding') and stristr($h, 'gzip'))
        {
            //Now lets uncompress the compressed data
            $content = gzinflate( substr($content,10,-8) );
        }
    }

    return $content;
}

Of course, this fix is included in the Magic Mirror Repository on GitHub.

Man, it feels good if you solve a bug! :)

image

Read the next post in this series here:
MagicMirror: Magic Mirrors around the World!
Loading comments …
©2025 - MichaelTeeuw.nl