Skip to content

Commit

Permalink
issue opencaching#601 upload fieldnotes
Browse files Browse the repository at this point in the history
  • Loading branch information
hxdimpf committed Nov 25, 2023
1 parent 0462c38 commit 17ebf73
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 0 deletions.
170 changes: 170 additions & 0 deletions okapi/services/fieldnotes/upload/WebService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php

namespace okapi\services\fieldnotes\upload;

use okapi\core\Exception\InvalidParam;
use okapi\core\Exception\ParamMissing;
use okapi\core\Db;
use okapi\core\Okapi;
use okapi\core\OkapiServiceRunner;
use okapi\core\Request\OkapiInternalRequest;
use okapi\core\Request\OkapiRequest;
use okapi\services\logs\LogsCommon;
use okapi\Settings;

class WebService
{
public static function options()
{
return array(
'min_auth_level' => 3
);
}

public static function call(OkapiRequest $request)
{
$result = array(
'success' => false // if the installation doesn't support it
);

if (Settings::get('OC_BRANCH') == 'oc.de')
{

$field_notes = $request->get_parameter('field_notes');
if (!$field_notes) throw new ParamMissing('field_notes');

$result = Okapi::get_submittable_logtype_names();
$result = json_encode($result, JSON_PRETTY_PRINT); // debug
return Okapi::formatted_response($request, $result);

$notes = self::parse_notes($field_notes);
if ($notes === false) throw new InvalidParam('field_notes', "Input data not recognized.");

foreach ($notes as $n)
{
$geocache = OkapiServiceRunner::call(
'services/caches/geocache',
new OkapiInternalRequest($request->consumer, $request->token, array(
'cache_code' => $n['code'],
'fields' => 'internal_id'
))
);
$user_id = $request->token->user_id;
$geocache_id = $geocache['internal_id'];
$type = Okapi::logtypename2id($n['type']);
$date = date("Y-m-d H:i:s", strtotime($n['date']));
$text = $n['log'];

Db::query("
insert into field_note (
user_id, geocache_id, type, date, text
) values (
'".Db::escape_string($user_id)."',
'".Db::escape_string($geocache_id)."',
'".Db::escape_string($type)."',
'".Db::escape_string($date)."',
'".Db::escape_string($text)."'
)
");

}
$result = array(
'success' => true
);
//$result = json_encode($notes, JSON_PRETTY_PRINT); // debug
}
return Okapi::formatted_response($request, $result);
}

// ------------------------------------------------------------------

private static function parse_notes($field_notes)
{
$decoded_field_notes = base64_decode($field_notes, true);
if ($decoded_field_notes === false) return false;

$multiline = self::fieldNotesTxtArea2Array($decoded_field_notes);

$parsed_records = [];

foreach ($multiline as $line) {
$line = trim($line);
$fields = self::CSVtoArray($line);

$code = $fields[0];
$date = $fields[1];
$type = $fields[2];
$log = nl2br($fields[3]);

$parsed_records[] = [
'code' => $code,
'date' => $date,
'type' => $type,
'log' => $log,
];
}
return $parsed_records;
}


// ------------------------------------------------------------------

private static function fieldNotesTxtArea2Array($fieldnotes)
{
$output = [];
$buffer = '';
$start = true;

$lines = explode("\n", $fieldnotes);
$lines = array_filter($lines); // Drop empty lines

foreach ($lines as $line) {
if ($start) {
$buffer = $line;
$start = false;
} else {
if (strpos($line, 'OC') !== 0) {
$buffer .= "\n" . $line;
} else {
$output[] = trim($buffer);
$buffer = $line;
}
}
}

if (!$start) {
$output[] = trim($buffer);
}

return $output;
}

// ------------------------------------------------------------------

private static function CSVtoArray($text)
{
$ret = [''];
$i = 0;
$p = '';
$s = true;

foreach (str_split($text) as $l) {
if ('"' === $l) {
$s = !$s;
if ('"' === $p) {
$ret[$i] .= '"';
$l = '-';
} elseif ('' === $p) {
$l = '-';
}
} elseif ($s && ',' === $l) {
$l = $ret[++$i] = '';
} else {
$ret[$i] .= $l;
}
$p = $l;
}

return $ret;
}
}
47 changes: 47 additions & 0 deletions okapi/services/fieldnotes/upload/docs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<xml>
<brief>Upload Fieldnotes</brief>
<issue-id>630</issue-id>
<desc>
<p>Upload a set of one or more fieldnotes records.</p>
</desc>
<req name='field_notes'>
<p>Fieldnotes consist of one or more records in CSV format. Each
record comprises a geocache log consisting of four fields:</p>
<ul>
<li>Geocache Code</li>
<li>Date</li>
<li>Log Type</li>
<li>Log Text</li>
</ul>
<p>The first three fields are simple entities, the Log Text field is
different and a bit difficult as it may spread over muliple lines
and it may contain quote characters. In order to preserve the structure
of the records, the <i>field_notes</i> parameter must be passed as a
<b>base64 encoded utf8 string</b>. UTF-16LE, UTF-16BE with or without
BOM are not supported.
</p>
<p>Since the log type is passed as a string, its value must match the
values supported by the platform (case sensitive!):
<pre>
[
"Found it",
"Didn't find it",
"Comment",
"Attended",
"Will attend",
"Archived",
"Ready to search",
"Temporarily unavailable"
]
</pre>
</p>
<p>Note: This service method is not supported on all installations</p>
</req>
<common-format-params/>
<returns>
<p>A dictionary of the following structure:</p>
<ul>
<li>success - true</li>
</ul>
</returns>
</xml>

0 comments on commit 17ebf73

Please sign in to comment.