How to pick up data from json with multiple level with scala - scala

I want to pick up data from the json, but i can not code it in scala, i can only write it in php, because it is very simple to use, but i have no idea how can i do the same thing in scala. please help me out.
{
"home": {
"type": "literal",
"options": {
"route": "\/",
"defaults": {
"controller": "Apiv1\\Controller\\Index",
"action": "index"
}
}
},
"praise": {
"type": "literal",
"options": {
"route": "\/apiv1\/praise",
"defaults": {
"controller": "Apiv1\\Controller\\Praise",
"action": "index"
}
},
"may_terminate": true,
"child_routes": {
"status": {
"type": "literal",
"options": {
"route": "\/status",
"defaults": {
"action": "status"
}
}
}
}
},
"admin": {
"type": "literal",
"options": {
"route": "\/admin",
"defaults": {
"controller": "Admin\\Controller\\Index",
"action": "index"
}
},
"may_terminate": true,
"child_routes": {
"routes": {
"type": "literal",
"options": {
"route": "\/routes",
"defaults": {
"controller": "Admin\\Controller\\Routes",
"action": "index"
}
},
"may_terminate": true,
"child_routes": {
"list": {
"type": "literal",
"options": {
"route": "\/list",
"defaults": {
"action": "list"
}
}
}
}
}
}
}
}
I want to pick up the route field from the json, and i would like to list all routes
here is my php version function
function parseRoute($a, $pre = '', &$urls)
{
foreach ($a as $k => $v) {
$route = $pre . $v['options']['route'];
$urls[] = $route;
if (isset($v['child_routes']) && is_array($v['child_routes'])) {
$this->parseRoute($v['child_routes'], $route, $urls);
}
$route = null;
}
}
$urls = array();
var_dump(parseRoute(json_decode($data), '', $urls));

The best thing to do is to use one of the existing JSON libraries for Scala. Here is related question describing your options:
What JSON library to use in Scala?
Next is an example of using Lift-JSON. See the link, there are many examples. Here is what you can do:
import net.liftweb.json._
val rawJson = """{
"home":{
"type":"literal",
"options":{
"route":"/",
"defaults":{
"controller":"Apiv1\\Controller\\Index",
"action":"index"
}
}
},
"praise":{
"type":"literal",
"options":{
"route":"/apiv1/praise",
"defaults":{
"controller":"Apiv1\\Controller\\Praise",
"action":"index"
}
},
"may_terminate":true,
"child_routes":{
"status":{
"type":"literal",
"options":{
"route":"/status",
"defaults":{
"action":"status"
}
}
}
}
},
"admin":{
"type":"literal",
"options":{
"route":"/admin",
"defaults":{
"controller":"Admin\\Controller\\Index",
"action":"index"
}
},
"may_terminate":true,
"child_routes":{
"routes":{
"type":"literal",
"options":{
"route":"/routes",
"defaults":{
"controller":"Admin\\Controller\\Routes",
"action":"index"
}
},
"may_terminate":true,
"child_routes":{
"list":{
"type":"literal",
"options":{
"route":"/list",
"defaults":{
"action":"list"
}
}
}
}
}
}
}
}"""
val json = parse(rawJson)
val routeList = json \\ "route"
// which returns a structure like this:
JObject(List(JField(route,JString(/)), JField(route,JString(/apiv1/praise)), JField(route,JString(/status)), JField(route,JString(/admin)), JField(route,JString(/routes)), JField(route,JString(/list))))
// which is a JSON object
// if you want a list of routes as strings as in your example extract them this way now:
val routeList: List[String] = routeObject \\ classOf[JString]
// which returns:
List[String] = List(/, /apiv1/praise, /status, /admin, /routes, /list)
Note that I'm assuming that routes can be at any level of nesting in JSON doc (you might want to enforce certain level or parent of the 'route'). I also assume that all routes are Strings and ignore the ones which are not - if you want more options you can pattern match on the type of route using derivative classes of JValue: JArray, JString, JObject, etc.

Related

Write custom transform file for design tokens from Figma in Style Dictionary for Flutter

