Created
December 16, 2013 01:31
-
-
Save amygdala/7981101 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once 'Model.php'; | |
/** | |
* Model class for feed objects | |
*/ | |
class FeedModel extends Model { | |
const FEED_MODEL_KIND = 'FeedModel'; | |
const SUBSCRIBER_URL_NAME = 'subscriber_url'; | |
const ETAG_PROPERTY_NAME = 'etag'; | |
const LAST_CRAWL_DATE_NAME = 'last_crawled'; | |
const SUBSCRIBER_LIST_NAME = 'subscribers'; | |
private $subscriber_url; | |
private $subscriber_list; | |
private $etag; | |
private $last_crawl_date; | |
public function __construct($url) { | |
parent::__construct(); | |
$this->key_name = sha1($url); | |
$this->subscriber_url = $url; | |
$this->subscriber_list = []; | |
} | |
public function getSubscriberUrl() { | |
return $this->subscriber_url; | |
} | |
public function setETag($etag) { | |
$this->etag = $etag; | |
} | |
public function getETag() { | |
return $this->etag; | |
} | |
public function getLastCrawlDate() { | |
return $this->last_crawl_date; | |
} | |
public function setLastCrawlDate($date_time) { | |
$this->last_crawl_date = $date_time; | |
} | |
public function getSubscriberList() { | |
return $this->subscriber_list; | |
} | |
public function addSubscriber($id) { | |
if ($this->subscriber_list == null) { | |
$this->subscriber_list = [$id]; | |
return true; | |
} | |
if (!in_array($id, $this->subscriber_list)) { | |
$this->subscriber_list[] = $id; | |
return true; | |
} | |
return false; | |
} | |
public function removeSubscriber($id) { | |
$key = array_search($id, $this->subscriber_list); | |
if ($key!==false) { | |
unset($this->subscriber_list[$key]); | |
return true; | |
} | |
return false; | |
} | |
protected static function getKindName() { | |
return self::FEED_MODEL_KIND; | |
} | |
/** | |
* Generate the entity property map from the feed object fields. | |
*/ | |
protected function getKindProperties() { | |
$property_map = []; | |
$property_map[self::SUBSCRIBER_URL_NAME] = | |
parent::createStringProperty($this->subscriber_url, true); | |
if ($this->etag) { | |
$property_map[self::ETAG_PROPERTY_NAME] = | |
parent::createStringProperty($this->etag); | |
} | |
if ($this->last_crawl_date) { | |
$property_map[self::LAST_CRAWL_DATE_NAME] = | |
parent::createStringProperty($this->last_crawl_date); | |
} | |
if (!empty($this->subscriber_list)) { | |
$property_map[self::SUBSCRIBER_LIST_NAME] = | |
parent::createStringListProperty($this->subscriber_list); | |
} | |
return $property_map; | |
} | |
/** | |
* Fetch a feed object given its feed URL. If get a cache miss, fetch from the Datastore. | |
* @param $feed_url URL of the feed. | |
*/ | |
public static function get($feed_url) { | |
$mc = new Memcache(); | |
$key = self::getCacheKey($feed_url); | |
$response = $mc->get($key); | |
if ($response) { | |
return [$response]; | |
} | |
$query = parent::createQuery(self::FEED_MODEL_KIND); | |
$feed_url_filter = parent::createStringFilter(self::SUBSCRIBER_URL_NAME, | |
$feed_url); | |
$filter = parent::createCompositeFilter([$feed_url_filter]); | |
$query->setFilter($filter); | |
$results = parent::executeQuery($query); | |
$extracted = self::extractQueryResults($results); | |
return $extracted; | |
} | |
/** | |
* This method will be called after a Datastore put. | |
*/ | |
protected function onItemWrite() { | |
$mc = new Memcache(); | |
try { | |
$key = self::getCacheKey($this->subscriber_url); | |
$mc->add($key, $this, 0, 120); | |
} | |
catch (Google_Cache_Exception $ex) { | |
syslog(LOG_WARNING, "in onItemWrite: memcache exception"); | |
} | |
} | |
/** | |
* This method will be called prior to a datastore delete | |
*/ | |
protected function beforeItemDelete() { | |
$mc = new Memcache(); | |
$key = self::getCacheKey($this->subscriber_url); | |
$mc->delete($key); | |
} | |
/** | |
* Extract the results of a Datastore query into FeedModel objects | |
* @param $results Datastore query results | |
*/ | |
protected static function extractQueryResults($results) { | |
$query_results = []; | |
foreach($results as $result) { | |
$id = @$result['entity']['key']['path'][0]['id']; | |
$key_name = @$result['entity']['key']['path'][0]['name']; | |
$props = $result['entity']['properties']; | |
$url = $props[self::SUBSCRIBER_URL_NAME]->getStringValue(); | |
if (isset($props[self::ETAG_PROPERTY_NAME])) { | |
$etag = @$props[self::ETAG_PROPERTY_NAME]->getStringValue(); | |
} | |
else { | |
$etag = null; | |
} | |
if (isset($props[self::LAST_CRAWL_DATE_NAME])) { | |
$last_crawl_date = @$props[self::LAST_CRAWL_DATE_NAME]->getStringValue(); | |
} | |
else { | |
$last_crawl_date = null; | |
} | |
$subscribers = []; | |
if (isset($props[self::SUBSCRIBER_LIST_NAME])) { | |
if (!empty($props[self::SUBSCRIBER_LIST_NAME]['listValue'])) { | |
$subslist = $props[self::SUBSCRIBER_LIST_NAME]->getListValue(); | |
foreach ($subslist as $s) { | |
$subscribers[] = $s->getStringValue(); | |
} | |
} | |
} | |
$feed_model = new FeedModel($url); | |
$feed_model->setKeyId($id); | |
$feed_model->setKeyName($key_name); | |
$feed_model->last_crawl_date = $last_crawl_date; | |
$feed_model->subscriber_list = $subscribers; | |
$feed_model->etag = $etag; | |
// Cache this read feed. | |
$feed_model->onItemWrite(); | |
$query_results[] = $feed_model; | |
} | |
return $query_results; | |
} | |
private static function getCacheKey($feed_url) { | |
return sprintf("%s_%s", self::FEED_MODEL_KIND, sha1($feed_url)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment