Libove Blog

Personal Blog about anything - mostly programming, cooking and random thoughts

Valley of Dunes

Valley of Dunes

Serenity

Serenity

Endurance

Endurance

Open Sourced: Fedi-Games

I've open sourced fedi-games, as previously mentioned here. The code is still quiet rough as this is a learning project for me. But maybe someone finds this useful to implement their own ActivityPub server. Or maybe someone wants to build some new games :)


Fediverse Games

In order to understand the ActivityPub protocol (at some point I want to make my blog available via ActivityPub) I've created a minimal server hosting game services for the Fediverse.

The service is currently hosted on games.rerere.org and provides three games:

  • Rock Paper Scissors
  • Tic-Tac-Toe
  • Bunkers, an artillery game

The games can be played by mentioning the service and and your opponent in a note. I've mainly tested these with Mastodon but they should also work with other fediverse apps.

Screenshot from the Bunkers games

I want to release the source code soon, but it still needs some clean up, documentation and testing to be useful to anyone. The server is written in go and if you want to build something similar I've used these libraries to help with the ActivityPub implementation:


#


#


Inheritance Pattern in Go

Go isn't an object oriented language and doesn't have inheritance. Sometimes I still want to model something in a similar way as I would in an object oriented languages. My blog software has different types of "entries", e.g. articles, images, recipes ... This is modeled by an interface Entry which has to be implemented by each type of post.

// truncated for simplicity
type Entry interface {
	ID() string
	Content() EntryContent
	PublishedAt() *time.Time
	Title() string
	SetID(id string)
	SetPublishedAt(publishedAt *time.Time)
}

One problem with this is, that I have to implement these functions for each type of entry. Many of these implementation will be identical leading to a high degree of code duplication. To avoid this I've created an EntryBase, which implements sensible defaults.

type EntryBase struct {
	id          string
	publishedAt *time.Time
}

func (e *EntryBase) ID() string {
	return e.id
}

func (e *EntryBase) PublishedAt() *time.Time {
	return e.publishedAt
}

func (e *EntryBase) SetID(id string) {
	e.id = id
}

func (e *EntryBase) SetPublishedAt(publishedAt *time.Time) {
	e.publishedAt = publishedAt
}

With this "base class" the specific implementations only have to implement functions which differ between entry types.

type Article struct {
	EntryBase
	meta ArticleMetaData
}

type ArticleMetaData struct {
	Title   string
	Content string
}


func (e *Article) Title() string {
	return e.meta.Title
}

func (e *Article) Content() model.EntryContent {
    // render content from markdown	
}

Pilz Kichererbsen Risotto

Servings: 3 Portionen , Prep Time:

Ingredients

  • 250g Risotto Reis
  • 1 Glas Kichererbsen
  • 400g Champignons
  • 2 kleine Zwiebel
  • 2 Knoblauchzehen
  • 25g getrocknete Pilze
  • 300ml Gemüsebrühe
  • ½ Dose Kokosmilch
  • 1 EL Sojasoße
  • 1 EL Balsamico Essig
  • Thymian und Pfeffer

Instructions

  • Getrocknete Pilze in 300 ml Wasser einweichen (~30 min). Aus Wasser nehmen und grob hacken. Wasser aufbewahren!
  • Pilze in Würfel schneiden und in Olivenöl goldbraun anbraten. Anschließen aus der Pfanne nehmen und beiseite Stellen.
  • Zwiebel und Knoblauch fein gehackt bei mittlerer Hitze leicht braun anbraten.
  • Reis und getrocknete Pilze hinzufügen und 1-2 Minuten mit anbraten. Mit Pilzewasser ablöschen.
  • Pilze und Kichererbsen hinzufügen.
  • Mischung aus Gemüsebrühe, Sojasoße, Essig und Thymian portionsweise hinzugeben.
  • Solange kochen und Flüssigkeit hinzufügen bis Reis fast gar ist.
  • Kokosmilch und Pfeffer hinzufügen. Für etwa 5 Minuten kochen bis gewünschte Konsistenz erreicht ist.

Soap Bubble

Soap Bubble