/*
* Copyright 2016 Sam Sun <me@samczsun.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.samczsun.skype4j.internal.participants.info;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.samczsun.skype4j.Skype;
import com.samczsun.skype4j.chat.Chat;
import com.samczsun.skype4j.exceptions.ChatNotFoundException;
import com.samczsun.skype4j.exceptions.ConnectionException;
import com.samczsun.skype4j.exceptions.NoSuchContactException;
import com.samczsun.skype4j.internal.Endpoints;
import com.samczsun.skype4j.internal.SkypeImpl;
import com.samczsun.skype4j.internal.Utils;
import com.samczsun.skype4j.internal.client.FullClient;
import com.samczsun.skype4j.internal.utils.Encoder;
import com.samczsun.skype4j.participants.info.Contact;
import org.jsoup.helper.Validate;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.UUID;
import java.util.regex.Pattern;
public class ContactImpl implements Contact {
private static final Pattern PHONE_NUMBER = Pattern.compile("\\+[0-9]+");
public static Contact createContact(SkypeImpl skype, String username) throws ConnectionException {
Validate.notEmpty(username, "Username must not be empty");
return new ContactImpl(skype, username, getObject(skype, username));
}
public static Contact createContact(SkypeImpl skype, String username, JsonObject unaddedData) throws ConnectionException {
Validate.notEmpty(username, "Username must not be empty");
return new ContactImpl(skype, username, unaddedData);
}
private static JsonObject getObject(SkypeImpl skype, String username) throws ConnectionException {
JsonArray array = Endpoints.PROFILE_INFO
.open(skype)
.expect(200, "While getting contact info")
.as(JsonArray.class)
.post(new JsonObject()
.add("usernames", new JsonArray()
.add(username)
)
);
return array.get(0).asObject();
}
private SkypeImpl skype;
private String username;
private String displayName;
private String firstName;
private String lastName;
private String birthday;
private String gender;
private String language;
private String avatarURL;
private BufferedImage avatar;
private String mood;
private String richMood;
private String country;
private String city;
private boolean isPhone;
private boolean isAuthorized;
private boolean isBlocked;
// What is this?
private String authCertificate;
private UUID personId;
private String type;
public ContactImpl(SkypeImpl skype, String username, JsonObject unaddedData) throws ConnectionException {
this.skype = skype;
this.username = username;
if (!PHONE_NUMBER.matcher(username).matches()) {
updateProfile(unaddedData);
updateContactInfo();
} else {
this.isPhone = true;
}
}
public ContactImpl(SkypeImpl skype, JsonObject contact) throws ConnectionException {
this.skype = skype;
update(contact);
updateProfile(getObject(skype, getUsername()));
}
private void updateContactInfo() throws ConnectionException {
if (this.skype instanceof FullClient) {
JsonObject obj = Endpoints.GET_CONTACT_BY_ID
.open(skype, skype.getUsername(), username)
.as(JsonObject.class)
.expect(200, "While getting contact info")
.get();
if (obj.get("contacts").asArray().size() > 0) {
JsonObject contact = obj.get("contacts").asArray().get(0).asObject();
update(contact);
} else {
this.isAuthorized = false;
this.isBlocked = false;
}
}
}
@Override
public String getUsername() {
return this.username;
}
@Override
public String getDisplayName() {
return this.displayName;
}
@Override
public String getFirstName() {
return this.firstName;
}
@Override
public String getLastName() {
return this.lastName;
}
@Override
public BufferedImage getAvatarPicture() throws ConnectionException {
if (this.avatarURL != null) {
if (this.avatar == null) {
//Casting might not be safe.
this.avatar = Endpoints
.custom(this.avatarURL, skype)
.expect(200, "While fetching avatar")
.as(BufferedImage.class)
.get();
}
BufferedImage clone = new BufferedImage(avatar.getWidth(), avatar.getHeight(), avatar.getType());
Graphics2D g2d = clone.createGraphics();
g2d.drawImage(avatar, 0, 0, null);
g2d.dispose();
return clone;
}
return null;
}
@Override
public String getAvatarURL() {
return this.avatarURL;
}
@Override
public String getMood() {
return this.mood;
}
@Override
public String getRichMood() {
return this.richMood;
}
@Override
public String getCountry() {
return this.country;
}
@Override
public String getCity() {
return this.city;
}
@Override
public boolean isAuthorized() {
return this.isAuthorized;
}
@Override
public void authorize() throws ConnectionException {
Endpoints.AUTHORIZE_CONTACT.open(skype, this.username).expect(200, "While authorizing contact").put();
updateContactInfo();
}
@Override
public void unauthorize() throws ConnectionException {
if (isAuthorized) {
Endpoints.UNAUTHORIZE_CONTACT_SELF
.open(skype, this.username)
.expect(200, "While unauthorizing contact")
.put();
} else {
Endpoints.DECLINE_CONTACT_REQUEST
.open(skype, this.username)
.expect(201, "While unauthorizing contact")
.put();
}
updateContactInfo();
}
@Override
public void sendRequest(String message) throws ConnectionException, NoSuchContactException {
Endpoints.AUTHORIZATION_REQUEST
.open(skype, this.username)
.on(404, (connection) -> {
throw new NoSuchContactException();
})
.expect(201, "While sending request")
.expect(200, "While sending request")
.put("greeting=" + Encoder.encode(message));
updateContactInfo();
}
@Override
public boolean isBlocked() {
return this.isBlocked;
}
@Override
public void block(boolean reportAbuse) throws ConnectionException {
Endpoints.BLOCK_CONTACT
.open(skype, this.username)
.expect(201, "While unblocking contact")
.put("reporterIp=127.0.0.1&uiVersion=" + Skype.VERSION + (reportAbuse ? "&reportAbuse=1" : ""));
updateContactInfo();
}
@Override
public void unblock() throws ConnectionException {
Endpoints.UNBLOCK_CONTACT.open(skype, this.username).expect(201, "While unblocking contact").put();
updateContactInfo();
}
@Override
public boolean isPhone() {
return this.isPhone;
}
@Override
public Chat getPrivateConversation() throws ConnectionException, ChatNotFoundException {
return skype.getOrLoadChat("8:" + this.username);
}
public void update(JsonObject contact) {
this.username = contact.get("id").asString();
this.isAuthorized = contact.get("authorized").asBoolean();
this.isBlocked = contact.get("blocked").asBoolean();
this.displayName = Utils.getString(contact, "display_name");
this.avatarURL = Utils.getString(contact, "avatar_url");
this.mood = Utils.getString(contact, "mood");
this.type = Utils.getString(contact, "type");
this.authCertificate = Utils.getString(contact, "auth_certificate");
this.firstName = contact.get("name") == null ? null : Utils.getString(contact.get("name").asObject(), "first");
if (contact.get("locations") != null) {
JsonObject locations = contact.get("locations").asArray().get(0).asObject();
this.country = locations.get("country") == null ? null : locations.get("country").asString();
this.city = locations.get("city") == null ? null : locations.get("city").asString();
}
}
public void updateProfile(JsonObject profile) {
this.firstName = Utils.getString(profile, "firstname");
this.lastName = Utils.getString(profile, "lastname");
this.birthday = Utils.getString(profile, "birthday");
if (profile.get("gender") != null) {
if (profile.get("gender").isNumber()) {
this.gender = String.valueOf(profile.get("gender").asInt());
} else if (profile.get("gender").isString()) {
this.gender = profile.get("gender").asString();
} else if (profile.get("gender").isBoolean()) {
this.gender = profile.get("gender").asBoolean() ? "1" : "0";
} else {
this.gender = profile.get("gender").toString();
}
}
this.language = Utils.getString(profile, "language");
this.avatarURL = Utils.getString(profile, "avatarUrl");
if (this.displayName == null)
this.displayName = Utils.getString(profile, "displayname");
if (this.mood == null)
this.mood = Utils.getString(profile, "mood");
if (this.richMood == null)
this.richMood = Utils.getString(profile, "richMood");
if (this.country == null)
this.country = Utils.getString(profile, "country");
if (this.city == null)
this.city = Utils.getString(profile, "city");
if (this.displayName == null) {
if (this.firstName != null) {
this.displayName = this.firstName;
if (this.lastName != null) {
this.displayName = this.displayName + " " + this.lastName;
}
} else if (this.lastName != null) {
this.displayName = this.lastName;
} else {
this.displayName = this.username;
}
}
}
}