diff --git a/ChangeLog b/ChangeLog index 73fb3d9fd..992cc0278 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2011-03-17 francis + + * UI/MailerUI/UIxMailAccountActions.m (-listMailboxesAction): + moved code that fetches the inbox quota to [SOGoMailAccount getInboxQuota]. + + * SoObjects/Mailer/SOGoMailAccount.m (-getInboxQuota): new method + created partially from the method [UIxMailAccountActions listMailboxesAction]. + + * UI/MailerUI/UIxMailFolderActions.m (-deleteAction) + (-copyMessagesAction, -expungeAction, -emptyTrashAction): we now + return a JSON representation of the inbox quota when these actions + succeeds. + (-quotasAction): removed this method which was no longer used. + + * UI/WebServerResources/MailerUI.js (updateQuotas): new function + extracted from updateMailboxTreeInPage. It is called when a folder + operation returns the inbox quota. + 2011-03-15 francis * UI/MailerUI/UIxMailListActions.m (-getMailAction): removed this diff --git a/SoObjects/Mailer/SOGoMailAccount.h b/SoObjects/Mailer/SOGoMailAccount.h index db16fe53c..56cb84653 100644 --- a/SoObjects/Mailer/SOGoMailAccount.h +++ b/SoObjects/Mailer/SOGoMailAccount.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2010 Inverse inc. + Copyright (C) 2009-2011 Inverse inc. Copyright (C) 2004-2005 SKYRIX Software AG This file is part of SOGo. @@ -63,6 +63,7 @@ typedef enum { - (BOOL) imapAclConformsToIMAPExt; - (BOOL) supportsQuotas; +- (id) getInboxQuota; - (BOOL) updateFilters; - (NSArray *) identities; diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index e5c9323d4..0438bd3ba 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -1,6 +1,6 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG - Copyright (C) 2007-2009 Inverse inc. + Copyright (C) 2007-2011 Inverse inc. This file is part of SOGo. @@ -227,6 +227,39 @@ static NSString *sieveScriptName = @"sogo"; return [capability containsObject: @"quota"]; } +- (id) getInboxQuota +{ + SOGoMailFolder *inbox; + NGImap4Client *client; + NSString *inboxName; + SOGoDomainDefaults *dd; + id inboxQuota, infos; + float quota; + + inboxQuota = nil; + if ([self supportsQuotas]) + { + dd = [[context activeUser] domainDefaults]; + quota = [dd softQuotaRatio]; + inbox = [self inboxFolderInContext: context]; + inboxName = [NSString stringWithFormat: @"/%@", [inbox relativeImap4Name]]; + client = [[inbox imap4Connection] client]; + infos = [[client getQuotaRoot: [inbox relativeImap4Name]] objectForKey: @"quotas"]; + inboxQuota = [infos objectForKey: inboxName]; + if (quota != 0 && inboxQuota != nil) + { + // A soft quota ratio is imposed for all users + quota = quota * [(NSNumber*)[inboxQuota objectForKey: @"maxQuota"] intValue]; + inboxQuota = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithLong: (long)(quota+0.5)], @"maxQuota", + [inboxQuota objectForKey: @"usedSpace"], @"usedSpace", + nil]; + } + } + + return inboxQuota; +} + - (BOOL) updateFilters { NSMutableArray *requirements; diff --git a/UI/MailerUI/UIxMailAccountActions.m b/UI/MailerUI/UIxMailAccountActions.m index 50e7a9f75..f596c0c88 100644 --- a/UI/MailerUI/UIxMailAccountActions.m +++ b/UI/MailerUI/UIxMailAccountActions.m @@ -1,6 +1,6 @@ /* UIxMailAccountActions.m - this file is part of SOGo * - * Copyright (C) 2007, 2008 Inverse inc. + * Copyright (C) 2007, 2011 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -137,38 +137,10 @@ folders = [self _jsonFolders: rawFolders]; inboxQuota = nil; - // Retrieve INBOX quota - if ([co supportsQuotas]) - { - SOGoMailFolder *inbox; - NGImap4Client *client; - NSString *inboxName; - SOGoDomainDefaults *dd; - id infos; - float quota; - - dd = [[context activeUser] domainDefaults]; - quota = [dd softQuotaRatio]; - inbox = [co inboxFolderInContext: context]; - inboxName = [NSString stringWithFormat: @"/%@", [inbox relativeImap4Name]]; - client = [[inbox imap4Connection] client]; - infos = [[client getQuotaRoot: [inbox relativeImap4Name]] objectForKey: @"quotas"]; - inboxQuota = [infos objectForKey: inboxName]; - if (quota != 0 && inboxQuota != nil) - { - // A soft quota ration is imposed for all users - quota = quota * [(NSNumber*)[inboxQuota objectForKey: @"maxQuota"] intValue]; - inboxQuota = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat: (long)(quota+0.5)], @"maxQuota", - [inboxQuota objectForKey: @"usedSpace"], @"usedSpace", - nil]; - } - } - - // The parameter order is important here, as if the server doesn't support + // The parameters order is important here, as if the server doesn't support // quota, inboxQuota will be nil and it'll terminate the list of objects/keys. data = [NSDictionary dictionaryWithObjectsAndKeys: folders, @"mailboxes", - inboxQuota, @"quotas", + [co getInboxQuota], @"quotas", nil]; response = [self responseWithStatus: 200 andString: [data jsonRepresentation]]; diff --git a/UI/MailerUI/UIxMailFolderActions.h b/UI/MailerUI/UIxMailFolderActions.h index 74ea5e23b..ad82797f1 100644 --- a/UI/MailerUI/UIxMailFolderActions.h +++ b/UI/MailerUI/UIxMailFolderActions.h @@ -38,7 +38,6 @@ - (WOResponse *) emptyTrashAction; - (WOResponse *) subscribeAction; - (WOResponse *) unsubscribeAction; -- (WOResponse *) quotasAction; @end diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 3b55cf9cf..234623ebd 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -1,8 +1,9 @@ /* UIxMailFolderActions.m - this file is part of SOGo * - * Copyright (C) 2007-2010 Inverse inc. + * Copyright (C) 2007-2011 Inverse inc. * * Author: Wolfgang Sourdeau + * Francis Lachapelle * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -295,9 +296,11 @@ - (WOResponse *) copyMessagesAction { SOGoMailFolder *co; + SOGoMailAccount *account; WOResponse *response; NSArray *uids; NSString *value, *destinationFolder; + NSDictionary *data; co = [self clientObject]; value = [[context request] formValueForKey: @"uid"]; @@ -309,7 +312,13 @@ uids = [value componentsSeparatedByString: @","]; response = [co copyUIDs: uids toFolder: destinationFolder inContext: context]; if (!response) - response = [self responseWith204]; + { + // We return the inbox quota + account = [co container]; + data = [NSDictionary dictionaryWithObjectsAndKeys: [account getInboxQuota], @"quotas", nil]; + response = [self responseWithStatus: 200 + andString: [data jsonRepresentation]]; + } } else { @@ -466,6 +475,8 @@ { NSException *error; SOGoTrashFolder *co; + SOGoMailAccount *account; + NSDictionary *data; WOResponse *response; co = [self clientObject]; @@ -479,20 +490,27 @@ else { [co flushMailCaches]; - response = [self responseWith204]; + + // We return the inbox quota + account = [co container]; + data = [NSDictionary dictionaryWithObjectsAndKeys: [account getInboxQuota], @"quotas", nil]; + response = [self responseWithStatus: 200 + andString: [data jsonRepresentation]]; } return response; } -- (WOResponse *) emptyTrashAction +- (WOResponse *) emptyTrashAction { NSException *error; SOGoTrashFolder *co; + SOGoMailAccount *account; NSEnumerator *subfolders; WOResponse *response; NGImap4Connection *connection; NSURL *currentURL; + NSDictionary *data; co = [self clientObject]; @@ -513,7 +531,13 @@ [response appendContentString: @"Unable to empty the trash folder."]; } else - response = [self responseWith204]; + { + // We return the inbox quota + account = [co container]; + data = [NSDictionary dictionaryWithObjectsAndKeys: [account getInboxQuota], @"quotas", nil]; + response = [self responseWithStatus: 200 + andString: [data jsonRepresentation]]; + } return response; } @@ -556,30 +580,6 @@ return [self _subscriptionStubAction]; } -- (WOResponse *) quotasAction -{ - SOGoMailFolder *folder; - NSURL *folderURL; - id infos; - WOResponse *response; - NGImap4Client *client; - NSString *responseString; - - response = [self responseWithStatus: 200]; - [response setHeader: @"text/plain; charset=UTF-8" - forKey: @"content-type"]; - - folder = [self clientObject]; - folderURL = [folder imap4URL]; - - client = [[folder imap4Connection] client]; - infos = [client getQuotaRoot: [folder relativeImap4Name]]; - responseString = [[infos objectForKey: @"quotas"] jsonRepresentation]; - [response appendContentString: responseString]; - - return response; -} - - (NSDictionary *) _unseenCount { EOQualifier *searchQualifier; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 120b7908d..713a3c69d 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -1962,7 +1962,17 @@ function updateMailboxTreeInPage() { inboxFound = true; } } + + updateQuotas(); +} + +function updateQuotas(quotas) { + if (quotas) + Mailer.quotas = quotas; if (Mailer.quotas && parseInt(Mailer.quotas.maxQuota) > 0) { + log ("updating quotas"); + var treeContent = $("folderTreeContent"); + var tree = $("mailboxTree"); var quotaDiv = $("quotaIndicator"); if (quotaDiv) { treeContent.removeChild(quotaDiv); @@ -2100,7 +2110,7 @@ function buildMailboxes(accountIdx, encoded) { var mailboxes = data.mailboxes; var unseen = (data.status? data.status.unseen : 0); - if (data.quotas) + if (accountIdx == 0 && data.quotas) Mailer.quotas = data.quotas; for (var i = 0; i < mailboxes.length; i++) { @@ -2225,8 +2235,7 @@ function onMenuExpungeFolder(event) { function onMenuEmptyTrash(event) { var folderID = document.menuTarget.getAttribute("dataname"); var urlstr = URLForFolderID(folderID) + "/emptyTrash"; - var errorLabel = _("The trash could not be emptied."); - triggerAjaxRequest(urlstr, onMenuEmptyTrashCallback, errorLabel); + triggerAjaxRequest(urlstr, onMenuEmptyTrashCallback, { "mailbox" : folderID }); if (folderID == Mailer.currentMailbox) { $('messageContent').innerHTML = ''; @@ -2238,20 +2247,28 @@ function onMenuEmptyTrash(event) { function onMenuEmptyTrashCallback(http) { if (http.readyState == 4 - && isHttpStatus204(http.status)) { + && http.status == 200) { deleteCachedMailboxByType('trash'); // Reload the folder tree if there was folders in the trash + var reloaded = false; var nodes = $("mailboxTree").select("DIV[datatype=trash]"); for (var i = 0; i < nodes.length; i++) { var sibling = nodes[i].next(); if (sibling && sibling.hasClassName("clip")) { initMailboxTree(); + reloaded = true; break; } } + if (!reloaded) { + var data = http.responseText.evalJSON(true); + // We currently only show the quota for the first account (0). + if (data.quotas && http.callbackData.mailbox.startsWith('/0/')) + updateQuotas(data.quotas); + } } else - showAlertDialog(http.callbackData); + showAlertDialog(_("The trash could not be emptied.")); } function _onMenuChangeToXXXFolder(event, folder) { @@ -2372,7 +2389,7 @@ function folderOperationCallback(http) { function folderRefreshCallback(http) { if (http.readyState == 4 - && isHttpStatus204(http.status)) { + && (http.status == 200 || isHttpStatus204(http.status))) { var oldMailbox = http.callbackData.mailbox; if (http.callbackData.refresh && oldMailbox == Mailer.currentMailbox) { @@ -2387,6 +2404,11 @@ function folderRefreshCallback(http) { else refreshCurrentFolder(); } + if (http.status == 200) { + var data = http.responseText.evalJSON(true); + if (data.quotas && http.callbackData.mailbox.startsWith('/0/')) + updateQuotas(data.quotas); + } } else { if (http.callbackData.id) {