aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/api/resource/PositionResource.java36
-rw-r--r--src/main/java/org/traccar/model/Position.java1
-rw-r--r--src/main/java/org/traccar/reports/CsvExportProvider.java76
-rw-r--r--src/main/java/org/traccar/reports/KmlExportProvider.java2
4 files changed, 109 insertions, 6 deletions
diff --git a/src/main/java/org/traccar/api/resource/PositionResource.java b/src/main/java/org/traccar/api/resource/PositionResource.java
index 28f8eb600..b4c8d18b9 100644
--- a/src/main/java/org/traccar/api/resource/PositionResource.java
+++ b/src/main/java/org/traccar/api/resource/PositionResource.java
@@ -20,6 +20,7 @@ import org.traccar.helper.model.PositionUtil;
import org.traccar.model.Device;
import org.traccar.model.Position;
import org.traccar.model.UserRestrictions;
+import org.traccar.reports.CsvExportProvider;
import org.traccar.reports.KmlExportProvider;
import org.traccar.storage.StorageException;
import org.traccar.storage.query.Columns;
@@ -32,10 +33,11 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.io.ByteArrayOutputStream;
+import javax.ws.rs.core.StreamingOutput;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@@ -49,6 +51,9 @@ public class PositionResource extends BaseResource {
@Inject
private KmlExportProvider kmlExportProvider;
+ @Inject
+ private CsvExportProvider csvExportProvider;
+
@GET
public Collection<Position> getJson(
@QueryParam("deviceId") long deviceId, @QueryParam("id") List<Long> positionIds,
@@ -84,10 +89,33 @@ public class PositionResource extends BaseResource {
@QueryParam("deviceId") long deviceId,
@QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException {
permissionsService.checkPermission(Device.class, getUserId(), deviceId);
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- kmlExportProvider.generateKml(stream, deviceId, from, to);
- return Response.ok(stream.toByteArray())
+ StreamingOutput stream = output -> {
+ try {
+ kmlExportProvider.generate(output, deviceId, from, to);
+ } catch (StorageException e) {
+ throw new WebApplicationException(e);
+ }
+ };
+ return Response.ok(stream)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.kml").build();
}
+ @Path("csv")
+ @GET
+ @Produces("text/csv")
+ public Response getCsv(
+ @QueryParam("deviceId") long deviceId,
+ @QueryParam("from") Date from, @QueryParam("to") Date to) throws StorageException {
+ permissionsService.checkPermission(Device.class, getUserId(), deviceId);
+ StreamingOutput stream = output -> {
+ try {
+ csvExportProvider.generate(output, deviceId, from, to);
+ } catch (StorageException e) {
+ throw new WebApplicationException(e);
+ }
+ };
+ return Response.ok(stream)
+ .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=positions.csv").build();
+ }
+
}
diff --git a/src/main/java/org/traccar/model/Position.java b/src/main/java/org/traccar/model/Position.java
index 348370e2c..d6c985458 100644
--- a/src/main/java/org/traccar/model/Position.java
+++ b/src/main/java/org/traccar/model/Position.java
@@ -150,7 +150,6 @@ public class Position extends Message {
public Position(String protocol) {
this.protocol = protocol;
- this.serverTime = new Date();
}
private String protocol;
diff --git a/src/main/java/org/traccar/reports/CsvExportProvider.java b/src/main/java/org/traccar/reports/CsvExportProvider.java
new file mode 100644
index 000000000..df55c470e
--- /dev/null
+++ b/src/main/java/org/traccar/reports/CsvExportProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 Anton Tananaev (anton@traccar.org)
+ *
+ * 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;
+
+import org.traccar.helper.DateUtil;
+import org.traccar.helper.model.PositionUtil;
+import org.traccar.model.Position;
+import org.traccar.storage.Storage;
+import org.traccar.storage.StorageException;
+
+import javax.inject.Inject;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class CsvExportProvider {
+
+ private final Storage storage;
+
+ @Inject
+ public CsvExportProvider(Storage storage) {
+ this.storage = storage;
+ }
+
+ public void generate(
+ OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException {
+
+ var positions = PositionUtil.getPositions(storage, deviceId, from, to);
+
+ var attributes = positions.stream()
+ .flatMap((position -> position.getAttributes().keySet().stream()))
+ .collect(Collectors.toUnmodifiableSet());
+
+ var properties = new LinkedHashMap<String, Function<Position, Object>>();
+ properties.put("id", Position::getId);
+ properties.put("deviceId", Position::getDeviceId);
+ properties.put("protocol", Position::getProtocol);
+ properties.put("serverTime", position -> DateUtil.formatDate(position.getServerTime()));
+ properties.put("deviceTime", position -> DateUtil.formatDate(position.getDeviceTime()));
+ properties.put("fixTime", position -> DateUtil.formatDate(position.getFixTime()));
+ properties.put("valid", Position::getValid);
+ properties.put("latitude", Position::getLatitude);
+ properties.put("longitude", Position::getLongitude);
+ properties.put("altitude", Position::getAltitude);
+ properties.put("speed", Position::getSpeed);
+ properties.put("course", Position::getCourse);
+ properties.put("address", Position::getAddress);
+ properties.put("accuracy", Position::getAccuracy);
+ attributes.forEach(key -> properties.put(key, position -> position.getAttributes().get(key)));
+
+ try (PrintWriter writer = new PrintWriter(outputStream)) {
+ writer.println(String.join(",", properties.keySet()));
+ positions.forEach(position -> writer.println(properties.values().stream()
+ .map(f -> Objects.toString(f.apply(position), ""))
+ .collect(Collectors.joining(","))));
+ }
+ }
+
+}
diff --git a/src/main/java/org/traccar/reports/KmlExportProvider.java b/src/main/java/org/traccar/reports/KmlExportProvider.java
index 977897833..e8b5c4278 100644
--- a/src/main/java/org/traccar/reports/KmlExportProvider.java
+++ b/src/main/java/org/traccar/reports/KmlExportProvider.java
@@ -39,7 +39,7 @@ public class KmlExportProvider {
this.storage = storage;
}
- public void generateKml(
+ public void generate(
OutputStream outputStream, long deviceId, Date from, Date to) throws StorageException {
var device = storage.getObject(Device.class, new Request(