@prologic@twtxt.net Well ain’t that grand? I’ll get it updated
On my blog: Free Culture News https://john.colagioia.net/blog/2024/06/09/free-culture-news.html #freeculture #linkdump #update
I think it is a good addition. Similar to how the Fraidycat RSS reader works. Fraidyc.at also support twtxt, but have not seen any updates since 2021…
@lyse@lyse.isobeef.org its a hierarchy key value format. I designed it for the network peering tools i use.. I can grant access to different parts of the tree to other users.. kinda like directory permissions. a basic example of the format is:
@namespace
# multi
# line
# comment
root :value
# example space comment
@namespace.name space-tag
# attribute comments
attribute attr-tag :value for attribute
# attribute with multiple
# lines of values
foo :bar
:bin
:baz
repeated :value1
repeated :value2
each @ starts the definition of a namespace kinda like [name] in ini format. It can have comments that show up before. then each attribute is key :value and can have their own # comment lines.
Values can be multi line.. and also repeated..
the namespaces and values can also have little meta data tags added to them.

the service can define webhooks/mqtt topics to be notified when the configs are updated. That way it can deploy the changes out when they are updated.
Finally getting around to cleaning up and updating my todo.txt file. Maybe I should put a task in there to remind me to check it.
@adi@twtxt.net I think it is, and one benefit they have is that you can add third-party repositories to the F-Droid app as you discover them. So, for instance, if you know of a developer who pushes builds to an F-Droid compatible repository, you can add that to your F-Droid app and start tracking updates like you would for any other app in there. Can’t do that with Google Play!
F-Droid tends to focus on open source applications that can be built in a reproducible way, which limits the inventory (though of course tends to mean the apps are safer and don’t spy on you). There are non-free apps in there as well but they come with warnings so you’re informed about what you might be sacrificing by using them.
That said if you have a favorite app you get through Google Play, there’s a decent chance it won’t be in F-Droid. Many “big corporate” apps aren’t, and vendor-specific apps tend not to be either. But for most of the major functions you might want, like email clients, calendar apps, weather apps, etc etc, there are very good substitutes now in F-Droid. You’re definitely making a trade-off though.
What I did was go through the apps I had installed on my last phone, found as many substitutes in F-Droid as I could, started using those instead to see how they worked, and bit by bit replaced as much as I could from Google Play with a comparable app from F-Droid. I still have a few apps (mostly vendor-specific things that don’t have substitutes) that come from Google Play but I’m aiming to be rid of those before I need to replace this phone.
My home ISP has had a few prefixes allocated. They haven’t rolled of out yet because their custom CRM system needs to be updated to be able to allocate/bill for it. Along other reasons they gave when I asked last.
Google Says It’ll Scrape Everything You Post Online for AI
Google updated its privacy policy over the weekend, explicitly saying the company reserves the right to scrape just about everything you post online to build its AI tools.
Google can eat shit.
Funny.. I would never buy an iPhone again. My wife switched back this last phone update and I can’t stand the interface.
twtxt, as I believe it was originally intended, are short little status updates – that’s it.
So, basically a .plan file for finger. But, on the web. like a *web*finger. We have come full circle on this loop!
@prologic@twtxt.net I have updated to kinda follow this. It now redirects to other webfingers if the resource has a different hostname. I’m still not sure what I should put multiple services with the same domain name. Like if they were to have conflicting properties.
$name$ and then dispatch the hashing or checking to its specific format.
Circling back to the IsPreferred method. A hasher can define its own IsPreferred method that will be called to check if the current hash meets the complexity requirements. This is good for updating the password hashes to be more secure over time.
func (p *Passwd) IsPreferred(hash string) bool {
_, algo := p.getAlgo(hash)
if algo != nil && algo == p.d {
// if the algorithm defines its own check for preference.
if ck, ok := algo.(interface{ IsPreferred(string) bool }); ok {
return ck.IsPreferred(hash)
}
return true
}
return false
}
https://github.com/sour-is/go-passwd/blob/main/passwd.go#L62-L74
example: https://github.com/sour-is/go-passwd/blob/main/pkg/argon2/argon2.go#L104-L133
$name$ and then dispatch the hashing or checking to its specific format.
Here is an example of usage:
func Example() {
pass := "my_pass"
hash := "my_pass"
pwd := passwd.New(
&unix.MD5{}, // first is preferred type.
&plainPasswd{},
)
_, err := pwd.Passwd(pass, hash)
if err != nil {
fmt.Println("fail: ", err)
}
// Check if we want to update.
if !pwd.IsPreferred(hash) {
newHash, err := pwd.Passwd(pass, "")
if err != nil {
fmt.Println("fail: ", err)
}
fmt.Println("new hash:", newHash)
}
// Output:
// new hash: $1$81ed91e1131a3a5a50d8a68e8ef85fa0
}
This shows how one would set a preferred hashing type and if the current version of ones password is not the preferred type updates it to enhance the security of the hashed password when someone logs in.
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L33-L59
Twting to see if it will update my links list.
it uses the queries you define for add/del/set/keys. which corrispond to something like INSERT INTO <table> (key, value) VALUES ($key, $value), DELETE ..., or UPDATE ...
the commands are issued by using the maddycli but not the running maddy daemon.
see https://maddy.email/reference/table/sql_query/
the best way to locate in source is anything that implements the MutableTable interface… https://github.com/foxcpp/maddy/blob/master/framework/module/table.go#L38
@tiktok@sour.is Hmm why arn’t you updating?
(cont.)
Just to give some context on some of the components around the code structure.. I wrote this up around an earlier version of aggregate code. This generic bit simplifies things by removing the need of the Crud functions for each aggregate.
Domain ObjectsA domain object can be used as an aggregate by adding the event.AggregateRoot struct and finish implementing event.Aggregate. The AggregateRoot implements logic for adding events after they are either Raised by a command or Appended by the eventstore Load or service ApplyFn methods. It also tracks the uncommitted events that are saved using the eventstore Save method.
type User struct {
Identity string ```json:"identity"`
CreatedAt time.Time
event.AggregateRoot
}
// StreamID for the aggregate when stored or loaded from ES.
func (a *User) StreamID() string {
return "user-" + a.Identity
}
// ApplyEvent to the aggregate state.
func (a *User) ApplyEvent(lis ...event.Event) {
for _, e := range lis {
switch e := e.(type) {
case *UserCreated:
a.Identity = e.Identity
a.CreatedAt = e.EventMeta().CreatedDate
/* ... */
}
}
}
Events
Events are applied to the aggregate. They are defined by adding the event.Meta and implementing the getter/setters for event.Event
type UserCreated struct {
eventMeta event.Meta
Identity string
}
func (c *UserCreated) EventMeta() (m event.Meta) {
if c != nil {
m = c.eventMeta
}
return m
}
func (c *UserCreated) SetEventMeta(m event.Meta) {
if c != nil {
c.eventMeta = m
}
}
Reading Events from EventStore
With a domain object that implements the event.Aggregate the event store client can load events and apply them using the Load(ctx, agg) method.
// GetUser populates an user from event store.
func (rw *User) GetUser(ctx context.Context, userID string) (*domain.User, error) {
user := &domain.User{Identity: userID}
err := rw.es.Load(ctx, user)
if err != nil {
if err != nil {
if errors.Is(err, eventstore.ErrStreamNotFound) {
return user, ErrNotFound
}
return user, err
}
return nil, err
}
return user, err
}
OnX Commands
An OnX command will validate the state of the domain object can have the command performed on it. If it can be applied it raises the event using event.Raise() Otherwise it returns an error.
// OnCreate raises an UserCreated event to create the user.
// Note: The handler will check that the user does not already exsist.
func (a *User) OnCreate(identity string) error {
event.Raise(a, &UserCreated{Identity: identity})
return nil
}
// OnScored will attempt to score a task.
// If the task is not in a Created state it will fail.
func (a *Task) OnScored(taskID string, score int64, attributes Attributes) error {
if a.State != TaskStateCreated {
return fmt.Errorf("task expected created, got %s", a.State)
}
event.Raise(a, &TaskScored{TaskID: taskID, Attributes: attributes, Score: score})
return nil
}
Crud Operations for OnX Commands
The following functions in the aggregate service can be used to perform creation and updating of aggregates. The Update function will ensure the aggregate exists, where the Create is intended for non-existent aggregates. These can probably be combined into one function.
// Create is used when the stream does not yet exist.
func (rw *User) Create(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
// Update is used when the stream already exists.
func (rw *User) Update(
ctx context.Context,
identity string,
fn func(*domain.User) error,
) (*domain.User, error) {
session, err := rw.GetUser(ctx, identity)
if err != nil {
return nil, err
}
if err = fn(session); err != nil {
return nil, err
}
_, err = rw.es.Save(ctx, session)
return session, err
}
I have updated my eventDB to have subscriptions! It now has websockets like msgbus. I have also added a in memory store that can be used along side the disk backed wal.
Boot drive failed on the server that hosts my Gemini capsule’s headless repo. Now there will officially be no updates until it’s fixed!
One year ago to the date I made the lastest update for #phpub2twtxt to github and now 365 days later I have published #pixelblog as its successor - lets see where things are going for trip around the sun
Okay, I’ve updated my examples page and shared the more complex ssh example. http://a.9srv.net/shortcuts
Love the new icons on the latest update!
@movq@www.uninformativ.de
Updated. Will it be possible for the subject be moved at the begining instead (like Yarn and tt do)?
@movq@www.uninformativ.de
Meanwhile I only restart my iPhone when an iOS update is available, which normally happens every 4-5 months or so, or more. 😋
@prologic@twtxt.net finally updated yarnd.. FORK!? Awesome!
Once a day.. though if it hasn’t updated in n-months maybe once a week?
Plan 9 got three slots in GSoC; we’ll be working on an updated Japanese input method, updating edwood, and getting Oauth2 support. 🎉🐇
@mckinley@twtxt.net @prologic@twtxt.net I have updated the ticket with my findings.. its not what you expect! /clickbait https://github.com/jointwt/twtxt/issues/424
Pushed small updates to tw. Next: make discoverability optional.
@vain@www.uninformativ.dedd @lyse@lyse.isobeef.orgdd @prologic@twtxt.netdd Nope.. i have updated my gist to include the feeds listing. feeds.txt
@prologic@twtxt.net the add function just scans recursivley everything.. but the idea is to just add and any new mentions then have a cron to update all known feeds
@prologic@twtxt.net yeah I do.
It seems a bit wonky that it imports from your packages in some places. I’m guessing that’s some legacy bits that need updates?
@lyxal@twtxt.net @prologic@twtxt.net if we edit the txt file does it update on web?
Did some work on WKD handling. Can update keys with HKP posts :) Ugh need to work on docs and unit tests. Boooorrring.
@prologic@twtxt.net Oh snap. that’s what i get for copy paste! ill just have to repost and update my key.
On the blog: Mid-Year Media Updates https://john.colagioia.net/blog/2020/06/28/media.html #media #nonfree
On the blog: Sitting Is the New Blah, Blah, Blah https://john.colagioia.net/blog/2020/06/14/standing.html #update #rant
On the blog: Some Updates https://john.colagioia.net/blog/2020/06/07/updates.html #update #rant
Posted to Entropy Arbitrage: Project Updates, Harriet Tubman Day https://john.colagioia.net/blog/2020/03/09/post-bicker.html #programming #project #devjournal #css #jekyll