<commit_before>/*
qgvdial is a cross platform Google Voice Dialer
Copyright (C) 2009-2014  <NAME>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Contact: <EMAIL>
*/

#include "IMainWindow.h"
#include "Lib.h"
#include "GVNumModel.h"
#include <QDesktopServices>

IMainWindow::IMainWindow(QObject *parent)
: QObject(parent)
, db(this)
, gvApi(true, this)
, oContacts(this)
, oInbox(this)
, oPhones(this)
, oLogUploader(this)
, oVmail(this)
, m_loginTask(NULL)
, m_logMessageMutex(QMutex::Recursive)
, m_mixPanel(this)
{
    qRegisterMetaType<ContactInfo>("ContactInfo");
    connect(&gvApi, SIGNAL(twoStepAuthentication(AsyncTaskToken*)),
            this, SLOT(onTFARequest(AsyncTaskToken*)));

    m_taskTimer.setSingleShot (true);
    m_taskTimer.setInterval (1 * 1000); // 1 second
    connect (&m_taskTimer, SIGNAL(timeout()), this, SLOT(onTaskTimerTimeout()));

    connect(&m_logMessageTimer, SIGNAL(timeout()),
            this, SLOT(onLogMessagesTimer()));
    m_logMessageTimer.setSingleShot (true);
    m_logMessageTimer.start (10);
}//IMainWindow::IMainWindow

void
IMainWindow::init()
{
    connect (qApp, SIGNAL(aboutToQuit()), this, SLOT(onQuit()));
}//IMainWindow::init

void
IMainWindow::onQuit()
{
    m_mixPanel.flushEvents();

    QList<QNetworkCookie> cookies = gvApi.getAllCookies ();
    db.saveCookies (cookies);

    db.deinit ();
}//IMainWindow::onQuit

void
IMainWindow::onInitDone()
{
    QString user, pass;

    do {
        db.init (Lib::ref().getDbDir());
        oContacts.init ();
        m_mixPanel.setToken(MIXPANEL_TOKEN);

        QList<QNetworkCookie> cookies;
        if (db.loadCookies (cookies)) {
            gvApi.setAllCookies (cookies);
        }

        ProxyInfo info;
        if (db.getProxyInfo (info)) {
            gvApi.setProxySettings (info.enableProxy, info.useSystemProxy,
                                    info.server, info.port, info.authRequired,
                                    info.user, info.pass);
            uiUpdateProxySettings(info);
            Q_DEBUG("Updated proxy settings");
        }

        if (db.usernameIsCached () && db.getUserPass (user,pass)) {
            Q_DEBUG("Init done, starting login");
            // Begin login
            beginLogin (user, pass);
        } else {
            Q_DEBUG("Init done, asking for login info");
            // Ask the user for login credentials
            uiRequestLoginDetails();
        }
    } while (0);
}//IMainWindow::onInitDone

void
IMainWindow::beginLogin(QString user, QString pass)
{
    bool ok;
    do {
        if (m_loginTask) {
            Q_WARN("Login is in progress");
            break;
        }

        user = user.trimmed();
        if (user.isEmpty ()) {
            Q_WARN("Empty user name");
            showStatusMessage ("Cannot login: Username is empty", SHOW_10SEC);
            break;
        }

        // If the user doesnt put in the domain, put it in....
        if (!user.contains ('@')) {
            user = user + "@gmail.com";
        }

        uiEnableContactUpdateFrequency (false);
        uiEnableInboxUpdateFrequency (false);

        // Begin logon
        m_loginTask = new AsyncTaskToken(this);
        if (NULL == m_loginTask) {
            Q_WARN("Failed to allocate token");
            break;
        }

        ok = connect(m_loginTask, SIGNAL(completed()),
                     this, SLOT(loginCompleted()));
        Q_ASSERT(ok);
        if (!ok) {
            Q_CRIT("Failed to connect signal");
        }

        m_loginTask->inParams["user"] = user;
        m_loginTask->inParams["pass"] = <PASSWORD>;

        Q_DEBUG(QString("Login using user %1").arg(user));
        startLongTask (LT_Login);

        if (!gvApi.login (m_loginTask)) {
            Q_WARN("Failed to log in");
            break;
        }

        m_user = user;
        m_pass = <PASSWORD>;
        uiSetUserPass(false);
    } while (0);
}//IMainWindow::beginLogin

void
IMainWindow::onTFARequest(AsyncTaskToken *task)
{
    Q_ASSERT(m_loginTask == task);
    Q_DEBUG("TFA required. Ask user for TFA PIN");
    uiRequestTFALoginDetails(task);
}//IMainWindow::onTFARequest

void
IMainWindow::resumeTFAAuth(void *ctx, int pin, bool useAlt)
{
    Q_ASSERT(m_loginTask == ctx);
    if (m_loginTask != ctx) {
        Q_CRIT("Context mismatch!!");
    }

    if (useAlt) {
        gvApi.resumeTFAAltLogin (m_loginTask);
    } else {
        m_loginTask->inParams["user_pin"] = QString::number (pin);
        gvApi.resumeTFALogin (m_loginTask);
    }
}//IMainWindow::resumeTFAAuth

void
IMainWindow::loginCompleted()
{
    AsyncTaskToken *task = (AsyncTaskToken *) QObject::sender ();
    Q_ASSERT(m_loginTask == task);
    m_loginTask = NULL;

    MixPanelEvent mEvent;
    mEvent.distinct_id = m_user;
    mEvent.properties["os"] = Lib::ref().getOsDetails();

    do {
        if (ATTS_SUCCESS == task->status) {
            Q_DEBUG("Login successful");

            mEvent.event = "Login";
            m_mixPanel.addEvent(mEvent);

            db.putUserPass (m_user, m_pass);

            // Begin contacts login
            oContacts.login (m_user);

            QDateTime after;
            db.getLatestInboxEntry (after);<commit_msg>mixpanel: Version<commit_after>/*
qgvdial is a cross platform Google Voice Dialer
Copyright (C) 2009-2014  <NAME>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

Contact: <EMAIL>
*/

#include "IMainWindow.h"
#include "Lib.h"
#include "GVNumModel.h"
#include <QDesktopServices>

IMainWindow::IMainWindow(QObject *parent)
: QObject(parent)
, db(this)
, gvApi(true, this)
, oContacts(this)
, oInbox(this)
, oPhones(this)
, oLogUploader(this)
, oVmail(this)
, m_loginTask(NULL)
, m_logMessageMutex(QMutex::Recursive)
, m_mixPanel(this)
{
    qRegisterMetaType<ContactInfo>("ContactInfo");
    connect(&gvApi, SIGNAL(twoStepAuthentication(AsyncTaskToken*)),
            this, SLOT(onTFARequest(AsyncTaskToken*)));

    m_taskTimer.setSingleShot (true);
    m_taskTimer.setInterval (1 * 1000); // 1 second
    connect (&m_taskTimer, SIGNAL(timeout()), this, SLOT(onTaskTimerTimeout()));

    connect(&m_logMessageTimer, SIGNAL(timeout()),
            this, SLOT(onLogMessagesTimer()));
    m_logMessageTimer.setSingleShot (true);
    m_logMessageTimer.start (10);
}//IMainWindow::IMainWindow

void
IMainWindow::init()
{
    connect (qApp, SIGNAL(aboutToQuit()), this, SLOT(onQuit()));
}//IMainWindow::init

void
IMainWindow::onQuit()
{
    m_mixPanel.flushEvents();

    QList<QNetworkCookie> cookies = gvApi.getAllCookies ();
    db.saveCookies (cookies);

    db.deinit ();
}//IMainWindow::onQuit

void
IMainWindow::onInitDone()
{
    QString user, pass;

    do {
        db.init (Lib::ref().getDbDir());
        oContacts.init ();
        m_mixPanel.setToken(<PASSWORD>);

        QList<QNetworkCookie> cookies;
        if (db.loadCookies (cookies)) {
            gvApi.setAllCookies (cookies);
        }

        ProxyInfo info;
        if (db.getProxyInfo (info)) {
            gvApi.setProxySettings (info.enableProxy, info.useSystemProxy,
                                    info.server, info.port, info.authRequired,
                                    info.user, info.pass);
            uiUpdateProxySettings(info);
            Q_DEBUG("Updated proxy settings");
        }

        if (db.usernameIsCached () && db.getUserPass (user,pass)) {
            Q_DEBUG("Init done, starting login");
            // Begin login
            beginLogin (user, pass);
        } else {
            Q_DEBUG("Init done, asking for login info");
            // Ask the user for login credentials
            uiRequestLoginDetails();
        }
    } while (0);
}//IMainWindow::onInitDone

void
IMainWindow::beginLogin(QString user, QString pass)
{
    bool ok;
    do {
        if (m_loginTask) {
            Q_WARN("Login is in progress");
            break;
        }

        user = user.trimmed();
        if (user.isEmpty ()) {
            Q_WARN("Empty user name");
            showStatusMessage ("Cannot login: Username is empty", SHOW_10SEC);
            break;
        }

        // If the user doesnt put in the domain, put it in....
        if (!user.contains ('@')) {
            user = user + "@<EMAIL>";
        }

        uiEnableContactUpdateFrequency (false);
        uiEnableInboxUpdateFrequency (false);

        // Begin logon
        m_loginTask = new AsyncTaskToken(this);
        if (NULL == m_loginTask) {
            Q_WARN("Failed to allocate token");
            break;
        }

        ok = connect(m_loginTask, SIGNAL(completed()),
                     this, SLOT(loginCompleted()));
        Q_ASSERT(ok);
        if (!ok) {
            Q_CRIT("Failed to connect signal");
        }

        m_loginTask->inParams["user"] = user;
        m_loginTask->inParams["pass"] = <PASSWORD>;

        Q_DEBUG(QString("Login using user %1").arg(user));
        startLongTask (LT_Login);

        if (!gvApi.login (m_loginTask)) {
            Q_WARN("Failed to log in");
            break;
        }

        m_user = user;
        m_pass = <PASSWORD>;
        uiSetUserPass(false);
    } while (0);
}//IMainWindow::beginLogin

void
IMainWindow::onTFARequest(AsyncTaskToken *task)
{
    Q_ASSERT(m_loginTask == task);
    Q_DEBUG("TFA required. Ask user for TFA PIN");
    uiRequestTFALoginDetails(task);
}//IMainWindow::onTFARequest

void
IMainWindow::resumeTFAAuth(void *ctx, int pin, bool useAlt)
{
    Q_ASSERT(m_loginTask == ctx);
    if (m_loginTask != ctx) {
        Q_CRIT("Context mismatch!!");
    }

    if (useAlt) {
        gvApi.resumeTFAAltLogin (m_loginTask);
    } else {
        m_loginTask->inParams["user_pin"] = QString::number (pin);
        gvApi.resumeTFALogin (m_loginTask);
    }
}//IMainWindow::resumeTFAAuth

void
IMainWindow::loginCompleted()
{
    AsyncTaskToken *task = (AsyncTaskToken *) QObject::sender ();
    Q_ASSERT(m_loginTask == task);
    m_loginTask = NULL;

    MixPanelEvent mEvent;
    mEvent.distinct_id = m_user;
    mEvent.distinct_id = mEvent.distinct_id.toLower ();
    mEvent.properties["os"] = Lib::ref().getOsDetails();
    mEvent.properties["version"] = "__QGVDIAL_VERSION__";

    do {
        if (ATTS_SUCCESS == task->status) {
            Q_DEBUG("Login successful");

            mEvent.event = "Login";
            m_mixPanel.addEvent(mEvent);

            db.putUserPass (m_user, m_pass);

            // Begin contacts login
            oContacts.login (m_user);

            QDateTime after;
            db.getLatestInboxEntry (after);
{'fraction_non_alphanumeric': 0.11837425910245554, 'fraction_numerical': 0.005757832345469941, 'mean_word_length': 2.6363916256157633, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2465349', 'n_tokens_mistral': 3738, 'n_tokens_neox': 3616, 'n_words': 882}