Skip to content

Commit

Permalink
Using new mail persistence API
Browse files Browse the repository at this point in the history
  • Loading branch information
marigostra committed May 3, 2024
1 parent 32e0b64 commit 23e72d0
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 73 deletions.
7 changes: 3 additions & 4 deletions src/main/java/org/luwrain/app/mail/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.luwrain.app.mail;

import java.io.*;

import org.luwrain.core.*;
import org.luwrain.core.events.*;
import org.luwrain.pim.*;
Expand All @@ -42,16 +44,13 @@ public App()
@Override protected AreaLayout onAppInit()
{
this.hooks = new Hooks(getLuwrain());
Log.debug(LOG_COMPONENT, "before data");
this.data = new Data();
Log.debug(LOG_COMPONENT, "after data");
this.data = new Data(new File(getLuwrain().getFileProperty(Luwrain.PROP_DIR_USERHOME), ".luwrain-defaults.conf"));
this.storing = org.luwrain.pim.Connections.getMailStoring(getLuwrain(), true);
/*
if (storing == null)
return null;
*/
this.conv = new Conv(this);
Log.debug("proba", "before main layout ");
this.mainLayout = new MainLayout(this, data);
Log.debug("proba", "after main layout");
this.startingLayout = new StartingLayout(this);
Expand Down
48 changes: 47 additions & 1 deletion src/main/java/org/luwrain/app/mail/Data.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,30 @@
package org.luwrain.app.mail;

import java.util.*;
import java.io.*;

import org.luwrain.core.*;
import org.luwrain.pim.mail2.persistence.dao.*;
import org.luwrain.pim.mail2.persistence.model.*;
import org.luwrain.pim.mail2.persistence.*;

import static org.luwrain.pim.mail2.FolderProperties.*;
import static org.luwrain.app.mail.App.*;

public final class Data
{
public final FolderDAO folderDAO = MailPersistence.getFolderDAO();
public final MessageDAO messageDAO = MailPersistence.getMessageDAO();
public final AccountDAO accountDAO = MailPersistence.getAccountDAO();
final File userSettingsFile;

Data()
Data(File userSettingsFile)
{
this.userSettingsFile = userSettingsFile;
if (folderDAO.getRoot() == null)
createInitialFolders();
if (accountDAO.getAll().isEmpty() && userSettingsFile != null )
createInitialAccounts();
}

private void createInitialFolders()
Expand Down Expand Up @@ -69,4 +75,44 @@ private void createInitialFolders()
f.setParentFolderId(root.getId());
folderDAO.add(f);
}

private void createInitialAccounts()
{
if (!userSettingsFile.exists())
return;
Log.debug(LOG_COMPONENT, "user settings file is " + userSettingsFile.getAbsolutePath());
try {
final var p = new Properties();
try (final var r = new BufferedReader(new InputStreamReader(new FileInputStream(userSettingsFile), "UTF-8"))) {
p.load(r);
}
final String
pop3Host = p.getProperty("pop3.host"),
pop3Port = p.getProperty("pop3.port"),
pop3Login = p.getProperty("pop3.login"),
pop3Passwd = p.getProperty("pop3.passwd");
if (pop3Host != null && !pop3Host.trim().isEmpty() &&
pop3Login != null && !pop3Login.trim().isEmpty())
{
final var a = new Account();
a.setName("Automatically created from default settings POP3 account on " + pop3Host.trim());
a.setType(Account.Type.POP3);
a.setHost(pop3Host.trim());
a.setPort((pop3Port != null && !pop3Port.trim().isEmpty())?Integer.parseInt(pop3Port.trim()):110);
a.setPasswd(pop3Passwd.trim());
a.setLogin(pop3Login.trim());
a.setEnabled(true);
a.setDefaultAccount(false);
a.setLeaveMessages(true);
a.setTrustedHosts("*");
a.setSsl(true);
accountDAO.add(a);
Log.debug(LOG_COMPONENT, "Added the POP3 account: host=" + a.getHost() + ", login=" + a.getLogin() + ", port=" + a.getPort());
}
}
catch(Exception e)
{
Log.error(LOG_COMPONENT, "unable to load user accounts settings: " + e.getMessage());
}
}
}
49 changes: 29 additions & 20 deletions src/main/java/org/luwrain/app/mail/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@

