streams-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (STREAMS-553) Implement Premium Search in streams-provider-twitter
Date Tue, 05 Dec 2017 01:58:00 GMT

    [ https://issues.apache.org/jira/browse/STREAMS-553?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16277885#comment-16277885
] 

ASF GitHub Bot commented on STREAMS-553:
----------------------------------------

steveblackmon closed pull request #405: STREAMS-553: Implement Premium Search in streams-provider-twitter
URL: https://github.com/apache/streams/pull/405
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
new file mode 100644
index 000000000..313832b9a
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearch.java
@@ -0,0 +1,48 @@
+/*
+ * 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
+ *
+ *   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.streams.twitter.api;
+
+import org.apache.juneau.remoteable.Body;
+import org.apache.juneau.remoteable.Path;
+import org.apache.juneau.remoteable.QueryIfNE;
+import org.apache.juneau.remoteable.RemoteMethod;
+import org.apache.juneau.remoteable.Remoteable;
+
+
+/**
+ * Interface for /search methods.
+ */
+@Remoteable(path = "https://api.twitter.com/1.1/"+ThirtyDaySearch.path)
+public interface ThirtyDaySearch {
+
+  String path = "tweets/search/30day";
+
+  /**
+   * Returns a collection of relevant Tweets matching a specified query.
+   *
+   * @param environment "environment to use"
+   * @param searchRequest {@link org.apache.streams.twitter.api.ThirtyDaySearchRequest}
+   * @return {@link ThirtyDaySearchResponse}
+   * @see <a href=https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search">https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search</a>
+   *
+   */
+  @RemoteMethod(httpMethod = "POST", path = "/{environment}.json")
+  public ThirtyDaySearchResponse thirtyDaySearch(@Path("environment") String environment,
@Body ThirtyDaySearchRequest searchRequest);
+
+}
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
new file mode 100644
index 000000000..cb89155d5
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/ThirtyDaySearchCounts.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ *
+ *   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.streams.twitter.api;
+
+import org.apache.juneau.remoteable.Body;
+import org.apache.juneau.remoteable.Path;
+import org.apache.juneau.remoteable.RemoteMethod;
+import org.apache.juneau.remoteable.Remoteable;
+
+
+/**
+ * Interface for /search methods.
+ */
+@Remoteable(path = "https://api.twitter.com/1.1/"+ ThirtyDaySearch.path)
+public interface ThirtyDaySearchCounts {
+
+  /**
+   * Returns counts of relevant Tweets matching a specified query.
+   *
+   * @param environment "environment to use"
+   * @param searchCountsRequest {@link org.apache.streams.twitter.api.ThirtyDaySearchCountsRequest}
+   * @return {@link ThirtyDaySearchCountsResponse}
+   * @see <a href=https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search">https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search</a>
+   *
+   */
+  @RemoteMethod(httpMethod = "POST", path = "/{environment}/counts.json")
+  public ThirtyDaySearchCountsResponse thirtyDaySearchCounts(@Path("environment") String
environment, @Body ThirtyDaySearchCountsRequest searchCountsRequest);
+
+}
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
index 679e6b11e..e3cdf5209 100644
--- a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/api/Twitter.java
@@ -32,6 +32,7 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.commons.lang.NotImplementedException;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.client.config.RequestConfig;
@@ -59,7 +60,21 @@
 /**
  * Implementation of all twitter interfaces using juneau.
  */
-public class Twitter implements Account, AccountActivity, DirectMessages, Favorites, Followers,
Friends, SevenDaySearch, Statuses, SuggestedUsers, Users, WelcomeMessages, WelcomeMessageRules
{
+public class Twitter implements
+  Account,
+  AccountActivity,
+  DirectMessages,
+  Favorites,
+  Followers,
+  Friends,
+  SevenDaySearch,
+  Statuses,
+  SuggestedUsers,
+  ThirtyDaySearch,
+  ThirtyDaySearchCounts,
+  Users,
+  WelcomeMessages,
+  WelcomeMessageRules {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(Twitter.class);
 
@@ -421,6 +436,20 @@ public SevenDaySearchResponse sevenDaySearch(SevenDaySearchRequest event)
{
     return proxy.sevenDaySearch(event);
   }
 
+  @Override
+  public ThirtyDaySearchResponse thirtyDaySearch(String environment, ThirtyDaySearchRequest
searchRequest) {
+    ThirtyDaySearch proxy = restClient.getRemoteableProxy(ThirtyDaySearch.class, TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
+    String env = StringUtils.defaultString(environment, configuration.getEnvironment());
+    return proxy.thirtyDaySearch(env, searchRequest);
+  }
+
+  @Override
+  public ThirtyDaySearchCountsResponse thirtyDaySearchCounts(String environment, ThirtyDaySearchCountsRequest
searchCountsRequest) {
+    ThirtyDaySearchCounts proxy = restClient.getRemoteableProxy(ThirtyDaySearchCounts.class,
TwitterProviderUtil.baseUrl(configuration)+"/"+ThirtyDaySearch.path);
+    String env = StringUtils.defaultString(environment, configuration.getEnvironment());
+    return proxy.thirtyDaySearchCounts(env, searchCountsRequest);
+  }
+
   @Override
   public DirectMessage destroy(Long id) {
     throw new NotImplementedException();
diff --git a/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/search/SearchUtil.java
b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/search/SearchUtil.java
new file mode 100644
index 000000000..efca26a6a
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/java/org/apache/streams/twitter/search/SearchUtil.java
@@ -0,0 +1,114 @@
+package org.apache.streams.twitter.search;
+
+import org.apache.streams.twitter.api.ThirtyDaySearch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.StringJoiner;
+
+public class SearchUtil {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(SearchUtil.class);
+
+  public static String toString(ThirtyDaySearchOperator operator) {
+    return toStringJoiner(operator).toString();
+  }
+
+  public static StringJoiner toStringJoiner(ThirtyDaySearchOperator operator) {
+    StringJoiner stringJoiner = new StringJoiner(" ");
+    if(operator.getNot()) {
+      stringJoiner.add("-");
+    }
+    stringJoiner.add("(");
+    for( String keyword : operator.getKeywords()) {
+      stringJoiner.add(keyword);
+    }
+    for( String emoji : operator.getEmojis()) {
+      stringJoiner.add(emoji);
+    }
+    for( String exact_phrase : operator.getExactPhrases()) {
+      stringJoiner.add(phrase(exact_phrase));
+    }
+    for( String from : operator.getFroms()) {
+      stringJoiner.add("from:" + from);
+    }
+    for( String to : operator.getTos()) {
+      stringJoiner.add("to:" + to);
+    }
+    for( String mention : operator.getMentions()) {
+      stringJoiner.add("@" + mention);
+    }
+    for( String retweets_of : operator.getRetweetsOfs()) {
+      stringJoiner.add("retweets_of:" + retweets_of);
+    }
+    for( String hashtag : operator.getHashtags()) {
+      stringJoiner.add("#" + hashtag);
+    }
+    for( String url : operator.getUrls()) {
+      stringJoiner.add("url:" + phrase(url));
+    }
+    for( String bio : operator.getBios()) {
+      stringJoiner.add("bio:" + phrase(bio));
+    }
+    for( String bio_location : operator.getBioLocations()) {
+      stringJoiner.add("bio_location:" + phrase(bio_location));
+    }
+    for( String bio_name : operator.getBioNames()) {
+      stringJoiner.add("bio_name:" + bio_name);
+    }
+    for( String place : operator.getPlaces()) {
+      stringJoiner.add("place:" + place);
+    }
+    for( String place_country : operator.getPlaceCountrys()) {
+      stringJoiner.add("place_country:" + phrase(place_country));
+    }
+    for( String point_radius : operator.getPointRadiuses()) {
+      stringJoiner.add("point_radius:" + point_radius);
+    }
+    for( String bounding_box : operator.getBoundingBoxes()) {
+      stringJoiner.add("bounding_box:" + bounding_box);
+    }
+    for( String time_zone : operator.getTimeZones()) {
+      stringJoiner.add("time_zone:" + time_zone);
+    }
+    if( operator.getHasImages() ) {
+      stringJoiner.add("has:images");
+    }
+    if( operator.getHasLinks() ) {
+      stringJoiner.add("has:links");
+    }
+    if( operator.getHasMedia() ) {
+      stringJoiner.add("has:media");
+    }
+    if( operator.getHasImages() ) {
+      stringJoiner.add("has:image");
+    }
+    if( operator.getHasVideos() ) {
+      stringJoiner.add("has:video");
+    }
+    if(operator.getAnds().size() > 0) {
+      for( ThirtyDaySearchOperator suboperator : operator.getAnds()) {
+        stringJoiner.add("AND");
+        stringJoiner.add(SearchUtil.toString(suboperator));
+      }
+    }
+    if(operator.getOrs().size() > 0) {
+      for( ThirtyDaySearchOperator suboperator : operator.getOrs()) {
+        stringJoiner.add("OR");
+        stringJoiner.add(SearchUtil.toString(suboperator));
+      }
+    }
+    stringJoiner.add(")");
+    return stringJoiner;
+  }
+
+  static String phrase(String in) {
+    if( in.contains(" ")) {
+      return "\"" + in + "\"";
+    } else {
+      return in;
+    }
+  }
+
+}
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsRequest.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsRequest.json
new file mode 100644
index 000000000..9aa5bb9e3
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsRequest.json
@@ -0,0 +1,42 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "javaType" : "org.apache.streams.twitter.api.ThirtyDaySearchCountsRequest",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search#CountsParameters",
+  "properties": {
+    "query": {
+      "description": "The equivalent of one Gnip PowerTrack rule, with up to 2048 characters
(and no limits on the number of positive and negative clauses).  This parameter should include
ALL portions of the PowerTrack rule, including all operators, and portions of the rule should
not be separated into other parameters of the query.",
+      "required": true,
+      "type": "string"
+    },
+    "fromDate": {
+      "description": "The oldest UTC timestamp (back to 3/21/2006) from which the activities
will be provided. Timestamp is in minute granularity and is inclusive (i.e. 12:00 includes
the 00 minute).",
+      "required": false,
+      "type": "string"
+    },
+    "toDate": {
+      "description": "The latest, most recent UTC timestamp to which the activities will
be provided. Timestamp is in minute granularity and is not inclusive (i.e. 11:59 does not
include the 59th minute of the hour).",
+      "required": false,
+      "type": "string"
+    },
+    "bucket": {
+      "description": "The unit of time for which count data will be provided. Count data
can be returned for every day, hour or minute in the requested timeframe. By default, hourly
counts will be provided..",
+      "required": false,
+      "type": "string",
+      "enum": [
+        "day",
+        "hour",
+        "minute"
+      ]
+    },
+    "next": {
+      "description": "This parameter is used to get the next \"page\" of results.",
+      "required": false,
+      "type": "string"
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsResponse.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsResponse.json
new file mode 100644
index 000000000..1c3aaa276
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchCountsResponse.json
@@ -0,0 +1,41 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "javaType" : "org.apache.streams.twitter.api.ThirtyDaySearchCountsResponse",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search",
+  "properties": {
+    "totalCount": {
+      "description": "totalCount.",
+      "type": "integer"
+    },
+    "results": {
+      "description": "The results.",
+      "type": "array",
+      "items": {
+        "type": "object",
+        "javaType": "org.apache.streams.twitter.api.ThirtyDaySearchCountItem",
+        "properties": {
+          "timePeriod": {
+            "type": "string"
+          },
+          "count": {
+            "type": "integer"
+          }
+        }
+      }
+    },
+    "next": {
+      "description": "This parameter is used to get the next \"page\" of results.",
+      "required": false,
+      "type": "string"
+    },
+    "requestParameters": {
+      "description": "The request Parameters.",
+      "$ref": "./ThirtyDaySearchCountsRequest.json"
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchRequest.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchRequest.json
new file mode 100644
index 000000000..21f5cceb0
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchRequest.json
@@ -0,0 +1,42 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "javaType" : "org.apache.streams.twitter.api.ThirtyDaySearchRequest",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search",
+  "properties": {
+    "query": {
+      "description": "The equivalent of one Gnip PowerTrack rule, with up to 2048 characters
(and no limits on the number of positive and negative clauses).  This parameter should include
ALL portions of the PowerTrack rule, including all operators, and portions of the rule should
not be separated into other parameters of the query.",
+      "required": true,
+      "type": "string"
+    },
+    "fromDate": {
+      "description": "The oldest UTC timestamp (back to 3/21/2006) from which the activities
will be provided. Timestamp is in minute granularity and is inclusive (i.e. 12:00 includes
the 00 minute).",
+      "required": false,
+      "type": "string"
+    },
+    "toDate": {
+      "description": "The latest, most recent UTC timestamp to which the activities will
be provided. Timestamp is in minute granularity and is not inclusive (i.e. 11:59 does not
include the 59th minute of the hour).",
+      "required": false,
+      "type": "string"
+    },
+    "maxResults": {
+      "description": "The maximum number of search results to be returned by a request. A
number between 10 and the system limit (currently 500). By default, a request response will
return 100 results.",
+      "required": false,
+      "type": "integer"
+    },
+    "next": {
+      "description": "This parameter is used to get the next \"page\" of results.",
+      "required": false,
+      "type": "string"
+    },
+    "tag": {
+      "description": "Tags can be used to segregate rules and their matching data into different
logical groups.",
+      "required": false,
+      "type": "string"
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchResponse.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchResponse.json
new file mode 100644
index 000000000..33d1b8d93
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/api/ThirtyDaySearchResponse.json
@@ -0,0 +1,28 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "javaType" : "org.apache.streams.twitter.api.ThirtyDaySearchResponse",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "https://developer.twitter.com/en/docs/tweets/search/api-reference/30-day-search",
+  "properties": {
+    "results": {
+      "description": "The results.",
+      "type": "array",
+      "items": {
+        "$ref": "../pojo/tweet.json"
+      }
+    },
+    "next": {
+      "description": "This parameter is used to get the next \"page\" of results.",
+      "required": false,
+      "type": "string"
+    },
+    "requestParameters": {
+      "description": "The request Parameters.",
+      "$ref": "./ThirtyDaySearchRequest.json"
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/SearchGroups.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/SearchGroups.json
new file mode 100644
index 000000000..94266531e
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/SearchGroups.json
@@ -0,0 +1,105 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "type": "object",
+  "javaType" : "org.apache.streams.twitter.search.SearchOperators",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "",
+  "properties": {
+    "keyword": {
+      "description": "Matches a keyword within the body of a Tweet.",
+      "type": "string"
+    },
+    "emoji": {
+      "description": "Matches an emoji within the body of a Tweet.",
+      "type": "string"
+    },
+    "exact_phrase": {
+      "description": "Matches an exact phrase within the body of a Tweet.",
+      "type": "string"
+    },
+    "from": {
+      "description": "Matches any Tweet from a specific user (name or ID).",
+      "type": "string"
+    },
+    "to": {
+      "description": "Matches any Tweet that is in reply to a particular user.",
+      "type": "string"
+    },
+    "mention": {
+      "description": "Matches any Tweet that mentions the given user (name or ID).",
+      "type": "string"
+    },
+    "retweets_of": {
+      "description": "Matches Retweets that are Tweets of a specified user (name or ID).",
+      "type": "string"
+    },
+    "hashtag": {
+      "description": "Matches any Tweet with the given hashtag.",
+      "type": "string"
+    },
+    "url": {
+      "description": "Performs a tokenized (keyword/phrase) match on the expanded URLs of
a Tweet.",
+      "type": "string"
+    },
+    "bio": {
+      "description": "Matches a keyword or phrase within the user bio of a Tweet.",
+      "type": "string"
+    },
+    "bio_name": {
+      "description": "Matches a keyword within the user bio name of a Tweet.",
+      "type": "string"
+    },
+    "bio_location": {
+      "description": "Matches Tweets where the user’s bio-level location contains the specified
keyword or phrase.",
+      "type": "string"
+    },
+    "place": {
+      "description": "Matches Tweets tagged with a specified location or 'Twitter place.",
+      "type": "string"
+    },
+    "place_country": {
+      "description": "Matches Tweets tagged with the specified location or Twitter place
ID (see examples). Multi-word place names (“New York City”, “Palo Alto”) should be
enclosed in quotes.",
+      "type": "string"
+    },
+    "point_radius": {
+      "description": "Matches against the Exact Location (x,y) of the Tweet when present,
and in Twitter, against a “Place” geo polygon, where the Place is fully contained within
the defined region.",
+      "type": "string"
+    },
+    "bounding_box": {
+      "description": "Matches against the Exact Location (x,y) of the Tweet when present,
and in Twitter, against a “Place” geo polygon.",
+      "type": "string"
+    },
+    "time_zone": {
+      "description": "Matches Tweets where the user-selected time zone specified in a user’s
profile settings matches a given string.",
+      "type": "string"
+    },
+    "has_links": {
+      "description": "This operator matches Tweets which contain links in the message body.",
+      "type": "boolean"
+    },
+    "lang": {
+      "description": "Matches Tweets that have been classified by Twitter as being of a particular
language. Assigned to one of over 50 languages or marked as 'undefined.'",
+      "type": "string"
+    },
+    "has_mentions": {
+      "description": "Matches Tweets that mention another Twitter user.",
+      "type": "boolean"
+    },
+    "has_images": {
+      "description": "A boolean search operator that returns all Tweets that contain a native
images (e.g. pic.twitter.com).",
+      "type": "boolean"
+    },
+    "has_videos": {
+      "description": "A boolean search operator that returns all Tweets that contain native
videos (does not include vine, periscope).",
+      "type": "boolean"
+    },
+    "has_media": {
+      "description": "Matches Tweets that contain a media url classified by Twitter, e.g.
pic.twitter.com.",
+      "type": "boolean"
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/ThirtyDaySearchOperator.json
b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/ThirtyDaySearchOperator.json
new file mode 100644
index 000000000..2ae16571b
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/main/jsonschema/org/apache/streams/twitter/search/ThirtyDaySearchOperator.json
@@ -0,0 +1,183 @@
+{
+  "$schema": "http://json-schema.org/draft-03/schema",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "id": "#",
+  "type": "object",
+  "javaType" : "org.apache.streams.twitter.search.ThirtyDaySearchOperator",
+  "javaInterfaces": ["java.io.Serializable"],
+  "description": "",
+  "properties": {
+    "keywords": {
+      "description": "Matches a keyword within the body of a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "emojis": {
+      "description": "Matches an emoji within the body of a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "exact_phrases": {
+      "description": "Matches an exact phrase within the body of a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "froms": {
+      "description": "Matches any Tweet from a specific user (name or ID).",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "tos": {
+      "description": "Matches any Tweet that is in reply to a particular user.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "mentions": {
+      "description": "Matches any Tweet that mentions the given user (name or ID).",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "retweets_ofs": {
+      "description": "Matches Retweets that are Tweets of a specified user (name or ID).",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "hashtags": {
+      "description": "Matches any Tweet with the given hashtag.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "urls": {
+      "description": "Performs a tokenized (keyword/phrase) match on the expanded URLs of
a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "bios": {
+      "description": "Matches a keyword or phrase within the user bio of a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "bio_names": {
+      "description": "Matches a keyword within the user bio name of a Tweet.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "bio_locations": {
+      "description": "Matches Tweets where the user’s bio-level location contains the specified
keyword or phrase.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "places": {
+      "description": "Matches Tweets tagged with a specified location or 'Twitter place.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "place_countrys": {
+      "description": "Matches Tweets tagged with the specified location or Twitter place
ID (see examples). Multi-word place names (“New York City”, “Palo Alto”) should be
enclosed in quotes.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "point_radiuses": {
+      "description": "Matches against the Exact Location (x,y) of the Tweet when present,
and in Twitter, against a “Place” geo polygon, where the Place is fully contained within
the defined region.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "bounding_boxes": {
+      "description": "Matches against the Exact Location (x,y) of the Tweet when present,
and in Twitter, against a “Place” geo polygon.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "time_zones": {
+      "description": "Matches Tweets where the user-selected time zone specified in a user’s
profile settings matches a given string.",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "langs": {
+      "description": "Matches Tweets that have been classified by Twitter as being of a particular
language. Assigned to one of over 50 languages or marked as 'undefined.'",
+      "type": "array",
+      "items": {
+        "type": "string"
+      }
+    },
+    "has_images": {
+      "description": "A boolean search operator that returns all Tweets that contain a native
images (e.g. pic.twitter.com).",
+      "type": "boolean",
+      "default": false
+    },
+    "has_links": {
+      "description": "This operator matches Tweets which contain links in the message body.",
+      "type": "boolean",
+      "default": false
+    },
+    "has_mentions": {
+      "description": "Matches Tweets that mention another Twitter user.",
+      "type": "boolean",
+      "default": false
+    },
+    "has_videos": {
+      "description": "A boolean search operator that returns all Tweets that contain native
videos (does not include vine, periscope).",
+      "type": "boolean",
+      "default": false
+    },
+    "has_media": {
+      "description": "Matches Tweets that contain a media url classified by Twitter, e.g.
pic.twitter.com.",
+      "type": "boolean",
+      "default": false
+    },
+    "not": {
+      "description": "'NOT' all of these operators.",
+      "type": "boolean",
+      "default": false
+    },
+    "ands": {
+      "description": "'AND' these additional operators.",
+      "type": "array",
+      "items": {
+        "$ref": "#"
+      }
+    },
+    "ors": {
+      "description": "'OR' these additional operators.",
+      "type": "array",
+      "items": {
+        "$ref": "#"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/api/TwitterIT.java
b/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/api/TwitterIT.java
index b3e4ad5fd..d8fd4d921 100644
--- a/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/api/TwitterIT.java
+++ b/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/api/TwitterIT.java
@@ -50,6 +50,12 @@
 import org.apache.streams.twitter.api.StatusesShowRequest;
 import org.apache.streams.twitter.api.SuggestedUserCategory;
 import org.apache.streams.twitter.api.SuggestedUsers;
+import org.apache.streams.twitter.api.ThirtyDaySearch;
+import org.apache.streams.twitter.api.ThirtyDaySearchCounts;
+import org.apache.streams.twitter.api.ThirtyDaySearchCountsRequest;
+import org.apache.streams.twitter.api.ThirtyDaySearchCountsResponse;
+import org.apache.streams.twitter.api.ThirtyDaySearchRequest;
+import org.apache.streams.twitter.api.ThirtyDaySearchResponse;
 import org.apache.streams.twitter.api.Twitter;
 import org.apache.streams.twitter.api.Users;
 import org.apache.streams.twitter.api.UsersLookupRequest;
@@ -82,6 +88,7 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static java.util.Objects.isNull;
 import static java.util.Objects.nonNull;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.testng.Assert.assertEquals;
@@ -298,6 +305,41 @@ public void testSuggestedUsersCategories() throws Exception {
     assertThat("members.size() > 0", members.size() > 0);
   }
 
+  /*
+   Disabled because it requires a premium environment.
+   */
+  @Test(enabled = false, dependsOnGroups = {"Account"}, groups = {"Search"})
+  public void testThirtyDaySearch() throws Exception {
+    ThirtyDaySearch search = Twitter.getInstance(config);
+    nonNull(search);
+    ThirtyDaySearchRequest searchRequest = new ThirtyDaySearchRequest();
+    searchRequest.setQuery("big data");
+    ThirtyDaySearchResponse searchResponse = search.thirtyDaySearch(config.getEnvironment(),
searchRequest);
+    nonNull(searchResponse);
+    assertThat("searchResponse.getResults().size() > 0", searchResponse.getResults().size()
> 0);
+    nonNull(searchResponse.getNext());
+    ThirtyDaySearchRequest nextRequest = searchRequest.withNext(searchResponse.getNext());
+    ThirtyDaySearchResponse nextResponse = search.thirtyDaySearch(config.getEnvironment(),
nextRequest);
+    nonNull(nextResponse);
+    assertThat("nextResponse.getResults().size() > 0", nextResponse.getResults().size()
> 0);
+    nonNull(nextResponse.getNext());
+  }
+
+  /*
+   Disabled because it is deactivated in a development environmnt.
+   */
+  @Test(enabled = false, dependsOnGroups = {"Account"}, groups = {"Search"})
+  public void testThirtyDaySearchCounts() throws Exception {
+    ThirtyDaySearchCounts searchCounts = Twitter.getInstance(config);
+    nonNull(searchCounts);
+    ThirtyDaySearchCountsRequest searchRequest = new ThirtyDaySearchCountsRequest();
+    searchRequest.setQuery("big data");
+    ThirtyDaySearchCountsResponse searchCountsResponse = searchCounts.thirtyDaySearchCounts(config.getEnvironment(),
searchRequest);
+    nonNull(searchCountsResponse);
+    assertThat("searchCountsResponse.getTotalCounts() > 0", searchCountsResponse.getTotalCount()
> 0);
+    assertThat("searchCountsResponse.getResults().size() > 0", searchCountsResponse.getResults().size()
> 0);
+  }
+
   @Test(
       enabled=false,
       dependsOnGroups = {"Account"},
diff --git a/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/search/SearchUtilTest.java
b/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/search/SearchUtilTest.java
new file mode 100644
index 000000000..ddf953c70
--- /dev/null
+++ b/streams-contrib/streams-provider-twitter/src/test/java/org/apache/streams/twitter/test/search/SearchUtilTest.java
@@ -0,0 +1,79 @@
+package org.apache.streams.twitter.test.search;
+
+import org.apache.streams.twitter.search.SearchUtil;
+import org.apache.streams.twitter.search.ThirtyDaySearchOperator;
+
+import org.apache.commons.lang.StringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.testng.collections.Lists;
+
+public class SearchUtilTest {
+
+  @Test
+  public void test1() throws Exception {
+    ThirtyDaySearchOperator operator = new ThirtyDaySearchOperator()
+      .withBios(Lists.newArrayList(
+        "steve",
+        "matthew",
+        "ate",
+        "suneel"
+      ));
+    String query = SearchUtil.toString(operator);
+    Assert.assertEquals( 4, StringUtils.countMatches(query, "bio:"));
+    Assert.assertTrue( query.contains("steve"));
+    Assert.assertTrue( query.contains("suneel"));
+  }
+
+  @Test
+  public void test2() throws Exception {
+    ThirtyDaySearchOperator operator = new ThirtyDaySearchOperator()
+      .withBioLocations(Lists.newArrayList(
+        "New York City",
+        "Austin",
+        "San Francisco"
+      ));
+    String query = SearchUtil.toString(operator);
+    Assert.assertEquals( 2, StringUtils.countMatches(query, "bio_location:\""));
+    Assert.assertTrue( query.contains("New York City"));
+    Assert.assertTrue( query.contains("Austin"));
+    Assert.assertTrue( query.contains("San Francisco"));
+  }
+
+  @Test
+  public void test3() throws Exception {
+    ThirtyDaySearchOperator operator = new ThirtyDaySearchOperator()
+      .withKeywords(Lists.newArrayList("rock"))
+      .withAnds(Lists.newArrayList(new ThirtyDaySearchOperator()
+        .withKeywords(Lists.newArrayList("roll"))));
+    String query = SearchUtil.toString(operator);
+    Assert.assertEquals( "( rock AND ( roll ) )", query );
+  }
+
+  @Test
+  public void test4() throws Exception {
+    ThirtyDaySearchOperator operator = new ThirtyDaySearchOperator()
+      .withKeywords(Lists.newArrayList("a"))
+      .withAnds(Lists.newArrayList(
+        new ThirtyDaySearchOperator()
+          .withKeywords(Lists.newArrayList("b"))
+          .withOrs(Lists.newArrayList(
+            new ThirtyDaySearchOperator()
+              .withKeywords(Lists.newArrayList("c")))
+          )
+      ))
+      .withOrs(Lists.newArrayList(
+        new ThirtyDaySearchOperator()
+          .withKeywords(Lists.newArrayList("d"))
+          .withAnds(Lists.newArrayList(
+            new ThirtyDaySearchOperator()
+              .withKeywords(Lists.newArrayList("e"))
+          )
+        )
+      ))
+      .withNot(true);
+    String query = SearchUtil.toString(operator);
+    Assert.assertEquals( "- ( a AND ( b OR ( c ) ) OR ( d AND ( e ) ) )", query);
+  }
+
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Implement Premium Search in streams-provider-twitter
> ----------------------------------------------------
>
>                 Key: STREAMS-553
>                 URL: https://issues.apache.org/jira/browse/STREAMS-553
>             Project: Streams
>          Issue Type: New Feature
>            Reporter: Steve Blackmon
>
> https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)


Mime
View raw message