aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRenaud Allard <renaud@allard.it>2016-10-20 08:31:57 +0200
committerRenaud Allard <renaud@allard.it>2016-10-20 08:31:57 +0200
commit1104c2738e19579c5865db5c030388e1e320f0b4 (patch)
treea6571455b6f5d88581c8034bd1059968d506ed01 /src
parent0d347cd7aac2ebfad01c1635f3893964be2e67ae (diff)
parent4f7356cc1c6962f46ca522246d5b63dc06a2d268 (diff)
downloadtraccar-server-1104c2738e19579c5865db5c030388e1e320f0b4.tar.gz
traccar-server-1104c2738e19579c5865db5c030388e1e320f0b4.tar.bz2
traccar-server-1104c2738e19579c5865db5c030388e1e320f0b4.zip
Merge branch 'master' of https://github.com/tananaev/traccar
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/api/resource/EventResource.java13
-rw-r--r--src/org/traccar/api/resource/PositionResource.java24
-rw-r--r--src/org/traccar/api/resource/ReportResource.java70
-rw-r--r--src/org/traccar/database/DataManager.java11
-rw-r--r--src/org/traccar/model/Event.java2
-rw-r--r--src/org/traccar/model/User.java5
-rw-r--r--src/org/traccar/protocol/H02FrameDecoder.java16
-rw-r--r--src/org/traccar/protocol/H02Protocol.java2
-rw-r--r--src/org/traccar/protocol/RuptelaProtocolDecoder.java32
-rw-r--r--src/org/traccar/reports/Events.java95
-rw-r--r--src/org/traccar/reports/Route.java60
-rw-r--r--src/org/traccar/reports/Summary.java29
-rw-r--r--src/org/traccar/reports/Trips.java66
-rw-r--r--src/org/traccar/reports/model/DeviceReport.java49
-rw-r--r--src/org/traccar/reports/model/TripReport.java48
15 files changed, 420 insertions, 102 deletions
diff --git a/src/org/traccar/api/resource/EventResource.java b/src/org/traccar/api/resource/EventResource.java
index 74a748ea5..c0a8f968d 100644
--- a/src/org/traccar/api/resource/EventResource.java
+++ b/src/org/traccar/api/resource/EventResource.java
@@ -1,14 +1,12 @@
package org.traccar.api.resource;
import java.sql.SQLException;
-import java.util.Collection;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.traccar.Context;
@@ -26,14 +24,9 @@ public class EventResource extends BaseResource {
public Event get(@PathParam("id") long id) throws SQLException {
Event event = Context.getDataManager().getEvent(id);
Context.getPermissionsManager().checkDevice(getUserId(), event.getDeviceId());
+ if (event.getGeofenceId() != 0) {
+ Context.getPermissionsManager().checkGeofence(getUserId(), event.getGeofenceId());
+ }
return event;
}
-
- @GET
- public Collection<Event> get(
- @QueryParam("deviceId") long deviceId, @QueryParam("type") String type,
- @QueryParam("interval") int interval) throws SQLException {
- Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
- return Context.getDataManager().getLastEvents(deviceId, type, interval);
- }
}
diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java
index e00e06e7a..92b62c0a6 100644
--- a/src/org/traccar/api/resource/PositionResource.java
+++ b/src/org/traccar/api/resource/PositionResource.java
@@ -18,6 +18,7 @@ package org.traccar.api.resource;
import org.traccar.Context;
import org.traccar.api.BaseResource;
import org.traccar.model.Position;
+import org.traccar.web.CsvBuilder;
import org.traccar.web.JsonConverter;
import javax.ws.rs.Consumes;
@@ -25,17 +26,23 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
import java.sql.SQLException;
import java.util.Collection;
@Path("positions")
-@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PositionResource extends BaseResource {
+ public static final String TEXT_CSV = "text/csv";
+ public static final String CONTENT_DISPOSITION_VALUE_CSV = "attachment; filename=positions.csv";
+
@GET
- public Collection<Position> get(
+ @Produces(MediaType.APPLICATION_JSON)
+ public Collection<Position> getJson(
@QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to)
throws SQLException {
if (deviceId == 0) {
@@ -47,4 +54,17 @@ public class PositionResource extends BaseResource {
}
}
+ @GET
+ @Produces(TEXT_CSV)
+ public Response getCsv(
+ @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to)
+ throws SQLException {
+ Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
+ CsvBuilder csv = new CsvBuilder();
+ csv.addHeaderLine(new Position());
+ csv.addArray(Context.getDataManager().getPositions(
+ deviceId, JsonConverter.parseDate(from), JsonConverter.parseDate(to)));
+ return Response.ok(csv.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_CSV).build();
+ }
+
}
diff --git a/src/org/traccar/api/resource/ReportResource.java b/src/org/traccar/api/resource/ReportResource.java
index 0dd0452ff..709eef377 100644
--- a/src/org/traccar/api/resource/ReportResource.java
+++ b/src/org/traccar/api/resource/ReportResource.java
@@ -1,5 +1,7 @@
package org.traccar.api.resource;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
@@ -23,8 +25,8 @@ import org.traccar.web.JsonConverter;
@Consumes(MediaType.APPLICATION_JSON)
public class ReportResource extends BaseResource {
- public static final String TEXT_CSV = "text/csv";
- public static final String CONTENT_DISPOSITION_VALUE = "attachment; filename=report.csv";
+ private static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
+ private static final String CONTENT_DISPOSITION_VALUE_XLSX = "attachment; filename=report.xlsx";
@Path("route")
@GET
@@ -38,14 +40,16 @@ public class ReportResource extends BaseResource {
@Path("route")
@GET
- @Produces(TEXT_CSV)
- public Response getRouteCsv(
+ @Produces(XLSX)
+ public Response getRouteExcel(
@QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds,
- @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException {
- return Response.ok(Route.getCsv(getUserId(), deviceIds, groupIds,
- JsonConverter.parseDate(from), JsonConverter.parseDate(to)))
- .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE)
- .build();
+ @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Route.getExcel(stream, getUserId(), deviceIds, groupIds,
+ JsonConverter.parseDate(from), JsonConverter.parseDate(to));
+
+ return Response.ok(stream.toByteArray())
+ .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build();
}
@Path("events")
@@ -61,15 +65,17 @@ public class ReportResource extends BaseResource {
@Path("events")
@GET
- @Produces(TEXT_CSV)
- public Response getEventsCsv(
+ @Produces(XLSX)
+ public Response getEventsExcel(
@QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds,
@QueryParam("type") final List<String> types,
- @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException {
- return Response.ok(Events.getCsv(getUserId(), deviceIds, groupIds,
- types, JsonConverter.parseDate(from), JsonConverter.parseDate(to)))
- .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE)
- .build();
+ @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Events.getExcel(stream, getUserId(), deviceIds, groupIds, types,
+ JsonConverter.parseDate(from), JsonConverter.parseDate(to));
+
+ return Response.ok(stream.toByteArray())
+ .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build();
}
@Path("summary")
@@ -84,14 +90,16 @@ public class ReportResource extends BaseResource {
@Path("summary")
@GET
- @Produces(TEXT_CSV)
- public Response getSummaryCsv(
+ @Produces(XLSX)
+ public Response getSummaryExcel(
@QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds,
- @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException {
- return Response.ok(Summary.getCsv(getUserId(), deviceIds, groupIds,
- JsonConverter.parseDate(from), JsonConverter.parseDate(to)))
- .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE)
- .build();
+ @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Summary.getExcel(stream, getUserId(), deviceIds, groupIds,
+ JsonConverter.parseDate(from), JsonConverter.parseDate(to));
+
+ return Response.ok(stream.toByteArray())
+ .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build();
}
@Path("trips")
@@ -106,14 +114,16 @@ public class ReportResource extends BaseResource {
@Path("trips")
@GET
- @Produces(TEXT_CSV)
- public Response getTripsCsv(
+ @Produces(XLSX)
+ public Response getTripsExcel(
@QueryParam("deviceId") final List<Long> deviceIds, @QueryParam("groupId") final List<Long> groupIds,
- @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException {
- return Response.ok(Trips.getCsv(getUserId(), deviceIds, groupIds,
- JsonConverter.parseDate(from), JsonConverter.parseDate(to)))
- .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE)
- .build();
+ @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException {
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ Trips.getExcel(stream, getUserId(), deviceIds, groupIds,
+ JsonConverter.parseDate(from), JsonConverter.parseDate(to));
+
+ return Response.ok(stream.toByteArray())
+ .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build();
}
}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 58d16d7f5..e98e1429c 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -20,7 +20,6 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.SQLException;
-import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
@@ -332,22 +331,14 @@ public class DataManager {
.executeUpdate());
}
- public Collection<Event> getEvents(long deviceId, String type, Date from, Date to) throws SQLException {
+ public Collection<Event> getEvents(long deviceId, Date from, Date to) throws SQLException {
return QueryBuilder.create(dataSource, getQuery("database.selectEvents"))
.setLong("deviceId", deviceId)
- .setString("type", type)
.setDate("from", from)
.setDate("to", to)
.executeQuery(Event.class);
}
- public Collection<Event> getLastEvents(long deviceId, String type, int interval) throws SQLException {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.SECOND, -interval);
- Date from = calendar.getTime();
- return getEvents(deviceId, type, from, new Date());
- }
-
public Collection<Geofence> getGeofences() throws SQLException {
return QueryBuilder.create(dataSource, getQuery("database.selectGeofencesAll"))
.executeQuery(Geofence.class);
diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java
index c3c8b5320..5b4b0e089 100644
--- a/src/org/traccar/model/Event.java
+++ b/src/org/traccar/model/Event.java
@@ -35,6 +35,8 @@ public class Event extends Message {
public Event() {
}
+ public static final String ALL_EVENTS = "allEvents";
+
public static final String TYPE_COMMAND_RESULT = "commandResult";
public static final String TYPE_DEVICE_ONLINE = "deviceOnline";
diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java
index 59951718e..860c91629 100644
--- a/src/org/traccar/model/User.java
+++ b/src/org/traccar/model/User.java
@@ -140,14 +140,11 @@ public class User extends Extensible {
this.coordinateFormat = coordinateFormat;
}
- private String password;
-
public String getPassword() {
- return password;
+ return null;
}
public void setPassword(String password) {
- this.password = password;
if (password != null && !password.isEmpty()) {
Hashing.HashingResult hashingResult = Hashing.createHash(password);
hashedPassword = hashingResult.getHash();
diff --git a/src/org/traccar/protocol/H02FrameDecoder.java b/src/org/traccar/protocol/H02FrameDecoder.java
index feba8033d..2a005e760 100644
--- a/src/org/traccar/protocol/H02FrameDecoder.java
+++ b/src/org/traccar/protocol/H02FrameDecoder.java
@@ -22,6 +22,9 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder;
public class H02FrameDecoder extends FrameDecoder {
+ private static final int MESSAGE_SHORT = 32;
+ private static final int MESSAGE_LONG = 45;
+
private int messageLength;
public H02FrameDecoder(int messageLength) {
@@ -49,10 +52,17 @@ public class H02FrameDecoder extends FrameDecoder {
return buf.readBytes(index + 1 - buf.readerIndex());
}
- } else if (marker == '$' && buf.readableBytes() >= messageLength) {
+ } else if (marker == '$') {
- // Return binary message
- return buf.readBytes(messageLength);
+ if (messageLength > 0 && buf.readableBytes() >= messageLength) {
+ return buf.readBytes(messageLength);
+ } else if (buf.readableBytes() >= MESSAGE_SHORT) {
+ if (buf.getUnsignedByte(buf.readerIndex() + MESSAGE_SHORT - 1) == 0) {
+ return buf.readBytes(MESSAGE_SHORT);
+ } else if (buf.readableBytes() >= MESSAGE_LONG) {
+ return buf.readBytes(MESSAGE_LONG);
+ }
+ }
}
diff --git a/src/org/traccar/protocol/H02Protocol.java b/src/org/traccar/protocol/H02Protocol.java
index 06ac2a6fa..089721aed 100644
--- a/src/org/traccar/protocol/H02Protocol.java
+++ b/src/org/traccar/protocol/H02Protocol.java
@@ -43,7 +43,7 @@ public class H02Protocol extends BaseProtocol {
serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
- int messageLength = Context.getConfig().getInteger(getName() + ".messageLength", 32);
+ int messageLength = Context.getConfig().getInteger(getName() + ".messageLength");
pipeline.addLast("frameDecoder", new H02FrameDecoder(messageLength));
pipeline.addLast("stringEncoder", new StringEncoder());
pipeline.addLast("objectEncoder", new H02ProtocolEncoder());
diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java
index 224c027f3..84cc0e101 100644
--- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java
+++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2014 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2013 - 2016 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
}
public static final int MSG_RECORDS = 1;
+ public static final int MSG_EXTENDED_RECORDS = 68;
public static final int MSG_SMS_VIA_GPRS = 108;
@Override
@@ -53,7 +54,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
int type = buf.readUnsignedByte();
- if (type == MSG_RECORDS) {
+ if (type == MSG_RECORDS || type == MSG_EXTENDED_RECORDS) {
List<Position> positions = new LinkedList<>();
buf.readUnsignedByte(); // records left
@@ -67,45 +68,56 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder {
position.setTime(new Date(buf.readUnsignedInt() * 1000));
buf.readUnsignedByte(); // timestamp extension
+ if (type == MSG_EXTENDED_RECORDS) {
+ buf.readUnsignedByte(); // record extension
+ }
+
buf.readUnsignedByte(); // priority (reserved)
+ position.setValid(true);
position.setLongitude(buf.readInt() / 10000000.0);
position.setLatitude(buf.readInt() / 10000000.0);
position.setAltitude(buf.readUnsignedShort() / 10.0);
position.setCourse(buf.readUnsignedShort() / 100.0);
- int satellites = buf.readUnsignedByte();
- position.set(Position.KEY_SATELLITES, satellites);
- position.setValid(satellites >= 3);
+ position.set(Position.KEY_SATELLITES, buf.readUnsignedByte());
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
position.set(Position.KEY_HDOP, buf.readUnsignedByte() / 10.0);
- buf.readUnsignedByte();
+ if (type == MSG_EXTENDED_RECORDS) {
+ buf.readUnsignedShort(); // event
+ } else {
+ buf.readUnsignedByte(); // event
+ }
// Read 1 byte data
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedByte());
+ int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedByte());
}
// Read 2 byte data
cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedShort());
+ int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedShort());
}
// Read 4 byte data
cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readUnsignedInt());
+ int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedInt());
}
// Read 8 byte data
cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- position.set(Position.PREFIX_IO + buf.readUnsignedByte(), buf.readLong());
+ int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ position.set(Position.PREFIX_IO + id, buf.readLong());
}
positions.add(position);
diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java
index ed7e9e411..77d995f56 100644
--- a/src/org/traccar/reports/Events.java
+++ b/src/org/traccar/reports/Events.java
@@ -16,16 +16,34 @@
*/
package org.traccar.reports;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
+import org.jxls.area.Area;
+import org.jxls.builder.xls.XlsCommentAreaBuilder;
+import org.jxls.common.CellRef;
+import org.jxls.formula.StandardFormulaProcessor;
+import org.jxls.transform.Transformer;
+import org.jxls.transform.poi.PoiTransformer;
+import org.jxls.util.TransformerFactory;
import org.traccar.Context;
+import org.traccar.model.Device;
import org.traccar.model.Event;
-import org.traccar.web.CsvBuilder;
+import org.traccar.model.Geofence;
+import org.traccar.model.Group;
+import org.traccar.reports.model.DeviceReport;
import org.traccar.web.JsonConverter;
public final class Events {
@@ -38,25 +56,80 @@ public final class Events {
JsonArrayBuilder json = Json.createArrayBuilder();
for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) {
Context.getPermissionsManager().checkDevice(userId, deviceId);
- for (String type : types) {
- for (Event event : Context.getDataManager().getEvents(deviceId, type, from, to)) {
- json.add(JsonConverter.objectToJson(event));
+ Collection<Event> events = Context.getDataManager().getEvents(deviceId, from, to);
+ boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS);
+ for (Event event : events) {
+ if (all || types.contains(event.getType())) {
+ long geofenceId = event.getGeofenceId();
+ if (geofenceId == 0 || Context.getGeofenceManager().checkGeofence(userId, geofenceId)) {
+ json.add(JsonConverter.objectToJson(event));
+ }
}
}
}
return json.build().toString();
}
- public static String getCsv(long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
- Collection<String> types, Date from, Date to) throws SQLException {
- CsvBuilder csv = new CsvBuilder();
- csv.addHeaderLine(new Event());
+ public static void getExcel(OutputStream outputStream,
+ long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
+ Collection<String> types, Date from, Date to) throws SQLException, IOException {
+ ArrayList<DeviceReport> devicesEvents = new ArrayList<>();
+ ArrayList<String> sheetNames = new ArrayList<>();
+ HashMap<Long, String> geofenceNames = new HashMap<>();
for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) {
Context.getPermissionsManager().checkDevice(userId, deviceId);
- for (String type : types) {
- csv.addArray(Context.getDataManager().getEvents(deviceId, type, from, to));
+ Collection<Event> events = Context.getDataManager().getEvents(deviceId, from, to);
+ boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS);
+ for (Iterator<Event> iterator = events.iterator(); iterator.hasNext();) {
+ Event event = iterator.next();
+ if (all || types.contains(event.getType())) {
+ long geofenceId = event.getGeofenceId();
+ if (geofenceId != 0) {
+ if (Context.getGeofenceManager().checkGeofence(userId, geofenceId)) {
+ Geofence geofence = Context.getGeofenceManager().getGeofence(geofenceId);
+ if (geofence != null) {
+ geofenceNames.put(geofenceId, geofence.getName());
+ }
+ } else {
+ iterator.remove();
+ }
+ }
+ } else {
+ iterator.remove();
+ }
+ }
+ DeviceReport deviceEvents = new DeviceReport();
+ Device device = Context.getIdentityManager().getDeviceById(deviceId);
+ deviceEvents.setDeviceName(device.getName());
+ sheetNames.add(deviceEvents.getDeviceName());
+ if (device.getGroupId() != 0) {
+ Group group = Context.getDeviceManager().getGroupById(device.getGroupId());
+ if (group != null) {
+ deviceEvents.setGroupName(group.getName());
+ }
+ }
+ deviceEvents.setObjects(events);
+ devicesEvents.add(deviceEvents);
+ }
+ String templatePath = Context.getConfig().getString("report.templatesPath",
+ "templates/export/");
+ try (InputStream inputStream = new FileInputStream(templatePath + "/events.xlsx")) {
+ org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext();
+ jxlsContext.putVar("devices", devicesEvents);
+ jxlsContext.putVar("sheetNames", sheetNames);
+ jxlsContext.putVar("geofenceNames", geofenceNames);
+ jxlsContext.putVar("from", from);
+ jxlsContext.putVar("to", to);
+ jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]");
+ Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream);
+ List<Area> xlsAreas = new XlsCommentAreaBuilder(transformer).build();
+ for (Area xlsArea : xlsAreas) {
+ xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext);
+ xlsArea.setFormulaProcessor(new StandardFormulaProcessor());
+ xlsArea.processFormulas();
}
+ transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName());
+ transformer.write();
}
- return csv.build();
}
}
diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java
index 45b81cd8c..6992c89cc 100644
--- a/src/org/traccar/reports/Route.java
+++ b/src/org/traccar/reports/Route.java
@@ -16,16 +16,31 @@
*/
package org.traccar.reports;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
+import org.jxls.area.Area;
+import org.jxls.builder.xls.XlsCommentAreaBuilder;
+import org.jxls.common.CellRef;
+import org.jxls.formula.StandardFormulaProcessor;
+import org.jxls.transform.Transformer;
+import org.jxls.transform.poi.PoiTransformer;
+import org.jxls.util.TransformerFactory;
import org.traccar.Context;
+import org.traccar.model.Device;
+import org.traccar.model.Group;
import org.traccar.model.Position;
-import org.traccar.web.CsvBuilder;
+import org.traccar.reports.model.DeviceReport;
import org.traccar.web.JsonConverter;
public final class Route {
@@ -45,14 +60,45 @@ public final class Route {
return json.build().toString();
}
- public static String getCsv(long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
- Date from, Date to) throws SQLException {
- CsvBuilder csv = new CsvBuilder();
- csv.addHeaderLine(new Position());
+ public static void getExcel(OutputStream outputStream,
+ long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
+ Date from, Date to) throws SQLException, IOException {
+ ArrayList<DeviceReport> devicesRoutes = new ArrayList<>();
+ ArrayList<String> sheetNames = new ArrayList<>();
for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) {
Context.getPermissionsManager().checkDevice(userId, deviceId);
- csv.addArray(Context.getDataManager().getPositions(deviceId, from, to));
+ Collection<Position> positions = Context.getDataManager().getPositions(deviceId, from, to);
+ DeviceReport deviceRoutes = new DeviceReport();
+ Device device = Context.getIdentityManager().getDeviceById(deviceId);
+ deviceRoutes.setDeviceName(device.getName());
+ sheetNames.add(deviceRoutes.getDeviceName());
+ if (device.getGroupId() != 0) {
+ Group group = Context.getDeviceManager().getGroupById(device.getGroupId());
+ if (group != null) {
+ deviceRoutes.setGroupName(group.getName());
+ }
+ }
+ deviceRoutes.setObjects(positions);
+ devicesRoutes.add(deviceRoutes);
+ }
+ String templatePath = Context.getConfig().getString("report.templatesPath",
+ "templates/export/");
+ try (InputStream inputStream = new FileInputStream(templatePath + "/route.xlsx")) {
+ org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext();
+ jxlsContext.putVar("devices", devicesRoutes);
+ jxlsContext.putVar("sheetNames", sheetNames);
+ jxlsContext.putVar("from", from);
+ jxlsContext.putVar("to", to);
+ jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]");
+ Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream);
+ List<Area> xlsAreas = new XlsCommentAreaBuilder(transformer).build();
+ for (Area xlsArea : xlsAreas) {
+ xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext);
+ xlsArea.setFormulaProcessor(new StandardFormulaProcessor());
+ xlsArea.processFormulas();
+ }
+ transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName());
+ transformer.write();
}
- return csv.build();
}
}
diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java
index d4171f644..14f8b7839 100644
--- a/src/org/traccar/reports/Summary.java
+++ b/src/org/traccar/reports/Summary.java
@@ -16,17 +16,23 @@
*/
package org.traccar.reports;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
+import org.jxls.transform.poi.PoiTransformer;
+import org.jxls.util.JxlsHelper;
import org.traccar.Context;
import org.traccar.model.Position;
import org.traccar.reports.model.SummaryReport;
-import org.traccar.web.CsvBuilder;
import org.traccar.web.JsonConverter;
public final class Summary {
@@ -78,14 +84,23 @@ public final class Summary {
return json.build().toString();
}
- public static String getCsv(long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
- Date from, Date to) throws SQLException {
- CsvBuilder csv = new CsvBuilder();
- csv.addHeaderLine(new SummaryReport());
+ public static void getExcel(OutputStream outputStream,
+ long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
+ Date from, Date to) throws SQLException, IOException {
+ ArrayList<SummaryReport> summaries = new ArrayList<>();
for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) {
Context.getPermissionsManager().checkDevice(userId, deviceId);
- csv.addLine(calculateSummaryResult(deviceId, from, to));
+ summaries.add(calculateSummaryResult(deviceId, from, to));
+ }
+ String templatePath = Context.getConfig().getString("report.templatesPath",
+ "templates/export/");
+ try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) {
+ org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext();
+ jxlsContext.putVar("summaries", summaries);
+ jxlsContext.putVar("from", from);
+ jxlsContext.putVar("to", to);
+ JxlsHelper.getInstance().setUseFastFormulaProcessor(false)
+ .processTemplate(inputStream, outputStream, jxlsContext);
}
- return csv.build();
}
}
diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java
index f0a10edbd..705644849 100644
--- a/src/org/traccar/reports/Trips.java
+++ b/src/org/traccar/reports/Trips.java
@@ -16,18 +16,32 @@
*/
package org.traccar.reports;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import java.util.List;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
+import org.jxls.area.Area;
+import org.jxls.builder.xls.XlsCommentAreaBuilder;
+import org.jxls.common.CellRef;
+import org.jxls.formula.StandardFormulaProcessor;
+import org.jxls.transform.Transformer;
+import org.jxls.transform.poi.PoiTransformer;
+import org.jxls.util.TransformerFactory;
import org.traccar.Context;
+import org.traccar.model.Device;
+import org.traccar.model.Group;
import org.traccar.model.Position;
+import org.traccar.reports.model.DeviceReport;
import org.traccar.reports.model.TripReport;
-import org.traccar.web.CsvBuilder;
import org.traccar.web.JsonConverter;
public final class Trips {
@@ -50,16 +64,24 @@ public final class Trips {
}
TripReport trip = new TripReport();
+
long tripDuration = endTrip.getFixTime().getTime() - positions.get(startIndex).getFixTime().getTime();
long deviceId = startTrip.getDeviceId();
trip.setDeviceId(deviceId);
trip.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName());
+
trip.setStartPositionId(startTrip.getId());
+ trip.setStartLat(startTrip.getLatitude());
+ trip.setStartLon(startTrip.getLongitude());
trip.setStartTime(startTrip.getFixTime());
trip.setStartAddress(startTrip.getAddress());
+
trip.setEndPositionId(endTrip.getId());
+ trip.setEndLat(endTrip.getLatitude());
+ trip.setEndLon(endTrip.getLongitude());
trip.setEndTime(endTrip.getFixTime());
trip.setEndAddress(endTrip.getAddress());
+
boolean ignoreOdometer = Context.getDeviceManager()
.lookupConfigBoolean(deviceId, "report.ignoreOdometer", false);
trip.setDistance(ReportUtils.calculateDistance(startTrip, endTrip, !ignoreOdometer));
@@ -157,14 +179,44 @@ public final class Trips {
return json.build().toString();
}
- public static String getCsv(long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
- Date from, Date to) throws SQLException {
- CsvBuilder csv = new CsvBuilder();
- csv.addHeaderLine(new TripReport());
+ public static void getExcel(OutputStream outputStream,
+ long userId, Collection<Long> deviceIds, Collection<Long> groupIds,
+ Date from, Date to) throws SQLException, IOException {
+ ArrayList<DeviceReport> devicesTrips = new ArrayList<>();
+ ArrayList<String> sheetNames = new ArrayList<>();
for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) {
Context.getPermissionsManager().checkDevice(userId, deviceId);
- csv.addArray(detectTrips(deviceId, from, to));
+ Collection<TripReport> trips = detectTrips(deviceId, from, to);
+ DeviceReport deviceTrips = new DeviceReport();
+ Device device = Context.getIdentityManager().getDeviceById(deviceId);
+ deviceTrips.setDeviceName(device.getName());
+ sheetNames.add(deviceTrips.getDeviceName());
+ if (device.getGroupId() != 0) {
+ Group group = Context.getDeviceManager().getGroupById(device.getGroupId());
+ if (group != null) {
+ deviceTrips.setGroupName(group.getName());
+ }
+ }
+ deviceTrips.setObjects(trips);
+ devicesTrips.add(deviceTrips);
+ }
+ String templatePath = Context.getConfig().getString("report.templatesPath",
+ "templates/export/");
+ try (InputStream inputStream = new FileInputStream(templatePath + "/trips.xlsx")) {
+ org.jxls.common.Context jxlsContext = PoiTransformer.createInitialContext();
+ jxlsContext.putVar("devices", devicesTrips);
+ jxlsContext.putVar("sheetNames", sheetNames);
+ jxlsContext.putVar("from", from);
+ jxlsContext.putVar("to", to);
+ Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream);
+ List<Area> xlsAreas = new XlsCommentAreaBuilder(transformer).build();
+ for (Area xlsArea : xlsAreas) {
+ xlsArea.applyAt(new CellRef(xlsArea.getStartCellRef().getCellName()), jxlsContext);
+ xlsArea.setFormulaProcessor(new StandardFormulaProcessor());
+ xlsArea.processFormulas();
+ }
+ transformer.deleteSheet(xlsAreas.get(0).getStartCellRef().getSheetName());
+ transformer.write();
}
- return csv.build();
}
}
diff --git a/src/org/traccar/reports/model/DeviceReport.java b/src/org/traccar/reports/model/DeviceReport.java
new file mode 100644
index 000000000..c072de231
--- /dev/null
+++ b/src/org/traccar/reports/model/DeviceReport.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2016 Andrey Kunitsyn (abyss@fox5.ru)
+ *
+ * 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 org.traccar.reports.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class DeviceReport {
+
+ private String deviceName;
+ public String getDeviceName() {
+ return deviceName;
+ }
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
+ }
+
+ private String groupName = "";
+ public String getGroupName() {
+ return groupName;
+ }
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ private List<?> objects;
+ public Collection<?> getObjects() {
+ return objects;
+ }
+ public void setObjects(Collection<?> objects) {
+ this.objects = new ArrayList<>(objects);
+ }
+
+}
diff --git a/src/org/traccar/reports/model/TripReport.java b/src/org/traccar/reports/model/TripReport.java
index 3a77b02ca..d726195cb 100644
--- a/src/org/traccar/reports/model/TripReport.java
+++ b/src/org/traccar/reports/model/TripReport.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton.tananaev@gmail.com)
+ * Copyright 2016 Andrey Kunitsyn (abyss@fox5.ru)
+ *
+ * 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 org.traccar.reports.model;
import java.util.Date;
@@ -20,6 +36,38 @@ public class TripReport extends BaseReport {
this.endPositionId = endPositionId;
}
+ private double startLat;
+ public double getStartLat() {
+ return startLat;
+ }
+ public void setStartLat(double startLat) {
+ this.startLat = startLat;
+ }
+
+ private double startLon;
+ public double getStartLon() {
+ return startLon;
+ }
+ public void setStartLon(double startLon) {
+ this.startLon = startLon;
+ }
+
+ private double endLat;
+ public double getEndLat() {
+ return endLat;
+ }
+ public void setEndLat(double endLat) {
+ this.endLat = endLat;
+ }
+
+ private double endLon;
+ public double getEndLon() {
+ return endLon;
+ }
+ public void setEndLon(double endLon) {
+ this.endLon = endLon;
+ }
+
private Date startTime;
public Date getStartTime() {
if (startTime != null) {