Initial
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a user of Mastodon and their associated profile.
|
||||
*/
|
||||
public class Account extends BaseModel{
|
||||
// Base attributes
|
||||
|
||||
/**
|
||||
* The account id
|
||||
*/
|
||||
@RequiredField
|
||||
public String id;
|
||||
/**
|
||||
* The username of the account, not including domain.
|
||||
*/
|
||||
@RequiredField
|
||||
public String username;
|
||||
/**
|
||||
* The Webfinger account URI. Equal to username for local users, or username@domain for remote users.
|
||||
*/
|
||||
@RequiredField
|
||||
public String acct;
|
||||
/**
|
||||
* The location of the user's profile page.
|
||||
*/
|
||||
@RequiredField
|
||||
public String url;
|
||||
|
||||
// Display attributes
|
||||
|
||||
/**
|
||||
* The profile's display name.
|
||||
*/
|
||||
@RequiredField
|
||||
public String displayName;
|
||||
/**
|
||||
* The profile's bio / description.
|
||||
*/
|
||||
@RequiredField
|
||||
public String note;
|
||||
/**
|
||||
* An image icon that is shown next to statuses and in the profile.
|
||||
*/
|
||||
@RequiredField
|
||||
public String avatar;
|
||||
/**
|
||||
* A static version of the avatar. Equal to avatar if its value is a static image; different if avatar is an animated GIF.
|
||||
*/
|
||||
public String avatarStatic;
|
||||
/**
|
||||
* An image banner that is shown above the profile and in profile cards.
|
||||
*/
|
||||
@RequiredField
|
||||
public String header;
|
||||
/**
|
||||
* A static version of the header. Equal to header if its value is a static image; different if header is an animated GIF.
|
||||
*/
|
||||
public String headerStatic;
|
||||
/**
|
||||
* Whether the account manually approves follow requests.
|
||||
*/
|
||||
public boolean locked;
|
||||
/**
|
||||
* Custom emoji entities to be used when rendering the profile. If none, an empty array will be returned.
|
||||
*/
|
||||
public List<Emoji> emojis;
|
||||
/**
|
||||
* Whether the account has opted into discovery features such as the profile directory.
|
||||
*/
|
||||
public boolean discoverable;
|
||||
|
||||
// Statistical attributes
|
||||
|
||||
/**
|
||||
* When the account was created.
|
||||
*/
|
||||
@RequiredField
|
||||
public Instant createdAt;
|
||||
/**
|
||||
* When the most recent status was posted.
|
||||
*/
|
||||
// @RequiredField
|
||||
public LocalDate lastStatusAt;
|
||||
/**
|
||||
* How many statuses are attached to this account.
|
||||
*/
|
||||
public int statusesCount;
|
||||
/**
|
||||
* The reported followers of this profile.
|
||||
*/
|
||||
public int followersCount;
|
||||
/**
|
||||
* The reported follows of this profile.
|
||||
*/
|
||||
public int followingCount;
|
||||
|
||||
// Optional attributes
|
||||
|
||||
/**
|
||||
* Indicates that the profile is currently inactive and that its user has moved to a new account.
|
||||
*/
|
||||
public Account moved;
|
||||
/**
|
||||
* Additional metadata attached to a profile as name-value pairs.
|
||||
*/
|
||||
public List<AccountField> fields;
|
||||
/**
|
||||
* A presentational flag. Indicates that the account may perform automated actions, may not be monitored, or identifies as a robot.
|
||||
*/
|
||||
public boolean bot;
|
||||
/**
|
||||
* An extra entity to be used with API methods to verify credentials and update credentials.
|
||||
*/
|
||||
public Source source;
|
||||
/**
|
||||
* An extra entity returned when an account is suspended.
|
||||
*/
|
||||
public boolean suspended;
|
||||
/**
|
||||
* When a timed mute will expire, if applicable.
|
||||
*/
|
||||
public Instant muteExpiresAt;
|
||||
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(fields!=null){
|
||||
for(AccountField f:fields)
|
||||
f.postprocess();
|
||||
}
|
||||
if(emojis!=null){
|
||||
for(Emoji e:emojis)
|
||||
e.postprocess();
|
||||
}
|
||||
if(moved!=null)
|
||||
moved.postprocess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Account{"+
|
||||
"id='"+id+'\''+
|
||||
", username='"+username+'\''+
|
||||
", acct='"+acct+'\''+
|
||||
", url='"+url+'\''+
|
||||
", displayName='"+displayName+'\''+
|
||||
", note='"+note+'\''+
|
||||
", avatar='"+avatar+'\''+
|
||||
", avatarStatic='"+avatarStatic+'\''+
|
||||
", header='"+header+'\''+
|
||||
", headerStatic='"+headerStatic+'\''+
|
||||
", locked="+locked+
|
||||
", emojis="+emojis+
|
||||
", discoverable="+discoverable+
|
||||
", createdAt="+createdAt+
|
||||
", lastStatusAt="+lastStatusAt+
|
||||
", statusesCount="+statusesCount+
|
||||
", followersCount="+followersCount+
|
||||
", followingCount="+followingCount+
|
||||
", moved="+moved+
|
||||
", fields="+fields+
|
||||
", bot="+bot+
|
||||
", source="+source+
|
||||
", suspended="+suspended+
|
||||
", muteExpiresAt="+muteExpiresAt+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Represents a profile field as a name-value pair with optional verification.
|
||||
*/
|
||||
public class AccountField extends BaseModel{
|
||||
/**
|
||||
* The key of a given field's key-value pair.
|
||||
*/
|
||||
@RequiredField
|
||||
public String name;
|
||||
/**
|
||||
* The value associated with the name key.
|
||||
*/
|
||||
@RequiredField
|
||||
public String value;
|
||||
/**
|
||||
* Timestamp of when the server verified a URL value for a rel="me” link.
|
||||
*/
|
||||
public Instant verifiedAt;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
public class Application extends BaseModel{
|
||||
@RequiredField
|
||||
public String name;
|
||||
public String website;
|
||||
public String vapidKey;
|
||||
public String clientId;
|
||||
public String clientSecret;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Application{"+
|
||||
"name='"+name+'\''+
|
||||
", website='"+website+'\''+
|
||||
", vapidKey='"+vapidKey+'\''+
|
||||
", clientId='"+clientId+'\''+
|
||||
", clientSecret='"+clientSecret+'\''+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
|
||||
public abstract class BaseModel{
|
||||
@CallSuper
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
try{
|
||||
boolean allRequired=getClass().isAnnotationPresent(AllFieldsAreRequired.class);
|
||||
for(Field fld:getClass().getFields()){
|
||||
if(!fld.getType().isPrimitive() && !Modifier.isTransient(fld.getModifiers()) && (allRequired || fld.isAnnotationPresent(RequiredField.class))){
|
||||
if(fld.get(this)==null){
|
||||
throw new ObjectValidationException("Required field '"+fld.getName()+"' of type "+fld.getType().getSimpleName()+" was null in "+getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(IllegalAccessException ignore){}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
/**
|
||||
* Represents a custom emoji.
|
||||
*/
|
||||
public class Emoji extends BaseModel{
|
||||
/**
|
||||
* The name of the custom emoji.
|
||||
*/
|
||||
@RequiredField
|
||||
public String shortcode;
|
||||
/**
|
||||
* A link to the custom emoji.
|
||||
*/
|
||||
@RequiredField
|
||||
public String url;
|
||||
/**
|
||||
* A link to a static copy of the custom emoji.
|
||||
*/
|
||||
@RequiredField
|
||||
public String staticUrl;
|
||||
/**
|
||||
* Whether this Emoji should be visible in the picker or unlisted.
|
||||
*/
|
||||
@RequiredField
|
||||
public boolean visibleInPicker;
|
||||
/**
|
||||
* Used for sorting custom emoji in the picker.
|
||||
*/
|
||||
public String category;
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.Html;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
import org.joinmastodon.android.model.catalog.CatalogInstance;
|
||||
|
||||
import java.net.IDN;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Instance extends BaseModel{
|
||||
/**
|
||||
* The domain name of the instance.
|
||||
*/
|
||||
@RequiredField
|
||||
public String uri;
|
||||
/**
|
||||
* The title of the website.
|
||||
*/
|
||||
@RequiredField
|
||||
public String title;
|
||||
/**
|
||||
* Admin-defined description of the Mastodon site.
|
||||
*/
|
||||
@RequiredField
|
||||
public String description;
|
||||
/**
|
||||
* A shorter description defined by the admin.
|
||||
*/
|
||||
@RequiredField
|
||||
public String shortDescription;
|
||||
/**
|
||||
* An email that may be contacted for any inquiries.
|
||||
*/
|
||||
@RequiredField
|
||||
public String email;
|
||||
/**
|
||||
* The version of Mastodon installed on the instance.
|
||||
*/
|
||||
@RequiredField
|
||||
public String version;
|
||||
/**
|
||||
* Primary langauges of the website and its staff.
|
||||
*/
|
||||
// @RequiredField
|
||||
public List<String> languages;
|
||||
/**
|
||||
* Whether registrations are enabled.
|
||||
*/
|
||||
public boolean registrations;
|
||||
/**
|
||||
* Whether registrations require moderator approval.
|
||||
*/
|
||||
public boolean approvalRequired;
|
||||
/**
|
||||
* Whether invites are enabled.
|
||||
*/
|
||||
public boolean invitesEnabled;
|
||||
/**
|
||||
* URLs of interest for clients apps.
|
||||
*/
|
||||
public Map<String, String> urls;
|
||||
|
||||
/**
|
||||
* Banner image for the website.
|
||||
*/
|
||||
public String thumbnail;
|
||||
/**
|
||||
* A user that can be contacted, as an alternative to email.
|
||||
*/
|
||||
public Account contactAccount;
|
||||
public Stats stats;
|
||||
|
||||
public int maxTootChars;
|
||||
public List<Rule> rules;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(contactAccount!=null)
|
||||
contactAccount.postprocess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Instance{"+
|
||||
"uri='"+uri+'\''+
|
||||
", title='"+title+'\''+
|
||||
", description='"+description+'\''+
|
||||
", shortDescription='"+shortDescription+'\''+
|
||||
", email='"+email+'\''+
|
||||
", version='"+version+'\''+
|
||||
", languages="+languages+
|
||||
", registrations="+registrations+
|
||||
", approvalRequired="+approvalRequired+
|
||||
", invitesEnabled="+invitesEnabled+
|
||||
", urls="+urls+
|
||||
", thumbnail='"+thumbnail+'\''+
|
||||
", contactAccount="+contactAccount+
|
||||
'}';
|
||||
}
|
||||
|
||||
public CatalogInstance toCatalogInstance(){
|
||||
CatalogInstance ci=new CatalogInstance();
|
||||
ci.domain=uri;
|
||||
ci.normalizedDomain=IDN.toUnicode(uri);
|
||||
ci.description=Html.fromHtml(shortDescription).toString().trim();
|
||||
if(languages!=null){
|
||||
ci.language=languages.get(0);
|
||||
ci.languages=languages;
|
||||
}else{
|
||||
ci.languages=Collections.emptyList();
|
||||
ci.language="unknown";
|
||||
}
|
||||
ci.proxiedThumbnail=thumbnail;
|
||||
if(stats!=null)
|
||||
ci.totalUsers=stats.userCount;
|
||||
return ci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class Rule implements Parcelable{
|
||||
public String id;
|
||||
public String text;
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags){
|
||||
dest.writeString(this.id);
|
||||
dest.writeString(this.text);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source){
|
||||
this.id=source.readString();
|
||||
this.text=source.readString();
|
||||
}
|
||||
|
||||
public Rule(){
|
||||
}
|
||||
|
||||
protected Rule(Parcel in){
|
||||
this.id=in.readString();
|
||||
this.text=in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Rule> CREATOR=new Parcelable.Creator<Rule>(){
|
||||
@Override
|
||||
public Rule createFromParcel(Parcel source){
|
||||
return new Rule(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rule[] newArray(int size){
|
||||
return new Rule[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class Stats implements Parcelable{
|
||||
public int userCount;
|
||||
public int statusCount;
|
||||
public int domainCount;
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags){
|
||||
dest.writeInt(this.userCount);
|
||||
dest.writeInt(this.statusCount);
|
||||
dest.writeInt(this.domainCount);
|
||||
}
|
||||
|
||||
public void readFromParcel(Parcel source){
|
||||
this.userCount=source.readInt();
|
||||
this.statusCount=source.readInt();
|
||||
this.domainCount=source.readInt();
|
||||
}
|
||||
|
||||
public Stats(){
|
||||
}
|
||||
|
||||
protected Stats(Parcel in){
|
||||
this.userCount=in.readInt();
|
||||
this.statusCount=in.readInt();
|
||||
this.domainCount=in.readInt();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Stats> CREATOR=new Parcelable.Creator<Stats>(){
|
||||
@Override
|
||||
public Stats createFromParcel(Parcel source){
|
||||
return new Stats(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stats[] newArray(int size){
|
||||
return new Stats[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.api.RequiredField;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents display or publishing preferences of user's own account. Returned as an additional entity when verifying and updated credentials, as an attribute of Account.
|
||||
*/
|
||||
public class Source extends BaseModel{
|
||||
/**
|
||||
* Profile bio.
|
||||
*/
|
||||
@RequiredField
|
||||
public String note;
|
||||
/**
|
||||
* Metadata about the account.
|
||||
*/
|
||||
@RequiredField
|
||||
public List<AccountField> fields;
|
||||
/**
|
||||
* The default post privacy to be used for new statuses.
|
||||
*/
|
||||
public StatusPrivacy privacy;
|
||||
/**
|
||||
* Whether new statuses should be marked sensitive by default.
|
||||
*/
|
||||
public boolean sensitive;
|
||||
/**
|
||||
* The default posting language for new statuses.
|
||||
*/
|
||||
public String language;
|
||||
/**
|
||||
* The number of pending follow requests.
|
||||
*/
|
||||
public int followRequestCount;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
for(AccountField f:fields)
|
||||
f.postprocess();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public enum StatusPrivacy{
|
||||
@SerializedName("public")
|
||||
PUBLIC,
|
||||
@SerializedName("unlisted")
|
||||
UNLISTED,
|
||||
@SerializedName("private")
|
||||
PRIVATE,
|
||||
@SerializedName("direct")
|
||||
DIRECT;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
|
||||
/**
|
||||
* Represents an OAuth token used for authenticating with the API and performing actions.
|
||||
*/
|
||||
@AllFieldsAreRequired
|
||||
public class Token extends BaseModel{
|
||||
/**
|
||||
* An OAuth token to be used for authorization.
|
||||
*/
|
||||
public String accessToken;
|
||||
/**
|
||||
* The OAuth token type. Mastodon uses Bearer tokens.
|
||||
*/
|
||||
public String tokenType;
|
||||
/**
|
||||
* The OAuth scopes granted by this token, space-separated.
|
||||
*/
|
||||
public String scope;
|
||||
/**
|
||||
* When the token was generated.
|
||||
* (unixtime)
|
||||
*/
|
||||
public long createdAt;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.joinmastodon.android.model.catalog;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
import org.joinmastodon.android.model.BaseModel;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
public class CatalogCategory extends BaseModel{
|
||||
public String category;
|
||||
public int serversCount;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "CatalogCategory{"+
|
||||
"category='"+category+'\''+
|
||||
", serversCount="+serversCount+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.joinmastodon.android.model.catalog;
|
||||
|
||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||
import org.joinmastodon.android.api.ObjectValidationException;
|
||||
import org.joinmastodon.android.model.BaseModel;
|
||||
|
||||
import java.net.IDN;
|
||||
import java.util.List;
|
||||
|
||||
@AllFieldsAreRequired
|
||||
public class CatalogInstance extends BaseModel{
|
||||
public String domain;
|
||||
public String version;
|
||||
public String description;
|
||||
public List<String> languages;
|
||||
public String region;
|
||||
public List<String> categories;
|
||||
public String proxiedThumbnail;
|
||||
public int totalUsers;
|
||||
public int lastWeekUsers;
|
||||
public boolean approvalRequired;
|
||||
public String language;
|
||||
public String category;
|
||||
|
||||
public transient String normalizedDomain;
|
||||
|
||||
@Override
|
||||
public void postprocess() throws ObjectValidationException{
|
||||
super.postprocess();
|
||||
if(domain.startsWith("xn--") || domain.contains(".xn--"))
|
||||
normalizedDomain=IDN.toUnicode(domain);
|
||||
else
|
||||
normalizedDomain=domain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "CatalogInstance{"+
|
||||
"domain='"+domain+'\''+
|
||||
", version='"+version+'\''+
|
||||
", description='"+description+'\''+
|
||||
", languages="+languages+
|
||||
", region='"+region+'\''+
|
||||
", categories="+categories+
|
||||
", proxiedThumbnail='"+proxiedThumbnail+'\''+
|
||||
", totalUsers="+totalUsers+
|
||||
", lastWeekUsers="+lastWeekUsers+
|
||||
", approvalRequired="+approvalRequired+
|
||||
", language='"+language+'\''+
|
||||
", category='"+category+'\''+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user