Skip to content

Commit e8e7e8b

Browse files
committed
#236 qr code generation for cloning via HTTP API
1 parent 3443568 commit e8e7e8b

File tree

9 files changed

+90
-19
lines changed

9 files changed

+90
-19
lines changed

integration-tests/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<dependency>
7070
<groupId>com.github.kenglxn.qrgen</groupId>
7171
<artifactId>javase</artifactId>
72-
<version>2.1.0</version>
72+
<version>${qrgen.version}</version>
7373
<scope>test</scope>
7474
</dependency>
7575
</dependencies>

pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
<commons-validator.version>1.5.0</commons-validator.version>
103103
<postgresql.version>9.4.1208</postgresql.version>
104104
<HikariCP.version>2.4.7</HikariCP.version>
105+
<qrgen.version>2.1.0</qrgen.version>
105106

106107
<!-- test versions -->
107108
<commons-lang3.version>3.4</commons-lang3.version>

server/core/src/main/java/cc/blynk/server/core/protocol/enums/Command.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ public final class Command {
7070
public static final short HTTP_NOTIFY = 46;
7171
public static final short HTTP_EMAIL = 47;
7272
public static final short HTTP_GET_PROJECT = 48;
73-
public static final short HTTP_TOTAL = 49;
73+
public static final short HTTP_QR = 49;
74+
public static final short HTTP_TOTAL = 50;
7475

7576

7677
//all this code just to make logging more user-friendly

server/core/src/main/java/cc/blynk/server/core/stats/GlobalStats.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
public class GlobalStats {
1111

12-
private static final int LAST_COMMAND_INDEX = 50;
12+
private static final int LAST_COMMAND_INDEX = 51;
1313
public final Meter incomeMessages;
1414
public final LongAdder[] specificCounters;
1515

server/http-api/pom.xml

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
<version>${project.version}</version>
2424
</dependency>
2525

26-
2726
<dependency>
2827
<groupId>commons-validator</groupId>
2928
<artifactId>commons-validator</artifactId>
3029
<version>${commons-validator.version}</version>
3130
</dependency>
3231

32+
<dependency>
33+
<groupId>com.github.kenglxn.qrgen</groupId>
34+
<artifactId>javase</artifactId>
35+
<version>${qrgen.version}</version>
36+
</dependency>
37+
3338
</dependencies>
3439

3540
</project>

server/http-api/src/main/java/cc/blynk/server/api/http/logic/HttpAPILogic.java

+38
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,17 @@
2525
import cc.blynk.server.notifications.push.GCMWrapper;
2626
import cc.blynk.server.notifications.push.android.AndroidGCMMessage;
2727
import cc.blynk.server.notifications.push.ios.IOSGCMMessage;
28+
import cc.blynk.utils.ByteUtils;
2829
import cc.blynk.utils.StringUtils;
30+
import net.glxn.qrgen.core.image.ImageType;
31+
import net.glxn.qrgen.javase.QRCode;
2932
import org.apache.logging.log4j.LogManager;
3033
import org.apache.logging.log4j.Logger;
3134

3235
import javax.ws.rs.*;
3336
import javax.ws.rs.core.MediaType;
37+
import java.io.IOException;
38+
import java.util.Base64;
3439

3540
import static cc.blynk.core.http.Response.*;
3641
import static cc.blynk.server.core.protocol.enums.Command.*;
@@ -186,6 +191,39 @@ public Response getWidgetPinData(@PathParam("token") String token,
186191
return ok(widget.getJsonValue());
187192
}
188193

194+
@GET
195+
@Path("{token}/qr")
196+
//todo cover with test
197+
public Response updateWidgetPinData(@PathParam("token") String token) {
198+
globalStats.mark(HTTP_QR);
199+
200+
User user = userDao.tokenManager.getUserByToken(token);
201+
202+
if (user == null) {
203+
log.error("Requested token {} not found.", token);
204+
return Response.badRequest("Invalid token.");
205+
}
206+
207+
Integer dashId = user.getDashIdByToken(token);
208+
209+
if (dashId == null) {
210+
log.error("Dash id for token {} not found. User {}", token, user.name);
211+
return Response.badRequest("Didn't find dash id for token.");
212+
}
213+
214+
DashBoard dashBoard = user.profile.getDashById(dashId);
215+
216+
try {
217+
byte[] compressed = ByteUtils.compress(dashBoard.toString());
218+
String qrData = "bp1" + Base64.getEncoder().encodeToString(compressed);
219+
byte[] qrDataBinary = QRCode.from(qrData).to(ImageType.PNG).withSize(500, 500).stream().toByteArray();
220+
return ok(qrDataBinary, "image/png");
221+
} catch (IOException ioe) {
222+
log.error("Error generating QR.", ioe);
223+
return Response.badRequest("Error generating QR.");
224+
}
225+
}
226+
189227
@PUT
190228
@Path("{token}/pin/{pin}")
191229
@Consumes(value = MediaType.APPLICATION_JSON)

server/http-core/src/main/java/cc/blynk/core/http/Response.java

+12
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ public Response(HttpVersion version, HttpResponseStatus status, String content,
3636
headers().set(CONTENT_LENGTH, content().readableBytes());
3737
}
3838

39+
public Response(HttpVersion version, HttpResponseStatus status, byte[] content, String contentType) {
40+
super(version, status, (content == null ? Unpooled.EMPTY_BUFFER : Unpooled.copiedBuffer(content)));
41+
headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
42+
headers().set(CONTENT_TYPE, contentType);
43+
headers().set(CONTENT_LENGTH, content().readableBytes());
44+
}
45+
3946
public Response(HttpVersion version, HttpResponseStatus status) {
4047
super(version, status);
4148
headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
@@ -85,6 +92,11 @@ public static Response ok(String data, String contentType) {
8592
return new Response(HTTP_1_1, OK, data, contentType);
8693
}
8794

95+
public static Response ok(byte[] data, String contentType) {
96+
return new Response(HTTP_1_1, OK, data, contentType);
97+
}
98+
99+
88100
public static Response ok(boolean bool) {
89101
return new Response(HTTP_1_1, OK, String.valueOf(bool), JSON);
90102
}

server/http-core/src/main/java/cc/blynk/core/http/handlers/StaticFileHandler.java

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cc.blynk.core.http.handlers;
22

3+
import cc.blynk.utils.ContentTypeUtil;
34
import cc.blynk.utils.ServerProperties;
45
import io.netty.buffer.Unpooled;
56
import io.netty.channel.*;
@@ -106,20 +107,6 @@ private static void setDateAndCacheHeaders(io.netty.handler.codec.http.HttpRespo
106107
LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified())));
107108
}
108109

