package gotnames.web.st;
import gotnames.Utils;
import gotnames.dm.KTrans;
import gotnames.dm.ProfilePicture;
import gotnames.dm.ProfilePictureData;
import gotnames.dm.QueryBuilder;
import gotnames.dm.User;
import gotnames.dm.User.Gender;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.jdo.PersistenceManager;
import org.apache.commons.io.IOUtils;
import com.medallia.spider.Task;
import com.medallia.tiny.CollUtils;
import com.medallia.tiny.Empty;
import com.medallia.tiny.Encoding;
import com.medallia.tiny.Func;
import com.medallia.tiny.Funcs;
import com.medallia.tiny.Strings;
/**
* See {@link DownloadArchiveTask}.
*/
public class UploadArchiveTask extends Task {
@Input interface Params {
byte[] archive();
}
PostAction action(User user, final PersistenceManager pm, Params p) {
if (!user.isAdmin())
return redirectToTask(GuessNamesTask.class);
final Long groupKey = user.getGroupKey();
ZipInputStream zipFile = new ZipInputStream(new ByteArrayInputStream(p.archive()));
ZipEntry ze;
try {
final List<String> msg = Empty.list();
final Map<String, ProfilePictureData> profilePics = Empty.hashMap();
List<String> rows = null;
while ((ze = zipFile.getNextEntry()) != null) {
String fileName = ze.getName();
if ("Users.csv".equals(fileName)) {
rows = CollUtils.tail(Strings.split(IOUtils.toString(zipFile, Encoding.CHARSET_UTF8_NAME), "\n"));
} else {
// profile picture
int lastDot = fileName.lastIndexOf('.');
String fullName = lastDot < 0 ? fileName : fileName.substring(0, lastDot);
try {
final ProfilePictureData profilePicture = ProfilePictureData.getProfilePicture(IOUtils.toByteArray(zipFile));
msg.add("Read profile picture for " + fileName);
profilePics.put(fullName, profilePicture);
} catch (RuntimeException e) {
msg.add("Failed to read profile picture for " + fileName + ": " + e.getMessage());
}
}
}
if (rows == null)
return rawStringUtf8("No 'Users.csv' in zip file");
List<User> users = Funcs.map(rows, new Func<String, User>() {
@Override public User call(String row) {
List<String> cells = Strings.split(row, "\t");
final String firstName = notNull("First name", row, strip(cells.get(0)));
final String lastName = notNull("Last name", row, strip(cells.get(1)));
final String email = notNull("Email", row, strip(cells.get(2)));
final Gender gender = notNull("Gender", row, Gender.parse(strip(cells.get(3))));
final boolean disableEmail = cells.size() > 4 && Boolean.valueOf(strip(cells.get(4)).toLowerCase());
final boolean admin = cells.size() > 5 && Boolean.valueOf(strip(cells.get(5)).toLowerCase());
return new KTrans<User>(pm) {
@Override protected User call() {
User u = QueryBuilder.begin(pm, User.class).getSingleByField("email", email);
if (u == null) {
u = User.newUser(groupKey);
u.setEmail(email);
}
u.setFirstName(firstName);
u.setLastName(lastName);
u.setGender(gender);
u.setDisableEmail(disableEmail);
u.setAdmin(admin);
ProfilePictureData profilePicture = profilePics.get(u.getFullName());
if (profilePicture != null)
u.setProfilePictureInfo(profilePicture);
pm.makePersistent(u);
msg.add("User saved: " + u.getFullName());
return u;
}
}.go();
}
});
for (User u : users) {
// Update profile picture if present
ProfilePicture.saveProfilePicture(u, pm, profilePics.get(u.getFullName()));
}
return rawStringUtf8("OK; updated " + rows.size() + " users\n\n" + Strings.join("\n", msg));
} catch (IOException e) {
return rawStringUtf8("Unable to read ZIP archive: " + e.getMessage());
}
}
private <X> X notNull(String field, Object context, X x) {
return Utils.notNull(x, field + " is required in " + context);
}
private String strip(String str) {
return str.replace("\"", "");
}
}