From dc5f2151d9e74f525d74663d599320b8cf3d9c47 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 31 May 2017 22:30:45 +1200 Subject: Implement image saving --- src/org/traccar/database/MediaManager.java | 37 +++++++++++++++++++ src/org/traccar/model/Position.java | 3 ++ src/org/traccar/protocol/WatchProtocolDecoder.java | 41 ++++++++++++++++------ 3 files changed, 70 insertions(+), 11 deletions(-) (limited to 'src/org') diff --git a/src/org/traccar/database/MediaManager.java b/src/org/traccar/database/MediaManager.java index a492e1e6f..4b5930642 100644 --- a/src/org/traccar/database/MediaManager.java +++ b/src/org/traccar/database/MediaManager.java @@ -15,7 +15,20 @@ */ package org.traccar.database; +import org.jboss.netty.buffer.ChannelBuffer; import org.traccar.Config; +import org.traccar.helper.Log; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.Date; public class MediaManager { @@ -25,4 +38,28 @@ public class MediaManager { path = config.getString("media.path"); } + private File createFile(String uniqueId, String name) throws IOException { + Path filePath = Paths.get(path, uniqueId, name); + Files.createDirectories(filePath.getParent()); + return filePath.toFile(); + } + + public String writeFile(String uniqueId, ChannelBuffer buf, String extension) { + int size = buf.readableBytes(); + String name = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + "." + extension; + try (FileOutputStream output = new FileOutputStream(createFile(uniqueId, name)); + FileChannel fileChannel = output.getChannel()) { + ByteBuffer byteBuffer = buf.toByteBuffer(); + int written = 0; + while (written < size) { + written += fileChannel.write(byteBuffer); + } + fileChannel.force(false); + return name; + } catch (IOException e) { + Log.warning(e); + } + return null; + } + } diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index bfd142b7d..c6420c17b 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -37,6 +37,9 @@ public class Position extends Message { public static final String KEY_HOURS = "hours"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; + public static final String KEY_IMAGE = "image"; + public static final String KEY_VIDEO = "video"; + public static final String KEY_SOUND = "sound"; // The units for the below four KEYs currently vary. // The preferred units of measure are specified in the comment for each. diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index cfd165d06..7af856a9c 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; import org.traccar.helper.Parser; @@ -139,22 +140,25 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(4); // length buf.skipBytes(1); // delimiter - String content = null; + buf.writerIndex(buf.writerIndex() - 1); // ignore ending + int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); - if (contentIndex > 0) { - content = buf.toString(contentIndex + 1, buf.writerIndex() - 2 - contentIndex, StandardCharsets.US_ASCII); - } else { - contentIndex = buf.writerIndex() - 1; + if (contentIndex < 0) { + contentIndex = buf.writerIndex(); } String type = buf.readBytes(contentIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); + if (contentIndex < buf.writerIndex()) { + buf.readerIndex(contentIndex + 1); + } + if (type.equals("LK")) { sendResponse(channel, manufacturer, id, "LK"); - if (content != null) { - String[] values = content.split(","); + if (buf.readable()) { + String[] values = buf.toString(StandardCharsets.US_ASCII).split(","); if (values.length >= 3) { Position position = new Position(); position.setProtocol(getProtocolName()); @@ -175,7 +179,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, manufacturer, id, "AL"); } - Parser parser = new Parser(PATTERN_POSITION, content); + Parser parser = new Parser(PATTERN_POSITION, buf.toString(StandardCharsets.US_ASCII)); if (!parser.matches()) { return null; } @@ -211,17 +215,32 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (type.equals("PULSE") || type.equals("heart")) { - if (content != null) { + if (buf.readable()) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date()); position.setValid(false); - position.set("pulse", content); - position.set(Position.KEY_RESULT, content); + String pulse = buf.toString(StandardCharsets.US_ASCII); + position.set("pulse", pulse); + position.set(Position.KEY_RESULT, pulse); return position; } + } else if (type.equals("img")) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + int timeIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); + buf.readerIndex(timeIndex + 12 + 2); + position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(id, buf, "jpg")); + + return position; + } return null; -- cgit v1.2.3