See ChangeLog.
Monotone-Parent: 82564e2898976a6c09a85817e4b2954a5c58b7a9 Monotone-Revision: 9349907ea60fdc16f7e49e777a53ccaa1117180d Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2011-11-21T14:09:26maint-2.0.2
parent
b5fdc4a7c9
commit
413bb609dd
10
ChangeLog
10
ChangeLog
|
@ -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:...)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue