diff --git a/README.md b/README.md index 7053837..4d3f470 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,14 @@ Step 2. Use this library --- ## For the Log In with Patreon flow + ```java import com.github.jasminb.jsonapi.JSONAPIDocument; import com.patreon.PatreonAPI; import com.patreon.PatreonOAuth; import com.patreon.PatreonOAuth; -import com.patreon.resources.User; -import com.patreon.resources.Pledge; +import com.patreon.resources.v1.User; +import com.patreon.resources.v1.Pledge; ... @@ -48,12 +49,18 @@ String accessToken = tokens.getAccessToken(); PatreonAPI apiClient = new PatreonAPI(accessToken); JSONAPIDocument userResponse = apiClient.fetchUser(); User user = userResponse.get(); -Log.i(user.getFullName()); +Log. + +i(user.getFullName()); List pledges = user.getPledges() -if (pledges != null && pledges.size() > 0) { - Pledge pledge = pledges.get(0); - Log.i(pledge.getAmountCents()); -} +if(pledges !=null&&pledges. + +size() >0){ +Pledge pledge = pledges.get(0); + Log. + +i(pledge.getAmountCents()); + } // You should save the user's PatreonOAuth.TokensResponse in your database // (for refreshing their Patreon data whenever you like), // along with any relevant user info or pledge info you want to store. diff --git a/src/main/java/com/patreon/PatreonAPI.java b/src/main/java/com/patreon/PatreonAPI.java index 4ca62aa..5b9dfa1 100644 --- a/src/main/java/com/patreon/PatreonAPI.java +++ b/src/main/java/com/patreon/PatreonAPI.java @@ -3,12 +3,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.github.jasminb.jsonapi.*; -import com.patreon.resources.Campaign; -import com.patreon.resources.Pledge; -import com.patreon.resources.RequestUtil; -import com.patreon.resources.User; import com.patreon.resources.shared.BaseResource; import com.patreon.resources.shared.Field; +import com.patreon.resources.v1.Campaign; +import com.patreon.resources.v1.Pledge; +import com.patreon.resources.v1.RequestUtil; +import com.patreon.resources.v1.User; +import com.patreon.resources.v2.CampaignV2; +import com.patreon.resources.v2.Member; +import com.patreon.resources.v2.Tier; +import com.patreon.resources.v2.UserV2; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URLEncodedUtils; @@ -58,12 +62,81 @@ public PatreonAPI(String accessToken) { this.converter = new ResourceConverter( objectMapper, User.class, + UserV2.class, Campaign.class, - Pledge.class + Member.class, + CampaignV2.class, + Pledge.class, + Tier.class ); this.converter.enableDeserializationOption(DeserializationFeature.ALLOW_UNKNOWN_INCLUSIONS); } + public JSONAPIDocument v2FetchIdentity() throws IOException { + URIBuilder pathBuilder = new URIBuilder() + .setPath("v2/identity") + .addParameter("include", "campaign"); + addFieldsParam(pathBuilder, UserV2.class, UserV2.UserField.getDefaultFields()); + addFieldsParam(pathBuilder, CampaignV2.class, CampaignV2.CampaignField.getDefaultFields()); + return converter.readDocument( + getDataStream(pathBuilder.toString()), + UserV2.class + ); + } + + public JSONAPIDocument> v2FetchCampaigns(Integer count) throws IOException { + URIBuilder pathBuilder = new URIBuilder() + .setPath("v2/campaigns") + .addParameter("page[count]", String.valueOf(count)); + addFieldsParam(pathBuilder, CampaignV2.class, CampaignV2.CampaignField.getDefaultFields()); + return converter.readDocumentCollection( + getDataStream(pathBuilder.toString()), + CampaignV2.class + ); + } + + public JSONAPIDocument v2FetchCampaign(String campaignId) throws IOException { + URIBuilder pathBuilder = new URIBuilder() + .setPath(String.format("v2/campaigns/%s", campaignId)); + addFieldsParam(pathBuilder, CampaignV2.class, CampaignV2.CampaignField.getDefaultFields()); + return converter.readDocument( + getDataStream(pathBuilder.toString()), + CampaignV2.class + ); + } + + public JSONAPIDocument> v2FetchCampaignMembers(String campaignId, Integer count) throws IOException { + // Check count is less than 1000 + if (count > 1000) { + throw new IllegalArgumentException("Count must be less than 1000"); + } + + URIBuilder pathBuilder = new URIBuilder() + .setPath(String.format("v2/campaigns/%s/members", campaignId)) + .addParameter("include", "user,currently_entitled_tiers") + .addParameter("page[count]", String.valueOf(count)); + addFieldsParam(pathBuilder, Member.class, Member.MemberField.getDefaultFields()); + addFieldsParam(pathBuilder, UserV2.class, UserV2.UserField.getDefaultFields()); + addFieldsParam(pathBuilder, Tier.class, Tier.TierField.getDefaultFields()); + return converter.readDocumentCollection( + getDataStream(pathBuilder.toString()), + Member.class + ); + } + + public JSONAPIDocument v2FetchMember(String memberId) throws IOException { + URIBuilder pathBuilder = new URIBuilder() + .setPath(String.format("v2/members/%s", memberId)) + .addParameter("include", "user,currently_entitled_tiers"); + addFieldsParam(pathBuilder, Member.class, Member.MemberField.getDefaultFields()); + addFieldsParam(pathBuilder, UserV2.class, UserV2.UserField.getDefaultFields()); + addFieldsParam(pathBuilder, Tier.class, Tier.TierField.getDefaultFields()); + return converter.readDocument( + getDataStream(pathBuilder.toString()), + Member.class + ); + } + /** * Get the user object of the creator * @@ -83,8 +156,8 @@ public JSONAPIDocument fetchUser() throws IOException { */ public JSONAPIDocument fetchUser(Collection optionalFields) throws IOException { URIBuilder pathBuilder = new URIBuilder() - .setPath("current_user") - .addParameter("include", "pledges"); + .setPath("api/current_user") + .addParameter("include", "pledges"); if (optionalFields != null) { Set optionalAndDefaultFields = new HashSet<>(optionalFields); optionalAndDefaultFields.addAll(User.UserField.getDefaultFields()); @@ -106,9 +179,9 @@ public JSONAPIDocument fetchUser(Collection optionalFields */ public JSONAPIDocument> fetchCampaigns() throws IOException { String path = new URIBuilder() - .setPath("current_user/campaigns") - .addParameter("include", "rewards,creator,goals") - .toString(); + .setPath("api/current_user/campaigns") + .addParameter("include", "rewards,creator,goals") + .toString(); return converter.readDocumentCollection( getDataStream(path), Campaign.class @@ -132,18 +205,18 @@ public JSONAPIDocument> fetchPageOfPledges(String campaignId, int p /** * Retrieve pledges for the specified campaign * - * @param campaignId id for campaign to retrieve - * @param pageSize how many pledges to return - * @param pageCursor A cursor retreived from a previous API call, or null for the initial page. - * See {@link #getNextCursorFromDocument(JSONAPIDocument)} + * @param campaignId id for campaign to retrieve + * @param pageSize how many pledges to return + * @param pageCursor A cursor retreived from a previous API call, or null for the initial page. + * See {@link #getNextCursorFromDocument(JSONAPIDocument)} * @param optionalFields A list of optional fields to return. See {@link Pledge.PledgeField} * @return the page of pledges * @throws IOException Thrown when the GET request failed */ public JSONAPIDocument> fetchPageOfPledges(String campaignId, int pageSize, String pageCursor, Collection optionalFields) throws IOException { URIBuilder pathBuilder = new URIBuilder() - .setPath(String.format("campaigns/%s/pledges", campaignId)) - .addParameter("page[count]", String.valueOf(pageSize)); + .setPath(String.format("api/campaigns/%s/pledges", campaignId)) + .addParameter("page[count]", String.valueOf(pageSize)); if (pageCursor != null) { pathBuilder.addParameter("page[cursor]", pageCursor); } @@ -183,10 +256,25 @@ public String getNextCursorFromDocument(JSONAPIDocument document) { } public List fetchAllPledges(String campaignId) throws IOException { + return fetchAllPledges(campaignId, false); + } + + /** + * Retrieve all pledges for the specified campaign + * + * @param campaignId id for campaign to retrieve + * @return the list of pledges + * @throws IOException Thrown when the GET request failed + */ + public List fetchAllPledges(String campaignId, boolean full) throws IOException { Set pledges = new HashSet<>(); String cursor = null; + Collection fields = null; + if (full) { + fields = Pledge.PledgeField.getAllFields(); + } while (true) { - JSONAPIDocument> pledgesPage = fetchPageOfPledges(campaignId, 15, cursor); + JSONAPIDocument> pledgesPage = fetchPageOfPledges(campaignId, 15, cursor, fields); pledges.addAll(pledgesPage.get()); cursor = getNextCursorFromDocument(pledgesPage); if (cursor == null) { @@ -203,9 +291,10 @@ private InputStream getDataStream(String suffix) throws IOException { /** * Add fields[type]=fieldName,fieldName,fieldName as a query parameter to the request represented by builder + * * @param builder A URIBuilder building a request to the API - * @param type A BaseResource annotated with {@link com.github.jasminb.jsonapi.annotations.Type} - * @param fields A list of fields to include. Only fields in this list will be retrieved in the query + * @param type A BaseResource annotated with {@link com.github.jasminb.jsonapi.annotations.Type} + * @param fields A list of fields to include. Only fields in this list will be retrieved in the query * @return builder */ private URIBuilder addFieldsParam(URIBuilder builder, Class type, Collection fields) { diff --git a/src/main/java/com/patreon/resources/Campaign.java b/src/main/java/com/patreon/resources/v1/Campaign.java similarity index 99% rename from src/main/java/com/patreon/resources/Campaign.java rename to src/main/java/com/patreon/resources/v1/Campaign.java index ba14bc9..0130b38 100644 --- a/src/main/java/com/patreon/resources/Campaign.java +++ b/src/main/java/com/patreon/resources/v1/Campaign.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import com.fasterxml.jackson.annotation.JsonProperty; @@ -7,7 +7,6 @@ import com.patreon.resources.shared.BaseResource; import com.patreon.resources.shared.Field; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; diff --git a/src/main/java/com/patreon/resources/Goal.java b/src/main/java/com/patreon/resources/v1/Goal.java similarity index 98% rename from src/main/java/com/patreon/resources/Goal.java rename to src/main/java/com/patreon/resources/v1/Goal.java index c03e62c..4321155 100644 --- a/src/main/java/com/patreon/resources/Goal.java +++ b/src/main/java/com/patreon/resources/v1/Goal.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.jasminb.jsonapi.annotations.Type; diff --git a/src/main/java/com/patreon/resources/Pledge.java b/src/main/java/com/patreon/resources/v1/Pledge.java similarity index 70% rename from src/main/java/com/patreon/resources/Pledge.java rename to src/main/java/com/patreon/resources/v1/Pledge.java index bcb4a72..4fc3977 100644 --- a/src/main/java/com/patreon/resources/Pledge.java +++ b/src/main/java/com/patreon/resources/v1/Pledge.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.jasminb.jsonapi.annotations.Relationship; @@ -6,15 +6,13 @@ import com.patreon.resources.shared.BaseResource; import com.patreon.resources.shared.Field; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.stream.Collectors; @Type("pledge") public class Pledge extends BaseResource { - + public enum PledgeField implements Field { AmountCents("amount_cents", true), CreatedAt("created_at", true), @@ -23,6 +21,7 @@ public enum PledgeField implements Field { PledgeCapCents("pledge_cap_cents", true), TotalHistoricalAmountCents("total_historical_amount_cents", false), IsPaused("is_paused", false), + Status("status", false), HasShippingAddress("has_shipping_address", false), ; @@ -38,6 +37,10 @@ public static Collection getDefaultFields() { return Arrays.stream(values()).filter(Field::isDefault).collect(Collectors.toList()); } + public static Collection getAllFields() { + return Arrays.asList(values()); + } + @Override public String getPropertyName() { return this.propertyName; @@ -49,6 +52,25 @@ public boolean isDefault() { } } + public enum PledgeStatus { + valid, + declined, + pending, + disabled, + fraud, + unknown, + ; + + public static PledgeStatus fromString(String status) { + for (PledgeStatus s : PledgeStatus.values()) { + if (s.toString().equals(status)) { + return s; + } + } + return unknown; + } + } + private int amountCents; private String createdAt; private String declinedSince; @@ -58,6 +80,7 @@ public boolean isDefault() { //Optional properties. Will be null if not requested private Integer totalHistoricalAmountCents; private Boolean isPaused; + private PledgeStatus status; private Boolean hasShippingAddress; @Relationship("creator") @@ -70,17 +93,18 @@ public boolean isDefault() { private Reward reward; public Pledge( - @JsonProperty("amount_cents") int amount_cents, - @JsonProperty("created_at") String created_at, - @JsonProperty("declined_since") String declined_since, - @JsonProperty("patron_pays_fees") boolean patron_pays_fees, - @JsonProperty("pledge_cap_cents") int pledge_cap_cents, - @JsonProperty("total_historical_amount_cents") Integer total_historical_amount_cents, - @JsonProperty("is_paused") Boolean is_paused, - @JsonProperty("has_shipping_address") Boolean has_shipping_address, - @JsonProperty("creator") User creator, - @JsonProperty("patron") User patron, - @JsonProperty("reward") Reward reward + @JsonProperty("amount_cents") int amount_cents, + @JsonProperty("created_at") String created_at, + @JsonProperty("declined_since") String declined_since, + @JsonProperty("patron_pays_fees") boolean patron_pays_fees, + @JsonProperty("pledge_cap_cents") int pledge_cap_cents, + @JsonProperty("total_historical_amount_cents") Integer total_historical_amount_cents, + @JsonProperty("is_paused") Boolean is_paused, + @JsonProperty("status") String status, + @JsonProperty("has_shipping_address") Boolean has_shipping_address, + @JsonProperty("creator") User creator, + @JsonProperty("patron") User patron, + @JsonProperty("reward") Reward reward ) { this.amountCents = amount_cents; this.createdAt = created_at; @@ -89,6 +113,7 @@ public Pledge( this.pledgeCapCents = pledge_cap_cents; this.totalHistoricalAmountCents = total_historical_amount_cents; this.isPaused = is_paused; + this.status = PledgeStatus.fromString(status); this.hasShippingAddress = has_shipping_address; this.creator = creator; this.patron = patron; @@ -130,6 +155,13 @@ public Boolean getPaused() { return isPaused; } + /** + * @return The status of the pledge, or null if this field wasn't requested + */ + public PledgeStatus getStatus() { + return status; + } + /** * @return Whether this patron has a shipping address, or null if this field wasn't requested */ diff --git a/src/main/java/com/patreon/resources/RequestUtil.java b/src/main/java/com/patreon/resources/v1/RequestUtil.java similarity index 93% rename from src/main/java/com/patreon/resources/RequestUtil.java rename to src/main/java/com/patreon/resources/v1/RequestUtil.java index cabb20e..d91a265 100644 --- a/src/main/java/com/patreon/resources/RequestUtil.java +++ b/src/main/java/com/patreon/resources/v1/RequestUtil.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import java.io.IOException; import java.io.InputStream; @@ -13,7 +13,7 @@ public class RequestUtil { public InputStream request(String pathSuffix, String accessToken) throws IOException { - String prefix = BASE_URI + "/api/oauth2/api/"; + String prefix = BASE_URI + "/api/oauth2/"; URL url = new URL(prefix.concat(pathSuffix)); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Authorization", "Bearer ".concat(accessToken)); diff --git a/src/main/java/com/patreon/resources/Reward.java b/src/main/java/com/patreon/resources/v1/Reward.java similarity index 98% rename from src/main/java/com/patreon/resources/Reward.java rename to src/main/java/com/patreon/resources/v1/Reward.java index 714c852..b9fbc0f 100644 --- a/src/main/java/com/patreon/resources/Reward.java +++ b/src/main/java/com/patreon/resources/v1/Reward.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.jasminb.jsonapi.annotations.Relationship; @@ -6,7 +6,6 @@ import com.patreon.resources.shared.BaseResource; import com.patreon.resources.shared.Field; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; diff --git a/src/main/java/com/patreon/resources/User.java b/src/main/java/com/patreon/resources/v1/User.java similarity index 99% rename from src/main/java/com/patreon/resources/User.java rename to src/main/java/com/patreon/resources/v1/User.java index 59eb974..0eb52c0 100644 --- a/src/main/java/com/patreon/resources/User.java +++ b/src/main/java/com/patreon/resources/v1/User.java @@ -1,4 +1,4 @@ -package com.patreon.resources; +package com.patreon.resources.v1; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/com/patreon/resources/v2/CampaignV2.java b/src/main/java/com/patreon/resources/v2/CampaignV2.java new file mode 100644 index 0000000..123ff44 --- /dev/null +++ b/src/main/java/com/patreon/resources/v2/CampaignV2.java @@ -0,0 +1,272 @@ +package com.patreon.resources.v2; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.jasminb.jsonapi.annotations.Relationship; +import com.github.jasminb.jsonapi.annotations.Type; +import com.patreon.resources.shared.BaseResource; +import com.patreon.resources.shared.Field; +import com.patreon.resources.v1.Goal; +import com.patreon.resources.v1.Pledge; +import com.patreon.resources.v1.Reward; +import com.patreon.resources.v1.User; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Type("campaign") +public class CampaignV2 extends BaseResource { + + public enum CampaignField implements Field { + CreatedAt("created_at", true), + CreationName("creation_name", true), +// Idk why but 'discord_server_id' gives 500 from server side if we request /identity +// DiscordServerId("discord_server_id", true), + GoogleAnalyticsId("google_analytics_id", true), + HasRss("has_rss", true), + HasSentRssNotify("has_sent_rss_notify", true), + ImageSmallUrl("image_small_url", true), + ImageUrl("image_url", true), + IsChargedImmediately("is_charged_immediately", true), + IsMonthly("is_monthly", true), + IsNsfw("is_nsfw", true), + MainVideoEmbed("main_video_embed", true), + MainVideoUrl("main_video_url", true), + OneLiner("one_liner", true), + PatronCount("patron_count", true), + PayPerName("pay_per_name", true), + PledgeUrl("pledge_url", true), + PublishedAt("published_at", true), + RssArtworkUrl("rss_artwork_url", true), + RssFeedTitle("rss_feed_title", true), + ShowEarnings("show_earnings", true), + Summary("summary", true), + +// Idk why but 'thanks_*' gives 500 from server side if we request /identity +// ThanksEmbed("thanks_embed", true), +// ThanksMsg("thanks_msg", true), +// ThanksVideoUrl("thanks_video_url", true), + Url("url", true), + Vanity("vanity", true), + ; + + private final String propertyName; + private final boolean isDefault; + + CampaignField(String propertyName, boolean isDefault) { + this.propertyName = propertyName; + this.isDefault = isDefault; + } + + public static Collection getDefaultFields() { + return Arrays.stream(values()).filter(Field::isDefault).collect(Collectors.toList()); + } + + @Override + public String getPropertyName() { + return this.propertyName; + } + + @Override + public boolean isDefault() { + return this.isDefault; + } + } + + @JsonProperty("created_at") private String createdAt; + @JsonProperty("creation_name") private String creationName; + @JsonProperty("discord_server_id") private String discordServerId; + @JsonProperty("google_analytics_id") private String googleAnalyticsId; + @JsonProperty("has_rss") private Boolean hasRss; + @JsonProperty("has_sent_rss_notify") private Boolean hasSentRssNotify; + @JsonProperty("image_small_url") private String imageSmallUrl; + @JsonProperty("image_url") private String imageUrl; + @JsonProperty("is_charged_immediately") private Boolean isChargedImmediately; + @JsonProperty("is_monthly") private Boolean isMonthly; + @JsonProperty("is_nsfw") private Boolean isNsfw; + @JsonProperty("main_video_embed") private String mainVideoEmbed; + @JsonProperty("main_video_url") private String mainVideoUrl; + @JsonProperty("one_liner") private String oneLiner; + @JsonProperty("patron_count") private Integer patronCount; + @JsonProperty("pay_per_name") private String payPerName; + @JsonProperty("pledge_url") private String pledgeUrl; + @JsonProperty("published_at") private String publishedAt; + @JsonProperty("rss_artwork_url") private String rssArtworkUrl; + @JsonProperty("rss_feed_title") private String rssFeedTitle; + @JsonProperty("show_earnings") private Boolean showEarnings; + @JsonProperty("summary") private String summary; + @JsonProperty("thanks_embed") private String thanksEmbed; + @JsonProperty("thanks_msg") private String thanksMsg; + @JsonProperty("thanks_video_url") private String thanksVideoUrl; + @JsonProperty("url") private String url; + @JsonProperty("vanity") private String vanity; + + public CampaignV2( + @JsonProperty ("created_at") String createdAt, + @JsonProperty ("creation_name") String creationName, + @JsonProperty ("discord_server_id") String discordServerId, + @JsonProperty ("google_analytics_id") String googleAnalyticsId, + @JsonProperty ("has_rss") Boolean hasRss, + @JsonProperty ("has_sent_rss_notify") Boolean hasSentRssNotify, + @JsonProperty ("image_small_url") String imageSmallUrl, + @JsonProperty ("image_url") String imageUrl, + @JsonProperty ("is_charged_immediately") Boolean isChargedImmediately, + @JsonProperty ("is_monthly") Boolean isMonthly, + @JsonProperty ("is_nsfw") Boolean isNsfw, + @JsonProperty ("main_video_embed") String mainVideoEmbed, + @JsonProperty ("main_video_url") String mainVideoUrl, + @JsonProperty ("one_liner") String oneLiner, + @JsonProperty ("patron_count") Integer patronCount, + @JsonProperty ("pay_per_name") String payPerName, + @JsonProperty ("pledge_url") String pledgeUrl, + @JsonProperty ("published_at") String publishedAt, + @JsonProperty ("rss_artwork_url") String rssArtworkUrl, + @JsonProperty ("rss_feed_title") String rssFeedTitle, + @JsonProperty ("show_earnings") Boolean showEarnings, + @JsonProperty ("summary") String summary, + @JsonProperty ("thanks_embed") String thanksEmbed, + @JsonProperty ("thanks_msg") String thanksMsg, + @JsonProperty ("thanks_video_url") String thanksVideoUrl, + @JsonProperty ("url") String url, + @JsonProperty ("vanity") String vanity + ) { + this.createdAt = createdAt; + this.creationName = creationName; + this.discordServerId = discordServerId; + this.googleAnalyticsId = googleAnalyticsId; + this.hasRss = hasRss; + this.hasSentRssNotify = hasSentRssNotify; + this.imageSmallUrl = imageSmallUrl; + this.imageUrl = imageUrl; + this.isChargedImmediately = isChargedImmediately; + this.isMonthly = isMonthly; + this.isNsfw = isNsfw; + this.mainVideoEmbed = mainVideoEmbed; + this.mainVideoUrl = mainVideoUrl; + this.oneLiner = oneLiner; + this.patronCount = patronCount; + this.payPerName = payPerName; + this.pledgeUrl = pledgeUrl; + this.publishedAt = publishedAt; + this.rssArtworkUrl = rssArtworkUrl; + this.rssFeedTitle = rssFeedTitle; + this.showEarnings = showEarnings; + this.summary = summary; + this.thanksEmbed = thanksEmbed; + this.thanksMsg = thanksMsg; + this.thanksVideoUrl = thanksVideoUrl; + this.url = url; + this.vanity = vanity; + } + + public String getCreatedAt() { + return createdAt; + } + + public String getCreationName() { + return creationName; + } + + public String getDiscordServerId() { + return discordServerId; + } + + public String getGoogleAnalyticsId() { + return googleAnalyticsId; + } + + public Boolean getHasRss() { + return hasRss; + } + + public Boolean getHasSentRssNotify() { + return hasSentRssNotify; + } + + public String getImageSmallUrl() { + return imageSmallUrl; + } + + public String getImageUrl() { + return imageUrl; + } + + public Boolean getChargedImmediately() { + return isChargedImmediately; + } + + public Boolean getMonthly() { + return isMonthly; + } + + public Boolean getNsfw() { + return isNsfw; + } + + public String getMainVideoEmbed() { + return mainVideoEmbed; + } + + public String getMainVideoUrl() { + return mainVideoUrl; + } + + public String getOneLiner() { + return oneLiner; + } + + public Integer getPatronCount() { + return patronCount; + } + + public String getPayPerName() { + return payPerName; + } + + public String getPledgeUrl() { + return pledgeUrl; + } + + public String getPublishedAt() { + return publishedAt; + } + + public String getRssArtworkUrl() { + return rssArtworkUrl; + } + + public String getRssFeedTitle() { + return rssFeedTitle; + } + + public Boolean getShowEarnings() { + return showEarnings; + } + + public String getSummary() { + return summary; + } + + public String getThanksEmbed() { + return thanksEmbed; + } + + public String getThanksMsg() { + return thanksMsg; + } + + public String getThanksVideoUrl() { + return thanksVideoUrl; + } + + public String getUrl() { + return url; + } + + public String getVanity() { + return vanity; + } + +} diff --git a/src/main/java/com/patreon/resources/v2/Member.java b/src/main/java/com/patreon/resources/v2/Member.java new file mode 100644 index 0000000..0c31d78 --- /dev/null +++ b/src/main/java/com/patreon/resources/v2/Member.java @@ -0,0 +1,194 @@ +package com.patreon.resources.v2; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.jasminb.jsonapi.annotations.Relationship; +import com.github.jasminb.jsonapi.annotations.Type; +import com.patreon.resources.shared.BaseResource; +import com.patreon.resources.shared.Field; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Type("member") +public class Member extends BaseResource { + public enum MemberField implements Field { + CampaignLifetimeSupportCents("campaign_lifetime_support_cents", true), + CurrentlyEntitledAmountCents("currently_entitled_amount_cents", true), + Email("email", true), + FullName("full_name", true), + IsFollower("is_follower", true), + LastChargeDate("last_charge_date", true), + LastChargeStatus("last_charge_status", true), + LifetimeSupportCents("lifetime_support_cents", true), + NextChargeDate("next_charge_date", true), + Note ("note", true), + PatronStatus("patron_status", true), + PledgeCadence("pledge_cadence", true), + PledgeRelationshipStart("pledge_relationship_start", true), + WillPayAmountCents("will_pay_amount_cents", true), + ; + + + /** + * The field's name from the API in JSON + */ + public final String propertyName; + + /** + * Whether the field is included by default + */ + public final boolean isDefault; + MemberField(String propertyName, boolean isDefault) { + this.propertyName = propertyName; + this.isDefault = isDefault; + } + + @Override + public String getPropertyName() { + return this.propertyName; + } + + @Override + public boolean isDefault() { + return this.isDefault; + } + + public static Collection getDefaultFields() { + return Arrays.stream(values()).filter(Field::isDefault).collect(Collectors.toList()); + } + } + + private int campaign_lifetime_support_cents; + private int currently_entitled_amount_cents; + private String email; + private String full_name; + private boolean is_follower; + private String last_charge_date; + private String last_charge_status; + private int lifetime_support_cents; + private String next_charge_date; + private String note; + private String patron_status; + private int pledge_cadence; + private String pledge_relationship_start; + private int will_pay_amount_cents; + + @Relationship("campaign") + private CampaignV2 campaign; + + @Relationship("user") + private UserV2 user; + + @Relationship("currently_entitled_tiers") + private List currently_entitled_tiers; + + @JsonCreator + public Member( + @JsonProperty ("campaign_lifetime_support_cents") int campaign_lifetime_support_cents, + @JsonProperty ("currently_entitled_amount_cents") int currently_entitled_amount_cents, + @JsonProperty ("email") String email, + @JsonProperty ("full_name") String full_name, + @JsonProperty ("is_follower") boolean is_follower, + @JsonProperty ("last_charge_date") String last_charge_date, + @JsonProperty ("last_charge_status") String last_charge_status, + @JsonProperty ("lifetime_support_cents") int lifetime_support_cents, + @JsonProperty ("next_charge_date") String next_charge_date, + @JsonProperty ("note") String note, + @JsonProperty ("patron_status") String patron_status, + @JsonProperty ("pledge_cadence") int pledge_cadence, + @JsonProperty ("pledge_relationship_start") String pledge_relationship_start, + @JsonProperty ("will_pay_amount_cents") int will_pay_amount_cents, + @JsonProperty("campaign") CampaignV2 campaign, + @JsonProperty("user") UserV2 user, + @JsonProperty("currently_entitled_tiers") List currently_entitled_tiers + ) { + this.campaign_lifetime_support_cents = campaign_lifetime_support_cents; + this.currently_entitled_amount_cents = currently_entitled_amount_cents; + this.email = email; + this.full_name = full_name; + this.is_follower = is_follower; + this.last_charge_date = last_charge_date; + this.last_charge_status = last_charge_status; + this.lifetime_support_cents = lifetime_support_cents; + this.next_charge_date = next_charge_date; + this.note = note; + this.patron_status = patron_status; + this.pledge_cadence = pledge_cadence; + this.pledge_relationship_start = pledge_relationship_start; + this.will_pay_amount_cents = will_pay_amount_cents; + this.campaign = campaign; + this.user = user; + this.currently_entitled_tiers = currently_entitled_tiers; + } + + public int getCampaignLifetimeSupportCents() { + return campaign_lifetime_support_cents; + } + + public int getCurrentlyEntitledAmountCents() { + return currently_entitled_amount_cents; + } + + public String getEmail() { + return email; + } + + public String getFullName() { + return full_name; + } + + public boolean isFollower() { + return is_follower; + } + + public String getLastChargeDate() { + return last_charge_date; + } + + public String getLastChargeStatus() { + return last_charge_status; + } + + public int getLifetimeSupportCents() { + return lifetime_support_cents; + } + + public String getNextChargeDate() { + return next_charge_date; + } + + public String getNote() { + return note; + } + + public String getPatronStatus() { + return patron_status; + } + + public int getPledgeCadence() { + return pledge_cadence; + } + + public String getPledgeRelationshipStart() { + return pledge_relationship_start; + } + + public int getWillPayAmountCents() { + return will_pay_amount_cents; + } + + public CampaignV2 getCampaign() { + return campaign; + } + + public UserV2 getUser() { + return user; + } + + public List getCurrentlyEntitledTiers() { + return currently_entitled_tiers; + } +} diff --git a/src/main/java/com/patreon/resources/v2/Tier.java b/src/main/java/com/patreon/resources/v2/Tier.java new file mode 100644 index 0000000..2ac0d22 --- /dev/null +++ b/src/main/java/com/patreon/resources/v2/Tier.java @@ -0,0 +1,200 @@ +package com.patreon.resources.v2; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.jasminb.jsonapi.annotations.Type; +import com.patreon.resources.shared.BaseResource; +import com.patreon.resources.shared.Field; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +/** + * Attribute Type Description + * amount_cents integer Monetary amount associated with this tier (in U.S. cents). + * created_at string (UTC ISO format) Datetime this tier was created. + * description string Tier display description. + * discord_role_ids object The discord role IDs granted by this tier. Can be null. + * edited_at string (UTC ISO format) Datetime tier was last modified. + * image_url string Full qualified image URL associated with this tier. Can be null. + * patron_count integer Number of patrons currently registered for this tier. + * post_count integer Number of posts published to this tier. Can be null. + * published boolean true if the tier is currently published. + * published_at string (UTC ISO format) Datetime this tier was last published. Can be null. + * remaining integer Remaining number of patrons who may subscribe, if there is a user_limit. Can be null. + * requires_shipping boolean true if this tier requires a shipping address from patrons. + * title string Tier display title. + * unpublished_at string (UTC ISO format) Datetime tier was unpublished, while applicable. Can be null. + * url string Fully qualified URL associated with this tier. + * user_limit integer Maximum number of patrons this tier is limited to, if applicable. Can be null. + */ +@Type("tier") +public class Tier extends BaseResource { + public enum TierField implements Field { + AmountCents("amount_cents", true), + CreatedAt("created_at", true), + Description("description", true), + DiscordRoleIds("discord_role_ids", true), + EditedAt("edited_at", true), + ImageUrl("image_url", true), + PatronCount("patron_count", true), + PostCount("post_count", true), + Published("published", true), + PublishedAt("published_at", true), + Remaining("remaining", true), + RequiresShipping("requires_shipping", true), + Title("title", true), + UnpublishedAt("unpublished_at", true), + Url("url", true), + UserLimit("user_limit", true), + ; + + /** + * The field's name from the API in JSON + */ + public final String propertyName; + + /** + * Whether the field is included by default + */ + public final boolean isDefault; + + TierField(String propertyName, boolean isDefault) { + this.propertyName = propertyName; + this.isDefault = isDefault; + } + + @Override + public String getPropertyName() { + return this.propertyName; + } + + @Override + public boolean isDefault() { + return this.isDefault; + } + + public static Collection getDefaultFields() { + return Arrays.stream(values()).filter(Field::isDefault).collect(Collectors.toList()); + } + } + + private int amount_cents; + private String created_at; + private String description; + private Object discord_role_ids; + private String edited_at; + private String image_url; + private int patron_count; + private int post_count; + private boolean published; + private String published_at; + private int remaining; + private boolean requires_shipping; + private String title; + private String unpublished_at; + private String url; + private int user_limit; + + @JsonCreator + public Tier( + @JsonProperty("amount_cents") int amount_cents, + @JsonProperty("created_at") String created_at, + @JsonProperty("description") String description, + @JsonProperty("discord_role_ids") Object discord_role_ids, + @JsonProperty("edited_at") String edited_at, + @JsonProperty("image_url") String image_url, + @JsonProperty("patron_count") int patron_count, + @JsonProperty("post_count") int post_count, + @JsonProperty("published") boolean published, + @JsonProperty("published_at") String published_at, + @JsonProperty("remaining") int remaining, + @JsonProperty("requires_shipping") boolean requires_shipping, + @JsonProperty("title") String title, + @JsonProperty("unpublished_at") String unpublished_at, + @JsonProperty("url") String url, + @JsonProperty("user_limit") int user_limit + ) { + this.amount_cents = amount_cents; + this.created_at = created_at; + this.description = description; + this.discord_role_ids = discord_role_ids; + this.edited_at = edited_at; + this.image_url = image_url; + this.patron_count = patron_count; + this.post_count = post_count; + this.published = published; + this.published_at = published_at; + this.remaining = remaining; + this.requires_shipping = requires_shipping; + this.title = title; + this.unpublished_at = unpublished_at; + this.url = url; + this.user_limit = user_limit; + } + + public int getAmountCents() { + return amount_cents; + } + + public String getCreatedAt() { + return created_at; + } + + public String getDescription() { + return description; + } + + public Object getDiscordRoleIds() { + return discord_role_ids; + } + + public String getEditedAt() { + return edited_at; + } + + public String getImageUrl() { + return image_url; + } + + public int getPatronCount() { + return patron_count; + } + + public int getPostCount() { + return post_count; + } + + public boolean isPublished() { + return published; + } + + public String getPublishedAt() { + return published_at; + } + + public int getRemaining() { + return remaining; + } + + public boolean isRequiresShipping() { + return requires_shipping; + } + + public String getTitle() { + return title; + } + + public String getUnpublishedAt() { + return unpublished_at; + } + + public String getUrl() { + return url; + } + + public int getUserLimit() { + return user_limit; + } +} diff --git a/src/main/java/com/patreon/resources/v2/UserV2.java b/src/main/java/com/patreon/resources/v2/UserV2.java new file mode 100644 index 0000000..59b6b82 --- /dev/null +++ b/src/main/java/com/patreon/resources/v2/UserV2.java @@ -0,0 +1,168 @@ +package com.patreon.resources.v2; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.jasminb.jsonapi.annotations.Relationship; +import com.github.jasminb.jsonapi.annotations.Type; +import com.patreon.resources.shared.BaseResource; +import com.patreon.resources.shared.Field; + +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +@Type("user") +public class UserV2 extends BaseResource { + public enum UserField implements Field { + About("about", true), + CanSeeNsfw("can_see_nsfw", true), + Created("created", true), + Email("email", true), + FirstName("first_name", true), + FullName("full_name", true), + HidePledges("hide_pledges", true), + ImageUrl("image_url", true), + IsEmailVerified("is_email_verified", true), + LastName("last_name", true), + LikeCount("like_count", true), + // TODO: add this +// SocialConnections("social_connections", true), + ThumbUrl("thumb_url", true), + Url("url", true), + ; + + /** + * The field's name from the API in JSON + */ + public final String propertyName; + + /** + * Whether the field is included by default + */ + public final boolean isDefault; + + UserField(String propertyName, boolean isDefault) { + this.propertyName = propertyName; + this.isDefault = isDefault; + } + + @Override + public String getPropertyName() { + return this.propertyName; + } + + @Override + public boolean isDefault() { + return this.isDefault; + } + + public static Collection getDefaultFields() { + return Arrays.stream(values()).filter(Field::isDefault).collect(Collectors.toList()); + } + } + + private String about; + private boolean can_see_nsfw; + private String created; + private String email; + private String first_name; + private String full_name; + private boolean hide_pledges; + private String image_url; + private boolean is_email_verified; + private String last_name; + private int like_count; + private String thumb_url; + private String url; + + @Relationship("campaign") + private CampaignV2 campaign; + + @JsonCreator + public UserV2( + @JsonProperty("about") String about, + @JsonProperty("can_see_nsfw") boolean can_see_nsfw, + @JsonProperty("created") String created, + @JsonProperty("email") String email, + @JsonProperty("first_name") String first_name, + @JsonProperty("full_name") String full_name, + @JsonProperty("hide_pledges") boolean hide_pledges, + @JsonProperty("image_url") String image_url, + @JsonProperty("is_email_verified") boolean is_email_verified, + @JsonProperty("last_name") String last_name, + @JsonProperty("like_count") int like_count, + @JsonProperty("thumb_url") String thumb_url, + @JsonProperty("url") String url, + @JsonProperty("campaign") CampaignV2 campaign + ) { + this.about = about; + this.can_see_nsfw = can_see_nsfw; + this.created = created; + this.email = email; + this.first_name = first_name; + this.full_name = full_name; + this.hide_pledges = hide_pledges; + this.image_url = image_url; + this.is_email_verified = is_email_verified; + this.last_name = last_name; + this.like_count = like_count; + this.thumb_url = thumb_url; + this.url = url; + this.campaign = campaign; + } + + public String getAbout() { + return about; + } + + public boolean isCanSeeNsfw() { + return can_see_nsfw; + } + + public String getCreated() { + return created; + } + + public String getEmail() { + return email; + } + + public String getFirstName() { + return first_name; + } + + public String getFullName() { + return full_name; + } + + public boolean isHide_pledges() { + return hide_pledges; + } + + public String getImage_url() { + return image_url; + } + + public boolean isEmailVerified() { + return is_email_verified; + } + + public String getLastName() { + return last_name; + } + + public int getLikeCount() { + return like_count; + } + + public String getThumbUrl() { + return thumb_url; + } + + public String getUrl() { + return url; + } + public CampaignV2 getCampaign() { + return campaign; + } +} diff --git a/src/test/java/com/patreon/PatreonAPITest.java b/src/test/java/com/patreon/PatreonAPITest.java index 34876f6..cc5388c 100644 --- a/src/test/java/com/patreon/PatreonAPITest.java +++ b/src/test/java/com/patreon/PatreonAPITest.java @@ -1,17 +1,15 @@ package com.patreon; import com.github.jasminb.jsonapi.JSONAPIDocument; -import com.patreon.resources.Campaign; -import com.patreon.resources.Pledge; -import com.patreon.resources.RequestUtil; -import com.patreon.resources.User; +import com.patreon.resources.v1.Campaign; +import com.patreon.resources.v1.Pledge; +import com.patreon.resources.v1.RequestUtil; +import com.patreon.resources.v1.User; import junit.framework.TestCase; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.mockito.ArgumentCaptor; -import org.mockito.Matchers; import org.mockito.Mockito; -import org.powermock.api.mockito.PowerMockito; import java.nio.charset.Charset; import java.util.Arrays;