okapi r594

This commit is contained in:
following
2013-03-29 17:34:48 +01:00
parent f89c8b6fd9
commit f931529dca
8 changed files with 243 additions and 20 deletions

View File

@ -778,7 +778,7 @@ class Okapi
{
public static $data_store;
public static $server;
public static $revision = 590; # This gets replaced in automatically deployed packages
public static $revision = 594; # This gets replaced in automatically deployed packages
private static $okapi_vars = null;
/** Get a variable stored in okapi_vars. If variable not found, return $default. */

View File

@ -27,6 +27,7 @@ use okapi\OkapiServiceRunner;
use okapi\OkapiInternalRequest;
use okapi\OkapiInternalConsumer;
use okapi\services\replicate\ReplicateCommon;
use okapi\services\attrs\AttrHelper;
class CronJobController
{
@ -50,6 +51,7 @@ class CronJobController
new FulldumpGeneratorJob(),
new TileTreeUpdater(),
new SearchSetsCleanerJob(),
new AttrsRefresherJob(),
);
foreach ($cache as $cronjob)
if (!in_array($cronjob->get_type(), array('pre-request', 'cron-5')))
@ -537,13 +539,13 @@ class TileTreeUpdater extends Cron5Job
if (!$response['more'])
break;
} catch (BadRequest $e) {
# Invalid 'since' parameter? May happen whne crontab was
# Invalid 'since' parameter? May happen when crontab was
# not working for more than 10 days. Or, just after OKAPI
# is installed (and this is the first time this cronjob
# if being run).
$mail_admins = ($tiletree_revision > 0);
\okapi\services\caches\map\ReplicateListener::reset($mail_admins);
\okapi\services\caches\map\ReplicateListener::reset();
Okapi::set_var('clog_followup_revision', $current_clog_revision);
break;
}
@ -773,3 +775,17 @@ class LocaleChecker extends Cron5Job
}
}
/**
* Once every hour, update the official cache attributes listing.
*
* WRTODO: Make it 12 hours later.
*/
class AttrsRefresherJob extends Cron5Job
{
public function get_period() { return 3600; }
public function execute()
{
require_once($GLOBALS['rootpath']."okapi/services/attrs/attr_helper.inc.php");
AttrHelper::refresh_if_stale();
}
}

View File

@ -23,6 +23,7 @@ class OkapiServiceRunner
'services/apiref/method',
'services/apiref/method_index',
'services/apiref/issue',
'services/attrs/info',
'services/oauth/request_token',
'services/oauth/authorize',
'services/oauth/access_token',

View File

