从 Outlook VCALENDAR ics 事件文件中提取文件附件

问题描述

我收到了一封带有 ics 事件附件的电子邮件,我将其 imported 放入了 Google 日历,但后来发现它丢失了附件。该文件约为 3MB,我可以在 ATTACH 组件中看到一个 base64 编码的 docx 文件

$ cat event.ics | head -n 24
BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN
VERSION:2.0
METHOD:REQUEST
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VTIMEZONE
TZID:Eastern Standard Time
BEGIN:STANDARD
DTSTART:16011104T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010311T020000
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ATTACH;ENCODING=BASE64;VALUE=BINARY;X-FILENAME="Instructions.docx":UEsDBBQABgA
    AAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

如何在 Python 或 Bash 中提取此附件?

解决方法

我发现了一个似乎有效的 icalendar pypi module

apt-get install python3-venv
cd /tmp
python3 -m venv ical
source ./ical/bin/activate

pip install icalendar

python << SCRIPTMARKER
from icalendar import Calendar,Event
import base64
import io

g = open('/tmp/event.ics','rb') # read ics
gcal = Calendar.from_ical(g.read())

for component in gcal.walk():
    print(component.name)
    if component.name == "VEVENT":
        b64 = component.get('attach')
        data = base64.b64decode(b64)
        f = open('/tmp/event.docx','wb') # write binary attachment
        f.write(data)
        print(f)
        f.close()

g.close()
SCRIPTMARKER

# Results after running the above:
VCALENDAR
VTIMEZONE
STANDARD
DAYLIGHT
VEVENT
<_io.BufferedWriter name='/tmp/event.docx'>
VALARM

然后我可以将 event.docx 文件上传到 Google Drive 并在那里打开它。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...