Grails. Domain class. Method AddTo*? - json

I have this example:
def mycreate = {
def id = params.id;
def data = JSON.parse(params.data);
def credit = Credit.get(id);
def front = new Front ();
front.properties = data;
credit.addToFronts(front).save()
render (front as JSON)
}
This action returns something like this:
{"class":"test.Front","id":null,"credits":{"class":"Credit","id":1},"dateCreated":null,"description":"write text here."}
But, for me, the params "id" and "dateCreated" are null. How can I get the values of these params?

Related

Return function value as a value in a dictionary

dic1 = {}
class Piglet:
pass
def __init__(self,name,age):
self.name = name
self.age = age
def speak_or_not(self):
if self.age>2:
return True
else:
return False
def speak_dic(self):
global dic1
dic1[self.name] = speak_or_not()
pig1 = Piglet("Shaun",3)
pig1.speak_dic()
print(dic1)
I want to add the return value of the function speak_or_not as a value of dictionary dic1 which will result in a output like: {"Shaun":True} since age>2. But it prints an empty dictionary.
How to call a function and set the return value of the function as a value of the dictionary?
The code is not correct. In the speak_dic function, you are calling speak_or_not, which does not exist. Instead, you need to call self.speak_or_not.
Attaching the corrected code below.
dic1 = {}
class Piglet:
def __init__(self,name,age):
self.name = name
self.age = age
def speak_or_not(self):
if self.age>2:
return True
else:
return False
def speak_dic(self):
global dic1
dic1[self.name] = self.speak_or_not()
pig1 = Piglet("Shaun",3)
pig1.speak_dic()
print(pig1)
Also, you need to print dic1 to show the dictionary.
Hope this helps.

Return valid GeoJSON with Flask + GeoAlchemy2 app

Since few days I am wondering how to make my Flask app return valid GeoJSON, here is what I got so far:
models.py
class Building(base):
__tablename__ = 'buildings'
id = Column(Integer, primary_key=True)
district = Column(Unicode)
address = Column(Unicode)
name = Column(Unicode)
building_type = Column(Unicode)
mpoly = Column(Geometry('MULTIPOLYGON'))
building = relationship("User")
# this part is done as answered here: https://stackoverflow.com/questions/41684512/cant-transform-geometry-to-geojson
def building_to_dict(self):
return mapping(shapely.wkb.loads(str(self.mpoly), True))
def __str__(self):
d = dict()
d["id"] = self.id
d["district"] = self.district
d["address"] = self.address
d["name"] = self.name
d["building_type"] = self.building_type
d["mpoly"] = self.building_to_dict()
return shapely.dumps(d)
Now at main file I have following routing:
app.py
#app.route('/geojson')
def get_json():
features = session.query(Building.mpoly.ST_AsGeoJSON()).all()
return jsonify(features)
And here are my two problems:
1)
Returned JSON-like response that looks like following:
"{\"type\":\"MultiPolygon\",\"coordinates\":[[[[16.8933137,52.471446],...,]]]}"
Is not proper GeoJSON.
Features variable before jsonify looks this way:
[('{"type":"MultiPolygon","coordinates":[[[[16.914159616,52.473822807],...,]]]}',)]
2)
How my GeoAlchemy query should look like, to return not just geometry field, but others as well?
Any kind of hints or helps highly appreciated, thanks in advance!
You may use marshmallow-sqlalchemy for creating json like responses.
create
schemas.py
#!schemas.py
from marshmallow import fields
from marshmallow_sqlalchemy import ModelSchema
from app.models import Building
from geoalchemy.shape import to_shape
class BuildingSchema(ModelSchema):
id = fields.Integer()
district = fileds.Unicode()
address = fileds.Unicode()
name = fields.Unicode()
building_type = fields.Unicode()
mpoly = fileds.Method("geom_to_json")
#staticmethod
def geom_to_json(obj):
mpoly = to_shape(obj.mpoly)
return {
lat: mpoly.y,
lon: mpoly.x,
#and so on ...
}
class Meta:
model = Building
exclude = ("mpoly")
bulding_schema = BuildingSchema(many=True)
after this you can use it in your views(routes)
from app.schemas import building_schema
#app.route('/geojson')
def json():
buildings = Buildings.query.all()
response = building_schema.dumps(buildings)
return response

