File: LinkedMediaLoader.java

package info (click to toggle)
gpsprune 26.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,824 kB
  • sloc: java: 52,154; sh: 25; makefile: 21; python: 15
file content (175 lines) | stat: -rw-r--r-- 5,604 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package tim.prune.function.media;

import java.io.File;
import java.net.URL;
import java.util.HashSet;
import java.util.List;

import javax.swing.JOptionPane;

import tim.prune.App;
import tim.prune.I18nManager;
import tim.prune.cmd.AppendMediaCmd;
import tim.prune.cmd.CompoundCommand;
import tim.prune.cmd.ConnectMediaCmd;
import tim.prune.data.DataPoint;
import tim.prune.data.Distance;
import tim.prune.data.MediaObject;
import tim.prune.data.UnitSetLibrary;
import tim.prune.load.ItemToLoad.BlockStatus;
import tim.prune.load.MediaHelper;

/**
 * Class to load a single media item (photo / audio)
 * and link it to the referenced point
 */
public class LinkedMediaLoader
{
	private final App _app;
	private final HashSet<String> _blockedDomains = new HashSet<>();
	private final HashSet<String> _allowedDomains = new HashSet<>();

	public LinkedMediaLoader(App inApp) {
		_app = inApp;
	}

	/**
	 * Load a media using a provided url
	 * @param inUrl url
	 * @param inPoint point to which this media will be attached
	 * @param inStatus possible block status already applied
	 */
	public void loadFromUrl(URL inUrl, DataPoint inPoint, BlockStatus inStatus)
	{
		processBlockStatus(inUrl, inStatus);
		if (isDomainAllowed(inUrl)) {
			loadMedia(MediaHelper.createMediaObjectFromUrl(inUrl), inPoint);
		}
		_app.informDataLoadComplete();
	}

	private void processBlockStatus(URL inUrl, BlockStatus inStatus)
	{
		if (inStatus == BlockStatus.NOT_ASKED || inStatus == BlockStatus.ASKED) {
			return;
		}
		String domain = inUrl.getHost();
		if (inStatus == BlockStatus.ALLOW) {
			_allowedDomains.add(domain);
		}
		else if (inStatus == BlockStatus.BLOCK) {
			_blockedDomains.add(domain);
		}
	}

	/**
	 * After the media object has been constructed, load it and attach it
	 * @param inMedia media object, or null if load failed
	 * @param inPoint data point to which it will be attached
	 */
	private void loadMedia(MediaObject inMedia, DataPoint inPoint)
	{
		if (inMedia == null) {
			return;
		}
		// Check if the media object has a point now (from exif)
		DataPoint exifPoint = inMedia.getDataPoint();
		final MediaObject.Status originalMediaStatus =
			(exifPoint == null ? MediaObject.Status.NOT_CONNECTED : MediaObject.Status.TAGGED);
		inMedia.setOriginalStatus(originalMediaStatus);
		MediaObject.Status currMediaStatus = MediaObject.Status.TAGGED;
		if (exifPoint != null)
		{
			final double distinMetres = Distance.convertRadiansToDistance(
				DataPoint.calculateRadiansBetween(exifPoint, inPoint), UnitSetLibrary.UNITS_METRES);
			if (distinMetres > 10.0) {
				currMediaStatus = MediaObject.Status.CONNECTED; // still connected but changed
			}
		}
		inMedia.setCurrentStatus(currMediaStatus);
		// Now create the command
		CompoundCommand command = new CompoundCommand()
				.addCommand(new AppendMediaCmd(List.of(inMedia)))
				.addCommand(new ConnectMediaCmd(inPoint, inMedia));
		command.setDescription(I18nManager.getText("undo.loadmedia", shortenName(inMedia.getName())));
		command.setConfirmText(I18nManager.getText("confirm.loadedmedia"));
		_app.execute(command);
	}

	private String shortenName(String inName)
	{
		if (inName == null) {
			return "";
		}
		if (inName.length() < 30) {
			return inName;
		}
		return "..." + inName.substring(inName.length() - 30);
	}

	/**
	 * Check whether the domain of the given URL is allowed or blocked
	 * @param inUrl entire Url for display in the question message if necessary
	 * @return true if allowed, false if blocked
	 */
	private boolean isDomainAllowed(URL inUrl)
	{
		if (inUrl == null) {
			return false;
		}
		final String domain = inUrl.getHost();
		if (_allowedDomains.contains(domain)) {
			return true;
		}
		if (_blockedDomains.contains(domain)) {
			return false;
		}
		Object[] buttonTexts = {I18nManager.getText("button.allow"), I18nManager.getText("button.block")};
		final String question = splitUrl(inUrl.toString()) + "\n\n" + I18nManager.getText("dialog.loadlinkedmedia.allowdomain", domain);
		int answer = JOptionPane.showOptionDialog(_app.getFrame(), question,
				I18nManager.getText("dialog.loadlinkedmedia.title"), JOptionPane.YES_NO_OPTION,
				JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1]);
		if (answer == JOptionPane.YES_OPTION) {
			_allowedDomains.add(domain);
		}
		if (answer == JOptionPane.NO_OPTION) {
			_blockedDomains.add(domain);
		}
		return answer == JOptionPane.YES_OPTION;
	}

	public boolean isDomainKnown(String inDomain) {
		return _allowedDomains.contains(inDomain) || _blockedDomains.contains(inDomain);
	}

	/**
	 * @param inUrl url which is perhaps too long for one line
	 * @return string with line breaks to make more readable in dialog
	 */
	static String splitUrl(String inUrl)
	{
		final int splitLength = 50;
		StringBuilder builder = new StringBuilder();
		String urlString = inUrl.trim();
		int startPos = 0;
		while ((startPos + splitLength) < urlString.length()) {
			builder.append(urlString.substring(startPos, startPos+splitLength));
			builder.append('\n');
			startPos += splitLength;
		}
		builder.append(urlString.substring(startPos));
		return builder.toString();
	}

	/**
	 * Load a media object from inside an archive, like a zip or a kmz
	 * @param inArchiveFile container file from which data was loaded
	 * @param inPath path to media within archive
	 * @param inPoint data point to which it should be attached
	 */
	public void loadFromArchive(File inArchiveFile, String inPath, DataPoint inPoint)
	{
		loadMedia(MediaHelper.createMediaObjectRelative(inArchiveFile, inPath, inArchiveFile), inPoint);
		_app.informDataLoadComplete();
	}
}