109-
private static String getContentType(String fileName) {
110-
if (fileName.endsWith(".ico")) {
111-
return "image/x-icon";
112-
}
113-
if (fileName.endsWith(".js")) {
114-
return "application/javascript";
115-
}
116-
if (fileName.endsWith(".css")) {
117-
return "text/css";
118-
}
119-
120-
return "text/html";
121-
}
122-
123110
@Override
124111
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
125112
if (!(msg instanceof FullHttpRequest)) {
@@ -211,7 +198,7 @@ private void serveStatic(ChannelHandlerContext ctx, FullHttpRequest request) thr
211198
HttpHeaders.setContentLength(response, fileLength);
212199

213200
//setting content type
214-
response.headers().set(CONTENT_TYPE, getContentType(file.getName()));
201+
response.headers().set(CONTENT_TYPE, ContentTypeUtil.getContentType(file.getName()));
215202

216203
setDateAndCacheHeaders(response, file);
217204
if (HttpHeaders.isKeepAlive(request)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package cc.blynk.utils;
2+
3+
/**
4+
* The Blynk Project.
5+
* Created by Dmitriy Dumanskiy.
6+
* Created on 07.07.16.
7+
*/
8+
public class ContentTypeUtil {
9+
10+
public static String getContentType(String fileName) {
11+
if (fileName.endsWith(".ico")) {
12+
return "image/x-icon";
13+
}
14+
if (fileName.endsWith(".js")) {
15+
return "application/javascript";
16+
}
17+
if (fileName.endsWith(".css")) {
18+
return "text/css";
19+
}
20+
if (fileName.endsWith(".png")) {
21+
return "image/png";
22+
}
23+
24+
return "text/html";
25+
}
26+
27+
}

0 commit comments

Comments
 (0)