/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/service/contacts.go
254 строки
8 KB
zoom-ua
remove golang.org/x/net/context in favor of context (#28708)
17 дек 2025, 18:24
Не верифицирован
17 дек 2025, 18:24
67b0ffe
Код
Авторство
О чём код?
// Copyright 2019 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package service import ( "context" "fmt" "sort" "time" "github.com/keybase/client/go/contacts" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" "github.com/keybase/client/go/uidmap" "github.com/keybase/go-framed-msgpack-rpc/rpc" ) type bulkLookupContactsProvider struct{} var _ contacts.ContactsProvider = (*bulkLookupContactsProvider)(nil) func (c *bulkLookupContactsProvider) LookupAllWithToken(mctx libkb.MetaContext, emails []keybase1.EmailAddress, numbers []keybase1.RawPhoneNumber, token contacts.Token, ) (contacts.ContactLookupResults, error) { defer mctx.Trace(fmt.Sprintf("bulkLookupContactsProvider#LookupAllWithToken(len=%d)", len(emails)+len(numbers)), nil)() return contacts.BulkLookupContacts(mctx, emails, numbers, token) } func (c *bulkLookupContactsProvider) LookupAll(mctx libkb.MetaContext, emails []keybase1.EmailAddress, numbers []keybase1.RawPhoneNumber, ) (contacts.ContactLookupResults, error) { defer mctx.Trace(fmt.Sprintf("bulkLookupContactsProvider#LookupAll(len=%d)", len(emails)+len(numbers)), nil)() return c.LookupAllWithToken(mctx, emails, numbers, contacts.NoneToken) } func (c *bulkLookupContactsProvider) FindUsernames(mctx libkb.MetaContext, uids []keybase1.UID, ) (res map[keybase1.UID]contacts.ContactUsernameAndFullName, err error) { defer mctx.Trace(fmt.Sprintf("bulkLookupContactsProvider#FillUsernames(len=%d)", len(res)), nil)() const fullnameFreshness = 10 * time.Minute const networkTimeBudget = uidmap.DefaultNetworkBudget const forceNetworkForFullNames = true nameMap, err := uidmap.MapUIDsReturnMapMctx(mctx, uids, fullnameFreshness, networkTimeBudget, forceNetworkForFullNames) if err != nil { return nil, err } res = make(map[keybase1.UID]contacts.ContactUsernameAndFullName) for uid, v := range nameMap { ufp := contacts.ContactUsernameAndFullName{ Username: v.NormalizedUsername.String(), } if fullNamePkg := v.FullName; fullNamePkg != nil { ufp.Fullname = fullNamePkg.FullName.String() } res[uid] = ufp } return res, nil } func (c *bulkLookupContactsProvider) FindFollowing(mctx libkb.MetaContext, uids []keybase1.UID, ) (res map[keybase1.UID]bool, err error) { defer mctx.Trace(fmt.Sprintf("bulkLookupContactsProvider#FillFollowing(len=%d)", len(res)), nil)() arg := libkb.NewLoadUserArgWithMetaContext(mctx).WithSelf(true).WithStubMode(libkb.StubModeUnstubbed) err = mctx.G().GetFullSelfer().WithUser(arg, func(user *libkb.User) error { mctx.Debug("In WithUser: user found: %t", user != nil) if user == nil { return libkb.UserNotFoundError{} } var trackList []*libkb.TrackChainLink idTable := user.IDTable() if idTable != nil { trackList = idTable.GetTrackList() } mctx.Debug("In WithUser: idTable exists: %t, trackList len: %d", idTable != nil, len(trackList)) res = make(map[keybase1.UID]bool) if len(trackList) == 0 { // Nothing to do. return nil } followedUIDSet := make(map[keybase1.UID]struct{}, len(trackList)) for _, track := range trackList { uid, err := track.GetTrackedUID() if err != nil { return err } followedUIDSet[uid] = struct{}{} } for _, v := range uids { _, found := followedUIDSet[v] res[v] = found } return nil }) if err != nil { return nil, err } return res, nil } func (c *bulkLookupContactsProvider) FindServiceMaps(mctx libkb.MetaContext, uids []keybase1.UID, ) (res map[keybase1.UID]libkb.UserServiceSummary, err error) { defer mctx.Trace(fmt.Sprintf("bulkLookupContactsProvider#FindServiceMaps(len=%d)", len(uids)), &err)() const serviceMapFreshness = 12 * time.Hour const networkTimeBudget = uidmap.DefaultNetworkBudget pkgs := mctx.G().ServiceMapper.MapUIDsToServiceSummaries(mctx.Ctx(), mctx.G(), uids, serviceMapFreshness, networkTimeBudget) res = make(map[keybase1.UID]libkb.UserServiceSummary, len(pkgs)) for uid, pkg := range pkgs { if pkg.ServiceMap != nil { res[uid] = pkg.ServiceMap } } return res, nil } type ContactsHandler struct { libkb.Contextified *BaseHandler contactsProvider *contacts.CachedContactsProvider } func NewCachedContactsProvider(g *libkb.GlobalContext) *contacts.CachedContactsProvider { return &contacts.CachedContactsProvider{ Provider: &bulkLookupContactsProvider{}, Store: contacts.NewContactCacheStore(g), } } func NewContactsHandler(xp rpc.Transporter, g *libkb.GlobalContext, provider *contacts.CachedContactsProvider) *ContactsHandler { handler := &ContactsHandler{ Contextified: libkb.NewContextified(g), BaseHandler: NewBaseHandler(g, xp), contactsProvider: provider, } return handler } var _ keybase1.ContactsInterface = (*ContactsHandler)(nil) func (h *ContactsHandler) LookupContactList(ctx context.Context, arg keybase1.LookupContactListArg) (res []keybase1.ProcessedContact, err error) { mctx := libkb.NewMetaContext(ctx, h.G()).WithLogTag("LOOKCON") defer mctx.Trace(fmt.Sprintf("ContactsHandler#LookupContactList(len=%d)", len(arg.Contacts)), &err)() return contacts.ResolveContacts(mctx, h.contactsProvider, arg.Contacts) } func (h *ContactsHandler) SaveContactList(ctx context.Context, arg keybase1.SaveContactListArg) (res keybase1.ContactListResolutionResult, err error) { mctx := libkb.NewMetaContext(ctx, h.G()).WithLogTag("SAVECON") defer mctx.Trace(fmt.Sprintf("ContactsHandler#SaveContactList(len=%d)", len(arg.Contacts)), &err)() return contacts.ResolveAndSaveContacts(mctx, h.contactsProvider, arg.Contacts) } func (h *ContactsHandler) LookupSavedContactsList(ctx context.Context, sessionID int) (res []keybase1.ProcessedContact, err error) { mctx := libkb.NewMetaContext(ctx, h.G()).WithLogTag("LOADCON") defer mctx.Trace("ContactsHandler#LookupSavedContactsList", &err)() store := h.G().SyncedContactList savedContacts, err := store.RetrieveContacts(mctx) if err != nil { return nil, err } return savedContacts, nil } func (h *ContactsHandler) GetContactsForUserRecommendations(ctx context.Context, sessionID int) (res []keybase1.ProcessedContact, err error) { mctx := libkb.NewMetaContext(ctx, h.G()).WithLogTag("RECSCON") defer mctx.Trace("ContactsHandler#GetContactsForUserRecommendations", &err)() savedContacts, err := h.G().SyncedContactList.RetrieveContacts(mctx) if err != nil { return nil, err } // Allocate space for the number of all saved contacts - we will likely // return less, though. res = make([]keybase1.ProcessedContact, 0, len(savedContacts)) // Find contacts that have at least one resolved component, we are going to // take only the resolved component from them (chose one if there are // multiple). seenResolvedContacts := make(map[int]struct{}) for _, contact := range savedContacts { if contact.Resolved { seenResolvedContacts[contact.ContactIndex] = struct{}{} } } // Find the best contact for each resolved username. // Map usernames to index in `res` list. contactForUsername := make(map[string]int, len(seenResolvedContacts)) currentUID := mctx.CurrentUID() for _, contact := range savedContacts { if !contact.Resolved { if _, found := seenResolvedContacts[contact.ContactIndex]; found { // This contact has a resolved component, skip unresolved ones // completely. continue } res = append(res, contact) } else { if contact.Uid.Equal(currentUID) { // Some people have their phone number in contact list, do not // show current user in recommendations. continue } if currentIndex, found := contactForUsername[contact.Username]; found { current := res[currentIndex] var overwrite bool // NOTE: add more rules here if needed. if current.Component.Email == nil && contact.Component.Email != nil { // Prefer email components to phone ones. overwrite = true } if overwrite { res[currentIndex] = contact } } else { contactForUsername[contact.Username] = len(res) res = append(res, contact) } } } sort.Slice(res, func(i, j int) bool { return res[i].DisplayName < res[j].DisplayName }) return res, nil }