🧮 USERS:1 FEEDS:2 TWTS:333 ARCHIVED:36357 CACHE:1579 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:332 ARCHIVED:36316 CACHE:1563 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:331 ARCHIVED:36304 CACHE:1600 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:330 ARCHIVED:36287 CACHE:1596 FOLLOWERS:13 FOLLOWING:14
🧮 Users: 2, Feeds: 6, Twts: 1026, Archived: 1116347, Cache: 89202, Followers: 29, and Following: 701.
🧮 USERS:1 FEEDS:2 TWTS:329 ARCHIVED:36277 CACHE:1614 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:328 ARCHIVED:36263 CACHE:1622 FOLLOWERS:13 FOLLOWING:14
👋 Hello @burglar@txt.sour.is, welcome to txt.sour.is, a Yarn.social Pod! To get started you may want to check out the pod’s Discover feed to find users to follow and interact with. To follow new users, use the ⨁ Follow button on their profile page or use the Follow form and enter a Twtxt URL. You may also find other feeds of interest via Feeds. Welcome! 🤗
👋 Hello @burglar@txt.sour.is, welcome to txt.sour.is, a Yarn.social Pod! To get started you may want to check out the pod’s Discover feed to find users to follow and interact with. To follow new users, use the ⨁ Follow button on their profile page or use the Follow form and enter a Twtxt URL. You may also find other feeds of interest via Feeds. Welcome! 🤗
🧮 USERS:1 FEEDS:2 TWTS:327 ARCHIVED:36241 CACHE:1665 FOLLOWERS:13 FOLLOWING:14
I’ve realized that trying to strictly follow what is on the IndieWeb wiki won’t work well for me. Thus, I have to invent and change some things to make it work better. ⌘ Read more
(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
}
(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
}
🧮 USERS:1 FEEDS:2 TWTS:326 ARCHIVED:36217 CACHE:1658 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:325 ARCHIVED:36174 CACHE:1662 FOLLOWERS:13 FOLLOWING:14
The XMPP Standards Foundation: Mid Term Evaluation Updates
It’s been a month since I wrote my last blog. For those of you who have been following my blogs, thanks a lot for taking the time to read them. In this blog, I will give the updates post mid-term evaluation and the challenges that I have been facing and how I overcame some of them.
For those of you who don’t know much about GSoC, a mid-term evaluat … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:324 ARCHIVED:36126 CACHE:1630 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:323 ARCHIVED:36095 CACHE:1620 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:322 ARCHIVED:36071 CACHE:1610 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:321 ARCHIVED:36041 CACHE:1614 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:320 ARCHIVED:36015 CACHE:1629 FOLLOWERS:13 FOLLOWING:14
To all my feed subscribers: If you are annoyed by the TTS audio or the “Interactions” link, add a “.min” in front of the feed type in the URL. For example https://jlelse.blog/.min.rss. Thanks for following! 😄 ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:319 ARCHIVED:35977 CACHE:1621 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:318 ARCHIVED:35951 CACHE:1608 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:317 ARCHIVED:35790 CACHE:1611 FOLLOWERS:13 FOLLOWING:14
Ignite Realtime Blog: REST API Openfire plugin 1.9.1 released!
Woopsie doodle! It turns out that a rather annoying bug was introduced in version 1.9.0 of the REST API plugin for Openfire, that we released earlier today!
To avoid unnecessary issues, we’ve decided to follow up with an immediate new release that addresses this issue. … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:316 ARCHIVED:35745 CACHE:1618 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:315 ARCHIVED:35714 CACHE:1620 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:314 ARCHIVED:35694 CACHE:1628 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:313 ARCHIVED:35653 CACHE:1609 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:312 ARCHIVED:35548 CACHE:1535 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:311 ARCHIVED:35521 CACHE:1525 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:310 ARCHIVED:35401 CACHE:1496 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:309 ARCHIVED:35369 CACHE:1481 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:308 ARCHIVED:35338 CACHE:1485 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:307 ARCHIVED:35290 CACHE:1458 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:306 ARCHIVED:35250 CACHE:1455 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:305 ARCHIVED:35225 CACHE:1459 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:304 ARCHIVED:35175 CACHE:1452 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:303 ARCHIVED:35163 CACHE:1475 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:302 ARCHIVED:35148 CACHE:1473 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:301 ARCHIVED:35133 CACHE:1463 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:300 ARCHIVED:35117 CACHE:1470 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:299 ARCHIVED:35064 CACHE:1473 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:298 ARCHIVED:35034 CACHE:1450 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:297 ARCHIVED:35006 CACHE:1434 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:296 ARCHIVED:34976 CACHE:1413 FOLLOWERS:13 FOLLOWING:14
Minkowski Space
⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:295 ARCHIVED:34938 CACHE:1394 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:294 ARCHIVED:34917 CACHE:1389 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:293 ARCHIVED:34885 CACHE:1387 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:292 ARCHIVED:34863 CACHE:1384 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:291 ARCHIVED:34842 CACHE:1418 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:290 ARCHIVED:34827 CACHE:1421 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:289 ARCHIVED:34810 CACHE:1428 FOLLOWERS:13 FOLLOWING:14
No more Telegram Premium
Telegram decided to cancel my Premium, I got the following message from the @PremiumBot: ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:288 ARCHIVED:34804 CACHE:1427 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:287 ARCHIVED:34793 CACHE:1449 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:286 ARCHIVED:34787 CACHE:1461 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:285 ARCHIVED:34767 CACHE:1465 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:284 ARCHIVED:34741 CACHE:1467 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:283 ARCHIVED:34725 CACHE:1489 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:282 ARCHIVED:34707 CACHE:1492 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:281 ARCHIVED:34685 CACHE:1484 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:280 ARCHIVED:34669 CACHE:1493 FOLLOWERS:13 FOLLOWING:14
Taiwan slams Beijing for blocking UN Ocean Conference delegates
Taipei vows to oppose mainland’s ‘malign influence’ in organisation following latest diplomatic snub. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:279 ARCHIVED:34650 CACHE:1498 FOLLOWERS:13 FOLLOWING:14
Is the US setting up an ‘Asia-style Nato’? North Korea thinks so
Pyongyang also blamed US hostility for forcing North Korea to develop stronger defences, following recent joint exercises with South Korea and Japan. ⌘ Read more
Rupture and reset (2017-2022): Hong Kong’s turbulent years and Covid-19 battle in 25 photos
A months-long anti-government movement that brought the city to its knees was followed by the emergence of a crippling pandemic. These are Hong Kong’s years of hard knocks, but a new chapter beckons that may offer renewal. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:278 ARCHIVED:34640 CACHE:1502 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:277 ARCHIVED:34627 CACHE:1503 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:276 ARCHIVED:34470 CACHE:1475 FOLLOWERS:13 FOLLOWING:14
Chinese security official calls for crackdown on gangs following Tangshan attack
The political and legal affairs chief urges authorities to ‘fight against evil’ in the wake of a brutal assault on women in northern China. ⌘ Read more
Following Friends in Fitness Apps is Associated with Higher Levels of Physical Activity
[Sponsored Article]
The past few years have seen huge growth in mobile fitness apps globally. Expecting increased revenue to be generated from this category, app designers strive to add features to enhance the user experience and motivate better performance.
Dr HUANG Guanxiong, Dr Crystal JIANG Li, and doctoral student SUN Mengru from CityU’s … ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:275 ARCHIVED:34441 CACHE:1479 FOLLOWERS:13 FOLLOWING:14
China’s strict Covid-19 border controls show more signs of easing, as Zhejiang province cuts entry quarantine
Beijing and Wuhan among cities already following relaxed rule, as China seeks to repair damage to travel and aviation sectors. ⌘ Read more
Malaysia’s role pressuring Myanmar junta praised by UN human rights expert
Tom Andrews urged 10-member bloc Asean to follow Malaysia’s lead and move from non-interference to ‘non-indifference’ in Myanmar, with much more needing to be done to avoid more death and suffering. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:274 ARCHIVED:34430 CACHE:1492 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:273 ARCHIVED:34398 CACHE:1491 FOLLOWERS:13 FOLLOWING:14
the-spatializer/instagram-follower-scraper
Scrap Instagram Follower, detect accounts you follow, accounts that follow you, accounts that follow you but you don’t follow back, accounts you follow but don’t follow you back using python
Language: Python
Star: 1
Watch: 1 ⌘ Read more
jerrykhh/ig_follower
Instagram follower to CSV and auto-follow
Language: Python
Star: 7
Watch: 7 ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:272 ARCHIVED:34354 CACHE:1524 FOLLOWERS:13 FOLLOWING:14
Russian journalist sells Nobel Prize for Ukrainian children – worth millions
‘It has to become a beginning of a flash mob as an example to follow so people auction their valuable possessions to help Ukrainians,’ said Dmitry Muratov, who shared Nobel Peace Prize with Filipino journalist Maria Ressa. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:271 ARCHIVED:34334 CACHE:1534 FOLLOWERS:13 FOLLOWING:14
following legislation from the ELSC (european long site commission), I now have to adopt an ocelot
🧮 USERS:1 FEEDS:2 TWTS:270 ARCHIVED:34313 CACHE:1557 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:269 ARCHIVED:34277 CACHE:1541 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:268 ARCHIVED:34262 CACHE:1550 FOLLOWERS:13 FOLLOWING:14
Elimination of nuclear weapons an urgent need, UN chief warns
UN’s Antonio Guterres said it is important to ‘focus on the humanitarian consequences of nuclear weapons’. There are concerns Moscow will follow through on threats and about China and North Korea expanding their nuclear capabilities. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:267 ARCHIVED:34252 CACHE:1547 FOLLOWERS:13 FOLLOWING:14
Hong Kong raises key interest rate by 75 basis points in lockstep with Federal Reserve hike overnight
The Hong Kong Monetary Authority (HKMA) raised the city’s base rate by 75 basis points to 2 per cent, following the Fed’s most aggressive hike since 1994. ⌘ Read more
Australia-China relations: Canberra’s foreign minister Penny Wong to travel to Solomon Islands amid China security pact concerns
Australia, New Zealand, Japan and the US have voiced concerns Beijing could establish a military presence in the Pacific following the signing of a security pact with the Solomon Islands. ⌘ Read more
🧮 USERS:1 FEEDS:2 TWTS:266 ARCHIVED:34234 CACHE:1551 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:265 ARCHIVED:34209 CACHE:1542 FOLLOWERS:13 FOLLOWING:14
🧮 USERS:1 FEEDS:2 TWTS:264 ARCHIVED:34172 CACHE:1525 FOLLOWERS:13 FOLLOWING:14
🧮 Users: 2, Feeds: 6, Twts: 1007, Archived: 886396, Cache: 121354, Followers: 29, and Following: 699.
🧮 USERS:1 FEEDS:2 TWTS:263 ARCHIVED:34140 CACHE:1500 FOLLOWERS:13 FOLLOWING:14
My current state regarding meal replacements
In my 2019 Year in Review, I wrote the following: ⌘ Read more
🧮 Users: 2, Feeds: 6, Twts: 1006, Archived: 883595, Cache: 122433, Followers: 29, and Following: 699.
🧮 USERS:1 FEEDS:2 TWTS:262 ARCHIVED:34084 CACHE:1458 FOLLOWERS:13 FOLLOWING:14