@ -0,0 +1,157 @@
<?php
namespace okapi\services\attrs;
use Exception;
use ErrorException;
use okapi\Okapi;
use okapi\Settings;
use okapi\Cache;
use okapi\OkapiRequest;
use okapi\ParamMissing;
use okapi\InvalidParam;
use okapi\OkapiServiceRunner;
use okapi\OkapiInternalRequest;
use SimpleXMLElement;
class AttrHelper
{
private static $CACHE_KEY = 'attrs/attrlist/1';
private static $attr_dict = null;
private static $last_refreshed = null;
/**
* Forces the download of the new attributes from Google Code.
*/
private static function refresh_now()
{
try
{
$opts = array(
'http' => array(
'method' => "GET",
'timeout' => 5.0
)
);
$context = stream_context_create($opts);
$xml = file_get_contents("http://opencaching-api.googlecode.com/svn/trunk/etc/attributes.xml",
false, $context);
}
catch (ErrorException $e)
{
# Google failed on us. We won't update the cached attributes.
return;
}
$my_site_url = "http://opencaching.pl/"; // WRTODO
$doc = simplexml_load_string($xml);
$cachedvalue = array(
'attr_dict' => array(),
'last_refreshed' => time(),
);
foreach ($doc->attr as $attrnode)
{
$attr = array(
'code' => (string)$attrnode['okapi_attr_id'],
'gs_equiv' => null,
'internal_id' => null,
'names' => array(),
'descriptions' => array()
);
foreach ($attrnode->groundspeak as $gsnode)
{
$attr['gs_equiv'] = array(
'id' => (int)$gsnode['id'],
'inc' => in_array((string)$gsnode['inc'], array("true", "1")) ? 1 : 0,
'name' => (string)$gsnode['name']
);
}
foreach ($attrnode->opencaching as $ocnode)
{
if ((string)$ocnode['site_url'] == $my_site_url) {
$attr['internal_id'] = (int)$ocnode['id'];
}
}
foreach ($attrnode->name as $namenode)
{
$attr['names'][(string)$namenode['lang']] = (string)$namenode;
}
foreach ($attrnode->desc as $descnode)
{
$xml = $descnode->asxml(); /* contains "<desc lang="...">" and "</desc>" */
$innerxml = preg_replace("/(^[^>]+>)|(<[^<]+$)/us", "", $xml);
$attr['descriptions'][(string)$descnode['lang']] = self::cleanup_string($innerxml);
}
$cachedvalue['attr_dict'][$attr['code']] = $attr;
}
# Cache it for a month (just in case, usually it will be refreshed every day).
Cache::set(self::$CACHE_KEY, $cachedvalue, 30*86400);
self::$attr_dict = $cachedvalue['attr_dict'];
self::$last_refreshed = $cachedvalue['last_refreshed'];
}
/**
* Initialize all the internal attributes (if not yet initialized). This
* loads attribute values from the cache. If they are not present in the cache,
* it won't download them from Google Code, it will initialize them as empty!
*/
private static function init_from_cache()
{
if (self::$attr_dict !== null)
{
/* Already initialized. */
return;
}
$cachedvalue = Cache::get(self::$CACHE_KEY);
if ($cachedvalue === null)
{
$cachedvalue = array(
'attr_dict' => array(),
'last_refreshed' => 0,
);
}
self::$attr_dict = $cachedvalue['attr_dict'];
self::$last_refreshed = $cachedvalue['last_refreshed'];
}
/**
* Check if the cached attribute values might be stale. If they were not
* refreshed in a while, perform the refresh from Google Code. (This might
* take a couple of seconds, it should be done via a cronjob.)
*/
public static function refresh_if_stale()
{
self::init_from_cache();
if (self::$last_refreshed < time() - 86400)
self::refresh_now();
if (self::$last_refreshed < time() - 3 * 86400)
{
Okapi::mail_admins(
"OKAPI was unable to refresh attributes",
"OKAPI periodically refreshes all cache attributes from the list\n".
"kept in global repository. OKAPI tried to contact the repository,\n".
"but it failed. Your list of attributes might be stale.\n\n".
"You should probably update OKAPI or contact OKAPI developers."
);
}
}
/**
* Return a dictionary of all attributes. The format is the same as in the "attributes"
* key returned by the "services/attrs/attrlist" method.
*/
public static function get_attrdict()
{
self::init_from_cache();
return self::$attr_dict;
}
/** "\n\t\tBla blabla\n\t\t<b>bla</b>bla.\n\t" => "Bla blabla <b>bla</b>bla." */
private static function cleanup_string($s)
{
return preg_replace('/(^\s+)|(\s+$)/us', "", preg_replace('/\s+/us', " ", $s));
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace okapi\services\attrs\info;
use Exception;
use ErrorException;
use okapi\Okapi;
use okapi\Settings;
use okapi\Cache;
use okapi\OkapiRequest;
use okapi\ParamMissing;
use okapi\InvalidParam;
use okapi\OkapiServiceRunner;
use okapi\OkapiInternalRequest;
use okapi\services\attrs\AttrHelper;
class WebService
{
public static function options()
{
return array(
'min_auth_level' => 1
);
}
public static function call(OkapiRequest $request)
{
# The list of attributes is periodically refreshed by contacting OKAPI
# repository (the refreshing is done via a cronjob). This method displays
# the cached version of the list.
require_once 'attr_helper.inc.php';
AttrHelper::refresh_if_stale();
$results = array(
'attributes' => AttrHelper::get_attrdict()
);
return Okapi::formatted_response($request, $results);
}
}

View File

@ -0,0 +1,12 @@
<xml>
<brief>ALPHA: Get the list of all cache attributes</brief>
<issue-id>194</issue-id>
<desc>
This method is in its ALPHA stage. It's signature will most probably change, or
it might be removed altogether. You should not use it!
</desc>
<common-format-params/>
<returns>
Not yet documented. You should not use this method.
</returns>
</xml>

View File

@ -45,24 +45,8 @@ class ReplicateListener
{
# This will be called when there are "too many" entries in the changelog
# and the replicate module thinks it better to just reset the entire TileTree.
# For the first hours after such reset maps may work very slow!
# For the first hours after such reset maps may work a little slower.
if ($mail_admins)
{
Okapi::mail_admins("OKAPI TileMap database reset",
"Hello,\n\n".
"OKAPI's 'replicate' module detected a big database update. As result\n".
"of this, OKAPI decided to reset the TileMap cache. This may\n".
"temporarily influence TileMap performance. The map may work much\n".
"slower during the next few hours or days, while the cache is being\n".
"rebuilt.\n\n".
"If this happens frequently, please contact OKAPI developers. It may\n".
"indicate a bug in OKAPI's 'replicate' module or cronjob settings.\n\n".
"Thanks!\n\n".
"P.S. This may also happen if you didn't run OKAPI on this server\n".
"for a while (your server was down or OKAPI didn't work properly)."
);
}
Db::execute("delete from okapi_tile_status");
Db::execute("delete from okapi_tile_caches");
}

View File

@ -46,6 +46,19 @@ class View
foreach ($langkeys as $langkey)
print " $langkey: ".$langs[$langkey]."\n";
}
foreach ($dict as $internal_id => $langs)
{
print "<attr okapi_attr_id=\"TODO\">\n";
print "\t<groundspeak id=\"TODO\" inc=\"TODO\" name=\"TODO\" />\n";
print "\t<opencaching site_url=\"SITEURLTODO\" id=\"$internal_id\" />\n";
$langkeys = array_keys($langs);
usort($langkeys, function($a, $b) {
return ($a == "en") ? -1 : (($a == $b) ? 0 : (($a < $b) ? -1 : 1));
});
foreach ($langkeys as $langkey)
print "\t<name lang=\"$langkey\">".$langs[$langkey]."</name>\n";
print "</attr>\n";
}
$response = new OkapiHttpResponse();
$response->content_type = "text/plain; charset=utf-8";