In Django, how do I render JSON given an OrderedDict?

I'm using Django and Python 3.7. I'm having trouble returning JSON from one of my views. I have this view code ...
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
print("data: ", data)
return HttpResponse(data, content_type="application/json")
The service method referenced returns the following data ...
def get_hints(self, article):
...
sorted_articles_map = OrderedDict(sorted(rank_map.items(), key=operator.itemgetter(1), reverse=True))
return list(sorted_articles_map.keys())
The data returned from the serializer looks like this, definitely not json ...
[OrderedDict([('id', 10777935), ('created_on_ms', 1577985486000.0), ('label', 'World'), ('title', "Outrage and Disgust After 'Serial Killer' ...,
How do I render proper JSON?
Edit: Adding Article serializer ...
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'created_on_ms', 'label', 'title', 'mobile_path', 'path', 'url', 'is_media', 'checked_for_dup', 'original_path', 'is_spiked']
Option 1
Use the #api_view()--(drf doc) decorator of DRF along with Response--(drf doc) class
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view(['GET'])
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
return Response(data)
Option 2
You will get similar response by using JsonResponse--(django doc)
from django.http.response import JsonResponse
def get_hints(request):
article_id = request.GET.get('article_id', None)
article = Article.objects.get(pk=article_id)
s = ArticlesService()
objects = s.get_hints(article)
data = ArticleSerializer(objects, many=True).data
return JsonResponse(data, safe=False)

Set the product name based on price, if price is zero or -1 or null ignore those products

Hi here i have whole bunch of products with different json objects. I have to get the product name based on the price. If price is not zero or not null get that product.
Here is the script:
Below script will traverse thru the json and extracts the product name where there is price and also put the data into a map called productPriceMap which can be used later.
def productPriceMap = [:]
def jsonParsed = new groovy.json.JsonSlurper().parseText(json)
jsonParsed.products.collect{ product ->
product.productRatePlans.collect { ratePlan ->
ratePlan.productRatePlanCharges.collect { charge ->
charge.productRatePlanChargeTiers.collect{ tier ->
if (tier.price) {
log.info "${tier.price} - ${product.name}"
productPriceMap[product.name] = tier.price
}
}
}
}
}
log.info "Product and price map\n$productPriceMap"
You can quickly try this online Demo
I am sure this can be shortened / more groovified. But this is what I could get it.
What you are doing is filtering a certain list. So it gives you some result, but has to be stored somewhere to use it further.
Like this
def toList(priceNullCheck){
def filteredList = [priceNullCheck].flatten().findAll { it != null}
log.info filteredList
}
Else you can return [priceNullCheck].flatten().findAll { it != null} directly
UPDATED
import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def response = groovyUtils.getXmlHolder("TestRequest#Response")
def collectResult = []
use (groovy.xml.dom.DOMCategory) {
for( node in response.getDomNodes("//*:products//*:e")) {
def eachNodeAsXml = groovyUtils.getXmlHolder(nodeToString(node))
String priceTagValue = eachNodeAsXml.getNodeValue("//*:price")
float price = priceTagValue?Float.parseFloat(priceTagValue):0
if(price>0)
collectResult.add(eachNodeAsXml.getNodeValue("/*:name"))
}
}
println collectResult
def nodeToString(def node)
{
StringWriter writer = new StringWriter();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(node), new StreamResult(writer));
return writer.toString();
}

How to access elements of JSON object in view.gsp to use as parameters in an image call?

I think I'm passing a JSON object from my controller to my view but I can't seem to access the discreet elements of the JSON. Please share your thoughts.
How much of the DisplayRecentPortlet is required, should I be
accessing the JSON elements there?
Am I really passing JSON?
How might I access the individual elements inside jsonObj to construct an
img tag in the view?
DisplayRecentContoller.groovy
package cssinstaviewer
import groovy.json.*
import grails.converters.JSON
class DisplayRecentController {
def view() {
def apiUrl = new URL("https://api.instagram.com/v1/users/STUFFTHATWORKS/media/recent/?client_id=STUFFTHATWORKS")
def doc = new JsonSlurper().parseText(apiUrl.text)
def jsonObj = new JsonBuilder(doc.data.images.low_resolution[0])
render(view:"view", model: [jsonObj: jsonObj as JSON])
}
}
DisplayRecentPortlet.groovy
package cssinstaviewer
import javax.portlet.*
class DisplayRecentPortlet {
def title = 'CSS Instagram Viewer'
def description = '''
CSS Instagram Viewer
'''
def displayName = 'CSS Instagram Viewer'
def supports = ['text/html':['view']]
//uncomment to declare events support
//def events = [publish: ["event-1"], process: ["event-2"]]
//uncomment to declare public render parameter support
//def public_render_params = ["prp-1","prp-2"]
// Used for liferay
// #see http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/anatomy-of-a-portlet
def liferay_display_category = "category.St. Scholastica"
def actionView = {
//TODO Define action phase for 'view' portlet mode
portletResponse.setRenderParameter("prp-1", "value-1");
}
def eventView = {
//TODO Define event phase for 'view' portlet mode.
def eventValue = portletRequest.event.value
}
def renderView = {
//TODO Define render phase for 'view' portlet mode.
//Return the map of the variables bound to the view,
//in this case view.gsp if it exists or render.gsp if not
['jsonObj':'jsonObj']
}
def resourceView = {
//TODO define resource phase for 'view' portlet mode.
//Render HTML as response
render {
html {
head()
body {
"Render me"
}
}
}
}
def actionEdit = {
//TODO Define action phase for 'edit' portlet mode
portletResponse.setEvent("event-1","event-1")
portletResponse.setPortletMode(PortletMode.VIEW)
}
def renderHelp = {
//TODO Define render phase for 'help' portlet mode
//Return the map of the variables bound to the view,
//in this case help.gsp if it exists or render.gsp if not
['mykey':'myvalue']
}
def doResource = {
//TODO Define handling for default resource URL handling method, independent of porlet mode
//Return the map of the variables bound to the view,
//in this case resource.gsp
['mykey':'myvalue']
}
//invoked by setting 'action' param in resourceURL (as an example) to 'doSomethingAjaxy'
def doSomethingAjaxy = {
//render JSON
render(contentType:"text/json") {
example(mykey:"myvalue")
}
}
//invoked by setting 'action' param in eventURL (as an example) to 'handleThisEvent'
def handleThisEvent = {
//render thisEvent.gsp
render(view:"thisEvent")
}
}
view.gsp
<%#page import="cssinstaviewer.DisplayRecentPortlet"%>
<%# taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<div>
<g:set var="instaImg" value="${jsonObj}" />
instImg = ${instaImg}
<hr />
jsonObj ${jsonObj}"
</div>
Output
instImg = {"content":{"height":306,"width":306,"url":"http://scontent-a.cdninstagram.com/hphotos-xap1/t51.2885-15/925254_1484378108464185_1325554272_a.jpg"}} jsonObj {"content":{"height":306,"width":306,"url":"http://scontent-a.cdninstagram.com/hphotos-xap1/t51.2885-15/925254_1484378108464185_1325554272_a.jpg"}}"
Well, I didn't need to send JSON from the controller I changed
render(view:"view", model: [jsonObj: jsonObj as JSON])
to
render(view:"view", model: [jsonObj: jsonObj])
and then I could address the elements separately by key name in the view.
<img src="${instaImg.content.url}" width="${instaImg.content.width}" height="${instaImg.content.height}">
It is a little peculiar to put a JSON object in the model like you are doing but that aside, I will make an attempt to address your specific question...
In your controller you could do something like this to add the image path to the model:
def view() {
def apiUrl = new URL("https://api.instagram.com/v1/users/STUFFTHATWORKS/media/recent/?client_id=STUFFTHATWORKS")
def doc = new JsonSlurper().parseText(apiUrl.text)
def jsonObj = new JsonBuilder(doc.data.images.low_resolution[0])
def imagePath = jsonObj.content.url
render(view:"view", model: [jsonObj: jsonObj as JSON, imagePath: imagePath])
}
And then in your view you could do something like this...
<img src="${imagePath}"/>
You could also do something like this...
<img src="${jsonObj.content.url}"/>
Is any of that the sort of thing you are looking for?
You should also take a look at http://grails.org/doc/latest/ref/Tags/img.html as a mechanism for generating the img tag.