๐Ÿ“ง CLI to deduplicate mails from mail boxes.

Overview

Mail Deduplicate

Command-line tool to deduplicate mails from a set of boxes.

Stable release: Last release Python versions

Development: Unittests status Documentation Status Coverage Status

https://raw.githubusercontent.com/kdeldycke/mail-deduplicate/develop/docs/cli-coloured-header.png

Features

  • Duplicate detection based on cherry-picked and normalized mail headers.
  • Source and deduplicate mails from multiple sources.
  • Reads and writes to mbox, maildir, babyl, mh and mmdf formats.
  • Multiple duplicate selection strategies based on size, content, timestamp, file path or random choice.
  • Copy, move or delete the resulting set of mails after the deduplication.
  • Dry-run mode.
  • Protection against false-positives by checking for size and content differences.

Screenshots

https://raw.githubusercontent.com/kdeldycke/mail-deduplicate/develop/docs/cli-colored-help.png
https://raw.githubusercontent.com/kdeldycke/mail-deduplicate/develop/docs/cli-coloured-run.png

Installation

This package is available on PyPi, so you can install the latest stable release and its dependencies with a simple pip call:

$ pip install mail-deduplicate

Documentation

Docs are hosted on Read the Docs.

Comments
  • [WIP, HELP NEEDED] Fix many issues

    [WIP, HELP NEEDED] Fix many issues

    Hi,

    This started as a fix for #19 , but has grown somewhat.

    So far I have:

    • Fixed memory consumption issues (#8, #19, and probably #3) by storing only mail file names (not whole Message objects) while detecting possible duplicate mails. The Messsage objects are loaded from disk while processing clusters of mail files that have the same hash.
    • Fixed the cmp issue described in #34
    • Attempted to fix several issues with encodings #32 . I have rudimentary fixes forcing decoding of the message lines, but there are still issues. Any help is welcome.
    • Added a progress bar in place of printing a '.' every 100 messages

    Cheers, Kevin

    โœจ enhancement ๐Ÿ› bug 
    opened by kdm9 19
  • Unclear how to install

    Unclear how to install

    Since transitioning from a simple script to a package, it's not at all clear how to use this any more. README.rst is missing any installation instructions, and the usage text begins:

    Usage: __init__.py [OPTIONS] [MAILDIR [MAILDIR ...]]
    

    which is obviously wrong.

    ๐Ÿ“š documentation 
    opened by aspiers 17
  • No deletion: all mail differences within limits

    No deletion: all mail differences within limits

    I am using

    mdedup -C -1 -S -1 -s delete-smaller maildirname

    But I still get "Check that mail differences are within the limits." messages, and nothing is deleted. All duplicates are either ignored or skipped.

    โ”‚ Mails      โ”‚   Metric โ”‚
    โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
    โ”‚ Found      โ”‚      227 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Rejected   โ”‚        0 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Kept       โ”‚      227 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Unique     โ”‚        7 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Duplicates โ”‚      220 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Deleted    โ”‚        0 โ”‚
    โ•˜โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•งโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•›
    โ•’โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•คโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ••
    โ”‚ Duplicate sets                       โ”‚   Metric โ”‚
    โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ชโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ก
    โ”‚ Total                                โ”‚      117 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Ignored                              โ”‚        7 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Skipped                              โ”‚      110 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Rejected (bad encoding)              โ”‚        0 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Rejected (too dissimilar in size)    โ”‚        0 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Rejected (too dissimilar in content) โ”‚        0 โ”‚
    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
    โ”‚ Deduplicated                         โ”‚        0 โ”‚
    

    What might be wrong?

    Is there a way to rename the files rather than delete duplicates?

    Thanks for help.

    Vikas

    ๐Ÿ› bug 
    opened by vikasrawal 15
  • No graceful handling of crashes/further Unicode issues

    No graceful handling of crashes/further Unicode issues

    Hi,

    I've had a number of unhandled exceptions related to all the Unicode issues (#32, #33, #35). I accidentally originally installed the Python 2 version of maildir-deduplicate, and it is better on the Python 3 version, but several of my mails still manage to cause unhandled exceptions.

    These seem to predominantly be mails which have been wrongly encoded - which should have been marked and encoded as UTF, but haven't been. Python does seem to recognize something is off and shift those characters to 0xFFFD, the Unicode Replacement Character, but nevertheless fails with UnicodeEncodeError: 'ascii' codec can't encode character '\ufffd' in position 13: ordinal not in range(128).

    I understand that maildir-deduplicate can't magically know in what particular way a fucked up mail was fucked up and treat the wrong data correctly. That mail was encoded wrongly and that's my problem, not maildir-deduplicate's.

    What's annoying me is the lack of handling on the exception. There are over 4000 mails in that maildir, the vast majority of which are perfectly RFC-compliant, and I can't parse that folder because a handful of mails are screwed and maildir-deduplicate doesn't properly handle it.

    I don't expect the software to magically fix broken input. But if I have 1 broken e-mail out of a thousand, I do expect it to just skip the broken one and do the other 999.

    Unicode-errors are the most common ones, but it's not limited to that: I've also had one run fail on me because of a missing header in a collection:

      File "/usr/local/lib/python3.4/dist-packages/maildir_deduplicate/deduplicate.py", line 355, in get_lines_from_message_body
        header_text, sep, body = message.as_string().partition("\n\n")
      File "/usr/lib/python3.4/email/message.py", line 159, in as_string
        g.flatten(self, unixfrom=unixfrom)
      File "/usr/lib/python3.4/email/generator.py", line 112, in flatten
        self._write(msg)
      File "/usr/lib/python3.4/email/generator.py", line 178, in _write
        self._dispatch(msg)
      File "/usr/lib/python3.4/email/generator.py", line 211, in _dispatch
        meth(msg)
      File "/usr/lib/python3.4/email/generator.py", line 269, in _handle_multipart
        g.flatten(part, unixfrom=False, linesep=self._NL)
      File "/usr/lib/python3.4/email/generator.py", line 112, in flatten
        self._write(msg)
      File "/usr/lib/python3.4/email/generator.py", line 178, in _write
        self._dispatch(msg)
      File "/usr/lib/python3.4/email/generator.py", line 211, in _dispatch
        meth(msg)
      File "/usr/lib/python3.4/email/generator.py", line 269, in _handle_multipart
        g.flatten(part, unixfrom=False, linesep=self._NL)
      File "/usr/lib/python3.4/email/generator.py", line 112, in flatten
        self._write(msg)
      File "/usr/lib/python3.4/email/generator.py", line 186, in _write
        msg.replace_header('content-transfer-encoding', munge_cte[0])
      File "/usr/lib/python3.4/email/message.py", line 559, in replace_header
        raise KeyError(_name)
    KeyError: 'content-transfer-encoding'
    

    The fact that you're using exceptions at all is good. But not handling exceptions is bad, and not handling exceptions in a program designed for batch processing is just wrong.

    I will try to hack something up for my local installation and I will submit a patch if I succeed, but this is ultimately a question of design mentality: You are currently placing the burden of dealing with problematic input on the user. You're essentially saying "this program will work fine...if you made sure those 10000 mails you want to scan are all RFC-compliant in advance!".

    I do believe it would greatly increase the usefulness of this tool if you expected it to fail on some messages and dealt with that gracefully, instead of just crashing back into the terminal in the middle of processing.

    Thank you for your efforts. I haven't actually gotten this tool to work yet, but thanks to your work, I at least have a shot at dealing with these mails. I do appreciate the time you're investing.

    ๐Ÿ› bug 
    opened by EvilRenegade 13
  • Implement *-discarded actions

    Implement *-discarded actions

    Preliminary checks

    Describe the bug

    When running mdedup -a delete-discarded -s select-one ./.MyMailDirFolder I get the follwoing result:

    NotImplementedError: delete-discarded action not implemented yet.

    To reproduce

    Steps to reproduce the behavior:

    1. The full mdedup -a delete-discarded -s select-one ./.MyMailDirFolder CLI invocation you used.

      $ mdedup -a delete-discarded -s select-one ./.MyMailDirFolder
      
    2. The data set leading to the bug. Try to produce here the minimal subset of mails leading to the bug, and add copies of those mails (eventually censored). This effort will help maintainers add this particular edge-case to the set of unittests to prevent future regressions. You can reduce down the issue to a particular deduplicate subset by using the --hash-only parameter.

    Expected behavior

    Duplicated emails being deleted

    Is this an expected behaviour?

    โœจ enhancement 
    opened by vladox 12
  • 'module' object has no attribute 'init'

    'module' object has no attribute 'init'

    # pip3 install --user maildir-deduplicate
    [...]
    Successfully installed boltons-18.0.0 click-6.7 click-log-0.2.1 maildir-deduplicate-2.1.0 progressbar2-3.37.1 python-utils-2.3.0 tabulate-0.8.2
    
    # ~/.local/bin/mdedup --help
    Traceback (most recent call last):
      File "/root/.local/bin/mdedup", line 7, in <module>
        from maildir_deduplicate.cli import cli
      File "/root/.local/lib64/python3.4/site-packages/maildir_deduplicate/cli.py", line 51, in <module>
        @click_log.init(logger)
    AttributeError: 'module' object has no attribute 'init'
    
    # python3 --version
    Python 3.4.6
    # pip3 --version
    pip 9.0.1 from /usr/lib64/python3.4/site-packages (python 3.4)
    

    This is on a funtoo system. Used --user so that dependencies wouldn't collide with package manager.

    ๐Ÿ› bug 
    opened by dgasaway 12
  • AttributeError: Message instance has no attribute 'get_all'

    AttributeError: Message instance has no attribute 'get_all'

    Not having much luck getting this to work:

    Traceback (most recent call last):
      File "/tmp/python/bin/mdedup", line 9, in <module>
        load_entry_point('maildir-deduplicate==1.0.1.dev0', 'console_scripts', 'mdedup')()
      File "/tmp/python/local/lib/python2.7/site-packages/click/core.py", line 700, in __call__
        return self.main(*args, **kwargs)
      File "/tmp/python/local/lib/python2.7/site-packages/click/core.py", line 680, in main
        rv = self.invoke(ctx)
      File "/tmp/python/local/lib/python2.7/site-packages/click/core.py", line 1027, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/tmp/python/local/lib/python2.7/site-packages/click/core.py", line 873, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/tmp/python/local/lib/python2.7/site-packages/click/core.py", line 508, in invoke
        return callback(*args, **kwargs)
      File "/tmp/python/local/lib/python2.7/site-packages/click/decorators.py", line 16, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/tmp/maildir-deduplicate/maildir_deduplicate/cli.py", line 137, in deduplicate
        dedup.add_maildir(maildir)
      File "/tmp/maildir-deduplicate/maildir_deduplicate/deduplicate.py", line 72, in add_maildir
        mail_file, message, self.use_message_id)
      File "/tmp/maildir-deduplicate/maildir_deduplicate/deduplicate.py", line 95, in compute_hash
        canonical_headers_text = cls.canonical_headers(mail_file, message)
      File "/tmp/maildir-deduplicate/maildir_deduplicate/deduplicate.py", line 115, in canonical_headers
        for value in mail.get_all(header):
    AttributeError: Message instance has no attribute 'get_all'
    
    ๐Ÿ› bug 
    opened by brianmay 11
  • Encoding issue

    Encoding issue

    Hi @kdeldycke

    Since the changes we made yesterday I have been able to analyse a bigger set of my maildir. It appears that we missed a few encoding issues. The attached seems to fix them, but checking this on another test-set (specifically a non-English maildir) would be wise.

    Cheers, K

    โœจ enhancement 
    opened by kdm9 10
  • UnicodeDecodeError

    UnicodeDecodeError

    I tried to use mdedup on my maildir with 8276 and got the following error:

    Traceback (most recent call last):
      File "/home/user/bin/mdedup", line 11, in <module>
        sys.exit(cli())
      File "/home/user/.local/lib/python2.7/site-packages/click/core.py", line 716, in __call__
        return self.main(*args, **kwargs)
      File "/home/user/.local/lib/python2.7/site-packages/click/core.py", line 696, in main
        rv = self.invoke(ctx)
      File "/home/user/.local/lib/python2.7/site-packages/click/core.py", line 1060, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/user/.local/lib/python2.7/site-packages/click/core.py", line 889, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/user/.local/lib/python2.7/site-packages/click/core.py", line 534, in invoke
        return callback(*args, **kwargs)
      File "/home/user/.local/lib/python2.7/site-packages/click/decorators.py", line 17, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/home/user/.local/lib/python2.7/site-packages/maildir_deduplicate/cli.py", line 139, in deduplicate
        dedup.add_maildir(maildir)
      File "/home/user/.local/lib/python2.7/site-packages/maildir_deduplicate/deduplicate.py", line 80, in add_maildir
        mail_file, message, self.use_message_id)
      File "/home/user/.local/lib/python2.7/site-packages/maildir_deduplicate/deduplicate.py", line 103, in compute_hash
        canonical_headers_text = cls.canonical_headers(mail_file, message)
      File "/home/user/.local/lib/python2.7/site-packages/maildir_deduplicate/deduplicate.py", line 125, in canonical_headers
        canonical_value = cls.canonical_header_value(header, value)
      File "/home/user/.local/lib/python2.7/site-packages/maildir_deduplicate/deduplicate.py", line 148, in canonical_header_value
        value = re.sub('\s+', ' ', value).strip()
      File "/usr/lib/python2.7/re.py", line 155, in sub
        return _compile(pattern, flags).sub(repl, string, count)
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xdc in position 4: ordinal not in range(128)
    

    Unfortunately I can't identify the message, which causes this error. mdedup -v doesn't show more information. How can I find the problematic message?

    ๐Ÿ› bug 
    opened by scus1 10
  • Crash TypeError: 'NoneType' object has no attribute '__getitem__'

    Crash TypeError: 'NoneType' object has no attribute '__getitem__'

    I am getting a reproducible error:

    I use this command python init.py -o /path-to-my-dir/getmaildir/

    This is the whole output (yes, there are a lot of mails in that dir)

    Processing 460581 mails in /mnt/rraid/COMPRESSED/Backup/Mails/getmaildir .........................Traceback (most recent call last):
      File "__init__.py", line 572, in <module>
        main()
      File "__init__.py", line 516, in main
        duplicates_run(opts, maildir_paths)
      File "__init__.py", line 534, in duplicates_run
        mail_count += collate_folder_by_hash(mails_by_hash, maildir, opts.message_id)
      File "__init__.py", line 287, in collate_folder_by_hash
        mail_hash, header_text = compute_hash_key(mail_file, message, use_message_id)
      File "__init__.py", line 271, in compute_hash_key
        canonical_headers_text = get_canonical_headers(mail_file, message)
      File "__init__.py", line 182, in get_canonical_headers
        canonical_value = get_canonical_header_value(header, value)
      File "__init__.py", line 241, in get_canonical_header_value
        utc_timestamp = email.utils.mktime_tz(parsed)
      File "/usr/lib/python2.7/email/_parseaddr.py", line 154, in mktime_tz
        if data[9] is None:
    TypeError: 'NoneType' object has no attribute '__getitem__'
    

    any ideas?

    (update: the error message)

    ๐Ÿ› bug 
    opened by masgo 10
  • Add Python 3.6 support

    Add Python 3.6 support

    The way I understand it, mail-deduplicate now requires python 3.7 or later. Bionic is on 3.6. Given that it is an LTS release of Ubuntu would it be possible to support python 3.6 as well?

    ๐Ÿ™ help wanted ๐ŸŽ feature request 
    opened by leggewie 9
  • Bump click-extra from 3.5.0 to 3.6.0

    Bump click-extra from 3.5.0 to 3.6.0

    Bumps click-extra from 3.5.0 to 3.6.0.

    Release notes

    Sourced from click-extra's releases.

    v3.6.0

    ๐Ÿ Available on PyPi

    Changelog

    Sourced from click-extra's changelog.

    {gh}3.6.0 (2022-12-28) <compare/v3.5.0...v3.6.0>

    • Add new constants to group platforms by family.
    • Add heuristics to recognize new platforms: IBM AIX, Cygwin, FreeBSD, GNU/Hurd, NetBSD, OpenBSD, Oracle Solaris, SunOS, Windows Subsystem for Linux v1 and v2.
    • Document version option usage.
    • Split version code to its own file and tests.
    • Run tests on Python 3.12-dev.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    ๐Ÿ“ฆ dependencies 
    opened by dependabot[bot] 1
  • Bump coverage from 7.0.0 to 7.0.1

    Bump coverage from 7.0.0 to 7.0.1

    Bumps coverage from 7.0.0 to 7.0.1.

    Changelog

    Sourced from coverage's changelog.

    Version 7.0.1 โ€” 2022-12-23

    • When checking if a file mapping resolved to a file that exists, we weren't considering files in .whl files. This is now fixed, closing issue 1511_.

    • File pattern rules were too strict, forbidding plus signs and curly braces in directory and file names. This is now fixed, closing issue 1513_.

    • Unusual Unicode or control characters in source files could prevent reporting. This is now fixed, closing issue 1512_.

    • The PyPy wheel now installs on PyPy 3.7, 3.8, and 3.9, closing issue 1510_.

    .. _issue 1510: nedbat/coveragepy#1510 .. _issue 1511: nedbat/coveragepy#1511 .. _issue 1512: nedbat/coveragepy#1512 .. _issue 1513: nedbat/coveragepy#1513

    .. _changes_7-0-0:

    Commits
    • c5cda3a docs: releases take a little bit longer now
    • 9d4226e docs: latest sample HTML report
    • 8c77758 docs: prep for 7.0.1
    • da1b282 fix: also look into .whl files for source
    • d327a70 fix: more information when mapping rules aren't working right.
    • 35e249f fix: certain strange characters caused reporting to fail. #1512
    • 152cdc7 fix: don't forbid plus signs in file names. #1513
    • 31513b4 chore: make upgrade
    • 873b059 test: don't run tests on Windows PyPy-3.9
    • 5c5caa2 build: PyPy wheel now installs on 3.7, 3.8, and 3.9. #1510
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    ๐Ÿ“ฆ dependencies 
    opened by dependabot[bot] 1
  • Release v7.1.1

    Release v7.1.1

    Description

    This PR is ready to be merged. The merge event will trigger[^1] the:

    1. creation of a v7.1.1 tag on main branch
    2. build if project based on Poetry, then release to PyPi
    3. publication of a GitHub release

    [^1]: as defined by release.yaml.

    How-to release v7.1.1

    1. click Re-run all jobs from the workflow run, to refresh the release date to today
    2. wait for the re-run to complete and check the result in diff view
    3. click Ready for review button below, to get this PR out of Draft mode
    4. click Rebase and merge button below (โ€ผ๏ธ do not ~Squash and merge~: the auto-tagging job needs the 2 distinct commits in this PR)

    Workflow metadata

    Auto-generated on run #3636851148 by prepare-release job from changelog.yaml workflow.

    ๐Ÿ†™ changelog 
    opened by github-actions[bot] 0
  • Bump minor version to v7.2.0

    Bump minor version to v7.2.0

    Description

    Ready to be merged into main branch, at the discretion of the maintainers, to bump the minor part of the version number.

    To bump version to v7.2.0

    1. click Ready for review button below, to get this PR out of Draft mode
    2. click Rebase and merge button below

    Workflow metadata

    Auto-generated on run #3636851148 by version-increments job from changelog.yaml workflow.

    ๐Ÿ†™ changelog 
    opened by github-actions[bot] 0
  • Bump major version to v8.0.0

    Bump major version to v8.0.0

    Description

    Ready to be merged into main branch, at the discretion of the maintainers, to bump the major part of the version number.

    To bump version to v8.0.0

    1. click Ready for review button below, to get this PR out of Draft mode
    2. click Rebase and merge button below

    Workflow metadata

    Auto-generated on run #3636851148 by version-increments job from changelog.yaml workflow.

    ๐Ÿ†™ changelog 
    opened by github-actions[bot] 0
Releases(v7.1.0)
Owner
Kevin Deldycke
VP, Engineering Manager, Founding Engineer - Billing, Payments & IAM.
Kevin Deldycke
A Discord Mod Mail bot made in python

Fish-Mail The mod mail bot for Fish Hosting Note: You are not allowed to remove the names in the credit command Note: If you want any ideas/commands a

28 Aug 30, 2022
PGP encrypted / multipart templated emails for Django

Created by Stephen McDonald Introduction django-email-extras is a Django reusable app providing the ability to send PGP encrypted and multipart emails

stephenmcd 75 May 14, 2022
Send email in Python conveniently for gmail using yagmail

yagmail -- Yet Another GMAIL/SMTP client For the asynchronous asyncio version, look here: https://github.com/kootenpv/aioyagmail The goal here is to m

Pascal van Kooten 2.4k Dec 31, 2022
Email-osint - Email OSINT tool written in python3

Email-osint - Email OSINT tool written in python3

Surtains 7 Nov 28, 2022
Email pass separator

email-pass-separator hii check out our new tool in kali linux use 'filename ' Dont forget to put inverted comma email:password separator Image Command

Hackers Tech 2 Sep 22, 2021
Use Django admin to manage drip campaign emails using querysets on Django's User model.

Django Drip Drip campaigns are pre-written sets of emails sent to customers or prospects over time. Django Drips lets you use the admin to manage drip

Zapier 630 Nov 16, 2022
A small system for writing via email.

A small system for writing via email.

0 Nov 24, 2021
Python Email Sender (PES) is a program made with Python using smtplib, socket and tkinter.

Python Email Sender (PES) is a program made with Python using smtplib, socket and tkinter. This program was made for sender email to be a gmail account because that's what I used when testing it out,

Zacky2613 1 Aug 26, 2022
ok-mail-helperๆ˜ฏไธ€ไธชๅŸบไบŽimap/smtpๅ่ฎฎ้‚ฎไปถๅฎขๆˆท็ซฏ๏ผŒไฝฟ็”จpython3.xๅผ€ๅ‘

ok-mail-helper ok-mail-helperๆ˜ฏไธ€ไธชๅŸบไบŽimap/smtpๅ่ฎฎ้‚ฎไปถๅฎขๆˆท็ซฏ๏ผŒไฝฟ็”จpython3.xๅผ€ๅ‘๏ผŒๆ”ฏๆŒ้‚ฎไปถๆŽฅๆ”ถๅนถ่งฃๆžใ€้‚ฎไปถๅ‘้€๏ผŒ็”จๆˆทๅฏๅœจ่‡ชๅทฑ็š„้กน็›ฎไธญ็›ดๆŽฅๅผ•ๅ…ฅใ€ๅผ€็ฎฑๅณ็”จ๏ผŒๆˆ–่€…็ป“ๅˆflask็ญ‰webๆก†ๆžถ่ฝปๆพๅšๆˆhttpๆŽฅๅฃไพ›ๅ‰็ซฏ่ฐƒ็”จใ€ๆŠŠ้‚ฎ็ฎฑ็ฎก็†้›†ๆˆๅˆฐ่‡ชๅทฑ็š„็ณป็ปŸไธญ๏ผŒไบฆๅฏ้€š่ฟ‡

xlvchao 1 Feb 08, 2022
This is the mail server that handles responses from the Contact Form

mailserver About This is the mail server that handles responses from the Contact Form Contributors โœจ Thanks goes to these wonderful people (emoji key)

IoLang 3 Jan 03, 2022
Fastapi mail system sending mails(individual, bulk) attachments(individual, bulk)

Fastapi-mail The fastapi-mail simple lightweight mail system, sending emails and attachments(individual && bulk) ๐Ÿ”จ Installation $ pip install fastap

Sabuhi 399 Dec 29, 2022
Email-bomber - Email bomber unlike other email bombers u don't need your gmail email id to use this

Email-bomber - Email bomber unlike other email bombers u don't need your gmail email id to use this

rfeferfefe 82 Dec 17, 2022
Will iterate through a list of emails on an attached csv file and email all of them a message of your choice

Email_Bot Will iterate through a list of emails on an attached csv file and email all of them a message of your choice. Before using, make sure you al

J. Brandon Walker 1 Nov 30, 2021
This library is helpful when creating accounts, it has everything you need for this

AccountGeneratorHelper Library to facilitate accounts generation. Unofficial API for temp email services. Receive SMS from free services. Parsing and

Denis 52 Jan 07, 2023
A package for sending email from your Pyramid application

pyramid_mailer pyramid_mailer is a package for sending email from your Pyramid application. It is compatible with Python 2.7, 3.4, 3.5, 3.6, and 3.7 a

Pylons Project 50 Sep 17, 2022
Mail hosting made simple

Modoboa Modoboa is a mail hosting and management platform including a modern and simplified Web User Interface. It provides useful components such as

Modoboa 2.4k Jan 03, 2023
SMTP checker to check Mail Access via SMTP

SMTP checker to check Mail Access via SMTP with easy usage ! Medusa has been written and tested with Python 3.8. It should run on any OS as long as Python and all dependencies are installed.

h3x0 23 Dec 05, 2022
An API to send emails through python3's smtplib module.

An API to send emails through python3's smtplib module. Just configure your SMTP server credentials and you are ready to send a lot of emails through API, designed to be used as a newsletter service.

Adnan Ahmad 15 Nov 24, 2022
Bulk Email and certificate sending application

demir.ai E-mail services This application allows you to send automatic mass mail and automatic mass certificates to the people in your mailing list, m

Ahmet Furkan DEMIR 16 Nov 01, 2022
A spammer to send mass emails to teachers. (Education Purposes only!)

Securly-Extension-Spammer A spammer to send mass emails to teachers. (Education Purposes only!) Setup Just go a securly blocked page(You can do this b

3 Jan 25, 2022