eveCalendarsvc.py (31251B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\eveCalendarsvc.py 2 import time 3 import utillib 4 from carbon.common.script.sys.service import Service 5 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING 6 from carbon.common.script.util.format import GetTimeParts, GetYearMonthFromTime 7 from carbon.common.script.util.timerstuff import AutoTimer 8 from carbonui import uiconst 9 from carbonui.primitives.container import Container 10 from eve.client.script.ui.shared.eveCalendar import CalendarNewEventWnd, CalendarSingleDayWnd, CalendarWnd 11 from eve.client.script.ui.shared.stateFlag import AddAndSetFlagIcon, FlagIcon 12 import blue 13 from eve.client.script.parklife import states as state 14 import localization 15 import eveLocalization 16 from carbonui.uicore import uicore 17 from eve.client.script.util import eveMisc 18 from eveexceptions import UserError 19 from menu import MenuLabel 20 from eveexceptions.exceptionEater import ExceptionEater 21 from localization import GetByLabel 22 from notifications.client.notificationSettings.notificationSettingHandler import NotificationSettingData 23 from notifications.common.formatters.calendar import CalendarNotificationFormatter 24 import eve.common.script.util.notificationconst as notificationConst 25 from player_messaging.client.ui_message import prompt_player_fsd_dialog 26 from timeDateHelpers.const import MONTHANDYEAR_NAME_TEXT 27 import eve.common.lib.appConst as const 28 RESPONSETYPES = {const.eventResponseAccepted: 'UI/Calendar/ResponseTypes/Accepted', 29 const.eventResponseDeclined: 'UI/Calendar/ResponseTypes/Declined', 30 const.eventResponseDeleted: 'UI/Calendar/ResponseTypes/Canceled', 31 const.eventResponseUninvited: 'UI/Calendar/ResponseTypes/Uninvited', 32 const.eventResponseUndecided: 'UI/Calendar/ResponseTypes/NotResponded', 33 const.eventResponseMaybe: 'UI/Calendar/ResponseTypes/MaybeReply'} 34 EVENTTYPES = {const.calendarTagPersonal: 'UI/Calendar/CalendarWindow/GroupPersonal', 35 const.calendarTagCorp: 'UI/Calendar/CalendarWindow/GroupCorp', 36 const.calendarTagAlliance: 'UI/Calendar/CalendarWindow/GroupAlliance', 37 const.calendarTagCCP: 'UI/Calendar/CalendarWindow/GroupCcp', 38 const.calendarTagAutomated: 'UI/Calendar/CalendarWindow/GroupAutomated'} 39 TAGLIST = [const.calendarTagPersonal, 40 const.calendarTagCorp, 41 const.calendarTagAlliance, 42 const.calendarTagCCP, 43 const.calendarTagAutomated] 44 45 class CalendarSvc(Service): 46 __guid__ = 'svc.calendar' 47 __displayname__ = 'Calendar service' 48 __notifyevents__ = ['OnNewCalendarEvent', 49 'OnEditCalendarEvent', 50 'OnRemoveCalendarEvent', 51 'OnSessionChanged', 52 'OnEventResponseByExternal'] 53 __startupdependencies__ = ['settings', 'objectCaching'] 54 55 def Run(self, *etc): 56 self.state = SERVICE_START_PENDING 57 self.events = {} 58 self.eventDetails = {} 59 self.eventsNotified = set() 60 self.nextEvents = {} 61 self.eventResponses = None 62 self.calendarMgr = sm.RemoteSvc('calendarMgr') 63 self.state = SERVICE_RUNNING 64 self._calendarProxy = None 65 self.notificationThread = AutoTimer(60000, self.CheckForNewEvents_thread) 66 67 def GetCalendarProxy(self): 68 if self._calendarProxy is None: 69 self._calendarProxy = sm.ProxySvc('calendarProxy') 70 return self._calendarProxy 71 72 def IsInPast(self, year, month, monthday, hour = 0, min = 0, allowToday = 0, *args): 73 now = blue.os.GetWallclockTime() 74 if allowToday: 75 cyear, cmonth, cwd, cday, chour, cmin, csec, cms = GetTimeParts(now) 76 now = blue.os.GetTimeFromParts(cyear, cmonth, cday, 0, 0, 0, 0) 77 thisDay = blue.os.GetTimeFromParts(year, month, monthday, hour, min, 0, 0) 78 return self.IsInPastFromBlueTime(thisDay, now) 79 80 def IsInPastFromBlueTime(self, then, now = None, *args): 81 if now is None: 82 now = blue.os.GetWallclockTime() + eveLocalization.GetTimeDelta() * const.SEC 83 inPast = now > then 84 return inPast 85 86 def IsTooFarInFuture(self, year, month): 87 now = blue.os.GetWallclockTime() 88 rlYear, rlMonth, wd, day, hour, min, sec, ms = GetTimeParts(now) 89 nowNumMonths = rlYear * 12 + rlMonth 90 thenNumMonths = year * 12 + month 91 difference = thenNumMonths - nowNumMonths 92 if difference > const.calendarViewRangeInMonths: 93 return True 94 return False 95 96 def FlushCache(self): 97 self.events = {} 98 self.nextEvents = {} 99 100 def GetMonthText(self, year, month, *args): 101 return localization.GetByLabel(MONTHANDYEAR_NAME_TEXT[month - 1], year=year) 102 103 def GetBrowsedMonth(self, direction, year, month): 104 if direction == 1: 105 if month == const.calendarDecember: 106 year += 1 107 month = const.calendarJanuary 108 else: 109 month += 1 110 elif direction == -1: 111 if month == const.calendarJanuary: 112 year -= 1 113 month = const.calendarDecember 114 else: 115 month -= 1 116 return (year, month) 117 118 def GetEventMenu(self, eventInfo, myResponse = None, getJumpOption = True, *args): 119 m = [] 120 m.append((MenuLabel('/Carbon/UI/Calendar/ViewEvent'), self.OpenEventWnd, (eventInfo,))) 121 if getattr(eventInfo, 'isDeleted', None): 122 return m 123 canDelete = 0 124 if not self.IsInPastFromBlueTime(then=eventInfo.eventDateTime): 125 if eventInfo.ownerID != session.charid: 126 if eventInfo.flag in [const.calendarTagCorp, const.calendarTagAlliance]: 127 if eventInfo.ownerID in [session.corpid, session.allianceid] and session.corprole & const.corpRoleChatManager == const.corpRoleChatManager: 128 canDelete = 1 129 m.append((MenuLabel('/Carbon/UI/Calendar/EditEvent'), self.OpenEditEventWnd, (eventInfo,))) 130 if myResponse is None: 131 iconPath, myResponse = self.GetMyResponseIconFromID(eventInfo.eventID) 132 m.append(None) 133 if eventInfo.flag is not const.calendarTagCCP: 134 if myResponse != const.eventResponseAccepted: 135 m.append((MenuLabel('/Carbon/UI/Calendar/Accept'), self.RespondToEvent, (eventInfo.eventID, eventInfo, const.eventResponseAccepted))) 136 if myResponse != const.eventResponseMaybe: 137 m.append((MenuLabel('/Carbon/UI/Calendar/MaybeReply'), self.RespondToEvent, (eventInfo.eventID, eventInfo, const.eventResponseMaybe))) 138 if myResponse != const.eventResponseDeclined: 139 m.append((MenuLabel('/Carbon/UI/Calendar/Decline'), self.RespondToEvent, (eventInfo.eventID, eventInfo, const.eventResponseDeclined))) 140 elif eventInfo.flag == const.calendarTagPersonal: 141 canDelete = 1 142 m.append((MenuLabel('/Carbon/UI/Calendar/EditEvent'), self.OpenEditEventWnd, (eventInfo,))) 143 if getJumpOption: 144 m.append(None) 145 m.append((MenuLabel('/Carbon/UI/Calendar/GotoDay'), self.JumpToDay, (eventInfo,))) 146 if canDelete: 147 m.append(None) 148 m.append((MenuLabel('/Carbon/UI/Calendar/DeleteEvent'), self.DeleteEvent, (eventInfo.eventID, eventInfo.ownerID))) 149 return m 150 151 def JumpToDay(self, eventInfo): 152 calendar = self.FindCalendar() 153 if calendar: 154 year, month, wd, monthday, hour, minute, sec, ms = blue.os.GetTimeParts(eventInfo.eventDateTime) 155 calendar.SetMonth(year, month, updateInView=1) 156 blue.synchro.Yield() 157 if calendar and not calendar.destroyed: 158 calendar.CrawlForAndSetMonthday(monthday) 159 160 def OpenNewEventWnd(self, year, month, monthday, *args): 161 configname = 'calendarNewEventWnd_%s_%s_%s' % (year, month, monthday) 162 CalendarNewEventWnd.Open(windowID=configname, year=year, month=month, monthday=monthday) 163 164 def CreateNewEvent(self, dateTime, duration, title, description, eventTag, important = 0, invitees = []): 165 if not title.strip(): 166 raise UserError('CalendarEventMustSpecifyTitle') 167 year, month, wd, day, hour, min, sec, ms = blue.os.GetTimeParts(dateTime) 168 if self.IsTooFarInFuture(year, month): 169 raise UserError('CalendarTooFarIntoFuture', {'numMonths': const.calendarViewRangeInMonths}) 170 if len(title) > const.calendarMaxTitleSize: 171 raise UserError('CalendarTitleTooLong') 172 newEventID = None 173 if eventTag == const.calendarTagPersonal: 174 if invitees: 175 newEventID = eveMisc.CSPAChargedAction('CSPACalendarCheck', self.calendarMgr, 'CreatePersonalEvent', dateTime, duration, title, description, important, invitees) 176 else: 177 newEventID = self.calendarMgr.CreatePersonalEvent(dateTime, duration, title, description, important, invitees) 178 if newEventID is not None: 179 self.OnNewCalendarEvent(eventID=newEventID, ownerID=session.charid, eventDateTime=dateTime, eventDuration=duration, eventTitle=title, importance=important) 180 if self.eventResponses is not None: 181 self.eventResponses[newEventID] = const.eventResponseAccepted 182 elif eventTag == const.calendarTagCorp: 183 newEventID = self.calendarMgr.CreateCorporationEvent(dateTime, duration, title, description, important) 184 elif eventTag == const.calendarTagAlliance: 185 newEventID = self.calendarMgr.CreateAllianceEvent(dateTime, duration, title, description, important) 186 187 def UpdateEventParticipants(self, eventID, charsToAdd, charsToRemove): 188 if eventID is not None: 189 if len(charsToAdd) > 0: 190 eveMisc.CSPAChargedAction('CSPACalendarCheck', self.calendarMgr, 'UpdateEventParticipants', eventID, charsToAdd, charsToRemove) 191 elif len(charsToRemove) > 0: 192 self.calendarMgr.UpdateEventParticipants(eventID, charsToAdd, charsToRemove) 193 self.objectCaching.InvalidateCachedMethodCall('calendarMgr', 'GetResponsesToEvent', eventID, session.charid) 194 195 def EditEvent(self, eventID, oldDateTime, dateTime, duration, title, description, eventTag, important = 0): 196 year, month, wd, day, hour, min, sec, ms = blue.os.GetTimeParts(dateTime) 197 if self.IsTooFarInFuture(year, month): 198 raise UserError('CalendarTooFarIntoFuture', {'numMonths': const.calendarViewRangeInMonths}) 199 if oldDateTime != dateTime: 200 if prompt_player_fsd_dialog('CalendarEventEditDate', {}, uiconst.YESNO) != uiconst.ID_YES: 201 return False 202 if eventTag == const.calendarTagPersonal: 203 self.calendarMgr.EditPersonalEvent(eventID, oldDateTime, dateTime, duration, title, description, important) 204 elif eventTag == const.calendarTagCorp: 205 self.calendarMgr.EditCorporationEvent(eventID, oldDateTime, dateTime, duration, title, description, important) 206 elif eventTag == const.calendarTagAlliance: 207 self.calendarMgr.EditAllianceEvent(eventID, oldDateTime, dateTime, duration, title, description, important) 208 return True 209 210 def GetEventFlag(self, ownerID, autoEventType = None): 211 if ownerID == session.corpid: 212 if autoEventType is None: 213 return const.calendarTagCorp 214 return const.calendarTagAutomated 215 elif ownerID == session.allianceid: 216 return const.calendarTagAlliance 217 elif ownerID == const.ownerSystem: 218 return const.calendarTagCCP 219 else: 220 return const.calendarTagPersonal 221 222 def GetEventsByMonthYear(self, month, year): 223 eventList = self.events.get((month, year)) 224 if eventList is None: 225 eventList = [] 226 dbRowList = self.GetCalendarProxy().GetEventList(month, year) 227 for dbRows in dbRowList: 228 if dbRows is not None: 229 eventList.extend([ utillib.KeyVal(x) for x in dbRows ]) 230 231 for x in eventList: 232 x.flag = self.GetEventFlag(x.ownerID, x.Get('autoEventType', None)) 233 234 self.events[month, year] = eventList 235 return eventList 236 237 def GetEventResponses(self): 238 if self.eventResponses is None: 239 dbRows = self.calendarMgr.GetResponsesForCharacter() 240 self.eventResponses = {} 241 for dbRow in dbRows: 242 self.eventResponses[dbRow.eventID] = dbRow.status 243 244 return self.eventResponses 245 246 def GetEventDetails(self, eventID, ownerID): 247 if eventID not in self.eventDetails: 248 self.eventDetails[eventID] = self.GetCalendarProxy().GetEventDetails(eventID, ownerID) 249 return self.eventDetails[eventID] 250 251 def OpenSingleDayWnd(self, header, year, month, monthday, events, isADay = 1, wndType = 'singleWndDay', *args): 252 windowInstanceID = '%s_%s_%s_%s' % (wndType, 253 year, 254 month, 255 monthday) 256 wnd = CalendarSingleDayWnd.GetIfOpen(windowID=wndType, windowInstanceID=windowInstanceID) 257 if wnd: 258 wnd.Maximize() 259 return 260 shift = uicore.uilib.Key(uiconst.VK_SHIFT) 261 if not shift: 262 for someWnd in uicore.registry.GetWindows()[:]: 263 if isinstance(someWnd, CalendarSingleDayWnd): 264 someWnd.CloseByUser() 265 266 wnd = CalendarSingleDayWnd.Open(windowID=wndType, windowInstanceID=windowInstanceID, header=header, wndType=wndType, year=year, month=month, monthday=monthday, events=events, isADay=isADay) 267 268 def OpenEditEventWnd(self, eventInfo, *args): 269 self.OpenEventWnd(eventInfo, edit=1) 270 271 def OpenEventWnd(self, eventInfo, edit = 0, *args): 272 year, month, wd, monthday, hour, min, sec, ms = blue.os.GetTimeParts(eventInfo.eventDateTime) 273 windowInstanceID = 'calendarEventWnd_%s' % eventInfo.eventID 274 if edit: 275 wnd = CalendarNewEventWnd.GetIfOpen(windowID='calendarEventWnd', windowInstanceID=windowInstanceID) 276 if wnd and not wnd.inEditMode: 277 wnd.CloseByUser() 278 wnd = CalendarNewEventWnd.Open(windowID='calendarEventWnd', windowInstanceID=windowInstanceID, year=year, month=month, monthday=monthday, eventInfo=eventInfo, edit=edit) 279 if wnd: 280 wnd.Maximize() 281 282 def RespondToEvent(self, eventID, eventKV, response): 283 self.calendarMgr.SendEventResponse(eventID, eventKV.ownerID, response) 284 self._RespondToEvent(eventID, eventKV, response) 285 286 def _RespondToEvent(self, eventID, eventKV, response): 287 if self.eventResponses is not None: 288 self.eventResponses[eventID] = response 289 if response != const.eventResponseDeclined: 290 if eventKV.eventDateTime > blue.os.GetWallclockTime(): 291 year, month = GetYearMonthFromTime(eventKV.eventDateTime) 292 if self.IsInNextEventsWindow(year, month): 293 self.nextEvents[eventID] = eventKV 294 elif eventID in self.nextEvents: 295 self.nextEvents.pop(eventID, None) 296 self.objectCaching.InvalidateCachedMethodCall('calendarMgr', 'GetResponsesToEvent', eventID, eventKV.ownerID) 297 sm.ScatterEvent('OnReloadToDo') 298 sm.ScatterEvent('OnRespondToEvent') 299 sm.ScatterEvent('OnReloadCalendar') 300 301 def DeleteEvent(self, eventID, ownerID): 302 if prompt_player_fsd_dialog('CalendarDeleteEvent', {}, uiconst.YESNO) != uiconst.ID_YES: 303 return False 304 self.calendarMgr.DeleteEvent(eventID, ownerID) 305 name = 'calendarEventWnd_%s' % eventID 306 CalendarNewEventWnd.CloseIfOpen(windowID=name) 307 return True 308 309 def IsInNextEventsWindow(self, eventYear, eventMonth): 310 now = blue.os.GetWallclockTime() + eveLocalization.GetTimeDelta() * const.SEC 311 nowYear, nowMonth = GetYearMonthFromTime(now) 312 if eventYear == nowYear: 313 return eventMonth in (nowMonth, nowMonth + 1) 314 if eventYear == nowYear + 1: 315 return nowMonth == const.calendarDecember and eventMonth == const.calendarJanuary 316 return False 317 318 def OnNewCalendarEvent(self, eventID, ownerID, eventDateTime, eventDuration, eventTitle, importance, autoEventType = None, doBlink = True): 319 year, month = GetYearMonthFromTime(eventDateTime) 320 now = blue.os.GetWallclockTime() 321 eventList = self.events.get((month, year)) 322 if eventList is not None: 323 if eventID not in [ x.eventID for x in eventList ]: 324 eventKV = utillib.KeyVal(eventID=eventID, ownerID=ownerID, eventDateTime=eventDateTime, eventDuration=eventDuration, eventTitle=eventTitle, importance=importance, flag=self.GetEventFlag(ownerID, autoEventType)) 325 eventKV.isDeleted = False 326 eventKV.dateModified = blue.os.GetWallclockTime() 327 eventList.append(eventKV) 328 self.events[month, year] = eventList 329 if eventDateTime > now and self.IsInNextEventsWindow(year, month): 330 self.nextEvents[eventID] = eventKV 331 if doBlink and ownerID != session.charid and eventDateTime > now and self.IsInNextEventsWindow(year, month): 332 sm.GetService('neocom').Blink('calendar', GetByLabel('UI/Neocom/Blink/NewCalendarEvent')) 333 sm.ScatterEvent('OnReloadCalendar') 334 sm.ScatterEvent('OnReloadToDo') 335 336 def OnEditCalendarEvent(self, eventID, ownerID, oldEventDateTime, eventDateTime, eventDuration, eventTitle, importance, autoEventType = None): 337 oldYear, oldMonth = GetYearMonthFromTime(oldEventDateTime) 338 if eventID in self.nextEvents: 339 self.nextEvents.pop(eventID) 340 if eventID in self.eventDetails: 341 self.eventDetails.pop(eventID) 342 if oldEventDateTime != eventDateTime: 343 if self.eventResponses is None: 344 self.GetEventResponses() 345 if ownerID != session.charid: 346 oldReply = self.eventResponses.get(eventID, const.eventResponseUndecided) 347 if oldReply in (const.eventResponseUndecided, const.eventResponseAccepted, const.eventResponseMaybe): 348 self.eventResponses[eventID] = const.eventResponseUndecided 349 year, month = GetYearMonthFromTime(eventDateTime) 350 if eventDateTime > blue.os.GetWallclockTime() and self.IsInNextEventsWindow(year, month): 351 sm.GetService('neocom').Blink('calendar', GetByLabel('UI/Neocom/Blink/CalendarEventModified')) 352 self.objectCaching.InvalidateCachedMethodCall('calendarMgr', 'GetResponsesToEvent', eventID, ownerID) 353 eventList = self.events.get((oldMonth, oldYear)) 354 if eventList is not None: 355 for evt in eventList: 356 if eventID == evt.eventID: 357 eventList.remove(evt) 358 359 self.events[oldMonth, oldYear] = eventList 360 self.OnNewCalendarEvent(eventID, ownerID, eventDateTime, eventDuration, eventTitle, importance, autoEventType, doBlink=False) 361 362 def OnRemoveCalendarEvent(self, eventID, eventDateTime, isDeleted): 363 year, month, wd, monthday, hour, min, sec, ms = blue.os.GetTimeParts(eventDateTime) 364 eventList = self.events.get((month, year)) 365 if eventList is not None: 366 for x in eventList: 367 if x.eventID == eventID: 368 if isDeleted: 369 x.isDeleted = True 370 x.dateModified = blue.os.GetWallclockTime() 371 else: 372 eventList.remove(x) 373 break 374 375 self.events[month, year] = eventList 376 if self.eventResponses and eventID in self.eventResponses and self.eventResponses.get(eventID, None) != const.eventResponseDeclined: 377 self.eventResponses.pop(eventID) 378 self.nextEventsFetched = False 379 sm.ScatterEvent('OnReloadToDo') 380 sm.ScatterEvent('OnReloadCalendar') 381 382 def OnSessionChanged(self, isRemote, session, change): 383 if 'corpid' in change or 'allianceid' in change: 384 self.events = {} 385 self.nextEvents = {} 386 self.nextEventsFetched = False 387 sm.ScatterEvent('OnReloadToDo') 388 sm.ScatterEvent('OnReloadCalendar') 389 390 def OnEventResponseByExternal(self, eventID, eventKV, response): 391 eventKV.flag = self.GetEventFlag(eventKV.flag) 392 self._RespondToEvent(eventID, eventKV, response) 393 394 def GetResponsesToEvent(self, eventID, ownerID): 395 dbRows = self.calendarMgr.GetResponsesToEvent(eventID, ownerID) 396 responseDict = {} 397 for row in dbRows: 398 if row.status != const.eventResponseUninvited: 399 responseDict[row.characterID] = row.status 400 401 return responseDict 402 403 def GetResponsesToEventInStatusDict(self, eventID, responseDict): 404 statusDict = {} 405 accepted = [] 406 rejected = [] 407 noreply = [] 408 maybe = [] 409 for charID, response in responseDict.iteritems(): 410 if response == const.eventResponseUndecided: 411 noreply.append(charID) 412 elif response == const.eventResponseDeclined: 413 rejected.append(charID) 414 elif response == const.eventResponseAccepted: 415 accepted.append(charID) 416 elif response == const.eventResponseMaybe: 417 maybe.append(charID) 418 419 statusDict[const.eventResponseUndecided] = noreply 420 statusDict[const.eventResponseDeclined] = rejected 421 statusDict[const.eventResponseAccepted] = accepted 422 statusDict[const.eventResponseMaybe] = maybe 423 return statusDict 424 425 def GetResponseIconNum(self, response): 426 if response == const.eventResponseAccepted: 427 return 'ui_38_16_193' 428 if response in [const.eventResponseDeclined, const.eventResponseDeleted]: 429 return 'ui_38_16_194' 430 if response == const.eventResponseUndecided: 431 return 'ui_38_16_177' 432 if response == const.eventResponseMaybe: 433 return 'ui_38_16_195' 434 return 'ui_38_16_192' 435 436 def GetLongResponseIconPath(self, response): 437 return self.GetResponseIconNum(response) 438 439 def GetMyResponseIconFromID(self, eventID, long = 0, getDeleted = 0): 440 if getDeleted: 441 myResponse = const.eventResponseDeleted 442 else: 443 myResponse = self.GetMyResponse(eventID) 444 if long: 445 icon = self.GetLongResponseIconPath(myResponse) 446 else: 447 icon = self.GetResponseIconNum(myResponse) 448 return (icon, myResponse) 449 450 def GetActiveTags(self, *args): 451 showTags = 0 452 for tag in TAGLIST: 453 checked = settings.user.ui.Get('calendarTagCheked_%s' % tag, 1) 454 if checked: 455 showTags += tag 456 457 return showTags 458 459 def LoadTagIcon(self, tag): 460 if tag not in [const.calendarTagCorp, 461 const.calendarTagAlliance, 462 const.calendarTagCCP, 463 const.calendarTagAutomated]: 464 return 465 else: 466 tagIconCont = Container(name='tagIconCont', parent=None, align=uiconst.TOPLEFT, pos=(0, 0, 14, 14)) 467 self.LoadTagIconInContainer(tag, tagIconCont, left=0, top=0) 468 return tagIconCont 469 470 def LoadTagIconInContainer(self, tag, cont, left = 2, top = 4, *args): 471 cont.Flush() 472 if tag == const.calendarTagCorp: 473 AddAndSetFlagIcon(parentCont=cont, flag=state.flagSamePlayerCorp, top=top, left=left) 474 elif tag == const.calendarTagAlliance: 475 AddAndSetFlagIcon(parentCont=cont, flag=state.flagSameAlliance, top=top, left=left) 476 elif tag == const.calendarTagCCP: 477 self.LoadCCPIcon(cont, top, left) 478 elif tag == const.calendarTagAutomated: 479 self.LoadAutomatedIcon(cont, top, left) 480 481 def LoadCCPIcon(self, container, top, left, *args): 482 if getattr(container.sr, 'flag', None) is None or container.sr.flag.destroyed: 483 container.sr.flag = FlagIcon(parent=container, left=left, top=top, state=uiconst.UI_DISABLED, align=uiconst.TOPRIGHT) 484 container.sr.flag.SetBackgroundColor((0.7, 0.7, 0.7)) 485 container.sr.flag.SetIconTexturePath(iconIdx=2) 486 487 def LoadAutomatedIcon(self, container, top, left, *args): 488 if getattr(container.sr, 'flag', None) is None or container.sr.flag.destroyed: 489 container.sr.flag = FlagIcon(parent=container, pos=(left, 490 top, 491 11, 492 11), state=uiconst.UI_DISABLED, align=uiconst.TOPRIGHT) 493 container.sr.flag.flagIcon.texturePath = 'res:/UI/Texture/Icons/AutomatedEntry_Icon_Alpha.png' 494 color = sm.GetService('stateSvc').GetStateFlagColor(state.flagSamePlayerCorp) 495 container.sr.flag.SetBackgroundColor(color, opacity=0.75) 496 497 def GetMyChangedEvents(self, monthsAhead = 1): 498 events = self.GetEventsNextXMonths(monthsAhead) 499 showTag = self.GetActiveTags() 500 changedEvents = {} 501 now = blue.os.GetWallclockTime() + eveLocalization.GetTimeDelta() * const.SEC 502 for eventID, eventKV in events.iteritems(): 503 if self.IsInUpdateEventsList(now, eventKV) and (showTag is None or showTag & eventKV.flag != 0): 504 changedEvents[eventID] = eventKV 505 506 return changedEvents 507 508 def GetMyNextEvents(self, monthsAhead = 1): 509 events = self.GetEventsNextXMonths(monthsAhead) 510 showTag = self.GetActiveTags() 511 myNextEvents = {} 512 now = blue.os.GetWallclockTime() + eveLocalization.GetTimeDelta() * const.SEC 513 for eventID, eventKV in events.iteritems(): 514 if self.IsOnToDoList(now, eventKV) and (showTag is None or showTag & eventKV.flag != 0): 515 myNextEvents[eventID] = eventKV 516 517 return myNextEvents 518 519 def GetEventsNextXMonths(self, monthsAhead = 1, force = 0): 520 if getattr(self, 'nextEventsFetched', False) and not force: 521 return self.nextEvents 522 self.nextEvents = self.FetchNextEvents(monthsAhead=monthsAhead) 523 self.nextEventsFetched = True 524 return self.nextEvents 525 526 def FetchNextEvents(self, monthsAhead = 1): 527 now = blue.os.GetWallclockTime() + eveLocalization.GetTimeDelta() * const.SEC 528 year, month, wd, day, hour, minute, sec, ms = blue.os.GetTimeParts(now) 529 nextEvents = self.FetchNextEventsDict(month, year, now) 530 for i in xrange(monthsAhead): 531 monthsFromNow = i + 1 532 y, m = self.GetBrowsedMonth(monthsFromNow, year, month) 533 nextMonthEvents = self.FetchNextEventsDict(m, y, now) 534 nextEvents.update(nextMonthEvents) 535 536 return nextEvents 537 538 def FetchNextEventsDict(self, month, year, now): 539 dict = {} 540 events = self.GetEventsByMonthYear(month, year) 541 for eventKV in events: 542 dict[eventKV.eventID] = eventKV 543 544 return dict 545 546 def IsOnToDoList(self, now, eventKV): 547 if eventKV.eventDateTime < now: 548 return False 549 if eventKV.isDeleted: 550 return False 551 if self.GetMyResponse(eventKV.eventID) in [const.eventResponseDeclined]: 552 return False 553 return True 554 555 def IsInUpdateEventsList(self, now, eventKV): 556 if now > eventKV.eventDateTime: 557 return False 558 myResponse = self.GetMyResponse(eventKV.eventID) 559 if eventKV.isDeleted and myResponse != const.eventResponseDeclined: 560 return True 561 if myResponse == const.eventResponseUndecided: 562 return True 563 return False 564 565 def GetMyResponse(self, eventID): 566 if self.eventResponses is None: 567 self.GetEventResponses() 568 myResponse = self.eventResponses.get(eventID, const.eventResponseUndecided) 569 return myResponse 570 571 def GetEventHint(self, eventInfo, myResponse): 572 if eventInfo is None: 573 return '' 574 if eventInfo.eventDuration is None: 575 durationLabel = localization.GetByLabel('UI/Calendar/EventWindow/DateNotSpecified') 576 else: 577 hours = eventInfo.eventDuration / 60 578 durationLabel = localization.GetByLabel('UI/Calendar/EventWindow/DateSpecified', hours=hours) 579 responseLabel = localization.GetByLabel(self.GetResponseType().get(myResponse, 'UI/Generic/Unknown')) 580 if getattr(eventInfo, 'eventTimeStamp', None) is None: 581 year, month, wd, day, hour, min, sec, ms = blue.os.GetTimeParts(eventInfo.eventDateTime) 582 ts = time.struct_time((year, 583 month, 584 day, 585 hour, 586 min, 587 sec, 588 0, 589 1, 590 0)) 591 eventInfo.eventTimeStamp = localization.formatters.FormatDateTime(value=ts, dateFormat='none', timeFormat='short') 592 et = self.GetEventTypes().get(eventInfo.flag, '-') 593 if et != '-': 594 et = localization.GetByLabel(et) 595 hint = localization.GetByLabel('UI/Calendar/Hints/Event', time=eventInfo.eventTimeStamp, title=eventInfo.eventTitle, eventType=et, response=responseLabel, duration=durationLabel, owner=cfg.eveowners.Get(eventInfo.ownerID).name) 596 if eventInfo.importance > 0: 597 hint += localization.GetByLabel('UI/Calendar/Hints/EventImportant') 598 return hint 599 600 def GetResponseType(self, *args): 601 return RESPONSETYPES 602 603 def GetEventTypes(self, *args): 604 return EVENTTYPES 605 606 def ShowCharacterInfo(self, itemID): 607 return sm.GetService('info').ShowInfo(const.typeCharacter, itemID) 608 609 def FindCalendar(self, *args): 610 calendar = None 611 wnd = CalendarWnd.GetIfOpen() 612 if wnd: 613 calendar = wnd.sr.calendarForm 614 return calendar 615 616 def CheckForNewEvents_thread(self): 617 if not session.charid: 618 return 619 showTagMask = self.GetActiveTags() 620 if not showTagMask: 621 return 622 if not AreNotificationActiveForCalendarEvents(): 623 return 624 events = self.GetEventsNextXMonths() 625 now = blue.os.GetWallclockTime() 626 newEnoughTime = now - 5 * const.MIN 627 notificationSvc = sm.GetService('notificationSvc') 628 for each in events.itervalues(): 629 if each.isDeleted: 630 continue 631 if each.eventID in self.eventsNotified: 632 continue 633 if showTagMask & each.flag == 0: 634 continue 635 if newEnoughTime < each.eventDateTime <= now: 636 with ExceptionEater('NotificationSvc: CheckForNewEvents_thread'): 637 notificationData = CalendarNotificationFormatter.MakeData(each) 638 notificationSvc.MakeAndScatterNotification(type=notificationConst.notificationTypeCalendarEvent, data=notificationData) 639 self.eventsNotified.add(each.eventID) 640 641 642 def AreNotificationActiveForCalendarEvents(): 643 notificationSetting = settings.char.notifications.Get('notificationSettingsData', {}).get(notificationConst.notificationTypeCalendarEvent) 644 if not notificationSetting: 645 return True 646 settingData = NotificationSettingData.fromTuple(notificationSetting) 647 if settingData.showPopup or settingData.showAtAll: 648 return True 649 return False