Get coordinates from a Tweet using the Twitter API - java

I'm trying to correctly get information from tweets using the Twitter API and Java. I'm trying to get the exact coordinates from this tweet which have geo tag enabled.
From now, I've created the corresponding Java classes as the documentation dictates, but maybe I'm not understanding very well the Geo Objects, since neither the coordinates, bounding_box or place appear. My guess is that I'm not declaring correctly those classes.
For the Tweet class:
// Imports here
public class Tweet {
#SerializedName("created_at")
public String created_at;
#SerializedName("id")
public long id;
// ... All the rest of the parameters
#SerializedName("coordinates")
public Coordinates coordinates;
#SerializedName("place")
public transient Place place;
For the Coordinates class:
// Imports here
public class Coordinates {
#SerializedName("coordinates")
public String coordinates;
#SerializedName("type")
public String type;
}
For the Place class:
// Imports here
public class Place {
#SerializedName("id")
public String id;
#SerializedName("url")
public String url;
// ... All the rest of the parameters
#SerializedName("bounding_box")
public String bounding_box;
}
When I make a petition to get the json information from the linked tweet I get the following data, and as you can see the fields coordinates or places does not appear. If it is useful, I'm using MongoDB Java API to store the json files and its Java POJO manager. You can find all the code here: https://github.com/marmatsan/theTrainEngine
{
"_id" : NumberLong("1212893878430420992"),
"created_at" : "Fri Jan 03 00:30:09 +0000 2020",
"favorite_count" : 0,
"favorited" : false,
"id_str" : "1212893878430420992",
"is_quote_status" : false,
"lang" : "en",
"possibly_sensitive" : false,
"quoted_status_id" : NumberLong(0),
"quoted_status_id_str" : NumberLong(0),
"reply_count" : 0,
"retweet_count" : 0,
"retweeted" : false,
"source" : "Twitter for Android",
"text" : "Test 1",
"truncated" : "false",
"user" : {
"_id" : NumberLong(593955589),
"created_at" : "Tue May 29 18:59:38 +0000 2012",
"default_profile" : false,
"default_profile_image" : false,
"description" : "En búsqueda del verdadero camino del Tao estudiando Ingeniería en Tecnologías de Telecomunicación.",
"favourites_count" : 7497,
"followers_count" : 186,
"friends_count" : 114,
"id_str" : "593955589",
"listed_count" : 5,
"location" : "Salamanca/Toledo/Madrid",
"name" : "Martín 👾",
"profile_banner_url" : "https://pbs.twimg.com/profile_banners/593955589/1513111580",
"profile_image_url_https" : "https://pbs.twimg.com/profile_images/1130587021678927874/50unsAd3_normal.png",
"protected_att" : false,
"screen_name" : "MMateos97",
"statuses_count" : 19420,
"url" : "https://github.com/marmatsan",
"verified" : false
}
}
Edit: As stated in the answer, the problem is of the implementation, because when I remove the transient modifier from the Place object the program does not work. If someone has a fix for this problem please leave it in the comments.

When I request the status it has the correct fields for this status.
$ okurl https://api.twitter.com/1.1/statuses/show/1212893878430420992.json
...
"geo":null,
"coordinates":null,
"place":{"id":"fd110fb449209bc4","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/fd110fb449209bc4.json","place_type":"city","name":"Burguillos de Toledo"
https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/geo-objects#tweet-exact
Read the difference between "Tweet with Twitter Place" and "Tweet with exact location".
I suspect your "transient" field is causing Mongo not to save this field.

Related

Azure Functions CosmosDb Binding api keeps loading

First of all, the api works as intended locally, when deploying to azure functions app, the api endpoint keeps loading and it will eventually show HTTP.504(Gateway Timeout)
page keeps loading, no response from azure functions
Integration
I'm looking to fetch all data from the collection when I call HttpTrigger
Function.java
#FunctionName("get")
public HttpResponseMessage get(
#HttpTrigger(name = "req",
methods = {HttpMethod.GET, HttpMethod.POST},
authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
#CosmosDBInput(name = "database",
databaseName = "progMobile",
collectionName = "news",
partitionKey = "{Query.id}",
connectionStringSetting = "CosmosDBConnectionString")
Optional<String> item,
final ExecutionContext context) {
// Item list
context.getLogger().info("Parameters are: " + request.getQueryParameters());
context.getLogger().info("String from the database is " + (item.isPresent() ? item.get() : null));
// Convert and display
if (!item.isPresent()) {
return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
.body("Document not found.")
.build();
}
else {
// return JSON from Cosmos. Alternatively, we can parse the JSON string
// and return an enriched JSON object.
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body(item.get())
.build();
}
}
Function.json
{
"scriptFile" : "../ProgMobileBackend-1.0-SNAPSHOT.jar",
"entryPoint" : "com.function.Function.get",
"bindings" : [ {
"type" : "httpTrigger",
"direction" : "in",
"name" : "req",
"methods" : [ "GET", "POST" ],
"authLevel" : "ANONYMOUS"
}, {
"type" : "cosmosDB",
"direction" : "in",
"name" : "database",
"databaseName" : "progMobile",
"partitionKey" : "{Query.id}",
"connectionStringSetting" : "CosmosDBConnectionString",
"collectionName" : "news"
}, {
"type" : "http",
"direction" : "out",
"name" : "$return"
} ]
}
Azure Functions monitor log does not show any error
Running the function in the portal(Code + Test menu) does not show any error either
httpTrigger I'm using: https://johnmiguel.azurewebsites.net/api/get?id=id
I added CosmosDBConnectionString value to Azure Functions App configuration(did not check on "Deployment slot" option)
I'm using an instance of CosmosDB for NoSQL
Functions App runtime is set to Java and version set to Java 8
figured it out. Java function was in Java 17 and Function App in Java 8.

How get JSON Object with Retrofit 2 and Android Studio?

I am making an application in Android Studio and I want to consume API for cooking recipes, I have the following response from the API that I am consuming with Android Studio and Java:
API Response
"q" : "pollo",
"from" : 0,
"to" : 10,
"params" : {
"sane" : [ ],
"q" : [ "pollo" ],
"app_id" : [ "02" ],
"app_key" : [ "\n66b" ]
},
"more" : true,
"count" : 1000,
"hits" : [ {
"recipe" : {
"uri" : "http://www.edamam.com/ontologies/edamam.owl#recipe_d56f75c72ab67a45174441af1efe4473",
"label" : "Pollo con Crema a las Hierbas",
"image" : "http://cdn.kiwilimon.com/recetaimagen/23127/thumb120x90-15802.jpg",
"source" : "KiwiLimon",
"url" : "http://www.kiwilimon.com/receta/carnes-y-aves/pollo-con-crema-a-las-hierbas",
"shareAs" : "http://www.edamam.com/recipe/pollo-con-crema-a-las-hierbas-d56f75c72ab67a45174441af1efe4473/pollo",
"yield" : 42.0,
And continue with more 'recipe', what I want is to get only the array of hits that all the recipes have to be able to show in my application, the problem is that I get the following error:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
I understand that it is because it expects an array and it obtains a JSON object, but I do not know how to parse it, I have my Recipe model class and the RecipeService service and I manage everything in MainActivity, I have seen in some answers that I would have to do an intermediate response, but I do not understand how I could implement it in my code, then I show the classes that handle all this.
Recipe Class (Model):
public class Recipe {
private String label;
private String image;
private String source;
private String shareAs;
private List<String> dietLabels;
private List<String> healthLabels;
private List<String> cautions;
private List<String> ingredientLines;
private List<String> ingredients;
private double calories;
private double totalWeight;
private List<String> totalNutrients;
private List<String> totalDaily;
public String getLabel() {
return label;
}
.
.
.
RecipeService Class:
public interface RecipeService {
String API_ROUTE = "/search";
String API_KEY = "&app_key=" + Credentials.API_KEY;
String APP_ID = "&app_id=" + Credentials.APP_ID;
//String query = "";
#GET(API_ROUTE)
Call< List<Recipe> > getRecipe(#Query("q") String q);
}
MainActivity:
private void getRecipes() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://test-es.edamam.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
RecipeService recipeService = retrofit.create(RecipeService.class);
Call<List<Recipe>> call = recipeService.getRecipe("pollo");
System.out.println("GET RECIPES");
System.out.println("HEADERS: "+ call.request().headers());
call.enqueue(new Callback<List<Recipe>>() {
#Override
public void onResponse(Call<List<Recipe>> call, Response<List<Recipe>> response) {
System.out.println("RESPONSE CODE: " + response.code());
for(Recipe recipe : response.body()){
System.out.println("AÑADIENDO: " + recipe.getLabel());
recipes.add(recipe.getLabel());
}
//System.out.println(recipes.toArray().toString());
}
#Override
public void onFailure(Call<List<Recipe>> call, Throwable t) {
System.out.println("HA OCURRIDO UN FALLO");
System.out.println(t.getMessage());
}
});
}
If API response is exactly what you post then the response is INVALID JSON format. You may check your JSON validity by jsonlint.
Secondly, your error says,
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Which means, POJO is designed for a JSON array, but from the API you are getting a JSON object.
The solution is really simple.
There are tons of plugins in Android Studio like this, or go this online converter tool. Then hopefully you will not get the same error,

Spring boot + Jersey parse Response JSON data

I am trying to build a simple page the will display some places on the map. I'm really new to rest in Java and i'm using Spring boot + jersey framework.
I'm using google places api to search for places, i made the GET respond for a lat/lng that i'm passing thru PostMan:
http://localhost:9000/res/-23.558712/-46.592235
Inside the code im calling:
#GET
#Path("/{lat}/{lng}")
#Produces("application/json")
public void getBook(#PathParam("lat") String lat,#PathParam("lng") String lng) {
this.lat = lat;
this.lng = lng;
getdata();
}
public static void getdata(){
Client client = ClientBuilder.newClient();
String entity = client.target("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location="+ lat + "," + lng + "&radius=5000&types=market&name=dia&key=MY_KEY")
.request(MediaType.TEXT_PLAIN_TYPE)
.header("some-header", "true")
.get(String.class);
System.out.println(entity);
}
And i get a really big Json in the response:
"results" : [
{
"geometry" : {
"location" : {
"lat" : -23.5703071,
"lng" : -46.58153289999999
},
"viewport" : {
"northeast" : {
"lat" : -23.56895811970849,
"lng" : -46.5801839197085
},
"southwest" : {
"lat" : -23.5716560802915,
"lng" : -46.58288188029149
}
}
},....
And much more, my question is, how do i parse this JSON response to away that i can manage data? I want to get, name, location... to plot on the map.
I will have to create a model class with all response parameters?
I really don't know if this is all wrong.
This resource falls under reverse geocoding and if you need name of the location you should get it from "fromatted_address" attiribute, and address components will give you exact address. The following link has some information which might help you further. [reverse geocoding] https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding

MongoDB with Spring Data find object in array by id

I am using Spring Data with a Mongo DB embedded database and have the following document structure:
{
id : 111
messaage : abcd
commentsList: [
{
id : 123
text: test text
numberOfLikes : 5
numberOfDislikes: 2
}
]
}
I am trying to get a comment by id and update the numberOfLikes field by one and can't seem to get it to work, here is what I've tried and the java class structure:
public class Post {
private String id;
private String message;
private List<Comment> commentsList = new ArrayList<>();
...
}
public class Comment {
private String id;
private String text;
private int numberOfLikes;
private int numberOfDislikes;
...
}
Query query = new Query();
query.addCriteria(Criteria.where("commentsList._id").is("123"));
List<MongoComment> commentList = mongoTemplate.find(query, MongoComment.class);
Currently the returned list is always null.
Since you are trying to get a comment by id and update the numberOfLikes field by one, you essentially want to replicate this mongo shell update operation:
db.post.update(
{ "commentsList.id": "123" },
{
"$inc": { "commentsList.$.numberOfLikes": 1 }
}
)
The equivalent Spring Data MongoDB code follows:
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query;
import static org.springframework.data.mongodb.core.query.Update;
...
WriteResult wr = mongoTemplate.updateMulti(
new Query(where("commentsList.id").is("123")),
new Update().inc("commentsList.$.numberOfLikes", 1),
MongoPost.class
);
The id of the elements in the array "commentsList" is "id" (without the '_').
query.addCriteria(Criteria.where("commentsList.id").is("123"))
That should work.
The "_id" you're trying to query is the identifier Mongodb automatically generates for each document. Your document in the database looks like this:
{
_id: ObjectId("56b46e1d1d1353e38886dcc34f"),
id : 111,
messaage : "abcd",
commentsList: [
{
id : 123,
text: "test text",
numberOfLikes : 5,
numberOfDislikes: 2
}
]
}

Spring Mongo Upsert nested document

I am new bie to spring framework. I have my mongo document like
{
"_id" : ObjectId("527242d584ae917d8bd75c7b"),
"postTitle" : "Car",
"postDesc" : "rent",
"owner" : ObjectId("526a588f84aed6f41cca10bd"),
"intrest" : []
}
What I want is to search document having id
"_id" : ObjectId("527242d584ae917d8bd75c7b")
and update it to
{
"_id" : ObjectId("527242d584ae917d8bd75c7b"),
"postTitle" : "Car",
"postDesc" : "rent",
"owner" : ObjectId("526a588f84aed6f41cca10bd"),
"intrest" : [
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-10-31T11:45:25.256Z")
},
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-11-31T11:55:25.256a")
}
]
}
my domain is
#Document
public class Post {
#Id
private ObjectId _id;
private String postTitle;
private String postDesc;
private ObjectId owner=Global.getCurruser();
private List<Intrest> intrest = new ArrayList<Intrest>();
// Getters and setters
}
#Document
public class Intrest {
private ObjectId userId;
private Date timestamp;
// Getters and setters
}
What upsert should I write to add or modify entries in intrest array[].
Please Help.
I am using spring-mongodb .. Here is what I do
Intrest insertObj = new Insert();
//initilize insert obj here ..
Update args = new Update();
args.addToSet("intrest",insertObj);
Query query = new Query(Criteria.where("id").is("527242d584ae917d8bd75c7b"));
// if u want to do upsert
mongoOperation.findAndModify(query, args, FindAndModifyOptions.options().upsert(true), Post.class);
//if u want to just update
mongoOperation.findAndModify(query, args, Post.class);
I think what you intend to do is an update. Upsert will modify your document matching the given query if not it will create a new document , where as update will only modify your document if found. here is the reference
I do not know about java, but all you need to do is $pushAll operator (I really hope you can find how to do this with java driver).
db.collection.update(
{"_id" : ObjectId("527242d584ae917d8bd75c7b")},
{ $pushAll: { intrest: [ {
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-10-31T11:45:25.256Z")
},
{
"userId" : ObjectId("526a587d84aed6f41cca10bc"),
"timestamp" : ISODate("2013-11-31T11:55:25.256a")
}] } }
);

Categories