# Dreamwidth понимает public / friends / private (как в LJ) if security == "friends": post["security"] = "usemask" post["allowmask"] = 1 elif security == "private": post["security"] = "private" else: post["security"] = "public"
# Используем LJ.XMLRPC.postevent res = server.LJ.XMLRPC.postevent(post) return res # обычно содержит itemid, url и т.п.
def main(): ap = argparse.ArgumentParser(description="Post a text file to Dreamwidth via XML-RPC") ap.add_argument("file", help="Path to text file (UTF-8). First line is subject, rest is body.") ap.add_argument("--user", required=True, help="Dreamwidth username") ap.add_argument("--password", required=True, help="Dreamwidth password (лучше app-password)") ap.add_argument("--tags", default="", help="Tags, comma-separated or space-separated") ap.add_argument("--security", default="public", choices=["public", "friends", "private"]) args = ap.parse_args()
path = Path(args.file) subject, body = read_post_file(path)
res = post_to_dreamwidth( user=args.user, password=args.password, subject=subject, body=body, tags=args.tags, security=args.security, )
# Печатаем, что вернул сервер print("OK") for k in ("itemid", "anum", "url"): if k in res: print(f"{k}: {res[k]}") # На всякий случай покажем весь ответ, если там другое if not any(k in res for k in ("itemid", "anum", "url")): print(res)
no subject
Date: 2026-01-01 08:48 pm (UTC)no subject
Date: 2026-01-01 09:36 pm (UTC)no subject
Date: 2026-01-01 09:55 pm (UTC)no subject
Date: 2026-01-01 11:42 pm (UTC)no subject
Date: 2026-01-02 01:02 am (UTC)no subject
Date: 2026-01-02 07:26 am (UTC)no subject
Date: 2026-01-02 04:13 pm (UTC)no subject
Date: 2026-01-02 04:30 pm (UTC)#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import datetime as dt
import xmlrpc.client
from pathlib import Path
DW_XMLRPC = "https://www.dreamwidth.org/interface/xmlrpc"
def read_post_file(path: Path):
text = path.read_text(encoding="utf-8")
lines = text.splitlines()
if not lines:
raise ValueError("Файл пустой")
subject = lines[0].strip()
body = "\n".join(lines[1:]).lstrip("\n")
if not subject:
raise ValueError("Первая строка (заголовок) пустая")
return subject, body
def post_to_dreamwidth(user: str, password: str, subject: str, body: str,
tags: str = "", security: str = "public"):
server = xmlrpc.client.ServerProxy(DW_XMLRPC, allow_none=True)
now = dt.datetime.now()
post = {
"username": user,
"password": password,
"ver": 1,
"lineendings": "unix",
"subject": subject,
"event": body,
"year": now.year,
"mon": now.month,
"day": now.day,
"hour": now.hour,
"min": now.minute,
"props": {
"taglist": tags,
},
}
# Dreamwidth понимает public / friends / private (как в LJ)
if security == "friends":
post["security"] = "usemask"
post["allowmask"] = 1
elif security == "private":
post["security"] = "private"
else:
post["security"] = "public"
# Используем LJ.XMLRPC.postevent
res = server.LJ.XMLRPC.postevent(post)
return res # обычно содержит itemid, url и т.п.
def main():
ap = argparse.ArgumentParser(description="Post a text file to Dreamwidth via XML-RPC")
ap.add_argument("file", help="Path to text file (UTF-8). First line is subject, rest is body.")
ap.add_argument("--user", required=True, help="Dreamwidth username")
ap.add_argument("--password", required=True, help="Dreamwidth password (лучше app-password)")
ap.add_argument("--tags", default="", help="Tags, comma-separated or space-separated")
ap.add_argument("--security", default="public", choices=["public", "friends", "private"])
args = ap.parse_args()
path = Path(args.file)
subject, body = read_post_file(path)
res = post_to_dreamwidth(
user=args.user,
password=args.password,
subject=subject,
body=body,
tags=args.tags,
security=args.security,
)
# Печатаем, что вернул сервер
print("OK")
for k in ("itemid", "anum", "url"):
if k in res:
print(f"{k}: {res[k]}")
# На всякий случай покажем весь ответ, если там другое
if not any(k in res for k in ("itemid", "anum", "url")):
print(res)
if __name__ == "__main__":
main()
no subject
Date: 2026-01-02 07:51 pm (UTC)