okapi r594
This commit is contained in:
@ -778,7 +778,7 @@ class Okapi
|
|||||||
{
|
{
|
||||||
public static $data_store;
|
public static $data_store;
|
||||||
public static $server;
|
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;
|
private static $okapi_vars = null;
|
||||||
|
|
||||||
/** Get a variable stored in okapi_vars. If variable not found, return $default. */
|
/** 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\OkapiInternalRequest;
|
||||||
use okapi\OkapiInternalConsumer;
|
use okapi\OkapiInternalConsumer;
|
||||||
use okapi\services\replicate\ReplicateCommon;
|
use okapi\services\replicate\ReplicateCommon;
|
||||||
|
use okapi\services\attrs\AttrHelper;
|
||||||
|
|
||||||
class CronJobController
|
class CronJobController
|
||||||
{
|
{
|
||||||
@ -50,6 +51,7 @@ class CronJobController
|
|||||||
new FulldumpGeneratorJob(),
|
new FulldumpGeneratorJob(),
|
||||||
new TileTreeUpdater(),
|
new TileTreeUpdater(),
|
||||||
new SearchSetsCleanerJob(),
|
new SearchSetsCleanerJob(),
|
||||||
|
new AttrsRefresherJob(),
|
||||||
);
|
);
|
||||||
foreach ($cache as $cronjob)
|
foreach ($cache as $cronjob)
|
||||||
if (!in_array($cronjob->get_type(), array('pre-request', 'cron-5')))
|
if (!in_array($cronjob->get_type(), array('pre-request', 'cron-5')))
|
||||||
@ -537,13 +539,13 @@ class TileTreeUpdater extends Cron5Job
|
|||||||
if (!$response['more'])
|
if (!$response['more'])
|
||||||
break;
|
break;
|
||||||
} catch (BadRequest $e) {
|
} 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
|
# not working for more than 10 days. Or, just after OKAPI
|
||||||
# is installed (and this is the first time this cronjob
|
# is installed (and this is the first time this cronjob
|
||||||
# if being run).
|
# if being run).
|
||||||
|
|
||||||
$mail_admins = ($tiletree_revision > 0);
|
$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);
|
Okapi::set_var('clog_followup_revision', $current_clog_revision);
|
||||||
break;
|
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',
|
||||||
'services/apiref/method_index',
|
'services/apiref/method_index',
|
||||||
'services/apiref/issue',
|
'services/apiref/issue',
|
||||||
|
'services/attrs/info',
|
||||||
'services/oauth/request_token',
|
'services/oauth/request_token',
|
||||||
'services/oauth/authorize',
|
'services/oauth/authorize',
|
||||||
'services/oauth/access_token',
|
'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
|
# 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.
|
# 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_status");
|
||||||
Db::execute("delete from okapi_tile_caches");
|
Db::execute("delete from okapi_tile_caches");
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,19 @@ class View
|
|||||||
foreach ($langkeys as $langkey)
|
foreach ($langkeys as $langkey)
|
||||||
print " $langkey: ".$langs[$langkey]."\n";
|
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 = new OkapiHttpResponse();
|
||||||
$response->content_type = "text/plain; charset=utf-8";
|
$response->content_type = "text/plain; charset=utf-8";
|
||||||
|
Reference in New Issue
Block a user