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:
125
.venv/lib/python3.9/site-packages/caldav/config.py
Normal file
125
.venv/lib/python3.9/site-packages/caldav/config.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
"""
|
||||
This configuration parsing code was just copied from my plann library (and will be removed from there at some point in the future). Test coverage is poor as for now.
|
||||
"""
|
||||
|
||||
## This is being moved from my plann library. The code itself will be introduced into caldav 2.0, but proper test code and documentation will come in a later release (2.1?)
|
||||
|
||||
|
||||
## TODO TODO TODO - write test code for all the corner cases
|
||||
## TODO TODO TODO - write documentation of config format
|
||||
def expand_config_section(config, section="default", blacklist=None):
|
||||
"""
|
||||
In the "normal" case, will return [ section ]
|
||||
|
||||
We allow:
|
||||
|
||||
* * includes all sections in config file
|
||||
* "Meta"-sections in the config file with the keyword "contains" followed by a list of section names
|
||||
* Recursive "meta"-sections
|
||||
* Glob patterns (work_* for all sections starting with work_)
|
||||
* Glob patterns in "meta"-sections
|
||||
"""
|
||||
## Optimizating for a special case. The results should be the same without this optimization.
|
||||
if section == "*":
|
||||
return [x for x in config if not config[x].get("disable", False)]
|
||||
|
||||
## If it's not a glob-pattern ...
|
||||
if set(section).isdisjoint(set("[*?")):
|
||||
## If it's referring to a "meta section" with the "contains" keyword
|
||||
if "contains" in config[section]:
|
||||
results = []
|
||||
if not blacklist:
|
||||
blacklist = set()
|
||||
blacklist.add(section)
|
||||
for subsection in config[section]["contains"]:
|
||||
if not subsection in results and not subsection in blacklist:
|
||||
for recursivesubsection in expand_config_section(
|
||||
config, subsection, blacklist
|
||||
):
|
||||
if not recursivesubsection in results:
|
||||
results.append(recursivesubsection)
|
||||
return results
|
||||
else:
|
||||
## Disabled sections should be ignored
|
||||
if config.get("section", {}).get("disable", False):
|
||||
return []
|
||||
|
||||
## NORMAL CASE - return [ section ]
|
||||
return [section]
|
||||
## section name is a glob pattern
|
||||
matching_sections = [x for x in config if fnmatch(x, section)]
|
||||
results = set()
|
||||
for s in matching_sections:
|
||||
if set(s).isdisjoint(set("[*?")):
|
||||
results.update(expand_config_section(config, s))
|
||||
else:
|
||||
## Section names shouldn't contain []?* ... but in case they do ... don't recurse
|
||||
results.add(s)
|
||||
return results
|
||||
|
||||
|
||||
def config_section(config, section="default"):
|
||||
if section in config and "inherits" in config[section]:
|
||||
ret = config_section(config, config[section]["inherits"])
|
||||
else:
|
||||
ret = {}
|
||||
if section in config:
|
||||
ret.update(config[section])
|
||||
return ret
|
||||
|
||||
|
||||
def read_config(fn, interactive_error=False):
|
||||
if not fn:
|
||||
cfgdir = f"{os.environ.get('HOME', '/')}/.config/"
|
||||
for config_file in (
|
||||
f"{cfgdir}/caldav/calendar.conf",
|
||||
f"{cfgdir}/caldav/calendar.yaml",
|
||||
f"{cfgdir}/caldav/calendar.json",
|
||||
f"{cfgdir}/calendar.conf",
|
||||
"/etc/calendar.conf",
|
||||
"/etc/caldav/calendar.conf",
|
||||
):
|
||||
cfg = read_config(config_file)
|
||||
if cfg:
|
||||
return cfg
|
||||
return None
|
||||
|
||||
## This can probably be refactored into fewer lines ...
|
||||
try:
|
||||
try:
|
||||
with open(fn, "rb") as config_file:
|
||||
return json.load(config_file)
|
||||
except json.decoder.JSONDecodeError:
|
||||
## Late import, wrapped in try/except. yaml is external module,
|
||||
## and not included in the requirements as for now.
|
||||
try:
|
||||
import yaml
|
||||
|
||||
try:
|
||||
with open(fn, "rb") as config_file:
|
||||
return yaml.load(config_file, yaml.Loader)
|
||||
except yaml.scanner.ScannerError:
|
||||
logging.error(
|
||||
f"config file {fn} exists but is neither valid json nor yaml. Check the syntax."
|
||||
)
|
||||
except ImportError:
|
||||
logging.error(
|
||||
f"config file {fn} exists but is not valid json, and pyyaml is not installed."
|
||||
)
|
||||
|
||||
except FileNotFoundError:
|
||||
## File not found
|
||||
logging.info("no config file found")
|
||||
except ValueError:
|
||||
if interactive_error:
|
||||
logging.error(
|
||||
"error in config file. Be aware that the interactive configuration will ignore and overwrite the current broken config file",
|
||||
exc_info=True,
|
||||
)
|
||||
else:
|
||||
logging.error("error in config file. It will be ignored", exc_info=True)
|
||||
return {}
|
||||
Reference in New Issue
Block a user