• csiph.com

    From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Fri May 1 09:31:35 2026
    From Newsgroup: news.software.nntp

    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Fri May 1 20:19:16 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> posted:

    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.

    Another web interface to Usenet - welcome to the club!
    It appears to support full-text search also :-)

    You might want to add it to: https://en.wikipedia.org/wiki/Web-based_Usenet#Web-based_sites_and_popularity --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From InterLinked@nntp@phreaknet.org to news.software.nntp on Fri May 1 20:40:21 2026
    From Newsgroup: news.software.nntp

    On 5/1/2026 12:31 PM, Kevin Bowling wrote:
    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.

    Very nice! I was going to do something like this at some point, but this
    is basically what I intended to do (and with posting, on top of that).

    Is this directly integrated specifically with the CSIPH news spool, or
    using NNTP to talk to the news server? I was thinking recently it would
    be helpful to have something like this for private hierarchies or just
    testing in general.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Fri May 1 18:22:07 2026
    From Newsgroup: news.software.nntp

    On 5/1/26 5:40 PM, InterLinked wrote:
    On 5/1/2026 12:31 PM, Kevin Bowling wrote:
    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.

    Very nice! I was going to do something like this at some point, but this
    is basically what I intended to do (and with posting, on top of that).

    Is this directly integrated specifically with the CSIPH news spool, or
    using NNTP to talk to the news server? I was thinking recently it would
    be helpful to have something like this for private hierarchies or just testing in general.

    I wrote a from scratch NNTP library in async Rust (Tokio), so the webui
    uses that with a connection pool to talk to csiph's inn nnrp. The webui manages some memory caches of the newsgroup list, per group overviews,
    jwz article threading. The main bottleneck right now is inn OVER
    performance, I need to look into that a bit more but sent a couple
    patches for ovsqlite that might help. Getting threading to be useful
    requires a big OVER, around 10k articles, which I called eras. When the
    user pages near the border of an era, I create a temporary union I
    called a tandem with the next era, so you can generally have threading
    work 10k in either direction.

    The webui also manages search indexing (Tantivy) over NNTP and there is
    a small user binary from the same codebase that is used for inn's nnrpd
    so one account gives access to web and nnrp.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From InterLinked@nntp@phreaknet.org to news.software.nntp on Fri May 1 22:00:01 2026
    From Newsgroup: news.software.nntp

    On 5/1/2026 9:22 PM, Kevin Bowling wrote:
    On 5/1/26 5:40 PM, InterLinked wrote:
    Is this directly integrated specifically with the CSIPH news spool, or
    using NNTP to talk to the news server? I was thinking recently it
    would be helpful to have something like this for private hierarchies
    or just testing in general.

    I wrote a from scratch NNTP library in async Rust (Tokio), so the webui
    uses that with a connection pool to talk to csiph's inn nnrp.-a The webui manages some memory caches of the newsgroup list, per group overviews,
    jwz article threading.-a The main bottleneck right now is inn OVER performance, I need to look into that a bit more but sent a couple
    patches for ovsqlite that might help.-a Getting threading to be useful requires a big OVER, around 10k articles, which I called eras.-a When the user pages near the border of an era, I create a temporary union I
    called a tandem with the next era, so you can generally have threading
    work 10k in either direction.

    The webui also manages search indexing (Tantivy) over NNTP and there is
    a small user binary from the same codebase that is used for inn's nnrpd
    so one account gives access to web and nnrp.

    Very impressive. Not sure how feasible this would be, but is this
    something that you would consider open sourcing that others can run with
    other news servers?
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Sat May 2 00:01:46 2026
    From Newsgroup: news.software.nntp

    On 5/1/26 7:00 PM, InterLinked wrote:
    On 5/1/2026 9:22 PM, Kevin Bowling wrote:
    On 5/1/26 5:40 PM, InterLinked wrote:
    Is this directly integrated specifically with the CSIPH news spool,
    or using NNTP to talk to the news server? I was thinking recently it
    would be helpful to have something like this for private hierarchies
    or just testing in general.

    I wrote a from scratch NNTP library in async Rust (Tokio), so the
    webui uses that with a connection pool to talk to csiph's inn nnrp.
    The webui manages some memory caches of the newsgroup list, per group
    overviews, jwz article threading.-a The main bottleneck right now is
    inn OVER performance, I need to look into that a bit more but sent a
    couple patches for ovsqlite that might help.-a Getting threading to be
    useful requires a big OVER, around 10k articles, which I called eras.
    When the user pages near the border of an era, I create a temporary
    union I called a tandem with the next era, so you can generally have
    threading work 10k in either direction.

    The webui also manages search indexing (Tantivy) over NNTP and there
    is a small user binary from the same codebase that is used for inn's
    nnrpd so one account gives access to web and nnrp.

    Very impressive. Not sure how feasible this would be, but is this
    something that you would consider open sourcing that others can run with other news servers?

    Eventually, the NNTP lib first. It all will need some cleanup, somewhat specific to my setup and FreeBSD right now.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Sat May 2 09:15:15 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> posted:

    On 5/1/26 7:00 PM, InterLinked wrote:

    Very impressive. Not sure how feasible this would be, but is this something that you would consider open sourcing that others can run with other news servers?

    Eventually, the NNTP lib first. It all will need some cleanup, somewhat specific to my setup and FreeBSD right now.

    InterLinked, you might be interested in the code for my usenet/web interface, which is open-sourced at https://chiselapp.com/user/cmacleod/repository/newsgrouper/home

    Like Kevin, I had to do some work to clean it up for publication, however
    there are still a few things hard-coded which really should be configurable.

    Some differences from Kevin's code:

    - My Newsgrouper code is in Tcl - some may consider this a bug, to me
    it's a feature. :-)

    - Newsgrouper can pull overview info and posts from multiple nntp servers,
    caching them locally using a mixture of Sqlite and Redis and presenting
    them as a unified whole.

    - Newsgrouper cannot support full-text search of posts, which CSIPH does.

    - The user interface is of course significantly different. Newsgrouper
    uses a little Javascript to make it possible to drive most functionality
    from the keyboard (but is still usable without Javascript). It has
    various refinements like support for Face and X-Face images, which I
    imagine CSIPH may add in time.

    - CSIPH appears not to handle base64 encoding at present - see
    http://csiph.com/group/cn.fan/22724 - Newsgrouper does handle this,
    the same post can be seen at:
    https://newsgrouper.org/%3C867brmgy5g.fsf@gmail.com%3E .

    - Kevin says "The main bottleneck right now is inn OVER performance".
    I avoid that by keeping overview data in a Sqlite table, pulling only
    new OVER data from the nntp server(s) as required, then I can do fast
    queries against that db table to display thread and post lists.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Sat May 2 05:28:56 2026
    From Newsgroup: news.software.nntp

    On 5/2/26 2:15 AM, Colin Macleod wrote:
    Kevin Bowling <kevin.bowling@kev009.com> posted:

    On 5/1/26 7:00 PM, InterLinked wrote:

    Very impressive. Not sure how feasible this would be, but is this
    something that you would consider open sourcing that others can run with >>> other news servers?

    Eventually, the NNTP lib first. It all will need some cleanup, somewhat
    specific to my setup and FreeBSD right now.

    InterLinked, you might be interested in the code for my usenet/web interface, which is open-sourced at https://chiselapp.com/user/cmacleod/repository/newsgrouper/home

    Like Kevin, I had to do some work to clean it up for publication, however there are still a few things hard-coded which really should be configurable.

    Some differences from Kevin's code:

    - My Newsgrouper code is in Tcl - some may consider this a bug, to me
    it's a feature. :-)

    TCL is cool!

    - Newsgrouper can pull overview info and posts from multiple nntp servers,
    caching them locally using a mixture of Sqlite and Redis and presenting
    them as a unified whole.

    Since it is all NNTP based I could point it to other servers, but it
    would create a fairly unusual usage pattern if not done with permission
    and forethought.

    - Newsgrouper cannot support full-text search of posts, which CSIPH does.

    This turned out to be a fair amount of work, I had to do custom
    tokenizer, clustering, some hacky normalization before BM25 so the same
    thread with a bunch of quoting doesn't overscore, signatures don't blow
    out keywords, etc. My goal is to replace/displace Google Groups so it
    is a key feature. I probably have to reindex at least once more as I
    fixed some date parsing stuff but the current index is pretty good and
    got past alt.* and into comp.* now, a couple more days and it'll be
    fully populated.

    - The user interface is of course significantly different. Newsgrouper
    uses a little Javascript to make it possible to drive most functionality
    from the keyboard (but is still usable without Javascript). It has
    various refinements like support for Face and X-Face images, which I
    imagine CSIPH may add in time.

    There will never be any JS on CSIPH because it is meant to be used from
    retro systems. I've tested back to Mosaic. You'll need cookies for
    auth but that is still Netscape 1/IE2 era. It does come with tradeoffs
    but I like the aesthetic.

    - CSIPH appears not to handle base64 encoding at present - see
    http://csiph.com/group/cn.fan/22724 - Newsgrouper does handle this,
    the same post can be seen at:
    https://newsgrouper.org/%3C867brmgy5g.fsf@gmail.com%3E .

    Thanks, I'll fix this. Text encodings and time formats turned out to be
    quite a tarpit.


    - Kevin says "The main bottleneck right now is inn OVER performance".
    I avoid that by keeping overview data in a Sqlite table, pulling only
    new OVER data from the nntp server(s) as required, then I can do fast
    queries against that db table to display thread and post lists.

    I think I've got this nailed down
    https://github.com/InterNetNews/inn/pull/338

    I do aggressively cache things, but the particular use of overview for threading is extremely heavy. My overview DB is 26GB highly compressed
    and I don't want to over-optimize the webui over NNTP users.

    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Sat May 2 13:49:16 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> posted:

    - Newsgrouper can pull overview info and posts from multiple nntp servers,
    caching them locally using a mixture of Sqlite and Redis and presenting
    them as a unified whole.

    Since it is all NNTP based I could point it to other servers, but it
    would create a fairly unusual usage pattern if not done with permission
    and forethought.

    Indeed. I don't run my own nntp server, but I have liased with the admins
    of the servers I do pull from.


    - Newsgrouper cannot support full-text search of posts, which CSIPH does.

    This turned out to be a fair amount of work, I had to do custom
    tokenizer, clustering, some hacky normalization before BM25 so the same thread with a bunch of quoting doesn't overscore, signatures don't blow
    out keywords, etc. My goal is to replace/displace Google Groups so it
    is a key feature. I probably have to reindex at least once more as I
    fixed some date parsing stuff but the current index is pretty good and
    got past alt.* and into comp.* now, a couple more days and it'll be
    fully populated.

    Interesting.

    - The user interface is of course significantly different. Newsgrouper
    uses a little Javascript to make it possible to drive most functionality
    from the keyboard (but is still usable without Javascript). It has
    various refinements like support for Face and X-Face images, which I
    imagine CSIPH may add in time.

    There will never be any JS on CSIPH because it is meant to be used from retro systems. I've tested back to Mosaic. You'll need cookies for
    auth but that is still Netscape 1/IE2 era. It does come with tradeoffs
    but I like the aesthetic.

    Yes, I don't *require* JS, and I aim to be compatible with as wide a range
    of clients as possible, but for those which do support JS I think being
    able to hit Enter to jump to the next post etc. gets closer to the
    experience you would have with a traditional newsreader.

    - CSIPH appears not to handle base64 encoding at present - see
    http://csiph.com/group/cn.fan/22724 - Newsgrouper does handle this,
    the same post can be seen at:
    https://newsgrouper.org/%3C867brmgy5g.fsf@gmail.com%3E .

    Thanks, I'll fix this. Text encodings and time formats turned out to be quite a tarpit.

    Aargh - I also found parsing weird date formats a real headache.


    - Kevin says "The main bottleneck right now is inn OVER performance".
    I avoid that by keeping overview data in a Sqlite table, pulling only
    new OVER data from the nntp server(s) as required, then I can do fast
    queries against that db table to display thread and post lists.

    I think I've got this nailed down https://github.com/InterNetNews/inn/pull/338

    I do aggressively cache things, but the particular use of overview for threading is extremely heavy. My overview DB is 26GB highly compressed
    and I don't want to over-optimize the webui over NNTP users.


    Very interesting. A couple of questions:

    Do you have any protection against bots? These days AI scrapers can be
    very aggressive, effectively DDOSing websites. I guard against this by requiring a login at least as a guest for almost all pages except the
    login page. I also think it may be risky to allow Google etc. to
    index Usenet posts through a web interface - I suspect that SEO hacking
    was one of the factors driving the tidal wave of spam which Usenet
    suffered a couple of years ago before Google Groups disconnected.

    How far back does your coverage go? Looking at a couple of groups
    I see posts back to June 2015. Are you generating full-text indexes
    for 10 years?
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to news.software.nntp on Sat May 2 13:58:37 2026
    From Newsgroup: news.software.nntp

    Colin Macleod <user7@newsgrouper.org.invalid> wrote or quoted:
    Do you have any protection against bots?

    Somehow, this reminds me of:

    Some posters have these "X-No-Html: yes" headers,
    or "X-No-Archive: Yes", "Archive: no", etc. Possibly,
    they do not wish to be seen in the web (and maybe for
    the very reason that they then could be seen by bots
    and search engines etc.).


    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From InterLinked@nntp@phreaknet.org to news.software.nntp on Sat May 2 10:38:16 2026
    From Newsgroup: news.software.nntp

    On 5/2/2026 5:15 AM, Colin Macleod wrote:
    Kevin Bowling <kevin.bowling@kev009.com> posted:

    On 5/1/26 7:00 PM, InterLinked wrote:

    Very impressive. Not sure how feasible this would be, but is this
    something that you would consider open sourcing that others can run with >>> other news servers?

    Eventually, the NNTP lib first. It all will need some cleanup, somewhat
    specific to my setup and FreeBSD right now.

    Understood - when it's ready, I'll be waiting!

    InterLinked, you might be interested in the code for my usenet/web interface, which is open-sourced at https://chiselapp.com/user/cmacleod/repository/newsgrouper/home

    Like Kevin, I had to do some work to clean it up for publication, however there are still a few things hard-coded which really should be configurable.

    Thanks Colin! This is a nice resource as well.

    I'll admit, I'm more partial to the way Kevin's site works. What I was intending to put together myself was basically a stateless* NNTP client
    that showed all the groups and group info and then showed articles when
    you clicked on them (which is what CSIPH does, and more, and more
    efficiently at that). And FWIW, I like the aesthetic too.

    (*I was only planning to use it with my own news servers, to avoid
    putting too much load on a busy news server.)

    I was less interested in searching really, than just seeing a list of
    groups, with some basic stats like description, status, and article
    count, and being able to poke around and see if a group is any good.
    It's a bit cumbersome in a newsreader, as you have to subscribe to
    interesting looking groups to see what's in them, only to find they're
    no good (inactive or just filled with spam) and then delete them. A bit
    too much friction for discovering good groups... but CSIPH makes this
    very easy. (Eventually, I'd like to have my news server just have all
    the "genuine" Usenet groups and not even carry the inactive/spammy ones
    at all, to solve that issue for me.)

    If I search with no arguments, I think Newsgrouper does dump all the
    groups, but not sorted and without any article counts, so hard to get an
    idea at a glimpse as to how active a group is. Also, not paginated, so
    it's a bit overwhelming, though in some cases that is useful.

    I think the only thing I might have done that CSIPH doesn't seem to is
    also show the low and high water marks and maybe creation info (date and creator) as well - just because I would find it interesting to see what
    they are for each group, not because "normal" users would necessarily
    care about that.

    As far as "other news servers" go, eventually I would be looking for
    something I could run myself, so it could show private hierarchies that
    aren't on Usenet, only available to authenticated users on a private
    news network.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Russ Allbery@eagle@eyrie.org to news.software.nntp on Sat May 2 09:10:14 2026
    From Newsgroup: news.software.nntp

    Colin Macleod <user7@newsgrouper.org.invalid> writes:

    Some differences from Kevin's code:

    - My Newsgrouper code is in Tcl - some may consider this a bug, to me
    it's a feature. :-)

    I love that someone is still writing netnews code in Tcl these days!
    Although I see from your other message that you don't run your own server,
    so you probably can't answer the question of whether anyone still uses the (very minimal) Tcl support in INN.
    --
    Russ Allbery (eagle@eyrie.org) <https://www.eyrie.org/~eagle/>

    Please post questions rather than mailing me directly.
    <https://www.eyrie.org/~eagle/faqs/questions.html> explains why.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From SpallsHurgenson(NG)@user14325@newsgrouper.org.invalid to news.software.nntp on Sat May 2 17:02:06 2026
    From Newsgroup: news.software.nntp


    InterLinked <nntp@phreaknet.org> posted:


    Thanks Colin! This is a nice resource as well.
    I'll admit, I'm more partial to the way Kevin's site works. What I was intending to put together myself was basically a stateless* NNTP client
    that showed all the groups and group info and then showed articles when
    you clicked on them (which is what CSIPH does, and more, and more efficiently at that). And FWIW, I like the aesthetic too.




    I'm more a fan of Newsgrouper... if only for the soothing blue color
    scheme. CSIPH emulates the glaring whiteness of Google a bit too closely
    for my wearied and old eyes. But I like both, for different reasons.

    CSIPH I can see used as my 'research tool'; when I'm trying to find an article or topic. Its slightly cleaner interface and full-text search work well
    for this use. But when I want to quickly check, 'Hey, has somebody posted something new to the newsgroups I frequent', then I'll probably head to Newsgrouper first.

    But thank you both, Colin and Kevin, for providing these excellent services.

    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From =?UTF-8?Q?Julien_=C3=89LIE?=@iulius@nom-de-mon-site.com.invalid to news.software.nntp on Sun May 3 21:20:32 2026
    From Newsgroup: news.software.nntp

    Hi Kevin,

    My goal is to replace/displace Google Groups

    I really hope you'll manage to provide such a useful alternative!

    I see that the URLs contain article numbers, which may change in case of
    a renumbering (it may happen one day, who knows). It could be
    interesting to have a permanent link feature with a URL containing the Message-ID.


    I probably have to reindex at least once more as I
    fixed some date parsing stuff

    Did you try to use a library like https://docs.rs/dateparser/latest/dateparser/ which seems to handle lots
    of date formats?



    Regarding searches, how is the language taken into account?
    Searching "Usenet" with French languages give me articles written in
    English.
    http://csiph.com/search?q=usenet&lang=fr

    How often do you run innreport? It seems to be started automatically at
    04:15 but not every day?
    http://csiph.com/innreport/
    --
    Julien |eLIE

    -2-aSi ma femme doit |-tre veuve un jour, j'aimerais mieux que ce soit de
    mon vivant.-a-+ (Raymond Devos)

    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Sun May 3 20:25:26 2026
    From Newsgroup: news.software.nntp

    =?UTF-8?Q?Julien_=C3=89LIE?= <iulius@nom-de-mon-site.com.invalid> posted:

    I see that the URLs contain article numbers, which may change in case of
    a renumbering (it may happen one day, who knows). It could be
    interesting to have a permanent link feature with a URL containing the Message-ID.

    Perhaps it's worth mentioning that Newsgrouper already does this (I have
    had to change the format of the ordinary article URLs a couple of times).
    At the bottom of each article there is a "Permalink" which is a link
    of the form newsgrouper.org/<msgid> . Also there is a "Share" button
    for platforms which support this.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Tue May 5 02:01:27 2026
    From Newsgroup: news.software.nntp

    On 5/3/26 12:20 PM, Julien |eLIE wrote:
    Hi Kevin,

    My goal is to replace/displace Google Groups

    I really hope you'll manage to provide such a useful alternative!

    I see that the URLs contain article numbers, which may change in case of
    a renumbering (it may happen one day, who knows).-a It could be
    interesting to have a permanent link feature with a URL containing the Message-ID.

    Added


    I probably have to reindex at least once more as I fixed some date
    parsing stuff

    Did you try to use a library like https://docs.rs/dateparser/latest/ dateparser/ which seems to handle lots of date formats?

    I checked a few but none of them handle the real world corpus. In my
    NNTP library I currently have the following, I'm sure it is missing a
    lot but it seems easy to extend/maintain:

    /// Lenient Usenet date parser.
    ///
    /// Usenet articles (especially pre-2000) use many date formats that
    /// `chrono::DateTime::parse_from_rfc2822` rejects:
    ///
    /// - Named timezones: `Mon, 27 Apr 1993 10:30:00 EST`
    /// - Missing seconds: `Mon, 27 Apr 1993 10:30 +0000`
    /// - 2-digit years: `27 Apr 93 10:30:00 GMT`
    /// - C asctime: `Mon Apr 27 10:30:00 1993`
    /// - No day-of-week: `27 Apr 1993 10:30:00 +0000`
    ///
    /// This function normalizes the most common issues before parsing. #[cfg(feature = "chrono")]
    pub fn parse_usenet_date(s: &str) -> Option<chrono::DateTime<chrono::FixedOffset>> {
    use chrono::{DateTime, NaiveDateTime};

    // Fast path: strict RFC 2822.
    if let Ok(dt) = DateTime::parse_from_rfc2822(s) {
    return Some(dt);
    }

    // Normalize: replace named timezone abbreviations with numeric
    offsets.
    let normalized = replace_named_tz(s);
    if let Ok(dt) = DateTime::parse_from_rfc2822(&normalized) {
    return Some(dt);
    }

    // Try common format variants with explicit patterns.
    let patterns = [
    // With day-of-week, no seconds: "Mon, 27 Apr 1993 10:30 +0000"
    "%a, %d %b %Y %H:%M %z",
    // Without day-of-week: "27 Apr 1993 10:30:00 +0000"
    "%d %b %Y %H:%M:%S %z",
    // Without day-of-week, no seconds: "27 Apr 1993 10:30 +0000"
    "%d %b %Y %H:%M %z",
    // 2-digit year with day-of-week: "Mon, 27 Apr 93 10:30:00 +0000"
    "%a, %d %b %y %H:%M:%S %z",
    // 2-digit year without day-of-week: "27 Apr 93 10:30:00 +0000"
    "%d %b %y %H:%M:%S %z",
    // 2-digit year with day-of-week, no seconds: "Mon, 27 Apr 93
    10:30 +0000"
    "%a, %d %b %y %H:%M %z",
    // 2-digit year without day-of-week, no seconds: "27 Apr 93
    10:30 +0000"
    "%d %b %y %H:%M %z",
    ];
    for pat in &patterns {
    if let Ok(dt) = DateTime::parse_from_str(&normalized, pat) {
    return Some(dt);
    }
    }

    // C asctime format: "Mon Apr 27 10:30:00 1993" rCo no timezone info,
    // assume UTC (the best we can do without context).
    if let Ok(naive) = NaiveDateTime::parse_from_str(s.trim(), "%a %b
    %d %H:%M:%S %Y") {
    return Some(naive.and_utc().fixed_offset());
    }

    None
    }

    /// Replace common named timezone abbreviations with numeric UTC offsets. #[cfg(feature = "chrono")]
    fn replace_named_tz(s: &str) -> String {
    // Match the last whitespace-delimited token as a potential TZ name.
    let s = s.trim();
    let Some(last_space) = s.rfind([' ', '\t']) else {
    return s.to_owned();
    };
    let (prefix, tz) = s.split_at(last_space);
    let tz = tz.trim();

    let offset = match tz {
    "GMT" | "UTC" | "UT" => "+0000",
    "EST" => "-0500",
    "EDT" => "-0400",
    "CST" => "-0600",
    "CDT" => "-0500",
    "MST" => "-0700",
    "MDT" => "-0600",
    "PST" => "-0800",
    "PDT" => "-0700",
    "BST" => "+0100",
    "CET" | "MET" => "+0100",
    "CEST" | "MEST" => "+0200",
    "EET" => "+0200",
    "EEST" => "+0300",
    "JST" => "+0900",
    "KST" => "+0900",
    "IST" => "+0530", // India; ambiguous (also Ireland +0100,
    Israel +0200)
    "HKT" => "+0800",
    "AEST" => "+1000",
    "AEDT" => "+1100",
    "NZST" => "+1200",
    "NZDT" => "+1300",
    "HST" => "-1000",
    "AKST" => "-0900",
    "AKDT" => "-0800",
    "SAST" => "+0200",
    _ => return s.to_owned(),
    };
    format!("{prefix} {offset}")
    }

    Regarding searches, how is the language taken into account?
    Searching "Usenet" with French languages give me articles written in English.
    -a http://csiph.com/search?q=usenet&lang=fr

    Right now it is just altering the term stemmer.

    I need to hook up language detection and heuristics during indexing and
    store it as a document parameter to make it useful. That will make it possible to support a lot more languages but I will need to think about
    how they map to stemming, I guess if a language supports stemming it
    will use it if not it will just use the query term as is. Added to my
    list of things to do.

    How often do you run innreport?-a It seems to be started automatically at 04:15 but not every day?
    -a http://csiph.com/innreport/

    The current problem is expireover takes around the gap you see to
    complete. I suspect there was some regression in OpenZFS performance
    around 2021 but I never dug into it that really hurts this file at a
    time workload. I would like to look into both sides of that at some
    point, and using some POSIX API to get some parallelism would map well
    to all storage devices and file systems.

    In the mean time I found a new ZFS feature called a special device. I
    had a pair of enterprise SSDs in the server that were used for SLOG and
    L2ARC (cache). I was able to remove the L2ARC and turn it into a
    special, then use zfs rewrite so it is currently moving all
    files/records 64k or less to the SSDs. I have the ovsqlite record size
    set to 64k as well so it should improve performance quite a bit when the rewrite completes.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Tue May 5 02:07:46 2026
    From Newsgroup: news.software.nntp

    On 5/3/26 2:36 AM, Julien |eLIE wrote:
    Hi Kevin,

    There's massive contention in nnrp right now, it will let up a bit
    once search indexing is complete and https://github.com/InterNetNews/
    inn/ pull/338 is the ultimate root cause fix I will patch it in when I
    have a moment.

    Thanks a lot for the improvements you propose to ovsqlite; I'll have a
    look at it soon.

    A great webnews interface, thanks for sharing it!
    If I may suggest: it would look nicer if the Date colum was somehow normalized instead of taking the raw contents of the header field.

    Done. Raw date format is still available from Show all headers in an
    article.

    The newsgroups descriptions are not up-to-date.-a For instance fr.comp.sys.raspberry-pi currently has no description, and some other descriptions are old ones.

    Looks like I need to update newsgroups file. I saw some references that actsync can do this, but no examples, is it possible to have one
    actsync.cfg cover this? And I guess it needs to be more careful than
    active, should merge not remove entries?


    One thing that would be interesting is adopting IMAP's THREAD and SORT
    extensions for NNTP https://datatracker.ietf.org/doc/html/rfc5256

    That would be interesting indeed, though it adds a bit of load at server side.-a It is also quite a work to add support for that in all overview methods of INN (unless it would be ovsqlite-specific for instance), as
    well as in other still used news servers.

    There's some background here https://www.jwz.org/doc/threading.html, the threading itself should be light weight but I have not considered the implications of the overview backends.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Tue May 5 03:01:01 2026
    From Newsgroup: news.software.nntp

    On 5/2/26 5:28 AM, Kevin Bowling wrote:
    On 5/2/26 2:15 AM, Colin Macleod wrote:
    - CSIPH appears not to handle base64 encoding at present - see
    -a-a http://csiph.com/group/cn.fan/22724 - Newsgrouper does handle this,
    -a-a the same post can be seen at:
    -a-a https://newsgrouper.org/%3C867brmgy5g.fsf@gmail.com%3E .

    Thanks, I'll fix this.-a Text encodings and time formats turned out to be quite a tarpit.

    I think this is fixed, there is multipart and base64 handling in place.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Tue May 5 12:56:31 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> posted:

    On 5/2/26 5:28 AM, Kevin Bowling wrote:
    On 5/2/26 2:15 AM, Colin Macleod wrote:
    - CSIPH appears not to handle base64 encoding at present - see
    -a-a http://csiph.com/group/cn.fan/22724 - Newsgrouper does handle this, >> -a-a the same post can be seen at:
    -a-a https://newsgrouper.org/%3C867brmgy5g.fsf@gmail.com%3E .

    Thanks, I'll fix this.-a Text encodings and time formats turned out to be quite a tarpit.

    I think this is fixed, there is multipart and base64 handling in place.

    Indeed, looks better now! :-)
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Tue May 5 13:19:06 2026
    From Newsgroup: news.software.nntp

    I made a test post just now, which worked ok.

    I would suggest having a warning that the email you set in your profile
    when creating an account *will be exposed* in the From line when you post.
    When I created my account I was not sure if this required a real email
    address (for newsgrouper I require that a user registers with a real email which I do not expose publicly).
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Tue May 5 06:38:09 2026
    From Newsgroup: news.software.nntp

    On 5/5/26 06:19, Colin Macleod wrote:
    I made a test post just now, which worked ok.

    I would suggest having a warning that the email you set in your profile
    when creating an account *will be exposed* in the From line when you post. When I created my account I was not sure if this required a real email address (for newsgrouper I require that a user registers with a real email which I do not expose publicly).


    I intend to do the same thing, create a second field called the display
    email. The system will require (and send a validation link) to the registration email to cut down on false signups. Then posts will only
    show the display email which can be invalid.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Tue May 5 14:00:57 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> posted:

    On 5/5/26 06:19, Colin Macleod wrote:
    I made a test post just now, which worked ok.

    I would suggest having a warning that the email you set in your profile when creating an account *will be exposed* in the From line when you post. When I created my account I was not sure if this required a real email address (for newsgrouper I require that a user registers with a real email which I do not expose publicly).


    I intend to do the same thing, create a second field called the display email. The system will require (and send a validation link) to the registration email to cut down on false signups. Then posts will only
    show the display email which can be invalid.

    That makes sense.

    By the way, one benefit of your system is that it's accessible to users
    in the UK. Because I'm in the UK I cannot risk ignoring our ill-advised
    Online Safety Act, but its requirements are so far-reaching and vague
    that I concluded the only practical way for me to comply with it was to
    just block access from UK IP addresses.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From =?UTF-8?Q?Julien_=C3=89LIE?=@iulius@nom-de-mon-site.com.invalid to news.software.nntp on Tue May 5 21:49:22 2026
    From Newsgroup: news.software.nntp

    Hi Kevin,

    I see that the URLs contain article numbers, which may change in case
    of a renumbering (it may happen one day, who knows).-a It could be
    interesting to have a permanent link feature with a URL containing the
    Message-ID.

    Added

    Oh, thanks a lot for having added this feature!


    I checked a few but none of them handle the real world corpus.-a In my
    NNTP library I currently have the following, I'm sure it is missing a
    lot but it seems easy to extend/maintain

    FWIW, Russ once had an extensive look at all the dates present in the Standford's news server. You'll find at the beginning of the INN test
    suite for the date library (tests/lib/date-t.c) a list of date header
    fields you may consider adding to your parser.


    How often do you run innreport?-a It seems to be started automatically
    at 04:15 but not every day?
    -a-a http://csiph.com/innreport/

    The current problem is expireover takes around the gap you see to
    complete.

    Oh, that's quite long! I thought ovsqlite was way more faster.
    Maybe you did not try but would tradindexed be faster? (at least for newsgroups with less than thousands of millions of articles)
    --
    Julien |eLIE

    -2-aSur vingt personnes qui parlent de nous, dix-neuf en disent du mal et
    la vingti|?me, qui en dit du bien, le dit mal.-a-+ (Rivarol)

    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From =?UTF-8?Q?Julien_=C3=89LIE?=@iulius@nom-de-mon-site.com.invalid to news.software.nntp on Tue May 5 22:06:42 2026
    From Newsgroup: news.software.nntp

    Hi Kevin,

    If I may suggest: it would look nicer if the Date colum was somehow
    normalized instead of taking the raw contents of the header field.

    Done.-a Raw date format is still available from Show all headers in an article.

    Seen. Thanks!


    Looks like I need to update newsgroups file.-a I saw some references that actsync can do this, but no examples, is it possible to have one
    actsync.cfg cover this?-a And I guess it needs to be more careful than active, should merge not remove entries?

    actsync does not have that feature. It would be useful to have, though.

    You could use "getlist -h news.server.com newsgroups" to fetch the
    newsgroups file from another server, or download the one from the ISC at
    https://downloads.isc.org/pub/usenet/CONFIG/newsgroups.gz

    Yet, if I understand well, you want to keep the descriptions of removed newsgroups in the external source. If that's the case, you need merging
    them with a bit of care, yes.


    There's some background here https://www.jwz.org/doc/threading.html

    A robust algorithm widely used during 6 years by millions of people.
    It's great that its author describes it.
    --
    Julien |eLIE

    -2-arCo Attention, vous autres-a; le chef a dit de le ramener vivant-a!
    rCo Finasser-a! Toujours finasser-a!-a-+ (Ast|-rix)

    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Wed May 6 20:21:57 2026
    From Newsgroup: news.software.nntp

    Kevin Bowling <kevin.bowling@kev009.com> wrote:
    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.

    I made a breaking change to URLs so everything is referenced by
    Message-ID after thinking about some of the feedback. The URLs can get
    a little much, but I think codifying my article numbers everywhere is short-sighted if I want to rebuild my spool in some different
    configuration. The permalink handler still stands as there are cases
    like references where the redirect is useful, but there are also Message
    IDs on top of a group like http://csiph.com/group/news.software.nntp/a/10t2kh8%25241a6i%25241@csiph.com where the browsed group adds some context for things like threading.

    The multi-server case is more interesting than I initially judged: I
    pointed the software (locally with indexing disabled) at nntp.gmane.io
    and it works perfectly well, which makes sense as it's INN as well.

    The internals would need some rework to actually handle multi-server,
    article numbers are still too convenient for i.e. efficient cache
    structures and efficient read tracking, but that could still work with a
    tuple if needed. No immediate plans to do this, but I had the thought
    that virtual NNTP servers might be kind of cool.. I could create
    something like groups.io but with dual (NNTP+web) or tri mode
    (NNTP+web+email) where NNTP is the backing store, but web and email readers/writers can participate equally. NNTP readers get the benefit
    of full history, web readers get full text search. The virtual NNTP
    server only shows the subset of lists in the group. No immediate plans
    for that just a thought, at least the external facing stuff will be
    stable to any major reworks.
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Thu May 7 02:24:14 2026
    From Newsgroup: news.software.nntp

    "Kevin Bowling" <kevin.bowling@kev009.com> posted:

    The internals would need some rework to actually handle multi-server,
    article numbers are still too convenient for i.e. efficient cache
    structures and efficient read tracking, but that could still work with a tuple if needed.

    I went through a similar evolution with Newsgrouper. I started with
    a single nntp server (eternal-september) and just used its article
    numbers directly. But then I wanted to add in other servers with
    longer history, plus old stuff from the Internet Archive, etc..
    After trying various alternatives I moved to identifying articles
    within a group by their unix-format timestamp (seconds since 1/1/1970).
    I get this from parsing the Date header. If this collides with another
    article in the same group I just increment it until it's unique.
    This system would break down if a group got more than one post per
    second for a sustained period, but at that level of traffic other
    things would probably be breaking anyway.

    This system makes it easy to combine posts from different sources
    with consistent ordering. On the downside, computing the number of
    new posts for a user is no longer just subtracting the new highest
    post number from what it was on their last visit. That is now an
    SQL query to count the number of posts with timestamps higher than
    the previous highest one, but with a suitable index that's very fast.

    One tricky point is that this per-group de-duplication of timestamps
    can cause a cross-posted article to have different timestamps in
    different groups. For a cross-posted article I provide links to see
    it in the context of each other group where it exists, but I can't use timestamp-based links for this because they might vary, so here I use
    the same kind of group/<msgid> link you describe.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to news.software.nntp on Thu May 7 23:23:20 2026
    From Newsgroup: news.software.nntp

    Colin Macleod <user7@newsgrouper.org.invalid> wrote or quoted:
    different groups. For a cross-posted article I provide links to see
    it in the context of each other group where it exists, but I can't use >timestamp-based links for this because they might vary, so here I use

    The "normalized" approach in a relational database would be to have
    one group for posts,

    POST
    ID date header_A header_B body
    1 . . .
    2 . . .
    3 . . .

    , one group for newsgroups,

    NEWSGROUP
    ID name
    1 news.software.nntp
    2 alt.folklore.computer
    3 alt.usage.english

    , and one table for the relation "post-group",

    POST_GROUP
    1 1
    1 2
    2 2

    , which would mean "post 1 was crossposted to group 1 and 2,
    post 2 was posted to group 2".

    The IDs would be unique numbers generated by the DB on insert.

    But since you mention "links", and relational database terminology
    does not have "links", it's possible you are using some other type
    of database - then the above approach might not be appropriate.

    Now, we just need to know whether a post that just came
    from a server already is in the database. One could use
    the message ID for that, but message IDs do not have to be
    unique over a long timespan of decades I think, so one might
    combine the message ID with the date or something.

    Then, what if a post from another server has the same MID and
    date, but differs in the Path header? Ok, but, what if it differs
    in the "From" header? One From header might have the full original
    From, the other From header might have an mail address mangled to
    "privacy-protect" it. What if the two versions of that post differ
    in their body? Maybe one version of the post came from a history
    where one party tried to "repair" or "fix" the encoding of the
    body. One version might be the body with correct encodings, one with
    broken encodings. Do we want to add rules to assess which variant of
    a header or body is better and store only this one? Or store both,
    maybe using a compression scheme that only stores the diffs?


    --- Synchronet 3.21f-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to news.software.nntp on Fri May 8 06:48:49 2026
    From Newsgroup: news.software.nntp

    ram@zedat.fu-berlin.de (Stefan Ram) posted:

    Colin Macleod <user7@newsgrouper.org.invalid> wrote or quoted:
    different groups. For a cross-posted article I provide links to see
    it in the context of each other group where it exists, but I can't use >timestamp-based links for this because they might vary, so here I use

    The "normalized" approach in a relational database would be to have
    one group for posts,

    You can see the db schema I use for Newsgrouper in https://chiselapp.com/user/cmacleod/repository/newsgrouper/file?name=scripts/db_create.tcl&ci=tip

    It's not fully normalised, the 'over' table duplicates info for cross-posted articles. 'dat' is the unix timestamp I explained in my previous post.
    'prev' is the msgid of the post which this one is replying to, if any. 'xgrpids' is a list of ids of any other groups this article is posted to. Actually 'posts' in the groups table is no longer used.
    Here /data is a 1TB ssd, /data2 is a 4TB hdd.


    But since you mention "links", and relational database terminology
    does not have "links", it's possible you are using some other type
    of database - then the above approach might not be appropriate.

    I'm using this data to generate a web interface, so by 'links' I mean
    web hyperlinks. The db indexes make it practical to find the posts
    when those links are clicked.


    Now, we just need to know whether a post that just came
    from a server already is in the database. One could use
    the message ID for that, but message IDs do not have to be
    unique over a long timespan of decades I think, so one might
    combine the message ID with the date or something.

    My understanding is that message-ids *are* expected to be globally
    unique for all time, and my code relies on that. Once a specific
    msgid,grpid combination has been loaded into the 'over' table,
    any duplicates of that seen later will be ignored.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Kevin Bowling@kevin.bowling@kev009.com to news.software.nntp on Sun May 17 14:06:36 2026
    From Newsgroup: news.software.nntp

    On 5/1/26 09:31, Kevin Bowling wrote:
    I made a web thing: http://csiph.com/groups

    It's like google groups but it sucks less.

    Some major updates:
    1) True multi-lingual search. This was pretty intense so I am curious
    how it works for people interested in other languages. In particular I
    had to write a CJK tokenizer based on Lucene's. Languages with a
    snowball stemmer get native tokenization and stemming. The default "all languages" allows faceted search so you don't necessarily need to select
    a language for basic searches.
    2) Keyboard shortcuts. I found a way to do it without JS, it is a
    little quirky per browser without JS but it's there for power users.
    3) Signup flow changes. You now have to verify your email, but there is
    an additional "display email" field that may be fictitious for public
    posting.
    4) CSIPH inn changes.. running the patches in my "INN scalability enhancements" post, plus added canlock to the FreeBSD port (csiph-web is exempt for now because the service account would have to manage them
    itself, but NNTP works). Will deploy (optional) HTTPS and NNTPS shortly.

    Regards,
    Kevin
    --- Synchronet 3.22a-Linux NewsLink 1.2