package com.openseedbox.models;
import com.openseedbox.code.Util;
import com.openseedbox.gson.SerializedAccessorName;
import com.openseedbox.gson.UseAccessor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import play.Play;
import play.data.validation.Email;
import play.data.validation.Required;
import siena.Column;
import siena.Table;
import siena.Unique;
import siena.embed.Embedded;
@Table("users")
public class User extends ModelBase {
@Email @Required @Column("email_address")
@Unique("email_address_unique") private String emailAddress;
@Column("open_id") private String openId;
@Column("is_admin") private boolean admin;
@Column("avatar_url") private String avatarUrl;
@Required @Column("display_name") private String displayName;
@Column("last_access") private Date lastAccess;
@Column("api_key") private String apiKey;
@Column("plan_id") private Plan plan;
@Embedded private List<String> groups;
@Column("node_id") private Node dedicatedNode;
public static final transient String TORRENT_GROUP_UNGROUPED = "Ungrouped";
public static User findByApiKey(String apiKey) {
return User.all().filter("apiKey", apiKey).get();
}
public static User findByOpenId(String openId) {
return User.all().filter("openId", openId).get();
}
public static User findByEmailAddress(String emailAddress) {
return User.all().filter("emailAddress", emailAddress).get();
}
public boolean hasExceededLimits() {
Plan p = getPlan();
if (p == null || p.getMaxDiskspaceGb() == -1) {
return false;
}
return (getUsedSpaceBytes() > p.getMaxDiskspaceBytes());
}
public List<UserTorrent> getRunningTorrents() {
return UserTorrent.all().filter("user", this).filter("paused", false).fetch();
}
public void generateApiKey() {
String salt = Play.configuration.getProperty("application.secret", "salt value");
String key = this.emailAddress + salt;
this.apiKey = DigestUtils.md5Hex(key);
this.save();
}
public long getUsedSpaceBytes() {
List<UserTorrent> ut = getTorrents();
long sum = 0;
//TODO: make less retardedly inefficient
for (UserTorrent u : ut) {
sum += u.getTorrent().getTotalSizeBytes();
}
return sum;
}
public String getUsedSpace() {
return Util.getBestRate(getUsedSpaceBytes());
}
public List<UserTorrent> getTorrents() {
return getTorrentsInGroup(null);
}
public List<UserTorrent> getTorrentsInGroup(String group) {
List<UserTorrent> ut;
if (group == null) {
ut = UserTorrent.getByUser(this);
} else if (group.equals(User.TORRENT_GROUP_UNGROUPED)) {
ut = UserTorrent.getByUserAndGroup(this, null);
ut.addAll(UserTorrent.getByUserAndGroup(this, User.TORRENT_GROUP_UNGROUPED));
} else {
ut = UserTorrent.getByUserAndGroup(this, group);
}
if (ut.isEmpty()) {
return ut;
}
//Batch-load Torrents from the database to save a database call per torrent
List<String> hashes = new ArrayList<String>();
for (UserTorrent u : ut) {
hashes.add(u.getTorrentHash());
}
List<Torrent> all = Torrent.getByHash(hashes);
for (UserTorrent u : ut) {
for (Torrent t : all) {
if (u.getTorrentHash().equals(t.getTorrentHash())) {
u.setTorrent(t);
}
}
}
return ut;
}
public boolean hasPlan() {
return plan != null;
}
public List<Invoice> getUnpaidInvoices() {
return Invoice.getUnpaidForUser(this);
}
public List<Invoice> getPaidInvoices() {
return Invoice.getPaidForUser(this);
}
public void addTorrentGroup(String groupName) {
List<String> tgroups = getGroups();
if (!tgroups.contains(groupName)) {
tgroups.add(groupName);
setGroups(tgroups);
save();
}
}
public void removeTorrentGroup(String groupName) {
List<String> tgroups = getGroups();
tgroups.remove(groupName);
setGroups(tgroups);
save();
}
public UserStats getUserStats() {
int available = getPlan().getMaxDiskspaceGb();
long used = 0l;
long down = 0l;
long up = 0l;
List<UserTorrent> torrents = getTorrents();
for (UserTorrent ut : torrents) {
used += ut.getTorrent().getTotalSizeBytes();
down += ut.getTorrent().getDownloadSpeedBytes();
up += ut.getTorrent().getUploadSpeedBytes();
}
return new UserStats(available, used, down, up);
}
/* Getters and Setters */
public String getDisplayName() {
return StringUtils.isEmpty(this.displayName) ? this.emailAddress : this.displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean isAdmin) {
this.admin = isAdmin;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public Date getLastAccess() {
return lastAccess;
}
public void setLastAccess(Date lastAccess) {
this.lastAccess = lastAccess;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public Plan getPlan() {
if (plan != null) {
plan.get();
}
return plan;
}
public void setPlan(Plan plan) {
this.plan = plan;
}
public List<String> getGroups() {
if (groups != null) {
if (!groups.contains("Ungrouped")) {
Collections.reverse(groups);
groups.add("Ungrouped");
Collections.reverse(groups);
}
return groups;
}
return new ArrayList<String>(Arrays.asList("Ungrouped"));
}
public void setGroups(List<String> groups) {
this.groups = groups;
}
public boolean hasDedicatedNode() {
return dedicatedNode != null;
}
public Node getDedicatedNode() {
if (dedicatedNode != null) {
dedicatedNode.get();
}
return dedicatedNode;
}
public void setDedicatedNode(Node dedicatedNode) {
this.dedicatedNode = dedicatedNode;
}
/* End Getters and Setters */
@UseAccessor
public class UserStats {
private int availableSpaceGb;
private long usedSpaceBytes;
private long totalDownloadSpeedBytes;
private long totalUploadSpeedBytes;
public UserStats(int availableSpaceGb, long usedSpaceBytes, long totalDownloadSpeedBytes, long totalUploadSpeedBytes) {
this.availableSpaceGb = availableSpaceGb;
this.usedSpaceBytes = usedSpaceBytes;
this.totalDownloadSpeedBytes = totalDownloadSpeedBytes;
this.totalUploadSpeedBytes = totalUploadSpeedBytes;
}
@SerializedAccessorName("available-space-gb")
public String getAvailableSpaceGb() {
if (availableSpaceGb != -1) {
return "" + availableSpaceGb + " GB";
}
return "Unlimited GB";
}
@SerializedAccessorName("used-space-gb")
public String getUsedSpaceGb() {
return Util.getBestRate(usedSpaceBytes);
}
@SerializedAccessorName("percent-used")
public String getPercentUsed() {
if (availableSpaceGb != -1 && usedSpaceBytes > 0) {
long bytes = getPlan().getMaxDiskspaceBytes();
String asPercent = Util.formatPercentage(((double) usedSpaceBytes / (double) bytes) * 100);
return asPercent + "%";
}
return "";
}
@SerializedAccessorName("total-download-rate")
public String getTotalDownloadRate() {
return Util.getBestRate(totalDownloadSpeedBytes);
}
@SerializedAccessorName("total-upload-rate")
public String getTotalUploadRate() {
return Util.getBestRate(totalUploadSpeedBytes);
}
}
}