I have barebone Flutter 2.5 project and Figma design tokens which were exported via Figma Tokens.
Those design tokens look like this:
project\style_dictionary\properties\tokens.json
{
"borderWidth": {
"100": {
"value": "1.5",
"type": "borderWidth"
}
},
"opacity": {
"basic": {
"100": {
"value": "0.04",
"type": "opacity"
}
}
},
"colors": {
"basic": {
"red": {
"50": {
"value": "#ffebee",
"type": "color"
}
}
}
}
}
and Style Dictionary config which looks like this
project\style_dictionary\config.json
{
"source": [
"properties/*.json"
],
"platforms": {
"flutter": {
"transformGroup": "flutter",
"buildPath": "../lib/unique_file/",
"files": [
{
"destination": "style_dictionary.dart",
"format": "flutter/class.dart",
"className": "StyleDictionary"
}
]
},
"flutter-separate": {
"transformGroup": "flutter-separate",
"buildPath": "../lib/unique_file/",
"files": [
{
"destination": "style_dictionary_color.dart",
"format": "flutter/class.dart",
"className": "StyleDictionaryColor",
"type": "color",
"filter": {
"attributes": {
"category": "colors"
}
}
}
]
}
}
}
Running style-dictionary build in CMD in style_dictionary will generate next file
project\lib\unique_file\style_dictionary_color.dart
import 'dart:ui';
class StyleDictionaryColor {
StyleDictionaryColor._();
static const basicRed50 = #ffebee;
}
But in should be like that at the end
project\lib\unique_file\style_dictionary_color.dart
import 'dart:ui';
class StyleDictionaryColor {
StyleDictionaryColor._();
static const basicRed50 = Color(0xFFFFEBEE);
}
Question:
How and where can I create Style Dictionary transforms file to create right dart file with Color type of the static variable?
I cannot modify exported design tokens.
Create a project\build.js as a custom Transforms file. Logic of creation was used from default Flutter color transforms and Documentation
const StyleDictionary = require('style-dictionary')
const baseConfig = require('./style_dictionary/config.json')
const Color = require('tinycolor2')
StyleDictionary.registerTransform({
name: 'colors/hex8flutter',
type: 'value',
matcher: prop => {
return prop.attributes.category === 'colors'
},
transformer: prop => {
var str = Color(prop.value).toHex8().toUpperCase();
return `Color(0x${str.slice(6)}${str.slice(0, 6)})`;
},
})
const StyleDictionaryExtended = StyleDictionary.extend(baseConfig)
StyleDictionaryExtended.buildAllPlatforms()
Modify project\style_dictionary\config.json so it can be executed from project directory and include new transforms - "transformColorsToColor" together with other transforms from Flutter
{
"source": [
"style_dictionary/properties/*.json"
],
"platforms": {
"flutter": {
"transforms": ["attribute/cti", "name/cti/camel", "color/hex8flutter", "size/flutter/remToDouble", "content/flutter/literal", "asset/flutter/literal", "font/flutter/literal", "colors/hex8flutter"],
"buildPath": "lib/unique_file/",
"files": [
{
"destination": "style_dictionary.dart",
"format": "flutter/class.dart",
"className": "StyleDictionary"
}
]
},
"flutter-separate": {
"transforms": ["attribute/cti", "name/ti/camel", "color/hex8flutter", "size/flutter/remToDouble", "content/flutter/literal", "asset/flutter/literal", "font/flutter/literal", "colors/hex8flutter"],
"buildPath": "lib/unique_file/",
"files": [
{
"destination": "style_dictionary_color.dart",
"format": "flutter/class.dart",
"className": "StyleDictionaryColor",
"type": "color",
"filter": {
"attributes": {
"category": "colors"
}
}
}
]
}
}
}
Run npm init with all default answers
Run npm install --save tinycolor2
Run node build.js

How do I add custom queries in GraphQL using Strapi?

