summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.lonestar.org>2019-04-28 11:19:23 -0400
committerJakob L. Kreuze <zerodaysfordays@sdf.lonestar.org>2019-04-28 11:19:23 -0400
commit4652c09617588b72ccda83de2ebd07bf81242978 (patch)
treee66b40645355fdbd8307c275b97275627be056f1
parentdd11ee48361469049d3960764d80c617c3015040 (diff)
Generate headers for 'post-articleHEADv0.1.0master
-rw-r--r--brisket.hy69
1 files changed, 57 insertions, 12 deletions
diff --git a/brisket.hy b/brisket.hy
index f42db86..1b88e76 100644
--- a/brisket.hy
+++ b/brisket.hy
@@ -22,12 +22,14 @@
(setv __license__ "GPL")
(setv __version__ "0.1.0 'Kansas City-style'")
+(import [binascii [hexlify]])
(import [configparser [ConfigParser]])
+(import [nntplib [NNTP-SSL]])
(import [os [getcwd getenv makedirs]])
(import [os.path [dirname expanduser join]])
-(import [sys [argv exit stderr stdin]])
-(import [nntplib [NNTP-SSL]])
(import [subprocess [Popen PIPE]])
+(import [sys [argv exit stderr stdin]])
+(import [time [strftime]])
(require [hy.contrib.walk [let]])
@@ -165,22 +167,65 @@ usage: fetch-posts (group [optional]) (article-id [optional])"
[group (fetch-group-articles session dest write-to-stdout group)]
[True (fetch-all-articles session dest write-to-stdout)])))
+;; RFC 5536, the Netnews Article Format specifies the following headers as
+;; mandatory an article.
+;;
+;; - Date
+;; - From
+;; - Message-ID
+;; - Newsgroups
+;; - Path
+;; - Subject
+;;
+;; The following headers, though not mandatory, are handled as well by brisket.
+;;
+;; - User-Agent
+;; - Mime-Version
+;; - Content-Type
+;; - Content-Transfer-Encoding
+;; - Content-Language
+
+(defn generate-message-id [posting-address]
+ (let [random (with [rand (open "/dev/urandom" "rb")]
+ (hexlify (.read rand 16)))
+ host (second (.split posting-address "@"))]
+ (.format "<brisket-{}@{}>" random host)))
+
+(defn generate-headers [posting-address subject group]
+ "Return a list of headers to prepend to an article."
+ [(.format "Date: {}" (strftime "%a, %d %b %Y %H:%M:%S %z"))
+ (.format "From: {}" posting-address)
+ (.format "Message-ID: {}" (generate-message-id posting-address))
+ (.format "Newsgroups: {}" group)
+ (.format "Path: {}" "not-for-mail")
+ (.format "Subject: {}" subject)
+ (.format "User-Agent: {} {}" "brisket" __version__)
+ (.format "Mime-Version: {}" "1.0")
+ (.format "Content-Type: {}" "text/plain; charset=utf-8")
+ (.format "Content-Transfer-Encoding: {}" "7bit")
+ (.format "Content-Language: {}" "en-US")])
+
(defn post-article [session &rest args]
"Post an article to the server.
Reads from stdin if the path of a file is not specified.
-usage: post-article [group] (path [optional])"
- (when (= (len args) 0)
- (err "usage: post-article [group] (path [optional])")
+usage: post-article [posting-address] [subject] [group] (path [optional])"
+ (when (< (len args) 3)
+ (err "usage: post-article [posting-address] [subject] [group] (path [optional])")
(return))
- (let [group (first args)
- path (if (> (len args) 1) (second args))]
- (.group session group)
- (if path
- (with [f (open path "rb")]
- (.post session))
- (.post session (list (map str.encode (.split (.read stdin) "\n")))))))
+ (let [posting-address (nth args 0)
+ subject (nth args 1)
+ group (nth args 2)
+ headers (generate-headers posting-address subject group)
+ path (if (> (len args) 3) (nth args 3))
+ content (if path
+ (with [f (open path)]
+ (+ (list (map str.encode headers))
+ (list (map str.encode (.split (.read f) "\n")))))
+ (+ (list (map str.encode headers))
+ (list (map str.encode (.split (.read stdin) "\n")))))]
+ (.post session content)))
(defn make-config []
"Create a default configuration file.