| <?php |
| require_once("config.php"); |
| |
| class write { |
| public static function do($json) { |
| echo json_encode($json)."\n"; |
| exit(); |
| } |
| } |
| |
| class conv { |
| public static function ask($msg_array) { |
| $items = array(); |
| |
| foreach ($msg_array as $msg) { |
| $items[] = array("simpleResponse" => array("textToSpeech" => $msg)); |
| } |
| |
| self::ask_custom($items); |
| } |
| |
| public static function ask_followup($msg, &$i18n) { |
| self::ask([$msg, $i18n->msg("followup_".mt_rand(1, 3))]); |
| } |
| |
| public static function ask_custom($items) { |
| $json = array(); |
| $json["payload"] = array(); |
| $json["payload"]["google"] = array(); |
| $json["payload"]["google"]["expectUserResponse"] = true; |
| $json["payload"]["google"]["richResponse"] = array(); |
| $json["payload"]["google"]["richResponse"]["items"] = $items; |
| |
| write::do($json); |
| } |
| |
| public static function has($item, &$json) { |
| foreach ($json["originalDetectIntentRequest"]["payload"]["surface"]["capabilities"] as $cap) { |
| if ($cap["name"] == $item) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| |
| class i18n { |
| public static $hllist = array("en", "es"); |
| public $i18n_strings = null; |
| public $language = null; |
| |
| function __construct($lang) { |
| global $_GET; |
| global $conf; |
| |
| if (empty($this->i18n_strings)) { |
| $this->i18n_strings = array(); |
| } |
| |
| $this->language = $lang; |
| |
| $this->i18n_strings = json_decode(file_get_contents("assistant/".$this->language.".json"), true); |
| |
| return true; |
| } |
| |
| function msg($message, $strings = null) { |
| if (!isset($this->i18n_strings[$message])) { |
| return false; |
| } |
| |
| $string = $this->i18n_strings[$message]; |
| |
| if ($strings != null && is_array($strings)) { |
| foreach ($strings as $i => $subst) { |
| $string = str_replace("{".$i."}", $subst, $string); |
| } |
| } |
| |
| return $string; |
| } |
| } |
| |
| function get_graph() { |
| global $conf; |
| return json_decode(file_get_contents($conf["apiurl"]), true); |
| } |
| |
| function comma($array, $wait=false) { |
| global $i18n; |
| if (count($array) == 0) { |
| return ""; |
| } |
| if (count($array) == 1) { |
| return $array[0]; |
| } |
| $break = ($wait ? '<break time="0.5s"/>' : ""); |
| return implode($break.", ", array_slice($array, 0, -1)).$break.", ".$i18n->msg("and")." ".$array[count($array)-1]; |
| } |
| |
| $json = json_decode(file_get_contents('php://input'), true); |
| |
| if ($json === NULL || !isset($json["originalDetectIntentRequest"]) || !isset($json["originalDetectIntentRequest"]["source"]) || $json["originalDetectIntentRequest"]["source"] != "google") { |
| exit(); |
| } |
| |
| $graph = get_graph(); |
| $lang = (isset($json["queryResult"]["languageCode"]) && in_array(substr($json["queryResult"]["languageCode"], 0, 2), i18n::$hllist) ? substr($json["queryResult"]["languageCode"], 0, 2) : "en"); |
| $i18n = new i18n($lang); |
| |
| switch ($json["queryResult"]["intent"]["displayName"]) { |
| case "showVertex": |
| if (!isset($json["queryResult"]["parameters"]["Vertex"])) { |
| exit(); |
| } |
| |
| $shortest = -1; |
| $closest = -1; |
| $closest_id = -1; |
| |
| foreach ($graph["nodes"] as $id => $node) { |
| $lev = levenshtein(strtolower($json["queryResult"]["parameters"]["Vertex"]), strtolower($node["name"])); |
| |
| if ($lev == 0) { |
| $closest = $node["name"]; |
| $shortest = $lev; |
| $closest_id = $id; |
| } |
| |
| if (($lev <= $shortest || $shortest < 0) && $lev <= 3) { |
| $closest = $node["name"]; |
| $shortest = $lev; |
| $closest_id = $id; |
| } |
| } |
| |
| if ($shortest != -1) { |
| $neighbors = array(); |
| // We're suposing each vertex has a different name. If not, this would get rid of some of the edges, but if two vertexs had the same name there would be no way to differentiate them anyway, so I think it's ok. |
| foreach ($graph["edges"] as $edge) { |
| if ($edge["a"] == $closest_id) { |
| $neighbors[$graph["nodes"][$edge["b"]]["name"]] = $edge["votes"]; |
| } elseif ($edge["b"] == $closest_id) { |
| $neighbors[$graph["nodes"][$edge["a"]]["name"]] = $edge["votes"]; |
| } |
| } |
| if (count($neighbors) == 0) { |
| conv::ask_followup($i18n->msg("new_to_graph", array("person" => $closest)), $i18n); |
| } else { |
| arsort($neighbors); |
| $params = array("person" => $closest, "count" => (count($neighbors) == 1 ? $i18n->msg("count_singular") : $i18n->msg("count_plural", array("count" => count($neighbors))))); |
| if (conv::has("actions.capability.SCREEN_OUTPUT", $json)) { |
| $items = [ |
| array( |
| "simpleResponse" => array( |
| "textToSpeech" => $i18n->msg("edges_display", $params) |
| ) |
| ), |
| array( |
| "tableCard" => array( |
| "columnProperties" => [ |
| array( |
| "header" => "Adjacent vertex" |
| ), |
| array("header" => "Votes") |
| ], |
| "rows" => [] |
| ) |
| ), |
| array( |
| "simpleResponse" => array( |
| "textToSpeech" => $i18n->msg("followup_".mt_rand(1, 3)) |
| ) |
| ) |
| ]; |
| foreach ($neighbors as $neighbor => $votes) { |
| $items[1]["tableCard"]["rows"][] = array("cells" => [array("text" => $neighbor), array("text" => (string)$votes)]); |
| } |
| conv::ask_custom($items); |
| } else { // This code shows a table if the user has a screen, and |
| // as of now tables are finally public! |
| $people = array_keys($neighbors); |
| $people_string = comma($people); |
| $params["edges"] = $people_string; |
| $num = mt_rand(1, 3); |
| conv::ask_followup($i18n->msg("edges_".$num, $params), $i18n); |
| } |
| } |
| } else { |
| conv::ask_followup($i18n->msg("not_found", array("person" => $json["queryResult"]["parameters"]["Vertex"])), $i18n); |
| } |
| break; |
| |
| case "randomFact": |
| $rand = mt_rand(0, 5); |
| switch ($rand) { |
| case 0: // Last edge in the graph |
| $last = array_values(array_slice($graph["edges"], -1))[0]; |
| conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_last_edge", array("person1" => $graph["nodes"][$last["a"]]["name"], "person2" => $graph["nodes"][$last["b"]]["name"])))), $i18n); |
| break; |
| |
| case 1: // Num vertices |
| conv::ask_followup($i18n->msg("didyouknow_num_vertices", array("count" => count($graph["nodes"]))), $i18n); |
| break; |
| |
| case 2: // Num edges |
| conv::ask_followup($i18n->msg("didyouknow_num_edges", array("count" => count($graph["edges"]))), $i18n); |
| break; |
| |
| case 3: // First 3 vertices K3 |
| conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_k3"))), $i18n); |
| break; |
| |
| case 4: // Creator |
| conv::ask_followup($i18n->msg("didyouknow_creator"), $i18n); |
| break; |
| |
| case 5: // Groph |
| conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_groph"))), $i18n); |
| break; |
| } |
| |
| break; |
| |
| case "numVertexs": |
| conv::ask_followup($i18n->msg("num_vertices", array("count" => count($graph["nodes"]))), $i18n); |
| break; |
| |
| case "numEdges": |
| conv::ask_followup($i18n->msg("num_edges", array("count" => count($graph["edges"]))), $i18n); |
| break; |
| |
| case "latestNews": |
| $param = (isset($json["queryResult"]["parameters"]["numEdges"]) ? $json["queryResult"]["parameters"]["numEdges"] : null); |
| $num = (isset($param) && !empty($param) ? (int)$param : 4); |
| $last = array_values(array_slice($graph["edges"], -$num)); |
| $edges = []; |
| foreach ($last as $edge) { |
| $edges[] = $graph["nodes"][$edge["a"]]["name"]." - ".$graph["nodes"][$edge["b"]]["name"]; |
| } |
| $edges_string = comma($edges, true); |
| conv::ask_followup($i18n->msg((isset($param) && !empty($param) ? "latest_news_count" : "latest_news"), array("edges" => $edges_string, "count" => $num)), $i18n); |
| break; |
| |
| default: |
| exit(); |
| } |