okapi r594
This commit is contained in:
@ -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. */
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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',
|
||||
|
157
htdocs/okapi/services/attrs/attr_helper.inc.php
Normal file
157
htdocs/okapi/services/attrs/attr_helper.inc.php
Normal 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));
|
||||
}
|
||||
}
|
40
htdocs/okapi/services/attrs/info.php
Normal file
40
htdocs/okapi/services/attrs/info.php
Normal 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);
|
||||
}
|
||||
}
|
12
htdocs/okapi/services/attrs/info.xml
Normal file
12
htdocs/okapi/services/attrs/info.xml
Normal 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>
|
@ -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");
|
||||
}
|
||||
|
@ -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";
|
||||
|
Reference in New Issue
Block a user