]> git.basschouten.com Git - openhab-addons.git/blob
03a03292fd0affa69eef858d4dc62ffeda44aa52
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.mail.internal;
14
15 import static org.openhab.binding.mail.internal.MailBindingConstants.CHANNEL_TYPE_UID_FOLDER_MAILCOUNT;
16
17 import java.util.Properties;
18 import java.util.concurrent.ScheduledFuture;
19 import java.util.concurrent.TimeUnit;
20
21 import javax.mail.Flags;
22 import javax.mail.Folder;
23 import javax.mail.MessagingException;
24 import javax.mail.Session;
25 import javax.mail.Store;
26 import javax.mail.search.FlagTerm;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.openhab.binding.mail.internal.config.POP3IMAPChannelConfig;
31 import org.openhab.binding.mail.internal.config.POP3IMAPConfig;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.thing.Channel;
34 import org.openhab.core.thing.ChannelUID;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingStatus;
37 import org.openhab.core.thing.ThingStatusDetail;
38 import org.openhab.core.thing.binding.BaseThingHandler;
39 import org.openhab.core.types.Command;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * The {@link POP3IMAPHandler} is responsible for handling commands, which are
45  * sent to one of the channels.
46  *
47  * @author Jan N. Klug - Initial contribution
48  */
49 @NonNullByDefault
50 public class POP3IMAPHandler extends BaseThingHandler {
51     private final Logger logger = LoggerFactory.getLogger(POP3IMAPHandler.class);
52
53     private @NonNullByDefault({}) POP3IMAPConfig config;
54     private @Nullable ScheduledFuture<?> refreshTask;
55     private final String baseProtocol;
56     private String protocol = "imap";
57
58     public POP3IMAPHandler(Thing thing) {
59         super(thing);
60         baseProtocol = thing.getThingTypeUID().getId(); // pop3 or imap
61     }
62
63     @Override
64     public void handleCommand(ChannelUID channelUID, Command command) {
65     }
66
67     @Override
68     public void initialize() {
69         config = getConfigAs(POP3IMAPConfig.class);
70
71         protocol = baseProtocol;
72
73         if (config.security == ServerSecurity.SSL) {
74             protocol = protocol.concat("s");
75         }
76
77         if (config.port == 0) {
78             switch (protocol) {
79                 case "imap":
80                     config.port = 143;
81                     break;
82                 case "imaps":
83                     config.port = 993;
84                     break;
85                 case "pop3":
86                     config.port = 110;
87                     break;
88                 case "pop3s":
89                     config.port = 995;
90                     break;
91                 default:
92                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
93                     return;
94             }
95         }
96
97         refreshTask = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refresh, TimeUnit.SECONDS);
98         updateStatus(ThingStatus.ONLINE);
99     }
100
101     @SuppressWarnings("null")
102     @Override
103     public void dispose() {
104         if (refreshTask != null) {
105             if (!refreshTask.isCancelled()) {
106                 refreshTask.cancel(true);
107             }
108         }
109     }
110
111     private void refresh() {
112         Properties props = new Properties();
113         props.setProperty("mail." + baseProtocol + ".starttls.enable", "true");
114         props.setProperty("mail.store.protocol", protocol);
115         Session session = Session.getInstance(props);
116
117         try (Store store = session.getStore()) {
118             store.connect(config.hostname, config.port, config.username, config.password);
119
120             for (Channel channel : thing.getChannels()) {
121                 if (CHANNEL_TYPE_UID_FOLDER_MAILCOUNT.equals(channel.getChannelTypeUID())) {
122                     final POP3IMAPChannelConfig channelConfig = channel.getConfiguration()
123                             .as(POP3IMAPChannelConfig.class);
124                     final String folderName = channelConfig.folder;
125                     if (folderName == null || folderName.isEmpty()) {
126                         logger.info("missing or empty folder name in channel {}", channel.getUID());
127                     } else {
128                         try (Folder mailbox = store.getFolder(folderName)) {
129                             mailbox.open(Folder.READ_ONLY);
130                             if (channelConfig.type == MailCountChannelType.TOTAL) {
131                                 updateState(channel.getUID(), new DecimalType(mailbox.getMessageCount()));
132                             } else {
133                                 updateState(channel.getUID(), new DecimalType(
134                                         mailbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)).length));
135                             }
136                         } catch (MessagingException e) {
137                             throw e;
138                         }
139                     }
140                 }
141             }
142         } catch (MessagingException e) {
143             logger.info("error when trying to refresh IMAP: {}", e.getMessage());
144         }
145     }
146 }