I'm using graphQL to query a MongoDB database in React, using Strapi as my CMS. I'm using Apollo to handle the GraphQL queries. I'm able to get my objects by passing an ID argument, but I want to be able to pass different arguments like a name.
This works:
{
course(id: "5eb4821d20c80654609a2e0c") {
name
description
modules {
title
}
}
}
This doesn't work, giving the error "Unknown argument \"name\" on field \"course\" of type \"Query\"
{
course(name: "course1") {
name
description
modules {
title
}
}
}
From what I've read, I need to define a custom query, but I'm not sure how to do this.
The model for Course looks like this currently:
"kind": "collectionType",
"collectionName": "courses",
"info": {
"name": "Course"
},
"options": {
"increments": true,
"timestamps": true
},
"attributes": {
"name": {
"type": "string",
"unique": true
},
"description": {
"type": "richtext"
},
"banner": {
"collection": "file",
"via": "related",
"allowedTypes": [
"images",
"files",
"videos"
],
"plugin": "upload",
"required": false
},
"published": {
"type": "date"
},
"modules": {
"collection": "module"
},
"title": {
"type": "string"
}
}
}
and the
Any help would be appreciated.
Referring to Strapi GraphQL Query API
You can use where with the query courses to filter your fields. You will get a list of courses instead of one course
This should work:
{
courses(where: { name: "course1" }) {
name
description
modules {
title
}
}
}

"How to get username by userID in google assistant action?"