import java.util.*;
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;

import org.luwrain.core.*;
import org.luwrain.pim.mail.*;
import org.luwrain.pim.mail2.*;
//import org.luwrain.pim.mail2.persistence.model.*;
import org.luwrain.pim.mail.script.*;

import static org.luwrain.script.ScriptUtils.*;
Expand All @@ -35,19 +38,25 @@ final class Hooks
ORGANIZE_SUMMARY = "luwrain.mail.summary.organize";

private final Luwrain luwrain;
Hooks(Luwrain luwrain) { this.luwrain = luwrain; }
private final MailObj mailObj;

List<SummaryItem> organizeSummary(MailMessage[] messages)
Hooks(Luwrain luwrain)
{
Log.debug("proba", "" + messages.length + " messages");
final MessageObj [] hookObjs = new MessageObj[messages.length];
for(int i = 0;i < messages.length;i++)
hookObjs[i] = new MessageObj(messages[i]);
final Object[] args = new Object[]{getArray(hookObjs)};
final Object[] res;
final List<SummaryItem> items = new ArrayList<>();
this.luwrain = luwrain;
this.mailObj = new MailObj(luwrain);
}

List<SummaryItem> organizeSummary(List<Message> messages)
{
final var m = new ArrayList<MessageObj>();
messages.forEach(mm -> m.add(new MessageObj(mm)));
final List<Object> res;
final var items = new ArrayList<SummaryItem>();
try {
res = asArray(provider(luwrain, ORGANIZE_SUMMARY, new Object[]{getArray(hookObjs)}));
res = asListOfNativeObjects(provider(luwrain, ORGANIZE_SUMMARY, new Object[]{
mailObj,
ProxyArray.fromArray((Object[])m.toArray(new MessageObj[m.size()]))
}));
}
catch(RuntimeException e)
{
Expand All @@ -61,31 +70,31 @@ List<SummaryItem> organizeSummary(MailMessage[] messages)
}
for(Object o: res)
{
if (!(o instanceof Value))
continue;
final Value value = (Value)o;
if (value.isString())
if (o instanceof String s)
{
items.add(new SummaryItem(value.asString()));
items.add(new SummaryItem(s));
continue;
}
final MessageObj messageObj = value.asHostObject();
if (messageObj == null)
continue;
items.add(new SummaryItem(messageObj.getMessage()));
if (o instanceof MessageObj mm)
{
items.add(new SummaryItem(mm.getMessage()));
continue;
}
}
return items;
}

void makeReply(MailMessage message)
void makeReply(Message message)
{
/*
try {
chainOfResponsibilityNoExc(luwrain, REPLY, new Object[]{new MessageObj(message)});
}
catch(RuntimeException e)
{
luwrain.crash(e);
}
*/
}

Map<String, MailAccount> server(String mailAddr)
Expand Down
79 changes: 42 additions & 37 deletions src/main/java/org/luwrain/app/mail/MainLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.luwrain.controls.reader.*;
import org.luwrain.pim.*;
import org.luwrain.pim.mail.*;
import org.luwrain.pim.mail2.*;
import org.luwrain.pim.mail.script.*;
import org.luwrain.app.base.*;

Expand Down Expand Up @@ -55,7 +56,7 @@ final class MainLayout extends LayoutBase implements TreeListArea.LeafClickHandl
private final List<SummaryItem> summaryItems = new ArrayList<>();
private boolean showDeleted = false;
private Folder folder = null;
private MailMessage message = null;
private Message message = null;

