nix: Make nix the root
Which means now I'll have to think about real prefixes in commit names.
This commit is contained in:
		
							parent
							
								
									550eed06e0
								
							
						
					
					
						commit
						ee178b7d57
					
				
					 190 changed files with 5 additions and 6 deletions
				
			
		
							
								
								
									
										344
									
								
								unprocessed/config/scripts/melConf
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										344
									
								
								unprocessed/config/scripts/melConf
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,344 @@ | |||
| #!/usr/bin/env python3 | ||||
| 
 | ||||
| """ | ||||
| Meh mail client conf generator for other things | ||||
| """ | ||||
| 
 | ||||
| import configparser | ||||
| import os | ||||
| import sys | ||||
| 
 | ||||
| # TODO Find config file from XDG | ||||
| # TODO Signature file | ||||
| # TODO Write ~/.mail/[mailbox]/color file if required by sth? | ||||
| # TODO Write in .config or .cache /mel | ||||
| # TODO Fix IMAPS with mbsync | ||||
| 
 | ||||
| configPath = os.path.join(os.path.expanduser("~"), ".config", "mel", "accounts.conf") | ||||
| 
 | ||||
| config = configparser.ConfigParser() | ||||
| config.read(configPath) | ||||
| 
 | ||||
| storageFull = os.path.realpath(os.path.expanduser(config["GENERAL"]["storage"])) | ||||
| config["GENERAL"]["storage"] = storageFull | ||||
| 
 | ||||
| SERVER_DEFAULTS = { | ||||
|     "imap": {"port": 143, "starttls": True}, | ||||
|     "smtp": {"port": 587, "starttls": True}, | ||||
| } | ||||
| SERVER_ITEMS = {"host", "port", "user", "pass", "starttls"} | ||||
| ACCOUNT_DEFAULTS = { | ||||
|     "color": "#FFFFFF", | ||||
|     "color16": "0", | ||||
|     # "colormutt": "white", | ||||
|     "inboxfolder": "INBOX", | ||||
|     "archivefolder": "Archive", | ||||
|     "draftsfolder": "Drafts", | ||||
|     "sentfolder": "Sent", | ||||
|     "spamfolder": "Spam", | ||||
|     "trashfolder": "Trash", | ||||
| } | ||||
| 
 | ||||
| # Reading sections | ||||
| accounts = dict() | ||||
| mails = set() | ||||
| 
 | ||||
| for name in config.sections(): | ||||
|     if not name.islower(): | ||||
|         continue | ||||
|     section = config[name] | ||||
| 
 | ||||
|     data = dict() | ||||
|     for server in SERVER_DEFAULTS.keys(): | ||||
|         for item in SERVER_ITEMS: | ||||
|             key = server + item | ||||
|             try: | ||||
|                 val = ( | ||||
|                     section.get(key) | ||||
|                     or section.get(item) | ||||
|                     or SERVER_DEFAULTS[server][item] | ||||
|                 ) | ||||
|             except KeyError: | ||||
|                 raise KeyError("{}.{}".format(name, key)) | ||||
| 
 | ||||
|             if isinstance(val, str): | ||||
|                 if val == "True": | ||||
|                     val = True | ||||
|                 elif val == "False": | ||||
|                     val = False | ||||
|                 elif val.isnumeric(): | ||||
|                     val = int(val) | ||||
|             data[key] = val | ||||
| 
 | ||||
|     for key in section.keys(): | ||||
|         if key in SERVER_ITEMS: | ||||
|             continue | ||||
|         data[key] = section[key] | ||||
| 
 | ||||
|     for k, v in config["DEFAULT"].items(): | ||||
|         if k not in data: | ||||
|             data[k] = v | ||||
| 
 | ||||
|     for k, v in ACCOUNT_DEFAULTS.items(): | ||||
|         if k not in data: | ||||
|             data[k] = v | ||||
| 
 | ||||
|     mails.add(section["from"]) | ||||
|     if "alternatives" in section: | ||||
|         for alt in section["alternatives"].split(";"): | ||||
|             mails.add(alt) | ||||
| 
 | ||||
|     data["account"] = name | ||||
|     data["storage"] = os.path.join(config["GENERAL"]["storage"], name) | ||||
|     data["storageInbox"] = os.path.join(data["storage"], "INBOX") | ||||
|     accounts[name] = data | ||||
| 
 | ||||
| general = dict() | ||||
| section = config["GENERAL"] | ||||
| for key in section.keys(): | ||||
|     general[key] = section[key] | ||||
| general["main"] = accounts[general["main"]] | ||||
| 
 | ||||
| 
 | ||||
| # OfflineIMAP | ||||
| 
 | ||||
| OFFLINEIMAP_BEGIN = """[general] | ||||
| # List of accounts to be synced, separated by a comma. | ||||
| accounts = {} | ||||
| maxsyncaccounts = {} | ||||
| stocktimeout = 60 | ||||
| pythonfile = ~/.config/offlineimap.py | ||||
| 
 | ||||
| [mbnames] | ||||
| enabled = yes | ||||
| filename = ~/.mutt/mailboxes | ||||
| header = "mailboxes " | ||||
| peritem = "+%(accountname)s/%(foldername)s" | ||||
| sep = " " | ||||
| footer = "\\n" | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| OFFLINEIMAP_ACCOUNT = """[Account {account}] | ||||
| localrepository = {account}-local | ||||
| remoterepository = {account}-remote | ||||
| autorefresh = 0.5 | ||||
| quick = 10 | ||||
| utf8foldernames = yes | ||||
| postsynchook = ~/.mutt/postsync | ||||
| 
 | ||||
| [Repository {account}-local] | ||||
| type = Maildir | ||||
| localfolders = {storage} | ||||
| 
 | ||||
| [Repository {account}-remote] | ||||
| type = IMAP | ||||
| {secconf} | ||||
| keepalive = 60 | ||||
| holdconnectionopen = yes | ||||
| remotehost = {imaphost} | ||||
| remoteport = {imapport} | ||||
| remoteuser = {imapuser} | ||||
| remotepass = {imappass} | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| offlineIMAPstr = OFFLINEIMAP_BEGIN.format(",".join(accounts), len(accounts)) | ||||
| for name, account in accounts.items(): | ||||
|     if account["imapstarttls"]: | ||||
|         secconf = "ssl = no" | ||||
|     else: | ||||
|         secconf = "sslcacertfile = /etc/ssl/certs/ca-certificates.crt" | ||||
|     offlineIMAPstr += OFFLINEIMAP_ACCOUNT.format(**account, secconf=secconf) | ||||
| # TODO Write | ||||
| 
 | ||||
| # mbsync | ||||
| MBSYNC_ACCOUNT = """IMAPAccount {account} | ||||
| Host {imaphost} | ||||
| Port {imapport} | ||||
| User {imapuser} | ||||
| Pass "{imappassEscaped}" | ||||
| {secconf} | ||||
| 
 | ||||
| IMAPStore {account}-remote | ||||
| Account {account} | ||||
| 
 | ||||
| MaildirStore {account}-local | ||||
| Subfolders Verbatim | ||||
| Path {storage}/ | ||||
| Inbox {storageInbox}/ | ||||
| 
 | ||||
| Channel {account} | ||||
| Master :{account}-remote: | ||||
| Slave :{account}-local: | ||||
| Patterns * | ||||
| Create Both | ||||
| SyncState * | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| mbsyncStr = "" | ||||
| for name, account in accounts.items(): | ||||
|     if account["imapstarttls"]: | ||||
|         secconf = "SSLType STARTTLS" | ||||
|     else: | ||||
|         secconf = "SSLType IMAPS" | ||||
|     if "certificate" in account: | ||||
|         secconf += "\nCertificateFile {certificate}".format(**account) | ||||
|     imappassEscaped = account["imappass"].replace("\\", "\\\\") | ||||
|     mbsyncStr += MBSYNC_ACCOUNT.format( | ||||
|         **account, secconf=secconf, imappassEscaped=imappassEscaped | ||||
|     ) | ||||
| mbsyncFilepath = os.path.join(os.path.expanduser("~"), ".config/mel/mbsyncrc") | ||||
| with open(mbsyncFilepath, "w") as f: | ||||
|     f.write(mbsyncStr) | ||||
| 
 | ||||
| # msmtp | ||||
| MSMTP_BEGIN = """defaults | ||||
| protocol smtp | ||||
| auth on | ||||
| tls_trust_file /etc/ssl/certs/ca-certificates.crt | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| MSMTP_ACCOUNT = """account {account} | ||||
| from {from} | ||||
| user {smtpuser} | ||||
| password {smtppass} | ||||
| host {smtphost} | ||||
| port {smtpport} | ||||
| tls on | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| msmtpStr = MSMTP_BEGIN | ||||
| for name, account in accounts.items(): | ||||
|     msmtpStr += MSMTP_ACCOUNT.format(**account) | ||||
| mbsyncFilepath = os.path.join(os.path.expanduser("~"), ".config/msmtp/config") | ||||
| with open(mbsyncFilepath, "w") as f: | ||||
|     f.write(msmtpStr) | ||||
| 
 | ||||
| 
 | ||||
| # notmuch | ||||
| NOTMUCH_BEGIN = """[database] | ||||
| path={storage} | ||||
| 
 | ||||
| [user] | ||||
| name={main[name]} | ||||
| primary_email={main[from]} | ||||
| other_email={other_email} | ||||
| 
 | ||||
| [new] | ||||
| tags=unprocessed;unread; | ||||
| ignore= | ||||
| 
 | ||||
| [search] | ||||
| exclude_tags=deleted;spam; | ||||
| 
 | ||||
| [maildir] | ||||
| synchronize_flags=true | ||||
| 
 | ||||
| [crypto] | ||||
| gpg_path=gpg | ||||
| 
 | ||||
| """ | ||||
| 
 | ||||
| other_email = mails.copy() | ||||
| other_email.remove(general["main"]["from"]) | ||||
| other_email = ";".join(other_email) | ||||
| notmuchStr = NOTMUCH_BEGIN.format(**general, other_email=other_email) | ||||
| mbsyncFilepath = os.path.join(os.path.expanduser("~"), ".config/notmuch-config") | ||||
| with open(mbsyncFilepath, "w") as f: | ||||
|     f.write(notmuchStr) | ||||
| 
 | ||||
| # mutt (temp) | ||||
| 
 | ||||
| ## mailboxes | ||||
| MAILBOXES_BEGIN = "mailboxes" | ||||
| 
 | ||||
| mailboxesStr = MAILBOXES_BEGIN | ||||
| for name, account in accounts.items(): | ||||
|     lines = "-" * (20 - len(name)) | ||||
|     mailboxesStr += f' "+{name}{lines}"' | ||||
|     for root, dirs, files in os.walk(account["storage"]): | ||||
|         if "cur" not in dirs or "new" not in dirs or "tmp" not in dirs: | ||||
|             continue | ||||
|         assert root.startswith(storageFull) | ||||
|         path = root[len(storageFull) + 1 :] | ||||
|         mailboxesStr += f' "+{path}"' | ||||
| mailboxesStr += "\n" | ||||
| mailboxesFilepath = os.path.join(os.path.expanduser("~"), ".mutt/mailboxes") | ||||
| with open(mailboxesFilepath, "w") as f: | ||||
|     f.write(mailboxesStr) | ||||
| 
 | ||||
| ## accounts | ||||
| # TODO html mails | ||||
| 
 | ||||
| MUTT_ACCOUNT = """set from = "{from}" | ||||
| set sendmail = "/usr/bin/msmtp -a {account}" | ||||
| set realname = "{name}" | ||||
| set spoolfile = "+{account}/{inboxfolder}" | ||||
| set mbox = "+{account}/{archivefolder}" | ||||
| set postponed = "+{account}/{draftsfolder}" | ||||
| set record = "+{account}/{sentfolder}" | ||||
| set trash = "+{account}/{trashfolder}" | ||||
| set signature = "~/.mutt/accounts/{account}.sig" | ||||
| set content_type = "text/plain" | ||||
| set sig_dashes = yes | ||||
| 
 | ||||
| color status {colormutt} default | ||||
| 
 | ||||
| macro index D \\ | ||||
|     "<clear-flag>N<save-message>+{account}/{trashfolder}<enter>" \\ | ||||
|     "move message to the trash" | ||||
| 
 | ||||
| macro index S \\ | ||||
|     "<clear-flag>N<save-message>+{account}/{spamfolder}<enter>"  \\ | ||||
|     "mark message as spam" | ||||
| # vim: syntax=muttrc | ||||
| """ | ||||
| 
 | ||||
| for name, account in accounts.items(): | ||||
|     muttStr = MUTT_ACCOUNT.format(**account) | ||||
| 
 | ||||
|     # Config | ||||
|     muttFilepath = os.path.join(os.path.expanduser("~"), f".mutt/accounts/{name}") | ||||
|     with open(muttFilepath, "w") as f: | ||||
|         f.write(muttStr) | ||||
| 
 | ||||
|     # Signature | ||||
|     sigStr = account.get("sig", account.get("name", "")) | ||||
|     sigFilepath = os.path.join(os.path.expanduser("~"), f".mutt/accounts/{name}.sig") | ||||
|     with open(sigFilepath, "w") as f: | ||||
|         f.write(sigStr) | ||||
| 
 | ||||
| MUTT_SELECTOR = """ | ||||
| set folder = "{storage}" | ||||
| source ~/.mutt/mailboxes | ||||
| 
 | ||||
| source ~/.mutt/accounts/{main[account]} | ||||
| 
 | ||||
| {hooks} | ||||
| 
 | ||||
| source ~/.mutt/custom | ||||
| 
 | ||||
| # vim: syntax=muttrc | ||||
| """ | ||||
| 
 | ||||
| selectStr = "" | ||||
| hooks = "" | ||||
| for name, account in accounts.items(): | ||||
|     hooks += f"folder-hook {name}/* source ~/.mutt/accounts/{name}\n" | ||||
| selectStr += MUTT_SELECTOR.format(**general, hooks=hooks) | ||||
| selectFilepath = os.path.join(os.path.expanduser("~"), ".mutt/muttrc") | ||||
| with open(selectFilepath, "w") as f: | ||||
|     f.write(selectStr) | ||||
| 
 | ||||
| ## Color | ||||
| for name, account in accounts.items(): | ||||
|     # Config | ||||
|     colorFilepath = os.path.join( | ||||
|         os.path.expanduser("~"), f'{general["storage"]}/{name}/color' | ||||
|     ) | ||||
|     with open(colorFilepath, "w") as f: | ||||
|         f.write(account["color"]) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue