Browse Source

merge changes for 'DataBuilder' and Account Management Backend

Noah Vogt 3 years ago
parent
commit
6047475be8

+ 3 - 0
app/build.gradle

@@ -59,6 +59,9 @@ dependencies {
 
     implementation 'com.google.code.gson:gson:2.8.7'
 
+    implementation 'androidx.work:work-runtime:2.6.0'
+
+
     implementation 'androidx.appcompat:appcompat:1.2.0'
     implementation 'com.google.android.material:material:1.3.0'
     implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

+ 0 - 1
app/src/main/AndroidManifest.xml

@@ -22,7 +22,6 @@
             </intent-filter>
         </activity>
         <activity android:name=".SettingsActivity"/>
-        <activity android:name=".data.ReadInMailsActivity"/>
     </application>
 
 </manifest>

+ 43 - 26
app/src/main/java/com/noahvogt/miniprojekt/MainActivity.java

@@ -6,9 +6,11 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.PopupMenu;
 import android.widget.Toast;
 
 import androidx.appcompat.app.AlertDialog;
@@ -18,7 +20,6 @@ import androidx.drawerlayout.widget.DrawerLayout;
 import androidx.fragment.app.DialogFragment;
 
 
-import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
@@ -37,6 +38,7 @@ import androidx.navigation.NavController;
 import androidx.navigation.Navigation;
 import androidx.navigation.ui.AppBarConfiguration;
 import androidx.navigation.ui.NavigationUI;
+import androidx.work.Data;
 
 import com.chaquo.python.Python;
 import com.chaquo.python.android.AndroidPlatform;
@@ -44,7 +46,7 @@ import com.google.android.material.snackbar.Snackbar;
 import com.noahvogt.miniprojekt.data.CustomAdapter;
 import com.noahvogt.miniprojekt.data.EmailViewModel;
 import com.noahvogt.miniprojekt.data.MailFunctions;
-import com.noahvogt.miniprojekt.data.ReadInMailsActivity;
+import com.noahvogt.miniprojekt.workers.DownloadWorker;
 import com.noahvogt.miniprojekt.ui.show.MessageShowFragment;
 import com.noahvogt.miniprojekt.data.BooleanTypeAdapter;
 
@@ -52,20 +54,22 @@ import java.lang.reflect.Type;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
+
 import com.google.gson.Gson;
 
 
 
 import static com.noahvogt.miniprojekt.R.id.drawer_layout;
 
-public class MainActivity extends AppCompatActivity implements View.OnClickListener, CustomAdapter.SelectedMessage {
+public class MainActivity extends AppCompatActivity implements View.OnClickListener, CustomAdapter.SelectedMessage, PopupMenu.OnMenuItemClickListener {
 
     private AppBarConfiguration mAppBarConfiguration;
 
     public static final int NEW_WORD_ACTIVITY_REQUEST_CODE = 1;
+    public static final String emailData = "Email";
+    public static final String passwordData = "Password";
+    public static final String nameData = "Name";
     public static EmailViewModel mEmailViewModel;
     public static RecyclerView recyclerView;
 
@@ -220,6 +224,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     public boolean onCreateOptionsMenu(Menu menu) {
         /* Inflate the menu; this adds items to the action bar if it is present. */
         getMenuInflater().inflate(R.menu.main, menu);
+
         return true;
     }
 
@@ -286,6 +291,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         dialog.show();
     }
 
+    public static MailServerCredentials newMailServerCredentials;
+    public static SharedPreferences.Editor credentialsEditor;
+
     public void createNewEmailDialog(){
         /* define View window */
         AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
@@ -308,7 +316,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         dialog.show();
 
         SharedPreferences.Editor preferencesEditor = preferences.edit();
-        SharedPreferences.Editor credentialsEditor = mailServerCredentials.edit();
+        credentialsEditor = mailServerCredentials.edit();
 
         if (! Python.isStarted()) {
             Python.start(new AndroidPlatform(this));
@@ -325,21 +333,29 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
                 String email = newemail_email.getText().toString();
                 String password = newemail_password.getText().toString();
 
+                Data.Builder builder = new Data.Builder();
+                builder.putString(emailData, email)
+                        .putString(passwordData, password)
+                        .putString(nameData, name);
+
                 if (!MailFunctions.validateEmail(newemail_email) | !MailFunctions.validateName(newemail_name) |
                         !MailFunctions.validatePassword(newemail_password)) {
                     return;
                 }
-
                 /* connect to mail server */
                 showToast("Probe Connection ...");
                 if (MailFunctions.canConnect(MailFunctions.getImapHostFromEmail(email), email, password) == Boolean.TRUE) {
                     showToast("was able to connect");
 
-                    // Intent intent = new Intent(getBaseContext(), ReadInMailsActivity.class);
-                    // intent.putExtra("Email", email);
-                    // intent.putExtra("Password", password);
-                    // startActivity(intent);
-                    // startActivityForResult(intent, MainActivity.NEW_WORD_ACTIVITY_REQUEST_CODE);
+
+                    /*
+                    Intent intent = new Intent(getBaseContext(), DownloadWorker.class);
+                    intent.putExtra("Email", email);
+                    intent.putExtra("Password", password);
+                    startActivity(intent);
+
+                     */
+                    //startActivityForResult(intent, MainActivity.NEW_WORD_ACTIVITY_REQUEST_CODE);
 
                     /* TODO: replace legacy strings down below completely with serialized settings json string */
                     preferencesEditor.putString("name", name);
@@ -360,8 +376,6 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
                     boolean newEmailIsUnique = true;
                     try {
                         for (int i = 0; i < allUsersCredentials.size(); i++) {
-                            System.out.println("User #" + i + 1);
-                            System.out.println(allUsersCredentials.get(i).getUsername());
                             if (allUsersCredentials.get(i).getUsername().equals(email)) {
                                 newEmailIsUnique = false;
                                 break;
@@ -383,21 +397,14 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
                         showToast("Success: added new email account");
                     } else {
                         showToast("Error: cannot add the same email twice");
-                    }
-                } else {
-                    askForChangeMailServerSettingsDialog(name, email, password);
                 }
+            } else {
+                    askForChangeMailServerSettingsDialog(name, email, password);
             }
-        });
+        }});
 
-
-        newemail_cancel_button.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                dialog.dismiss();
-            }
-        });
-    }
+    newemail_cancel_button.setOnClickListener(v -> dialog.dismiss());
+ }
 
 
     /* show debug output in  specific view */
@@ -418,5 +425,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         dialog.show(getSupportFragmentManager(), "tag");
 
     }
+
+    @Override
+    public boolean onMenuItemClick(MenuItem item) {
+        switch (item.getItemId()){
+            case R.id.action_refresh:
+
+                return true;
+        }
+        return false;
+    }
 }
 

+ 3 - 1
app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewHolder.java

@@ -55,13 +55,15 @@ public class EmailViewHolder extends RecyclerView.ViewHolder {
         if (message.length() > 30){
             message = message.substring(0,30) + "...";
         }
-        if (date.length() > 9){
+        /*if (date.length() > 9){
             date = "INVALID";
         }
         if (!isDate(date)){
             date = "INVALID";
         }
 
+         */
+
         fromItemView.setText(from);
         subjectItemView.setText(subject);
         dateItemView.setText(date);

+ 18 - 0
app/src/main/java/com/noahvogt/miniprojekt/data/EmailViewModel.java

@@ -4,15 +4,20 @@ import android.app.Application;
 
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.AndroidViewModel;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
 
 import com.noahvogt.miniprojekt.DataBase.EmailRepository;
 import com.noahvogt.miniprojekt.DataBase.Message;
+import com.noahvogt.miniprojekt.workers.DownloadWorker;
 
 import java.util.List;
 
 public class EmailViewModel extends AndroidViewModel {
 
     private EmailRepository mEmailRepository;
+    private WorkManager mWorkManager;
 
     private LiveData<List<Message>> mDraftMessage;
     private LiveData<List<Message>> mInboxMessage;
@@ -22,6 +27,7 @@ public class EmailViewModel extends AndroidViewModel {
 
     public EmailViewModel(Application application) {
         super(application);
+        mWorkManager = WorkManager.getInstance(application);
         mEmailRepository = new EmailRepository(application);
         mInboxMessage = mEmailRepository.getInboxMessages();
         mDraftMessage = mEmailRepository.getDraftMessages();
@@ -30,6 +36,16 @@ public class EmailViewModel extends AndroidViewModel {
         mSpamMessage = mEmailRepository.getSpamMessage();
     }
 
+    /*requests Worker and applies password, email to it */
+    public void applyDownload(Data data){
+        OneTimeWorkRequest downloadRequest =
+                new OneTimeWorkRequest.Builder(DownloadWorker.class)
+                .setInputData(data)
+                .build();
+
+        mWorkManager.enqueue(downloadRequest);
+    }
+
     public LiveData<List<Message>> getDraftMessage(){
         return mDraftMessage;
     }
@@ -47,4 +63,6 @@ public class EmailViewModel extends AndroidViewModel {
     public void deleteMessage(Message message){mEmailRepository.deleteMessage(message);}
 
     public void updateMessage(int id, String folder){mEmailRepository.updateMessage(id, folder);}
+
+
 }

+ 10 - 1
app/src/main/java/com/noahvogt/miniprojekt/data/MailFunctions.java

@@ -36,6 +36,7 @@ public class MailFunctions {
         return pythonMailFunctions.callAttr("listMailboxes", IMAPConnection).asList();
     }
 
+
     public static String fetchMailsFromBox(PyObject IMAPConnection, String Folder) {
         Python python = Python.getInstance();
         PyObject pythonMailFunctions = python.getModule("mailFunctions");
@@ -62,6 +63,10 @@ public class MailFunctions {
         String topLevelHost = email.substring(email.lastIndexOf("@") + 1);
         if (topLevelHost.endsWith("edubs.ch")) {
             return "teamwork.edubs.ch";
+
+        }else if (topLevelHost.endsWith("yahoo.com")){
+            return "imap.mail.yahoo.com";
+
         } else {
             return "imap." + topLevelHost;
         }
@@ -71,7 +76,11 @@ public class MailFunctions {
         String topLevelHost = email.substring(email.lastIndexOf("@") + 1);
         if (topLevelHost.equals("noahvogt.com")) {
             return "mail.noahvogt.com";
-        } else {
+
+        } else if (topLevelHost.endsWith("yahoo.com")){
+            return "smtp.mail.yahoo.com";
+        }
+        else {
             return "smtp." + topLevelHost;
         }
     }

+ 114 - 0
app/src/main/java/com/noahvogt/miniprojekt/workers/DownloadWorker.java

@@ -0,0 +1,114 @@
+package com.noahvogt.miniprojekt.workers;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+import com.chaquo.python.PyObject;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import com.noahvogt.miniprojekt.DataBase.Message;
+import com.noahvogt.miniprojekt.MailServerCredentials;
+import com.noahvogt.miniprojekt.MainActivity;
+import com.noahvogt.miniprojekt.data.BooleanTypeAdapter;
+import com.noahvogt.miniprojekt.data.MailFunctions;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.noahvogt.miniprojekt.MainActivity.mEmailViewModel;
+import static com.noahvogt.miniprojekt.MainActivity.newMailServerCredentials;
+
+public class DownloadWorker extends Worker {
+
+    public DownloadWorker(
+            @NonNull Context appContext,
+            @NonNull WorkerParameters workerParameters){
+        super(appContext, workerParameters);
+    }
+
+    private static final String TAG = DownloadWorker.class.getSimpleName();
+
+
+    @NonNull
+    @NotNull
+    @Override
+    public Result doWork() {
+            try {
+                String mEmail = getInputData().getString(MainActivity.emailData);
+                String mPassword = getInputData().getString(MainActivity.passwordData);
+                String mName = getInputData().getString(MainActivity.nameData);
+
+                    /*List folders = MailFunctions.listMailboxes(MailFunctions.getIMAPConnection(MailFunctions.getImapHostFromEmail(mEmail), mEmail, mPassword, 993));
+                    System.out.println(folders);
+                    for (int i = 0; i < folders.size(); i++) {
+                        //showToast(folders.get(i).toString());
+                        // TODO: select right folder to store, Synchronization
+                        /*gives list of Message Objects/dictionaries */
+                        /*String messages = MailFunctions.fetchMailsFromBox(
+                                MailFunctions.getIMAPConnection(
+                                        MailFunctions.getImapHostFromEmail(mEmail), mEmail, mPassword, 993),
+                                folders.get(i).toString());
+                        System.out.println(folders.get(i).toString());
+                        System.out.println(messages);
+
+                         */
+
+                /* init custom gson with hook to parse booleans correctly */
+                GsonBuilder gsonBuilder = new GsonBuilder();
+                gsonBuilder.registerTypeAdapter(Boolean.class, new BooleanTypeAdapter());
+                Gson gson = gsonBuilder.create();
+
+                /* safe mail server login credentials */
+                newMailServerCredentials = new MailServerCredentials(
+                        mName, mEmail, mPassword, MailFunctions.getImapHostFromEmail(mEmail), MailFunctions.getSmtpHostFromEmail(mEmail), 993, 587, "");
+                String newCredentialsJson = gson.toJson(newMailServerCredentials);
+                System.out.println(newCredentialsJson);
+                MainActivity.credentialsEditor.putString("data", newCredentialsJson);
+                MainActivity.credentialsEditor.apply();
+
+                /* download all messages from mail server */
+
+                /* read login credentials from SharedPreferences */
+                SharedPreferences credentialsReader = getApplicationContext().getSharedPreferences("UserPreferences", Context.MODE_PRIVATE);
+                String readJsonData = credentialsReader.getString("data", "");
+                MailServerCredentials readMailServerCredentials = gson.fromJson(readJsonData, MailServerCredentials.class);
+
+
+                /* fetch and print draft messages */
+                String fetchedMails = MailFunctions.fetchMailsFromBox(MailFunctions.getIMAPConnection(newMailServerCredentials.getImapHost(),
+                        newMailServerCredentials.getUsername(), newMailServerCredentials.getPassword(), newMailServerCredentials.getImapPort()), "INBOX");
+                System.out.println("Yaaay" + fetchedMails + "\n MAANCBJC");
+
+                /* parse messages in arraylist of Message class and loop through it */
+                Type messageType = new TypeToken<ArrayList<Message>>(){}.getType();
+                ArrayList<Message> messages = gson.fromJson(fetchedMails, messageType);
+                for (int i = 0; i < messages.size(); i++) {
+                    Message message = messages.get(i);
+                    mEmailViewModel.insert(message);
+                    System.out.println("Message #" + i);
+                    System.out.println("Date: " + message.getDate());
+                    System.out.println("Subject: " + message.getSubject());
+                    System.out.println(messages.get(i).toString());
+                }
+
+
+
+
+
+                return Result.success();
+            } catch (Throwable throwable){
+                Log.e(TAG, "Error, downloading Messages", throwable);
+                return Result.failure();
+            }
+
+    }
+}

+ 9 - 9
app/src/main/python/mailFunctions.py

@@ -98,15 +98,15 @@ def verifyNoBytes(messages, output_list):
                 exit()
 
 def fetchMails(connection, inbox):
-    print("###" + inbox + "###")
-    print(type(inbox))
+    #print("###" + inbox + "###")
+    #print(type(inbox))
     try:
         status, messages = connection.select(inbox)
     except:
         return []
 
-    print("status-------\n" + status)
-    print("messages-------\n" + str(messages))
+    #print("status-------\n" + status)
+    #print("messages-------\n" + str(messages))
     # number of top emails to fetch
     #N = 3
     # total number of emails
@@ -123,12 +123,12 @@ def fetchMails(connection, inbox):
 
             msg = email.message_from_bytes(data[0][1])
 
-            print(num)
+            #print(num)
 
             raw_string = email.header.decode_header(msg['Subject'])[0]
-            print("raw_string: " + str(raw_string))
+            #print("raw_string: " + str(raw_string))
             raw_from = email.header.decode_header(msg['From'])
-            print("raw_from" + str(raw_from))
+            #print("raw_from" + str(raw_from))
             try:
                 raw_to = email.header.decode_header(msg['To'])
             except TypeError:
@@ -141,9 +141,9 @@ def fetchMails(connection, inbox):
                 raw_bcc = email.header.decode_header(msg['BCC'])
             except TypeError:
                 raw_bcc = [""]
-            print("raw_to" + str(raw_to))
+            #print("raw_to" + str(raw_to))
             raw_date = email.header.decode_header(msg['Date'])[0]
-            print("raw_to" + str(raw_date))
+            #print("raw_to" + str(raw_date))
 
             raw_msg = str(msg)
 

+ 3 - 0
app/src/main/res/menu/main.xml

@@ -6,4 +6,7 @@
         android:orderInCategory="100"
         android:title="@string/action_settings"
         app:showAsAction="never" />
+    <item
+        android:id="@+id/action_refresh"
+        android:title="@string/action_refresh"/>
 </menu>

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -5,7 +5,9 @@
     <string name="nav_header_title">Max Mustermann</string>
     <string name="nav_header_subtitle">max@mustermann.com</string>
     <string name="nav_header_desc">Navigation header</string>
+
     <string name="action_settings">Settings</string>
+    <string name="action_refresh">Refresh</string>
 
     <string name="drawer_inbox">Inbox</string>
     <string name="drawer_sent">Sent</string>