Javier López-Contreras | 6d1d72d | 2018-12-27 23:17:18 +0100 | [diff] [blame] | 1 | <?php
|
| 2 | require_once("config.php");
|
| 3 |
|
| 4 | class write {
|
| 5 | public static function do($json) {
|
| 6 | echo json_encode($json)."\n";
|
| 7 | exit();
|
| 8 | }
|
| 9 | }
|
| 10 |
|
| 11 | class conv {
|
| 12 | public static function ask($msg_array) {
|
| 13 | $items = array();
|
| 14 |
|
| 15 | foreach ($msg_array as $msg) {
|
| 16 | $items[] = array("simpleResponse" => array("textToSpeech" => $msg));
|
| 17 | }
|
| 18 |
|
| 19 | self::ask_custom($items);
|
| 20 | }
|
| 21 |
|
| 22 | public static function ask_followup($msg, &$i18n) {
|
| 23 | self::ask([$msg, $i18n->msg("followup_".mt_rand(1, 3))]);
|
| 24 | }
|
| 25 |
|
| 26 | public static function ask_custom($items) {
|
| 27 | $json = array();
|
| 28 | $json["payload"] = array();
|
| 29 | $json["payload"]["google"] = array();
|
| 30 | $json["payload"]["google"]["expectUserResponse"] = true;
|
| 31 | $json["payload"]["google"]["richResponse"] = array();
|
| 32 | $json["payload"]["google"]["richResponse"]["items"] = $items;
|
| 33 |
|
| 34 | write::do($json);
|
| 35 | }
|
| 36 |
|
| 37 | public static function has($item, &$json) {
|
| 38 | foreach ($json["originalDetectIntentRequest"]["payload"]["surface"]["capabilities"] as $cap) {
|
| 39 | if ($cap["name"] == $item) {
|
| 40 | return true;
|
| 41 | }
|
| 42 | }
|
| 43 | return false;
|
| 44 | }
|
| 45 | }
|
| 46 |
|
| 47 | class i18n {
|
| 48 | public static $hllist = array("en", "es");
|
| 49 | public $i18n_strings = null;
|
| 50 | public $language = null;
|
| 51 |
|
| 52 | function __construct($lang) {
|
| 53 | global $_GET;
|
| 54 | global $conf;
|
| 55 |
|
| 56 | if (empty($this->i18n_strings)) {
|
| 57 | $this->i18n_strings = array();
|
| 58 | }
|
| 59 |
|
| 60 | $this->language = $lang;
|
| 61 |
|
| 62 | $this->i18n_strings = json_decode(file_get_contents("assistant/".$this->language.".json"), true);
|
| 63 |
|
| 64 | return true;
|
| 65 | }
|
| 66 |
|
| 67 | function msg($message, $strings = null) {
|
| 68 | if (!isset($this->i18n_strings[$message])) {
|
| 69 | return false;
|
| 70 | }
|
| 71 |
|
| 72 | $string = $this->i18n_strings[$message];
|
| 73 |
|
| 74 | if ($strings != null && is_array($strings)) {
|
| 75 | foreach ($strings as $i => $subst) {
|
| 76 | $string = str_replace("{".$i."}", $subst, $string);
|
| 77 | }
|
| 78 | }
|
| 79 |
|
| 80 | return $string;
|
| 81 | }
|
| 82 | }
|
| 83 |
|
| 84 | function get_graph() {
|
| 85 | global $conf;
|
| 86 | return json_decode(file_get_contents($conf["apiurl"]), true);
|
| 87 | }
|
| 88 |
|
| 89 | function comma($array, $wait=false) {
|
| 90 | global $i18n;
|
| 91 | if (count($array) == 0) {
|
| 92 | return "";
|
| 93 | }
|
| 94 | if (count($array) == 1) {
|
| 95 | return $array[0];
|
| 96 | }
|
| 97 | $break = ($wait ? '<break time="0.5s"/>' : "");
|
| 98 | return implode($break.", ", array_slice($array, 0, -1)).$break.", ".$i18n->msg("and")." ".$array[count($array)-1];
|
| 99 | }
|
| 100 |
|
| 101 | $json = json_decode(file_get_contents('php://input'), true);
|
| 102 |
|
| 103 | if ($json === NULL || !isset($json["originalDetectIntentRequest"]) || !isset($json["originalDetectIntentRequest"]["source"]) || $json["originalDetectIntentRequest"]["source"] != "google") {
|
| 104 | exit();
|
| 105 | }
|
| 106 |
|
| 107 | $graph = get_graph();
|
| 108 | $lang = (isset($json["queryResult"]["languageCode"]) && in_array(substr($json["queryResult"]["languageCode"], 0, 2), i18n::$hllist) ? substr($json["queryResult"]["languageCode"], 0, 2) : "en");
|
| 109 | $i18n = new i18n($lang);
|
| 110 |
|
| 111 | switch ($json["queryResult"]["intent"]["displayName"]) {
|
| 112 | case "showVertex":
|
| 113 | if (!isset($json["queryResult"]["parameters"]["Vertex"])) {
|
| 114 | exit();
|
| 115 | }
|
| 116 |
|
| 117 | $shortest = -1;
|
| 118 | $closest = -1;
|
| 119 | $closest_id = -1;
|
| 120 |
|
| 121 | foreach ($graph["nodes"] as $id => $node) {
|
| 122 | $lev = levenshtein(strtolower($json["queryResult"]["parameters"]["Vertex"]), strtolower($node["name"]));
|
| 123 |
|
| 124 | if ($lev == 0) {
|
| 125 | $closest = $node["name"];
|
| 126 | $shortest = $lev;
|
| 127 | $closest_id = $id;
|
| 128 | }
|
| 129 |
|
| 130 | if (($lev <= $shortest || $shortest < 0) && $lev <= 3) {
|
| 131 | $closest = $node["name"];
|
| 132 | $shortest = $lev;
|
| 133 | $closest_id = $id;
|
| 134 | }
|
| 135 | }
|
| 136 |
|
| 137 | if ($shortest != -1) {
|
| 138 | $neighbors = array();
|
| 139 | // 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.
|
| 140 | foreach ($graph["edges"] as $edge) {
|
| 141 | if ($edge["a"] == $closest_id) {
|
| 142 | $neighbors[$graph["nodes"][$edge["b"]]["name"]] = $edge["votes"];
|
| 143 | } elseif ($edge["b"] == $closest_id) {
|
| 144 | $neighbors[$graph["nodes"][$edge["a"]]["name"]] = $edge["votes"];
|
| 145 | }
|
| 146 | }
|
| 147 | if (count($neighbors) == 0) {
|
| 148 | conv::ask_followup($i18n->msg("new_to_graph", array("person" => $closest)), $i18n);
|
| 149 | } else {
|
| 150 | arsort($neighbors);
|
| 151 | $params = array("person" => $closest, "count" => (count($neighbors) == 1 ? $i18n->msg("count_singular") : $i18n->msg("count_plural", array("count" => count($neighbors)))));
|
avm99963 | 7797f62 | 2020-07-01 18:25:40 +0200 | [diff] [blame] | 152 | if (conv::has("actions.capability.SCREEN_OUTPUT", $json)) {
|
Javier López-Contreras | 6d1d72d | 2018-12-27 23:17:18 +0100 | [diff] [blame] | 153 | $items = [
|
| 154 | array(
|
| 155 | "simpleResponse" => array(
|
| 156 | "textToSpeech" => $i18n->msg("edges_display", $params)
|
| 157 | )
|
| 158 | ),
|
| 159 | array(
|
| 160 | "tableCard" => array(
|
| 161 | "columnProperties" => [
|
| 162 | array(
|
| 163 | "header" => "Adjacent vertex"
|
| 164 | ),
|
| 165 | array("header" => "Votes")
|
| 166 | ],
|
| 167 | "rows" => []
|
| 168 | )
|
| 169 | ),
|
| 170 | array(
|
| 171 | "simpleResponse" => array(
|
| 172 | "textToSpeech" => $i18n->msg("followup_".mt_rand(1, 3))
|
| 173 | )
|
| 174 | )
|
| 175 | ];
|
| 176 | foreach ($neighbors as $neighbor => $votes) {
|
| 177 | $items[1]["tableCard"]["rows"][] = array("cells" => [array("text" => $neighbor), array("text" => (string)$votes)]);
|
| 178 | }
|
| 179 | conv::ask_custom($items);
|
avm99963 | 7797f62 | 2020-07-01 18:25:40 +0200 | [diff] [blame] | 180 | } else { // This code shows a table if the user has a screen, but
|
Javier López-Contreras | 6d1d72d | 2018-12-27 23:17:18 +0100 | [diff] [blame] | 181 | // unfortunately tables are not public yet.
|
Javier López-Contreras | 6d1d72d | 2018-12-27 23:17:18 +0100 | [diff] [blame] | 182 | $people = array_keys($neighbors);
|
| 183 | $people_string = comma($people);
|
| 184 | $params["edges"] = $people_string;
|
| 185 | $num = mt_rand(1, 3);
|
| 186 | conv::ask_followup($i18n->msg("edges_".$num, $params), $i18n);
|
avm99963 | 7797f62 | 2020-07-01 18:25:40 +0200 | [diff] [blame] | 187 | }
|
Javier López-Contreras | 6d1d72d | 2018-12-27 23:17:18 +0100 | [diff] [blame] | 188 | }
|
| 189 | } else {
|
| 190 | conv::ask_followup($i18n->msg("not_found", array("person" => $json["queryResult"]["parameters"]["Vertex"])), $i18n);
|
| 191 | }
|
| 192 | break;
|
| 193 |
|
| 194 | case "randomFact":
|
| 195 | $rand = mt_rand(0, 5);
|
| 196 | switch ($rand) {
|
| 197 | case 0: // Last edge in the graph
|
| 198 | $last = array_values(array_slice($graph["edges"], -1))[0];
|
| 199 | 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);
|
| 200 | break;
|
| 201 |
|
| 202 | case 1: // Num vertices
|
| 203 | conv::ask_followup($i18n->msg("didyouknow_num_vertices", array("count" => count($graph["nodes"]))), $i18n);
|
| 204 | break;
|
| 205 |
|
| 206 | case 2: // Num edges
|
| 207 | conv::ask_followup($i18n->msg("didyouknow_num_edges", array("count" => count($graph["edges"]))), $i18n);
|
| 208 | break;
|
| 209 |
|
| 210 | case 3: // First 3 vertices K3
|
| 211 | conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_k3"))), $i18n);
|
| 212 | break;
|
| 213 |
|
| 214 | case 4: // Creator
|
| 215 | conv::ask_followup($i18n->msg("didyouknow_creator"), $i18n);
|
| 216 | break;
|
| 217 |
|
| 218 | case 5: // Groph
|
| 219 | conv::ask_followup($i18n->msg("random_fact", array("fact" => $i18n->msg("didyouknow_groph"))), $i18n);
|
| 220 | break;
|
| 221 | }
|
| 222 |
|
| 223 | break;
|
| 224 |
|
| 225 | case "numVertexs":
|
| 226 | conv::ask_followup($i18n->msg("num_vertices", array("count" => count($graph["nodes"]))), $i18n);
|
| 227 | break;
|
| 228 |
|
| 229 | case "numEdges":
|
| 230 | conv::ask_followup($i18n->msg("num_edges", array("count" => count($graph["edges"]))), $i18n);
|
| 231 | break;
|
| 232 |
|
| 233 | case "latestNews":
|
| 234 | $param = (isset($json["queryResult"]["parameters"]["numEdges"]) ? $json["queryResult"]["parameters"]["numEdges"] : null);
|
| 235 | $num = (isset($param) && !empty($param) ? (int)$param : 4);
|
| 236 | $last = array_values(array_slice($graph["edges"], -$num));
|
| 237 | $edges = [];
|
| 238 | foreach ($last as $edge) {
|
| 239 | $edges[] = $graph["nodes"][$edge["a"]]["name"]." - ".$graph["nodes"][$edge["b"]]["name"];
|
| 240 | }
|
| 241 | $edges_string = comma($edges, true);
|
| 242 | conv::ask_followup($i18n->msg((isset($param) && !empty($param) ? "latest_news_count" : "latest_news"), array("edges" => $edges_string, "count" => $num)), $i18n);
|
| 243 | break;
|
| 244 |
|
| 245 | default:
|
| 246 | exit();
|
| 247 | }
|