See ChangeLog.

Monotone-Parent: 82564e2898976a6c09a85817e4b2954a5c58b7a9
Monotone-Revision: 9349907ea60fdc16f7e49e777a53ccaa1117180d

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2011-11-21T14:09:26
maint-2.0.2
Francis Lachapelle 2011-11-21 14:09:26 +00:00
parent b5fdc4a7c9
commit 413bb609dd
10 changed files with 316 additions and 26 deletions

View File

@ -1,3 +1,13 @@
2011-11-21 Francis Lachapelle <flachapelle@inverse.ca>
* UI/WebServerResources/UIxPreferences.js (initPreferences):
initialize calendar for the new vacation end date optional parameter.
* UI/PreferencesUI/UIxPreferences.m (-enableVacationEndDate)
(-disableVacationEndDate, -setEnableVacationEndDate:)
(-vacationEndDate, -setVacationEndDate:): getters/setters for the
new optional vacation end date.
2011-11-16 Ludovic Marcotte <lmarcotte@inverse.ca>
* SoObjects/SOGo/SOGoSieveManager.m (-updateFiltersForLogin:...)

View File

@ -16,7 +16,8 @@ $(SOGO_TOOL)_OBJC_FILES += \
SOGoToolRemoveDoubles.m \
SOGoToolRemove.m \
SOGoToolRenameUser.m \
SOGoToolUserPreferences.m
SOGoToolUserPreferences.m \
SOGoToolExpireAutoReply.m
SOGO_SLAPD_SOCKD = sogo-slapd-sockd
$(SOGO_SLAPD_SOCKD)_INSTALL_DIR = $(SOGO_ADMIN_TOOLS)

View File

@ -0,0 +1,198 @@
/* SOGoToolUserPreferences.m - this file is part of SOGo
*
* Copyright (C) 2011 Inverse inc.
*
* Author: Francis Lachapelle <flachapelle@inverse.ca>
*
* 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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLContentStore/GCSChannelManager.h>
#import <GDLContentStore/NSURL+GCS.h>
#import <NGExtensions/NSNull+misc.h>
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoSystemDefaults.h>
#import <SOGo/SOGoUserDefaults.h>
#import <SOGo/SOGoSieveManager.h>
#import "SOGoTool.h"
@interface SOGoToolExpireAutoReply : SOGoTool
@end
@implementation SOGoToolExpireAutoReply
+ (void) initialize
{
}
+ (NSString *) command
{
return @"expire-autoreply";
}
+ (NSString *) description
{
return @"disable auto reply for reached end dates";
}
- (void) usage
{
fprintf (stderr, "expire-autoreply authname:authpassword\n\n"
" authname administrator username of the Sieve server\n"
" authpassword administrator password of the Sieve server\n");
}
- (BOOL) removeAutoReplyForLogin: (NSString *) theLogin
withSieveUsername: (NSString *) theUsername
andPassword: (NSString *) thePassword
{
NSMutableDictionary *vacationOptions;
SOGoUserDefaults *userDefaults;
SOGoSieveManager *manager;
SOGoUser *user;
BOOL result;
user = [SOGoUser userWithLogin: theLogin];
manager = [SOGoSieveManager sieveManagerForUser: user];
userDefaults = [user userDefaults];
vacationOptions = [[userDefaults vacationOptions] mutableCopy];
[vacationOptions autorelease];
[vacationOptions setObject: [NSNumber numberWithBool: NO] forKey: @"enabled"];
[userDefaults setVacationOptions: vacationOptions];
result = [userDefaults synchronize];
if (result)
{
result = [manager updateFiltersForLogin: theLogin
authname: theUsername
password: thePassword
account: nil];
if (!result)
{
// Can't update Sieve script -- Reactivate auto-reply
[vacationOptions setObject: [NSNumber numberWithBool: YES] forKey: @"enabled"];
[userDefaults setVacationOptions: vacationOptions];
[userDefaults synchronize];
}
}
return result;
}
- (void) expireAutoReplyWithUsername: (NSString *) theUsername
andPassword: (NSString *) thePassword
{
GCSChannelManager *cm;
EOAdaptorChannel *channel;
NSArray *attrs;
NSDictionary *infos, *defaults, *vacationOptions;
NSString *sql, *profileURL, *user, *c_defaults;
NSURL *tableURL;
SOGoSystemDefaults *sd;
BOOL enabled;
unsigned int endTime, now;
now = [[NSCalendarDate calendarDate] timeIntervalSince1970];
sd = [SOGoSystemDefaults sharedSystemDefaults];
profileURL = [sd profileURL];
if (profileURL)
{
tableURL = [[NSURL alloc] initWithString: profileURL];
cm = [GCSChannelManager defaultChannelManager];
channel = [cm acquireOpenChannelForURL: tableURL];
if (channel)
{
sql = [NSString stringWithFormat: @"SELECT c_uid, c_defaults FROM %@",
[tableURL gcsTableName]];
[channel evaluateExpressionX: sql];
attrs = [channel describeResults: NO];
while ((infos = [channel fetchAttributes: attrs withZone: NULL]))
{
user = [infos objectForKey: @"c_uid"];
c_defaults = [infos objectForKey: @"c_defaults"];
if ([c_defaults isNotNull])
{
defaults = [c_defaults objectFromJSONString];
vacationOptions = (NSDictionary *) [defaults objectForKey: @"Vacation"];
enabled = [[vacationOptions objectForKey: @"enabled"] boolValue];
if (enabled)
{
enabled = [[vacationOptions objectForKey: @"endDateEnabled"] boolValue];
if (enabled)
{
endTime = [[vacationOptions objectForKey: @"endDate"] intValue];
if (endTime <= now)
{
if ([self removeAutoReplyForLogin: user
withSieveUsername: theUsername
andPassword: thePassword])
NSLog(@"Removed auto-reply of user %@", user);
else
NSLog(@"An error occured while removing auto-reply of user %@", user);
}
}
}
}
}
}
}
}
- (BOOL) run
{
NSRange r;
NSString *creds, *authname, *authpwd;
BOOL rc;
int max;
max = [arguments count];
rc = NO;
if (max > 0)
{
creds = [arguments objectAtIndex: 0];
r = [creds rangeOfString: @":"];
if (r.location != NSNotFound)
{
authname = [creds substringToIndex: r.location];
authpwd = [creds substringFromIndex: r.location+1];
[self expireAutoReplyWithUsername: authname andPassword: authpwd];
rc = YES;
}
}
if (!rc)
[self usage];
return rc;
}
@end

View File

@ -27,8 +27,11 @@
"Add default email addresses" = "Add default email addresses";
"Days between responses :" = "Days between responses :";
"Do not send responses to mailing lists" = "Do not send responses to mailing lists";
"Disable auto reply on" = "Disable auto reply on";
"Please specify your message and your email addresses for which you want to enable auto reply."
= "Please specify your message and your email addresses for which you want to enable auto reply.";
"End date of your auto reply must be in the future."
= "End date of your auto reply must be in the future.";
/* forward messages */
"Forward incoming messages" = "Forward incoming messages";

