--- /dev/null
+# write state file into each slaves mailbox
+SyncState *
+CopyArrivalDate yes
+
+IMAPAccount gmail
+Host imap.gmail.com
+User samir.benmendil@gmail.com
+PassCmd "sed -rn '/imap.gmail.com/ s/.*password (.*)/\\1/p' ~/.netrc"
+SSLType IMAPS
+CertificateFile /etc/ssl/certs/ca-certificates.crt
+
+IMAPStore gmail-remote
+Account gmail
+
+MaildirStore gmail-local
+Path ~/mail/gmail/
+Inbox ~/mail/gmail/inbox/
+SubFolders Verbatim
+
+Channel gmail-default
+Master :gmail-remote:
+Slave :gmail-local:
+Patterns "INBOX"
+
+Channel gmail-youtube
+Master :gmail-remote:
+Slave :gmail-local:
+Patterns "youtube"
+
+Channel gmail-youtube-orig
+Master :gmail-remote:
+Slave :gmail-local:
+Patterns "youtube-orig"
+
+Channel gmail-archive
+Master :gmail-remote:"[Google Mail]/All Mail"
+Slave :gmail-local:"archive"
+
+Channel gmail-drafts
+Master :gmail-remote:"[Google Mail]/Drafts"
+Slave :gmail-local:"drafts"
+
+Channel gmail-sent
+Master :gmail-remote:"[Google Mail]/Sent Mail"
+Slave :gmail-local:"sent"
+
+Channel gmail-spam
+Master :gmail-remote:"[Google Mail]/Spam"
+Slave :gmail-local:"spam"
+
+Channel gmail-flagged
+Master :gmail-remote:"[Google Mail]/Starred"
+Slave :gmail-local:"flagged"
+
+Channel gmail-bin
+Master :gmail-remote:"[Google Mail]/Bin"
+Slave :gmail-local:"bin"
+
+Group gmail
+Channel gmail-default
+Channel gmail-youtube
+Channel gmail-youtube-orig
+Channel gmail-archive
+Channel gmail-drafts
+Channel gmail-sent
+Channel gmail-spam
+Channel gmail-flagged
+Channel gmail-bin
--- /dev/null
+#!/usr/bin/env python3
+
+from datetime import timedelta
+from email import message_from_file
+import re
+import sys
+import youtube_dl
+
+
+FROM = "{uploader} <noreply@youtube.com>"
+SUBJECT = "{title}"
+CONTENT = """\
+{uploader} just uploaded a video
+{title} ({duration})
+
+{webpage_url}
+
+Description
+───────────────────────────────────────────────────────────────────────
+
+{description}
+
+───────────────────────────────────────────────────────────────────────
+
+Manage notifications: https://www.youtube.com/subscription_manager
+"""
+
+
+def parse_file(fd):
+ msg = message_from_file(fd)
+
+ payload = ""
+ if msg.is_multipart():
+ for part in msg.get_payload():
+ if part.get_content_type() != 'text/plain':
+ continue
+ charset = part.get_content_charset()
+ payload = part.get_payload(decode=True).decode(charset)
+ else:
+ payload = msg.get_payload(decode=True).decode(charset)
+
+ url = re.search(r'^https?://www.youtube.com/watch\?v=[\w-]{11}', payload, re.MULTILINE).group()
+ # print(url)
+ with youtube_dl.YoutubeDL({'quiet' : True}) as ytdl:
+ info = ytdl.extract_info(url, download=False, force_generic_extractor=True)
+
+ if info is None:
+ return False
+
+ info['duration'] = timedelta(seconds=info['duration'])
+
+ del msg['From']
+ msg['From'] = FROM.format(**info)
+
+ del msg['Subject']
+ msg['Subject'] = SUBJECT.format(**info)
+
+ msg.set_payload(CONTENT.format(**info))
+
+ return msg
+
+
+if __name__ == "__main__":
+ if len(sys.argv) == 1:
+ msg = parse_file(sys.stdin)
+ else:
+ with open(sys.argv[1], 'r') as fd:
+ msg = parse_file(fd)
+ print(msg)
--- /dev/null
+#!/usr/bin/env bash
+
+dir="$(dirname "${BASH_SOURCE[0]}")"
+config=$dir/config
+
+### pre-sync {{{
+
+### }}}
+
+### sync {{{
+mbsync -c "$config" -a
+errno=$?
+
+if [[ $errno -ne 0 ]]; then
+ echo "mbsync failed, ignoring post-sync commands." >&2
+ exit $errno
+fi
+### }}}
+
+### post-sync {{{
+yt_src_mb=youtube-orig
+yt_dst_mb=youtube
+yt_parser=$dir/parse-mail.py
+maildir=$(sed -nr 's/^Path\s*(.*)$/\1/p' $config)
+
+
+if [[ -z $maildir ]]; then
+ echo "Could not extract 'Path' from 'MaildirStore' in '$config'" >&2
+ exit 1
+fi
+
+# expand tilde
+maildir=${maildir/#~/$HOME}
+
+shopt -s extglob
+shopt -s nullglob
+for mail in "$maildir"/$yt_src_mb/new/* ; do
+ mangled_mail=${mail/$yt_src_mb/$yt_dst_mb}
+ # remove UID for mbsync to regenerate it
+ mangled_mail="${mangled_mail/,U=+([0-9])}"
+
+ echo -n "Parsing new message '$(basename "$mail")'..."
+ $yt_parser <"$mail" >"$mangled_mail"
+
+ if [[ $? -eq 0 ]]; then
+ echo " Success."
+ else
+ echo " Failure! Copying message as is."
+ cp "$mail" "$mangled_mail"
+ fi
+
+ # sync {a,m}time
+ touch --reference "$mail" "$mangled_mail"
+ mv "$mail" "${mail/new/cur}S"
+done
+# resync new yt_dst_mb
+mbsync -c "$config" gmail-$yt_src_mb gmail-$yt_dst_mb
+
+### }}}
+
--- /dev/null
+[Unit]
+Description=Mailbox synchronization service
+After=network.target network-online.target dbus.socket
+
+[Service]
+Type=oneshot
+ExecStart=%h/.config/isync/sync-mail
--- /dev/null
+[Unit]
+Description=Mailbox synchronization timer
+
+[Timer]
+# every 5 minutes
+OnCalendar=*:00/5:00
+Persistent=true
+
+[Install]
+WantedBy=timers.target