Vision- grabbing source image uri in each AnnotateImageResponse from batch_annotate_images - google-cloud-platform

Images are uploaded in google bucket. Code given below is running fine. It's in python3. I am trying to catch each image_uri for corresponding AnnotateImageResponse so that I can save responses in database with corresponding image uris. How can I grab input image_uri for each response? Because in each response, source image uri data not available. I may be wrong but I guess, while making requests in generate_request function, I may need to send image_uri as image_context, but not finding any good docs for that. please help.
Image files uploaded in google buckets are
'39149.7ae80cfb87bb228201e251f3e234ffde.jpg', 'anatomy_e.jpg'
def generate_request(input_image_uri):
if isinstance(input_image_uri, six.binary_type):
input_image_uri = input_image_uri.decode('utf-8')
source = {'image_uri': input_image_uri}
image = {'source': source}
features = [{"type_": vision.Feature.Type.LABEL_DETECTION},{"type_": vision.Feature.Type.FACE_DETECTION},{"type_": vision.Feature.Type.TEXT_DETECTION}]
requests = {"image": image, "features": features}
return requests
def sample_async_batch_annotate_images(input_uri):
client = vision.ImageAnnotatorClient()
requests = [
generate_request(input_uri.format(filename)) for filename in ['39149.7ae80cfb87bb228201e251f3e234ffde.jpg','anatomy_e.jpg',]
]
# below response is A BatchAnnotateFilesResponse instance.
response = client.batch_annotate_images(requests=requests)
for each in response.responses:
#each response is AnnotateImageResponse instance
print("each_response", each)
sample_async_batch_annotate_images('gs://imagevisiontest/{}')

