[
  {
    "lines": [
      "## Interface", 
      "", 
      "SignPuddle 3 organizes user interface elements into interface collections.", 
      "Interface collections are available in three different forms: database, plain text files, and JSON objects", 
      "", 
      "### Databases", 
      "", 
      "Each collection is available as an SQLite database.", 
      "These databases are the primary source and all edits are directly applied to the database.", 
      "", 
      "table entry", 
      "+ key", 
      "+ message", 
      "+ description", 
      "+ icon", 
      "+ user", 
      "+ created_at", 
      "+ updated_at", 
      "", 
      "### Plain Text Files", 
      "", 
      "Each collection is available as a plain text field where each entry occupies its own line.", 
      "Each entry contains multiple fields that are divided by tab characters.", 
      "The plain text files are designed for easy import and export from the databases.", 
      "", 
      "key /t message /t description /t icon /t user /t created_at /t updated_at", 
      "", 
      "### JSON Data files", 
      "", 
      "The interface JSON data file is an object.", 
      "Each key contains an object with three properties: message, description, icon, and updated_at.", 
      "", 
      "{", 
      "  \"name\": \"en-US-interface-sp3\",", 
      "  \"data\": {", 
      "    \"key.example.one\": {", 
      "      \"message\": \"example message\",", 
      "      \"description\": \"example description\",", 
      "      \"icon\": \"example\",", 
      "      \"updated_at\": \"date-time\"", 
      "    }", 
      "  }", 
      "}", 
      ""
    ], 
    "host": "https://signpuddle.com/server", 
    "meta": "Generated from ApiTxt format (output/interface.txt) using txt2json.py", 
    "root": "interface", 
    "title": "SignPuddle 3 Interface API"
  }, 
  {
    "lines": [
      "+ Source: [ApiTxt format](../src/interface.txt) and [JSON objects](../src/interface.json)", 
      "+ Documents: [API Blueprint](../doc/interface.md) and [Stand Alone HTML](../doc/interface.htm)", 
      "+ Live Page: [API Interface](../api/interface.html) and [JavaScript](../api/interface.js)"
    ], 
    "group": "interface", 
    "description": "Resources related to interface collections"
  }, 
  {
    "route": "/interface{?name}", 
    "name": "Interfaces available", 
    "parameters": [
      {
        "description": "partial interface name", 
        "type": "string", 
        "name": "name", 
        "example": "sp3"
      }
    ]
  }, 
  {
    "code": [
      "$dir = 'data/db/';", 
      "$ext = '.db';", 
      "$out = [];", 
      "if ($name){", 
      "  if (strpos($name,\"interface\")!==false){", 
      "    $interfaces = $dir . '*' . $name . '*' . $ext;", 
      "    $files = glob($interfaces);", 
      "  } else {", 
      "    $interfaces = $dir . '*interface*' . $name . '*' . $ext;", 
      "    $files = glob($interfaces);", 
      "    if (count($files)==0) {", 
      "      $interfaces = $dir . '*' . $name . '*interface*' . $ext;", 
      "      $files = glob($interfaces);", 
      "    }", 
      "  }", 
      "} else {", 
      "  $interfaces = $dir . '*interface*' . $ext;", 
      "  $files = glob($interfaces);", 
      "}", 
      "foreach ($files as $filename) {", 
      "  $out[] = str_replace($ext,'',str_replace($dir,'',$filename));", 
      "}", 
      "if (count($out)){", 
      "  echo json_pretty($out);", 
      "} else {", 
      "  $app->response->setStatus(204);", 
      "}", 
      "return;"
    ], 
    "method": "GET", 
    "dialog": [
      {
        "responses": [
          {
            "status": 200, 
            "body": [
              "[\"en-US-interface-sp3\"]"
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "Get available interfaces"
  }, 
  {
    "route": "/interface/{name}{?update}", 
    "name": "Interface resource", 
    "parameters": [
      {
        "description": "The name of an interface", 
        "type": "required,string", 
        "name": "name", 
        "example": "`en-US-interface-sp3`"
      }, 
      {
        "description": "Forces a rewrite of the interface for json and txt formats", 
        "type": "optional,number", 
        "name": "update", 
        "example": "1"
      }
    ], 
    "description": "Access to available interfaces"
  }, 
  {
    "code": [
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "rightsCheck($name,$pass,SP_VIEW);", 
      "$check = isset($headers['If-Modified-Since'])?$headers['If-Modified-Since']:'';", 
      "if (strpos($name,'.')){", 
      "  $parts = explode('.',$name);", 
      "  $name = $parts[0];", 
      "  $format = $parts[1];", 
      "  if (!in_array($format,['db','txt','json'])){", 
      "    haltNotFound();", 
      "  }", 
      "} else {", 
      "  $format = 'json';", 
      "}", 
      "$dir = 'data/' . $format . '/';", 
      "$ext = '.' . $format;", 
      "$file = $dir . $name . $ext;", 
      "$err = invalidName($name);", 
      "if ($err){", 
      "  $files = glob('data/db/' . $name . '*interface-sp3.db');", 
      "  if (count($files)==0){", 
      "    haltBadRequest($err);", 
      "  } else {", 
      "\t$name = str_replace(\".db\",'',str_replace('data/db/','',$files[0]));", 
      "  }", 
      "}", 
      "$lastModified = lastModified($name);", 
      "if ($lastModified <= $check  && !$update){", 
      "  haltNotModified();", 
      "}", 
      "if ($format=='json' && (!file_exists($file) || $update)) {", 
      "  $json = interface2json($name);", 
      "  file_put_contents($file,$json);", 
      "} else if ($format=='txt' && (!file_exists($file) || $update)) {", 
      "  $txt = interface2txt($name);", 
      "  file_put_contents($file,$txt);", 
      "}", 
      "if(file_exists($file)) {", 
      "  header('Last-Modified: ' . $lastModified);", 
      "  $searchTime = searchtime($timein);", 
      "  header(\"Search-Time: \" . $searchTime);", 
      "  getFile($file);", 
      "} else {", 
      "  haltNotFound();", 
      "}"
    ], 
    "method": "GET", 
    "dialog": [
      {
        "request": {
          "headers": {
            "If-Modified-Since": "2019-01-16T16:56:19.175Z"
          }, 
          "name": "interface text"
        }, 
        "responses": [
          {
            "status": 200, 
            "body": [
              "print.buttons.main\tmessage\tdescription\ticon"
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "retrieve interface"
  }, 
  {
    "route": "/interface/{name}/key", 
    "name": "Interface keys", 
    "parameters": [
      {
        "description": "The name of an interface", 
        "type": "required,string", 
        "name": "name", 
        "example": "`en-US-interface-sp3`"
      }
    ], 
    "description": "Access to interface keys"
  }, 
  {
    "code": [
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "$check = isset($headers['If-Modified-Since'])?$headers['If-Modified-Since']:'';", 
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "$lastModified = lastModified($name);", 
      "if ($lastModified <= $check){", 
      "  haltNotModified();", 
      "}", 
      "header('Last-Modified: ' . $lastModified);", 
      "echo json_pretty(interfaceKeys($name,$pass));"
    ], 
    "method": "GET", 
    "dialog": [
      {
        "request": {
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9", 
            "If-Modified-Since": "2019-01-16T16:56:19.175Z"
          }, 
          "name": "interface keys"
        }, 
        "responses": [
          {
            "status": 200, 
            "body": [
              "[\"print.buttons.main\"]"
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "retrieve interface keys"
  }, 
  {
    "route": "/interface/{name}/search/{text}", 
    "name": "Interface entries search", 
    "parameters": [
      {
        "description": "The name of an interface", 
        "type": "required,string", 
        "name": "name", 
        "example": "`en-US-interface-sp3`"
      }, 
      {
        "description": "The text for searching", 
        "type": "required,string", 
        "name": "text", 
        "example": "`SignPuddle`"
      }
    ], 
    "description": "Search interface for text"
  }, 
  {
    "code": [
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "echo json_pretty(interfaceSearch($name,$text,$pass));"
    ], 
    "method": "GET", 
    "dialog": [
      {
        "request": {
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9"
          }, 
          "name": "matching interface entries"
        }, 
        "responses": [
          {
            "status": 200, 
            "body": [
              "[", 
              "  {", 
              "    \"key\": \"print.buttons.main\",", 
              "    \"message\": \"Print it!\"", 
              "  }", 
              "]"
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "retrieve matching entries"
  }, 
  {
    "route": "/interface/{name}/entry", 
    "name": "Interface entry resource", 
    "parameters": [
      {
        "description": "The name of an interface", 
        "type": "string", 
        "name": "name", 
        "example": "`en-US-interface-sp3`"
      }
    ], 
    "description": "Entries for interface"
  }, 
  {
    "code": [
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "if (!$pass){", 
      "  haltForbidden();", 
      "}", 
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "$data = $app->request->getbody();", 
      "$data = json_decode($data,true);", 
      "interfaceEntryNew($name,$data,$pass);", 
      "$app->response->setStatus(201);", 
      "return;"
    ], 
    "method": "POST", 
    "dialog": [
      {
        "request": {
          "body": [
            "{\"key\":\"new.key.one\", \"message\":\"UI text\",\"description\":\"about the text\",\"icon\":\"search\"}"
          ], 
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9"
          }, 
          "type": "application/json", 
          "name": "add new interface entry"
        }, 
        "responses": [
          {
            "status": 201, 
            "body": [
              "..."
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "add interface entry"
  }, 
  {
    "route": "/interface/{name}/entry/{key}", 
    "name": "Interface entry resource for key", 
    "parameters": [
      {
        "description": "The name of an interface", 
        "type": "string", 
        "name": "name", 
        "example": "`en-US-interface-sp3`"
      }, 
      {
        "description": "The name of an interface key", 
        "type": "string", 
        "name": "key", 
        "example": "system.button.open"
      }
    ], 
    "description": "Specific entries for interface"
  }, 
  {
    "code": [
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "$check = isset($headers['If-Modified-Since'])?$headers['If-Modified-Since']:'';", 
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "$entries = interfaceKeySearch($name,$key,$pass);", 
      "if (!$entries){", 
      "  haltNoContent();", 
      "}", 
      "$lastModified = max(array_map(function($o) {return $o->updated_at;},$entries));", 
      "if ($lastModified <= $check){", 
      "  haltNotModified();", 
      "}", 
      "header('Last-Modified: ' . $lastModified);", 
      "echo json_pretty($entries);"
    ], 
    "method": "GET", 
    "dialog": [
      {
        "request": {
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9", 
            "If-Modified-Since": "2019-01-16T16:56:19.175Z"
          }, 
          "name": "an interface entry"
        }, 
        "responses": [
          {
            "status": 200, 
            "body": [
              "..."
            ], 
            "type": "text/plain"
          }
        ]
      }
    ], 
    "name": "retrieve interface entry"
  }, 
  {
    "code": [
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "$data = $app->request->getbody();", 
      "$data = json_decode($data,true);", 
      "interfaceEntryUpdate($name,$key,$data,$pass);", 
      "$app->response->setStatus(204);", 
      "return;"
    ], 
    "method": "PUT", 
    "dialog": [
      {
        "request": {
          "body": [
            "{\"key\":\"new.key.one\", \"message\":\"UI text\",\"description\":\"about the text\",\"icon\":\"search\"}"
          ], 
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9"
          }, 
          "name": "an update for an existing entry"
        }, 
        "responses": [
          {
            "status": 204
          }
        ]
      }
    ], 
    "name": "update interface entry"
  }, 
  {
    "code": [
      "$err = invalidName($name);", 
      "if ($err){", 
      "  haltBadRequest($err);", 
      "}", 
      "$headers = getHeaders();", 
      "$pass = isset($headers['Pass'])?$headers['Pass']:'';", 
      "interfaceEntryDelete($name,$key,$pass);", 
      "$app->response->setStatus(204);"
    ], 
    "method": "DELETE", 
    "dialog": [
      {
        "request": {
          "headers": {
            "Pass": "724fd4b4438fba9d0c5ab89d0833e5c9"
          }, 
          "name": "the removal of an interface entry"
        }, 
        "responses": [
          {
            "status": 204
          }
        ]
      }
    ], 
    "name": "remove interface entry"
  }
]
