Skip to content

Commit

Permalink
Functionality to upload to Twitter
Browse files Browse the repository at this point in the history
  • Loading branch information
RohanNagar committed Aug 22, 2017
1 parent 326c95f commit e8e65da
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sanction.lightning.models.facebook;
package com.sanction.lightning.models;

public enum PublishType {
TEXT("text"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
import com.restfb.scope.ScopeBuilder;
import com.restfb.scope.UserDataPermissions;

import com.sanction.lightning.models.PublishType;
import com.sanction.lightning.models.facebook.FacebookPhoto;
import com.sanction.lightning.models.facebook.FacebookPhotoDetail;
import com.sanction.lightning.models.facebook.FacebookUser;
import com.sanction.lightning.models.facebook.FacebookVideo;
import com.sanction.lightning.models.facebook.PublishType;

import java.io.InputStream;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
import com.sanction.lightning.exception.ThunderConnectionException;
import com.sanction.lightning.facebook.FacebookService;
import com.sanction.lightning.facebook.FacebookServiceFactory;
import com.sanction.lightning.models.PublishType;
import com.sanction.lightning.models.facebook.FacebookPhoto;
import com.sanction.lightning.models.facebook.FacebookUser;
import com.sanction.lightning.models.facebook.FacebookVideo;
import com.sanction.lightning.models.facebook.PublishType;
import com.sanction.thunder.ThunderClient;
import com.sanction.thunder.models.PilotUser;
import io.dropwizard.auth.Auth;
Expand Down Expand Up @@ -296,16 +296,24 @@ public Response publish(@Auth Key key,
FacebookService facebookService =
facebookServiceFactory.newFacebookService(pilotUser.getFacebookAccessToken());

// Get the name of the file if publishing media
String filename;
if (type.equals(PublishType.TEXT)) {
filename = null;
} else {
filename = contentDispositionHeader.getFileName();
}

String uploadedFile = facebookService.publish(inputStream, type, message,
contentDispositionHeader.getFileName(), videoTitle);
filename, videoTitle);

if (uploadedFile == null) {
LOG.error("Error uploading to Facebook for username {}.", email);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Error uploading to Facebook.").build();
}

return Response.ok(uploadedFile).build();
return Response.status(Response.Status.CREATED).entity(uploadedFile).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,30 @@
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
import com.sanction.lightning.authentication.Key;
import com.sanction.lightning.models.PublishType;
import com.sanction.lightning.models.twitter.TwitterUser;
import com.sanction.lightning.twitter.TwitterService;
import com.sanction.lightning.twitter.TwitterServiceFactory;
import com.sanction.thunder.ThunderClient;
import com.sanction.thunder.models.PilotUser;
import io.dropwizard.auth.Auth;

import java.io.InputStream;

import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

@Path("/twitter")
@Produces(MediaType.APPLICATION_JSON)
public class TwitterResource {
Expand All @@ -27,6 +35,7 @@ public class TwitterResource {

// Counts number of requests
private final Meter usersRequests;
private final Meter publishRequests;
private final Meter oauthRequests;

/**
Expand All @@ -46,6 +55,9 @@ public TwitterResource(ThunderClient thunderClient, MetricRegistry metrics,
this.usersRequests = metrics.meter(MetricRegistry.name(
TwitterResource.class,
"users-requests"));
this.publishRequests = metrics.meter(MetricRegistry.name(
TwitterResource.class,
"publish-requests"));
this.oauthRequests = metrics.meter(MetricRegistry.name(
TwitterResource.class,
"oauth-requests"));
Expand Down Expand Up @@ -90,6 +102,79 @@ public Response getUser(@Auth Key key,
return Response.ok(user).build();
}

/**
* Publishes to a user's Twitter Feed.
*
* @param key The authentication key for the requesting application.
* @param email The email of the PilotUser to upload as.
* @param password The password of the PilotUser.
* @param type The type of the publish to perform.
* @param message The text message to publish.
* @param inputStream The inputStream for the file to be upload.
* @param contentDispositionHeader Additional information about the file to upload.
* @return The ID of the created post if successful.
*/
@POST
@Path("/publish")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response publish(@Auth Key key,
@QueryParam("email") String email,
@HeaderParam("password") String password,
@QueryParam("type") PublishType type,
@QueryParam("message") String message,
@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition
contentDispositionHeader) {
publishRequests.mark();

if (email == null) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("The 'email' query parameter is required to post a tweet.").build();
}

if (password == null || password.equals("")) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Incorrect or missing header credentials.").build();
}

if (type == null) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("The 'type' query parameter is required to determine what to publish.").build();
}

if ((type.equals(PublishType.PHOTO) || type.equals(PublishType.VIDEO))
&& inputStream == null) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("A file is required to publish a photo or video.").build();
}

if (type.equals(PublishType.TEXT) && (message == null || message.equals(""))) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Posting a text message requires the 'message' parameter.").build();
}

PilotUser pilotUser = thunderClient.getUser(email, password);
TwitterService service = twitterServiceFactory.newTwitterService(
pilotUser.getTwitterAccessToken(),
pilotUser.getTwitterAccessSecret());

// Get the name of the file if publishing media
String filename;
if (type.equals(PublishType.TEXT)) {
filename = null;
} else {
filename = contentDispositionHeader.getFileName();
}

Long id = service.publish(type, message, filename, inputStream);
if (id == null) {
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
.entity("Unable to retrieve information from Twitter.").build();
}

return Response.status(Response.Status.CREATED).entity(id).build();
}

/**
* Generates a Twitter URL that can be used to authenticate a PilotUser.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package com.sanction.lightning.twitter;

import com.sanction.lightning.models.PublishType;
import com.sanction.lightning.models.twitter.TwitterUser;

import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import twitter4j.Status;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
Expand Down Expand Up @@ -76,6 +83,33 @@ public TwitterUser getTwitterUser() {
twitterUser.isVerified());
}

/**
* Publishes text or media to Twitter.
*
* @param type The type to upload to perform.
* @param message The text to publish.
* @param filename The name to call the file on Twitter.
* Will be ignored if only publishing text.
* @param inputStream The InputStream of the file to upload to Twitter.
* @return The ID of the post if successful, or {@code null} on failure.
*/
public Long publish(PublishType type, String message, String filename, InputStream inputStream) {
StatusUpdate update = new StatusUpdate(message);
if (type.equals(PublishType.PHOTO) || type.equals(PublishType.VIDEO)) {
update.setMedia(filename, inputStream);
}

try {
Status status = twitterClient.updateStatus(update);

return status.getId();
} catch (TwitterException e) {
LOG.error("Unable to publish to Twitter. "
+ "Twitter error code: {}", e.getErrorCode(), e);
return null;
}
}

/**
* Retrieves a new OAuth URL from Twitter.
* Should only be called if the TwitterService was constructed without an authenticating user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import com.sanction.lightning.authentication.Key;
import com.sanction.lightning.facebook.FacebookService;
import com.sanction.lightning.facebook.FacebookServiceFactory;
import com.sanction.lightning.models.PublishType;
import com.sanction.lightning.models.facebook.FacebookPhoto;
import com.sanction.lightning.models.facebook.FacebookUser;
import com.sanction.lightning.models.facebook.FacebookVideo;
import com.sanction.lightning.models.facebook.PublishType;
import com.sanction.thunder.ThunderClient;
import com.sanction.thunder.models.PilotUser;

Expand Down Expand Up @@ -314,17 +314,17 @@ public void testPublishWithBadTypeValue() {
}

@Test
public void testPublishWIthNullInputStream() {
Response response = resource.publish(key, "Test", "password", PublishType.PHOTO,
"Test Message", null, null, "Test Title");
public void testPublishTextWithNullMessage() {
Response response = resource.publish(key, "Test", "password", PublishType.TEXT,
null, inputStream, contentDisposition, "Test Title");

assertEquals(response.getStatusInfo(), Response.Status.BAD_REQUEST);
}

@Test
public void testPublishWIthNullMessage() {
Response response = resource.publish(key, "Test", "password", PublishType.TEXT,
null, inputStream, contentDisposition, "Test Title");
public void testPublishPhotoWithNullInputStream() {
Response response = resource.publish(key, "Test", "password", PublishType.PHOTO,
"Test Message", null, null, "Test Title");

assertEquals(response.getStatusInfo(), Response.Status.BAD_REQUEST);
}
Expand Down Expand Up @@ -382,7 +382,21 @@ public void testPublishWithNullFacebookResponse() {
}

@Test
public void testPublishWithNullVideoTitle() {
public void testPublishTextWithNullInputStream() {
when(facebookService.publish(any(InputStream.class),
any(PublishType.class), any(String.class), any(String.class),
any(String.class))).thenReturn("Test");

Response response = resource.publish(key, "Test", "password", PublishType.TEXT,
"Test", null, null, null);
String result = (String) response.getEntity();

assertEquals(response.getStatusInfo(), Response.Status.CREATED);
assertEquals(result, "Test");
}

@Test
public void testPublishPhotoWithNullVideoTitle() {
when(facebookService.publish(any(InputStream.class),
any(PublishType.class), any(String.class), any(String.class),
any(String.class))).thenReturn("Test");
Expand All @@ -391,12 +405,12 @@ public void testPublishWithNullVideoTitle() {
"Test", inputStream, contentDisposition, null);
String result = (String) response.getEntity();

assertEquals(response.getStatusInfo(), Response.Status.OK);
assertEquals(response.getStatusInfo(), Response.Status.CREATED);
assertEquals(result, "Test");
}

@Test
public void testPublishWithNullMessage() {
public void testPublishPhotoWithNullMessage() {
when(facebookService.publish(any(InputStream.class),
any(PublishType.class), any(String.class), any(String.class),
any(String.class))).thenReturn("Test");
Expand All @@ -405,7 +419,7 @@ public void testPublishWithNullMessage() {
null, inputStream, contentDisposition, "Test");
String result = (String) response.getEntity();

assertEquals(response.getStatusInfo(), Response.Status.OK);
assertEquals(response.getStatusInfo(), Response.Status.CREATED);
assertEquals(result, "Test");
}

Expand All @@ -419,7 +433,7 @@ public void testPublish() {
"Test", inputStream, contentDisposition, "Test");
String result = (String) response.getEntity();

assertEquals(response.getStatusInfo(), Response.Status.OK);
assertEquals(response.getStatusInfo(), Response.Status.CREATED);
assertEquals(result, "Test");
}

Expand Down
Loading

0 comments on commit e8e65da

Please sign in to comment.