I was connected my chatbot to google assistant action. They give only the userID, how to get username by using this userID?
You can get username without knowing userid, by the permissions document here. You can take a look at this sample code.
Or you can use account linking feature.
Tip! for userID, you can check out this doc
For Python:
There is no official library for developing google action using Python but,
You can add permission intent in possibleIntent array. So your Action SDK JSON will be,
{
"expectUserResponse": true,
"expectedInputs": [
{
"inputPrompt": {
"richInitialPrompt": {
"items": [
{
"simpleResponse": {
"textToSpeech": "PLACEHOLDER"
}
}
]
}
},
"possibleIntents": [
{
"intent": "actions.intent.PERMISSION",
"inputValueData": {
"#type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
"optContext": "To address you by name and know your location",
"permissions": [
"NAME",
"DEVICE_PRECISE_LOCATION"
]
}
}
]
}
],
"conversationToken": "{\"data\":{}}",
"userStorage": "{\"data\":{}}"
}
{`"actions": [
{
"description": "Default Welcome Intent",
"name": "MAIN",
"fulfillment": {
"conversationName": "welcome"
},
"intent": {
"name": "actions.intent.MAIN",
"trigger": {
"queryPatterns":["talk to Mr Bot"]
}
}
},
{
"description": "Rasa Intent",
"name": "TEXT",
"fulfillment": {
"conversationName": "rasa_intent"
},
"intent": {
"name": "actions.intent.TEXT",
"trigger": {
"queryPatterns":[]
}
}
}],
"conversations": {
"welcome": {
"name": "welcome",
"url": "https://ac752bb0.ngrok.io/webhooks/google_home/webhook",
"fulfillmentApiVersion": 2
},
"rasa_intent": {
"name": "rasa_intent",
"url": "https://ac752bb0.ngrok.io/webhooks/google_home/webhook",
"fulfillmentApiVersion": 2
}
} }
this is my action.json,
class GoogleConnector(InputChannel):
#classmethod
def name(cls):
return "google_home"
#def __init__(self):
# self.out_channel = CustomOutput(url, access_token)
def blueprint(self, on_new_message):
google_webhook = Blueprint('google_webhook', __name__)
#google_webhook.route("/", methods=['GET'])
def health():
return jsonify({"status": "ok"})
#google_webhook.route("/webhook", methods=['POST'])
def receive():
payload = json.loads(request.data)
sender_id = payload['user']['userId']
intent = payload['inputs'][0]['intent']
text = payload['inputs'][0]['rawInputs'][0]['query']
if intent == 'actions.intent.MAIN':
message = "<speak>Hello! <break time=\"1\"/> Welcome to the Rasa-powered Google Assistant skill. You can start by saying hi."
else:
out = CollectingOutputChannel()
on_new_message(UserMessage(text, out, sender_id))
responses = [m["text"] for m in out.messages]
message = responses[0]
r = json.dumps(
{
"conversationToken": "{\"state\":null,\"data\":{}}",
"expectUserResponse": 'true',
"expectedInputs": [
{
"inputPrompt": {
"initialPrompts": [
{
"ssml": message
}
]
},
"possibleIntents": [
{
"intent": "actions.intent.TEXT"
}
]
}
]
})
return r
return google_webhook
this my google connector python code,
how to modified this for account signin

elastic4s: how to add analyzer/filter for german_phonebook to analysis?

How do I add the following german_phonebook analyzer to elastic search using elastic4s?
"index": {
"analysis": {
"analyzer": {
"german": {
"filter": [
"lowercase",
"german_stop",
"german_normalization",
"german_stemmer"
],
"tokenizer": "standard"
},
"german_phonebook": {
"filter": [
"german_phonebook"
],
"tokenizer": "keyword"
},
"mySynonyms": {
"filter": [
"lowercase",
"mySynonymFilter"
],
"tokenizer": "standard"
}
},
"filter": {
"german_phonebook": {
"country": "CH",
"language": "de",
"type": "icu_collation",
"variant": "#collation=phonebook"
},
"german_stemmer": {
"language": "light_german",
"type": "stemmer"
},
"german_stop": {
"stopwords": "_german",
"type": "stop"
},
"mySynonymFilter": {
"synonyms": [
"swisslift,lift"
],
"type": "synonym"
}
}
},
The core question here is which filter to use for the german_phonebook filter of type icu_collation?
...
Following the answer I came up with this code:
case class GPhonebook() extends TokenFilterDefinition {
val filterType = "phonebook"
def name = "german_phonebook"
override def build(source: XContentBuilder): Unit = {
source.field("tokenizer", "keyword")
source.field("country", "CH")
source.field("language", "de")
source.field("type", "icu_collation")
source.field("variant", "#collation=phonebook")
}
}
The analyzer definition looks like this now:
CustomAnalyzerDefinition(
"german_phonebook",
KeywordTokenizer("myKeywordTokenizer2"),
GPhonebook()
)
What you really want is someway to say
CustomTokenFilter("german_phonebook) or BuiltInTokenFilter("german_phonebook") but you can't (I'll add that).
So for now, you need to extend TokenFilterDefinition.
Eg, Something like
case class GPhonebook extends TokenFilterDefinition {
val filterType = "phonebook"
override def build(source: XContentBuilder): Unit = {
// set extra params in here
}
}

Disable Copy in CCP context menu for JsTree

How can I disable the "Copy" (but not cut / paste) functionality of the jsTree right click context menu?
This pretty much did the trick.
$("#housingTree").jstree({
"plugins": ["themes", "html_data", "ui", "crrm", "hotkeys", "contextmenu"],
"core": { "initially_open": ["phtml_1"] },
"contextmenu": {
"items": function ($node) {
return {
"Rename": {
"label": "Rename",
"action": function (obj) { this.rename(obj); }
},
"Create": {
"label": "Create",
"action": function (obj) { this.create(obj); }
},
"Delete": {
"label": "Delete",
"action": function (obj) { this.remove(obj); }
},
"Cut": {
"label": "Cut",
"action": function (obj) { this.cut(obj); }
},
"Paste": {
"label": "Paste",
"action": function (obj) { this.paste(obj); }
}
};
}
}
})
i dont know if the action functions are the default functions or custom functions, but that didnt work for me... anyway your post did set me in the right path! thanks!
this is how i did it, after finding another post:
"contextmenu": {
"items": function ($node) {
var tree = $("#html1Tree").jstree(true);
return {
"Rename": {
"label": "Rename",
"action": function (obj) {
tree.edit($node);
}
},
"Create": {
"label": "Create",
"action": function (obj) {
$node = tree.create_node($node);
tree.edit($node);
}
}
};
}
}
jsTree and Context Menu: modify items
The shorter approach could be
"contextmenu": {
"items": function(node) {
var defaultItems = $.jstree.defaults.contextmenu.items();
console.log("default items : "+JSON.stringify(defaultItems));
delete defaultItems.ccp.submenu.copy;
return defaultItems;
}
},
You can console.log(defaultItems). It wil print json representation of object. You can modify other properties also.
this is my easiest option.
All main code placed in "contextmenu.items" block.
$('#c-list').jstree({
"core": {
"themes": {"responsive": false},
"check_callback": true,
},
"types": {
"default": {
"icon": "fa fa-folder text-warning fa-lg"
},
"file": {
"icon": "fa fa-file text-warning fa-lg"
}
},
"contextmenu":{
'items' : function(node) {
var items = $.jstree.defaults.contextmenu.items();
items.ccp = false;
return items;
}
},
"plugins": ["contextmenu", "dnd", "types", "search", "wholerow","checkbox"]
});