accessGroupsController.py (16391B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\structure\accessGroups\accessGroupsController.py 2 from eve.client.script.ui.structure.accessGroups.menuProvider import MenuProvider 3 from eve.client.script.ui.structure.accessGroups.ownerGroupUtils import GetMemberIDsToUpdate, GetMembershipTypeByMemberID 4 from localization import GetByLabel 5 from player_messaging.client.ui_message import prompt_player_fsd_dialog 6 from signals import Signal 7 import ownergroups.ownergroupConst as ownergroupConst 8 from ownergroups.ownergroupsUIUtil import GetTextForWarning 9 import carbonui.const as uiconst 10 import inventorycommon.const as invConst 11 REMOTE_SERVICE_NAME = 'ownerGroupManager' 12 13 class AccessGroupsController(object): 14 __notifyevents__ = ['OnOwnerGroupsUpdated'] 15 16 def __init__(self): 17 sm.RegisterNotify(self) 18 self.remoteSvc = sm.RemoteSvc(REMOTE_SERVICE_NAME) 19 self.objectCashingSvc = sm.GetService('objectCaching') 20 self.on_new_group_created = Signal(signalName='on_new_group_created') 21 self.on_group_selected = Signal(signalName='on_group_selected') 22 self.on_groupmembers_changed = Signal(signalName='on_groupmembers_changed') 23 self.on_groupmembers_removed = Signal(signalName='on_groupmembers_removed') 24 self.on_group_deleted = Signal(signalName='on_group_deleted') 25 self.on_group_updated = Signal(signalName='on_group_updated') 26 self.on_groups_reload = Signal(signalName='on_groups_reload') 27 self.membersByGroupID = {} 28 self.groupByGroupID = None 29 self.publicGroupsByGroupID = {} 30 self.myGroupsCacheInvalidated = False 31 self.currentSearchResults = None 32 33 def GetGroupLogs(self, groupID): 34 if groupID not in self.groupByGroupID or self.groupByGroupID[groupID].creatorID != session.corpid: 35 return self.remoteSvc.GetGroupLogs(groupID) 36 return [] 37 38 def GetMembers(self, groupID, noServerTrips = False): 39 if groupID in self.membersByGroupID or noServerTrips: 40 return self.membersByGroupID.get(groupID, None) 41 members = self.remoteSvc.GetMembers(groupID) 42 membershipTypeByMemberID = GetMembershipTypeByMemberID(members) 43 self.membersByGroupID[groupID] = membershipTypeByMemberID 44 return membershipTypeByMemberID 45 46 def UpdateMemberCache(self, groupID, updateDict): 47 self.UpdateClientCache(groupID, self.membersByGroupID, updateDict) 48 49 def UpdateClientCache(self, groupID, cacheDict, updateDict): 50 cacheForGroup = cacheDict.get(groupID) 51 if cacheForGroup is None: 52 return 53 cacheForGroup.update(updateDict) 54 55 def RemoveFromMemberCache(self, groupID, membersToRemove): 56 membershipTypeByMemberID = self.membersByGroupID.get(groupID, None) 57 if membershipTypeByMemberID is None: 58 return 59 for memberID in membersToRemove: 60 membershipTypeByMemberID.pop(memberID, None) 61 62 def GetAllMyMemberIDs(self): 63 allMemberIDs = set() 64 groupIDsToFetch = set() 65 for eachGroupID in self.GetMyGroups(): 66 groupMembers = self.GetMembers(eachGroupID, noServerTrips=True) 67 if groupMembers: 68 allMemberIDs.update(groupMembers.keys()) 69 else: 70 groupIDsToFetch.add(eachGroupID) 71 72 if groupIDsToFetch: 73 memberIDsInGroups, updateDict = self._GetUncachedMembers(groupIDsToFetch) 74 allMemberIDs.update(memberIDsInGroups) 75 self.membersByGroupID.update(updateDict) 76 allMemberIDsByGroupID = self.membersByGroupID.copy() 77 return (allMemberIDsByGroupID, allMemberIDs) 78 79 def _GetUncachedMembers(self, groupIDsToFetch): 80 uncachedMembersByGroupIDs = self.remoteSvc.GetMembersForMultipleGroups(list(groupIDsToFetch)) 81 updateDict = {} 82 memberIDsInGroups = set() 83 for groupID, members in uncachedMembersByGroupIDs.iteritems(): 84 membershipTypeByMemberID = GetMembershipTypeByMemberID(members) 85 updateDict[groupID] = membershipTypeByMemberID 86 87 return (memberIDsInGroups, updateDict) 88 89 def GetMyGroups(self): 90 if self.groupByGroupID is None: 91 self.groupByGroupID = {} 92 for g in self.remoteSvc.GetMyGroups(): 93 self.FixGroupLabelsForSystemGroups(g) 94 self.groupByGroupID[g.groupID] = g 95 96 return self.groupByGroupID 97 98 def IsMyGroupsCached(self): 99 return self.groupByGroupID is not None 100 101 @staticmethod 102 def FixGroupLabelsForSystemGroups(group): 103 if group.creatorID == invConst.ownerSystem: 104 if group.name.startswith('UI/AclBookmarks/'): 105 group.name = GetByLabel(group.name) 106 if group.description.startswith('UI/AclBookmarks/'): 107 group.description = GetByLabel(group.description) 108 109 def UpdatGroupCache(self, groupID, updateDict): 110 self.UpdateClientCache(groupID, self.groupByGroupID, updateDict) 111 112 def GetMyGroupInfo(self, groupID): 113 myGroups = self.GetMyGroups() 114 return myGroups.get(groupID) 115 116 def IsGroupCorpOwned(self, groupID): 117 groupInfo = self.GetMyGroupInfo(groupID) 118 if groupInfo: 119 return groupInfo.creatorID == session.corpid 120 return False 121 122 def OnCreateGroup(self, name, description): 123 self.Create(name, description) 124 self.InvalidateGetMyGroups() 125 self.on_new_group_created() 126 127 def Create(self, name, description): 128 return self.remoteSvc.Create(name, description) 129 130 def SelectGroup(self, groupID, sendSignal = True): 131 settings.user.ui.Set('accessGroup_lastGroup', groupID) 132 if sendSignal: 133 self.on_group_selected(groupID) 134 135 def GetSelectedGroupID(self): 136 return settings.user.ui.Get('accessGroup_lastGroup', None) 137 138 def EditGroupNameAndDescription(self, groupID, newName, newDesc): 139 self.remoteSvc.UpdateName(groupID, newName) 140 self.remoteSvc.UpdateDescription(groupID, newDesc) 141 self.UpdatGroupCache(groupID, updateDict={'name': newName, 142 'description': newDesc}) 143 self.on_group_updated(groupID) 144 145 def Delete(self, groupID): 146 group = self.GetMyGroupInfo(groupID) 147 ret = prompt_player_fsd_dialog('AccessGroupDeleteGroup', {'groupName': group.name}, uiconst.YESNO) 148 if ret != uiconst.ID_YES: 149 return 150 self.remoteSvc.Delete(groupID) 151 self.groupByGroupID.pop(groupID, None) 152 self.on_group_deleted() 153 154 def GetGroupInfoFromID(self, groupID, fetchToServer = False): 155 if not fetchToServer and not self.IsMyGroupsCached(): 156 return None 157 groupInfo = self.GetMyGroupInfo(groupID) 158 if groupInfo: 159 return groupInfo 160 if groupID in self.publicGroupsByGroupID: 161 return self.publicGroupsByGroupID[groupID] 162 if not fetchToServer: 163 return None 164 group = self.remoteSvc.GetGroup(groupID) 165 self.FixGroupLabelsForSystemGroups(group) 166 return group 167 168 def PopulatePublicGroupInfo(self, groupIDs, forceFetchInfoForPublicGroup = False): 169 self.GetMyGroups() 170 groupIDsToFetch = [ gID for gID in groupIDs if gID not in self.groupByGroupID and (forceFetchInfoForPublicGroup or gID not in self.publicGroupsByGroupID) ] 171 if not groupIDsToFetch: 172 return 173 if forceFetchInfoForPublicGroup: 174 for gID in groupIDsToFetch: 175 self.publicGroupsByGroupID.pop(gID, None) 176 177 for group in self.remoteSvc.GetGroupsMany(groupIDsToFetch): 178 self.FixGroupLabelsForSystemGroups(group) 179 self.publicGroupsByGroupID[group.groupID] = group 180 181 def AddPublicMember(self, groupID): 182 return self.AddMembers(groupID, {ownergroupConst.PUBLIC_MEMBER_ID: ownergroupConst.MEMBERSHIP_TYPE_MEMBER}) 183 184 def AddMembers(self, groupID, membershipTypeByMemberIDs, silently = False): 185 failedToAdd = [] 186 currentMembers = self.GetMembers(groupID) 187 membersToAdd = {} 188 if self.IsGroupCorpOwned(groupID): 189 return membershipTypeByMemberIDs.keys() 190 for memberID, membershipType in membershipTypeByMemberIDs.iteritems(): 191 if memberID not in currentMembers: 192 membersToAdd[memberID] = membershipType 193 194 if membersToAdd: 195 failedToAdd = self.remoteSvc.AddMembers(groupID, membersToAdd) 196 failedMemberIDs = {x[0] for x in failedToAdd} 197 membersToUpdate = {x:y for x, y in membersToAdd.iteritems() if x not in failedMemberIDs} 198 if not silently: 199 self.DisplayWarningIfNeeded(failedInfo=failedToAdd) 200 self.UpdateMemberCache(groupID, membersToUpdate) 201 self.on_groupmembers_changed(groupID) 202 return failedToAdd 203 204 def UpdateMembershipTypes(self, groupID, memberIDs, membershipType, silently = False): 205 failedToChange = [] 206 if session.charid in memberIDs: 207 cancelChange = self.CancelChangeBecauseOfDemotingYourself(groupID, membershipType) 208 if cancelChange: 209 memberIDs.remove(session.charid) 210 failedToChange.append((session.charid, 'NotDemotingYourself')) 211 if not memberIDs: 212 return failedToChange 213 groupMembers = self.GetMembers(groupID) 214 memberIDsToChange = [ mID for mID in memberIDs if groupMembers.get(mID, None) != membershipType ] 215 if not memberIDsToChange: 216 return failedToChange 217 failedToChange += self.remoteSvc.UpdateMembershipTypes(groupID, memberIDsToChange, membershipType) 218 membersToUpdate = self.GetUpdateMemberDict(memberIDsToChange, membershipType, failedToChange) 219 self.UpdateMemberCache(groupID, membersToUpdate) 220 if not silently: 221 self.DisplayWarningIfNeeded(failedInfo=failedToChange) 222 self.on_groupmembers_changed(groupID) 223 return failedToChange 224 225 def CancelChangeBecauseOfDemotingYourself(self, groupID, newRight): 226 group = self.GetMyGroupInfo(groupID) 227 accessRight = group.membershipType 228 if accessRight == ownergroupConst.MEMBERSHIP_TYPE_ADMIN and newRight != ownergroupConst.MEMBERSHIP_TYPE_ADMIN: 229 if prompt_player_fsd_dialog('AccessGroupDemoteAdmin', buttons=uiconst.YESNO) != uiconst.ID_YES: 230 return True 231 elif accessRight == ownergroupConst.MEMBERSHIP_TYPE_MANAGER and newRight not in (ownergroupConst.MEMBERSHIP_TYPE_ADMIN, ownergroupConst.MEMBERSHIP_TYPE_MANAGER): 232 if prompt_player_fsd_dialog('AccessGroupDemoteManager', buttons=uiconst.YESNO) != uiconst.ID_YES: 233 return True 234 return False 235 236 def RemoveMembers(self, groupID, memberIDs): 237 if session.charid in memberIDs: 238 if prompt_player_fsd_dialog('AccessGroupRemoveYourselfFromGroup', buttons=uiconst.YESNO) != uiconst.ID_YES: 239 memberIDs.discard(session.charid) 240 if not memberIDs: 241 return 242 failed = self.remoteSvc.DeleteMembers(groupID, list(memberIDs)) 243 self.DisplayWarningIfNeeded(failedInfo=failed) 244 memberIDsToUpdate = GetMemberIDsToUpdate(memberIDs, failed) 245 self.RemoveFromMemberCache(groupID, memberIDsToUpdate) 246 self.on_groupmembers_removed(groupID, memberIDsToUpdate) 247 248 def GetUpdateMemberDict(self, memberIDs, newMembershipType, failed): 249 failedMemberIDs = {x[0] for x in failed} 250 membersToUpdate = {x:newMembershipType for x in memberIDs if x not in failedMemberIDs} 251 return membersToUpdate 252 253 def SetGroupMembersWithSameRight(self, groupID, memberIDs, membershipType): 254 currentMembers = self.GetMembers(groupID) 255 oldMemberIDs, newMembersAndMembershipType = self._GetNewAndOldMemberInfo(memberIDs, currentMembers.keys(), membershipType) 256 failed = [] 257 if oldMemberIDs: 258 failed += self.UpdateMembershipTypes(groupID, list(oldMemberIDs), membershipType, silently=True) 259 if newMembersAndMembershipType: 260 failed += self.AddMembers(groupID, newMembersAndMembershipType, silently=True) 261 self.DisplayWarningIfNeeded(failedInfo=failed) 262 membersToUpdate = self.GetUpdateMemberDict(memberIDs, membershipType, failed) 263 if membersToUpdate: 264 self.UpdateMemberCache(groupID, membersToUpdate) 265 self.on_groupmembers_changed(groupID) 266 267 def _GetNewAndOldMemberInfo(self, memberIDs, currentGroupMemberIDs, membershipType): 268 oldMemberIDs = set() 269 newMembersAndMembershipType = {} 270 for memberID in memberIDs: 271 if memberID in currentGroupMemberIDs: 272 oldMemberIDs.add(memberID) 273 else: 274 newMembersAndMembershipType[memberID] = membershipType 275 276 return (oldMemberIDs, newMembersAndMembershipType) 277 278 def DisplayWarningIfNeeded(self, failedInfo): 279 if failedInfo: 280 warningLabelList = GetTextForWarning(failedInfo) 281 textList = [] 282 for label, kwargs in warningLabelList: 283 textForGroup = GetByLabel(label, **kwargs) 284 textList.append(textForGroup) 285 286 warningText = '<br><br>'.join(textList) 287 if warningText: 288 prompt_player_fsd_dialog('CustomInfo', {'info': warningText}, modal=False) 289 290 def OnOwnerGroupsUpdated(self, changedGroups): 291 selectedGroupID = settings.user.ui.Get('accessGroup_lastGroup', None) 292 self.myGroupsCacheInvalidated = False 293 for groupID, recordedChanges in changedGroups.iteritems(): 294 self.ProccessGroupChange(groupID, recordedChanges, selectedGroupID) 295 296 def ProccessGroupChange(self, groupID, recordedChanges, selectedGroupID): 297 if ownergroupConst.GROUP_DELETED in recordedChanges: 298 self.InvalidateGetMyGroupsIfNeeded() 299 self.on_group_deleted() 300 return 301 if self.IsInChange([ownergroupConst.GROUP_NAME_CHANGED, ownergroupConst.GROUP_DESCRIPTION_CHANGED], recordedChanges): 302 self.InvalidateGetMyGroupsIfNeeded() 303 self.on_group_updated(groupID) 304 if self.IsInChange([ownergroupConst.GROUP_MEMBER_ADDED, ownergroupConst.GROUP_MEMBERTYPE_CHANGED, ownergroupConst.GROUP_MEMBER_REMOVED], recordedChanges): 305 oldGroupMembers = self.membersByGroupID.get(groupID, {}).copy() 306 self.InvalidateGetMemberCache(groupID) 307 if ownergroupConst.GROUP_CHANGED_FOR_LISTENER in recordedChanges: 308 self.InvalidateGetMyGroupsIfNeeded() 309 self.on_group_updated(groupID) 310 return 311 if selectedGroupID == groupID: 312 if ownergroupConst.GROUP_MEMBER_REMOVED in recordedChanges: 313 self.OnCharactersRemoved(groupID, oldGroupMembers) 314 self.on_groupmembers_changed(groupID) 315 316 def InvalidateGetMemberCache(self, groupID): 317 self.objectCashingSvc.InvalidateCachedMethodCall(REMOTE_SERVICE_NAME, 'GetMembers', groupID) 318 self.membersByGroupID.pop(groupID, None) 319 320 def InvalidateGetMyGroupsIfNeeded(self): 321 if not self.myGroupsCacheInvalidated: 322 self.InvalidateGetMyGroups() 323 self.myGroupsCacheInvalidated = True 324 325 def InvalidateGetMyGroups(self): 326 self.objectCashingSvc.InvalidateCachedMethodCall(REMOTE_SERVICE_NAME, 'GetMyGroups') 327 self.groupByGroupID = None 328 329 def OnCharactersRemoved(self, groupID, oldGroupMembers): 330 newMembers = self.GetMembers(groupID) 331 removedMemberIDs = {x for x in oldGroupMembers if x not in newMembers} 332 if removedMemberIDs: 333 self.on_groupmembers_removed(groupID, removedMemberIDs) 334 335 def IsInChange(self, changeList, recordedChanges): 336 return bool(set(changeList) & set(recordedChanges)) 337 338 def GetCurrentSearchResults(self): 339 return self.currentSearchResults 340 341 def SetCurrentSearchResults(self, searchResults): 342 self.currentSearchResults = searchResults 343 self.on_groups_reload() 344 345 def GetMenuForGroupID(self, node): 346 return MenuProvider().GetMenuForGroupID(node, self) 347 348 def GetMenuForMember(self, groupID, nodes): 349 myGroupInfo = self.GetMyGroupInfo(groupID) 350 corpOwned = self.IsGroupCorpOwned(groupID) 351 return MenuProvider().GetMenuForMember(groupID, nodes, myGroupInfo.membershipType, self, corpOwned)