-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding support for generating and saving a QR code for a profile, upd…
…ating methods and documentation
- Loading branch information
1 parent
2cf6707
commit e50787a
Showing
7 changed files
with
576 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
260 changes: 260 additions & 0 deletions
260
src/main/java/com/github/natche/gravatarjavaclient/avatar/GravatarQrCodeRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
package com.github.natche.gravatarjavaclient.avatar; | ||
|
||
import com.github.natche.gravatarjavaclient.enums.GravatarQrImageType; | ||
import com.github.natche.gravatarjavaclient.enums.GravatarQrImageVersion; | ||
import com.github.natche.gravatarjavaclient.exceptions.GravatarJavaClientException; | ||
import com.github.natche.gravatarjavaclient.utils.Hasher; | ||
import com.github.natche.gravatarjavaclient.utils.InputValidator; | ||
import com.google.common.base.Preconditions; | ||
import com.google.common.collect.Range; | ||
import com.google.errorprone.annotations.CanIgnoreReturnValue; | ||
|
||
import javax.imageio.ImageIO; | ||
import java.awt.image.BufferedImage; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.URL; | ||
|
||
/** | ||
* A request for a user's profile QR code from Gravatar. | ||
*/ | ||
public final class GravatarQrCodeRequest { | ||
/** | ||
* The range of acceptable lengths for a QR code image returned by Gravatar. | ||
*/ | ||
private static final Range<Integer> IMAGE_LENGTH_RANGE = Range.closed(80, 1024); | ||
|
||
/** | ||
* The hash computed from the user email for this builder. | ||
*/ | ||
private final String hash; | ||
|
||
/** | ||
* The size for the image returned by this request. | ||
*/ | ||
private int size = IMAGE_LENGTH_RANGE.lowerEndpoint(); | ||
|
||
/** | ||
* The QR image type for this request. | ||
*/ | ||
private GravatarQrImageType imageType = GravatarQrImageType.DEFAULT; | ||
|
||
/** | ||
* The QR code version for this request. | ||
*/ | ||
private GravatarQrImageVersion version = GravatarQrImageVersion.BLANK; | ||
|
||
/** | ||
* Constructs a new GravatarQrCodeRequest from the provided hash. | ||
* | ||
* @param hash the hash pointing to an Avatar | ||
*/ | ||
private GravatarQrCodeRequest(String hash) { | ||
this.hash = hash; | ||
} | ||
|
||
/** | ||
* Constructs and returns a new GravatarQrCodeRequest. | ||
* | ||
* @param email the email for this Gravatar QR code request | ||
* @throws NullPointerException if the email is null | ||
* @throws IllegalArgumentException if the email is empty or not a valid email address | ||
*/ | ||
public static GravatarQrCodeRequest fromEmail(String email) { | ||
Preconditions.checkNotNull(email); | ||
Preconditions.checkArgument(!email.trim().isEmpty()); | ||
Preconditions.checkArgument(InputValidator.from(email).isValidEmailAddress()); | ||
|
||
String hash = Hasher.SHA256_HASHER.hash(email); | ||
return new GravatarQrCodeRequest(hash); | ||
} | ||
|
||
/** | ||
* Constructs and returns a new GravatarQrCodeRequest. | ||
* | ||
* @param hash the hash for this Gravatar QR code request obtained by SHA256 hashing a valid email address | ||
* @throws NullPointerException if the hash is null | ||
* @throws IllegalArgumentException if the hash is empty | ||
*/ | ||
public static GravatarQrCodeRequest fromHash(String hash) { | ||
Preconditions.checkNotNull(hash); | ||
Preconditions.checkArgument(!hash.trim().isEmpty()); | ||
|
||
return new GravatarQrCodeRequest(hash); | ||
} | ||
|
||
/** | ||
* Returns the hash for this request. | ||
* | ||
* @return the hash for this request | ||
*/ | ||
public String getHash() { | ||
return this.hash; | ||
} | ||
|
||
/** | ||
* Sets the image length the image of this request should return. | ||
* | ||
* @param imageLength the length of the image this request should return | ||
* @return this builder | ||
* @throws IllegalArgumentException if the provided image length is not in the range {@link #IMAGE_LENGTH_RANGE} | ||
*/ | ||
@CanIgnoreReturnValue | ||
public GravatarQrCodeRequest setSize(int imageLength) { | ||
Preconditions.checkArgument(IMAGE_LENGTH_RANGE.contains(imageLength)); | ||
this.size = imageLength; | ||
return this; | ||
} | ||
|
||
/** | ||
* Returns the size of the image this request should return. | ||
* | ||
* @return the size of the image this request should return | ||
*/ | ||
public int getSize() { | ||
return size; | ||
} | ||
|
||
/** | ||
* Sets the image type this request will use. | ||
* See {@link GravatarQrImageType}. | ||
* | ||
* @param type the image type | ||
* @return this builder | ||
* @throws NullPointerException if the provided type is null | ||
*/ | ||
@CanIgnoreReturnValue | ||
public GravatarQrCodeRequest setImageType(GravatarQrImageType type) { | ||
Preconditions.checkNotNull(type); | ||
this.imageType = type; | ||
return this; | ||
} | ||
|
||
/** | ||
* Returns the image type this request will use. | ||
* | ||
* @return the image type this request will use | ||
*/ | ||
public GravatarQrImageType getImageType() { | ||
return imageType; | ||
} | ||
|
||
/** | ||
* Sets the QR code version this request will use. | ||
* | ||
* @param version the QR code version this request will use | ||
* @return this builder | ||
* @throws NullPointerException if the provided version is null | ||
*/ | ||
@CanIgnoreReturnValue | ||
public GravatarQrCodeRequest setVersion(GravatarQrImageVersion version) { | ||
Preconditions.checkNotNull(version); | ||
this.version = version; | ||
return this; | ||
} | ||
|
||
/** | ||
* Returns the QR code version this request will use. | ||
* | ||
* @return the QR code version this request will use | ||
*/ | ||
public GravatarQrImageVersion getVersion() { | ||
return version; | ||
} | ||
|
||
/** | ||
* Returns the URL for requesting the QR code based on the current state of this. | ||
* | ||
* @return the URL for requesting the QR code based on the current state of this | ||
*/ | ||
public String getRequestUrl() { | ||
String baseUrl = "https://gravatar.com/"; | ||
return baseUrl + hash + ".qr" | ||
+ imageType.getAsUrlParameter(true) | ||
+ version.getAsUrlParameter(false) | ||
+ "&size=" + this.size; | ||
} | ||
|
||
/** | ||
* Reads and returns a {@link BufferedImage} using the URL constructed from the current state of this. | ||
* | ||
* @return a {@link BufferedImage} representing a QR code | ||
* @throws GravatarJavaClientException if an exception occurs reading from the URL | ||
*/ | ||
public BufferedImage getBufferedImage() { | ||
try { | ||
return ImageIO.read(new URL(getRequestUrl())); | ||
} catch (IOException e) { | ||
throw new GravatarJavaClientException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Saves the QR code obtained from this to the provided file as a PNG. | ||
* Note: the API returns a PNG which is why encoding options are not allowed by this method. | ||
* | ||
* @param saveTo the file to save the QR code to as a PNG | ||
* @return whether the save operation was successful | ||
* @throws NullPointerException if the provided file is null | ||
* @throws IllegalArgumentException if the provided file references a directory or exists | ||
*/ | ||
@CanIgnoreReturnValue | ||
public boolean saveTo(File saveTo) { | ||
Preconditions.checkNotNull(saveTo); | ||
Preconditions.checkArgument(!saveTo.isDirectory()); | ||
Preconditions.checkArgument(!saveTo.exists()); | ||
|
||
return GravatarAvatarRequestImageSaver.INSTANCE.saveTo(getBufferedImage(), saveTo, "png"); | ||
} | ||
|
||
/** | ||
* Returns a hashcode of this object. | ||
* | ||
* @return a hashcode of this object | ||
*/ | ||
@Override | ||
public int hashCode() { | ||
int ret = hash.hashCode(); | ||
ret = 31 * ret + Integer.hashCode(size); | ||
ret = 31 * ret + imageType.hashCode(); | ||
ret = 31 * ret + version.hashCode(); | ||
return ret; | ||
} | ||
|
||
/** | ||
* Returns a string representation of this object. | ||
* | ||
* @return a string representation of this object | ||
*/ | ||
@Override | ||
public String toString() { | ||
return "GravatarQrCodeRequest{" | ||
+ "hash=\"" + hash + "\", " | ||
+ "size=" + size + ", " | ||
+ "imageType=" + imageType + ", " | ||
+ "version=" + version | ||
+ "}"; | ||
|
||
} | ||
|
||
/** | ||
* Returns whether the provided object equals this. | ||
* | ||
* @param o the other object | ||
* @return whether the provided object equals this | ||
*/ | ||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} else if (!(o instanceof GravatarQrCodeRequest)) { | ||
return false; | ||
} | ||
|
||
GravatarQrCodeRequest other = (GravatarQrCodeRequest) o; | ||
return other.hash.equals(hash) | ||
&& other.version == version | ||
&& other.imageType == imageType | ||
&& other.size == size; | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
src/main/java/com/github/natche/gravatarjavaclient/enums/GravatarQrImageType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.github.natche.gravatarjavaclient.enums; | ||
|
||
/** | ||
* The valid types of QR images returned by the Gravatar API. | ||
*/ | ||
public enum GravatarQrImageType { | ||
/** | ||
* No logo or avatar. | ||
*/ | ||
BLANK, | ||
|
||
/** | ||
* Same as {@link #BLANK}. | ||
*/ | ||
DEFAULT, | ||
|
||
/** | ||
* The user's avatar. | ||
*/ | ||
USER, | ||
|
||
/** | ||
* The Gravatar logo. | ||
*/ | ||
GRAVATAR; | ||
|
||
/** | ||
* Returns the URL parameter for this image type. | ||
* | ||
* @param isFirstUrlParameter whether this is the first url parameter | ||
* @return the URL parameter for this image type | ||
*/ | ||
public String getAsUrlParameter(boolean isFirstUrlParameter) { | ||
String firstChar = isFirstUrlParameter ? "?" : "&"; | ||
return firstChar + "type=" + this.toString().toLowerCase(); | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/com/github/natche/gravatarjavaclient/enums/GravatarQrImageVersion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package com.github.natche.gravatarjavaclient.enums; | ||
|
||
/** | ||
* The QR code version of the image returned. | ||
*/ | ||
public enum GravatarQrImageVersion { | ||
/** | ||
* A standard QR code. | ||
*/ | ||
BLANK("blank"), | ||
|
||
/** | ||
* The same as {@link #BLANK}. | ||
*/ | ||
ONE("1"), | ||
|
||
/** | ||
* Modern "small dots" QR code. | ||
*/ | ||
THREE("3"); | ||
|
||
private final String urlParameter; | ||
|
||
GravatarQrImageVersion(String urlParameter) { | ||
this.urlParameter = urlParameter; | ||
} | ||
|
||
/** | ||
* Returns the URL parameter for this image version. | ||
* | ||
* @param isFirstUrlParameter whether this is the first url parameter | ||
* @return the URL parameter for this image version | ||
*/ | ||
public String getAsUrlParameter(boolean isFirstUrlParameter) { | ||
String firstChar = isFirstUrlParameter ? "?" : "&"; | ||
return firstChar + "version=" + this.urlParameter; | ||
} | ||
} |
Oops, something went wrong.