Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share GPX #978

Merged
merged 31 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0b9d50c
remove unused annotations
alisa911 Nov 20, 2024
e017c8f
add share gpx
alisa911 Nov 20, 2024
96fedd7
fix shared token
alisa911 Nov 20, 2024
14d564e
refactoring share gpx
alisa911 Nov 21, 2024
033af30
merge master
alisa911 Nov 28, 2024
e493f00
add share api
alisa911 Nov 28, 2024
d91e40d
add index
alisa911 Nov 28, 2024
b2b40b0
fix saveAccessedUser
alisa911 Nov 28, 2024
138137f
refactoring
alisa911 Nov 29, 2024
c635cbd
create table share_files
alisa911 Dec 2, 2024
bcf7abe
refactoring
alisa911 Dec 2, 2024
267b58e
merge master
alisa911 Dec 6, 2024
20d7d02
change share api
alisa911 Dec 11, 2024
a14d5da
open share file for owner
alisa911 Dec 11, 2024
9989a01
Merge branch 'master' into T2527
alisa911 Dec 13, 2024
593764b
add share details
alisa911 Dec 13, 2024
2878b47
add share flag for list-files
alisa911 Dec 13, 2024
de77bde
add changeShareType
alisa911 Dec 13, 2024
88ff43f
add share error file is not available
alisa911 Dec 16, 2024
579e4eb
add nickname field to PremiumUser
alisa911 Dec 17, 2024
b128058
add private share type
alisa911 Dec 18, 2024
161a9e0
Merge branch 'master' into T2527
alisa911 Dec 18, 2024
41e92f4
rename column id
alisa911 Dec 18, 2024
e71e43c
refactoring
alisa911 Dec 18, 2024
4450b40
change UUID
alisa911 Dec 18, 2024
a313d4d
refactoring
alisa911 Dec 18, 2024
36d2757
refactoring
alisa911 Dec 18, 2024
5a54608
Merge branch 'master' into T2527
alisa911 Dec 20, 2024
965f2f5
Merge branch 'master' into T2527
alisa911 Dec 26, 2024
36e6920
Merge branch 'master' into T2527
alisa911 Dec 27, 2024
4c76626
Merge branch 'master' into T2527
alisa911 Dec 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion db/sql_changeset_schema
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ ALTER TABLE supporters_device_sub add primary key (sku, orderid);
------ PREMIUM accounts ----
CREATE TABLE user_accounts(id serial primary key, email text not null, tokendevice text, orderid text, token text, tokentime timestamp, regtime timestamp);
CREATE TABLE user_account_devices(id serial primary key, userid integer, deviceid text, accesstoken text, lang text, brand text, model text, udpatetime timestamp);
CREATE TABLE user_files(id bigserial primary key, type text, name text, userid integer, deviceid integer, updatetime timestamp, clienttime timestamp, filesize bigint, zipfilesize bigint, storage text, gendetails jsonb, data bytea);
CREATE TABLE user_files(id bigserial primary key, type text, name text, userid integer, deviceid integer, updatetime timestamp, clienttime timestamp, filesize bigint, zipfilesize bigint, storage text, gendetails jsonb, data bytea, shared_url text, shared_info jsonb);
alisa911 marked this conversation as resolved.
Show resolved Hide resolved
CREATE TABLE promo_campaigns(name text, starttime timestamp, endtime timestamp, subactivemonths integer, numberlimit integer, used integer, lastusers text);
ALTER TABLE user_accounts ADD CONSTRAINT email_uniq UNIQUE (email);
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ public interface PremiumUserFilesRepository extends JpaRepository<UserFile, Long
UserFile findTopByUseridAndNameAndTypeAndUpdatetimeGreaterThanOrderByUpdatetimeDesc(int userid, String name, String type, Date updatetime);

List<UserFile> findAllByUseridAndNameAndTypeOrderByUpdatetimeDesc(int userid, String name, String type);

Iterable<UserFile> findAllByUserid(int userid);


UserFile findUserFileBySharedUrl(String sharedUrl);

@Query("SELECT uf FROM UserFile uf " +
"WHERE uf.userid = :userid AND uf.name LIKE :folderName% AND uf.type = :type " +
"AND uf.updatetime = (SELECT MAX(uft.updatetime) FROM UserFile uft WHERE uft.userid = :userid AND uft.name = uf.name)")
Expand Down Expand Up @@ -89,13 +91,17 @@ class UserFile {
@Column(name = "gendetails", columnDefinition = "jsonb")
@Type(type = "net.osmand.server.assist.data.JsonbType")
public JsonObject details;

// @Fetch(FetchMode.JOIN)

@Column(name = "data", columnDefinition="bytea")
public byte[] data;

// @Lob
// public Blob data;

@Column(name = "shared_url")
public String sharedUrl;

@Column(name = "shared_info", columnDefinition = "jsonb")
@Type(type = "net.osmand.server.assist.data.JsonbType")
public JsonObject sharedInfo;


}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.osmand.server.api.services;

import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
import static org.springframework.util.MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE;

import java.io.ByteArrayInputStream;
import java.io.File;
Expand All @@ -10,17 +11,10 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
Expand All @@ -33,6 +27,10 @@
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import net.osmand.shared.gpx.GpxFile;
import net.osmand.shared.gpx.GpxUtilities;
import okio.Buffer;
import okio.Source;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -1195,4 +1193,125 @@ public void updateDeviceLangInfo(PremiumUserDevicesRepository.PremiumUserDevice
devicesRepository.saveAndFlush(dev);
}
}

@Transactional
public String generateSharedUrl(PremiumUserFilesRepository.UserFile userFile) {
String fileName = userFile.name.replaceAll("\\s+", "_").toLowerCase();
String uniqueToken = UUID.randomUUID().toString();
String url = fileName + "_" + uniqueToken;
userFile.sharedUrl = url;
filesRepository.saveAndFlush(userFile);

return url;
}
alisa911 marked this conversation as resolved.
Show resolved Hide resolved

public PremiumUserFilesRepository.UserFile getUserFileBySharedUrl(String token) {
return filesRepository.findUserFileBySharedUrl(token);
}

public MapApiController.FileDownloadResult getFile(PremiumUserFilesRepository.UserFile userFile, PremiumUserDevicesRepository.PremiumUserDevice dev) throws IOException {
if (userFile == null || dev == null) {
return null;
}
try (InputStream bin = getInputStream(dev, userFile)) {
if (bin != null) {
InputStream inputStream = new GZIPInputStream(bin);
String fileName = URLEncoder.encode(sanitizeEncode(userFile.name), StandardCharsets.UTF_8);
return new MapApiController.FileDownloadResult(inputStream, fileName, APPLICATION_OCTET_STREAM_VALUE);
}
}
return null;
}

public GpxFile getFile(PremiumUserFilesRepository.UserFile file) throws IOException {
if (file == null || file.data == null) {
return null;
}
try (InputStream inputStream = new GZIPInputStream(new ByteArrayInputStream(file.data));
Source source = new Buffer().readFrom(inputStream)) {
GpxFile gpxFile = GpxUtilities.INSTANCE.loadGpxFile(source);
if (gpxFile.getError() == null) {
return gpxFile;
}
return null;
}
}

public static class FileSharedInfo {
public Set<Integer> accessedUsers;
public Set<Integer> blackList;
alisa911 marked this conversation as resolved.
Show resolved Hide resolved

public FileSharedInfo(Set<Integer> accessedUsers, Set<Integer> blackList) {
this.accessedUsers = accessedUsers;
this.blackList = blackList;
}

public FileSharedInfo() {
this.accessedUsers = new HashSet<>();
this.blackList = new HashSet<>();
}
}

public boolean saveAccessedUser(PremiumUserDevicesRepository.PremiumUserDevice dev, PremiumUserFilesRepository.UserFile userFile) {
final String ACCESSED_USERS = "accessedUsers";
FileSharedInfo fileSharedInfo = gson.fromJson(userFile.sharedInfo, FileSharedInfo.class);
if (fileSharedInfo == null) {
fileSharedInfo = new FileSharedInfo();
}
if (!fileSharedInfo.blackList.contains(dev.userid)) {
if (fileSharedInfo.accessedUsers.add(dev.userid)) {
userFile.sharedInfo.add(ACCESSED_USERS, gson.toJsonTree(fileSharedInfo.accessedUsers));
filesRepository.saveAndFlush(userFile);
}
return true;
}
return false;
}

