use of edu.stanford.muse.AddressBookManager.Contact in project epadd by ePADD.
the class EmailRenderer method getHTMLForHeader.
/**
* returns a HTML table string for the doc header
*
* @throws IOException
*/
private static StringBuilder getHTMLForHeader(EmailDocument ed, SearchResult searchResult, boolean IA_links, boolean debug) throws IOException {
AddressBook addressBook = searchResult.getArchive().addressBook;
Set<String> contactNames = new LinkedHashSet<>();
Set<String> contactAddresses = new LinkedHashSet<>();
String archiveID = ArchiveReaderWriter.getArchiveIDForArchive(searchResult.getArchive());
// get contact ids from searchResult object.
Set<Integer> highlightContactIds = searchResult.getHLInfoContactIDs().stream().map(Integer::parseInt).collect(Collectors.toSet());
if (highlightContactIds != null)
for (Integer hci : highlightContactIds) {
if (hci == null)
continue;
Contact c = searchResult.getArchive().addressBook.getContact(hci);
if (c == null)
continue;
contactNames.addAll(c.getNames());
contactAddresses.addAll(c.getEmails());
}
// get highlight terms from searchResult object for this document.
Set<String> highlightTerms = searchResult.getHLInfoTerms(ed);
StringBuilder result = new StringBuilder();
// header table
result.append("<table class=\"docheader rounded\">\n");
// + this.folderName + "</td></tr>\n");
if (debug)
result.append("<tr><td>docId: </td><td>" + ed.getUniqueId() + "</td></tr>\n");
result.append(JSPHelper.getHTMLForDate(archiveID, ed.date));
final String style = "<tr><td align=\"right\" class=\"muted\" valign=\"top\">";
// email specific headers
result.append(style + "From: </td><td align=\"left\">");
Address[] addrs = ed.from;
// get ArchiveID
if (addrs != null) {
result.append(formatAddressesAsHTML(archiveID, addrs, addressBook, TEXT_WRAP_WIDTH, highlightTerms, contactNames, contactAddresses));
}
result.append("\n</td></tr>\n");
result.append(style + "To: </td><td align=\"left\">");
addrs = ed.to;
if (addrs != null)
result.append(formatAddressesAsHTML(archiveID, addrs, addressBook, TEXT_WRAP_WIDTH, highlightTerms, contactNames, contactAddresses) + "");
result.append("\n</td></tr>\n");
if (ed.cc != null && ed.cc.length > 0) {
result.append(style + "Cc: </td><td align=\"left\">");
result.append(formatAddressesAsHTML(archiveID, ed.cc, addressBook, TEXT_WRAP_WIDTH, highlightTerms, contactNames, contactAddresses) + "");
result.append("\n</td></tr>\n");
}
if (ed.bcc != null && ed.bcc.length > 0) {
result.append(style + "Bcc: </td><td align=\"left\">");
result.append(formatAddressesAsHTML(archiveID, ed.bcc, addressBook, TEXT_WRAP_WIDTH, highlightTerms, contactNames, contactAddresses) + "");
result.append("\n</td></tr>\n");
}
String x = ed.description;
if (x == null)
x = "<None>";
result.append(style + "Subject: </td>");
// <pre> to escape special chars if any in the subject. max 70 chars in
// one line, otherwise spill to next line
result.append("<td align=\"left\"><b>");
x = DatedDocument.formatStringForMaxCharsPerLine(x, 70).toString();
if (x.endsWith("\n"))
x = x.substring(0, x.length() - 1);
Span[] names = searchResult.getArchive().getAllNamesInDoc(ed, false);
// Contains all entities and id if it is authorised else null
Map<String, Entity> entitiesWithId = new HashMap<>();
// we annotate three specially recognized types
Map<Short, String> recMap = new HashMap<>();
recMap.put(NEType.Type.PERSON.getCode(), "cp");
recMap.put(NEType.Type.PLACE.getCode(), "cl");
recMap.put(NEType.Type.ORGANISATION.getCode(), "co");
Arrays.stream(names).filter(n -> recMap.containsKey(NEType.getCoarseType(n.type).getCode())).forEach(n -> {
Set<String> types = new HashSet<>();
types.add(recMap.get(NEType.getCoarseType(n.type).getCode()));
entitiesWithId.put(n.text, new Entity(n.text, null, types));
});
x = searchResult.getArchive().annotate(x, ed.getDate(), ed.getUniqueId(), searchResult.getRegexToHighlight(), highlightTerms, entitiesWithId, IA_links, false);
result.append(x);
result.append("</b>\n");
result.append("\n</td></tr>\n");
// String messageId = Util.hash (ed.getSignature());
// String messageLink = "(<a href=\"browse?archiveID="+archiveID+"&adv-search=1&uniqueId=" + messageId + "\">Link</a>)";
// result.append ("\n" + style + "ID: " + "</td><td>" + messageId + " " + messageLink + "</td></tr>");
// end docheader table
result.append("</table>\n");
if (ModeConfig.isPublicMode())
return new StringBuilder(Util.maskEmailDomain(result.toString()));
return result;
}
use of edu.stanford.muse.AddressBookManager.Contact in project epadd by ePADD.
the class IndexUtils method computeDetailedFacetsForAttachmentBrowsing.
/*
Compute facet list for attachment browsing screen.
NOTE: We want attachment browsing screen to follow natural behaviour which it was not following so far. For example, if a user wanted to see only pdf files
(and therefore clicked on attachmentType facet as pdf then it is possible that some non-pdf files will also get displayed. It is because the granularity of the
search set is messages not attachments. So if a message has a pdf as well as jpg file as attachments then that message is selected as a results set. And when
displaying the attachments of this set of messages the user will be able to see the jpg file as well.
To get back the natural behavior (that is showing only those types of files in the attachment views which are expected by the user, we need to pass the
requested file types from the front end to all those places in the backend where the attachment set impacts user experience. In this function we compute
the facet details for the set of attachments present in set resultset of messages. However, we need to discount those attachments (although they are present in
the resultset of messages) which were not requested by the user. It will impact 'partitionAttachmentByAttachmentType' and 'partitionAttachmentBySize' methods.
It will not impact other facet computations like partitionAttachmentByPerson, direction or folder (Guess why?) because these attributes are message specific not
attachment specific.
*/
public static Map<String, Collection<DetailedFacetItem>> computeDetailedFacetsForAttachmentBrowsing(Multimap<String, String> request, Collection<Document> docs, Archive archive) {
AddressBook addressBook = archive.addressBook;
Set<String> attachmentExtensionsOfInterest = getAttachmentExtensionsOfInterest(request);
Map<String, Collection<DetailedFacetItem>> facetMap = new LinkedHashMap<>();
if (!ModeConfig.isPublicMode()) {
Map<String, DetailedFacetItem> attachmentTypesMap = partitionAttachmentsByAttachmentType(archive, docs, attachmentExtensionsOfInterest);
facetMap.put("attachment type", attachmentTypesMap.values());
}
Map<String, DetailedFacetItem> attachmentSizeMap = partitionAttachmentsBySize(archive, docs, attachmentExtensionsOfInterest);
facetMap.put("attachment size", attachmentSizeMap.values());
if (addressBook != null) {
// people
Map<Contact, DetailedFacetItem> peopleMap = partitionAttachmentsByPerson(docs, addressBook);
facetMap.put("correspondent", peopleMap.values());
// direction (sender: only one if anything with owner)
Map<String, DetailedFacetItem> directionMap = partitionAttachmentsByDirection(docs, addressBook);
if (// this size can at max be 1 when there is at least one message sent from the owner
directionMap.size() > 0)
facetMap.put("sender", directionMap.values());
}
if (!ModeConfig.isPublicMode()) {
Map<String, DetailedFacetItem> folderNameMap = partitionAttachmentsByFolder(docs);
if (folderNameMap.size() > 0)
facetMap.put("folders", folderNameMap.values());
}
// sort so that in each topic, the heaviest facets are first
for (String s : facetMap.keySet()) {
Collection<DetailedFacetItem> detailedFacets = facetMap.get(s);
List<DetailedFacetItem> list = new ArrayList<>(detailedFacets);
Collections.sort(list);
facetMap.put(s, list);
}
return facetMap;
}
use of edu.stanford.muse.AddressBookManager.Contact in project epadd by ePADD.
the class IndexUtils method partitionDocsByPerson.
/*
* public static Map<String, Collection<FacetItem>>
* computeFacets(Collection<Document> docs, AddressBook addressBook,
* GroupAssigner groupAssigner, Indexer indexer)
* {
* Map<String, Collection<FacetItem>> facetMap = new LinkedHashMap<String,
* Collection<FacetItem>>();
*
* // sentiments
* if (indexer != null)
* {
* List<FacetItem> sentimentItems = new ArrayList<FacetItem>();
*
* // rather brute-force, compute docs for all sentiments and then
* intersect...
* // a better way might be to process the selected messages and see which
* sentiments they reflect
* for (String sentiment: Sentiments.captionToQueryMap.keySet())
* {
* String query = Sentiments.captionToQueryMap.get(sentiment);
* List<Document> docsForTerm = new
* ArrayList<Document>(indexer.docsWithPhrase(query, -1));
* docsForTerm.retainAll(docs);
* String url = "sentiment=" + sentiment;
* sentimentItems.add(new FacetItem(sentiment,
* Sentiments.captionToQueryMap.get(sentiment), docsForTerm.size(), url));
* }
* facetMap.put("Sentiments", sentimentItems);
* }
*
* if (addressBook != null)
* {
* // groups
* if (groupAssigner != null)
* {
* Map<SimilarGroup<String>, FacetItem> groupMap = new
* LinkedHashMap<SimilarGroup<String>, FacetItem>();
* for (Document d: docs)
* {
* if (!(d instanceof EmailDocument))
* continue;
* EmailDocument ed = (EmailDocument) d;
* SimilarGroup<String> g = groupAssigner.getClosestGroup(ed);
* if (g == null)
* continue;
* FacetItem f = groupMap.get(g);
* if (f == null)
* {
* String url = "groupIdx=" + groupAssigner.getClosestGroupIdx(ed);
* groupMap.put(g, new FacetItem(g.name, g.elementsToString(), 1, url));
* }
* else
* f.count++;
* }
*
* facetMap.put("Groups", groupMap.values());
* }
*
* // people
* Map<Contact, FacetItem> peopleMap = new LinkedHashMap<Contact,
* FacetItem>();
* for (Document d: docs)
* {
* if (!(d instanceof EmailDocument))
* continue;
* EmailDocument ed = (EmailDocument) d;
* List<Contact> people = ed.getParticipatingContactsExceptOwn(addressBook);
* for (Contact c: people)
* {
* String s = c.pickBestName();
* FacetItem f = peopleMap.get(c);
* if (f == null)
* {
* String url = "person=" + c.canonicalEmail;
* peopleMap.put(c, new FacetItem(s, c.toTooltip(), 1, url));
* }
* else
* f.count++;
* }
* }
* facetMap.put("People", peopleMap.values());
* }
*
* // can do time also... locations?
*
* return facetMap;
* }
*/
public static Map<Contact, DetailedFacetItem> partitionDocsByPerson(Collection<? extends Document> docs, AddressBook ab) {
Map<Contact, DetailedFacetItem> result = new LinkedHashMap<>();
Map<Contact, Pair<String, String>> tooltip_cache = new LinkedHashMap<>();
for (Document d : docs) {
if (!(d instanceof EmailDocument))
continue;
EmailDocument ed = (EmailDocument) d;
List<Contact> people = ed.getParticipatingContactsExceptOwn(ab);
for (Contact c : people) {
String s = null;
String tooltip = null;
Pair<String, String> p = tooltip_cache.get(c);
if (p != null) {
s = p.getFirst();
tooltip = p.getSecond();
} else {
s = c.pickBestName();
tooltip = c.toTooltip();
if (ModeConfig.isPublicMode()) {
s = Util.maskEmailDomain(s);
tooltip = Util.maskEmailDomain(tooltip);
}
tooltip_cache.put(c, new Pair<>(s, tooltip));
}
DetailedFacetItem f = result.get(c);
if (f == null) {
// String url = "person=" + c.canonicalEmail;
// String url = "contact=" + ab.getContactId(c);
f = new DetailedFacetItem(s, tooltip, "contact", Integer.toString(ab.getContactId(c)));
result.put(c, f);
}
f.addDoc(ed);
}
}
return result;
}
use of edu.stanford.muse.AddressBookManager.Contact in project epadd by ePADD.
the class IndexUtils method selectDocsByPersons.
/**
* returns docs with any/all the given email/names. looks for all aliases of
* the person's name, not just the given one.
* runs through all docs times # given emailOrNames.
*/
private static Set<Document> selectDocsByPersons(AddressBook ab, Collection<EmailDocument> docs, String[] emailOrNames, int[] contactIds) {
Set<Contact> contactSet = new LinkedHashSet<>();
if (emailOrNames != null) {
for (String e : emailOrNames) {
Collection<Contact> contacts = ab.lookupByEmailOrName(e);
if (!Util.nullOrEmpty(contacts))
contactSet.addAll(contacts);
else
log.info("Unknown email/name " + e);
}
}
if (contactIds != null) {
for (int id : contactIds) {
Contact c = ab.getContact(id);
if (c == null)
log.info("Unknown contact ID " + id);
else
contactSet.add(c);
}
}
if (contactSet.isEmpty())
// return an empty list
return new LinkedHashSet<>();
// consider map impl in future where we can go directly from the names to the messages
// currently each call to selectDocsByPerson will go through all docs
Set<Document> docsForThisPerson = IndexUtils.selectDocsByContact(ab, docs, contactSet);
for (Document d : docsForThisPerson) {
if (!d.equals(d))
log.error("doc not itself!");
// if (!docsForThisPerson.contains(d))
// log.error ("Email doc is not good!");
// log.info (d);
}
if (log.isDebugEnabled()) {
StringBuilder sb = new StringBuilder();
for (String s : emailOrNames) sb.append(s + " ");
log.debug(docsForThisPerson.size() + " docs with person: [" + sb + "]");
}
return docsForThisPerson;
}
use of edu.stanford.muse.AddressBookManager.Contact in project epadd by ePADD.
the class IndexUtils method partitionAttachmentsByPerson.
/*
Semantics: Person1 -> Number of attachments in mails where Person1 was a correspondent,
Person2 -> Number of attachments in mails where Person2 was a correspondent.
*/
private static Map<Contact, DetailedFacetItem> partitionAttachmentsByPerson(Collection<? extends Document> docs, AddressBook ab) {
Map<Contact, DetailedFacetItem> result = new LinkedHashMap<>();
Map<Contact, Pair<String, String>> tooltip_cache = new LinkedHashMap<>();
// this index is used to create dummy email doc. Here for each attachment we should create one document
int indexToDifferentiate = 0;
for (Document d : docs) {
if (!(d instanceof EmailDocument))
continue;
EmailDocument ed = (EmailDocument) d;
List<Contact> people = ed.getParticipatingContactsExceptOwn(ab);
for (Contact c : people) {
String s = null;
String tooltip = null;
Pair<String, String> p = tooltip_cache.get(c);
if (p != null) {
s = p.getFirst();
tooltip = p.getSecond();
} else {
s = c.pickBestName();
tooltip = c.toTooltip();
if (ModeConfig.isPublicMode()) {
s = Util.maskEmailDomain(s);
tooltip = Util.maskEmailDomain(tooltip);
}
tooltip_cache.put(c, new Pair<>(s, tooltip));
}
DetailedFacetItem f = result.get(c);
if (f == null) {
// String url = "person=" + c.canonicalEmail;
// String url = "contact=" + ab.getContactId(c);
f = new DetailedFacetItem(s, "Number of attachments sent or received from " + tooltip, "contact", Integer.toString(ab.getContactId(c)));
result.put(c, f);
}
// For each attachment in this mail add a dummy document.
for (Blob attachment : ed.attachments) {
// dfi.addDoc(ed);
// create a dummy doc such that no two docs are same.
EmailDocument edummy = new EmailDocument(ed.id, ed.emailSource, ed.folderName, ed.to, ed.cc, ed.bcc, ed.from, ed.getSubjectWithoutTitle(), ed.messageID + indexToDifferentiate, ed.date);
// add it to f.
f.addDoc(edummy);
indexToDifferentiate++;
}
}
}
return result;
}
Aggregations