[
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:
[email protected]
> 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)