public List<String> getAccessedUsers(PremiumUserFilesRepository.UserFile userFile) {
List<String> accessedUsers = new ArrayList<>();
FileSharedInfo fileSharedInfo = gson.fromJson(userFile.sharedInfo, FileSharedInfo.class);
if (fileSharedInfo != null && fileSharedInfo.accessedUsers != null) {
for (Integer userId : fileSharedInfo.accessedUsers) {
PremiumUsersRepository.PremiumUser pu = usersRepository.findById(userId);
if (pu != null) {
accessedUsers.add(pu.email);
alisa911 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
return accessedUsers;
}

@Transactional
public boolean createFileBlacklist(PremiumUserFilesRepository.UserFile userFile, List<String> list) {
final String BLACK_LIST = "blackList";
FileSharedInfo fileSharedInfo = gson.fromJson(userFile.sharedInfo, FileSharedInfo.class);
if (fileSharedInfo == null) {
fileSharedInfo = new FileSharedInfo();
}
fileSharedInfo.blackList.addAll(list.stream().map(email -> {
PremiumUsersRepository.PremiumUser pu = usersRepository.findByEmailIgnoreCase(email);
return pu != null ? pu.id : null;
}).filter(Objects::nonNull).toList());
if (fileSharedInfo.blackList.isEmpty()) {
return false;
}
userFile.sharedInfo.add(BLACK_LIST, gson.toJsonTree(fileSharedInfo.blackList));
filesRepository.saveAndFlush(userFile);
return true;
}

public List<String> getBlackList(PremiumUserFilesRepository.UserFile userFile) {
List<String> blackList = new ArrayList<>();
FileSharedInfo fileSharedInfo = gson.fromJson(userFile.sharedInfo, FileSharedInfo.class);
if (fileSharedInfo != null && fileSharedInfo.blackList != null) {
for (Integer userId : fileSharedInfo.blackList) {
PremiumUsersRepository.PremiumUser pu = usersRepository.findById(userId);
if (pu != null) {
blackList.add(pu.email);
}
}
}
return blackList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@

import net.osmand.server.WebSecurityConfiguration.OsmAndProUser;
import net.osmand.server.api.services.GpxService;
import net.osmand.server.api.services.OsmAndMapsService;
import net.osmand.server.controllers.pub.UserSessionResources.GPXSessionContext;
import net.osmand.server.controllers.pub.UserSessionResources.GPXSessionFile;
import net.osmand.server.utils.WebGpxParser;
Expand Down Expand Up @@ -86,7 +85,6 @@ public class GpxController {
String srtmLocation;

@PostMapping(path = {"/clear"}, produces = "application/json")
@ResponseBody
public String clear(HttpServletRequest request, HttpSession httpSession) throws IOException {
GPXSessionContext ctx = session.getGpxResources(httpSession);
for (File f : ctx.tempFiles) {
Expand All @@ -98,14 +96,12 @@ public String clear(HttpServletRequest request, HttpSession httpSession) throws
}

@GetMapping(path = { "/get-gpx-info" }, produces = "application/json")
@ResponseBody
public String getGpx(HttpSession httpSession) {
GPXSessionContext ctx = session.getGpxResources(httpSession);
return gson.toJson(Map.of("all", ctx.files));
}

@GetMapping(path = {"/get-gpx-file"}, produces = "application/json")
@ResponseBody
public ResponseEntity<Resource> getGpx(@RequestParam String name, HttpSession httpSession) {
GPXSessionContext ctx = session.getGpxResources(httpSession);
File tmpGpx = null;
Expand Down Expand Up @@ -225,7 +221,6 @@ public ResponseEntity<String> uploadGpx(@RequestPart(name = "file") @Valid @NotN
}

@PostMapping(path = {"/get-gpx-analysis"}, produces = "application/json")
@ResponseBody
public ResponseEntity<String> getGpxInfo(@RequestPart(name = "file") @Valid @NotNull @NotEmpty MultipartFile file,
HttpServletRequest request, HttpSession httpSession) throws IOException {

Expand Down Expand Up @@ -260,7 +255,6 @@ public ResponseEntity<String> getGpxInfo(@RequestPart(name = "file") @Valid @Not
}

@PostMapping(path = {"/process-track-data"}, produces = "application/json")
@ResponseBody
public ResponseEntity<String> processTrackData(@RequestPart(name = "file") @Valid @NotNull @NotEmpty MultipartFile file,
HttpSession httpSession) throws IOException {

Expand All @@ -282,7 +276,6 @@ public ResponseEntity<String> processTrackData(@RequestPart(name = "file") @Vali
}

@PostMapping(path = {"/save-track-data"}, produces = "application/json")
@ResponseBody
public ResponseEntity<InputStreamResource> saveTrackData(@RequestBody String data,
HttpSession httpSession) throws IOException {
WebGpxParser.TrackData trackData = new Gson().fromJson(data, WebGpxParser.TrackData.class);
Expand Down
Loading