WIP: feat: get remote person's avatar and assign to user #9
4 changed files with 109 additions and 0 deletions
|
@ -185,3 +185,28 @@ func GetRemoteUsersWithNoLocalFollowers(ctx context.Context, olderThan time.Dura
|
||||||
return users, nil
|
return users, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetRemotePersons(ctx context.Context, page int) ([]FederatedUser, error) {
|
||||||
|
limit := 1
|
||||||
|
offset := page * limit
|
||||||
|
var federatedUsers []FederatedUser
|
||||||
|
|
||||||
|
err := db.GetEngine(ctx).
|
||||||
|
Table("federated_user").
|
||||||
|
Limit(limit, offset).
|
||||||
|
Find(&federatedUsers)
|
||||||
|
|
||||||
|
// TODO: this doesn't work, so fetching federated_user and then getting user. How to make this work?
|
||||||
|
// var users []user.User
|
||||||
|
// err := db.GetEngine(ctx).
|
||||||
|
// Table("user").
|
||||||
|
// Join("inner", "federated_user", "federated_user.user_id = user.id").
|
||||||
|
// Limit(limit, offset).
|
||||||
|
// Find(&users)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Trace("Error: GetRemotePersons: %w", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return federatedUsers, nil
|
||||||
|
}
|
||||||
|
|
|
@ -2922,6 +2922,7 @@ dashboard.sync_branch.started = Branches Sync started
|
||||||
dashboard.sync_tag.started = Tags Sync started
|
dashboard.sync_tag.started = Tags Sync started
|
||||||
dashboard.rebuild_issue_indexer = Rebuild issue indexer
|
dashboard.rebuild_issue_indexer = Rebuild issue indexer
|
||||||
dashboard.remote_actor_cleanup = Clean remote actors with no local followers
|
dashboard.remote_actor_cleanup = Clean remote actors with no local followers
|
||||||
|
dashboard.remote_actor_update = Update remote actors' data
|
||||||
|
|
||||||
users.user_manage_panel = Manage user accounts
|
users.user_manage_panel = Manage user accounts
|
||||||
users.new_account = Create User Account
|
users.new_account = Create User Account
|
||||||
|
|
|
@ -195,6 +195,7 @@ func initBasicTasks() {
|
||||||
|
|
||||||
if setting.Federation.Enabled {
|
if setting.Federation.Enabled {
|
||||||
registerCleanupRemotePersonsWithNoFollowers()
|
registerCleanupRemotePersonsWithNoFollowers()
|
||||||
|
registerUpdateRemotePersons()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -212,3 +213,15 @@ func registerCleanupRemotePersonsWithNoFollowers() {
|
||||||
return forgefed_service.CleanUpRemotePersons(ctx, acConfig.OlderThan)
|
return forgefed_service.CleanUpRemotePersons(ctx, acConfig.OlderThan)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func registerUpdateRemotePersons() {
|
||||||
|
RegisterTaskFatal("remote_actor_update", &OlderThanConfig{
|
||||||
|
BaseConfig: BaseConfig{
|
||||||
|
Enabled: true,
|
||||||
|
RunAtStart: true,
|
||||||
|
Schedule: "@every 6h",
|
||||||
|
},
|
||||||
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
||||||
|
return forgefed_service.UpdatePersonActor(ctx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -123,6 +123,20 @@ func SavePerson(ctx context.Context, person *ap.Person) (*user.User, error) {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetActorFromUser(ctx context.Context, u *user.User) (*ap.Actor, error) {
|
||||||
|
|
||||||
|
alias := u.Name
|
||||||
|
|
||||||
|
webfingerRes, err := WebFingerLookup(alias)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
actorID := webfingerRes.GetActorLink().Href
|
||||||
|
|
||||||
|
return GetActor(actorID)
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up remote actors (persons) without any followers in local instance
|
// Clean up remote actors (persons) without any followers in local instance
|
||||||
func CleanUpRemotePersons(ctx context.Context, olderThan time.Duration) error {
|
func CleanUpRemotePersons(ctx context.Context, olderThan time.Duration) error {
|
||||||
page := 0
|
page := 0
|
||||||
|
@ -147,3 +161,59 @@ func CleanUpRemotePersons(ctx context.Context, olderThan time.Duration) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdatePersonActor(ctx context.Context) error {
|
||||||
|
// NOTE: change of any of these don't matter at this point since we are
|
||||||
|
// ignoring actor's PreferredUsername and using their address to generate
|
||||||
|
// username and email. Ask suggestions from other devs.
|
||||||
|
//
|
||||||
|
// fmt.Println(person.ID.String())
|
||||||
|
// hostname, err := GetHostnameFromResource(person.ID.String())
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// u := new(user.User)
|
||||||
|
// u.Name = "@" + person.PreferredUsername.String() + "@" + hostname
|
||||||
|
// //panic(u.Name)
|
||||||
|
// u.Email = person.PreferredUsername.String() + "@" + hostname
|
||||||
|
// u.Website = person.URL.GetID().String()
|
||||||
|
// u.KeepEmailPrivate = true
|
||||||
|
|
||||||
|
page := 0
|
||||||
|
for {
|
||||||
|
federatedUsers, err := federation.GetRemotePersons(ctx, page)
|
||||||
|
if len(federatedUsers) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Trace("Error: UpdatePersonActor: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range federatedUsers {
|
||||||
|
log.Info("Updating users, got %s", f.ExternalID)
|
||||||
|
u, err := user.GetUserByName(ctx, f.ExternalID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Got error while getting user: %w", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
person, err := GetActorFromUser(ctx, u)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Got error while fetching actor: %w", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
avatar, err := GetPersonAvatar(ctx, person)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Got error while fetching avatar: %w", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if u.IsUploadAvatarChanged(avatar) {
|
||||||
|
_ = user_service.UploadAvatar(ctx, u, avatar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page += 1
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue