Added passing through name to number lookup for resolving numbers in exported events.
[qwerkisync] / EventTypes / SMS.cpp
1 /*
2  * Copyright (C) 2011, Jamie Thompson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public
6  * License as published by the Free Software Foundation; either
7  * version 3 of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18
19 #include "SMS.h"
20
21 #include "Attachment.h"
22 #include "DBBackends/RtcomEventLogger.h"
23 #include "EventParsers/VMGEntities/VMessage.h"
24 #include "NumberToNameLookup.h"
25 #include "Settings.h"
26
27 #include <QDateTime>
28 #include <QDir>
29 #include <QFile>
30 #include <QList>
31 #include <QRegExp>
32 #include <QString>
33 #include <QTextStream>
34
35 #include <utime.h>
36
37 #include <rtcom-eventlogger/event.h>
38 #include <rtcom-eventlogger/eventlogger-attach-iter.h>
39
40 using namespace EventTypes;
41
42 const DBBackends::iDBBackend &SMS::DB() const
43 {
44         return DBBackends::RtcomEventLogger(CurrentSettings(), *this);
45 }
46
47 SMS::SMS(const Settings &settings) :
48         m_Settings(settings)
49 {
50 }
51
52 SMS::~SMS()
53 {
54         foreach(QSharedPointer<Attachment> attachment, m_Attachments)
55         {
56                 attachment.clear();
57         }
58 }
59
60 SMS::SMS(const Settings &settings, const RTComElEvent &event, const QList<RTComElAttachment*> attachments) :
61         m_Settings(settings)
62 {
63         Version(2.1);
64         IsRead(event.fld_is_read);
65         Destination(event.fld_outgoing ? SENT : INBOX);
66         Timestamp(QDateTime::fromTime_t(event.fld_start_time).toUTC());
67         Tel(QString::fromUtf8(event.fld_remote_uid));
68         if(Tel().indexOf("0") == 0)
69                 Tel(QString(Tel()).replace(QRegExp("^0"), "+44"));
70         //Contents(QString(event.fld_free_text).replace("\n", QChar(0x2029)));
71         Contents(QString::fromUtf8(event.fld_free_text));
72         if(event.fld_flags != 0)
73         {
74                 qDebug() << "fld_flags: = " << event.fld_flags;
75         }
76         Pending(event.fld_flags & GetFlagValue("RTCOM_EL_FLAG_SMS_PENDING"));
77
78         // We directly access the m_Attachments member variable here rather than the
79         // accessor as the accessor is const
80         if(attachments.count() > 0)
81                 foreach(RTComElAttachment *attachment, attachments)
82                         m_Attachments.append(new Attachment(*attachment));
83 }
84 #include <QDebug>
85 const uint SMS::HashCode() const
86 {
87 //      qDebug() << Timestamp().toUTC().toTime_t() << ", " << qHash(Tel()) << ", " << qHash(Destination()) << ", " << qHash(Contents()) << ", " << Attachments().HashCode();
88
89 //      foreach(QChar c, Contents().toUtf8())
90 //      {
91 //              qDebug() << c.unicode();
92 //      }
93
94         return
95                 Timestamp().toUTC().toTime_t() ^
96                 qHash(Tel()) ^
97                 qHash(Destination()) ^
98                 qHash(Contents()) ^
99                 Attachments().HashCode();
100 }
101
102 RTComElEvent * SMS::toRTComEvent(const NumberToNameLookup &numberToNameLookup) const
103 {
104         QString groupId((Tel().length() < 7 || Tel().indexOf(QRegExp("[:alpha:]+")) > -1)
105                 ? Tel()
106                 : Tel().right(7));
107
108         RTComElEvent *event(rtcom_el_event_new());
109         memset(event, 0, sizeof(RTComElEvent));
110
111         RTCOM_EL_EVENT_SET_FIELD (event, service, g_strdup("RTCOM_EL_SERVICE_SMS"));
112         RTCOM_EL_EVENT_SET_FIELD (event, event_type, g_strdup("RTCOM_EL_EVENTTYPE_SMS_MESSAGE"));
113         RTCOM_EL_EVENT_SET_FIELD (event, storage_time, Timestamp().toUTC().toTime_t());
114         RTCOM_EL_EVENT_SET_FIELD (event, start_time, Timestamp().toUTC().toTime_t());
115         RTCOM_EL_EVENT_SET_FIELD (event, end_time, Timestamp().toUTC().toTime_t());
116         RTCOM_EL_EVENT_SET_FIELD (event, is_read, IsRead() ? 1 : 0);
117         RTCOM_EL_EVENT_SET_FIELD (event, outgoing, Destination() == SMS::SENT ? 1 : 0);
118         RTCOM_EL_EVENT_SET_FIELD (event, local_uid, g_strdup("ring/tel/ring"));
119         //RTCOM_EL_EVENT_SET_FIELD (&event, local_name, g_strdup("<SelfHandle>"));
120         RTCOM_EL_EVENT_SET_FIELD (event, remote_uid, g_strdup(Tel().toUtf8()));
121         //RTCOM_EL_EVENT_SET_FIELD (&event, remote_name, g_strdup(QString::number(numberToNameLookup.ContactDetails().value(Tel()).second).toUtf8()));
122         RTCOM_EL_EVENT_SET_FIELD (event, remote_ebook_uid, g_strdup(QString::number(numberToNameLookup.ContactDetails().value(Tel()).first).toUtf8()));
123         RTCOM_EL_EVENT_SET_FIELD (event, group_uid, g_strdup(groupId.toUtf8()));
124         //RTCOM_EL_EVENT_SET_FIELD (event, free_text, g_strdup(Contents().replace(0x2029, "\n").toUtf8()));
125         RTCOM_EL_EVENT_SET_FIELD (event, free_text, g_strdup(Contents().toUtf8()));
126
127         return event;
128 }
129
130 void SMS::Export(const QString &baseDirectory, const NumberToNameLookup &numberToNameLookup) const
131 {
132         // Build the path and ensure it exists...
133         QString eventFilename(baseDirectory);
134         eventFilename += Destination() == EventTypes::SMS::SENT ? "/Sent/" : "/Inbox/";
135         eventFilename += QString::number(Timestamp().toUTC().date().year()) + "/";
136         QDir().mkpath(eventFilename);
137
138         // ...then build the filename and open it.
139         eventFilename += QString::number(Timestamp().toUTC().toTime_t()) + ".vmg";
140         QFile data(eventFilename);
141         if (data.open(QFile::WriteOnly | QFile::Truncate))
142         {
143                 QTextStream stream(&data);
144
145                 QTextCodec *oldCodec = stream.codec();
146                 stream.setAutoDetectUnicode(false);
147                 stream.setCodec("UTF-16LE");
148
149                 EventParsers::VMGEntities::VMessage writer(CurrentSettings(), NULL, 1.1);
150                 writer.Write(stream, *this, numberToNameLookup);
151 //stream << "Test";
152                 //stream.setCodec(oldCodec);
153                 stream.flush();
154                 data.close();
155
156                 utimbuf fileTimes;
157                 fileTimes.modtime = Timestamp().toUTC().toTime_t();
158                 utime(eventFilename.toAscii(), &fileTimes);
159         }
160 }
161
162 QDebug operator<<(QDebug dbg, SMS& event)
163 {
164         dbg.nospace() << "\tFolder:\t\t" << (event.Destination() == SMS::SENT ? "Sent" : "Inbox") << "\n";
165         dbg.nospace() << "\tTimestamp:\t" << event.Timestamp().toUTC() << "\n";
166         dbg.nospace() << "\tRemote-Tel:\t" << event.Tel() << "\n";
167         //dbg.nospace() << "\tremote-name:\t" << event.fld_remote_name << "\n";
168         dbg.nospace() << "\tIs-read:\t\t" << (event.IsRead() ? "true" : "false") << "\n";
169         dbg.nospace() << "\tContents:\t" << event.Contents() << "\n";
170
171         return dbg;
172 }