Project

General

Profile

1
package eu.dnetlib.data.mdstore.plugins;
2

    
3
import java.io.ByteArrayInputStream;
4
import java.io.IOException;
5
import java.io.InputStream;
6
import java.util.Arrays;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Set;
10
import java.util.stream.Collectors;
11

    
12
import org.apache.commons.lang3.StringUtils;
13
import org.apache.commons.logging.Log;
14
import org.apache.commons.logging.LogFactory;
15
import org.apache.commons.net.ftp.FTPClient;
16
import org.apache.commons.net.ftp.FTPFile;
17

    
18
import com.google.common.net.UrlEscapers;
19

    
20
import eu.dnetlib.data.mdstore.plugins.objects.MdRecord;
21
import eu.dnetlib.data.mdstore.plugins.objects.MyURL;
22

    
23
public class EnrichLocalLinksPlugin extends MdRecordPlugin {
24

    
25
	private static final String DEFAULT_RIGHTS = "Open Access";
26

    
27
	private static final String INFO_FILENAME = "info.txt";
28

    
29
	private static final Log log = LogFactory.getLog(EnrichLocalLinksPlugin.class);
30

    
31
	private FTPClient ftpClient = new FTPClient();
32

    
33
	private String hostedBy;
34
	private String baseUrl;
35

    
36
	private String ftpServer;
37
	private String ftpUser;
38
	private String ftpPassword;
39
	private String ftpBaseDir;
40

    
41
	@Override
42
	protected void reconfigure(final Map<String, String> params) {
43
		setHostedBy(params.get("hostedBy"));
44
		setBaseUrl(params.get("baseUrl"));
45
		setFtpServer(params.get("ftpServer"));
46
		setFtpUser(params.get("ftpUser"));
47
		setFtpPassword(params.get("ftpPassword"));
48
		setFtpBaseDir(params.get("ftpBaseDir"));
49

    
50
		if (!getFtpBaseDir().startsWith("/")) {
51
			setFtpBaseDir("/" + getFtpBaseDir());
52
		}
53

    
54
		try {
55
			ftpClient.connect(getFtpServer());
56
			ftpClient.login(getFtpUser(), getFtpPassword());
57

    
58
			ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
59
			ftpClient.enterLocalPassiveMode();
60
			ftpClient.setBufferSize(1024);
61

    
62
			log.info("Connected to " + ftpServer);
63
		} catch (final IOException e) {
64
			log.error("Connection Failed");
65
			throw new RuntimeException(e);
66
		}
67
	}
68

    
69
	@Override
70
	protected void resetConfiguration() {
71
		if (ftpClient.isConnected()) {
72
			try {
73
				ftpClient.disconnect();
74
				log.info("Disconnected from " + ftpServer);
75
			} catch (final IOException e) {
76
				log.error("Disconnection Failed");
77
				throw new RuntimeException(e);
78
			}
79
		}
80
		setHostedBy(null);
81
		setBaseUrl(null);
82
		setFtpServer(null);
83
		setFtpUser(null);
84
		setFtpPassword(null);
85
		setFtpBaseDir(null);
86
	}
87

    
88
	@Override
89
	protected boolean updateRecord(final String recordId, final MdRecord doc) {
90

    
91
		final int year = doc.getDate();
92
		final String code = StringUtils.substringAfterLast(doc.getId(), ":");
93

    
94
		log.info(String.format("Processing record: %s (%s/%s)", doc.getId(), year, code));
95

    
96
		final List<String> files = touchAndListDir(doc.getTitle(), doc.getCreators(), doc.getType(), year, code);
97

    
98
		if (files.isEmpty()) {
99
			return false;
100
		} else {
101
			log.info("  - adding new urls: " + files.size());
102
			doc.setBestRights(DEFAULT_RIGHTS);
103
			for (final String f : files) {
104
				doc.getUrls().add(new MyURL(calculateUrl(recordId, code, year, f), getHostedBy(), DEFAULT_RIGHTS));
105
			}
106
		}
107
		return true;
108
	}
109

    
110
	private List<String> touchAndListDir(final String title, final Set<String> authors, final String type, final int year, final String code) {
111
		final String content = String.format(
112
				"TITLE     : %s\nAUTHOR(S) : %s\nTYPE      : %s\nYEAR      : %s\nCODE      : %s\n\n*** DO NOT EDIT THIS FILE ***\n\n",
113
				title,
114
				StringUtils.join(authors, ", "),
115
				type,
116
				year,
117
				code);
118

    
119
		if (ftpChangeDir(getFtpBaseDir()) && ftpChangeDir(Integer.toString(year)) && ftpChangeDir(code)) {
120

    
121
			try (InputStream is = new ByteArrayInputStream(content.getBytes())) {
122
				if (log.isDebugEnabled()) {
123
					log.debug(String.format(" - Saving file %s/%s/%s/%s", getFtpBaseDir(), year, code, INFO_FILENAME));
124
					log.debug(content);
125
				}
126
				if (!ftpClient.storeFile(INFO_FILENAME, is)) {
127
					log.error("Error saving file");
128
					throw new RuntimeException("Error saving file");
129
				}
130
			} catch (final IOException e) {
131
				log.error("Error saving info file");
132
				throw new RuntimeException("Error saving info file", e);
133
			}
134

    
135
			try {
136
				return Arrays.stream(ftpClient.listFiles())
137
						.map(FTPFile::getName)
138
						.filter(s -> s.toLowerCase().endsWith(".pdf"))
139
						.sorted()
140
						.collect(Collectors.toList());
141
			} catch (final IOException e) {
142
				log.error("Error listing files");
143
				throw new RuntimeException("Error listing files", e);
144
			}
145
		} else {
146
			log.error(String.format("Directory not found: %s/%s/%s", getFtpBaseDir(), year, code));
147
			throw new RuntimeException(String.format("Directory not found: %s/%s/%s", getFtpBaseDir(), year, code));
148
		}
149

    
150
	}
151

    
152
	private boolean ftpChangeDir(final String dir) {
153
		try {
154
			if (!ftpClient.changeWorkingDirectory(dir)) {
155
				ftpClient.makeDirectory(dir);
156
				return ftpClient.changeWorkingDirectory(dir);
157
			}
158
			return true;
159
		} catch (final IOException e) {
160
			log.error("Error changing or create dir: " + dir);
161
			throw new RuntimeException("Error changing or create dir: " + dir, e);
162
		}
163
	}
164

    
165
	private String calculateUrl(final String id, final String code, final int year, final String f) {
166
		// the parameter ID is necessary for a better integration with OpenAIRE
167
		return String.format("%s/%s/%s/%s?id=%s", getBaseUrl(), year, code, UrlEscapers.urlPathSegmentEscaper().escape(f),
168
				UrlEscapers.urlFormParameterEscaper().escape(id));
169
	}
170

    
171
	public String getHostedBy() {
172
		return hostedBy;
173
	}
174

    
175
	public void setHostedBy(final String hostedBy) {
176
		this.hostedBy = hostedBy;
177
	}
178

    
179
	public String getBaseUrl() {
180
		return baseUrl;
181
	}
182

    
183
	public void setBaseUrl(final String baseUrl) {
184
		this.baseUrl = baseUrl;
185
	}
186

    
187
	public String getFtpBaseDir() {
188
		return ftpBaseDir;
189
	}
190

    
191
	public void setFtpBaseDir(final String ftpBaseDir) {
192
		this.ftpBaseDir = ftpBaseDir;
193
	}
194

    
195
	public FTPClient getFtpClient() {
196
		return ftpClient;
197
	}
198

    
199
	public void setFtpClient(final FTPClient ftpClient) {
200
		this.ftpClient = ftpClient;
201
	}
202

    
203
	public String getFtpServer() {
204
		return ftpServer;
205
	}
206

    
207
	public void setFtpServer(final String ftpServer) {
208
		this.ftpServer = ftpServer;
209
	}
210

    
211
	public String getFtpUser() {
212
		return ftpUser;
213
	}
214

    
215
	public void setFtpUser(final String ftpUser) {
216
		this.ftpUser = ftpUser;
217
	}
218

    
219
	public String getFtpPassword() {
220
		return ftpPassword;
221
	}
222

    
223
	public void setFtpPassword(final String ftpPassword) {
224
		this.ftpPassword = ftpPassword;
225
	}
226

    
227
}
(6-6/12)