View File

@ -883,6 +883,40 @@
return ignore;
}
- (BOOL) enableVacationEndDate
{
return [[vacationOptions objectForKey: @"endDateEnabled"] boolValue];
}
- (BOOL) disableVacationEndDate
{
return ![self enableVacationEndDate];
}
- (void) setEnableVacationEndDate: (BOOL) enableVacationEndDate
{
[vacationOptions setObject: [NSNumber numberWithBool: enableVacationEndDate]
forKey: @"endDateEnabled"];
}
- (void) setVacationEndDate: (NSCalendarDate *) endDate
{
NSNumber *time;
time = [NSNumber numberWithInt: [endDate timeIntervalSince1970]];
[vacationOptions setObject: time forKey: @"endDate"];
}
- (NSCalendarDate *) vacationEndDate
{
int time;
time = [[vacationOptions objectForKey: @"endDate"] intValue];
return [NSCalendarDate dateWithTimeIntervalSince1970: time];
}
/* mail forward */
- (BOOL) isForwardEnabled

View File

@ -10,7 +10,7 @@
className="UIxPageFrame"
title="title"
const:popup="YES"
const:jsFiles="RowEditionController.js,PasswordPolicy.js,ckeditor/ckeditor.js"
const:jsFiles="RowEditionController.js,PasswordPolicy.js,ckeditor/ckeditor.js,skycalendar.js"
>
<script type="text/javascript">
var localeCode = '<var:string value="localeCode"/>';
@ -379,6 +379,17 @@
var:checked="ignoreLists" />
<var:string label:value="Do not send responses to mailing lists" /></label><br/>
<label class="timeDate"><input var:checked="enableVacationEndDate"
const:name="enableVacationEndDate" const:id="enableVacationEndDate" type="checkbox" class="checkBox"
/><var:string label:value="Disable auto reply on" /><var:component className="UIxTimeDateControl"
const:displayTimeControl="0"
var:disabled="disableVacationEndDate"
const:controlID="vacationEndDate"
date="vacationEndDate"
const:dayStartHour="0"
const:dayEndHour="23"
/></label>
</div>
</div>
</var:if

