Fix uniontype compatibility issue in TweetParser
1. Fix compatibility issue of UnionType in TweetParser.
2. Add unit test for TweetParser, covering missing attribute record
filtering.
Change-Id: Id7e316d20f929236b3fa17618bb8f87d28ac7efc
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1786
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
BAD: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Steven Jacobs <sjaco002@ucr.edu>
diff --git a/asterixdb/asterix-external-data/pom.xml b/asterixdb/asterix-external-data/pom.xml
index ff9fcb0..460f57d 100644
--- a/asterixdb/asterix-external-data/pom.xml
+++ b/asterixdb/asterix-external-data/pom.xml
@@ -170,6 +170,7 @@
<exclude>src/test/resources/classad/**</exclude> <!-- HTCondor (license in LICENSE file) -->
<exclude>src/test/resources/record.json</exclude> <!-- https://issues.apache.org/jira/browse/ASTERIXDB-1850 -->
<exclude>src/test/resources/change_feed.csv</exclude>
+ <exclude>src/test/resources/test_tweets.txt</exclude>
</excludes>
</configuration>
</plugin>
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/TweetParser.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/TweetParser.java
index 1b29c887..be49863 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/TweetParser.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/TweetParser.java
@@ -24,16 +24,16 @@
import org.apache.asterix.builders.IARecordBuilder;
import org.apache.asterix.builders.IAsterixListBuilder;
import org.apache.asterix.builders.ListBuilderFactory;
+import org.apache.asterix.builders.OrderedListBuilder;
import org.apache.asterix.builders.RecordBuilderFactory;
-import org.apache.asterix.builders.UnorderedListBuilder;
import org.apache.asterix.common.exceptions.ErrorCode;
import org.apache.asterix.common.exceptions.RuntimeDataException;
import org.apache.asterix.external.api.IRawRecord;
import org.apache.asterix.external.api.IRecordDataParser;
-import org.apache.asterix.om.base.AMutablePoint;
import org.apache.asterix.om.base.ANull;
import org.apache.asterix.om.types.ARecordType;
import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.om.util.container.IObjectPool;
@@ -59,25 +59,28 @@
public TweetParser(ARecordType recordType) {
this.recordType = recordType;
- aPoint = new AMutablePoint(0, 0);
}
- private void parseUnorderedList(JsonNode jArray, DataOutput output) throws IOException {
+ private void parseArrayList(JsonNode jArray, DataOutput output) throws IOException {
ArrayBackedValueStorage itemBuffer = getTempBuffer();
- UnorderedListBuilder unorderedListBuilder = (UnorderedListBuilder) getUnorderedListBuilder();
+ OrderedListBuilder arrayBuilder = (OrderedListBuilder) getArrayBuilder();
- unorderedListBuilder.reset(null);
+ arrayBuilder.reset(null);
for (int iter1 = 0; iter1 < jArray.size(); iter1++) {
itemBuffer.reset();
if (writeField(jArray.get(iter1), null, itemBuffer.getDataOutput())) {
- unorderedListBuilder.addItem(itemBuffer);
+ arrayBuilder.addItem(itemBuffer);
}
}
- unorderedListBuilder.write(output, true);
+ arrayBuilder.write(output, true);
}
- private boolean writeField(JsonNode fieldObj, IAType fieldType, DataOutput out) throws IOException {
+ private boolean writeField(JsonNode fieldObj, IAType originalFieldType, DataOutput out) throws IOException {
boolean writeResult = true;
+ IAType fieldType = originalFieldType;
+ if (originalFieldType instanceof AUnionType) {
+ fieldType = ((AUnionType) originalFieldType).getActualType();
+ }
if (fieldType != null) {
switch (fieldType.getTypeTag()) {
case STRING:
@@ -103,6 +106,9 @@
case OBJECT:
writeRecord(fieldObj, out, (ARecordType) fieldType);
break;
+ case ARRAY:
+ parseArrayList(fieldObj, out);
+ break;
default:
writeResult = false;
}
@@ -126,7 +132,7 @@
utf8Writer.writeUTF8(fieldObj.asText(), out);
} else if (fieldObj.isArray()) {
if ((fieldObj).size() != 0) {
- parseUnorderedList(fieldObj, out);
+ parseArrayList(fieldObj, out);
} else {
writeResult = false;
}
@@ -159,6 +165,7 @@
String[] curFNames = null;
int fieldN;
int attrIdx;
+ int expectedFieldsCount = 0;
ArrayBackedValueStorage fieldValueBuffer = getTempBuffer();
ArrayBackedValueStorage fieldNameBuffer = getTempBuffer();
@@ -167,6 +174,11 @@
if (curRecType != null) {
curTypes = curRecType.getFieldTypes();
curFNames = curRecType.getFieldNames();
+ for (IAType curType : curTypes) {
+ if (!(curType instanceof AUnionType)) {
+ expectedFieldsCount++;
+ }
+ }
}
recBuilder.reset(curRecType);
@@ -178,10 +190,11 @@
for (int iter1 = 0; iter1 < fieldN; iter1++) {
fieldValueBuffer.reset();
DataOutput fieldOutput = fieldValueBuffer.getDataOutput();
- if (obj.get(curFNames[iter1]).isNull()) {
+ if (obj.get(curFNames[iter1]).isNull() && !(curTypes[iter1] instanceof AUnionType)) {
if (curRecType.isClosedField(curFNames[iter1])) {
throw new RuntimeDataException(ErrorCode.PARSER_TWEET_PARSER_CLOSED_FIELD_NULL,
- curFNames[iter1]); } else {
+ curFNames[iter1]);
+ } else {
continue;
}
} else {
@@ -198,7 +211,7 @@
Iterator<String> iter = obj.fieldNames();
while (iter.hasNext()) {
attrName = iter.next();
- if (obj.get(attrName).isNull() || obj.size() == 0) {
+ if (obj.get(attrName) == null || obj.get(attrName).isNull() || obj.size() == 0) {
continue;
}
attrIdx = checkAttrNameIdx(curFNames, attrName);
@@ -219,7 +232,7 @@
}
}
}
- if (curRecType != null && closedFieldCount < curFNames.length) {
+ if (curRecType != null && closedFieldCount < expectedFieldsCount) {
throw new HyracksDataException("Non-null field is null");
}
}
@@ -230,8 +243,8 @@
return recordBuilderPool.allocate(ATypeTag.OBJECT);
}
- private IAsterixListBuilder getUnorderedListBuilder() {
- return listBuilderPool.allocate(ATypeTag.MULTISET);
+ private IAsterixListBuilder getArrayBuilder() {
+ return listBuilderPool.allocate(ATypeTag.ARRAY);
}
private ArrayBackedValueStorage getTempBuffer() {
diff --git a/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/parser/test/TweetParserTest.java b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/parser/test/TweetParserTest.java
new file mode 100644
index 0000000..5389310
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/parser/test/TweetParserTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.external.parser.test;
+
+import static org.apache.asterix.om.types.BuiltinType.AFLOAT;
+import static org.apache.asterix.om.types.BuiltinType.AINT64;
+import static org.apache.asterix.om.types.BuiltinType.AMISSING;
+import static org.apache.asterix.om.types.BuiltinType.ANULL;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.external.input.record.GenericRecord;
+import org.apache.asterix.external.parser.TweetParser;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import junit.extensions.PA;
+
+public class TweetParserTest {
+
+ @Test
+ public void openRecordTypeTest() throws IOException, URISyntaxException {
+ String[] ids = { "720549057849114629", "668950503552864257", "668945640186101761", "263602997047730177",
+ "668948268605403136", "741701526859567104" };
+ // contruct type
+ IAType geoFieldType = new ARecordType("GeoType", new String[] { "coordinates" },
+ new IAType[] { new AOrderedListType(AFLOAT, "point") }, true);
+ List<IAType> unionTypeList = new ArrayList<>();
+ unionTypeList.add(geoFieldType);
+ unionTypeList.add(ANULL);
+ unionTypeList.add(AMISSING);
+ IAType geoUnionType = new AUnionType(unionTypeList, "GeoType?");
+ ARecordType tweetRecordType = new ARecordType("TweetType", new String[] { "id", "geo" },
+ new IAType[] { AINT64, geoUnionType }, true);
+
+ TweetParser parser = new TweetParser(tweetRecordType);
+
+ List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("/test_tweets.txt").toURI()));
+ ByteArrayOutputStream is = new ByteArrayOutputStream();
+ DataOutput output = new DataOutputStream(is);
+ for (int iter1 = 0; iter1 < lines.size(); iter1++) {
+ GenericRecord<String> record = new GenericRecord<>();
+ record.set(lines.get(iter1));
+ try {
+ parser.parse(record, output);
+ } catch (HyracksDataException e) {
+ e.printStackTrace();
+ Assert.fail("Unexpected failure in parser.");
+ }
+ Assert.assertTrue((PA.getValue(parser, "aInt64")).toString().equals(ids[iter1]));
+ }
+ }
+
+ @Test
+ public void closedRecordTypeTest() throws IOException, URISyntaxException {
+ // contruct type
+ IAType geoFieldType = new ARecordType("GeoType", new String[] { "coordinates" },
+ new IAType[] { new AOrderedListType(AFLOAT, "point") }, true);
+ ARecordType tweetRecordType = new ARecordType("TweetType", new String[] { "id", "geo" },
+ new IAType[] { AINT64, geoFieldType }, true);
+
+ TweetParser parser = new TweetParser(tweetRecordType);
+ List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("/test_tweets.txt").toURI()));
+ ByteArrayOutputStream is = new ByteArrayOutputStream();
+ DataOutput output = new DataOutputStream(is);
+ int regularCount = 0;
+ for (int iter1 = 0; iter1 < lines.size(); iter1++) {
+ GenericRecord<String> record = new GenericRecord<>();
+ record.set(lines.get(iter1));
+ try {
+ parser.parse(record, output);
+ regularCount++;
+ } catch (HyracksDataException e) {
+ Assert.assertTrue(e.toString().contains("Non-null") && (iter1 == 0 || iter1 == 1));
+ }
+ }
+ Assert.assertTrue(regularCount == 4);
+ }
+}
diff --git a/asterixdb/asterix-external-data/src/test/resources/test_tweets.txt b/asterixdb/asterix-external-data/src/test/resources/test_tweets.txt
new file mode 100644
index 0000000..ed8869a
--- /dev/null
+++ b/asterixdb/asterix-external-data/src/test/resources/test_tweets.txt
@@ -0,0 +1,6 @@
+{"created_at":"Thu Apr 14 09:47:37 +0000 2016","id":720549057849114629,"id_str":"720549057849114629","text":"Pumpins and mother lovin humpins! https:\/\/t.co\/UFY2ptZEDE","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":22718875,"id_str":"22718875","name":"Austin Ireland","screen_name":"fastirish","location":"GaageBox2.0","url":null,"description":"CrossFit, raising elite offspring and tattoos. O, and tiny dogs!! #garagebox2.0 #unaffiliated","protected":false,"verified":false,"followers_count":206,"friends_count":336,"listed_count":10,"favourites_count":888,"statuses_count":1775,"created_at":"Wed Mar 04 02:14:49 +0000 2009","utc_offset":-14400,"time_zone":"Eastern Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"352726","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme5\/bg.gif","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme5\/bg.gif","profile_background_tile":false,"profile_link_color":"D02B55","profile_sidebar_border_color":"829D5E","profile_sidebar_fill_color":"99CC33","profile_text_color":"3E4415","profile_use_background_image":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/712092320099868672\/YUUcDgwG_normal.jpg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/712092320099868672\/YUUcDgwG_normal.jpg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/22718875\/1458315357","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":{"id":"07d9d0f1fd482001","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/07d9d0f1fd482001.json","place_type":"poi","name":"Steeplechase","full_name":"Steeplechase","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-75.655008,38.355629],[-75.655008,38.355629],[-75.655008,38.355629],[-75.655008,38.355629]]]},"attributes":{}},"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"urls":[],"user_mentions":[],"symbols":[],"media":[{"id":720549047702986752,"id_str":"720549047702986752","indices":[34,57],"media_url":"http:\/\/pbs.twimg.com\/media\/Cf_nio-VIAAd6wB.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/Cf_nio-VIAAd6wB.jpg","url":"https:\/\/t.co\/UFY2ptZEDE","display_url":"pic.twitter.com\/UFY2ptZEDE","expanded_url":"http:\/\/twitter.com\/fastirish\/status\/720549057849114629\/photo\/1","type":"photo","sizes":{"small":{"w":340,"h":453,"resize":"fit"},"large":{"w":960,"h":1280,"resize":"fit"},"medium":{"w":600,"h":800,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"}}}]},"extended_entities":{"media":[{"id":720549047702986752,"id_str":"720549047702986752","indices":[34,57],"media_url":"http:\/\/pbs.twimg.com\/media\/Cf_nio-VIAAd6wB.jpg","media_url_https":"https:\/\/pbs.twimg.com\/media\/Cf_nio-VIAAd6wB.jpg","url":"https:\/\/t.co\/UFY2ptZEDE","display_url":"pic.twitter.com\/UFY2ptZEDE","expanded_url":"http:\/\/twitter.com\/fastirish\/status\/720549057849114629\/photo\/1","type":"photo","sizes":{"small":{"w":340,"h":453,"resize":"fit"},"large":{"w":960,"h":1280,"resize":"fit"},"medium":{"w":600,"h":800,"resize":"fit"},"thumb":{"w":150,"h":150,"resize":"crop"}}}]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en","timestamp_ms":"1460627257202"}
+{"created_at":"Tue Nov 24 00:33:23 +0000 2015","id":668950503552864257,"id_str":"668950503552864257","text":"@K_Jenkins22 I know it could always be worse, lol I could always be a saints fan \ud83d\ude02","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":668949646656593920,"in_reply_to_status_id_str":"668949646656593920","in_reply_to_user_id":322358152,"in_reply_to_user_id_str":"322358152","in_reply_to_screen_name":"K_Jenkins22","user":{"id":375920299,"id_str":"375920299","name":"Taylor Casey","screen_name":"TeeCasey11","location":"Louisville Ky","url":null,"description":"I cant drown my demons they know how to swim","protected":false,"verified":false,"followers_count":614,"friends_count":327,"listed_count":1,"favourites_count":1518,"statuses_count":25058,"created_at":"Mon Sep 19 00:06:07 +0000 2011","utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"C0DEED","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme1\/bg.png","profile_background_tile":false,"profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/650694639981363200\/baMfTh4z_normal.jpg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/650694639981363200\/baMfTh4z_normal.jpg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/375920299\/1395204592","default_profile":true,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":{"id":"000df0c11a2783f2","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/000df0c11a2783f2.json","place_type":"city","name":"Hillview","full_name":"Hillview, KY","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-85.710047,38.029300],[-85.710047,38.086251],[-85.608063,38.086251],[-85.608063,38.029300]]]},"attributes":{}},"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"urls":[],"user_mentions":[{"screen_name":"K_Jenkins22","name":"Kirsty Jenkins","id":322358152,"id_str":"322358152","indices":[0,12]}],"symbols":[]},"favorited":false,"retweeted":false,"filter_level":"low","lang":"en","timestamp_ms":"1448325203203"}
+{"created_at":"Tue Nov 24 00:14:03 +0000 2015","id":668945640186101761,"id_str":"668945640186101761","text":"Just posted a photo @ Campus Martius Park https:\/\/t.co\/5Ax4E2CdWZ","source":"\u003ca href=\"http:\/\/instagram.com\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":48121888,"id_str":"48121888","name":"Kevin McKague","screen_name":"KevinOfMI","location":"Davison, Michigan","url":"http:\/\/KevinMcKague.wordpress.com","description":"I need to ride my bike until my brain shuts up and my muscles are screaming.\u00a0\nRight after these donuts. Dad of 3.\n Visit my blog 18 Wheels and a 12-Speed Bike.","protected":false,"verified":false,"followers_count":1178,"friends_count":1780,"listed_count":50,"favourites_count":2319,"statuses_count":22263,"created_at":"Wed Jun 17 21:24:03 +0000 2009","utc_offset":-18000,"time_zone":"Eastern Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"EBF5ED","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/378800000153875492\/VrUNrXXF.jpeg","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/378800000153875492\/VrUNrXXF.jpeg","profile_background_tile":true,"profile_link_color":"0084B4","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"DDFFCC","profile_text_color":"333333","profile_use_background_image":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/646097130977890304\/izCl0tCD_normal.jpg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/646097130977890304\/izCl0tCD_normal.jpg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/48121888\/1441581344","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":{"type":"Point","coordinates":[42.33170228,-83.04647491]},"coordinates":{"type":"Point","coordinates":[-83.04647491,42.33170228]},"place":{"id":"b463d3bd6064861b","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/b463d3bd6064861b.json","place_type":"city","name":"Detroit","full_name":"Detroit, MI","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-83.288056,42.255085],[-83.288056,42.450488],[-82.910520,42.450488],[-82.910520,42.255085]]]},"attributes":{}},"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"urls":[{"url":"https:\/\/t.co\/5Ax4E2CdWZ","expanded_url":"https:\/\/instagram.com\/p\/-cnH0kFL_g\/","display_url":"instagram.com\/p\/-cnH0kFL_g\/","indices":[42,65]}],"user_mentions":[],"symbols":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en","timestamp_ms":"1448324043686"}
+{"contributors":null,"text":"@Thaynalhul qosjaosjoa e tu nem viu","geo":{"type":"Point","coordinates":[-29.9460537,-50.99058655]},"retweeted":false,"in_reply_to_screen_name":"Thaynalhul","truncated":false,"entities":{"urls":[],"hashtags":[],"user_mentions":[{"id":157459005,"name":"Thayná Lhul","indices":[0,11],"screen_name":"Thaynalhul","id_str":"157459005"}]},"in_reply_to_status_id_str":"263602825592979456","id":263602997047730177,"in_reply_to_user_id_str":"157459005","source":"<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone<\/a>","favorited":false,"in_reply_to_status_id":263602825592979456,"in_reply_to_user_id":157459005,"retweet_count":0,"created_at":"Wed Oct 31 11:27:06 +0000 2012","id_str":"263602997047730177","place":{"id":"66a72011ed6d4853","bounding_box":{"type":"Polygon","coordinates":[[[-51.1012029,-30.0156525],[-50.8114625,-30.0156525],[-50.8114625,-29.765777],[-51.1012029,-29.765777]]]},"place_type":"city","name":"Gravataí","attributes":{},"country_code":"BR","url":"http://api.twitter.com/1/geo/id/66a72011ed6d4853.json","full_name":"Gravataí, Rio Grande do Sul","country":"Brasil"},"user":{"location":"","default_profile":false,"profile_background_tile":true,"statuses_count":26476,"lang":"pt","profile_link_color":"0099CC","profile_banner_url":"https://si0.twimg.com/profile_banners/338399662/1351549264","id":338399662,"following":null,"protected":false,"favourites_count":247,"profile_text_color":"333333","contributors_enabled":false,"verified":false,"description":"\u201cPorque a vida só dá pra quem se deu, pra quem amou, pra quem chorou, pra quem sofreu.\u201d #Belieber ","name":"beatriz ","profile_sidebar_border_color":"fff","profile_background_color":"FFF04D","created_at":"Tue Jul 19 14:39:45 +0000 2011","default_profile_image":false,"followers_count":998,"profile_image_url_https":"https://si0.twimg.com/profile_images/2778405459/f682a9eadbbe5ed9bc37c9e8e5a1d33b_normal.jpeg","geo_enabled":true,"profile_background_image_url":"http://a0.twimg.com/profile_background_images/697292787/7156609856becbed318bffd052449fc8.jpeg","profile_background_image_url_https":"https://si0.twimg.com/profile_background_images/697292787/7156609856becbed318bffd052449fc8.jpeg","follow_request_sent":null,"url":"http://ask.fm/soudaviuscka","utc_offset":-14400,"time_zone":"Santiago","notifications":null,"profile_use_background_image":true,"friends_count":277,"profile_sidebar_fill_color":"E6F6F9","screen_name":"bewexell","id_str":"338399662","profile_image_url":"http://a0.twimg.com/profile_images/2778405459/f682a9eadbbe5ed9bc37c9e8e5a1d33b_normal.jpeg","is_translator":false,"listed_count":3},"coordinates":{"type":"Point","coordinates":[-50.99058655,-29.9460537]}}
+{"created_at":"Tue Nov 24 00:24:30 +0000 2015","id":668948268605403136,"id_str":"668948268605403136","text":"\u26a1\ufe0fFeed me energy, I'll feed it back\/Spread love\/ Be the energy. It's more to opening your eyes. After\u2026 https:\/\/t.co\/SYWXANPYxI","source":"\u003ca href=\"http:\/\/instagram.com\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":35392759,"id_str":"35392759","name":"See-Oh-Be-Uh","screen_name":"ItsSeobia","location":"Exploring","url":null,"description":"Lifestyle over everything. We might take a break, but we don't quit. #Active #MovementSpeaksLouderThanYourTweets #EarnYourStripes","protected":false,"verified":false,"followers_count":951,"friends_count":471,"listed_count":28,"favourites_count":690,"statuses_count":49387,"created_at":"Sun Apr 26 03:38:50 +0000 2009","utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"A336F7","profile_background_image_url":"http:\/\/pbs.twimg.com\/profile_background_images\/215051616\/purple_flower.jpg","profile_background_image_url_https":"https:\/\/pbs.twimg.com\/profile_background_images\/215051616\/purple_flower.jpg","profile_background_tile":true,"profile_link_color":"05FF22","profile_sidebar_border_color":"099FF0","profile_sidebar_fill_color":"030003","profile_text_color":"8911B8","profile_use_background_image":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/574735896752308225\/EDeXr2-5_normal.png","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/574735896752308225\/EDeXr2-5_normal.png","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/35392759\/1428866329","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":{"type":"Point","coordinates":[41.8,-87.59]},"coordinates":{"type":"Point","coordinates":[-87.59,41.8]},"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[],"urls":[{"url":"https:\/\/t.co\/SYWXANPYxI","expanded_url":"https:\/\/instagram.com\/p\/-coUG4GMYI\/","display_url":"instagram.com\/p\/-coUG4GMYI\/","indices":[103,126]}],"user_mentions":[],"symbols":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en","timestamp_ms":"1448324670350"}
+{"created_at":"Sat Jun 11 18:39:58 +0000 2016","id":741701526859567104,"id_str":"741701526859567104","text":"Jazz Age Lawn Party #jalp2016 #governorsisland @ Governors Island https:\/\/t.co\/kj4dLzdngB","source":"\u003ca href=\"http:\/\/instagram.com\" rel=\"nofollow\"\u003eInstagram\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":17816081,"id_str":"17816081","name":"Paul Herrera","screen_name":"pherrera","location":"New York, NY","url":"http:\/\/www.pherrera.com","description":"The Michael Jordan of something","protected":false,"verified":false,"followers_count":479,"friends_count":443,"listed_count":36,"favourites_count":40,"statuses_count":12911,"created_at":"Tue Dec 02 19:36:06 +0000 2008","utc_offset":-14400,"time_zone":"Eastern Time (US & Canada)","geo_enabled":true,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"352726","profile_background_image_url":"http:\/\/abs.twimg.com\/images\/themes\/theme5\/bg.gif","profile_background_image_url_https":"https:\/\/abs.twimg.com\/images\/themes\/theme5\/bg.gif","profile_background_tile":false,"profile_link_color":"D02B55","profile_sidebar_border_color":"829D5E","profile_sidebar_fill_color":"99CC33","profile_text_color":"3E4415","profile_use_background_image":true,"profile_image_url":"http:\/\/pbs.twimg.com\/profile_images\/719606026153144321\/JrfcfLdP_normal.jpg","profile_image_url_https":"https:\/\/pbs.twimg.com\/profile_images\/719606026153144321\/JrfcfLdP_normal.jpg","profile_banner_url":"https:\/\/pbs.twimg.com\/profile_banners\/17816081\/1354488949","default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":{"type":"Point","coordinates":[40.69138889,-74.01611111]},"coordinates":{"type":"Point","coordinates":[-74.01611111,40.69138889]},"place":{"id":"01a9a39529b27f36","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/01a9a39529b27f36.json","place_type":"city","name":"Manhattan","full_name":"Manhattan, NY","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-74.026675,40.683935],[-74.026675,40.877483],[-73.910408,40.877483],[-73.910408,40.683935]]]},"attributes":{}},"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"entities":{"hashtags":[{"text":"jalp2016","indices":[20,29]},{"text":"governorsisland","indices":[30,46]}],"urls":[{"url":"https:\/\/t.co\/kj4dLzdngB","expanded_url":"https:\/\/www.instagram.com\/p\/BGhkqneIg8O\/","display_url":"instagram.com\/p\/BGhkqneIg8O\/","indices":[66,89]}],"user_mentions":[],"symbols":[]},"favorited":false,"retweeted":false,"possibly_sensitive":false,"filter_level":"low","lang":"en","timestamp_ms":"1465670398808"}
\ No newline at end of file