<?php
/**
* Scrapes a recent deviations feed together from deviantart.
*
* Uses a json formatted string from deviantart which works currently, however
* any changes will most likley break this. Hopefully only the xsl would need to
* be updated in such an event.
*
* GENERAL DISCLAIMER
*
* I am not personally affiliated with DeviantART in any way. Use of the
* DeviantART website by its Terms Of Service. I am not responsible for the way
* you use this script. The use of this script to scrape your DeviantART user
* gallery may be in breach of your agreement with DeviantART.
*
* LICENSE
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author Stephen Ingram <hide@address.com>
* @copyright Copyright (c) 2008, Stephen Ingram
* @package deviantartfeed
* @category deviantartfeed
* @todo The title and date regex is quick and dirty, it could easily be tripped
* up.
* @todo Investigate further what sort of output the DeviantART "DiFi" script
* will generate.
*/
class deviantartfeed
{
/**
* Location of config file
*
* If you move or rename the deviantart.ini file you must edit this path.
*
* @var string
*/
const config_file = 'deviantart.ini';
/**
* Holds loaded config array
*
* @var array
*/
public $conf;
/**
* Filesystem path to cache file.
*
* @var string
*/
public $cache;
/**
* Constructor does all the work
*/
public function __construct()
{
$this->conf = parse_ini_file(self::config_file, true);
$this->cache = $this->conf['cache']['path']
. $this->conf['cache']['file'];
if (file_exists($this->cache)
&& filemtime($this->cache) > time() - 86400)
return $this->output_cache();
/**
* Set url, broken into multiple lines for readability. Well...
*/
$url = "http://{$this->conf[feed][user]}artist.deviantart.com/global/difi/"
. "?c%5B%5D=Resources;htmlFromQuery;gallery%3A{$this->conf[feed][user]}"
. "%20sort%3Atime,{$this->conf[feed][start]},{$this->conf[feed][request]}"
. ",thumb150,artist%3A0&t=json";
/**
* Spoof user agent, not really necessary.
*/
ini_set(
'user_agent',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1)'
);
/**
* Get json string
*/
if (!$result = file_get_contents($url))
return;
/**
* Decode json string
*/
$result_object = json_decode($result);
/**
* Define xml file, includes attributes on channel that are used by the
* php function calls.
*/
$xml = "<channel
imageurl=\"{$this->conf[imagecache][url]}\"
imagecache=\"{$this->conf[imagecache][path]}\"
>
<title>{$this->conf[feed][user]}'s deviantART gallery</title>
<link>http://{$this->conf[feed][user]}.deviantart.com</link>";
/**
* Add any additional channel elements as defined in ini
*/
if (isset($this->conf['channel'])
&& !empty($this->conf['channel'])
)
foreach ($this->conf['channel'] as $name => $value)
$xml .= "<{$name}>{$value}</{$name}>";
$xml .= "<items>";
/**
* Add xml entry for each item in the response object.
*/
foreach($result_object->DiFi->response->calls[0]->response->content->resources as $item)
$xml .= '<item>' . $item[2] . '</item>';
/**
* Initialize the dom object and load the xml file from the string.
*/
$dom = new DOMDocument;
$dom->loadXML($xml . '</items></channel>');
/**
* Initialize the xsl dom object and load the xsl file form the
* filesystem.
*/
$xsl = new DOMDocument;
$xsl->load($this->conf['xsl']['path']);
/**
* Initialize the XSLT processor and enable php function calls
*/
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
/**
* Import the xsl object
*/
$proc->importStyleSheet($xsl);
/**
* Process the xml translation and save to the cache file.
*/
file_put_contents($this->cache, $proc->transformToXML($dom));
/**
* Call deviantart::output_cahce() to send the rss feed to the user,
* if enabled
*/
return $this->output_cache();
}
/**
* Return or send cache depenging on setting
*
* If not in cron mode sends the contents of the cache file to the user,
* otherwise simply returns void.
*
* @return void
*/
public function output_cache()
{
if($this->conf['general']['cron'])
return;
/* or redirect to the feed.
header('Location: '
. $this->conf['general']['url']
. $this->conf['cache']['url']
. $this->conf['cache']['file']
);
*/
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Mozilla')) {
header('Content-type: text/xml');
} else {
header('Content-Type: application/rss+xml');
}
header('Last-Modified: ' . date('r', filemtime($this->cache)));
echo file_get_contents($this->cache);
return;
}
/**
* Downloads a local cache of specified file.
*
* @param string $url
* @param string $base URL base to apply to output URL
* @param string $path Path base for local filesystem path.
* @return string URL to local cache.
*/
public static function xsl_make_local_cache($url, $base = '', $path = '')
{
ini_set(
'user_agent',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/Firefox/3.0.1'
);
/**
* Get file name
*/
$file = substr($url, strrpos($url, '/') + 1);
if (file_exists($path . $file))
return $base . $file;
file_put_contents($path . $file, file_get_contents($url));
return $base . $file;
}
/**
* Gets the artwork title from the proviced string
*
* @param string $string Vale of title attribute from input xml
* @return string Artwork title
*/
public static function xsl_get_title($string)
{
preg_match(
'/(.*?) by/',
$string,
$title
);
return $title[1];
}
/**
* Gets the artwork date in RFC 2822 format from the proviced string
*
* I'm assuming that deviantart records dates in UTC time, however I could
* be wrong.
*
* @param string $string Vale of title attribute from input xml
* @return string Artwork date
*/
public static function xsl_get_date($string)
{
/**
* I'm assuming that you can't have a , in your artork title.
*/
preg_match(
'/, (.*)/',
$string,
$date
);
date_default_timezone_set('UTC');
return date('r', strtotime($date[1]));
}
}
new deviantartfeed;