fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
105
.venv/lib/python3.9/site-packages/icalendar/cli.py
Executable file
105
.venv/lib/python3.9/site-packages/icalendar/cli.py
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
"""utility program that allows user to preview calendar's events"""
|
||||
|
||||
import sys
|
||||
import pathlib
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
|
||||
from icalendar import Calendar, __version__
|
||||
|
||||
|
||||
def _format_name(address):
|
||||
"""Retrieve the e-mail and the name from an address.
|
||||
|
||||
:arg an address object, e.g. mailto:test@test.test
|
||||
|
||||
:returns str: The name and the e-mail address.
|
||||
"""
|
||||
email = address.split(":")[-1]
|
||||
name = email.split("@")[0]
|
||||
if not email:
|
||||
return ""
|
||||
return f"{name} <{email}>"
|
||||
|
||||
|
||||
def _format_attendees(attendees):
|
||||
"""Format the list of attendees.
|
||||
|
||||
:arg any attendees: Either a list, a string or a vCalAddress object.
|
||||
|
||||
:returns str: Formatted list of attendees.
|
||||
"""
|
||||
if isinstance(attendees, str):
|
||||
attendees = [attendees]
|
||||
return "\n".join(map(lambda s: s.rjust(len(s) + 5), map(_format_name, attendees)))
|
||||
|
||||
|
||||
def view(event):
|
||||
"""Make a human readable summary of an iCalendar file.
|
||||
|
||||
:returns str: Human readable summary.
|
||||
"""
|
||||
summary = event.get("summary", default="")
|
||||
organizer = _format_name(event.get("organizer", default=""))
|
||||
attendees = _format_attendees(event.get("attendee", default=[]))
|
||||
location = event.get("location", default="")
|
||||
comment = event.get("comment", "")
|
||||
description = event.get("description", "").split("\n")
|
||||
description = "\n".join(map(lambda s: s.rjust(len(s) + 5), description))
|
||||
|
||||
start = event.decoded("dtstart")
|
||||
if "duration" in event:
|
||||
end = event.decoded("dtend", default=start + event.decoded("duration"))
|
||||
else:
|
||||
end = event.decoded("dtend", default=start)
|
||||
duration = event.decoded("duration", default=end - start)
|
||||
if isinstance(start, datetime):
|
||||
start = start.astimezone()
|
||||
start = start.strftime("%c")
|
||||
if isinstance(end, datetime):
|
||||
end = end.astimezone()
|
||||
end = end.strftime("%c")
|
||||
|
||||
return f""" Organizer: {organizer}
|
||||
Attendees:
|
||||
{attendees}
|
||||
Summary : {summary}
|
||||
Starts : {start}
|
||||
End : {end}
|
||||
Duration : {duration}
|
||||
Location : {location}
|
||||
Comment : {comment}
|
||||
Description:
|
||||
{description}"""
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("calendar_files", nargs="+", type=pathlib.Path)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
"-o",
|
||||
type=argparse.FileType("w"),
|
||||
default=sys.stdout,
|
||||
help="output file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v",
|
||||
"--version",
|
||||
action="version",
|
||||
version=f"{parser.prog} version {__version__}",
|
||||
)
|
||||
argv = parser.parse_args()
|
||||
|
||||
for calendar_file in argv.calendar_files:
|
||||
with open(calendar_file, encoding="utf-8-sig") as f:
|
||||
calendar = Calendar.from_ical(f.read())
|
||||
for event in calendar.walk("vevent"):
|
||||
argv.output.write(view(event) + "\n\n")
|
||||
|
||||
|
||||
__all__ = ["main", "view"]
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user