I was a little bit confused on your sample_async_batch_annotate_images function since it was named asynchronous but you are not using the asynchronous method of Vision API. The response from batch_annotate_images does not return context that contains the source image_uri. Also the image_context is only used to refine your image detection like providing language hints, telling the API to search for products, etc.
I suggest using the asynchronous batch annotate method of the API as it will include context which is seen at the end of the response along with the source image_uri. Also the response is saved in the output_uri specified in the code.
I processed this image and I renamed it to image_text.jpeg for testing on batch_annotate_images and async_batch_annotate_images:
Code snippet used for batch_annotate_images:
from google.cloud import vision_v1
def sample_batch_annotate_images(
input_image_uri="gs://your_bucket_here/image_text.jpeg",
):
client = vision_v1.ImageAnnotatorClient()
source = {"image_uri": input_image_uri}
image = {"source": source}
features = [
{"type_": vision_v1.Feature.Type.LABEL_DETECTION},
{"type_": vision_v1.Feature.Type.IMAGE_PROPERTIES},
]
requests = [{"image": image, "features": features}]
response = client.batch_annotate_images(requests=requests)
print(response)
sample_batch_annotate_images()
Response from batch_annotate_images:
responses {
label_annotations {
mid: "/m/02wzbmj"
description: "Standing"
score: 0.9516521096229553
topicality: 0.9516521096229553
}
label_annotations {
mid: "/m/01mwkf"
description: "Monochrome"
score: 0.9407921433448792
topicality: 0.9407921433448792
}
label_annotations {
mid: "/m/01lynh"
description: "Stairs"
score: 0.9399806261062622
topicality: 0.9399806261062622
}
label_annotations {
mid: "/m/03scnj"
description: "Line"
score: 0.9328843951225281
topicality: 0.9328843951225281
}
label_annotations {
mid: "/m/012yh1"
description: "Style"
score: 0.9320641756057739
topicality: 0.9320641756057739
}
label_annotations {
mid: "/m/03d49p1"
description: "Monochrome photography"
score: 0.911144495010376
topicality: 0.911144495010376
}
label_annotations {
mid: "/m/01g6gs"
description: "Black-and-white"
score: 0.9031684994697571
topicality: 0.9031684994697571
}
label_annotations {
mid: "/m/019sc"
description: "Black"
score: 0.8788009881973267
topicality: 0.8788009881973267
}
label_annotations {
mid: "/m/030zfn"
description: "Parallel"
score: 0.8722482919692993
topicality: 0.8722482919692993
}
label_annotations {
mid: "/m/05wkw"
description: "Photography"
score: 0.8370979428291321
topicality: 0.8370979428291321
}
image_properties_annotation {
dominant_colors {
colors {
color {
red: 195.0
green: 195.0
blue: 195.0
}
score: 0.4464040696620941
pixel_fraction: 0.10618651658296585
}
colors {
color {
red: 117.0
green: 117.0
blue: 117.0
}
score: 0.16896472871303558
pixel_fraction: 0.1623961180448532
}
colors {
color {
red: 13.0
green: 13.0
blue: 13.0
}
score: 0.12974770367145538
pixel_fraction: 0.24307478964328766
}
colors {
color {
red: 162.0
green: 162.0
blue: 162.0
}
score: 0.11677403748035431
pixel_fraction: 0.09510618448257446
}
colors {
color {
red: 89.0
green: 89.0
blue: 89.0
}
score: 0.08708541840314865
pixel_fraction: 0.17659279704093933
}
colors {
color {
red: 225.0
green: 225.0
blue: 225.0
}
score: 0.05102387070655823
pixel_fraction: 0.012119113467633724
}
colors {
color {
red: 64.0
green: 64.0
blue: 64.0
}
score: 1.7074732738819876e-07
pixel_fraction: 0.2045244723558426
}
}
}
crop_hints_annotation {
crop_hints {
bounding_poly {
vertices {
x: 123
}
vertices {
x: 226
}
vertices {
x: 226
y: 182
}
vertices {
x: 123
y: 182
}
}
confidence: 0.4375000298023224
importance_fraction: 0.794996440410614
}
}
}
Code snippet used for async_batch_annotate_images (got the code in Vision API docs):
from google.cloud import vision_v1
def sample_async_batch_annotate_images(
input_image_uri="gs://your_bucket_here/image_text.jpeg",
output_uri="gs://your_bucket_here/",
):
"""Perform async batch image annotation."""
client = vision_v1.ImageAnnotatorClient()
source = {"image_uri": input_image_uri}
image = {"source": source}
features = [
{"type_": vision_v1.Feature.Type.LABEL_DETECTION},
{"type_": vision_v1.Feature.Type.IMAGE_PROPERTIES},
]
# Each requests element corresponds to a single image. To annotate more
# images, create a request element for each image and add it to
# the array of requests
requests = [{"image": image, "features": features}]
gcs_destination = {"uri": output_uri}
# The max number of responses to output in each JSON file
batch_size = 2
output_config = {"gcs_destination": gcs_destination,
"batch_size": batch_size}
operation = client.async_batch_annotate_images(requests=requests, output_config=output_config)
print("Waiting for operation to complete...")
response = operation.result(90)
# The output is written to GCS with the provided output_uri as prefix
gcs_output_uri = response.output_config.gcs_destination.uri
print("Output written to GCS with prefix: {}".format(gcs_output_uri))
sample_async_batch_annotate_images()
Response from async_batch_annotate_images:
{
"responses":[
{
"labelAnnotations":[
{
"mid":"/m/02wzbmj",
"description":"Standing",
"score":0.9516521,
"topicality":0.9516521
},
{
"mid":"/m/01mwkf",
"description":"Monochrome",
"score":0.94079214,
"topicality":0.94079214
},
{
"mid":"/m/01lynh",
"description":"Stairs",
"score":0.9399806,
"topicality":0.9399806
},
{
"mid":"/m/03scnj",
"description":"Line",
"score":0.9328844,
"topicality":0.9328844
},
{
"mid":"/m/012yh1",
"description":"Style",
"score":0.9320642,
"topicality":0.9320642
},
{
"mid":"/m/03d49p1",
"description":"Monochrome photography",
"score":0.9111445,
"topicality":0.9111445
},
{
"mid":"/m/01g6gs",
"description":"Black-and-white",
"score":0.9031685,
"topicality":0.9031685
},
{
"mid":"/m/019sc",
"description":"Black",
"score":0.878801,
"topicality":0.878801
},
{
"mid":"/m/030zfn",
"description":"Parallel",
"score":0.8722483,
"topicality":0.8722483
},
{
"mid":"/m/05wkw",
"description":"Photography",
"score":0.83709794,
"topicality":0.83709794
}
],
"imagePropertiesAnnotation":{
"dominantColors":{
"colors":[
{
"color":{
"red":195,
"green":195,
"blue":195
},
"score":0.44640407,
"pixelFraction":0.10618652
},
{
"color":{
"red":117,
"green":117,
"blue":117
},
"score":0.16896473,
"pixelFraction":0.16239612
},
{
"color":{
"red":13,
"green":13,
"blue":13
},
"score":0.1297477,
"pixelFraction":0.24307479
},
{
"color":{
"red":162,
"green":162,
"blue":162
},
"score":0.11677404,
"pixelFraction":0.095106184
},
{
"color":{
"red":89,
"green":89,
"blue":89
},
"score":0.08708542,
"pixelFraction":0.1765928
},
{
"color":{
"red":225,
"green":225,
"blue":225
},
"score":0.05102387,
"pixelFraction":0.0121191135
},
{
"color":{
"red":64,
"green":64,
"blue":64
},
"score":1.7074733e-07,
"pixelFraction":0.20452447
}
]
}
},
"cropHintsAnnotation":{
"cropHints":[
{
"boundingPoly":{
"vertices":[
{
"x":123
},
{
"x":226
},
{
"x":226,
"y":182
},
{
"x":123,
"y":182
}
]
},
"confidence":0.43750003,
"importanceFraction":0.79499644
}
]
},
"context":{
"uri":"gs://your_bucket_here/image_text.jpeg"
}
}
]
}

Related

Number Formatting Issue with Custom Power BI Visual

Above is the card from the tutorial at https://learn.microsoft.com/en-us/power-bi/developer/custom-visual-develop-tutorial. Here is the related code for the visual.
I would like the number to be shown as a percentage value, i.e. 15.4% which is how it is formatting in the measure.
I have searched github, microsoft, google, etc. for a solution to this issue. I also skimmed all the recommended questions on Stack Overflow before posting. Any help get the number formatting to match the measures formatting would be greatly appreciated.
Here is the related code for the visual. (sorry for the length)
visual.ts
"use strict";
import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import DataView = powerbi.DataView;
import * as d3 from "d3";
import VisualObjectInstanceEnumeration = powerbi.VisualObjectInstanceEnumeration;
import { VisualSettings } from "./settings";
import { rgb, RGBColor, Color } from "d3";
export class Visual implements IVisual {
private visualSettings: VisualSettings;
private svg: d3.Selection<SVGElement, any, any, any>;
private container: d3.Selection<SVGElement, any, any, any>;
private circle: d3.Selection<SVGElement, any, any, any>;
private textLabel: d3.Selection<SVGElement, any, any, any>;
private textValue: d3.Selection<SVGElement, any, any, any>;
private settings: VisualSettings;
constructor(options: VisualConstructorOptions) {
console.log('Visual constructor', options);
this.svg = d3.select(options.element)
.append('svg')
.classed('circlecard', true);
this.container = this.svg.append("g")
.classed('container', true);
this.circle = this.container.append("circle")
.classed('circle', true);
this.textValue = this.container.append("text")
.classed("textValue", true);
this.textLabel = this.container.append("text")
.classed("textLabel", true);
}
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration {
const settings: VisualSettings = this.visualSettings ||
VisualSettings.getDefault() as VisualSettings;
return VisualSettings.enumerateObjectInstances(settings, options);
}
public update(options: VisualUpdateOptions) {
this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
let dataView: DataView = options.dataViews[0];
let width: number = options.viewport.width;
let height: number = options.viewport.height;
this.svg.attr("width", width)
.attr("height", height);
let radius: number = Math.min(width, height) / 2.2;
this.visualSettings = VisualSettings.parse<VisualSettings>(dataView);
this.visualSettings.circle.circleThickness = Math.max(0, this.visualSettings.circle.circleThickness);
this.visualSettings.circle.circleThickness = Math.min(10, this.visualSettings.circle.circleThickness);
this.circle
.style("fill", this.visualSettings.circle.circleColor)
.style("stroke", this.visualSettings.circle.circleColor)
.style("stroke-width",this.visualSettings.circle.circleThickness)
.attr("r", radius)
.attr("cx", width / 2)
.attr("cy", height / 2);
let fontSizeValue: number = Math.min(width, height) / 5;
this.textValue
.text(dataView.single.value as string)
.attr("x", "50%")
.attr("y", "50%")
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.style("font-size", fontSizeValue + "px");
let fontSizeLabel: number = fontSizeValue / 4;
this.textLabel
.text(dataView.metadata.columns[0].displayName)
.attr("x", "50%")
.attr("y", height / 2)
.attr("dy", fontSizeValue / 1.2)
.attr("text-anchor", "middle")
.style("font-size", fontSizeLabel + "px");
}
private static parseSettings(dataView: DataView): VisualSettings {
return VisualSettings.parse(dataView) as VisualSettings;
}
/**
* This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
* objects and properties you want to expose to the users in the property pane.
*
*/
}
capabilities.json
{
"dataRoles": [
{
"displayName": "Measure",
"name": "measure",
"kind": "Measure"
}
],
"objects": {
"circle": {
"displayName": "Circle",
"properties": {
"circleColor": {
"displayName": "Color",
"description": "The fill color of the circle.",
"type": {
"fill": {
"solid": {
"color": true
}
}
}
},
"circleThickness": {
"displayName": "Thickness",
"description": "The circle thickness.",
"type": {
"numeric": true
}
}
}
}
},
"dataViewMappings": [
{
"conditions": [
{ "measure": { "max": 1 } }
],
"single": {
"role": "measure"
}
}
]
}
settings.ts
"use strict";
import { dataViewObjectsParser } from "powerbi-visuals-utils-dataviewutils";
import DataViewObjectsParser = dataViewObjectsParser.DataViewObjectsParser;
export class CircleSettings {
public circleColor: string = "white";
public circleThickness: number = 2;
}
export class VisualSettings extends DataViewObjectsParser {
public circle: CircleSettings = new CircleSettings();
}
Thank you for viewing this.
One way I always handle my formats (when not possible via the interface)
is creating custom Measures that contain the format I want.
I created 2 cards to show unformatted and formatted values:
Measure formula :
Fmt_value = FORMAT(SUM('Table'[Column1]),"#,##0.0%;(#,##0.0%)")
see pictures:
Formatting Numeric values as %
Adding a Measure for Formatting
Hope this helps.

error in graphQL using imageSharp regex with gatsby

I'm using gatsby to create a simple blog. When I try to search for an specific image, I get an error from graphql. I have the following configs:
installed "gatsby-image": "^1.0.55"
graphql`
query MainLayoutQuery {
heroImage: imageSharp(id: { regex: "/hero.jpg/" }) {
id
sizes(quality: 100) {
base64
tracedSVG
aspectRatio
src
srcSet
srcWebp
srcSetWebp
sizes
originalImg
originalName
}
}
}
`
when I run that query in graphql ui I get:
{
"errors": [
{
"message": "Cannot read property 'id' of undefined",
"locations": [
{
"line": 31,
"column": 3
}
],
"path": [
"heroImage"
]
}
],
"data": {
"heroImage": null
}
}
But, if I run the same query without the regex, it works fine:
{
heroImage: imageSharp {
id
sizes(quality: 100) {
base64
tracedSVG
aspectRatio
src
srcSet
srcWebp
srcSetWebp
sizes
originalImg
originalName
}
}
}
Of course, it brings the first image it has access to
"data": {
"heroImage": {
"id": "/Users/marcosrios/dev/workspace/atravesando-todo-limite/src/posts/2018-08-25-tengo-miedo/cover.png absPath of file >> ImageSharp"
}
}
Which version of Gatsby are you using? If v2 you need to edit your query as there has been changes:
https://next.gatsbyjs.org/docs/migrating-from-v1-to-v2/#dont-query-nodes-by-id
Your query then would look like that:
graphql`
query MainLayoutQuery {
heroImage: imageSharp(fluid: { originalName: { regex: "/hero.jpg/" } }) {
id
fluid(quality: 100) {
base64
tracedSVG
aspectRatio
src
srcSet
srcWebp
srcSetWebp
sizes
originalImg
originalName
}
}
}
`

Determine velocity template request body property type?

I have an API Gateway that uses velocity templates as a thin wrapper to allow users to do CRUD operations on a DynamoDB table.
I'm trying to write the update operation as dynamically as possible, but where I'm stuck is with determining type from the request body's properties from within the velocity template. This is what I'm working with:
#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
#set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
#set($expressionAttributeNames = "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
#set($attrValue = $input.json("$.${attrName}"))
#if($attrValue.matches("^-?\\d+$"))
#set($attrValue = """:${attrName}"": { ""N"": ${attrValue}, ")
#else
#set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
#end
#set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
#if($foreach.hasNext)
#set($expressionAttributeNames = "${expressionAttributeNames}, ")
#end
#end
{
"TableName": "TABLE",
"Key": { "id": { "S": "$input.params('id')" } },
"UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
"ExpressionAttributeNames": {$expressionAttributeNames},
"ExpressionAttributeValues": {
$expressionAttributeValues
":updatedOn": { "N": "$context.requestTimeEpoch" }
}
}
Edit: This would be a sample request body:
https://api/v1/endpoint/123
{
"location": {
"lat": 42,
"lon": -71
},
"rating": 4
}
This is the current transformation I get:
{
"TableName": "users",
"Key": { "gcn": { "S": "123" } },
"UpdateExpression": "set #number = :number, #location = :location, updatedOn = :updatedOn",
"ExpressionAttributeNames": {"#number":"number", "#location":"location"},
"ExpressionAttributeValues": {
":number": { "S": "1" }, ":location": { "S": "{\"lat\":26.89199858375187,\"lon\":75.77141155196833}" },
":updatedOn": { "N": "" }
}
}
I currently just have a test for checking if a value is a number...and it isn't working.
After doing some more digging I reached what I set out for. I have a dynamic Velocity Template mapping for AWS API Gateway for the purpose of updating DynamoDB items.
So far it supports strings, numbers, booleans, and string-escaped objects, as that's how my project stores them (they are not query-able). ExpressionAttributeNames exists in case you use a reserved keyword for an attribute name...like I did for 'location'.
If anyone has any improvements/enhancements please let me know, it's a beast of a script.
#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
#set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
#set($expressionAttributeNames = "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
#set($attrValue = $input.json("$.${attrName}"))
#if($attrValue.toString().matches("[+-]?\d+"))
#set($attrValue = """:${attrName}"": { ""N"": ""${attrValue}"" }, ")
#elseif($attrValue.toString() == "true" || $attrValue.toString() == "false")
#set($attrValue = """:${attrName}"": { ""BOOL"": ${attrValue} }, ")
#elseif(($attrValue.toString().startsWith("{") && $attrValue.toString().endsWith("}")) ||
($attrValue.toString().startsWith("[") && $attrValue.toString().endsWith("]")) )
#set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
#else
#set($attrValue = """:${attrName}"": { ""S"": " + $attrValue + " },")
#end
#set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
#if($foreach.hasNext)
#set($expressionAttributeNames = "${expressionAttributeNames}, ")
#end
#end
{
"TableName": "", ## Insert your table here.
"Key": { "gcn": { "S": "$input.params('')" } }, ## Insert your key expression here.
## Update below if `updatedOn` is not your audit attribute.
"UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
"ExpressionAttributeNames": {$expressionAttributeNames},
"ExpressionAttributeValues": {
$expressionAttributeValues
":updatedOn": { "N": "$context.requestTimeEpoch.toString()" }
}
}
Sample Request Body:
{
"firstName": "John",
"isActive": true,
"_status": 1
}
Sample Transformation:
{
"TableName": "users",
"Key": {
"id": {
"S": "1"
}
},
"UpdateExpression": "set #firstName = :firstName, #isActive = :isActive, #_status = :_status, updatedOn = :updatedOn",
"ExpressionAttributeNames": {
"#firstName": "firstName",
"#isActive": "isActive",
"#_status": "_status"
},
"ExpressionAttributeValues": {
":firstName": {
"S": "John"
},
":isActive": {
"BOOL": true
},
":_status": {
"N": "1"
},
":updatedOn": {
"N": "123456789"
}
}
}

Regex in Mongodb for ISO Date field

How can I pick all the dates with time value as 00:00:00 despite the date value? Regex doesn't work for me.
{
"_id" : ObjectId("59115a92bbf6401d4455eb21"),
"name" : "sfdfsdfsf",
"create_date" : ISODate("2013-05-13T02:34:23.000Z"),
}
something like :
db.myCollection.find({"create_date": /*T00:00:00.000Z/ })
You need to first convert created date into string of time, and if time is 00:00:00:000, then include the document.
db.test.aggregate([
// Part 1: Project all fields and add timeCriteria field that contain only time(will be used to match 00:00:00:000 time)
{
$project: {
_id: 1,
name: "$name",
create_date: "$create_date",
timeCriteria: {
$dateToString: {
format: "%H:%M:%S:%L",
date: "$create_date"
}
}
}
},
// Part 2: match the time
{
$match: {
timeCriteria: {
$eq: "00:00:00:000"
}
}
},
// Part 3: re-project document, to exclude timeCriteria field.
{
$project: {
_id: 1,
name: "$name",
create_date: "$create_date"
}
}
]);
From MongoDB version >= 4.4 we can write custom filters using $function operator.
Note: Donot forget to chage the timezone to your requirement. Timezone is not mandatory.
let timeRegex = /.*T00:00:00.000Z$/i;
db.myCollection.find({
$expr: {
$function: {
body: function (createDate, timeRegex) {
return timeRegex.test(createDate);
},
args: [{ $dateToString: { date: "$create_date", timezone: "+0530" } }, timeRegex],
lang: "js"
}
}
});

I'm getting a "You can't use Gon public methods for storing data" error - Using Gon Gem and Rails 4

When I start my application I get the following error:
Completed 500 Internal Server Error in 9ms
F, [2015-08-11T13:32:09.513613 #10107] FATAL -- :
RuntimeError (You can't use Gon public methods for storing data):
app/controllers/application_controller.rb:228:in `set_gon'
lib/middleware/security.rb:11:in `call'
Line 228 is mentioned in that error. Here is what line 227 to line 237 looks like:
if current_user
gon.current_user = { sn: current_user.sn }
gon.accounts = current_user.accounts.inject({}) do |memo, account|
memo[account.currency] = {
currency: account.currency,
balance: account.balance,
locked: account.locked
} if account.currency_obj.try(:visible)
memo
end
end
And here is what the whole method looks like:
def set_gon
gon.env = Rails.env
gon.local = I18n.locale
gon.market = current_market.attributes
gon.ticker = current_market.ticker
gon.markets = Market.to_hash
gon.pusher = {
key: ENV['PUSHER_KEY'],
wsHost: ENV['PUSHER_HOST'] || 'ws.pusherapp.com',
wsPort: ENV['PUSHER_WS_PORT'] || '80',
wssPort: ENV['PUSHER_WSS_PORT'] || '443',
encrypted: ENV['PUSHER_ENCRYPTED'] == 'true'
}
gon.clipboard = {
:click => I18n.t('actions.clipboard.click'),
:done => I18n.t('actions.clipboard.done')
}
gon.i18n = {
brand: I18n.t('gon.brand'),
ask: I18n.t('gon.ask'),
bid: I18n.t('gon.bid'),
cancel: I18n.t('actions.cancel'),
latest_trade: I18n.t('private.markets.order_book.latest_trade'),
switch: {
notification: I18n.t('private.markets.settings.notification'),
sound: I18n.t('private.markets.settings.sound')
},
notification: {
title: I18n.t('gon.notification.title'),
enabled: I18n.t('gon.notification.enabled'),
new_trade: I18n.t('gon.notification.new_trade')
},
time: {
minute: I18n.t('chart.minute'),
hour: I18n.t('chart.hour'),
day: I18n.t('chart.day'),
week: I18n.t('chart.week'),
month: I18n.t('chart.month'),
year: I18n.t('chart.year')
},
chart: {
price: I18n.t('chart.price'),
volume: I18n.t('chart.volume'),
open: I18n.t('chart.open'),
high: I18n.t('chart.high'),
low: I18n.t('chart.low'),
close: I18n.t('chart.close'),
candlestick: I18n.t('chart.candlestick'),
line: I18n.t('chart.line'),
zoom: I18n.t('chart.zoom'),
depth: I18n.t('chart.depth'),
depth_title: I18n.t('chart.depth_title')
},
place_order: {
confirm_submit: I18n.t('private.markets.show.confirm'),
confirm_cancel: I18n.t('private.markets.show.cancel_confirm'),
price: I18n.t('private.markets.place_order.price'),
volume: I18n.t('private.markets.place_order.amount'),
sum: I18n.t('private.markets.place_order.total'),
price_high: I18n.t('private.markets.place_order.price_high'),
price_low: I18n.t('private.markets.place_order.price_low'),
full_bid: I18n.t('private.markets.place_order.full_bid'),
full_ask: I18n.t('private.markets.place_order.full_ask')
},
trade_state: {
new: I18n.t('private.markets.trade_state.new'),
partial: I18n.t('private.markets.trade_state.partial')
}
}
gon.currencies = Currency.all.inject({}) do |memo, currency|
memo[currency.code] = {
code: currency[:code],
symbol: currency[:symbol],
isCoin: currency[:coin]
}
memo
end
gon.fiat_currency = Currency.first.code
gon.tickers = {}
Market.all.each do |market|
gon.tickers[market.id] = market.unit_info.merge(Global[market.id].ticker)
end
if current_user
gon.current_user = { sn: current_user.sn }
gon.accounts = current_user.accounts.inject({}) do |memo, account|
memo[account.currency] = {
currency: account.currency,
balance: account.balance,
locked: account.locked
} if account.currency_obj.try(:visible)
memo
end
end
end
Anyone know how I can fix this?
I had the same error when my code looked like this:
gon.push = ({
article_id: #article.id
})
and when I removed '=' all worked.
gon.push({
article_id: #article.id
})