Giter Site home page Giter Site logo

postal's People

Contributors

atomicbird avatar greg3z avatar jeremiegirault avatar jibeex avatar kvap avatar loicwolff avatar mpdifran avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

postal's Issues

Compatibility with ReactiveCocoa 6.0.0 / ReactiveSwift 2.0.0

Hi,

I'd like to use ReactiveCocoa 6.0.0 (using ReactiveSwift 2.0.0) in my application, but found out (by a dependency problem with Result 3.1 vs. 3.2), that Postal uses ReactiveSwift 1.

Is there any chance, that Postal works with ReactiveSwift 2 / ReactiveCocoa 6 / Result 3.2.3 ?

Regards,
Eike

Question: How do you get the message text?

I'm struggling to find the right API to use to retrieve the message body. If I take the raw data from a message part, I can convert it to a String but it has extraneous characters. Is there an API to use to get the contents of a message?

Clean up from Xcode 10.2 changes

As mentioned in the recent XCode 10.2 PR thread: #83 (comment)

  • Result module was removed but is still referenced in Postal.podspec. I don't use pods in my project so I'm not sure what issues this may cause.

  • Postal-iOS framework has 7 swift language-related warnings:

Screen Shot 2019-04-22 at 5 39 00 PM

Emails return bad data

I am reading my emails like this:

func fetch ( forNumber: Int )
{
    pConnector?.fetchLast ( "INBOX", last: UInt(forNumber), flags: [ .headers ], onMessage:
    { email in
        print("Got Message: \(email)");
    }, onComplete:
    { error in
        if let error = error
        {
            print("Error! \(error) ")
        }
    } )
}

However, I get this as a response:

FetchResult(uid: 15430, header: nil, flags: MessageFlag., body: nil, rfc822Size: 0, internalDate: nil, gmailThreadId: nil, gmailMessageId: nil, gmailLabels: nil)

I am new to swift, and am just learning about how this library works so I am probably doing something wrong; Just not quite sure what. I would love to know why this is happening - Thanks

Edit


As you can see, after enabling the logger it does spit out some data. This leads me to believe that there is something wrong with the api/lib.

* 569 FETCH (UID 15430 ENVELOPE ("Mon, 22 Jan 2018 16:33:45 +0000 (GMT)" "The status for your app, Quick Things (1330243459), is now Ready for Sale." (("iTunes Store" NIL "no_reply" "email.apple.com")) (("iTunes Store" NIL "no_reply" "email.apple.com")) (("iTunes Store" NIL "no_reply" "email.apple.com")) ((NIL NIL "z.zoelec2" "gmail.com")) NIL NIL NIL "<[email protected]>") BODY[HEADER.FIELDS (References)] {2}

Carthage build error

error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'Result-iOS' from project 'Result')
error: SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'Result-iOS' from project 'Result')

Please release new version :(

Gmail requiring OAuth2

Looks like Gmail requires using OAuth2, otherwise the user has to set their gmail account to be accessible by "less secure" apps. ...

Certificate error

Whenever I try to connect to any e-mail account, I am getting a certificate error.

error: certificate. The operation couldn’t be completed. (Postal.PostalError error 4.)

How know encode type when I parse content a mail?

I have created a mail app using Postal Framework and my mail server send the message to app with different type data, so how I know a data in body is encode/decode by type?
In my example I don't know data should encode with NSUTF8StringEncoding or NSISO2022JPStringEncoding :(

msg.body?.allParts.forEach({ (singlePart) in
    let meesage = String.init(data: (singlePart.data?.rawData)!, encoding: NSUnicodeStringEncoding)
    if singlePart.mimeType == MimeType.textPlain {
        mailInfo.messageDescription = meesage?.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) ?? ""
    } else if singlePart.mimeType == MimeType.textHtml {
        mailInfo.message = meesage ?? ""
    }
})

Thanks for support!

Circle CI can't find libetpan

Breaks here

❌  /Users/distiller/theios/Pods/Postal/dependencies/module.modulemap:2:12: header 'build/ios/include/libetpan/libetpan.h' not found

    header "build/ios/include/libetpan/libetpan.h"
           ^



❌  /Users/distiller/theios/Pods/Postal/Postal/Address+Parsing.swift:26:8: could not build Objective-C module 'libetpan'

import libetpan
       ^

Any ideas how to fix, it works locally.

Manual Installation

CocoaPods and Carthage are awesome tools and make our life really easier, but there are some devs who still don't know how to use them.

It would be cool to add the Manual installation guide in your README.md. You can take a look at my iOS Readme Template to see how you can do it.

Commandline App | Postal library | postal.connect | I get nothing back (no error or else)

Hello,

I am new in this library and I hope I get help here. I use Swift 5.

When I use the following code I get only "ENDED" but nothing else back in the console. No error message. What I am doing wrong?

A happy New Year to all.

Greetings,
Sven

import Foundation      
import Postal  
    
let postal : Postal = Postal(configuration: Configuration(hostname: "email.none.none", port: 993, login: "[email protected]", password: .plain("test"), connectionType: .tls, checkCertificateEnabled: true, batchSize: 1000, spamFolderName: "junk"))  
    
func getEmail() {  
    let indexset = IndexSet(integer: 1)  
    postal.fetchMessages("INBOX", uids: indexset, flags: [ .headers ], onMessage: { email in  
        print("new email received: \(email)")  
    }, onComplete: { error in  
        if error == error {  
            print("an error occured: \(error)")  
        }  
    })  
}  
    
postal.connect { result in  
    switch result {  
    case .success:  
        getEmail()  
    case .failure(let error):  
        print("error: \(error)")  
    }  
}  
    
print("ENDED")  

0.5.0 (release in Cocoapods) won't compile in Swift 5.1

Hi -

When installing via Cocoapods, the install succeeds, but when I run a build, I get a bunch of compilation errors. Looks like Cocoapods has version 0.5.0, which appears to be a couple years old, and there are 22 commits to master since that release in GitHub.

When I install using the "manual" method, everything compiles smoothly and I can fetch my inbox using the sample code as expected.

Maybe it's time for a release? :)

Optimization of NSIndexSet.enumerate(batchSize: Int)

Problem:
We have to optimize the NSIndexSet.enumerate(batchSize: Int) because of too much complexity in it -> O(n)

Example:
If we try to fetch all emails we would do something like:

let range = NSRange(location: 1, length: Int.max - 1)
let indexSet = NSIndexSet(indexesInRange: range)

var results = [FetchResult]()
try imapSession.fetchMessages("INBOX", set: IMAPIndexes.indexes(indexSet), flags: [ .fullHeaders ]) { _ in }

Current result:
It takes too much time for a provider that have a batchSize == Int.max to create the only one indexset needed for the fetch.

Expected result:
Instant fetch

Possible solution:
We could try to use the Strideable protocol instead or simply optimize inside the method.

English localization deprecation warning

Upon launching a project that includes Postal as a framework, getting the following warning:

Screen Shot 2019-05-07 at 1 18 58 PM

the prompted auto-fix did the following and seems to resolve it:

diff --git a/Postal.xcodeproj/project.pbxproj b/Postal.xcodeproj/project.pbxproj

index c06c1f9..3eed3be 100644
--- a/Postal.xcodeproj/project.pbxproj
+++ b/Postal.xcodeproj/project.pbxproj
@@ -584,10 +584,9 @@
                        };
                        buildConfigurationList = 98DB008F1CEC6983003CAABB /* Build configuration list for PBXProject "Postal" */;
                        compatibilityVersion = "Xcode 3.2";
-                       developmentRegion = English;
+                       developmentRegion = en;
                        hasScannedForEncodings = 0;
                        knownRegions = (
-                               English,
                                en,
                                Base,
                        );

(Creating a new issue since I'm not sure what notifications/visibility a comment in a closed issue gets: #84 (comment))

EDIT: Also a tagged release that's stable for XCode 10.2 wouldn't go amiss.

Is support for push (IDLE) planned?

I was wondering if Postal supports Push (i.e. the user's email server informing an app that uses Postal about new messages). As far as I understand, this is known under the name IDLE (https://tools.ietf.org/html/rfc2177).

I didn't find any traces of it in the examples or in documentation/roadmap, so I thought I would ask how big the interest is in implementing it or if there have been any plans already.

I have also checked libetpan and it seems like it's available there. If implementing it is (in your opinion) uncomplicated enough for me to try it without substantial C experience, I'd love a tip on where to start.

Otherwise, I would greatly appreciate any advice on what other packages I might use for that functionality in a macOS app. I'm writing it in Swift, but wouldn't mind using a package from another language, if the interop works. From what I found, MailCore or libetpan could be my only options, would be interested to find out otherwise.

Thanks for any advice/help and to the contributors for their work.

Memory leaks while fetching last 10 mails

I have simple iOS app which connect to my gmail and get last 10 emails:

private lazy var oauthswift:OAuth2Swift = {
        let tempOauthswift = OAuth2Swift(
            consumerKey:    "MY_SECRET_KEY",
            consumerSecret: "",
            authorizeUrl:   "https://accounts.google.com/o/oauth2/v2/auth",
            accessTokenUrl: "https://accounts.google.com/o/oauth2/token",//!!!!!!!!!!!!!!!!!
            responseType:   "code"
        )
        tempOauthswift.allowMissingStateCheck = true
        return tempOauthswift
    }()
    
    @IBAction func tap(_ sender: Any) {
        oauthswift.authorize(
            withCallbackURL: URL(string: "MY_CALLBACK_URL:/oauth2Callback")!,
            scope: "https://mail.google.com/", state:"",
            success:
            {
                (credential, response, parameters) in
                let configuration = Configuration.gmail(login: "[email protected]", password: .accessToken(credential.oauthToken))
                print(credential.oauthToken)
                let postal = Postal(configuration: configuration)
                postal.connect { result in
                    switch result {
                    case .success:
                        print("success")
                    case .failure(let error):
                        print("error: \(error)")
                    }
                }
                postal.fetchLast("INBOX", last: 10, flags: [.body], onMessage: { (FetchResult) in
                    print(FetchResult)
                }, onComplete: { (PostalError) in
                    print(PostalError
.debugDescription)
                })
        },
            failure:
            { error in
                print("Error: \(error.localizedDescription)")
        })
    } 

My app fetches emails successfully but Instruments shows leaks:
postal_leaks

Any ideas?

Feature request / User Story: read, manipulate and append message

Hi Kevin,

You wrote "If you want new features, please submit an issue and we'll figure out how to implement them as quickly as possible 👍" so here is what I need to do in my application next. Maybe you can help me by implementing it. Meanwhile I'll try to understand how your code works so maybe I can contribute also by expanding the Postal API to cover more/all of the libetpan API. :-)

Here is what I want to do:

"As a developer of a mail app I want to add custom headers to an IMAP message on the server and manipulate flags of an IMAP message in order to add additional information to an IMAP message."

As IMAP servers typically don't support changing an existing message, you have to:

  1. Read the message
  2. Create a new message as a clone of the original message. (Ideal would be to have something like init(messageData:...))
  3. Manipulate the new message (add/change/delete custom headers, flags, etc.)
  4. APPEND the new message in the IMAP server.
  5. Set the deleted flag of the original message
  6. Expunge the folder to delete the original message.

It would be fantastic, if you could help me as I'm stuck (tried this with mailcore2 already, but it didn't work and ) :-) (the current unsolved problem of my workaround for the problem, that there is no init() method for cloning an existing message into a new message in the MessageBuilder is [https://github.com/MailCore/mailcore2/issues/1607])

Sending mail

Why do we skip sending mail functionality?
I do not want to use old Objective C MailCore.
Could not find any alternative for iOS

xpc connection interrupted

hi i'm using this code to retrive some messages from my account

postal.connect(timeout: Postal.defaultTimeout, completion: { [weak self] result in
            switch result {
            case .success:

                let filter = .unread && .from(value: "[email protected]")
                self?.postal.search("INBOX", filter: filter) { result in
                    switch result {
                    case .success(let indexes):
                        self?.postal.fetchMessages("INBOX", uids: indexes, flags: [ .fullHeaders ], onMessage: { message in
                            self?.messages.insert(message, at: 0)
                        }, onComplete: { error in
                            if let error = error {
                                self?.showAlertError("Error Obteniendo los Mensajes", message: (error as NSError).localizedDescription)
                            } else {
                                self?.tableView.reloadData()
                            }
                        })
                    case .failure(let error):
                        self?.showAlertError("Error Obteniendo los Mensajes Filtrados", message: (error as NSError).localizedDescription)
                    }
                }
            case .failure(let error):
                self?.showAlertError("Error de Connección", message: (error as NSError).localizedDescription)
            }
        })
    } 

my questions are, i'm doing something wrong? there is an easy way? what is xpc connection interrupted?, i cant find nothing in google.
I guess, it only matters to have connection to the network by data mobile or wifi, but I wonder, if I am using mobile data for my connection to the network, this influences something..

:-1: linker command failed with exit code 1 (use -v to see invocation)

My project crash with this error code
👎 linker command failed with exit code 1 (use -v to see invocation)

its brand new project with only Postal implemented and 1 function to ''connect''.
Could anybody please help

import UIKit
import Postal

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        postaloTest()
    }
    
    let login = "[email protected]"
    let password = "password123"

    func postaloTest (){
        let postal = Postal(configuration: .icloud(login: login, password: password))
        postal.connect { result in
            switch result {
            case .success:
                print("success")
            case .failure(let error):
                print("error: \(error)")
                
            }
        }
    }

}

Change Postal completion handlers queue

Today we dispatch results on the main thread because we assume that Postal is mostly used for UI purpose which is not necessarily true.

It's just an idea but I think we should remove this behaviour because if we use Postal for processing purpose we may not want Postal to enqueue on the main queue (even if here we are talking about very lightweight messages). Users might want to save some computations from the main-thread before actually displaying something to the UI.

So I would propose to drop this behaviour. As an example NSURLSession doesn't dispatch on the main thread even if the most common usage of it is to display something fetched from internet on the UI. And if we think about it. Postal and NSURLSession do, in a sense, the same kind of work...

As an alternative, we could add an option to the Postal instance or adding a parameter to methods that have a completion handler to let the choice to dispatch results on the main thread or not.

how to parse mail after fetch command

I am able to fetch the mail with header,body. But after fetching the mail how to parse the data?
Following is my code

postal.fetchLast("INBOX", last: 1, flags: [ .headers,.size,.fullHeaders,.body ], onMessage: { message in
    print("new email uid: \(message.uid)")
    print("new email body: \(message.body)")
}

How to parse this data received??

I mean basically how can i parse the mail to display in a viewer.

Gmail OAuth2 error

I've implemented Gmail Outh2 and pass the access token in. It got this error: error: login("Invalid credentials (Failure)")

The namespace Postal conflicts with the class named Postal

If a user want to create a class/struct/enum that as the same name as a public data type in Postal. The compiler will conflict with Postal class name and the Postal module.

e.g.

// Target1:
struct Address {
}

let postalAddress: Postal.Address = ... // Don't compile - try to find a nested type of the class Postal
let targetAddress: Address = ... // Compile but Target.Address

It is a known bug and I thought swift3 would fix this issue but it didn't and it becomes really annoying to whoever want to have a class named Address, or MessageHeader (every public class in Postal) for a complete other purpose...

To fix this I would propose to rename the Postal class for PostalClient. @jeremiegirault WDYT ?

Body: nil

Hi! I’m trying to fetch the email bodies. I have connected and got the headers correct but when I try to fetch the body it says “body: nil” also RFC size is 0.

How can I fetch it correctly? Is it my problem or is it from the API?

Thanks.

How to fetch email body

I am able to fetch message subject but I cannot fetch what's written in thr body of email. Plz help in swift

Not seeing any text/html parts in fetched messages

I'm fetching emails from Gmail, using Postal.

I fetch the last 100 emails, with all flags ([.structure, .size, .flags, .headers, .gmailLabels, .gmailThreadID, .gmailMessageID, .body, .fullHeaders, .headerSubject]), and then iterate over each fetch result's body.allParts and fetch the attachments for each part.

When I do this, I don't ever see any text/html parts, only ever text/plain, but when viewing the raw source of the mail on Gmail, it shows there is a text/html and a text/plain.

My code looks like so:

func fetchMail(in folder: Folder) {
	mailService?.fetchLast(folder.name, last: 100, flags: allFlags, onMessage: { result in
		result.body?.allParts.forEach { part in
			print(part.mimeType) // This always prints "text/plain"
			self.mailService?.fetchAttachments(folder.name, uid: result.uid, partId: part.id, onAttachment: { mailData in
				if let data = Data(base64Encoded: mailData.decodedData, options: .ignoreUnknownCharacters) {
					let content = String(data: data, encoding: .utf8)
					print(content) // this is always a plain text representation
				} else {
					let content = String(data: mailData.decodedData, encoding: .utf8)
					print(content) // this is always a plain text representation
				}
			}, onComplete: { error in
				if let error = error {
					print("Error fetching attachment: \(error)")
				}
			})
		}
	}, onComplete: { error in
		if let error = error {
			print("error fetching email in \(folder.name): \(error)")
			return
		}
	})
}

An example of the log when I'm testing this is as follows:

text/plain
Optional("D4Test was granted access to your Google account\r\n\r\n\r\[email protected]\r\n\r\nIf you did not grant access, you should check this activity and secure your\r\naccount.\r\nCheck activity\r\n<https://accounts.google.com/[email protected]&continue=https://myaccount.google.com/alert/nt/1570456286000?rfn%3D127%26rfnc%3D1%26eid%3D650020303090366957%26et%3D0%26anexp%3Dgivab-fa--mdv2-fa>\r\nYou received this email to let you know about important changes to your\r\nGoogle Account and services.\r\n© 2019 Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA\r\n")

But when I check the source of the email via the Gmail website it shows two parts of the email, one text/plain, which is the plain text encoded as bas64, and the other text/html, but the html part does not appear in the parts in the Postal response.

postal.logger statement doesn't compile

Hi klevefre,

you wrote about debugging Postal:

You can set a closure on a Postal instance to have IMAP logs:
let postal = Postal(configuration: ...)
postal.logger { log in
print(log)
}

Unfortunately this doesn't work in my code.
I get the compiler error message "Cannot call value of non-function type 'logger?'

This is my code:

init(hostname: String, userName: String, password: String) {
    log.debug("init called...")
    
    configuration = Configuration(hostname: hostname, port: 993, login: userName, password: .plain(password), connectionType: .tls, checkCertificateEnabled: false)
    
    let postal: Postal = Postal(configuration: configuration)
    postal.logger { log in
        print(log)
    }
[...]

What's wrong with my code? It's exactly as you wrote...?

fetchLast and fetchMessages never return...

I try to access my IMAP server with this code, which is based on your demo code:

`

import Foundation
import Postal

class MailManagerPostal {
    var configuration: Configuration!
    
    fileprivate lazy var postal: Postal = Postal(configuration: self.configuration)
    fileprivate var messages: [FetchResult] = []
    
    init(hostname: String, userName: String, password: String) {
        log.debug("init called...")
        
        configuration = Configuration(hostname: hostname, port: 993, login: userName, password: .plain(password), connectionType: .tls, checkCertificateEnabled: false)

        log.debug("configuration created: \(self.configuration.description)")
        
        postal.connect(timeout: Postal.defaultTimeout, completion: { [weak self] result in
            log.debug("postal.connect completed.")
            switch result {
            case .success:
                log.debug("fetching messages now.")
                
                let indexset = IndexSet(0...100000)
                
                self?.postal.fetchMessages("INBOX", uids: indexset, flags: [ .fullHeaders ], onMessage: { message in
                    log.debug("message : \(message.header)")
                    self?.messages.insert(message, at: 0)
                }, onComplete: { error in
                    if let error = error {
                        log.error("fetch failed: \((error as NSError).localizedDescription)")
                    } else {
                        log.debug("connection successful")
                    }
                    log.debug("fetch complete.")
                })
                
            case .failure(let error):
                log.error("connection failed: \((error as NSError).localizedDescription)")
            }
        })
        log.debug("init finished.")
    }
}

`

Problem: The last message I see is "fetching messages now.". Then nothing happens any more. What's happening here? Where is my mistake? The credentials I use work with using mailcode2 without a problem.

Some more questions:

  • How can I debug the IMAP requests?
  • Where can I find a documentation of the API?
  • Can I manipulate message, especially add custom headers to a message (or take a message, add custom headers, write it as a new message to the server and delete the old one...)?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.