Skip to content

Commit e64a477

Browse files
committed
(Breaking change) Wiki:
*getImageHistory: rename to getFileHistory, vectorize, bug fixes. *add file reversion.
1 parent f124716 commit e64a477

File tree

4 files changed

+140
-34
lines changed

4 files changed

+140
-34
lines changed

src/org/wikipedia/Wiki.java

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,7 +3656,7 @@ public synchronized void revisionDelete(Boolean hidecontent, Boolean hideuser, B
36563656
if (!temp.getClass().equals(clazz))
36573657
throw new IllegalArgumentException("All Events to be RevisionDeleted must be of the same type.");
36583658
// TODO: Apparently you can RevisionDelete old files (i.e.
3659-
// pseudo-LogEntries from getImageHistory and the file archive, but
3659+
// pseudo-LogEntries from getFileHistory and the file archive, but
36603660
// I have no idea how to get the necessary ID parameter.
36613661
// You can also RevisionDelete deleted revisions, but I need to
36623662
// test this first.
@@ -4203,7 +4203,7 @@ public List<Map<String, Object>> getFileMetadata(SequencedCollection<String> fil
42034203
* Commons).
42044204
*
42054205
* @param files the files for checking duplicates (may contain "File")
4206-
* @return the duplicates of those files
4206+
* @return the duplicates of those files, in order of input
42074207
* @throws IOException or UncheckedIOException if a network error occurs
42084208
* @throws IllegalArgumentException if any of the files has an invalid title
42094209
* @since 0.18
@@ -4231,25 +4231,28 @@ public List<List<String>> getDuplicates(List<String> files) throws IOException
42314231
}
42324232

42334233
/**
4234-
* Returns the upload history of an image. This is not the same as
4234+
* Returns the upload histories of a list of files. This is not the same as
42354235
* {@linkplain #getLogEntries(String, String, Wiki.RequestHelper) fetching
4236-
* a page's upload log}, as the image may have been deleted. This returns
4237-
* only the live history of an image.
4236+
* each file's upload log individually}, as the file may have been deleted.
4237+
* This returns only the live history of the files. The log entries so
4238+
* returned have the archive filename as details.
42384239
*
4239-
* @param title the title of the image (may contain File)
4240-
* @return the image history of the image
4240+
* @param titles a bunch of file titles (may contain File)
4241+
* @return the history of the files, in order of input
42414242
* @throws IOException or UncheckedIOException if a network error occurs
4242-
* @since 0.20
4243+
* @since 0.39
4244+
* @see #fileRevert(String, String)
42434245
*/
4244-
public List<LogEntry> getImageHistory(String title) throws IOException
4246+
public List<List<LogEntry>> getFileHistory(SequencedCollection<String> titles) throws IOException
42454247
{
42464248
Map<String, String> getparams = new HashMap<>();
4249+
List<String> files2 = new ArrayList<>(titles.size());
4250+
for (String title : titles)
4251+
files2.add("File:" + removeNamespace(normalize(title), FILE_NAMESPACE));
42474252
getparams.put("prop", "imageinfo");
4248-
getparams.put("iiprop", "timestamp|user|comment|parsedcomment");
4249-
getparams.put("titles", "File:" + removeNamespace(normalize(title), FILE_NAMESPACE));
4253+
getparams.put("iiprop", "timestamp|user|comment|parsedcomment|archivename");
42504254

4251-
String prefixtitle = namespaceIdentifier(FILE_NAMESPACE) + ":" + title;
4252-
List<LogEntry> history = makeListQuery("ii", getparams, null, "getImageHistory", -1, (line, results) ->
4255+
List<List<LogEntry>> history = makeVectorizedQuery("ii", getparams, files2, "getFileHistory", -1, (line, results) ->
42534256
{
42544257
if (line.contains("missing=\"\""))
42554258
return;
@@ -4259,18 +4262,24 @@ public List<LogEntry> getImageHistory(String title) throws IOException
42594262
{
42604263
int b = line.indexOf('>', a);
42614264
String temp = line.substring(a, b);
4262-
LogEntry le = parseLogEntry(temp, null, UPLOAD_LOG, "overwrite", prefixtitle);
4265+
LogEntry le = parseLogEntry(temp, null, UPLOAD_LOG, "overwrite", parseAttribute(line, "title", 0));
4266+
le.details = new HashMap<>();
4267+
le.details.put("archivename", parseAttribute(temp, "archivename", 0));
42634268
results.add(le);
42644269
}
42654270
});
42664271

4267-
// crude hack: action adjusting for first image (in the history, not our list)
4268-
int size = history.size();
4269-
if (size == 0)
4270-
return Collections.emptyList();
4271-
LogEntry last = history.get(size - 1);
4272-
last.action = "upload";
4273-
history.set(size - 1, last);
4272+
// adjust actions
4273+
for (int i = 0; i < history.size(); i++)
4274+
{
4275+
List<Wiki.LogEntry> history2 = history.get(i);
4276+
int size = history2.size();
4277+
if (size == 0)
4278+
continue;
4279+
LogEntry last = history2.get(size - 1);
4280+
last.action = "upload";
4281+
history2.set(size - 1, last);
4282+
}
42744283
return history;
42754284
}
42764285

@@ -4547,6 +4556,48 @@ public synchronized void upload(URL url, String filename, String contents, Strin
45474556
checkErrorsAndUpdateStatus(response, "upload", null, null);
45484557
log(Level.INFO, "upload", "Successfully uploaded to File:" + filename + ".");
45494558
}
4559+
4560+
/**
4561+
* Reverts a file to the given previous revision.
4562+
* @param filename the target file name (may contain File)
4563+
* @param filerev a file revision LogEntry from {@link #getFileHistory(List)}
4564+
* @param reason the reason for reverting the file
4565+
* @throws IOException or UncheckedIOException if a network error occurs
4566+
* @throws SecurityException if not logged in
4567+
* @throws CredentialException if (page is protected OR file is on a central
4568+
* repository) and we can't revert the file
4569+
* @throws CredentialExpiredException if cookies have expired
4570+
* @throws AccountLockedException if user is blocked
4571+
* @since 0.39
4572+
*/
4573+
public synchronized void fileRevert(String filename, Wiki.LogEntry filerev, String reason) throws IOException, LoginException
4574+
{
4575+
filename = removeNamespace(filename, FILE_NAMESPACE);
4576+
checkPermissions("upload", "upload_by_url");
4577+
throttle();
4578+
4579+
// protection
4580+
Map<String, Object> info = getPageInfo(List.of("File:" + filename)).get(0);
4581+
if (!checkRights(info, "upload"))
4582+
{
4583+
CredentialException ex = new CredentialException("Permission denied: page is protected.");
4584+
log(Level.WARNING, "upload", "Cannot revert file - permission denied." + ex);
4585+
throw ex;
4586+
}
4587+
4588+
// send and build request
4589+
Map<String, String> getparams = new HashMap<>();
4590+
getparams.put("action", "filerevert");
4591+
getparams.put("filename", normalize(filename));
4592+
Map<String, Object> postparams = new HashMap<>();
4593+
postparams.put("token", getToken("csrf"));
4594+
postparams.put("comment", reason);
4595+
postparams.put("archivename", filerev.getDetails().get("archivename"));
4596+
4597+
String response = makeApiCall(getparams, postparams, "fileRevert");
4598+
checkErrorsAndUpdateStatus(response, "fileRevert", null, null);
4599+
log(Level.INFO, "fileRevert", "Successfully reverted File:" + filename + ".");
4600+
}
45504601

45514602
// USER METHODS
45524603

@@ -6042,7 +6093,7 @@ public List<LogEntry> getLogEntries(String logtype, String action, Wiki.RequestH
60426093

60436094
/**
60446095
* Parses xml generated by <code>getLogEntries()</code>,
6045-
* <code>getImageHistory()</code> and <code>getBlockList()</code> into {@link Wiki.LogEntry}
6096+
* <code>getFileHistory()</code> and <code>getBlockList()</code> into {@link Wiki.LogEntry}
60466097
* objects. Override this if you want custom log types. NOTE: if
60476098
* RevisionDelete was used on a log entry, the relevant values will be
60486099
* null.
@@ -6090,7 +6141,8 @@ else if (reasonhidden)
60906141
}
60916142
else
60926143
{
6093-
reason = parseAttribute(xml, "comment", 0);
6144+
// space is important, if comment comes after parsedcomment
6145+
reason = parseAttribute(xml, " comment", 0);
60946146
parsedreason = parseAttribute(xml, "parsedcomment", 0);
60956147
}
60966148

@@ -6102,7 +6154,7 @@ else if (userhidden)
61026154
user = Wiki.Event.USER_DELETED;
61036155

61046156
// generic target name
6105-
// space is important -- commons.getImageHistory("File:Chief1.gif");
6157+
// space is important -- commons.getFileHistory("File:Chief1.gif");
61066158
if (target == null && xml.contains(" title=\""))
61076159
target = parseAttribute(xml, "title", 0);
61086160
else if (actionhidden)

test/WikiTests.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,6 @@ public static void main(String[] args) throws Exception
134134
for (Wiki.Revision revision : enWiki.contribs("", "127.0.", c, null))
135135
System.out.println(revision);
136136
137-
// getImageHistory
138-
for (Wiki.LogEntry entry : enWiki.getImageHistory("Davis Motor Car Company logo.jpg"))
139-
System.out.println(entry);
140-
141137
// Revision.diff
142138
System.out.println(enWiki.getRevision(473467375L).diff(Wiki.PREVIOUS_REVISION));
143139
@@ -172,7 +168,7 @@ public static void main(String[] args) throws Exception
172168
/*
173169
174170
// getOldImage/image history
175-
Wiki.LogEntry[] entries = enWiki.getImageHistory("File:Bohemian Rhapsody.png");
171+
Wiki.LogEntry[] entries = enWiki.getFileHistory("File:Bohemian Rhapsody.png");
176172
for (Wiki.LogEntry entry : entries)
177173
System.out.println(entry);
178174
FileOutputStream out2 = new FileOutputStream("hello.png");

test/org/wikipedia/LoggedInUnitTests.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package org.wikipedia;
2020

2121
import java.io.File;
22-
import java.net.URL;
22+
import java.net.URI;
2323
import java.nio.file.Files;
2424
import java.util.*;
2525
import org.junit.jupiter.api.*;
@@ -87,7 +87,8 @@ public void upload() throws Exception
8787
description = "Test image. Source (PD-NASA): [[:File:(Tsander) Large Impact Crater, Lunar Surface.jpg]]";
8888
uploadDest = "Wiki.java test5.jpg";
8989
reason = "Testing upload via URL";
90-
testWiki.upload(new URL("https://upload.wikimedia.org/wikipedia/commons/b/bc/%28Tsander%29_Large_Impact_Crater%2C_Lunar_Surface.jpg"),
90+
testWiki.upload(
91+
new URI("https://upload.wikimedia.org/wikipedia/commons/b/bc/%28Tsander%29_Large_Impact_Crater%2C_Lunar_Surface.jpg").toURL(),
9192
uploadDest, description, reason);
9293
// verify file uploaded is identical to copied image
9394
expected = File.createTempFile("wikijava_upload3", null);
@@ -108,6 +109,40 @@ public void upload() throws Exception
108109
}
109110
}
110111

112+
@Test
113+
public void fileRevert() throws Exception
114+
{
115+
String fname = "File:Wiki.java test6.jpg";
116+
try
117+
{
118+
File expected = File.createTempFile("wikijava_filerevert1", null);
119+
testWiki.upload(
120+
new URI("https://upload.wikimedia.org/wikipedia/commons/b/bc/%28Tsander%29_Large_Impact_Crater%2C_Lunar_Surface.jpg").toURL(),
121+
fname, "testing file reversion", "Test image. Source (PD-NASA): [[:File:(Tsander) Large Impact Crater, Lunar Surface.jpg]]");
122+
testWiki.getImage(fname, expected);
123+
testWiki.upload(new URI("https://upload.wikimedia.org/wikipedia/commons/0/00/PIA21465_-_North_Polar_Layers.jpg").toURL(),
124+
fname, "overwriting", "overwriting");
125+
List<Wiki.LogEntry> le = testWiki.getFileHistory(List.of(fname)).get(0);
126+
String comment = "test file revert";
127+
testWiki.fileRevert(fname, le.get(1), comment);
128+
le = testWiki.getFileHistory(List.of(fname)).get(0);
129+
130+
assertEquals(3, le.size());
131+
Wiki.LogEntry top = le.get(0);
132+
assertEquals(comment, top.getComment());
133+
assertEquals(fname, top.getTitle());
134+
File actual = File.createTempFile("wikijava_filerevert2", null);
135+
testWiki.getImage(fname, actual);
136+
assertArrayEquals(Files.readAllBytes(expected.toPath()),
137+
Files.readAllBytes(actual.toPath()), "file revert: image");
138+
}
139+
finally
140+
{
141+
// Requires admin rights... otherwise find an admin to delete manually.
142+
testWiki.delete(fname, "Test cleanup", false);
143+
}
144+
}
145+
111146
@Test
112147
public void edit() throws Exception
113148
{

test/org/wikipedia/WikiTest.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,33 @@ public void getCategories() throws Exception
433433
}
434434

435435
@Test
436-
public void getImageHistory() throws Exception
436+
public void getFileHistory() throws Exception
437437
{
438-
assertTrue(enWiki.getImageHistory("File:Sdfjgh&sld.jpg").isEmpty(), "non-existent file");
439-
assertTrue(enWiki.getImageHistory("File:WikipediaSignpostIcon.svg").isEmpty(), "commons image");
438+
String fname = "File:Example.svg";
439+
List<String> files = List.of("File:Sdfjgh&sld.jpg", fname);
440+
List<List<Wiki.LogEntry>> fhist = commons.getFileHistory(files);
441+
assertTrue(fhist.get(0).isEmpty(), "non-existent file");
442+
assertTrue(enWiki.getFileHistory(List.of("File:WikipediaSignpostIcon.svg")).get(0).isEmpty(), "commons image");
443+
444+
List<Wiki.LogEntry> example = fhist.get(1);
445+
int size = example.size();
446+
assertNull(example.get(0).getDetails().get("archivename"));
447+
Wiki.LogEntry le = example.get(size - 1);
448+
assertEquals(fname, le.getTitle());
449+
assertEquals("upload", le.getAction());
450+
assertEquals("Nethac DIU", le.getUser());
451+
assertEquals(OffsetDateTime.parse("2006-07-12T21:14:45Z"), le.getTimestamp());
452+
assertEquals("", le.getComment());
453+
assertEquals("20070525200009!Example.svg", le.getDetails().get("archivename"));
454+
le = example.get(size - 2);
455+
assertEquals(fname, le.getTitle());
456+
assertEquals("overwrite", le.getAction());
457+
assertEquals("Gmaxwell", le.getUser());
458+
assertEquals(OffsetDateTime.parse("2007-09-03T23:17:16Z"), le.getTimestamp());
459+
assertEquals("This is a straightforward resize.. the image is being used as an example in enwp [[w:Wikipedia:10" +
460+
"_things_you_did_not_know_about_images_on_Wikipedia]].. but it's a poor example without this change because the " +
461+
"image page image is ''smaller'' than the thumbn", le.getComment());
462+
assertEquals("20080323205329!Example.svg", le.getDetails().get("archivename"));
440463
}
441464

442465
@Test

0 commit comments

Comments
 (0)