MainLayout(App app, Data data)
{
Expand Down Expand Up @@ -136,11 +137,11 @@ summaryArea, actions(
action("reply", app.getStrings().actionReply(), HOT_KEY_REPLY, this::actSummaryReply),
action("mark", app.getStrings().actionMarkMessage(), new InputEvent(InputEvent.Special.INSERT), this::actMarkMessage, ()->{
final SummaryItem item = summaryArea.selected();
return item != null && item.message != null && item.message.getState() != MailMessage.State.MARKED;
return item != null && item.message != null && item.message.getMetadata().getState() != MessageMetadata.State.MARKED;
}),
action("unmark", app.getStrings().actionUnmarkMessage(), new InputEvent(InputEvent.Special.INSERT), this::actUnmarkMessage, ()->{
final SummaryItem item = summaryArea.selected();
return item != null && item.message != null && item.message.getState() == MailMessage.State.MARKED;
return item != null && item.message != null && item.message.getMetadata().getState() == MessageMetadata.State.MARKED;
}),
action("delete", app.getStrings().actionDeleteMessage(), new InputEvent(InputEvent.Special.DELETE), this::actDeleteMessage),
action("delete-forever", app.getStrings().actionDeleteMessageForever(), new InputEvent(InputEvent.Special.DELETE, EnumSet.of(InputEvent.Modifiers.CONTROL)), this::actDeleteMessageForever),
Expand All @@ -167,9 +168,15 @@ messageArea, actions(
void updateSummary()
{
this.summaryItems.clear();
if (showDeleted)
this.summaryItems.addAll(app.getHooks().organizeSummary(app.getStoring().getMessages().load(folder))); else
this.summaryItems.addAll(app.getHooks().organizeSummary(app.getStoring().getMessages().load(folder, (m)->{ return m.getState() != MailMessage.State.DELETED; })));
final var mm = data.messageDAO.getByFolderId(folder.getId());
final var m = new ArrayList<Message>();
m.ensureCapacity(mm.size());
mm.forEach(i -> m.add(new Message(i)));
if (!showDeleted)
{

}
this.summaryItems.addAll(app.getHooks().organizeSummary(m));
summaryArea.refresh();
}

Expand All @@ -184,38 +191,35 @@ void updateSummary()

private boolean actNewFolder()
{
/*
final MailFolder opened = foldersArea.opened();
final var opened = foldersArea.opened();
if (opened == null)
return false;
final String name = app.getConv().newFolderName();
if (name == null)
return true;
final int selectedIndex = foldersArea.selectedIndex();
final MailFolder newFolder = new MailFolder();
newFolder.setTitle(name);
app.getStoring().getFolders().save(opened, newFolder, Math.max(selectedIndex, 0));
foldersArea.requery();
foldersArea.refresh();
*/
final var newFolder = new Folder();
newFolder.setName(name);
newFolder.setParentFolderId(opened.getId());
data.folderDAO.add(newFolder);
foldersArea.requery();
foldersArea.refresh();
return true;
}

private boolean actRemoveFolder()
{
/*
final MailFolder opened = foldersArea.opened();
final Folder opened = foldersArea.opened();
if (opened == null)
return false;
final int selectedIndex = foldersArea.selectedIndex();
if (selectedIndex < 0)
return false;
if (!app.getConv().removeFolder())
return true;
app.getStoring().getFolders().remove(opened, selectedIndex);
// app.getStoring().getFolders().remove(opened, selectedIndex);
foldersArea.requery();
foldersArea.refresh();
*/
return true;
}

Expand All @@ -237,13 +241,13 @@ private boolean onFolderProps()

@Override public boolean onListClick(ListArea area, int index, SummaryItem item)
{
final MailMessage message = item.message;
final var message = item.message;
if (message == null)
return false;
if (message.getState() == MailMessage.State.NEW)
if (message.getMetadata().getState() == MessageMetadata.State.NEW)
{
message.setState(MailMessage.State.READ);
app.getStoring().getMessages().update(message);
message.getMetadata().setState(MessageMetadata.State.READ);
data.messageDAO.update(message.getMetadata());
summaryArea.refresh();
}
messageArea.setDocument(createDocForMessage(message, app.getStrings()), 128);
Expand All @@ -257,8 +261,8 @@ private boolean actMarkMessage()
final SummaryItem item = summaryArea.selected();
if (item == null || item.message == null)
return false;
item.message.setState(MailMessage.State.MARKED);
app.getStoring().getMessages().update(item.message);
item.message.getMetadata().setState(MessageMetadata.State.MARKED);
data.messageDAO.update(item.message.getMetadata());
app.setEventResponse(text(Sounds.SELECTED, app.getStrings().messageMarked()));
return true;
}
Expand All @@ -268,8 +272,8 @@ private boolean actUnmarkMessage()
final SummaryItem item = summaryArea.selected();
if (item == null || item.message == null)
return false;
item.message.setState(MailMessage.State.READ);
app.getStoring().getMessages().update(item.message);
item.message.getMetadata().setState(MessageMetadata.State.READ);
data.messageDAO.update(item.message.getMetadata());
app.setEventResponse(text(Sounds.SELECTED, app.getStrings().messageUnmarked()));
return true;
}
Expand All @@ -288,8 +292,8 @@ private boolean actDeleteMessage()
final var item = summaryArea.selected();
if (item == null || item.message == null)
return false;
item.message.setState(MailMessage.State.DELETED);
app.getStoring().getMessages().update(item.message);
item.message.getMetadata().setState(MessageMetadata.State.DELETED);
data.messageDAO.update(item.message.getMetadata());
//FIXME:not delete for showing deleted
summaryItems.remove(item);
summaryArea.refresh();
Expand All @@ -307,35 +311,36 @@ private boolean actDeleteMessageForever()
return false;
if (!app.getConv().deleteMessageForever())
return true;
app.getStoring().getMessages().delete(item.message);
//FIXME:deleting raw message
data.messageDAO.delete(item.message.getMetadata());
updateSummary();
return true;
}


private void announceSummaryMessage(SummaryItem summaryItem)
{
final MailMessage m = summaryItem.message;
final Message m = summaryItem.message;
if (m == null)
return;
if (m.getState() == null)
if (m.getMetadata().getState() == null)
{
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getFrom(), Suggestions.CLICKABLE_LIST_ITEM));
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getMetadata().getFromAddr(), Suggestions.CLICKABLE_LIST_ITEM));
return;
}
switch(m.getState())
switch(m.getMetadata().getState())
{
case NEW:
app.setEventResponse(listItem(Sounds.ATTENTION, m.getFrom(), Suggestions.CLICKABLE_LIST_ITEM));
app.setEventResponse(listItem(Sounds.ATTENTION, m.getMetadata().getFromAddr(), Suggestions.CLICKABLE_LIST_ITEM));
break;
case READ:
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getFrom(), Suggestions.CLICKABLE_LIST_ITEM));
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getMetadata().getFromAddr(), Suggestions.CLICKABLE_LIST_ITEM));
break;
case MARKED:
app.setEventResponse(listItem(Sounds.SELECTED, m.getFrom(), Suggestions.CLICKABLE_LIST_ITEM));
app.setEventResponse(listItem(Sounds.SELECTED, m.getMetadata().getFromAddr(), Suggestions.CLICKABLE_LIST_ITEM));
break;
default:
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getFrom(), Suggestions.CLICKABLE_LIST_ITEM));
app.setEventResponse(listItem(Sounds.LIST_ITEM, m.getMetadata().getFromAddr(), Suggestions.CLICKABLE_LIST_ITEM));
}
}

Expand Down
Loading

0 comments on commit 23e72d0

Please sign in to comment.