View File

@ -1777,27 +1777,6 @@ function calendarDisplayCallback(http) {
+ http.readyState + "/" + http.status + ")");
}
function assignCalendar(name) {
if (typeof(skycalendar) != "undefined") {
var node = $(name);
if (node) {
node.calendar = new skycalendar(node);
node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
var dateFormat = node.getAttribute("dateFormat");
if (dateFormat)
node.calendar.setDateFormat(dateFormat);
}
}
}
function popupCalendar(node) {
var nodeId = $(node).readAttribute("inputId");
var input = $(nodeId);
input.calendar.popup();
return false;
}
function onEventsSelectionChange() {
listOfSelection = this;
this.removeClassName("_unfocused");

View File

@ -66,6 +66,20 @@ DIV.listWrapper
border-left: 1px solid #9b9b9b;
background: #ccddec; }
/* time date control */
SPAN.timeDateControl INPUT.textField
{ width: 7em;
vertical-align: text-bottom; }
#vacation LABEL.timeDate,
#vacation LABEL.timeDate input.checkBox
{ line-height: 2.0em;
}
#vacation LABEL.timeDate,
#vacation LABEL.timeDate input.checkBox,
SPAN.timeDateControl SPAN
{ vertical-align: text-top; }
/* vacation, forward */
#vacation, #forward
{ padding-left: 2.5em; }
@ -81,6 +95,9 @@ DIV.listWrapper
{ height: 50px; }
#vacation SPAN
{ float: right; }
#vacation SPAN.timeDateControl,
#vacation SPAN.timeDateControl SPAN
{ float: none; }
#vacation BR,
#passwordView BR
{ clear: both; }

View File

@ -23,7 +23,7 @@ function savePreferences(sender) {
var end = $("dayEndTime");
var selectedEnd = parseInt(end.options[end.selectedIndex].value);
if (selectedStart >= selectedEnd) {
alert (_("Day start time must be prior to day end time."));
showAlertDialog (_("Day start time must be prior to day end time."));
sendForm = false;
}
}
@ -31,16 +31,24 @@ function savePreferences(sender) {
if ($("enableVacation") && $("enableVacation").checked) {
if ($("autoReplyText").value.strip().length == 0
|| $("autoReplyEmailAddresses").value.strip().length == 0) {
alert(_("Please specify your message and your email addresses for which you want to enable auto reply."));
showAlertDialog(_("Please specify your message and your email addresses for which you want to enable auto reply."));
sendForm = false;
}
if ($("enableVacationEndDate") && $("enableVacationEndDate").checked) {
var endDate = new Date($("vacationEndDate_date").value);
var now = new Date();
if (endDate.getTime() < now.getTime()) {
showAlertDialog(_("End date of your auto reply must be in the future."));
sendForm = false;
}
}
}
if ($("enableForward") && $("enableForward").checked) {
var addresses = $("forwardAddress").value.split(",");
for (var i = 0; i < addresses.length && sendForm; i++)
if (!emailRE.test(addresses[i].strip())) {
alert(_("Please specify an address to which you want to forward your messages."));
showAlertDialog(_("Please specify an address to which you want to forward your messages."));
sendForm = false;
}
}
@ -198,6 +206,14 @@ function initPreferences() {
initSieveFilters();
initMailAccounts();
assignCalendar('vacationEndDate_date');
$("enableVacationEndDate").on("change", function(event) {
if (this.checked)
$("vacationEndDate_date").enable();
else
$("vacationEndDate_date").disable();
});
}
function initSieveFilters() {

View File

@ -25,6 +25,27 @@ var calendars = [];
var RE_NUM = /^\-?\d+$/;
var dateFormat = "yyyy-mm-dd";
function assignCalendar(name) {
if (typeof(skycalendar) != "undefined") {
var node = $(name);
if (node) {
node.calendar = new skycalendar(node);
node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
var dateFormat = node.getAttribute("dateFormat");
if (dateFormat)
node.calendar.setDateFormat(dateFormat);
}
}
}
function popupCalendar(node) {
var nodeId = $(node).readAttribute("inputId");
var input = $(nodeId);
input.calendar.popup();
return false;
}
function skycalendar(obj_target) {
// assing methods
this.gen_date = cal_gen_date1;