Skip to content

Commit e924a84

Browse files
committed
Implement the new recommendation api
1 parent 7508e50 commit e924a84

10 files changed

Lines changed: 401 additions & 31 deletions

File tree

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,16 @@
11
package me.proxer.library.api;
22

33
import com.squareup.moshi.FromJson;
4-
import com.squareup.moshi.JsonDataException;
5-
6-
import javax.annotation.Nullable;
74

85
/**
96
* @author Ruben Gees
107
*/
118
class BooleanAdapter {
129

13-
@FromJson
14-
boolean fromJson(final Object json) {
15-
final String jsonString = json.toString();
16-
final Integer jsonInteger = toIntOrNull(jsonString);
17-
18-
if (jsonInteger != null) {
19-
if (jsonInteger == 1) {
20-
return true;
21-
} else if (jsonInteger == 0) {
22-
return false;
23-
}
24-
} else {
25-
if ("true".equals(jsonString)) {
26-
return true;
27-
} else if ("false".equals(jsonString)) {
28-
return false;
29-
}
30-
}
10+
private PrimitiveBooleanAdapter delegate = new PrimitiveBooleanAdapter();
3111

32-
throw new JsonDataException("Unable to map " + json + " to a boolean value");
33-
}
34-
35-
@Nullable
36-
private Integer toIntOrNull(final String candidate) {
37-
try {
38-
return (int) Float.parseFloat(candidate);
39-
} catch (NumberFormatException ignored) {
40-
return null;
41-
}
12+
@FromJson
13+
Boolean fromJson(final Object json) {
14+
return delegate.fromJson(json);
4215
}
4316
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package me.proxer.library.api;
2+
3+
import com.squareup.moshi.FromJson;
4+
import com.squareup.moshi.JsonDataException;
5+
6+
import javax.annotation.Nullable;
7+
8+
/**
9+
* @author Ruben Gees
10+
*/
11+
class PrimitiveBooleanAdapter {
12+
13+
@FromJson
14+
boolean fromJson(final Object json) {
15+
final String jsonString = json.toString();
16+
final Integer jsonInteger = toIntOrNull(jsonString);
17+
18+
if (jsonInteger != null) {
19+
if (jsonInteger == 1) {
20+
return true;
21+
} else if (jsonInteger == 0) {
22+
return false;
23+
}
24+
} else {
25+
if ("true".equals(jsonString)) {
26+
return true;
27+
} else if ("false".equals(jsonString)) {
28+
return false;
29+
}
30+
}
31+
32+
throw new JsonDataException("Unable to map " + json + " to a boolean value");
33+
}
34+
35+
@Nullable
36+
private Integer toIntOrNull(final String candidate) {
37+
try {
38+
return (int) Float.parseFloat(candidate);
39+
} catch (NumberFormatException ignored) {
40+
return null;
41+
}
42+
}
43+
}

library/src/main/java/me/proxer/library/api/ProxerApi.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ private void initMoshi() {
217217
.add(new VoidAdapter())
218218
.add(new DateAdapter())
219219
.add(new BooleanAdapter())
220+
.add(new PrimitiveBooleanAdapter())
220221
.add(new DelimitedEnumSetAdapterFactory())
221222
.add(new HttpUrlAdapter())
222223
.add(new NotificationAdapter())

library/src/main/java/me/proxer/library/api/info/InfoApi.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,11 @@ public ModifyUserInfoEndpoint markAsFavorite(final String entryId) {
8787
public ModifyUserInfoEndpoint markAsFinished(final String entryId) {
8888
return new ModifyUserInfoEndpoint(internalApi, entryId, UserInfoType.FINISHED);
8989
}
90+
91+
/**
92+
* Returns the respective endpoint.
93+
*/
94+
public RecommendationsEndpoint recommendations(final String entryId) {
95+
return new RecommendationsEndpoint(internalApi, entryId);
96+
}
9097
}

library/src/main/java/me/proxer/library/api/info/InternalApi.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,7 @@ ProxerCall<List<Relation>> relations(@Query("id") String id,
4545
@POST("info/setuserinfo")
4646
ProxerCall<Void> modifyUserInfo(@Field("id") String id,
4747
@Field("type") UserInfoType type);
48+
49+
@GET("info/recommendations")
50+
ProxerCall<List<Recommendation>> recommendations(@Query("id") String id);
4851
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package me.proxer.library.api.info;
2+
3+
import lombok.experimental.Accessors;
4+
import me.proxer.library.api.Endpoint;
5+
import me.proxer.library.api.ProxerCall;
6+
import me.proxer.library.entity.info.Recommendation;
7+
8+
import java.util.List;
9+
10+
/**
11+
* Endpoint for retrieving the most important information of an {@link Recommendation}.
12+
*
13+
* @author Ruben Gees
14+
*/
15+
@Accessors(fluent = true)
16+
public final class RecommendationsEndpoint implements Endpoint<List<Recommendation>> {
17+
18+
private final InternalApi internalApi;
19+
20+
private final String id;
21+
22+
RecommendationsEndpoint(final InternalApi internalApi, final String id) {
23+
this.internalApi = internalApi;
24+
this.id = id;
25+
}
26+
27+
/**
28+
* {@inheritDoc}
29+
*/
30+
@Override
31+
public ProxerCall<List<Recommendation>> build() {
32+
return internalApi.recommendations(id);
33+
}
34+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package me.proxer.library.entity.info;
2+
3+
import com.squareup.moshi.Json;
4+
import lombok.Getter;
5+
import lombok.Value;
6+
import me.proxer.library.entity.ProxerIdItem;
7+
import me.proxer.library.enums.*;
8+
9+
import javax.annotation.Nullable;
10+
import java.util.Set;
11+
12+
/**
13+
* Entity holding the data associated with a recommendation.
14+
*
15+
* @author Ruben Gees
16+
*/
17+
@Value
18+
public class Recommendation implements ProxerIdItem {
19+
20+
/**
21+
* Returns the id.
22+
*/
23+
@Getter(onMethod = @__({@Override}))
24+
@Json(name = "id")
25+
private String id;
26+
27+
/**
28+
* Returns the name.
29+
*/
30+
@Json(name = "name")
31+
private String name;
32+
33+
/**
34+
* Returns the genres.
35+
*/
36+
@Json(name = "genre")
37+
private Set<Genre> genres;
38+
39+
/**
40+
* Returns the fsk ratings.
41+
*/
42+
@Json(name = "fsk")
43+
private Set<FskConstraint> fskConstraints;
44+
45+
/**
46+
* Returns the description.
47+
*/
48+
@Json(name = "description")
49+
private String description;
50+
51+
/**
52+
* Returns the medium
53+
*/
54+
@Json(name = "medium")
55+
private Medium medium;
56+
57+
/**
58+
* Returns the amount of episodes, this entry has. They do not necessarily have to be uploaded.
59+
*/
60+
@Json(name = "count")
61+
private int episodeAmount;
62+
63+
/**
64+
* Returns the current state.
65+
*/
66+
@Json(name = "state")
67+
private MediaState state;
68+
69+
/**
70+
* Returns the sum of all ratings.
71+
*/
72+
@Json(name = "rate_sum")
73+
private int ratingSum;
74+
75+
/**
76+
* Returns the amount of ratings.
77+
*/
78+
@Json(name = "rate_count")
79+
private int ratingAmount;
80+
81+
/**
82+
* Returns the clicks on this entry, in this season.
83+
*/
84+
@Json(name = "clicks")
85+
private int clicks;
86+
87+
/**
88+
* Returns the category.
89+
*/
90+
@Json(name = "kat")
91+
private Category category;
92+
93+
/**
94+
* Returns the type of license.
95+
*/
96+
@Json(name = "license")
97+
private License license;
98+
99+
/**
100+
* Returns the amount of positive votes.
101+
*/
102+
@Json(name = "count_positive")
103+
private int positiveVotes;
104+
105+
/**
106+
* Returns the amount of negative votes.
107+
*/
108+
@Json(name = "count_negative")
109+
private int negativeVotes;
110+
111+
/**
112+
* Returns the vote of the user if present when calling the respective api.
113+
*/
114+
@Nullable
115+
@Json(name = "positive")
116+
private Boolean userVote;
117+
118+
public Recommendation(final String id, final String name, final Set<Genre> genres,
119+
final Set<FskConstraint> fskConstraints, final String description, final Medium medium,
120+
final int episodeAmount, final MediaState state, final int ratingSum, final int ratingAmount,
121+
final int clicks, final Category category, final License license, final int positiveVotes,
122+
final int negativeVotes, @Nullable Boolean userVote) {
123+
this.id = id;
124+
this.name = name;
125+
this.genres = genres;
126+
this.fskConstraints = fskConstraints;
127+
this.description = description;
128+
this.medium = medium;
129+
this.episodeAmount = episodeAmount;
130+
this.state = state;
131+
this.ratingSum = ratingSum;
132+
this.ratingAmount = ratingAmount;
133+
this.clicks = clicks;
134+
this.category = category;
135+
this.license = license;
136+
this.positiveVotes = positiveVotes;
137+
this.negativeVotes = negativeVotes;
138+
this.userVote = userVote;
139+
}
140+
141+
/**
142+
* Returns the average of all ratings.
143+
*/
144+
public final float getRating() {
145+
if (ratingAmount <= 0) {
146+
return 0;
147+
} else {
148+
return ratingSum / (float) ratingAmount;
149+
}
150+
}
151+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package me.proxer.library.api;
2+
3+
import com.squareup.moshi.JsonDataException;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
7+
import static org.assertj.core.api.Assertions.assertThat;
8+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
9+
10+
/**
11+
* @author Ruben Gees
12+
*/
13+
public class PrimitiveBooleanAdapterTest {
14+
15+
private PrimitiveBooleanAdapter adapter;
16+
17+
@Before
18+
public void setUp() {
19+
adapter = new PrimitiveBooleanAdapter();
20+
}
21+
22+
@Test
23+
public void testDefault() {
24+
assertThat(adapter.fromJson("true")).isTrue();
25+
}
26+
27+
@Test
28+
public void testAlternative() {
29+
assertThat(adapter.fromJson("1")).isTrue();
30+
}
31+
32+
@Test
33+
public void testDefaultFalse() {
34+
assertThat(adapter.fromJson("false")).isFalse();
35+
}
36+
37+
@Test
38+
public void testAlternativeFalse() {
39+
assertThat(adapter.fromJson("0")).isFalse();
40+
}
41+
42+
@Test
43+
public void testInvalid() {
44+
assertThatExceptionOfType(JsonDataException.class).isThrownBy(() -> adapter.fromJson("malformed"));
45+
}
46+
47+
@Test
48+
public void testInvalidNumber() {
49+
assertThatExceptionOfType(JsonDataException.class).isThrownBy(() -> adapter.fromJson("3"));
50+
}
51+
}

0 commit comments

Comments
 (0)