Compare commits
18 Commits
litmus_mod
...
MAPI_NEW_D
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e953a4ea87 | ||
|
|
22ea3cb16d | ||
|
|
e021985dac | ||
|
|
37c7fe2cc1 | ||
|
|
92449d5f2b | ||
|
|
0f4c47bad2 | ||
|
|
66a09211ae | ||
|
|
4d276aa864 | ||
|
|
9a9d38606a | ||
|
|
7ef7f62f45 | ||
|
|
412bc70111 | ||
|
|
cf982c25ce | ||
|
|
dfb5dde44f | ||
|
|
5b5ddf1efb | ||
|
|
2765860524 | ||
|
|
95560e128c | ||
|
|
2c4edc911e | ||
|
|
82d37c5f89 |
70
mozilla/mailnews/base/public/nsIMapiRegistry.idl
Normal file
@@ -0,0 +1,70 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
/**
|
||||
* This interface provides support for registering Mozilla as the default
|
||||
* Mail Client. This interface can also be used to get/set the user preference
|
||||
* for the default Mail Client.
|
||||
*
|
||||
*/
|
||||
[scriptable, uuid(c5be14ba-4e0a-4eec-a1b8-04363761d63c)]
|
||||
interface nsIMapiRegistry: nsISupports {
|
||||
|
||||
/** This is set to TRUE if Mozilla is the default Application
|
||||
*/
|
||||
attribute boolean isDefaultMailClient;
|
||||
|
||||
/** This is set TRUE only once per session.
|
||||
*/
|
||||
readonly attribute boolean showDialog;
|
||||
|
||||
/** This will bring the dialog asking the user if he/she wants to set
|
||||
* Mozilla as default Mail Client.
|
||||
* Call this only if Mozilla is not the default Mail client
|
||||
*/
|
||||
void showMailIntegrationDialog(in nsIDOMWindow parentWindow);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1"
|
||||
#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry"
|
||||
%}
|
||||
27
mozilla/mailnews/mapi/makefile.win
Normal file
@@ -0,0 +1,27 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Srilatha Moturi <srilatha@netscape.com>
|
||||
# Krishna Mohan Khandrika <kkhandrika@netscape.com>
|
||||
|
||||
DEPTH=..\..
|
||||
|
||||
DIRS=mapihook resources mapiDll
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
54
mozilla/mailnews/mapi/mapiDll/Mapi32.DEF
Normal file
@@ -0,0 +1,54 @@
|
||||
; ***** BEGIN LICENSE BLOCK *****
|
||||
; Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
;
|
||||
; The contents of this file are subject to the Mozilla Public License Version
|
||||
; 1.1 (the "License"); you may not use this file except in compliance with
|
||||
; the License. You may obtain a copy of the License at
|
||||
; http://www.mozilla.org/MPL/
|
||||
;
|
||||
; Software distributed under the License is distributed on an "AS IS" basis,
|
||||
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
; for the specific language governing rights and limitations under the
|
||||
; License.
|
||||
;
|
||||
; The Original Code is Mozilla.
|
||||
;
|
||||
; The Initial Developer of the Original Code is
|
||||
; Netscape Communications Corp.
|
||||
; Portions created by the Initial Developer are Copyright (C) 2001
|
||||
; the Initial Developer. All Rights Reserved.
|
||||
;
|
||||
; Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
;
|
||||
; Alternatively, the contents of this file may be used under the terms of
|
||||
; either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
; in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
; of those above. If you wish to allow use of your version of this file only
|
||||
; under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
; use your version of this file under the terms of the MPL, indicate your
|
||||
; decision by deleting the provisions above and replace them with the notice
|
||||
; and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
; the provisions above, a recipient may use your version of this file under
|
||||
; the terms of any one of the MPL, the GPL or the LGPL.
|
||||
;
|
||||
; ***** END LICENSE BLOCK *****
|
||||
|
||||
LIBRARY mozMapi32.dll
|
||||
DESCRIPTION 'Mozilla Simple MAPI Support'
|
||||
|
||||
EXPORTS
|
||||
MAPILogon
|
||||
MAPILogoff
|
||||
MAPISendMail
|
||||
MAPISendDocuments
|
||||
MAPIFindNext
|
||||
MAPIReadMail
|
||||
MAPISaveMail
|
||||
MAPIDeleteMail
|
||||
MAPIAddress
|
||||
MAPIDetails
|
||||
MAPIResolveName
|
||||
MAPIFreeBuffer
|
||||
GetMapiDllVersion
|
||||
|
||||
346
mozilla/mailnews/mapi/mapiDll/MapiDll.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
* Contributor(s): Rajiv Dayal (rdayal@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <mapidefs.h>
|
||||
#include <mapi.h>
|
||||
#include "msgMapi.h"
|
||||
#include "msgMapiMain.h"
|
||||
|
||||
#define MAX_RECIPS 100
|
||||
#define MAX_FILES 100
|
||||
|
||||
const CLSID CLSID_CMapiImp = {0x29f458be, 0x8866, 0x11d5,
|
||||
{0xa3, 0xdd, 0x0, 0xb0, 0xd0, 0xf3, 0xba, 0xa7}};
|
||||
const IID IID_nsIMapi = {0x6EDCD38E,0x8861,0x11d5,
|
||||
{0xA3,0xDD,0x00,0xB0,0xD0,0xF3,0xBA,0xA7}};
|
||||
|
||||
DWORD tId = 0;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE aInstance, DWORD aReason, LPVOID aReserved)
|
||||
{
|
||||
switch (aReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH : tId = TlsAlloc();
|
||||
if (tId == 0xFFFFFFFF)
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH : TlsFree(tId);
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL InitMozillaReference(nsIMapi **aRetValue)
|
||||
{
|
||||
// Check wehther this thread has a valid Interface
|
||||
// by looking into thread-specific-data variable
|
||||
|
||||
*aRetValue = (nsIMapi *)TlsGetValue(tId);
|
||||
|
||||
// Check whether the pointer actually resolves to
|
||||
// a valid method call; otherwise mozilla is not running
|
||||
|
||||
if ((*aRetValue) && (*aRetValue)->IsValid() == S_OK)
|
||||
return TRUE;
|
||||
|
||||
HRESULT hRes = ::CoInitialize(nsnull) ;
|
||||
|
||||
hRes = ::CoCreateInstance(CLSID_CMapiImp, NULL, CLSCTX_LOCAL_SERVER,
|
||||
IID_nsIMapi, (LPVOID *)aRetValue);
|
||||
|
||||
if (hRes == S_OK && (*aRetValue)->Initialize() == S_OK)
|
||||
if (TlsSetValue(tId, (LPVOID)(*aRetValue)))
|
||||
return TRUE;
|
||||
|
||||
// Either CoCreate or TlsSetValue failed; so return FALSE
|
||||
|
||||
if ((*aRetValue))
|
||||
(*aRetValue)->Release();
|
||||
|
||||
::CoUninitialize();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The MAPILogon function begins a Simple MAPI session, loading the default message ////
|
||||
// store and address book providers ////
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG FAR PASCAL MAPILogon(ULONG aUIParam, LPTSTR aProfileName,
|
||||
LPTSTR aPassword, FLAGS aFlags,
|
||||
ULONG aReserved, LPLHANDLE aSession)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
ULONG nSessionId = 0;
|
||||
nsIMapi *pNsMapi = NULL;
|
||||
|
||||
if (!InitMozillaReference(&pNsMapi))
|
||||
return MAPI_E_FAILURE;
|
||||
|
||||
if (!(aFlags & MAPI_UNICODE))
|
||||
{
|
||||
// Need to convert the parameters to Unicode.
|
||||
|
||||
char *pUserName = (char *) aProfileName;
|
||||
char *pPassWord = (char *) aPassword;
|
||||
|
||||
TCHAR ProfileName[MAX_NAME_LEN] = {0};
|
||||
TCHAR PassWord[MAX_PW_LEN] = {0};
|
||||
|
||||
if (pUserName != NULL)
|
||||
{
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, pUserName, -1, ProfileName,
|
||||
MAX_NAME_LEN))
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
if (pPassWord != NULL)
|
||||
{
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, pPassWord, -1, PassWord,
|
||||
MAX_NAME_LEN))
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
hr = pNsMapi->Login(aUIParam, ProfileName, PassWord, aFlags,
|
||||
&nSessionId);
|
||||
}
|
||||
else
|
||||
hr = pNsMapi->Login(aUIParam, aProfileName, aPassword,
|
||||
aFlags, &nSessionId);
|
||||
if (hr == S_OK)
|
||||
(*aSession) = (LHANDLE) nSessionId;
|
||||
else
|
||||
return nSessionId;
|
||||
|
||||
return SUCCESS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPILogoff (LHANDLE aSession, ULONG aUIParam,
|
||||
FLAGS aFlags, ULONG aReserved)
|
||||
{
|
||||
nsIMapi *pNsMapi = (nsIMapi *)TlsGetValue(tId);
|
||||
if (pNsMapi != NULL)
|
||||
{
|
||||
if (pNsMapi->Logoff((ULONG) aSession) == S_OK)
|
||||
pNsMapi->Release();
|
||||
pNsMapi = NULL;
|
||||
}
|
||||
|
||||
TlsSetValue(tId, NULL);
|
||||
|
||||
::CoUninitialize();
|
||||
|
||||
return SUCCESS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPISendMail (LHANDLE lhSession, ULONG ulUIParam, lpnsMapiMessage lpMessage,
|
||||
FLAGS flFlags, ULONG ulReserved )
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
BOOL bTempSession = FALSE ;
|
||||
nsIMapi *pNsMapi = NULL;
|
||||
|
||||
if (!InitMozillaReference(&pNsMapi))
|
||||
return MAPI_E_FAILURE;
|
||||
|
||||
if (lpMessage->nRecipCount > MAX_RECIPS)
|
||||
return MAPI_E_TOO_MANY_RECIPIENTS ;
|
||||
|
||||
if (lpMessage->nFileCount > MAX_FILES)
|
||||
return MAPI_E_TOO_MANY_FILES ;
|
||||
|
||||
if ( (!(flFlags & MAPI_DIALOG)) && (lpMessage->lpRecips == NULL) )
|
||||
return MAPI_E_UNKNOWN_RECIPIENT ;
|
||||
|
||||
if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK)
|
||||
{
|
||||
FLAGS LoginFlag ;
|
||||
if ( (flFlags & MAPI_LOGON_UI) && (flFlags & MAPI_NEW_SESSION) )
|
||||
LoginFlag = MAPI_LOGON_UI | MAPI_NEW_SESSION ;
|
||||
else if (flFlags & MAPI_LOGON_UI)
|
||||
LoginFlag = MAPI_LOGON_UI ;
|
||||
|
||||
hr = MAPILogon (ulUIParam, (LPTSTR) NULL, (LPTSTR) NULL, LoginFlag, 0, &lhSession) ;
|
||||
if (hr != SUCCESS_SUCCESS)
|
||||
return MAPI_E_LOGIN_FAILURE ;
|
||||
bTempSession = TRUE ;
|
||||
}
|
||||
|
||||
// we need to deal with null data passed in by MAPI clients, specially when MAPI_DIALOG is set.
|
||||
// The MS COM type lib code generated by MIDL for the MS COM interfaces checks for these parameters
|
||||
// to be non null, although null is a valid value for them here.
|
||||
nsMapiRecipDesc * lpRecips ;
|
||||
nsMapiFileDesc * lpFiles ;
|
||||
|
||||
nsMapiMessage Message ;
|
||||
memset (&Message, 0, sizeof (nsMapiMessage) ) ;
|
||||
nsMapiRecipDesc Recipient ;
|
||||
memset (&Recipient, 0, sizeof (nsMapiRecipDesc) );
|
||||
nsMapiFileDesc Files ;
|
||||
memset (&Files, 0, sizeof (nsMapiFileDesc) ) ;
|
||||
|
||||
if(!lpMessage)
|
||||
{
|
||||
lpMessage = &Message ;
|
||||
}
|
||||
if(!lpMessage->lpRecips)
|
||||
{
|
||||
lpRecips = &Recipient ;
|
||||
}
|
||||
else
|
||||
lpRecips = lpMessage->lpRecips ;
|
||||
if(!lpMessage->lpFiles)
|
||||
{
|
||||
lpFiles = &Files ;
|
||||
}
|
||||
else
|
||||
lpFiles = lpMessage->lpFiles ;
|
||||
|
||||
HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, (LPCTSTR) MAPI_SENDCOMPLETE_EVENT) ;
|
||||
|
||||
hr = pNsMapi->SendMail (lhSession, lpMessage,
|
||||
(short) lpMessage->nRecipCount, lpRecips,
|
||||
(short) lpMessage->nFileCount, lpFiles,
|
||||
flFlags, ulReserved);
|
||||
|
||||
// we are seeing a problem when using Word, although we return success from the MAPI support
|
||||
// MS COM interface in mozilla, we are getting this error here. This is a temporary hack !!
|
||||
if (hr == 0x800703e6)
|
||||
hr = SUCCESS_SUCCESS;
|
||||
|
||||
if (hr == SUCCESS_SUCCESS)
|
||||
WaitForSingleObject (hEvent, INFINITE) ;
|
||||
CloseHandle (hEvent) ;
|
||||
|
||||
if (bTempSession)
|
||||
MAPILogoff (lhSession, ulUIParam, 0,0) ;
|
||||
|
||||
return hr ;
|
||||
}
|
||||
|
||||
|
||||
ULONG FAR PASCAL MAPISendDocuments(ULONG ulUIParam, LPTSTR lpszDelimChar, LPTSTR lpszFilePaths,
|
||||
LPTSTR lpszFileNames, ULONG ulReserved)
|
||||
{
|
||||
LHANDLE lhSession ;
|
||||
nsIMapi *pNsMapi = NULL;
|
||||
|
||||
if (!InitMozillaReference(&pNsMapi))
|
||||
return MAPI_E_FAILURE;
|
||||
|
||||
unsigned long result = MAPILogon (ulUIParam, (LPTSTR) NULL, (LPTSTR) NULL, MAPI_LOGON_UI, 0, &lhSession) ;
|
||||
if (result != SUCCESS_SUCCESS)
|
||||
return MAPI_E_LOGIN_FAILURE ;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, (LPCTSTR) MAPI_SENDCOMPLETE_EVENT) ;
|
||||
|
||||
hr = pNsMapi->SendDocuments(lhSession, (LPTSTR) lpszDelimChar, (LPTSTR) lpszFilePaths,
|
||||
(LPTSTR) lpszFileNames, ulReserved) ;
|
||||
|
||||
if (hr == SUCCESS_SUCCESS)
|
||||
WaitForSingleObject (hEvent, INFINITE) ;
|
||||
CloseHandle (hEvent) ;
|
||||
|
||||
MAPILogoff (lhSession, ulUIParam, 0,0) ;
|
||||
|
||||
return hr ;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIFindNext(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageType,
|
||||
LPTSTR lpszSeedMessageID, FLAGS flFlags, ULONG ulReserved,
|
||||
LPTSTR lpszMessageID)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIReadMail(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageID,
|
||||
FLAGS flFlags, ULONG ulReserved, lpMapiMessage FAR *lppMessage)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPISaveMail(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage,
|
||||
FLAGS flFlags, ULONG ulReserved, LPTSTR lpszMessageID)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIDeleteMail(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageID,
|
||||
FLAGS flFlags, ULONG ulReserved)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIAddress(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszCaption,
|
||||
ULONG nEditFields, LPTSTR lpszLabels, ULONG nRecips,
|
||||
lpMapiRecipDesc lpRecips, FLAGS flFlags,
|
||||
ULONG ulReserved, LPULONG lpnNewRecips,
|
||||
lpMapiRecipDesc FAR *lppNewRecips)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIDetails(LHANDLE lhSession, ULONG ulUIParam, lpMapiRecipDesc lpRecip,
|
||||
FLAGS flFlags, ULONG ulReserved)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIResolveName(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszName,
|
||||
FLAGS flFlags, ULONG ulReserved, lpMapiRecipDesc FAR *lppRecip)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL MAPIFreeBuffer(LPVOID pv)
|
||||
{
|
||||
return MAPI_E_FAILURE;
|
||||
}
|
||||
|
||||
ULONG FAR PASCAL GetMapiDllVersion()
|
||||
{
|
||||
return 94;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
62
mozilla/mailnews/mapi/mapiDll/makefile.win
Normal file
@@ -0,0 +1,62 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corp.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
MODULE = mozMapi32
|
||||
EXPORT_LIBRARY = $(MODULE)
|
||||
LIBRARY_NAME = $(MODULE)
|
||||
DEFFILE = Mapi32.def
|
||||
|
||||
REQUIRES = MapiProxy \
|
||||
msgMapi \
|
||||
xpcom \
|
||||
string \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
###############################################################
|
||||
|
||||
LCFLAGS=-DUNICODE -D_UNICODE
|
||||
|
||||
OBJS= .\$(OBJDIR)\MapiDll.obj \
|
||||
$(NULL)
|
||||
|
||||
WIN_LIBS= ole32.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
47
mozilla/mailnews/mapi/mapihook/build/MapiProxy.def
Normal file
@@ -0,0 +1,47 @@
|
||||
; ***** BEGIN LICENSE BLOCK *****
|
||||
; Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
;
|
||||
; The contents of this file are subject to the Mozilla Public License Version
|
||||
; 1.1 (the "License"); you may not use this file except in compliance with
|
||||
; the License. You may obtain a copy of the License at
|
||||
; http://www.mozilla.org/MPL/
|
||||
;
|
||||
; Software distributed under the License is distributed on an "AS IS" basis,
|
||||
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
; for the specific language governing rights and limitations under the
|
||||
; License.
|
||||
;
|
||||
; The Original Code is Mozilla.
|
||||
;
|
||||
; The Initial Developer of the Original Code is
|
||||
; Netscape Communications Corp.
|
||||
; Portions created by the Initial Developer are Copyright (C) 2001
|
||||
; the Initial Developer. All Rights Reserved.
|
||||
;
|
||||
; Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
;
|
||||
; Alternatively, the contents of this file may be used under the terms of
|
||||
; either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
; in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
; of those above. If you wish to allow use of your version of this file only
|
||||
; under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
; use your version of this file under the terms of the MPL, indicate your
|
||||
; decision by deleting the provisions above and replace them with the notice
|
||||
; and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
; the provisions above, a recipient may use your version of this file under
|
||||
; the terms of any one of the MPL, the GPL or the LGPL.
|
||||
;
|
||||
; ***** END LICENSE BLOCK *****
|
||||
|
||||
LIBRARY MapiProxy.dll
|
||||
DESCRIPTION 'Proxy/Stub DLL'
|
||||
|
||||
EXPORTS
|
||||
DllGetClassObject @1 PRIVATE
|
||||
DllCanUnloadNow @2 PRIVATE
|
||||
GetProxyDllInfo @3 PRIVATE
|
||||
DllRegisterServer @4 PRIVATE
|
||||
DllUnregisterServer @5 PRIVATE
|
||||
|
||||
|
||||
68
mozilla/mailnews/mapi/mapihook/build/makefile.win
Normal file
@@ -0,0 +1,68 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corp.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE = MapiProxy
|
||||
EXPORT_LIBRARY = $(MODULE)
|
||||
LIBRARY_NAME = $(MODULE)
|
||||
DEFFILE = MapiProxy.def
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
##################################################################
|
||||
|
||||
LCFLAGS=-DREGISTER_PROXY_DLL -DUNICODE -D_UNICODE
|
||||
|
||||
OBJS= .\$(OBJDIR)\dlldata.obj \
|
||||
.\$(OBJDIR)\msgMapi_p.obj \
|
||||
.\$(OBJDIR)\msgMapi_i.obj \
|
||||
$(NULL)
|
||||
|
||||
WIN_LIBS= rpcrt4.lib
|
||||
|
||||
EXPORTS= msgMapi.h \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
msgMapi.h msgMapi_p.c msgMapi_i.c dlldata.c : msgMapi.idl
|
||||
midl $(UNICODE_FLAGS) msgMapi.idl
|
||||
|
||||
clobber::
|
||||
rm -f dlldata.c msgMapi_i.c msgMapi_p.c msgMapi.h
|
||||
|
||||
|
||||
114
mozilla/mailnews/mapi/mapihook/build/msgMapi.idl
Normal file
@@ -0,0 +1,114 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
* Contributor(s): Rajiv Dayal (rdayal@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This idl will be compiled by MIDL. MS-COM is used
|
||||
// as brdige between MAPI clients and the Mozilla.
|
||||
|
||||
import "unknwn.idl";
|
||||
|
||||
typedef wchar_t LOGIN_PW_TYPE[256];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long ulReserved;
|
||||
unsigned long flFlags; /* Flags */
|
||||
unsigned long nPosition_NotUsed; /* character in text to be replaced by attachment */
|
||||
LPTSTR lpszPathName; /* Full path name including file name */
|
||||
LPTSTR lpszFileName; /* Real (original) file name */
|
||||
unsigned char * lpFileType_NotUsed ;
|
||||
} nsMapiFileDesc, * lpnsMapiFileDesc;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long ulReserved;
|
||||
unsigned long ulRecipClass; /* MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG */
|
||||
LPTSTR lpszName; /* Recipient name to display */
|
||||
LPTSTR lpszAddress; /* Recipient email address */
|
||||
unsigned long ulEIDSize_NotUsed;
|
||||
unsigned char * lpEntryID_NotUsed ;
|
||||
} nsMapiRecipDesc, * lpnsMapiRecipDesc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long ulReserved;
|
||||
LPTSTR lpszSubject; /* Message Subject */
|
||||
LPTSTR lpszNoteText; /* Message Text */
|
||||
LPTSTR lpszMessageType_NotUsed;
|
||||
LPTSTR lpszDateReceived_notUsed; /* in YYYY/MM/DD HH:MM format */
|
||||
LPTSTR lpszConversationID_NotUsed; /* conversation thread ID */
|
||||
unsigned long flFlags; /* unread,return receipt */
|
||||
lpnsMapiRecipDesc lpOriginator; /* Originator descriptor */
|
||||
unsigned long nRecipCount; /* Number of recipients */
|
||||
lpnsMapiRecipDesc lpRecips; /* Recipient descriptors */
|
||||
unsigned long nFileCount; /* # of file attachments */
|
||||
lpnsMapiFileDesc lpFiles; /* Attachment descriptors */
|
||||
} nsMapiMessage, * lpnsMapiMessage;
|
||||
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(6EDCD38E-8861-11d5-A3DD-00B0D0F3BAA7),
|
||||
helpstring("nsIMapi Inteface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
|
||||
interface nsIMapi : IUnknown
|
||||
{
|
||||
HRESULT Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin,
|
||||
LOGIN_PW_TYPE aPassWord, unsigned long aFlags,
|
||||
[out] unsigned long *aSessionId);
|
||||
|
||||
HRESULT Initialize();
|
||||
HRESULT IsValid();
|
||||
HRESULT IsValidSession([in] unsigned long aSession);
|
||||
|
||||
HRESULT SendMail([in] unsigned long aSession, [in] lpnsMapiMessage aMessage,
|
||||
[in] short aRecipCount, [in, size_is(aRecipCount)] lpnsMapiRecipDesc aRecips,
|
||||
[in] short aFileCount, [in, size_is(aFileCount)] lpnsMapiFileDesc aFiles,
|
||||
[in] unsigned long aFlags, [in] unsigned long aReserved) ;
|
||||
|
||||
HRESULT SendDocuments( [in] unsigned long aSession,
|
||||
[in] LPTSTR aDelimChar, [in] LPTSTR aFilePaths,
|
||||
[in] LPTSTR aFileNames, [in] ULONG aFlags ) ;
|
||||
|
||||
HRESULT Logoff (unsigned long aSession);
|
||||
HRESULT CleanUp();
|
||||
};
|
||||
|
||||
|
||||
|
||||
41
mozilla/mailnews/mapi/mapihook/makefile.win
Normal file
@@ -0,0 +1,41 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corp.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Srilatha Moturi (srilatha@netscape.com)
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS= build public src
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
49
mozilla/mailnews/mapi/mapihook/public/makefile.win
Normal file
@@ -0,0 +1,49 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE=msgMapi
|
||||
XPIDL_MODULE=mapihook
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIMapiRegistry.idl \
|
||||
.\nsIMapiSupport.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
70
mozilla/mailnews/mapi/mapihook/public/nsIMapiRegistry.idl
Normal file
@@ -0,0 +1,70 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
/**
|
||||
* This interface provides support for registering Mozilla as the default
|
||||
* Mail Client. This interface can also be used to get/set the user preference
|
||||
* for the default Mail Client.
|
||||
*
|
||||
*/
|
||||
[scriptable, uuid(c5be14ba-4e0a-4eec-a1b8-04363761d63c)]
|
||||
interface nsIMapiRegistry: nsISupports {
|
||||
|
||||
/** This is set to TRUE if Mozilla is the default Application
|
||||
*/
|
||||
attribute boolean isDefaultMailClient;
|
||||
|
||||
/** This is set TRUE only once per session.
|
||||
*/
|
||||
readonly attribute boolean showDialog;
|
||||
|
||||
/** This will bring the dialog asking the user if he/she wants to set
|
||||
* Mozilla as default Mail Client.
|
||||
* Call this only if Mozilla is not the default Mail client
|
||||
*/
|
||||
void showMailIntegrationDialog(in nsIDOMWindow parentWindow);
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1"
|
||||
#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry"
|
||||
%}
|
||||
64
mozilla/mailnews/mapi/mapihook/public/nsIMapiSupport.idl
Normal file
@@ -0,0 +1,64 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* This interface provides support for registering Mozilla as a COM component
|
||||
* for extending the use of Mail/News through Simple MAPI.
|
||||
*
|
||||
*/
|
||||
|
||||
[noscript, uuid(8967fed2-c8bb-11d5-a3e9-00b0d0f3baa7)]
|
||||
interface nsIMapiSupport : nsISupports {
|
||||
|
||||
/** Initiates MAPI support
|
||||
*/
|
||||
|
||||
void initializeMAPISupport();
|
||||
|
||||
/** Shuts down the MAPI support
|
||||
*/
|
||||
|
||||
void shutdownMAPISupport();
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_IMAPISUPPORT_CONTRACTID "@mozilla.org/mapisupport;1"
|
||||
#define NS_IMAPISUPPORT_CLASSNAME "Mozilla MAPI Support"
|
||||
%}
|
||||
|
||||
|
||||
323
mozilla/mailnews/mapi/mapihook/src/Registry.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika <kkhandrika@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#undef _UNICODE
|
||||
#undef UNICODE
|
||||
|
||||
#include <objbase.h>
|
||||
#include "nsString.h"
|
||||
#include "Registry.h"
|
||||
|
||||
#define MAPI_PROXY_DLL_NAME "MapiProxy.dll"
|
||||
#define MAPI_STARTUP_ARG " /MAPIStartUp"
|
||||
#define MAX_SIZE 2048
|
||||
|
||||
// Size of a CLSID as a string
|
||||
const int CLSID_STRING_SIZE = 39;
|
||||
|
||||
// Proxy/Stub Dll Routines
|
||||
|
||||
typedef HRESULT (__stdcall ProxyServer)();
|
||||
|
||||
|
||||
// Convert a CLSID to a char string.
|
||||
|
||||
BOOL CLSIDtochar(const CLSID& clsid, char* szCLSID,
|
||||
int length)
|
||||
{
|
||||
LPOLESTR wszCLSID = NULL;
|
||||
|
||||
// Get CLSID
|
||||
HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
|
||||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
// Covert from wide characters to non-wide.
|
||||
wcstombs(szCLSID, wszCLSID, length);
|
||||
|
||||
// Free memory.
|
||||
CoTaskMemFree(wszCLSID);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Create a key and set its value.
|
||||
|
||||
BOOL setKeyAndValue(nsCAutoString keyName, const char* subKey,
|
||||
const char* theValue)
|
||||
{
|
||||
HKEY hKey;
|
||||
BOOL retValue = TRUE;
|
||||
|
||||
nsCAutoString theKey(keyName);
|
||||
if (subKey != NULL)
|
||||
{
|
||||
theKey += "\\";
|
||||
theKey += subKey;
|
||||
}
|
||||
|
||||
// Create and open key and subkey.
|
||||
long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, theKey.get(),
|
||||
0, NULL, REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS, NULL, &hKey, NULL);
|
||||
if (lResult != ERROR_SUCCESS)
|
||||
return FALSE ;
|
||||
|
||||
// Set the Value.
|
||||
if (theValue != NULL)
|
||||
{
|
||||
lResult = RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)theValue,
|
||||
strlen(theValue)+1);
|
||||
if (lResult != ERROR_SUCCESS)
|
||||
retValue = FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Delete a key and all of its descendents.
|
||||
|
||||
LONG recursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete
|
||||
const char* lpszKeyChild) // Key to delete
|
||||
{
|
||||
// Open the child.
|
||||
HKEY hKeyChild ;
|
||||
LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
|
||||
KEY_ALL_ACCESS, &hKeyChild) ;
|
||||
if (lRes != ERROR_SUCCESS)
|
||||
{
|
||||
return lRes ;
|
||||
}
|
||||
|
||||
// Enumerate all of the decendents of this child.
|
||||
FILETIME time ;
|
||||
char szBuffer[MAX_SIZE] ;
|
||||
DWORD dwSize = MAX_SIZE ;
|
||||
while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
|
||||
NULL, NULL, &time) == S_OK)
|
||||
{
|
||||
// Delete the decendents of this child.
|
||||
lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
|
||||
if (lRes != ERROR_SUCCESS)
|
||||
{
|
||||
// Cleanup before exiting.
|
||||
RegCloseKey(hKeyChild) ;
|
||||
return lRes;
|
||||
}
|
||||
dwSize = MAX_SIZE;
|
||||
}
|
||||
|
||||
// Close the child.
|
||||
RegCloseKey(hKeyChild) ;
|
||||
|
||||
// Delete this child.
|
||||
return RegDeleteKey(hKeyParent, lpszKeyChild) ;
|
||||
}
|
||||
|
||||
void RegisterProxy()
|
||||
{
|
||||
HINSTANCE h = NULL;
|
||||
ProxyServer *RegisterFunc = NULL;
|
||||
|
||||
char szModule[MAX_SIZE];
|
||||
char *pTemp = NULL;
|
||||
|
||||
HMODULE hModule = GetModuleHandle(NULL);
|
||||
DWORD dwResult = ::GetModuleFileName(hModule, szModule,
|
||||
sizeof(szModule)/sizeof(char));
|
||||
if (dwResult == 0)
|
||||
return;
|
||||
|
||||
pTemp = strrchr(szModule, '\\');
|
||||
if (pTemp == NULL)
|
||||
return;
|
||||
|
||||
*pTemp = '\0';
|
||||
nsCAutoString proxyPath(szModule);
|
||||
|
||||
proxyPath += "\\";
|
||||
proxyPath += MAPI_PROXY_DLL_NAME;
|
||||
|
||||
h = LoadLibrary(proxyPath.get());
|
||||
if (h == NULL)
|
||||
return;
|
||||
|
||||
RegisterFunc = (ProxyServer *) GetProcAddress(h, "DllRegisterServer");
|
||||
if (RegisterFunc)
|
||||
RegisterFunc();
|
||||
|
||||
FreeLibrary(h);
|
||||
}
|
||||
|
||||
void UnRegisterProxy()
|
||||
{
|
||||
HINSTANCE h = NULL;
|
||||
ProxyServer *UnRegisterFunc = NULL;
|
||||
|
||||
char szModule[MAX_SIZE];
|
||||
char *pTemp = NULL;
|
||||
|
||||
HMODULE hModule = GetModuleHandle(NULL);
|
||||
DWORD dwResult = ::GetModuleFileName(hModule, szModule,
|
||||
sizeof(szModule)/sizeof(char));
|
||||
if (dwResult == 0)
|
||||
return;
|
||||
|
||||
pTemp = strrchr(szModule, '\\');
|
||||
if (pTemp == NULL)
|
||||
return;
|
||||
|
||||
*pTemp = '\0';
|
||||
nsCAutoString proxyPath(szModule);
|
||||
|
||||
proxyPath += "\\";
|
||||
proxyPath += MAPI_PROXY_DLL_NAME;
|
||||
|
||||
h = LoadLibrary(proxyPath.get());
|
||||
if (h == NULL)
|
||||
return;
|
||||
|
||||
UnRegisterFunc = (ProxyServer *) GetProcAddress(h, "DllUnregisterServer");
|
||||
if (UnRegisterFunc)
|
||||
UnRegisterFunc();
|
||||
|
||||
FreeLibrary(h);
|
||||
}
|
||||
|
||||
// Register the component in the registry.
|
||||
|
||||
HRESULT RegisterServer(const CLSID& clsid, // Class ID
|
||||
const char* szFriendlyName, // Friendly Name
|
||||
const char* szVerIndProgID, // Programmatic
|
||||
const char* szProgID) // IDs
|
||||
{
|
||||
HMODULE hModule = GetModuleHandle(NULL);
|
||||
char szModuleName[MAX_SIZE];
|
||||
char szCLSID[CLSID_STRING_SIZE];
|
||||
|
||||
nsCAutoString independentProgId(szVerIndProgID);
|
||||
nsCAutoString progId(szProgID);
|
||||
|
||||
DWORD dwResult = ::GetModuleFileName(hModule, szModuleName,
|
||||
sizeof(szModuleName)/sizeof(char));
|
||||
|
||||
if (dwResult == 0)
|
||||
return S_FALSE;
|
||||
|
||||
nsCAutoString moduleName(szModuleName);
|
||||
nsCAutoString registryKey("CLSID\\");
|
||||
|
||||
moduleName += MAPI_STARTUP_ARG;
|
||||
|
||||
// Convert the CLSID into a char.
|
||||
|
||||
if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)))
|
||||
return S_FALSE;
|
||||
registryKey += szCLSID;
|
||||
|
||||
// Add the CLSID to the registry.
|
||||
if (!setKeyAndValue(registryKey, NULL, szFriendlyName))
|
||||
return S_FALSE;
|
||||
|
||||
if (!setKeyAndValue(registryKey, "LocalServer32", moduleName.get()))
|
||||
return S_FALSE;
|
||||
|
||||
// Add the ProgID subkey under the CLSID key.
|
||||
if (!setKeyAndValue(registryKey, "ProgID", szProgID))
|
||||
return S_FALSE;
|
||||
|
||||
// Add the version-independent ProgID subkey under CLSID key.
|
||||
if (!setKeyAndValue(registryKey, "VersionIndependentProgID", szVerIndProgID))
|
||||
return S_FALSE;
|
||||
|
||||
// Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
|
||||
if (!setKeyAndValue(independentProgId, NULL, szFriendlyName))
|
||||
return S_FALSE;
|
||||
if (!setKeyAndValue(independentProgId, "CLSID", szCLSID))
|
||||
return S_FALSE;
|
||||
if (!setKeyAndValue(independentProgId, "CurVer", szProgID))
|
||||
return S_FALSE;
|
||||
|
||||
// Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
|
||||
if (!setKeyAndValue(progId, NULL, szFriendlyName))
|
||||
return S_FALSE;
|
||||
if (!setKeyAndValue(progId, "CLSID", szCLSID))
|
||||
return S_FALSE;
|
||||
|
||||
RegisterProxy();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LONG UnregisterServer(const CLSID& clsid, // Class ID
|
||||
const char* szVerIndProgID, // Programmatic
|
||||
const char* szProgID) // IDs
|
||||
{
|
||||
LONG lResult = S_OK;
|
||||
|
||||
// Convert the CLSID into a char.
|
||||
|
||||
char szCLSID[CLSID_STRING_SIZE];
|
||||
if (!CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)))
|
||||
return S_FALSE;
|
||||
|
||||
UnRegisterProxy();
|
||||
|
||||
nsCAutoString registryKey("CLSID\\");
|
||||
registryKey += szCLSID;
|
||||
|
||||
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get());
|
||||
if (lResult == ERROR_SUCCESS || lResult == ERROR_FILE_NOT_FOUND)
|
||||
return lResult;
|
||||
|
||||
registryKey += "\\LocalServer32";
|
||||
|
||||
// Delete only the path for this server.
|
||||
|
||||
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, registryKey.get());
|
||||
if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND)
|
||||
return lResult;
|
||||
|
||||
// Delete the version-independent ProgID Key.
|
||||
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID);
|
||||
if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND)
|
||||
return lResult;
|
||||
|
||||
lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID);
|
||||
|
||||
return lResult;
|
||||
}
|
||||
56
mozilla/mailnews/mapi/mapihook/src/Registry.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Krishna Mohan Khandrika <kkhandrika@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _REGISTRY_H_
|
||||
#define _REGISTRY_H_
|
||||
|
||||
#include <objbase.h>
|
||||
|
||||
// This function will register a component in the Registry.
|
||||
|
||||
HRESULT RegisterServer(const CLSID& clsid,
|
||||
const char* szFriendlyName,
|
||||
const char* szVerIndProgID,
|
||||
const char* szProgID) ;
|
||||
|
||||
// This function will unregister a component.
|
||||
|
||||
HRESULT UnregisterServer(const CLSID& clsid,
|
||||
const char* szVerIndProgID,
|
||||
const char* szProgID) ;
|
||||
|
||||
#endif
|
||||
107
mozilla/mailnews/mapi/mapihook/src/makefile.win
Normal file
@@ -0,0 +1,107 @@
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE = msgMapi
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
LIBRARY_NAME=$(MODULE)
|
||||
MODULE_NAME = $(MODULE)
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
MapiProxy \
|
||||
appshell \
|
||||
windowwatcher \
|
||||
dom \
|
||||
profile \
|
||||
msgbase \
|
||||
pref \
|
||||
msgbaseutil \
|
||||
msgcompo \
|
||||
mailnews \
|
||||
necko \
|
||||
intl \
|
||||
editor \
|
||||
msgdb \
|
||||
uriloader \
|
||||
appstartup \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
############################################################################
|
||||
|
||||
LCFLAGS=-DUNICODE -D_UNICODE
|
||||
|
||||
|
||||
|
||||
OBJS= \
|
||||
..\build\$(OBJDIR)\msgMapi_i.obj \
|
||||
.\$(OBJDIR)\msgMapiFactory.obj \
|
||||
.\$(OBJDIR)\msgMapiHook.obj \
|
||||
.\$(OBJDIR)\msgMapiImp.obj \
|
||||
.\$(OBJDIR)\msgMapiMain.obj \
|
||||
.\$(OBJDIR)\msgMapiSupport.obj \
|
||||
.\$(OBJDIR)\nsMapiRegistry.obj \
|
||||
.\$(OBJDIR)\nsMapiRegistryUtils.obj \
|
||||
.\$(OBJDIR)\Registry.obj \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\msgbsutl.lib \
|
||||
$(LIBNSPR) \
|
||||
$(NULL)
|
||||
|
||||
WIN_LIBS= \
|
||||
ole32.lib \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS= \
|
||||
msgMapiFactory.h \
|
||||
msgMapiHook.h \
|
||||
msgMapiImp.h \
|
||||
msgMapiMain.h \
|
||||
msgMapiSupport.h \
|
||||
nsMapiRegistry.h \
|
||||
nsMapiRegistryUtils.h \
|
||||
Registry.h \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
118
mozilla/mailnews/mapi/mapihook/src/msgMapiFactory.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#undef UNICODE
|
||||
#undef _UNICODE
|
||||
|
||||
#include "msgMapiFactory.h"
|
||||
#include "msgMapiImp.h"
|
||||
#include "msgMapi.h"
|
||||
|
||||
CMapiFactory ::CMapiFactory()
|
||||
: m_cRef(1)
|
||||
{
|
||||
}
|
||||
|
||||
CMapiFactory::~CMapiFactory()
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiFactory::QueryInterface(const IID& aIid, void** aPpv)
|
||||
{
|
||||
if ((aIid == IID_IUnknown) || (aIid == IID_IClassFactory))
|
||||
{
|
||||
*aPpv = static_cast<IClassFactory*>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
*aPpv = nsnull;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
reinterpret_cast<IUnknown*>(*aPpv)->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CMapiFactory::AddRef()
|
||||
{
|
||||
return (PR_AtomicIncrement(&m_cRef));
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CMapiFactory::Release()
|
||||
{
|
||||
PRInt32 temp;
|
||||
temp = PR_AtomicDecrement(&m_cRef);
|
||||
if (m_cRef == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiFactory::CreateInstance(IUnknown* aUnknownOuter,
|
||||
const IID& aIid,
|
||||
void** aPpv)
|
||||
{
|
||||
// Cannot aggregate.
|
||||
|
||||
if (aUnknownOuter != nsnull)
|
||||
{
|
||||
return CLASS_E_NOAGGREGATION ;
|
||||
}
|
||||
|
||||
// Create component.
|
||||
|
||||
CMapiImp* pImp = new CMapiImp();
|
||||
if (pImp == nsnull)
|
||||
{
|
||||
return E_OUTOFMEMORY ;
|
||||
}
|
||||
|
||||
// Get the requested interface.
|
||||
HRESULT hr = pImp->QueryInterface(aIid, aPpv);
|
||||
|
||||
// Release the IUnknown pointer.
|
||||
// (If QueryInterface failed, component will delete itself.)
|
||||
|
||||
pImp->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiFactory::LockServer(PRBool aLock)
|
||||
{
|
||||
return S_OK ;
|
||||
}
|
||||
69
mozilla/mailnews/mapi/mapihook/src/msgMapiFactory.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MSG_MAPI_FACTORY_H
|
||||
#define MSG_MAPI_FACTORY_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include "nspr.h"
|
||||
|
||||
|
||||
class CMapiFactory : public IClassFactory
|
||||
{
|
||||
public :
|
||||
|
||||
// IUnknown
|
||||
|
||||
STDMETHODIMP QueryInterface (REFIID aIid, void** aPpv);
|
||||
STDMETHODIMP_(ULONG) AddRef(void);
|
||||
STDMETHODIMP_(ULONG) Release(void);
|
||||
|
||||
// IClassFactory
|
||||
|
||||
STDMETHODIMP CreateInstance (LPUNKNOWN aUnkOuter, REFIID aIid, void **aPpv);
|
||||
STDMETHODIMP LockServer (BOOL aLock);
|
||||
|
||||
CMapiFactory ();
|
||||
~CMapiFactory ();
|
||||
|
||||
private :
|
||||
|
||||
PRInt32 m_cRef;
|
||||
};
|
||||
|
||||
#endif // MSG_MAPI_FACTORY_H
|
||||
|
||||
777
mozilla/mailnews/mapi/mapihook/src/msgMapiHook.cpp
Normal file
@@ -0,0 +1,777 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
* Contributor(s): Srilatha Moturi (srilatha@netscape.com)
|
||||
* Contributor(s): Rajiv Dayal (rdayal@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define MAPI_STARTUP_ARG "/MAPIStartUp"
|
||||
|
||||
#define MAPI_STARTUP_ARG "/MAPIStartUp"
|
||||
|
||||
#include <mapidefs.h>
|
||||
#include <mapi.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsAppShellCIDs.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIAppShellService.h"
|
||||
#include "nsINativeAppSupport.h"
|
||||
#include "nsICmdLineService.h"
|
||||
#include "nsIProfileInternal.h"
|
||||
#include "nsIMsgAccountManager.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsMsgBaseCID.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "nsIMsgAttachment.h"
|
||||
#include "nsIMsgCompFields.h"
|
||||
#include "nsIMsgComposeParams.h"
|
||||
#include "nsIMsgCompose.h"
|
||||
#include "nsMsgCompCID.h"
|
||||
#include "nsIMsgSend.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsIMsgComposeService.h"
|
||||
#include "nsProxiedService.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsMsgI18N.h"
|
||||
|
||||
#include "msgMapi.h"
|
||||
#include "msgMapiHook.h"
|
||||
#include "msgMapiSupport.h"
|
||||
#include "msgMapiMain.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID);
|
||||
|
||||
class nsMAPISendListener : public nsIMsgSendListener
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~nsMAPISendListener() { }
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* void OnStartSending (in string aMsgID, in PRUint32 aMsgSize); */
|
||||
NS_IMETHOD OnStartSending(const char *aMsgID, PRUint32 aMsgSize) { return NS_OK; }
|
||||
|
||||
/* void OnProgress (in string aMsgID, in PRUint32 aProgress, in PRUint32 aProgressMax); */
|
||||
NS_IMETHOD OnProgress(const char *aMsgID, PRUint32 aProgress, PRUint32 aProgressMax) { return NS_OK;}
|
||||
|
||||
/* void OnStatus (in string aMsgID, in wstring aMsg); */
|
||||
NS_IMETHOD OnStatus(const char *aMsgID, const PRUnichar *aMsg) { return NS_OK;}
|
||||
|
||||
/* void OnStopSending (in string aMsgID, in nsresult aStatus, in wstring aMsg, in nsIFileSpec returnFileSpec); */
|
||||
NS_IMETHOD OnStopSending(const char *aMsgID, nsresult aStatus, const PRUnichar *aMsg,
|
||||
nsIFileSpec *returnFileSpec) {
|
||||
m_done = PR_TRUE;
|
||||
HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, (LPCTSTR) MAPI_SENDCOMPLETE_EVENT) ;
|
||||
SetEvent (hEvent) ;
|
||||
CloseHandle (hEvent) ;
|
||||
return NS_OK ;
|
||||
}
|
||||
|
||||
/* void OnSendNotPerformed */
|
||||
NS_IMETHOD OnSendNotPerformed(const char *aMsgID, nsresult aStatus)
|
||||
{
|
||||
return OnStopSending(aMsgID, aStatus, nsnull, nsnull) ;
|
||||
}
|
||||
|
||||
/* void OnGetDraftFolderURI (); */
|
||||
NS_IMETHOD OnGetDraftFolderURI(const char *aFolderURI) {return NS_OK;}
|
||||
|
||||
static nsresult CreateMAPISendListener( nsIMsgSendListener **ppListener);
|
||||
|
||||
PRBool IsDone() { return m_done ; }
|
||||
|
||||
protected :
|
||||
nsMAPISendListener() {
|
||||
NS_INIT_REFCNT();
|
||||
m_done = PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool m_done;
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMAPISendListener, nsIMsgSendListener)
|
||||
|
||||
nsresult nsMAPISendListener::CreateMAPISendListener( nsIMsgSendListener **ppListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(ppListener) ;
|
||||
|
||||
*ppListener = new nsMAPISendListener();
|
||||
if (! *ppListener)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*ppListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsMapiHook::isMapiService = PR_FALSE;
|
||||
|
||||
PRBool nsMapiHook::Initialize()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINativeAppSupport> native;
|
||||
|
||||
nsCOMPtr<nsICmdLineService> cmdLineArgs(do_GetService(kCmdLineServiceCID, &rv));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIAppShellService> appShell (do_GetService( "@mozilla.org/appshell/appShellService;1", &rv));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
rv = appShell->GetNativeAppSupport( getter_AddRefs( native ));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
rv = native->EnsureProfile(cmdLineArgs);
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsMapiHook::CleanUp()
|
||||
{
|
||||
// This routine will be fully implemented in future
|
||||
// to cleanup mapi related stuff inside mozilla code.
|
||||
}
|
||||
|
||||
PRBool nsMapiHook::DisplayLoginDialog(PRBool aLogin, PRUnichar **aUsername, \
|
||||
PRUnichar **aPassword)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool btnResult = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIAppShellService> appShell(do_GetService( "@mozilla.org/appshell/appShellService;1", &rv));
|
||||
if (NS_FAILED(rv) || !appShell) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPromptService> dlgService(do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv));
|
||||
if (NS_SUCCEEDED(rv) && dlgService)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || !bundleService) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(MAPI_PROPERTIES_CHROME, getter_AddRefs(bundle));
|
||||
if (NS_FAILED(rv) || !bundle) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
rv = bundleService->CreateBundle(
|
||||
"chrome://global/locale/brand.properties",
|
||||
getter_AddRefs(brandBundle));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
nsXPIDLString brandName;
|
||||
rv = brandBundle->GetStringFromName(
|
||||
NS_LITERAL_STRING("brandShortName").get(),
|
||||
getter_Copies(brandName));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
nsXPIDLString loginTitle;
|
||||
const PRUnichar *brandStrings[] = { brandName.get() };
|
||||
NS_NAMED_LITERAL_STRING(loginTitlePropertyTag, "loginTitle");
|
||||
const PRUnichar *dTitlePropertyTag = loginTitlePropertyTag.get();
|
||||
rv = bundle->FormatStringFromName(dTitlePropertyTag, brandStrings, 1,
|
||||
getter_Copies(loginTitle));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
if (aLogin)
|
||||
{
|
||||
nsXPIDLString loginText;
|
||||
rv = bundle->GetStringFromName(NS_LITERAL_STRING("loginTextwithName").get(),
|
||||
getter_Copies(loginText));
|
||||
if (NS_FAILED(rv) || !loginText) return PR_FALSE;
|
||||
|
||||
|
||||
|
||||
rv = dlgService->PromptUsernameAndPassword(nsnull, loginTitle,
|
||||
loginText, aUsername, aPassword,
|
||||
nsnull, PR_FALSE, &btnResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
//nsString loginString;
|
||||
nsXPIDLString loginText;
|
||||
const PRUnichar *userNameStrings[] = { *aUsername };
|
||||
|
||||
NS_NAMED_LITERAL_STRING(loginTextPropertyTag, "loginText");
|
||||
const PRUnichar *dpropertyTag = loginTextPropertyTag.get();
|
||||
rv = bundle->FormatStringFromName(dpropertyTag, userNameStrings, 1,
|
||||
getter_Copies(loginText));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
rv = dlgService->PromptPassword(nsnull, loginTitle, loginText,
|
||||
aPassword, nsnull, PR_FALSE, &btnResult);
|
||||
}
|
||||
}
|
||||
|
||||
return btnResult;
|
||||
}
|
||||
|
||||
PRBool nsMapiHook::VerifyUserName(const PRUnichar *aUsername, char **aIdKey)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (aUsername == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIMsgAccountManager> accountManager(do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
nsCOMPtr<nsISupportsArray> identities;
|
||||
rv = accountManager->GetAllIdentities(getter_AddRefs(identities));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
PRUint32 numIndentities;
|
||||
identities->Count(&numIndentities);
|
||||
|
||||
for (PRUint32 i = 0; i < numIndentities; i++)
|
||||
{
|
||||
// convert supports->Identity
|
||||
nsCOMPtr<nsISupports> thisSupports;
|
||||
rv = identities->GetElementAt(i, getter_AddRefs(thisSupports));
|
||||
if (NS_FAILED(rv)) continue;
|
||||
nsCOMPtr<nsIMsgIdentity> thisIdentity(do_QueryInterface(thisSupports, &rv));
|
||||
if (NS_SUCCEEDED(rv) && thisIdentity)
|
||||
{
|
||||
nsXPIDLCString email;
|
||||
rv = thisIdentity->GetEmail(getter_Copies(email));
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
// get the username from the email and compare with the username
|
||||
nsCAutoString aEmail(email.get());
|
||||
PRInt32 index = aEmail.FindChar('@');
|
||||
if (index != -1)
|
||||
aEmail.Truncate(index);
|
||||
|
||||
if (nsDependentString(aUsername) == NS_ConvertASCIItoUCS2(aEmail)) // == overloaded
|
||||
return NS_SUCCEEDED(thisIdentity->GetKey(aIdKey));
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMapiHook::IsBlindSendAllowed()
|
||||
{
|
||||
PRBool enabled = PR_FALSE;
|
||||
PRBool warn = PR_TRUE;
|
||||
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
|
||||
if (prefs) {
|
||||
prefs->GetBoolPref(PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND,&warn);
|
||||
prefs->GetBoolPref(PREF_MAPI_BLIND_SEND_ENABLED,&enabled);
|
||||
}
|
||||
if (!enabled)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!warn)
|
||||
return PR_TRUE; // Everything is okay.
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || !bundleService) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(MAPI_PROPERTIES_CHROME, getter_AddRefs(bundle));
|
||||
if (NS_FAILED(rv) || !bundle) return PR_FALSE;
|
||||
|
||||
nsXPIDLString warningMsg;
|
||||
rv = bundle->GetStringFromName(NS_LITERAL_STRING("mapiBlindSendWarning").get(),
|
||||
getter_Copies(warningMsg));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
nsXPIDLString dontShowAgainMessage;
|
||||
rv = bundle->GetStringFromName(NS_LITERAL_STRING("mapiBlindSendDontShowAgain").get(),
|
||||
getter_Copies(dontShowAgainMessage));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPromptService> dlgService(do_GetService("@mozilla.org/embedcomp/prompt-service;1", &rv));
|
||||
if (NS_FAILED(rv) || !dlgService) return PR_FALSE;
|
||||
|
||||
PRBool continueToWarn = PR_TRUE;
|
||||
PRBool okayToContinue = PR_FALSE;
|
||||
dlgService->ConfirmCheck(nsnull, nsnull, warningMsg, dontShowAgainMessage, &continueToWarn, &okayToContinue);
|
||||
|
||||
if (!continueToWarn && okayToContinue && prefs)
|
||||
prefs->SetBoolPref(PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND,PR_FALSE);
|
||||
|
||||
return okayToContinue;
|
||||
|
||||
}
|
||||
|
||||
// this is used for Send without UI
|
||||
nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (!IsBlindSendAllowed())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
/** create nsIMsgComposeParams obj and other fields to populate it **/
|
||||
|
||||
// get parent window
|
||||
nsCOMPtr<nsIAppShellService> appService = do_GetService( "@mozilla.org/appshell/appShellService;1", &rv);
|
||||
if (NS_FAILED(rv)|| (!appService) ) return rv ;
|
||||
|
||||
nsCOMPtr<nsIDOMWindowInternal> hiddenWindow;
|
||||
rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow));
|
||||
|
||||
if ( NS_FAILED(rv) ) return rv ;
|
||||
|
||||
// smtp password and Logged in used IdKey from MapiConfig (session obj)
|
||||
nsMAPIConfiguration * pMapiConfig = nsMAPIConfiguration::GetMAPIConfiguration() ;
|
||||
if (!pMapiConfig) return NS_ERROR_FAILURE ; // get the singelton obj
|
||||
PRUnichar * password = pMapiConfig->GetPassword(aSession) ;
|
||||
// password
|
||||
nsCAutoString smtpPassword ;
|
||||
smtpPassword.AssignWithConversion (password) ;
|
||||
// Id key
|
||||
char * MsgIdKey = pMapiConfig->GetIdKey(aSession) ;
|
||||
|
||||
// get the MsgIdentity for the above key using AccountManager
|
||||
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService (NS_MSGACCOUNTMANAGER_CONTRACTID) ;
|
||||
if (NS_FAILED(rv) || (!accountManager) ) return rv ;
|
||||
|
||||
nsCOMPtr <nsIMsgIdentity> pMsgId ;
|
||||
rv = accountManager->GetIdentity (MsgIdKey, getter_AddRefs(pMsgId)) ;
|
||||
if (NS_FAILED(rv) ) return rv ;
|
||||
|
||||
// create a send listener to get back the send status
|
||||
nsCOMPtr <nsIMsgSendListener> sendListener ;
|
||||
rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
|
||||
if (NS_FAILED(rv) || (!sendListener) ) return rv;
|
||||
|
||||
// create the compose params object
|
||||
nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ;
|
||||
|
||||
// populate the compose params
|
||||
pMsgComposeParams->SetType(nsIMsgCompType::New);
|
||||
pMsgComposeParams->SetFormat(nsIMsgCompFormat::Default);
|
||||
pMsgComposeParams->SetIdentity(pMsgId);
|
||||
pMsgComposeParams->SetComposeFields(aCompFields);
|
||||
pMsgComposeParams->SetSendListener(sendListener) ;
|
||||
pMsgComposeParams->SetSmtpPassword(smtpPassword.get());
|
||||
|
||||
// create the nsIMsgCompose object to send the object
|
||||
nsCOMPtr<nsIMsgCompose> pMsgCompose (do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || (!pMsgCompose) ) return rv ;
|
||||
|
||||
/** initialize nsIMsgCompose, Send the message, wait for send completion response **/
|
||||
|
||||
rv = pMsgCompose->Initialize(hiddenWindow, pMsgComposeParams) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
pMsgCompose->SendMsg(nsIMsgSend::nsMsgDeliverNow, pMsgId, nsnull) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
// assign to interface pointer from nsCOMPtr to facilitate typecast below
|
||||
nsIMsgSendListener * pSendListener = sendListener ;
|
||||
|
||||
// we need to wait here to make sure that we return only after send is completed
|
||||
// so we will have a event loop here which will process the events till the Send IsDone.
|
||||
nsCOMPtr<nsIEventQueueService> pEventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
|
||||
nsCOMPtr<nsIEventQueue> eventQueue;
|
||||
pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD,getter_AddRefs(eventQueue));
|
||||
while ( !((nsMAPISendListener *) pSendListener)->IsDone() )
|
||||
eventQueue->ProcessPendingEvents();
|
||||
|
||||
return rv ;
|
||||
}
|
||||
|
||||
// this is used to populate comp fields with Unicode data
|
||||
nsresult nsMapiHook::PopulateCompFields(lpnsMapiMessage aMessage,
|
||||
nsIMsgCompFields * aCompFields)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (aMessage->lpOriginator)
|
||||
{
|
||||
PRUnichar * From = aMessage->lpOriginator->lpszAddress ;
|
||||
aCompFields->SetFrom (From) ;
|
||||
}
|
||||
|
||||
nsAutoString To ;
|
||||
nsAutoString Cc ;
|
||||
nsAutoString Bcc ;
|
||||
|
||||
nsAutoString Comma ;
|
||||
Comma.AssignWithConversion(",");
|
||||
|
||||
if (aMessage->lpRecips)
|
||||
{
|
||||
for (int i=0 ; i < (int) aMessage->nRecipCount ; i++)
|
||||
{
|
||||
if (aMessage->lpRecips[i].lpszAddress)
|
||||
{
|
||||
switch (aMessage->lpRecips[i].ulRecipClass)
|
||||
{
|
||||
case MAPI_TO :
|
||||
if (To.Length() > 0)
|
||||
To += Comma ;
|
||||
To += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ;
|
||||
break ;
|
||||
|
||||
case MAPI_CC :
|
||||
if (Cc.Length() > 0)
|
||||
Cc += Comma ;
|
||||
Cc += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ;
|
||||
break ;
|
||||
|
||||
case MAPI_BCC :
|
||||
if (Bcc.Length() > 0)
|
||||
Bcc += Comma ;
|
||||
Bcc += (PRUnichar *) aMessage->lpRecips[i].lpszAddress ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set To, Cc, Bcc
|
||||
aCompFields->SetTo (To.get()) ;
|
||||
aCompFields->SetCc (Cc.get()) ;
|
||||
aCompFields->SetBcc (Bcc.get()) ;
|
||||
|
||||
// set subject
|
||||
if (aMessage->lpszSubject)
|
||||
{
|
||||
PRUnichar * Subject = aMessage->lpszSubject ;
|
||||
aCompFields->SetSubject(Subject) ;
|
||||
}
|
||||
|
||||
// handle attachments as File URL
|
||||
rv = HandleAttachments (aCompFields, aMessage->nFileCount, aMessage->lpFiles, PR_TRUE) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
// set body
|
||||
if (aMessage->lpszNoteText)
|
||||
{
|
||||
PRUnichar * Body = aMessage->lpszNoteText ;
|
||||
rv = aCompFields->SetBody(Body) ;
|
||||
}
|
||||
|
||||
#ifdef RAJIV_DEBUG
|
||||
// testing what all was set in CompFields
|
||||
printf ("To : %S \n", To.get()) ;
|
||||
printf ("CC : %S \n", Cc.get() ) ;
|
||||
printf ("BCC : %S \n", Bcc.get() ) ;
|
||||
#endif
|
||||
|
||||
return rv ;
|
||||
|
||||
}
|
||||
|
||||
nsresult nsMapiHook::HandleAttachments (nsIMsgCompFields * aCompFields, PRInt32 aFileCount,
|
||||
lpnsMapiFileDesc aFiles, BOOL aIsUnicode)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
nsCAutoString Attachments ;
|
||||
nsCAutoString TempFiles ;
|
||||
|
||||
nsCOMPtr <nsILocalFile> pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv) || (!pFile) ) return rv ;
|
||||
|
||||
for (int i=0 ; i < aFileCount ; i++)
|
||||
{
|
||||
if (aFiles[i].lpszPathName)
|
||||
{
|
||||
// check if attachment exists
|
||||
if (aIsUnicode)
|
||||
pFile->InitWithUnicodePath (aFiles[i].lpszPathName) ;
|
||||
else
|
||||
pFile->InitWithPath ((char *) aFiles[i].lpszPathName) ;
|
||||
PRBool bExist ;
|
||||
rv = pFile->Exists(&bExist) ;
|
||||
if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ;
|
||||
|
||||
// create Msg attachment object
|
||||
nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || (!attachment) ) return rv ;
|
||||
|
||||
// set url
|
||||
nsXPIDLCString pURL ;
|
||||
NS_GetURLSpecFromFile(pFile, getter_Copies(pURL));
|
||||
attachment->SetUrl(pURL) ;
|
||||
|
||||
if (aFiles[i].lpszFileName)
|
||||
{
|
||||
if (! aIsUnicode)
|
||||
{
|
||||
nsAutoString realFileName ;
|
||||
realFileName.AssignWithConversion ((char *) aFiles[i].lpszFileName) ;
|
||||
attachment->SetName(realFileName.get()) ;
|
||||
// attachment->SetName( (nsDependentString(aFiles[i].lpszFileName)).get() );
|
||||
}
|
||||
else
|
||||
attachment->SetName(aFiles[i].lpszFileName) ;
|
||||
}
|
||||
|
||||
attachment->SetTemporary(PR_FALSE) ;
|
||||
|
||||
rv = aCompFields->AddAttachment (attachment);
|
||||
}
|
||||
}
|
||||
return rv ;
|
||||
}
|
||||
|
||||
|
||||
// this is used to convert non Unicode data and then populate comp fields
|
||||
nsresult nsMapiHook::PopulateCompFieldsWithConversion(lpnsMapiMessage aMessage,
|
||||
nsIMsgCompFields * aCompFields)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (aMessage->lpOriginator)
|
||||
{
|
||||
nsAutoString From ;
|
||||
From.AssignWithConversion((char *) aMessage->lpOriginator->lpszAddress);
|
||||
aCompFields->SetFrom (From.get()) ;
|
||||
}
|
||||
|
||||
nsAutoString To ;
|
||||
nsAutoString Cc ;
|
||||
nsAutoString Bcc ;
|
||||
|
||||
nsAutoString Comma ;
|
||||
Comma.AssignWithConversion(",");
|
||||
|
||||
if (aMessage->lpRecips)
|
||||
{
|
||||
for (int i=0 ; i < (int) aMessage->nRecipCount ; i++)
|
||||
{
|
||||
if (aMessage->lpRecips[i].lpszAddress)
|
||||
{
|
||||
switch (aMessage->lpRecips[i].ulRecipClass)
|
||||
{
|
||||
case MAPI_TO :
|
||||
if (To.Length() > 0)
|
||||
To += Comma ;
|
||||
To.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress);
|
||||
break ;
|
||||
|
||||
case MAPI_CC :
|
||||
if (Cc.Length() > 0)
|
||||
Cc += Comma ;
|
||||
Cc.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress);
|
||||
break ;
|
||||
|
||||
case MAPI_BCC :
|
||||
if (Bcc.Length() > 0)
|
||||
Bcc += Comma ;
|
||||
Bcc.AppendWithConversion ((char *) aMessage->lpRecips[i].lpszAddress) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set To, Cc, Bcc
|
||||
aCompFields->SetTo (To.get()) ;
|
||||
aCompFields->SetCc (Cc.get()) ;
|
||||
aCompFields->SetBcc (Bcc.get()) ;
|
||||
|
||||
nsCAutoString platformCharSet;
|
||||
// set subject
|
||||
if (aMessage->lpszSubject)
|
||||
{
|
||||
nsAutoString Subject ;
|
||||
if (platformCharSet.IsEmpty())
|
||||
platformCharSet.Assign(nsMsgI18NFileSystemCharset());
|
||||
rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszSubject, Subject);
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
aCompFields->SetSubject(Subject.get()) ;
|
||||
}
|
||||
|
||||
// handle attachments as File URL
|
||||
rv = HandleAttachments (aCompFields, aMessage->nFileCount, aMessage->lpFiles, PR_FALSE) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
// set body
|
||||
if (aMessage->lpszNoteText)
|
||||
{
|
||||
nsAutoString Body ;
|
||||
if (platformCharSet.IsEmpty())
|
||||
platformCharSet.Assign(nsMsgI18NFileSystemCharset());
|
||||
rv = ConvertToUnicode(platformCharSet.get(), (char *) aMessage->lpszNoteText, Body);
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
rv = aCompFields->SetBody(Body.get()) ;
|
||||
}
|
||||
|
||||
#ifdef RAJIV_DEBUG
|
||||
// testing what all was set in CompFields
|
||||
printf ("To : %S \n", To.get()) ;
|
||||
printf ("CC : %S \n", Cc.get() ) ;
|
||||
printf ("BCC : %S \n", Bcc.get() ) ;
|
||||
#endif
|
||||
|
||||
return rv ;
|
||||
}
|
||||
|
||||
// this is used to populate the docs as attachments in the Comp fields for Send Documents
|
||||
nsresult nsMapiHook::PopulateCompFieldsForSendDocs(nsIMsgCompFields * aCompFields, ULONG aFlags,
|
||||
PRUnichar * aDelimChar, PRUnichar * aFilePaths)
|
||||
{
|
||||
nsAutoString strDelimChars ;
|
||||
nsString strFilePaths;
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (aFlags & MAPI_UNICODE)
|
||||
{
|
||||
if (aDelimChar)
|
||||
strDelimChars.Assign (aDelimChar) ;
|
||||
if (aFilePaths)
|
||||
strFilePaths.Assign (aFilePaths) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aDelimChar)
|
||||
strDelimChars.AssignWithConversion ((char*) aDelimChar) ;
|
||||
if (aFilePaths)
|
||||
strFilePaths.AssignWithConversion ((char *) aFilePaths) ;
|
||||
}
|
||||
|
||||
// check for comma in filename
|
||||
if (strDelimChars.Find (",") == kNotFound) // if comma is not in the delimiter specified by user
|
||||
{
|
||||
if (strFilePaths.Find(",") != kNotFound) // if comma found in filenames return error
|
||||
return NS_ERROR_FILE_INVALID_PATH ;
|
||||
}
|
||||
|
||||
nsCString Attachments ;
|
||||
|
||||
// only 1 file is to be sent, no delim specified
|
||||
if ((!strDelimChars.Length()) && (strFilePaths.Length()>0))
|
||||
{
|
||||
nsCOMPtr <nsILocalFile> pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv) || (!pFile) ) return rv ;
|
||||
pFile->InitWithUnicodePath (strFilePaths.get()) ;
|
||||
|
||||
PRBool bExist ;
|
||||
rv = pFile->Exists(&bExist) ;
|
||||
if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ;
|
||||
|
||||
nsXPIDLCString pURL ;
|
||||
NS_GetURLSpecFromFile(pFile, getter_Copies(pURL));
|
||||
if (pURL)
|
||||
Attachments.Assign(pURL) ;
|
||||
|
||||
// set attachments for comp field and return
|
||||
rv = aCompFields->SetAttachments (Attachments.get());
|
||||
return rv ;
|
||||
}
|
||||
|
||||
// multiple files to be sent, delim specified
|
||||
nsCOMPtr <nsILocalFile> pFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv) || (!pFile) ) return rv ;
|
||||
PRInt32 offset = 0 ;
|
||||
PRInt32 FilePathsLen = strFilePaths.Length() ;
|
||||
if (FilePathsLen)
|
||||
{
|
||||
PRUnichar * newFilePaths = (PRUnichar *) strFilePaths.get() ;
|
||||
while (offset != kNotFound)
|
||||
{
|
||||
nsString RemainingPaths ;
|
||||
RemainingPaths.Assign(newFilePaths) ;
|
||||
offset = RemainingPaths.Find (strDelimChars) ;
|
||||
if (offset != kNotFound)
|
||||
{
|
||||
RemainingPaths.SetLength (offset) ;
|
||||
if ((offset + strDelimChars.Length()) < FilePathsLen)
|
||||
newFilePaths += offset + strDelimChars.Length() ;
|
||||
}
|
||||
|
||||
pFile->InitWithUnicodePath (RemainingPaths.get()) ;
|
||||
|
||||
#ifdef RAJIV_DEBUG
|
||||
printf ("File : %S \n", RemainingPaths.get()) ;
|
||||
#endif
|
||||
PRBool bExist ;
|
||||
rv = pFile->Exists(&bExist) ;
|
||||
if (NS_FAILED(rv) || (!bExist) ) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST ;
|
||||
|
||||
nsXPIDLCString pURL ;
|
||||
NS_GetURLSpecFromFile(pFile, getter_Copies(pURL));
|
||||
if (pURL)
|
||||
{
|
||||
if (Attachments.Length() > 0)
|
||||
Attachments.Append(",") ;
|
||||
Attachments.Append(pURL) ;
|
||||
}
|
||||
}
|
||||
rv = aCompFields->SetAttachments (Attachments.get());
|
||||
}
|
||||
|
||||
return rv ;
|
||||
}
|
||||
|
||||
// this used for Send with UI
|
||||
nsresult nsMapiHook::ShowComposerWindow (unsigned long aSession, nsIMsgCompFields * aCompFields)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
// create a send listener to get back the send status
|
||||
nsCOMPtr <nsIMsgSendListener> sendListener ;
|
||||
rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
|
||||
if (NS_FAILED(rv) || (!sendListener) ) return rv ;
|
||||
|
||||
// create the compose params object
|
||||
nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ;
|
||||
|
||||
// populate the compose params
|
||||
pMsgComposeParams->SetType(nsIMsgCompType::New);
|
||||
pMsgComposeParams->SetFormat(nsIMsgCompFormat::Default);
|
||||
pMsgComposeParams->SetComposeFields(aCompFields);
|
||||
pMsgComposeParams->SetSendListener(sendListener) ;
|
||||
|
||||
/** get the nsIMsgComposeService object to open the compose window **/
|
||||
nsCOMPtr <nsIMsgComposeService> compService = do_GetService (NS_MSGCOMPOSESERVICE_CONTRACTID) ;
|
||||
if (NS_FAILED(rv)|| (!compService) ) return rv ;
|
||||
|
||||
rv = compService->OpenComposeWindowWithParams(nsnull, pMsgComposeParams) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
return rv ;
|
||||
}
|
||||
66
mozilla/mailnews/mapi/mapihook/src/msgMapiHook.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MSG_MAPI_HOOK_H_
|
||||
#define MSG_MAPI_HOOK_H_
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
class nsMapiHook
|
||||
{
|
||||
public :
|
||||
|
||||
static PRBool Initialize();
|
||||
static PRBool DisplayLoginDialog(PRBool aLogin, PRUnichar **aUsername,
|
||||
PRUnichar **aPassword);
|
||||
static PRBool VerifyUserName(const PRUnichar *aUsername, char **aIdKey);
|
||||
|
||||
static PRBool IsBlindSendAllowed () ;
|
||||
static nsresult BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields) ;
|
||||
static nsresult ShowComposerWindow (unsigned long aSession, nsIMsgCompFields * aCompFields) ;
|
||||
static nsresult PopulateCompFields(lpnsMapiMessage aMessage, nsIMsgCompFields * aCompFields) ;
|
||||
static nsresult PopulateCompFieldsWithConversion(lpnsMapiMessage aMessage,
|
||||
nsIMsgCompFields * aCompFields) ;
|
||||
static nsresult PopulateCompFieldsForSendDocs(nsIMsgCompFields * aCompFields,
|
||||
ULONG aFlags, LPTSTR aDelimChar, LPTSTR aFilePaths) ;
|
||||
static nsresult HandleAttachments (nsIMsgCompFields * aCompFields, PRInt32 aFileCount,
|
||||
lpnsMapiFileDesc aFiles, BOOL aIsUnicode) ;
|
||||
static void CleanUp();
|
||||
|
||||
static PRBool isMapiService;
|
||||
};
|
||||
|
||||
#endif // MSG_MAPI_HOOK_H_
|
||||
266
mozilla/mailnews/mapi/mapihook/src/msgMapiImp.cpp
Normal file
@@ -0,0 +1,266 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
* Contributor(s): Rajiv Dayal (rdayal@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <mapidefs.h>
|
||||
#include <mapi.h>
|
||||
#include "msgMapi.h"
|
||||
#include "msgMapiImp.h"
|
||||
#include "msgMapiFactory.h"
|
||||
#include "msgMapiMain.h"
|
||||
|
||||
#include "nsMsgCompFields.h"
|
||||
#include "msgMapiHook.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsMsgCompCID.h"
|
||||
|
||||
|
||||
|
||||
CMapiImp::CMapiImp()
|
||||
: m_cRef(1)
|
||||
{
|
||||
m_Lock = PR_NewLock();
|
||||
}
|
||||
|
||||
CMapiImp::~CMapiImp()
|
||||
{
|
||||
if (m_Lock)
|
||||
PR_DestroyLock(m_Lock);
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::QueryInterface(const IID& aIid, void** aPpv)
|
||||
{
|
||||
if (aIid == IID_IUnknown)
|
||||
{
|
||||
*aPpv = static_cast<nsIMapi*>(this);
|
||||
}
|
||||
else if (aIid == IID_nsIMapi)
|
||||
{
|
||||
*aPpv = static_cast<nsIMapi*>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
*aPpv = nsnull;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
reinterpret_cast<IUnknown*>(*aPpv)->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CMapiImp::AddRef()
|
||||
{
|
||||
return PR_AtomicIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CMapiImp::Release()
|
||||
{
|
||||
PRInt32 temp;
|
||||
temp = PR_AtomicDecrement(&m_cRef);
|
||||
if (m_cRef == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::IsValid()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::IsValidSession(unsigned long aSession)
|
||||
{
|
||||
nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration();
|
||||
if (pConfig && pConfig->IsSessionValid(aSession))
|
||||
return S_OK;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::Initialize()
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
if (!m_Lock)
|
||||
return E_FAIL;
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
// Initialize MAPI Configuration
|
||||
|
||||
nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration();
|
||||
if (pConfig != nsnull)
|
||||
if (nsMapiHook::Initialize())
|
||||
hr = S_OK;
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin, LOGIN_PW_TYPE aPassWord,
|
||||
unsigned long aFlags, unsigned long *aSessionId)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
PRBool bNewSession = PR_FALSE;
|
||||
char *id_key = nsnull;
|
||||
|
||||
if (aFlags & MAPI_NEW_SESSION)
|
||||
bNewSession = PR_TRUE;
|
||||
|
||||
// Check For Profile Name
|
||||
|
||||
if (aLogin != nsnull && aLogin[0] != '\0')
|
||||
{
|
||||
if (nsMapiHook::VerifyUserName(aLogin, &id_key) == PR_FALSE)
|
||||
{
|
||||
*aSessionId = MAPI_E_LOGIN_FAILURE;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
|
||||
// finally register(create) the session.
|
||||
|
||||
PRUint32 nSession_Id;
|
||||
PRInt16 nResult = 0;
|
||||
|
||||
nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration();
|
||||
if (pConfig != nsnull)
|
||||
nResult = pConfig->RegisterSession(aUIArg, aLogin, aPassWord,
|
||||
(aFlags & MAPI_FORCE_DOWNLOAD), bNewSession,
|
||||
&nSession_Id, id_key);
|
||||
|
||||
switch (nResult)
|
||||
{
|
||||
case -1 :
|
||||
{
|
||||
*aSessionId = MAPI_E_TOO_MANY_SESSIONS;
|
||||
return hr;
|
||||
}
|
||||
case 0 :
|
||||
{
|
||||
*aSessionId = MAPI_E_INSUFFICIENT_MEMORY;
|
||||
return hr;
|
||||
}
|
||||
default :
|
||||
{
|
||||
*aSessionId = nSession_Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::SendMail( unsigned long aSession, lpnsMapiMessage aMessage,
|
||||
short aRecipCount, lpnsMapiRecipDesc aRecips , short aFileCount, lpnsMapiFileDesc aFiles ,
|
||||
unsigned long aFlags, unsigned long aReserved)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
// Assign the pointers in the aMessage struct to the array of Recips and Files
|
||||
// recieved here from MS COM. These are used in BlindSendMail and ShowCompWin fns
|
||||
aMessage->lpRecips = aRecips ;
|
||||
aMessage->lpFiles = aFiles ;
|
||||
|
||||
/** create nsIMsgCompFields obj and populate it **/
|
||||
nsCOMPtr<nsIMsgCompFields> pCompFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv) || (!pCompFields) ) return MAPI_E_INSUFFICIENT_MEMORY ;
|
||||
|
||||
if (aFlags & MAPI_UNICODE)
|
||||
rv = nsMapiHook::PopulateCompFields(aMessage, pCompFields) ;
|
||||
else
|
||||
rv = nsMapiHook::PopulateCompFieldsWithConversion(aMessage, pCompFields) ;
|
||||
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
// see flag to see if UI needs to be brought up
|
||||
if (!(aFlags & MAPI_DIALOG))
|
||||
{
|
||||
rv = nsMapiHook::BlindSendMail(aSession, pCompFields);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = nsMapiHook::ShowComposerWindow(aSession, pCompFields);
|
||||
}
|
||||
}
|
||||
|
||||
return nsMAPIConfiguration::GetMAPIErrorFromNSError (rv) ;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CMapiImp::SendDocuments( unsigned long aSession, LPTSTR aDelimChar,
|
||||
LPTSTR aFilePaths, LPTSTR aFileNames, ULONG aFlags)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
/** create nsIMsgCompFields obj and populate it **/
|
||||
nsCOMPtr<nsIMsgCompFields> pCompFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv) || (!pCompFields) ) return MAPI_E_INSUFFICIENT_MEMORY ;
|
||||
|
||||
if (aFilePaths)
|
||||
{
|
||||
rv = nsMapiHook::PopulateCompFieldsForSendDocs(pCompFields, aFlags, aDelimChar, aFilePaths) ;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED (rv))
|
||||
rv = nsMapiHook::ShowComposerWindow(aSession, pCompFields);
|
||||
|
||||
return nsMAPIConfiguration::GetMAPIErrorFromNSError (rv) ;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::Logoff (unsigned long aSession)
|
||||
{
|
||||
nsMAPIConfiguration *pConfig = nsMAPIConfiguration::GetMAPIConfiguration();
|
||||
|
||||
if (pConfig->UnRegisterSession((PRUint32)aSession))
|
||||
return S_OK;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMapiImp::CleanUp()
|
||||
{
|
||||
nsMapiHook::CleanUp();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
92
mozilla/mailnews/mapi/mapihook/src/msgMapiImp.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MSG_MAPI_IMP_H
|
||||
#define MSG_MAPI_IMP_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <mapi.h>
|
||||
#include "msgMapi.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nspr.h"
|
||||
|
||||
const CLSID CLSID_CMapiImp = {0x29f458be, 0x8866, 0x11d5, {0xa3, 0xdd, 0x0, 0xb0, 0xd0, 0xf3, 0xba, 0xa7}};
|
||||
|
||||
// this class implements the MS COM interface nsIMapi that provides the methods
|
||||
// called by mapi32.dll to perform the mail operations as specified by MAPI.
|
||||
// These class methods in turn use the Mozilla Mail XPCOM interfaces to do so.
|
||||
class CMapiImp : public nsIMapi
|
||||
{
|
||||
|
||||
public :
|
||||
|
||||
// IUnknown
|
||||
|
||||
STDMETHODIMP QueryInterface(const IID& aIid, void** aPpv);
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
// Interface INsMapi
|
||||
|
||||
STDMETHODIMP Login(unsigned long aUIArg, LOGIN_PW_TYPE aLogin,
|
||||
LOGIN_PW_TYPE aPassWord, unsigned long aFlags,
|
||||
unsigned long *aSessionId);
|
||||
|
||||
STDMETHODIMP SendMail( unsigned long aSession, lpnsMapiMessage aMessage,
|
||||
short aRecipCount, lpnsMapiRecipDesc aRecips ,
|
||||
short aFileCount, lpnsMapiFileDesc aFiles ,
|
||||
unsigned long aFlags, unsigned long aReserved) ;
|
||||
|
||||
STDMETHODIMP SendDocuments( unsigned long aSession, LPTSTR aDelimChar,
|
||||
LPTSTR aFilePaths, LPTSTR aFileNames, ULONG aFlags);
|
||||
|
||||
STDMETHODIMP Initialize();
|
||||
STDMETHODIMP IsValid();
|
||||
STDMETHODIMP IsValidSession(unsigned long aSession);
|
||||
|
||||
STDMETHODIMP Logoff (unsigned long aSession);
|
||||
STDMETHODIMP CleanUp();
|
||||
|
||||
CMapiImp();
|
||||
~CMapiImp();
|
||||
|
||||
private :
|
||||
|
||||
PRLock *m_Lock;
|
||||
PRInt32 m_cRef;
|
||||
};
|
||||
|
||||
#endif // MSG_MAPI_IMP_H
|
||||
376
mozilla/mailnews/mapi/mapihook/src/msgMapiMain.cpp
Normal file
@@ -0,0 +1,376 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <mapidefs.h>
|
||||
#include <mapi.h>
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsMsgComposeStringBundle.h"
|
||||
#include "msgMapiMain.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
// move to xpcom bug 81956.
|
||||
class nsPRUintKey : public nsHashKey {
|
||||
protected:
|
||||
PRUint32 mKey;
|
||||
public:
|
||||
nsPRUintKey(PRUint32 key) : mKey(key) {}
|
||||
|
||||
PRUint32 HashCode(void) const {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
PRBool Equals(const nsHashKey *aKey) const {
|
||||
return mKey == ((const nsPRUintKey *) aKey)->mKey;
|
||||
}
|
||||
nsHashKey *Clone() const {
|
||||
return new nsPRUintKey(mKey);
|
||||
}
|
||||
PRUint32 GetValue() { return mKey; }
|
||||
};
|
||||
//
|
||||
|
||||
|
||||
nsMAPIConfiguration *nsMAPIConfiguration::m_pSelfRef = nsnull;
|
||||
PRUint32 nsMAPIConfiguration::session_generator = 0;
|
||||
PRUint32 nsMAPIConfiguration::sessionCount = 0;
|
||||
|
||||
nsMAPIConfiguration *nsMAPIConfiguration::GetMAPIConfiguration()
|
||||
{
|
||||
if (m_pSelfRef == nsnull)
|
||||
m_pSelfRef = new nsMAPIConfiguration();
|
||||
|
||||
return m_pSelfRef;
|
||||
}
|
||||
|
||||
nsMAPIConfiguration::nsMAPIConfiguration()
|
||||
: m_nMaxSessions(MAX_SESSIONS)
|
||||
{
|
||||
m_Lock = PR_NewLock();
|
||||
}
|
||||
|
||||
static PRBool
|
||||
FreeSessionMapEntries(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
nsMAPISession *pTemp = (nsMAPISession*) aData;
|
||||
if (pTemp)
|
||||
{
|
||||
delete pTemp;
|
||||
pTemp = nsnull;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
FreeProfileMapEntries(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsMAPIConfiguration::~nsMAPIConfiguration()
|
||||
{
|
||||
if (m_Lock)
|
||||
PR_DestroyLock(m_Lock);
|
||||
|
||||
m_SessionMap.Reset(FreeSessionMapEntries);
|
||||
m_ProfileMap.Reset(FreeProfileMapEntries);
|
||||
}
|
||||
|
||||
void nsMAPIConfiguration::OpenConfiguration()
|
||||
{
|
||||
// No. of max. sessions is set to MAX_SESSIONS. In future
|
||||
// if it is decided to have configuration (registry)
|
||||
// parameter, this function can be used to set the
|
||||
// max sessions;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PRInt16 nsMAPIConfiguration::RegisterSession(PRUint32 aHwnd,
|
||||
const PRUnichar *aUserName, const PRUnichar *aPassword,
|
||||
PRBool aForceDownLoad, PRBool aNewSession,
|
||||
PRUint32 *aSession, char *aIdKey)
|
||||
{
|
||||
PRInt16 nResult = 0;
|
||||
PRUint32 n_SessionId = 0;
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
// Check whether max sessions is exceeded
|
||||
|
||||
if (sessionCount >= m_nMaxSessions)
|
||||
{
|
||||
PR_Unlock(m_Lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aUserName != nsnull && aUserName[0] != '\0')
|
||||
{
|
||||
nsStringKey usernameKey(aUserName);
|
||||
n_SessionId = (PRUint32) m_ProfileMap.Get(&usernameKey);
|
||||
}
|
||||
|
||||
// try to share a session; if not create a session
|
||||
|
||||
if (n_SessionId > 0)
|
||||
{
|
||||
nsPRUintKey sessionKey(n_SessionId);
|
||||
nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey);
|
||||
if (pTemp != nsnull)
|
||||
{
|
||||
pTemp->IncrementSession();
|
||||
*aSession = n_SessionId;
|
||||
nResult = 1;
|
||||
}
|
||||
}
|
||||
else if (aNewSession || n_SessionId == 0) // checking for n_SessionId is a concession
|
||||
{
|
||||
// create a new session ; if new session is specified OR there is no session
|
||||
nsMAPISession *pTemp = nsnull;
|
||||
pTemp = new nsMAPISession(aHwnd, aUserName,
|
||||
aPassword, aForceDownLoad, aIdKey);
|
||||
|
||||
if (pTemp != nsnull)
|
||||
{
|
||||
session_generator++;
|
||||
|
||||
// I don't think there will be (2 power 32) sessions alive
|
||||
// in a cycle. This is an assumption
|
||||
|
||||
if (session_generator == 0)
|
||||
session_generator++;
|
||||
|
||||
nsPRUintKey sessionKey(session_generator);
|
||||
m_SessionMap.Put(&sessionKey, pTemp);
|
||||
if (aUserName != nsnull && aUserName[0] != '\0')
|
||||
{
|
||||
nsStringKey usernameKey(aUserName);
|
||||
m_ProfileMap.Put(&usernameKey, (void*)session_generator);
|
||||
}
|
||||
|
||||
*aSession = session_generator;
|
||||
sessionCount++;
|
||||
nResult = 1;
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
return nResult;
|
||||
}
|
||||
|
||||
PRBool nsMAPIConfiguration::UnRegisterSession(PRUint32 aSessionID)
|
||||
{
|
||||
PRBool bResult = PR_FALSE;
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
if (aSessionID != 0)
|
||||
{
|
||||
nsPRUintKey sessionKey(aSessionID);
|
||||
nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey);
|
||||
|
||||
if (pTemp != nsnull)
|
||||
{
|
||||
if (pTemp->DecrementSession() == 0)
|
||||
{
|
||||
if (pTemp->m_pProfileName.get() != nsnull)
|
||||
{
|
||||
nsStringKey stringKey(pTemp->m_pProfileName.get());
|
||||
m_ProfileMap.Remove(&stringKey);
|
||||
}
|
||||
m_SessionMap.Remove(&sessionKey);
|
||||
sessionCount--;
|
||||
bResult = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
return bResult;
|
||||
}
|
||||
|
||||
PRBool nsMAPIConfiguration::IsSessionValid(PRUint32 aSessionID)
|
||||
{
|
||||
if (aSessionID == 0)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool retValue = PR_FALSE;
|
||||
nsPRUintKey sessionKey(aSessionID);
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
retValue = m_SessionMap.Exists(&sessionKey);
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar *nsMAPIConfiguration::GetPassword(PRUint32 aSessionID)
|
||||
{
|
||||
PRUnichar *pResult = nsnull;
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
if (aSessionID != 0)
|
||||
{
|
||||
nsPRUintKey sessionKey(aSessionID);
|
||||
nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey);
|
||||
|
||||
if (pTemp)
|
||||
{
|
||||
pResult = pTemp->GetPassword();
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
|
||||
return pResult;
|
||||
}
|
||||
|
||||
char *nsMAPIConfiguration::GetIdKey(PRUint32 aSessionID)
|
||||
{
|
||||
char *pResult = nsnull;
|
||||
|
||||
PR_Lock(m_Lock);
|
||||
|
||||
if (aSessionID != 0)
|
||||
{
|
||||
nsPRUintKey sessionKey(aSessionID);
|
||||
nsMAPISession *pTemp = (nsMAPISession *)m_SessionMap.Get(&sessionKey);
|
||||
if (pTemp)
|
||||
{
|
||||
pResult = pTemp->GetIdKey();
|
||||
}
|
||||
}
|
||||
|
||||
PR_Unlock(m_Lock);
|
||||
return pResult;
|
||||
}
|
||||
|
||||
// util func
|
||||
HRESULT nsMAPIConfiguration::GetMAPIErrorFromNSError (nsresult res)
|
||||
{
|
||||
HRESULT hr = SUCCESS_SUCCESS ;
|
||||
|
||||
if (NS_SUCCEEDED (hr)) return hr ;
|
||||
|
||||
// if failure return the related MAPI failure code
|
||||
switch (res)
|
||||
{
|
||||
case NS_MSG_NO_RECIPIENTS :
|
||||
hr = MAPI_E_BAD_RECIPTYPE ;
|
||||
break ;
|
||||
case NS_ERROR_COULD_NOT_GET_USERS_MAIL_ADDRESS :
|
||||
hr = MAPI_E_INVALID_RECIPS ;
|
||||
break ;
|
||||
case NS_ERROR_COULD_NOT_LOGIN_TO_SMTP_SERVER :
|
||||
hr = MAPI_E_LOGIN_FAILURE ;
|
||||
break ;
|
||||
case NS_MSG_UNABLE_TO_OPEN_FILE :
|
||||
case NS_MSG_UNABLE_TO_OPEN_TMP_FILE :
|
||||
case NS_MSG_COULDNT_OPEN_FCC_FOLDER :
|
||||
case NS_ERROR_FILE_INVALID_PATH :
|
||||
hr = MAPI_E_ATTACHMENT_OPEN_FAILURE ;
|
||||
break ;
|
||||
case NS_ERROR_FILE_TARGET_DOES_NOT_EXIST :
|
||||
hr = MAPI_E_ATTACHMENT_NOT_FOUND ;
|
||||
break ;
|
||||
case NS_MSG_CANCELLING :
|
||||
hr = MAPI_E_USER_ABORT ;
|
||||
break ;
|
||||
case NS_MSG_ERROR_WRITING_FILE :
|
||||
case NS_MSG_UNABLE_TO_SAVE_TEMPLATE :
|
||||
case NS_MSG_UNABLE_TO_SAVE_DRAFT :
|
||||
hr = MAPI_E_ATTACHMENT_WRITE_FAILURE ;
|
||||
break ;
|
||||
default :
|
||||
hr = MAPI_E_FAILURE ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return hr ;
|
||||
}
|
||||
|
||||
|
||||
nsMAPISession::nsMAPISession(PRUint32 aHwnd, const PRUnichar *aUserName,\
|
||||
const PRUnichar *aPassword, \
|
||||
PRBool aForceDownLoad, char *aKey)
|
||||
: m_bIsForcedDownLoad(aForceDownLoad),
|
||||
m_hAppHandle(aHwnd),
|
||||
m_nShared(1),
|
||||
m_pIdKey(aKey)
|
||||
{
|
||||
m_pProfileName.Assign(aUserName);
|
||||
m_pPassword.Assign(aPassword);
|
||||
}
|
||||
|
||||
nsMAPISession::~nsMAPISession()
|
||||
{
|
||||
if (m_pIdKey != nsnull)
|
||||
{
|
||||
delete [] m_pIdKey;
|
||||
m_pIdKey = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 nsMAPISession::IncrementSession()
|
||||
{
|
||||
return ++m_nShared;
|
||||
}
|
||||
|
||||
PRUint32 nsMAPISession::DecrementSession()
|
||||
{
|
||||
return --m_nShared;
|
||||
}
|
||||
|
||||
PRUint32 nsMAPISession::GetSessionCount()
|
||||
{
|
||||
return m_nShared;
|
||||
}
|
||||
|
||||
PRUnichar *nsMAPISession::GetPassword()
|
||||
{
|
||||
return (PRUnichar *)m_pPassword.get();
|
||||
}
|
||||
|
||||
char *nsMAPISession::GetIdKey()
|
||||
{
|
||||
return m_pIdKey;
|
||||
}
|
||||
|
||||
112
mozilla/mailnews/mapi/mapihook/src/msgMapiMain.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MSG_MAPI_MAIN_H_
|
||||
#define NSG_MAPI_MAIN_H_
|
||||
|
||||
#define MAX_NAME_LEN 256
|
||||
#define MAX_PW_LEN 256
|
||||
#define MAX_SESSIONS 50
|
||||
#define MAPI_SENDCOMPLETE_EVENT "SendCompletionEvent"
|
||||
|
||||
#define MAPI_PROPERTIES_CHROME "chrome://messenger-mapi/locale/mapi.properties"
|
||||
#define PREF_MAPI_WARN_PRIOR_TO_BLIND_SEND "mapi.blind-send.warn"
|
||||
#define PREF_MAPI_BLIND_SEND_ENABLED "mapi.blind-send.enabled"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nspr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsHashtable.h"
|
||||
|
||||
class nsMAPIConfiguration
|
||||
{
|
||||
private :
|
||||
|
||||
static PRUint32 session_generator;
|
||||
static PRUint32 sessionCount;
|
||||
static nsMAPIConfiguration *m_pSelfRef;
|
||||
PRLock *m_Lock;
|
||||
PRUint32 m_nMaxSessions;
|
||||
|
||||
|
||||
nsHashtable m_ProfileMap;
|
||||
nsHashtable m_SessionMap;
|
||||
nsMAPIConfiguration();
|
||||
|
||||
public :
|
||||
static nsMAPIConfiguration *GetMAPIConfiguration();
|
||||
void OpenConfiguration();
|
||||
PRInt16 RegisterSession(PRUint32 aHwnd, const PRUnichar *aUserName, \
|
||||
const PRUnichar *aPassword, PRBool aForceDownLoad, \
|
||||
PRBool aNewSession, PRUint32 *aSession, char *aIdKey);
|
||||
PRBool IsSessionValid(PRUint32 aSessionID);
|
||||
PRBool UnRegisterSession(PRUint32 aSessionID);
|
||||
PRUnichar *GetPassword(PRUint32 aSessionID);
|
||||
char *GetIdKey(PRUint32 aSessionID);
|
||||
~nsMAPIConfiguration();
|
||||
|
||||
// a util func
|
||||
static HRESULT GetMAPIErrorFromNSError (nsresult res) ;
|
||||
};
|
||||
|
||||
class nsMAPISession
|
||||
{
|
||||
friend class nsMAPIConfiguration;
|
||||
|
||||
private :
|
||||
|
||||
PRBool m_bIsForcedDownLoad;
|
||||
PRBool m_bApp_or_Service;
|
||||
PRUint32 m_hAppHandle;
|
||||
PRUint32 m_nShared;
|
||||
char *m_pIdKey;
|
||||
nsString m_pProfileName;
|
||||
nsString m_pPassword;
|
||||
|
||||
public :
|
||||
|
||||
nsMAPISession(PRUint32 aHwnd, const PRUnichar *aUserName, \
|
||||
const PRUnichar *aPassword, \
|
||||
PRBool aForceDownLoad, char *aKey);
|
||||
PRUint32 IncrementSession();
|
||||
PRUint32 DecrementSession();
|
||||
PRUint32 GetSessionCount();
|
||||
PRUnichar *nsMAPISession::GetPassword();
|
||||
char *nsMAPISession::GetIdKey();
|
||||
~nsMAPISession();
|
||||
};
|
||||
|
||||
#endif // MSG_MAPI_MAIN_H_
|
||||
209
mozilla/mailnews/mapi/mapihook/src/msgMapiSupport.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsCOMPtr.h"
|
||||
#include "objbase.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIAppStartupNotifier.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranchInternal.h"
|
||||
|
||||
#include "msgMapiSupport.h"
|
||||
#include "nsMapiRegistryUtils.h"
|
||||
#include "nsMapiRegistry.h"
|
||||
#include "msgMapiImp.h"
|
||||
|
||||
/** Implementation of the nsIMapiSupport interface.
|
||||
* Use standard implementation of nsISupports stuff.
|
||||
*/
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMapiSupport, nsIMapiSupport, nsIObserver);
|
||||
|
||||
static NS_METHOD nsMapiRegistrationProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath, const char *registryLocation, const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsICategoryManager> categoryManager(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY, "Mapi Support",
|
||||
"service," NS_IMAPISUPPORT_CONTRACTID, PR_TRUE, PR_TRUE, nsnull);
|
||||
|
||||
return rv ;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiSupport::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, "profile-after-change"))
|
||||
return InitializeMAPISupport();
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
|
||||
return ShutdownMAPISupport();
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID))
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefs = do_QueryInterface(aSubject, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// which preference changed?
|
||||
if (!nsCRT::strcmp(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, NS_ConvertUCS2toUTF8(aData).get()))
|
||||
{
|
||||
PRBool bIsDefault = PR_FALSE ;
|
||||
rv = prefs->GetBoolPref(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, &bIsDefault);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr <nsIMapiRegistry> mapiRegistry = do_CreateInstance(NS_IMAPIREGISTRY_CONTRACTID, &rv) ;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mapiRegistry->SetIsDefaultMailClient(bIsDefault) ;
|
||||
}
|
||||
return rv ;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService(do_GetService("@mozilla.org/observer-service;1", &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = observerService->AddObserver(this,"profile-after-change", PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(prefs, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = prefInternal->AddObserver(MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT, this, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsMapiSupport::nsMapiSupport()
|
||||
: m_dwRegister(0),
|
||||
m_nsMapiFactory(nsnull)
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsMapiSupport::~nsMapiSupport()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiSupport::InitializeMAPISupport()
|
||||
{
|
||||
::CoInitialize(nsnull) ;
|
||||
|
||||
if (m_nsMapiFactory == nsnull) // No Registering if already done. Sanity Check!!
|
||||
{
|
||||
m_nsMapiFactory = new CMapiFactory();
|
||||
|
||||
if (m_nsMapiFactory != nsnull)
|
||||
{
|
||||
HRESULT hr = ::CoRegisterClassObject(CLSID_CMapiImp, \
|
||||
m_nsMapiFactory, \
|
||||
CLSCTX_LOCAL_SERVER, \
|
||||
REGCLS_MULTIPLEUSE, \
|
||||
&m_dwRegister);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
m_nsMapiFactory->Release() ;
|
||||
m_nsMapiFactory = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiSupport::ShutdownMAPISupport()
|
||||
{
|
||||
if (m_dwRegister != 0)
|
||||
::CoRevokeClassObject(m_dwRegister);
|
||||
|
||||
if (m_nsMapiFactory != nsnull)
|
||||
{
|
||||
m_nsMapiFactory->Release();
|
||||
m_nsMapiFactory = nsnull;
|
||||
}
|
||||
|
||||
::CoUninitialize();
|
||||
|
||||
return NS_OK ;
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMapiRegistry);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMapiSupport);
|
||||
|
||||
// The list of components we register
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{
|
||||
NS_IMAPIREGISTRY_CLASSNAME,
|
||||
NS_IMAPIREGISTRY_CID,
|
||||
NS_IMAPIREGISTRY_CONTRACTID,
|
||||
nsMapiRegistryConstructor
|
||||
},
|
||||
|
||||
{
|
||||
NS_IMAPISUPPORT_CLASSNAME,
|
||||
NS_IMAPISUPPORT_CID,
|
||||
NS_IMAPISUPPORT_CONTRACTID,
|
||||
nsMapiSupportConstructor,
|
||||
nsMapiRegistrationProc,
|
||||
nsnull
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(msgMapiModule, components);
|
||||
|
||||
66
mozilla/mailnews/mapi/mapihook/src/msgMapiSupport.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Krishna Mohan Khandrika (kkhandrika@netscape.com)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef MSG_MAPI_SUPPORT_H_
|
||||
#define MSG_MAPI_SUPPORT_H_
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIMapiSupport.h"
|
||||
#include "msgMapiFactory.h"
|
||||
|
||||
#define NS_IMAPISUPPORT_CID \
|
||||
{0x8967fed2, 0xc8bb, 0x11d5, \
|
||||
{ 0xa3, 0xe9, 0x00, 0xb0, 0xd0, 0xf3, 0xba, 0xa7 }}
|
||||
|
||||
class nsMapiSupport : public nsIMapiSupport,
|
||||
public nsIObserver
|
||||
{
|
||||
public :
|
||||
nsMapiSupport();
|
||||
~nsMapiSupport();
|
||||
|
||||
// Declare all interface methods we must implement.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIMAPISUPPORT
|
||||
|
||||
private :
|
||||
|
||||
DWORD m_dwRegister;
|
||||
CMapiFactory *m_nsMapiFactory;
|
||||
};
|
||||
|
||||
#endif // MSG_MAPI_SUPPORT_H_
|
||||
167
mozilla/mailnews/mapi/mapihook/src/nsMapiRegistry.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsProxiedService.h"
|
||||
|
||||
#include "nsMapiRegistryUtils.h"
|
||||
#include "nsMapiRegistry.h"
|
||||
|
||||
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
|
||||
/** Implementation of the nsIMapiRegistry interface.
|
||||
* Use standard implementation of nsISupports stuff.
|
||||
*/
|
||||
NS_IMPL_ISUPPORTS1(nsMapiRegistry, nsIMapiRegistry);
|
||||
|
||||
nsMapiRegistry::nsMapiRegistry() {
|
||||
NS_INIT_ISUPPORTS();
|
||||
m_ShowDialog = ! m_registryUtils.verifyRestrictedAccess();
|
||||
m_DefaultMailClient = m_registryUtils.IsDefaultMailClient();
|
||||
}
|
||||
|
||||
nsMapiRegistry::~nsMapiRegistry() {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiRegistry::GetIsDefaultMailClient(PRBool * retval) {
|
||||
// we need to get the value from registry everytime
|
||||
// because the registry settings can be changed from
|
||||
// other mail applications.
|
||||
*retval = m_registryUtils.IsDefaultMailClient();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiRegistry::GetShowDialog(PRBool * retval) {
|
||||
*retval = m_ShowDialog;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMapiRegistry::SetIsDefaultMailClient(PRBool aIsDefaultMailClient)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (aIsDefaultMailClient)
|
||||
{
|
||||
rv = m_registryUtils.setDefaultMailClient();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_DefaultMailClient = PR_TRUE;
|
||||
else
|
||||
m_registryUtils.ShowMapiErrorDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = m_registryUtils.unsetDefaultMailClient();
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_DefaultMailClient = PR_FALSE;
|
||||
else
|
||||
m_registryUtils.ShowMapiErrorDialog();
|
||||
}
|
||||
|
||||
return rv ;
|
||||
}
|
||||
|
||||
/** This will bring up the dialog box only once per session and
|
||||
* only if the current app is not default Mail Client.
|
||||
* This also checks the registry if the registry key
|
||||
* showMapiDialog is set
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsMapiRegistry::ShowMailIntegrationDialog(nsIDOMWindow *aParentWindow) {
|
||||
nsresult rv;
|
||||
if (!m_ShowDialog || !m_registryUtils.getShowDialog()) return NS_OK;
|
||||
nsCOMPtr<nsIPromptService> promptService(do_GetService(
|
||||
"@mozilla.org/embedcomp/prompt-service;1", &rv));
|
||||
if (NS_SUCCEEDED(rv) && promptService)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = m_registryUtils.MakeMapiStringBundle (getter_AddRefs (bundle)) ;
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString dialogTitle;
|
||||
const PRUnichar *brandStrings[] = { m_registryUtils.brandName() };
|
||||
NS_NAMED_LITERAL_STRING(dialogTitlePropertyTag, "dialogTitle");
|
||||
rv = bundle->FormatStringFromName(dialogTitlePropertyTag.get(),
|
||||
brandStrings, 1,
|
||||
getter_Copies(dialogTitle));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString dialogText;
|
||||
NS_NAMED_LITERAL_STRING(dialogTextPropertyTag, "dialogText");
|
||||
rv = bundle->FormatStringFromName(dialogTextPropertyTag.get(),
|
||||
brandStrings, 1,
|
||||
getter_Copies(dialogText));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString checkboxText;
|
||||
rv = bundle->GetStringFromName(
|
||||
NS_LITERAL_STRING("checkboxText").get(),
|
||||
getter_Copies(checkboxText));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool checkValue = PR_FALSE;
|
||||
PRInt32 buttonPressed = 0;
|
||||
rv = promptService->ConfirmEx(aParentWindow,
|
||||
dialogTitle,
|
||||
dialogText.get(),
|
||||
(nsIPromptService::BUTTON_TITLE_YES *
|
||||
nsIPromptService::BUTTON_POS_0) +
|
||||
(nsIPromptService::BUTTON_TITLE_NO *
|
||||
nsIPromptService::BUTTON_POS_1),
|
||||
nsnull,
|
||||
nsnull,
|
||||
nsnull,
|
||||
checkboxText,
|
||||
&checkValue,
|
||||
&buttonPressed);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
rv = m_registryUtils.SetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop",
|
||||
"showMapiDialog", (checkValue) ? "0" : "1");
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
m_ShowDialog = PR_FALSE;
|
||||
if (!buttonPressed)
|
||||
rv = SetIsDefaultMailClient(PR_TRUE) ; // SetDefaultMailClient();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
76
mozilla/mailnews/mapi/mapihook/src/nsMapiRegistry.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsmapiregistry_h____
|
||||
#define nsmapiregistry_h____
|
||||
|
||||
#include "nsIMapiRegistry.h"
|
||||
|
||||
#ifndef MAX_BUF
|
||||
#define MAX_BUF 4096
|
||||
#endif
|
||||
|
||||
/* c5be14ba-4e0a-4eec-a1b8-04363761d63c */
|
||||
#define NS_IMAPIREGISTRY_CID \
|
||||
{ 0xc5be14ba, 0x4e0a, 0x4eec, {0xa1, 0xb8, 0x04, 0x36, 0x37, 0x61, 0xd6, 0x3c} }
|
||||
#define NS_IMAPIREGISTRY_CONTRACTID "@mozilla.org/mapiregistry;1"
|
||||
#define NS_IMAPIREGISTRY_CLASSNAME "Mozilla MAPI Registry"
|
||||
|
||||
#define MAILNEWS_ALLOW_DEFAULT_MAIL_CLIENT "mailnews.default_mail_client"
|
||||
|
||||
class nsMapiRegistry : public nsIMapiRegistry {
|
||||
public:
|
||||
// ctor/dtor
|
||||
nsMapiRegistry();
|
||||
virtual ~nsMapiRegistry();
|
||||
|
||||
// Declare all interface methods we must implement.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMAPIREGISTRY
|
||||
|
||||
protected:
|
||||
|
||||
PRBool m_DefaultMailClient;
|
||||
PRBool m_ShowDialog;
|
||||
nsMapiRegistryUtils m_registryUtils ;
|
||||
|
||||
private:
|
||||
// Special member to handle initialization.
|
||||
PRBool mHaveBeenSet;
|
||||
}; // nsMapiRegistry
|
||||
|
||||
#endif // nsmapiregistry_h____
|
||||
743
mozilla/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.cpp
Normal file
@@ -0,0 +1,743 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#undef UNICODE
|
||||
#undef _UNICODE
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "msgMapiImp.h"
|
||||
#include "msgMapiMain.h"
|
||||
#include "nsMapiRegistryUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIPromptService.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
|
||||
#define EXE_EXTENSION ".exe"
|
||||
#define USERAGENT_VERSION_PREF "general.useragent.misc"
|
||||
#define USERAGENT_VERSION_NS_PREF "general.useragent.vendorSub"
|
||||
#define USERAGENT_PREF_PREFIX "rv:"
|
||||
|
||||
nsMapiRegistryUtils::nsMapiRegistryUtils()
|
||||
{
|
||||
m_mapiStringBundle = nsnull ;
|
||||
}
|
||||
|
||||
const char * nsMapiRegistryUtils::thisApplication()
|
||||
{
|
||||
if (m_thisApp.IsEmpty()) {
|
||||
char buffer[MAX_PATH] = {0};
|
||||
DWORD len = ::GetModuleFileName(NULL, buffer, MAX_PATH);
|
||||
if (!len) return nsnull ;
|
||||
char shortPathBuf[MAX_PATH] = {0};
|
||||
len = ::GetShortPathName(buffer, shortPathBuf, MAX_PATH);
|
||||
if (!len) return nsnull ;
|
||||
m_thisApp = buffer;
|
||||
m_thisApp.ToUpperCase();
|
||||
}
|
||||
|
||||
return m_thisApp.get() ;
|
||||
}
|
||||
|
||||
const PRUnichar * nsMapiRegistryUtils::brandName()
|
||||
{
|
||||
nsresult rv;
|
||||
if (m_brand.IsEmpty()) {
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(
|
||||
kStringBundleServiceCID, &rv));
|
||||
if (NS_SUCCEEDED(rv) && bundleService) {
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
rv = bundleService->CreateBundle(
|
||||
"chrome://global/locale/brand.properties",
|
||||
getter_AddRefs(brandBundle));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsXPIDLString brandName;
|
||||
rv = brandBundle->GetStringFromName(
|
||||
NS_LITERAL_STRING("brandShortName").get(),
|
||||
getter_Copies(brandName));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
m_brand = brandName ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_brand.get() ;
|
||||
}
|
||||
|
||||
const PRUnichar * nsMapiRegistryUtils::versionNo()
|
||||
{
|
||||
if (!m_versionNo.IsEmpty())
|
||||
return m_versionNo.get() ;
|
||||
|
||||
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
|
||||
if (prefs) {
|
||||
nsXPIDLCString versionStr ;
|
||||
nsresult rv = prefs->GetCharPref(USERAGENT_VERSION_NS_PREF, getter_Copies(versionStr));
|
||||
if (NS_SUCCEEDED(rv) && versionStr)
|
||||
m_versionNo.AssignWithConversion (versionStr.get()) ;
|
||||
else {
|
||||
rv = prefs->GetCharPref(USERAGENT_VERSION_PREF, getter_Copies(versionStr));
|
||||
if (NS_SUCCEEDED(rv) && versionStr) {
|
||||
m_versionNo.AssignWithConversion (versionStr.get()) ;
|
||||
m_versionNo.StripChars (USERAGENT_PREF_PREFIX) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_versionNo.get() ;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsMapiRegistryUtils::verifyRestrictedAccess() {
|
||||
char subKey[] = "Software\\Mozilla - Test Key";
|
||||
PRBool result = PR_FALSE;
|
||||
DWORD dwDisp = 0;
|
||||
HKEY key;
|
||||
// Try to create/open a subkey under HKLM.
|
||||
DWORD rc = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
subKey,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_WRITE,
|
||||
NULL,
|
||||
&key,
|
||||
&dwDisp);
|
||||
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
// Key was opened; first close it.
|
||||
::RegCloseKey(key);
|
||||
// Delete it if we just created it.
|
||||
switch(dwDisp) {
|
||||
case REG_CREATED_NEW_KEY:
|
||||
::RegDeleteKey(HKEY_LOCAL_MACHINE, subKey);
|
||||
break;
|
||||
case REG_OPENED_EXISTING_KEY:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Can't create/open it; we don't have access.
|
||||
result = PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::SetRegistryKey(HKEY baseKey, const char * keyName,
|
||||
const char * valueName, char * value)
|
||||
{
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
HKEY key;
|
||||
LONG rc = ::RegCreateKey(baseKey, keyName, &key);
|
||||
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
rc = ::RegSetValueEx(key, valueName, NULL, REG_SZ,
|
||||
(LPBYTE)(const char*)value, strlen(value));
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
result = NS_OK;
|
||||
}
|
||||
::RegCloseKey(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::DeleteRegistryValue(HKEY baseKey, const char * keyName,
|
||||
const char * valueName)
|
||||
{
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
HKEY key;
|
||||
LONG rc = ::RegOpenKey(baseKey, keyName, &key);
|
||||
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
rc = ::RegDeleteValue(key, valueName);
|
||||
if (rc == ERROR_SUCCESS)
|
||||
result = NS_OK;
|
||||
::RegCloseKey(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsMapiRegistryUtils::GetRegistryKey(HKEY baseKey, const char * keyName,
|
||||
const char * valueName, nsCAutoString & value)
|
||||
{
|
||||
HKEY key;
|
||||
LONG rc = ::RegOpenKey(baseKey, keyName, &key);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
char buffer[MAX_PATH] = {0};
|
||||
DWORD len = sizeof buffer;
|
||||
rc = ::RegQueryValueEx(key, valueName, NULL, NULL,
|
||||
(LPBYTE)buffer, &len);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
if (len)
|
||||
value = buffer;
|
||||
}
|
||||
::RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRBool nsMapiRegistryUtils::IsDefaultMailClient()
|
||||
{
|
||||
if (!isSmartDll() && !isMozDll())
|
||||
return PR_FALSE;
|
||||
nsCAutoString name;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Clients\\Mail", "", name);
|
||||
if (!name.IsEmpty()) {
|
||||
nsCAutoString keyName("Software\\Clients\\Mail\\");
|
||||
keyName += name.get();
|
||||
keyName += "\\protocols\\mailto\\shell\\open\\command";
|
||||
|
||||
nsCAutoString result;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", result);
|
||||
if (!result.IsEmpty()) {
|
||||
nsCAutoString strExtension;
|
||||
strExtension.Assign(EXE_EXTENSION);
|
||||
result.ToUpperCase();
|
||||
strExtension.ToUpperCase();
|
||||
PRInt32 index = result.RFind(strExtension.get());
|
||||
if (index != kNotFound) {
|
||||
result.Truncate(index + strExtension.Length());
|
||||
}
|
||||
nsCAutoString thisApp (thisApplication()) ;
|
||||
return (result == thisApp);
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::saveDefaultMailClient()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCAutoString name ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Clients\\Mail", "", name);
|
||||
if (!name.IsEmpty()) {
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail",
|
||||
(char *)name.get());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString keyName("Software\\Clients\\Mail\\");
|
||||
keyName += name.get();
|
||||
keyName += "\\protocols\\mailto\\shell\\open\\command";
|
||||
nsCAutoString appPath ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, keyName.get(), "", appPath);
|
||||
if (!appPath.IsEmpty()) {
|
||||
nsCAutoString stringName("HKEY_LOCAL_MACHINE\\");
|
||||
stringName += keyName.get();
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
stringName.get(), (char *)appPath.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail",
|
||||
"");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::saveUserDefaultMailClient()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCAutoString name ;
|
||||
GetRegistryKey(HKEY_CURRENT_USER,"Software\\Clients\\Mail", "", name);
|
||||
if (!name.IsEmpty()) {
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"HKEY_CURRENT_USER\\Software\\Clients\\Mail",
|
||||
(char *)name.get());
|
||||
}
|
||||
else {
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"HKEY_CURRENT_USER\\Software\\Clients\\Mail",
|
||||
"");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether it is a smart dll or not. Smart dll is the one installed by
|
||||
* IE5 or Outlook Express which forwards the MAPI calls to the dll based on the
|
||||
* registry key setttings.
|
||||
* Returns TRUE if is a smart dll.
|
||||
*/
|
||||
|
||||
typedef HRESULT (FAR PASCAL GetOutlookVersionFunc)();
|
||||
PRBool nsMapiRegistryUtils::isSmartDll()
|
||||
{
|
||||
char buffer[MAX_PATH] = {0};
|
||||
if (GetSystemDirectory(buffer, sizeof(buffer)) == 0)
|
||||
return PR_FALSE;
|
||||
PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll");
|
||||
|
||||
HINSTANCE hInst;
|
||||
GetOutlookVersionFunc *doesExist = nsnull;
|
||||
hInst = LoadLibrary(buffer);
|
||||
if (hInst == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
doesExist = (GetOutlookVersionFunc *) GetProcAddress (hInst, "GetOutlookVersion");
|
||||
FreeLibrary(hInst);
|
||||
|
||||
return (doesExist != nsnull);
|
||||
}
|
||||
|
||||
typedef HRESULT (FAR PASCAL GetMapiDllVersion)();
|
||||
/**
|
||||
* Checks whether mapi32.dll is installed by this app.
|
||||
* Returns TRUE if it is.
|
||||
*/
|
||||
PRBool nsMapiRegistryUtils::isMozDll()
|
||||
{
|
||||
char buffer[MAX_PATH] = {0};
|
||||
if (GetSystemDirectory(buffer, sizeof(buffer)) == 0)
|
||||
return PR_FALSE;
|
||||
PL_strcatn(buffer, sizeof(buffer), "\\Mapi32.dll");
|
||||
|
||||
HINSTANCE hInst;
|
||||
GetMapiDllVersion *doesExist = nsnull;
|
||||
hInst = LoadLibrary(buffer);
|
||||
if (hInst == nsnull)
|
||||
return PR_FALSE;
|
||||
|
||||
doesExist = (GetMapiDllVersion *) GetProcAddress (hInst, "GetMapiDllVersion");
|
||||
FreeLibrary(hInst);
|
||||
|
||||
return (doesExist != nsnull);
|
||||
}
|
||||
|
||||
/** Renames Mapi32.dl in system directory to Mapi32_moz_bak.dll
|
||||
* copies the mozMapi32.dll from bin directory to the system directory
|
||||
*/
|
||||
nsresult nsMapiRegistryUtils::CopyMozMapiToWinSysDir()
|
||||
{
|
||||
nsresult rv;
|
||||
char buffer[MAX_PATH] = {0};
|
||||
if (GetSystemDirectory(buffer, sizeof(buffer)) == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString filePath(buffer);
|
||||
filePath.Append("\\Mapi32_moz_bak.dll");
|
||||
|
||||
nsCOMPtr<nsILocalFile> pCurrentMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || !pCurrentMapiFile) return rv;
|
||||
pCurrentMapiFile->InitWithPath(filePath.get());
|
||||
|
||||
nsCOMPtr<nsIFile> pMozMapiFile;
|
||||
nsCOMPtr<nsIProperties> directoryService =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
if (!directoryService) return NS_ERROR_FAILURE;
|
||||
rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(pMozMapiFile));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
pMozMapiFile->Append("mozMapi32.dll");
|
||||
|
||||
PRBool bExist;
|
||||
rv = pMozMapiFile->Exists(&bExist);
|
||||
if (NS_FAILED(rv) || !bExist) return rv;
|
||||
|
||||
rv = pCurrentMapiFile->Exists(&bExist);
|
||||
if (NS_SUCCEEDED(rv) && bExist)
|
||||
{
|
||||
rv = pCurrentMapiFile->Remove(PR_FALSE);
|
||||
}
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
filePath.Assign(buffer);
|
||||
filePath.Append("\\Mapi32.dll");
|
||||
pCurrentMapiFile->InitWithPath(filePath.get());
|
||||
rv = pCurrentMapiFile->Exists(&bExist);
|
||||
if (NS_SUCCEEDED(rv) && bExist)
|
||||
{
|
||||
rv = pCurrentMapiFile->MoveTo(nsnull, "Mapi32_moz_bak.dll");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCAutoString fullFilePath(buffer);
|
||||
fullFilePath.Append("\\Mapi32_moz_bak.dll");
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"Mapi_backup_dll",
|
||||
(char *)fullFilePath.get());
|
||||
if (NS_FAILED(rv)) {
|
||||
RestoreBackedUpMapiDll();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(fileName, "Mapi32.dll");
|
||||
filePath.Assign(buffer);
|
||||
pCurrentMapiFile->InitWithPath(filePath.get());
|
||||
rv = pMozMapiFile->CopyToUnicode(pCurrentMapiFile, fileName.get());
|
||||
if (NS_FAILED(rv))
|
||||
RestoreBackedUpMapiDll();
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** deletes the Mapi32.dll in system directory and renames Mapi32_moz_bak.dll
|
||||
* to Mapi32.dll
|
||||
*/
|
||||
nsresult nsMapiRegistryUtils::RestoreBackedUpMapiDll()
|
||||
{
|
||||
nsresult rv;
|
||||
char buffer[MAX_PATH] = {0};
|
||||
if (GetSystemDirectory(buffer, sizeof(buffer)) == 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString filePath(buffer);
|
||||
nsCAutoString previousFileName(buffer);
|
||||
filePath.Append("\\Mapi32.dll");
|
||||
previousFileName.Append("\\Mapi32_moz_bak.dll");
|
||||
|
||||
nsCOMPtr <nsILocalFile> pCurrentMapiFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || !pCurrentMapiFile) return NS_ERROR_FAILURE;
|
||||
pCurrentMapiFile->InitWithPath(filePath.get());
|
||||
|
||||
nsCOMPtr<nsILocalFile> pPreviousMapiFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || !pPreviousMapiFile) return NS_ERROR_FAILURE;
|
||||
pPreviousMapiFile->InitWithPath(previousFileName.get());
|
||||
|
||||
PRBool bExist;
|
||||
rv = pCurrentMapiFile->Exists(&bExist);
|
||||
if (NS_SUCCEEDED(rv) && bExist) {
|
||||
rv = pCurrentMapiFile->Remove(PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
rv = pPreviousMapiFile->Exists(&bExist);
|
||||
if (NS_SUCCEEDED(rv) && bExist)
|
||||
rv = pPreviousMapiFile->MoveTo(nsnull, "Mapi32.dll");
|
||||
if (NS_SUCCEEDED(rv))
|
||||
DeleteRegistryValue(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"Mapi_backup_dll");
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Sets Mozilla as default Mail Client
|
||||
*/
|
||||
nsresult nsMapiRegistryUtils::setDefaultMailClient()
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult mailKeySet=NS_ERROR_FAILURE;
|
||||
if (verifyRestrictedAccess()) return NS_ERROR_FAILURE;
|
||||
if (!isSmartDll()) {
|
||||
if (NS_FAILED(CopyMozMapiToWinSysDir())) return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = saveDefaultMailClient();
|
||||
if (NS_FAILED(saveUserDefaultMailClient()) ||
|
||||
NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
nsCAutoString keyName("Software\\Clients\\Mail\\");
|
||||
|
||||
nsCAutoString appName (NS_ConvertUCS2toUTF8(brandName()).get());
|
||||
if (!appName.IsEmpty()) {
|
||||
keyName.Append(appName.get());
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ;
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString defaultMailTitle;
|
||||
const PRUnichar *keyValuePrefixStr[] = { brandName(), versionNo() };
|
||||
NS_NAMED_LITERAL_STRING(defaultMailTitleTag, "defaultMailDisplayTitle");
|
||||
rv = bundle->FormatStringFromName(defaultMailTitleTag.get(),
|
||||
keyValuePrefixStr, 2,
|
||||
getter_Copies(defaultMailTitle));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(),
|
||||
"", NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(defaultMailTitle).get()) ) ;
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_FAILURE;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString thisApp (thisApplication()) ;
|
||||
if (NS_FAILED(rv)) return rv ;
|
||||
|
||||
nsCAutoString dllPath (thisApp) ;
|
||||
PRInt32 index = dllPath.RFind("\\");
|
||||
if (index != kNotFound)
|
||||
dllPath.Truncate(index + 1);
|
||||
dllPath += "mozMapi32.dll";
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(), "DLLPath",
|
||||
(char *)dllPath.get());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
keyName.Append("\\protocols\\mailto");
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(),
|
||||
"", "URL:MailTo Protocol");
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString appPath (thisApp);
|
||||
appPath += " \"%1\"";
|
||||
keyName.Append("\\shell\\open\\command");
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(),
|
||||
"", (char *)appPath.get());
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Clients\\Mail",
|
||||
"", (char *)appName.get());
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString mailAppPath(thisApp);
|
||||
mailAppPath += " -mail";
|
||||
nsCAutoString appKeyName ("Software\\Clients\\Mail\\");
|
||||
appKeyName.Append(appName.get());
|
||||
appKeyName.Append("\\shell\\open\\command");
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
appKeyName.get(),
|
||||
"", (char *)mailAppPath.get());
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString iconPath(thisApp);
|
||||
iconPath += ",0";
|
||||
nsCAutoString iconKeyName ("Software\\Clients\\Mail\\");
|
||||
iconKeyName.Append(appName.get());
|
||||
iconKeyName.Append("\\DefaultIcon");
|
||||
mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
iconKeyName.get(),
|
||||
"", (char *)iconPath.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(mailKeySet)) {
|
||||
nsresult desktopKeySet = SetRegistryKey(HKEY_CURRENT_USER,
|
||||
"Software\\Clients\\Mail",
|
||||
"", (char *)appName.get());
|
||||
if (NS_SUCCEEDED(desktopKeySet)) {
|
||||
desktopKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"defaultMailHasBeenSet", "1");
|
||||
}
|
||||
::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
|
||||
(LPARAM)"Software\\Clients\\Mail");
|
||||
RegisterServer(CLSID_CMapiImp, "Mozilla MAPI", "mozMapi", "mozMapi.1");
|
||||
return desktopKeySet;
|
||||
}
|
||||
|
||||
return mailKeySet;
|
||||
}
|
||||
|
||||
/** Removes Mozilla as the default Mail client and restores the previous setting
|
||||
*/
|
||||
nsresult nsMapiRegistryUtils::unsetDefaultMailClient() {
|
||||
nsresult result = NS_OK;
|
||||
nsresult mailKeySet = NS_ERROR_FAILURE;
|
||||
if (verifyRestrictedAccess()) return NS_ERROR_FAILURE;
|
||||
if (!isSmartDll()) {
|
||||
if (NS_FAILED(RestoreBackedUpMapiDll())) return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCAutoString name ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop",
|
||||
"HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail", name);
|
||||
nsCAutoString appName (NS_ConvertUCS2toUTF8(brandName()).get());
|
||||
|
||||
if (!name.IsEmpty() && !appName.IsEmpty() && name.Equals(appName)) {
|
||||
nsCAutoString keyName("HKEY_LOCAL_MACHINE\\Software\\Clients\\Mail\\");
|
||||
keyName.Append(appName.get());
|
||||
keyName.Append("\\protocols\\mailto\\shell\\open\\command");
|
||||
nsCAutoString appPath ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop",
|
||||
keyName.get(), appPath);
|
||||
if (!appPath.IsEmpty()) {
|
||||
keyName.Assign("Software\\Clients\\Mail\\");
|
||||
keyName.Append(appName.get());
|
||||
keyName.Append("\\protocols\\mailto\\shell\\open\\command");
|
||||
result = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(),
|
||||
"", (char *)appPath.get());
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
PRInt32 index = appPath.RFind("\\");
|
||||
if (index != kNotFound)
|
||||
appPath.Truncate(index + 1);
|
||||
appPath += "mozMapi32.dll";
|
||||
keyName.Assign("Software\\Clients\\Mail\\");
|
||||
keyName.Append(appName.get());
|
||||
result = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
keyName.get(),
|
||||
"DLLPath", (char *) appPath.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!name.IsEmpty()) {
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Clients\\Mail",
|
||||
"", (char *)name.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
mailKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Clients\\Mail",
|
||||
"", "");
|
||||
|
||||
if (NS_SUCCEEDED(mailKeySet)) {
|
||||
nsCAutoString userAppName ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"HKEY_CURRENT_USER\\Software\\Clients\\Mail", userAppName);
|
||||
nsresult desktopKeySet = NS_OK;
|
||||
if (!userAppName.IsEmpty()) {
|
||||
desktopKeySet = SetRegistryKey(HKEY_CURRENT_USER,
|
||||
"Software\\Clients\\Mail",
|
||||
"", (char *)userAppName.get());
|
||||
}
|
||||
else {
|
||||
DeleteRegistryValue(HKEY_CURRENT_USER, "Software\\Clients\\Mail", "");
|
||||
}
|
||||
if (NS_SUCCEEDED(desktopKeySet)) {
|
||||
desktopKeySet = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"defaultMailHasBeenSet", "0");
|
||||
}
|
||||
::SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
|
||||
(LPARAM)"Software\\Clients\\Mail");
|
||||
UnregisterServer(CLSID_CMapiImp, "mozMapi", "mozMapi.1");
|
||||
return desktopKeySet;
|
||||
}
|
||||
return mailKeySet;
|
||||
}
|
||||
|
||||
/** Returns FALSE if showMapiDialog is set to 0.
|
||||
* Returns TRUE otherwise
|
||||
* Also returns TRUE if the Mozilla has been set as the default mail client
|
||||
* and some other application has changed that setting.
|
||||
* This function gets called only if the current app is not the default mail
|
||||
* client
|
||||
*/
|
||||
PRBool nsMapiRegistryUtils::getShowDialog() {
|
||||
PRBool rv = PR_FALSE;
|
||||
nsCAutoString showDialog ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop",
|
||||
"showMapiDialog", showDialog);
|
||||
// if the user has not selected the checkbox, show dialog
|
||||
if (showDialog.IsEmpty() || showDialog.Equals("1"))
|
||||
rv = PR_TRUE;
|
||||
|
||||
if (!rv) {
|
||||
// even if the user has selected the checkbox
|
||||
// show it if some other application has changed the
|
||||
// default setting.
|
||||
nsCAutoString setMailDefault ;
|
||||
GetRegistryKey(HKEY_LOCAL_MACHINE,"Software\\Mozilla\\Desktop",
|
||||
"defaultMailHasBeenSet", setMailDefault);
|
||||
if (setMailDefault.Equals("1")) {
|
||||
// need to reset the defaultMailHasBeenSet to "0"
|
||||
// so that after the dialog is displayed once,
|
||||
// we do not keep displaying this dialog after the user has
|
||||
// selected the checkbox
|
||||
rv = SetRegistryKey(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Mozilla\\Desktop",
|
||||
"defaultMailHasBeenSet", "0");
|
||||
rv = PR_TRUE;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::MakeMapiStringBundle(nsIStringBundle ** aMapiStringBundle)
|
||||
{
|
||||
nsresult rv = NS_OK ;
|
||||
|
||||
if (m_mapiStringBundle)
|
||||
{
|
||||
*aMapiStringBundle = m_mapiStringBundle ;
|
||||
NS_ADDREF(*aMapiStringBundle);
|
||||
return rv ;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(
|
||||
kStringBundleServiceCID, &rv));
|
||||
if (NS_FAILED(rv) || !bundleService) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = bundleService->CreateBundle(
|
||||
MAPI_PROPERTIES_CHROME,
|
||||
getter_AddRefs(m_mapiStringBundle));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*aMapiStringBundle = m_mapiStringBundle) ;
|
||||
|
||||
return rv ;
|
||||
}
|
||||
|
||||
nsresult nsMapiRegistryUtils::ShowMapiErrorDialog()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPromptService> promptService(do_GetService(
|
||||
"@mozilla.org/embedcomp/prompt-service;1", &rv));
|
||||
if (NS_SUCCEEDED(rv) && promptService)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = MakeMapiStringBundle (getter_AddRefs (bundle)) ;
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString dialogTitle;
|
||||
const PRUnichar *brandStrings[] = { brandName() };
|
||||
NS_NAMED_LITERAL_STRING(dialogTitlePropertyTag, "errorMessageTitle");
|
||||
rv = bundle->FormatStringFromName(dialogTitlePropertyTag.get(),
|
||||
brandStrings, 1,
|
||||
getter_Copies(dialogTitle));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
nsXPIDLString dialogText;
|
||||
NS_NAMED_LITERAL_STRING(dialogTextPropertyTag, "errorMessage");
|
||||
rv = bundle->FormatStringFromName(dialogTextPropertyTag.get(),
|
||||
brandStrings, 1,
|
||||
getter_Copies(dialogText));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = promptService->Alert(nsnull, dialogTitle,
|
||||
dialogText);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
112
mozilla/mailnews/mapi/mapihook/src/nsMapiRegistryUtils.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsmapiregistryutils_h____
|
||||
#define nsmapiregistryutils_h____
|
||||
|
||||
#include <windows.h>
|
||||
#include <string.h>
|
||||
#include <winreg.h>
|
||||
|
||||
#include "Registry.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
||||
class nsMapiRegistryUtils
|
||||
{
|
||||
private :
|
||||
nsCAutoString m_thisApp ;
|
||||
nsAutoString m_brand ;
|
||||
nsAutoString m_versionNo ;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> m_mapiStringBundle ;
|
||||
public :
|
||||
nsMapiRegistryUtils() ;
|
||||
|
||||
// returns TRUE if the Mapi32.dll is smart dll.
|
||||
PRBool isSmartDll();
|
||||
// returns TRUE if the Mapi32.dll is a Mozilla dll.
|
||||
PRBool isMozDll();
|
||||
|
||||
// Returns the (fully-qualified) name of this executable.
|
||||
const char * thisApplication() ;
|
||||
// This returns the brand name for this application
|
||||
const PRUnichar * brandName() ;
|
||||
// This returns the version no for this application
|
||||
const PRUnichar * versionNo() ;
|
||||
// verifyRestrictedAccess - Returns PR_TRUE if this user only has restricted access
|
||||
// to the registry keys we need to modify.
|
||||
PRBool verifyRestrictedAccess() ;
|
||||
|
||||
// set the Windows registry key
|
||||
nsresult SetRegistryKey(HKEY baseKey, const char * keyName,
|
||||
const char * valueName, char * value);
|
||||
// delete a registry key
|
||||
nsresult DeleteRegistryValue(HKEY baseKey, const char * keyName,
|
||||
const char * valueName);
|
||||
// get a Windows registry key
|
||||
void GetRegistryKey(HKEY baseKey, const char * keyName,
|
||||
const char * valueName, nsCAutoString & value) ;
|
||||
|
||||
// Returns TRUE if the current application is default mail client.
|
||||
PRBool IsDefaultMailClient();
|
||||
// Sets Mozilla as default Mail Client
|
||||
nsresult setDefaultMailClient() ;
|
||||
// Removes Mozilla as the default Mail client and restores the previous setting
|
||||
nsresult unsetDefaultMailClient() ;
|
||||
|
||||
// Saves the current setting of the default Mail Client in
|
||||
// HKEY_LOCAL_MACHINE\\Software\\Mozilla\\Desktop
|
||||
nsresult saveDefaultMailClient();
|
||||
// Saves the current user setting of the default Mail Client in
|
||||
// HKEY_LOCAL_MACHINE\\Software\\Mozilla\\Desktop
|
||||
nsresult saveUserDefaultMailClient();
|
||||
|
||||
nsresult CopyMozMapiToWinSysDir();
|
||||
nsresult RestoreBackedUpMapiDll();
|
||||
|
||||
// Returns FALSE if showMapiDialog is set to 0.
|
||||
PRBool getShowDialog() ;
|
||||
|
||||
// create a string bundle for MAPI messages
|
||||
nsresult MakeMapiStringBundle(nsIStringBundle ** aMapiStringBundle) ;
|
||||
// display an error dialog for MAPI messages
|
||||
nsresult ShowMapiErrorDialog() ;
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
30
mozilla/mailnews/mapi/resources/content/contents.rdf
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the packages being supplied by this jar -->
|
||||
<RDF:Seq about="urn:mozilla:package:root">
|
||||
<RDF:li resource="urn:mozilla:package:messenger-mapi"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- package information -->
|
||||
<RDF:Description about="urn:mozilla:package:messenger-mapi"
|
||||
chrome:displayName="Messenger"
|
||||
chrome:author="mozilla.org"
|
||||
chrome:name="messenger-mapi"
|
||||
chrome:localeVersion="0.9.7"
|
||||
chrome:skinVersion="0.9.4">
|
||||
</RDF:Description>
|
||||
|
||||
<!-- overlay information -->
|
||||
<RDF:Seq about="urn:mozilla:overlays">
|
||||
<RDF:li resource="chrome://messenger/content/pref-mailnews.xul"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- mapi items for Mail And Newsgroups preferences pane -->
|
||||
<RDF:Seq about="chrome://messenger/content/pref-mailnews.xul">
|
||||
<RDF:li>chrome://messenger-mapi/content/pref-mailnewsOverlay.xul</RDF:li>
|
||||
</RDF:Seq>
|
||||
|
||||
</RDF:RDF>
|
||||
3
mozilla/mailnews/mapi/resources/content/jar.mn
Normal file
@@ -0,0 +1,3 @@
|
||||
messenger.jar:
|
||||
content/messenger-mapi/pref-mailnewsOverlay.xul
|
||||
content/messenger-mapi/contents.rdf
|
||||
29
mozilla/mailnews/mapi/resources/content/makefile.win
Normal file
@@ -0,0 +1,29 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
chrome::
|
||||
$(REGCHROME) content messenger-mapi messenger.jar
|
||||
14
mozilla/mailnews/mapi/resources/content/overlays.rdf
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<RDF:RDF xmlns:chrome="http://www.mozilla.org/rdf/chrome#"
|
||||
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
|
||||
<!-- mapi items for mailnews preferences -->
|
||||
<RDF:Seq about="urn:mozilla:overlays">
|
||||
<RDF:li resource="chrome://messenger/content/pref-mailnews.xul"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<RDF:Seq about="chrome://messenger/content/pref-mailnews.xul">
|
||||
<RDF:li>chrome://messenger/content/pref-mailnewsOverlay.xul</RDF:li>
|
||||
</RDF:Seq>
|
||||
|
||||
</RDF:RDF>
|
||||
104
mozilla/mailnews/mapi/resources/content/pref-mailnewsOverlay.js
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Srilatha Moturi <srilatha@netscape.com>
|
||||
*/
|
||||
|
||||
function mailnewsOverlayStartup() {
|
||||
mailnewsOverlayInit();
|
||||
parent.hPrefWindow.registerOKCallbackFunc(onOK);
|
||||
if (!("mapiPref" in parent)) {
|
||||
parent.mapiPref = new Object;
|
||||
parent.mapiPref.isDefaultMailClient =
|
||||
document.getElementById("mailnewsEnableMapi").checked;
|
||||
}
|
||||
else {
|
||||
// when we switch between different panes
|
||||
// set the checkbox based on the saved state
|
||||
var mailnewsEnableMapi = document.getElementById("mailnewsEnableMapi");
|
||||
if (parent.mapiPref.isDefaultMailClient)
|
||||
mailnewsEnableMapi.setAttribute("checked", "true");
|
||||
else
|
||||
mailnewsEnableMapi.setAttribute("checked", "false");
|
||||
}
|
||||
}
|
||||
|
||||
function mailnewsOverlayInit() {
|
||||
try {
|
||||
var mapiRegistry = Components.classes[ "@mozilla.org/mapiregistry;1" ].
|
||||
getService( Components.interfaces.nsIMapiRegistry );
|
||||
}
|
||||
catch(ex){
|
||||
mapiRegistry = null;
|
||||
}
|
||||
|
||||
const prefbase = "system.windows.lock_ui.";
|
||||
var mailnewsEnableMapi = document.getElementById("mailnewsEnableMapi");
|
||||
if (mapiRegistry) {
|
||||
// initialise preference component.
|
||||
// While the data is coming from the system registry, we use a set
|
||||
// of parallel preferences to indicate if the ui should be locked.
|
||||
try {
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService()
|
||||
.QueryInterface(Components.interfaces.nsIPrefService);
|
||||
var prefBranch = prefService.getBranch(prefbase);
|
||||
if (prefBranch && prefBranch.prefIsLocked("default_mail_client")) {
|
||||
if (prefBranch.getBoolPref("default_mail_client"))
|
||||
mapiRegistry.setDefaultMailClient();
|
||||
else
|
||||
mapiRegistry.unsetDefaultMailClient();
|
||||
mailnewsEnableMapi.setAttribute("disabled", "true");
|
||||
}
|
||||
}
|
||||
catch(ex) {}
|
||||
if (mapiRegistry.isDefaultMailClient)
|
||||
mailnewsEnableMapi.setAttribute("checked", "true");
|
||||
else
|
||||
mailnewsEnableMapi.setAttribute("checked", "false");
|
||||
}
|
||||
else
|
||||
mailnewsEnableMapi.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
function onEnableMapi() {
|
||||
// save the state of the checkbox
|
||||
if ("mapiPref" in parent)
|
||||
parent.mapiPref.isDefaultMailClient =
|
||||
document.getElementById("mailnewsEnableMapi").checked;
|
||||
}
|
||||
|
||||
function onOK()
|
||||
{
|
||||
try {
|
||||
var mapiRegistry = Components.classes[ "@mozilla.org/mapiregistry;1" ].
|
||||
getService( Components.interfaces.nsIMapiRegistry );
|
||||
}
|
||||
catch(ex){
|
||||
mapiRegistry = null;
|
||||
}
|
||||
if (mapiRegistry &&
|
||||
("mapiPref" in parent) &&
|
||||
(mapiRegistry.isDefaultMailClient != parent.mapiPref.isDefaultMailClient)) {
|
||||
if (parent.mapiPref.isDefaultMailClient)
|
||||
mapiRegistry.setDefaultMailClient();
|
||||
else
|
||||
mapiRegistry.unsetDefaultMailClient();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
The contents of this file are subject to the Mozilla Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/MPL/
|
||||
|
||||
oftware distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Srilatha Moturi <srilatha@netscape.com>
|
||||
-->
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % prefMailnewsOverlayDTD SYSTEM "chrome://messenger-mapi/locale/pref-mailnewsOverlay.dtd" >
|
||||
%prefMailnewsOverlayDTD;
|
||||
]>
|
||||
<overlay id="prefMailnewsOverlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/x-javascript">
|
||||
<![CDATA[
|
||||
_elementIDs.push("mailnewsEnableMapi");
|
||||
]]>
|
||||
</script>
|
||||
<script type="application/x-javascript" src="chrome://messenger-mapi/content/pref-mailnewsOverlay.js"/>
|
||||
<hbox autostretch="never" id="mapi">
|
||||
<checkbox id="mailnewsEnableMapi" label="&enableMapi.label;"
|
||||
accesskey="&enableMapi.accesskey;"
|
||||
preftype="bool" prefstring="mailnews.default_mail_client" prefattribute="checked"/>
|
||||
|
||||
</hbox>
|
||||
</overlay>
|
||||
23
mozilla/mailnews/mapi/resources/locale/en-US/contents.rdf
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the skins being supplied by this package -->
|
||||
<RDF:Seq about="urn:mozilla:locale:root">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- locale information -->
|
||||
<RDF:Description about="urn:mozilla:locale:en-US">
|
||||
<chrome:packages>
|
||||
<RDF:Seq about="urn:mozilla:locale:en-US:packages">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US:messenger-mapi"/>
|
||||
</RDF:Seq>
|
||||
</chrome:packages>
|
||||
</RDF:Description>
|
||||
|
||||
<!-- Version Information. State that we work only with major version of this
|
||||
package. -->
|
||||
<RDF:Description about="urn:mozilla:locale:en-US:messenger-mapi"
|
||||
chrome:localeVersion="0.9.7"/>
|
||||
</RDF:RDF>
|
||||
4
mozilla/mailnews/mapi/resources/locale/en-US/jar.mn
Normal file
@@ -0,0 +1,4 @@
|
||||
en-US.jar:
|
||||
locale/en-US/messenger-mapi/pref-mailnewsOverlay.dtd
|
||||
locale/en-US/messenger-mapi/mapi.properties
|
||||
locale/en-US/messenger-mapi/contents.rdf
|
||||
40
mozilla/mailnews/mapi/resources/locale/en-US/makefile.win
Normal file
@@ -0,0 +1,40 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
|
||||
|
||||
CHROME_DIR=locales\en-US
|
||||
CHROME_L10N_DIR=messenger\locale
|
||||
|
||||
CHROME_L10N = \
|
||||
.\pref-mailnewsOverlay.dtd \
|
||||
.\mapi.properties \
|
||||
.\contents.rdf \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
chrome::
|
||||
$(REGCHROME) locale en-US/messenger-mapi en-US.jar
|
||||
|
||||
23
mozilla/mailnews/mapi/resources/locale/en-US/mapi.properties
Normal file
@@ -0,0 +1,23 @@
|
||||
# Mail Integration Dialog
|
||||
dialogTitle=%S Mail
|
||||
dialogText=Do you want to use %S as the default mail application?
|
||||
checkboxText=Do not display this dialog again
|
||||
|
||||
# MAPI Messages
|
||||
loginText=Please enter your password for %S:
|
||||
loginTextwithName=Please enter your username and password
|
||||
loginTitle=%S Mail
|
||||
PasswordTitle=%S Mail
|
||||
|
||||
# MAPI Error Messages
|
||||
errorMessage=%S Mail could not be set as the default mail application because a registry key could not be updated. Verify with your system administrator that you have write access to your system registry, and then try again.
|
||||
errorMessageTitle=%S Mail
|
||||
|
||||
# MAPI Security Messages
|
||||
mapiBlindSendWarning=Another application is attempting to send mail using your user profile. Are you sure you want to send mail?
|
||||
mapiBlindSendDontShowAgain=Warn me whenever other applications try to send mail from me
|
||||
|
||||
#Default Mail Display String
|
||||
# localization note, $1%S is the app name, $2%S is the version
|
||||
defaultMailDisplayTitle=%S %S Mail
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<!ENTITY enableMapiTitle.label "When sending mail from other applications">
|
||||
<!ENTITY enableMapi.label "Use &vendorShortName; Mail as the default mail application.">
|
||||
<!ENTITY enableMapi.accesskey "u">
|
||||
28
mozilla/mailnews/mapi/resources/locale/makefile.win
Normal file
@@ -0,0 +1,28 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
DIRS=en-US
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
27
mozilla/mailnews/mapi/resources/makefile.win
Normal file
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Srilatha Moturi <srilatha@netscape.com>
|
||||
#
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS=content locale
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,3 +0,0 @@
|
||||
<FilesMatch ^(.*localconfig.*)$>
|
||||
deny from all
|
||||
</FilesMatch>
|
||||
@@ -1,44 +0,0 @@
|
||||
===Litmus Installation Instructions===
|
||||
|
||||
First of all, let me convince you that you in fact probbaly do not want
|
||||
to install Litmus. Litmus is not 1.0 software. Litmus is not even 0.5
|
||||
software. In fact, Litmus doesn't really do any of the things you would
|
||||
expect it to do yet.
|
||||
|
||||
In summary, if you're not looking to install Litmus because you are or
|
||||
want to be a Litmus developer, you'd best turn around and go back from
|
||||
whence you came.
|
||||
|
||||
If at any point you find that you don't understand these installation
|
||||
instructions, it's a good sign you want to turn back as well.
|
||||
|
||||
Required Perl Modules:
|
||||
Class::DBI
|
||||
Class::DBI::mysql
|
||||
Template
|
||||
Time::Piece
|
||||
Time::Piece::mysql
|
||||
Time::Seconds
|
||||
Date::Manip
|
||||
HTML::StripScripts
|
||||
HTML::StripScripts::Parser
|
||||
Text::Markdown
|
||||
XML::XPath
|
||||
|
||||
Once you've got everything installed, run: mysql < createdb.sql to
|
||||
create the Litmus database.
|
||||
|
||||
Then edit Litmus/Config.pm to give it the information it needs to
|
||||
connect to the database.
|
||||
|
||||
Run ./populatedb.pl to create products, testgroups, subgroups, etc...
|
||||
There is no UI at present for doing this.
|
||||
|
||||
Edit the newly created 'localconfig' file and provide your database
|
||||
configuration.
|
||||
|
||||
Then just pop the whole thing into a directory where your web server can
|
||||
get at it. Have fun!
|
||||
|
||||
Note: After upgrading Litmus, it's a good idea to run populatedb.pl
|
||||
again to pick up any schema changes that may have occured.
|
||||
@@ -1,109 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
# Max Kanat-Alexander <mkanat@bugzilla.org>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
# Global object store and function library for Litmus
|
||||
|
||||
package Litmus;
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus::Template;
|
||||
use Litmus::Config;
|
||||
use Litmus::Error;
|
||||
use Litmus::Auth;
|
||||
use Litmus::CGI;
|
||||
|
||||
our $_request_cache = {};
|
||||
|
||||
# each cgi _MUST_ call Litmus->init() prior to doing anything else.
|
||||
# init() ensures that the installation has not been disabled, deals with pending
|
||||
# login requests, and other essential tasks.
|
||||
sub init() {
|
||||
if ($Litmus::Config::disabled) {
|
||||
my $c = new CGI();
|
||||
print $c->header();
|
||||
print "Litmus has been shutdown by the administrator. Please try again later.";
|
||||
exit;
|
||||
}
|
||||
# check for pending logins:
|
||||
my $c = cgi();
|
||||
if ($c->param("login_type")) {
|
||||
Litmus::Auth::processLoginForm();
|
||||
}
|
||||
}
|
||||
|
||||
# Global Template object
|
||||
sub template() {
|
||||
my $class = shift;
|
||||
request_cache()->{template} ||= Litmus::Template->create();
|
||||
return request_cache()->{template};
|
||||
}
|
||||
|
||||
# Global CGI object
|
||||
sub cgi() {
|
||||
my $class = shift;
|
||||
request_cache()->{cgi} ||= new Litmus::CGI();
|
||||
return request_cache()->{cgi};
|
||||
}
|
||||
|
||||
sub getCurrentUser {
|
||||
return Litmus::Auth::getCurrentUser();
|
||||
}
|
||||
|
||||
# cache of global variables for a single request only
|
||||
# use me like: Litmus->request_cache->{'var'} = 'foo';
|
||||
# entries here are guarenteed to get flushed when the request ends,
|
||||
# even when running under mod_perl
|
||||
# from Bugzilla.pm:
|
||||
sub request_cache {
|
||||
if ($ENV{MOD_PERL}) {
|
||||
my $request = Apache->request();
|
||||
my $cache = $request->pnotes();
|
||||
# Sometimes mod_perl doesn't properly call DESTROY on all
|
||||
# the objects in pnotes(), so we register a cleanup handler
|
||||
# to make sure that this happens.
|
||||
if (!$cache->{cleanup_registered}) {
|
||||
$request->push_handlers(PerlCleanupHandler => sub {
|
||||
my $r = shift;
|
||||
foreach my $key (keys %{$r->pnotes}) {
|
||||
delete $r->pnotes->{$key};
|
||||
}
|
||||
});
|
||||
$cache->{cleanup_registered} = 1;
|
||||
}
|
||||
return $cache;
|
||||
}
|
||||
return $_request_cache;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,555 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::Auth;
|
||||
|
||||
use strict;
|
||||
|
||||
# IMPORTANT!
|
||||
## You _must_ call Litmus::Auth methods before sending a Content-type
|
||||
## header so that any required cookies can be sent.
|
||||
|
||||
require Exporter;
|
||||
use Litmus::Error;
|
||||
use Time::Piece;
|
||||
use Time::Seconds;
|
||||
use Litmus::DB::User;
|
||||
|
||||
use CGI;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw();
|
||||
|
||||
my $logincookiename = $Litmus::Config::user_cookiename;
|
||||
my $cookie_expire_days = 7;
|
||||
|
||||
# Given a username and password, validate the login. Returns the
|
||||
# Litmus::DB::User object associated with the username if the login
|
||||
# is sucuessful. Returns false otherwise.
|
||||
sub validate_login($$) {
|
||||
my $username = shift;
|
||||
my $password = shift;
|
||||
|
||||
return 0 if (!$username or $username eq '' or
|
||||
!$password or $password eq '');
|
||||
|
||||
my ($userobj) = Litmus::DB::User->search(email => $username);
|
||||
|
||||
if (!$userobj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$userobj->enabled() || $userobj->enabled() == 0) {
|
||||
die "Account ".$userobj->username()." has been disabled by the administrator";
|
||||
}
|
||||
|
||||
# for security reasons, we use the real (correct) crypt'd passwd
|
||||
# as the salt:
|
||||
my $realPasswordCrypted = $userobj->getRealPasswd();
|
||||
return 0 if (!$realPasswordCrypted or $realPasswordCrypted eq '');
|
||||
my $enteredPasswordCrypted = crypt($password, $realPasswordCrypted);
|
||||
if ($enteredPasswordCrypted eq $realPasswordCrypted) {
|
||||
return $userobj;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
# Used by a CGI when a login is required to proceed beyond a certain point.
|
||||
# requireLogin() will return a Litmus::User object to indicate that the user
|
||||
# is logged in, or it will redirect to a login page to allow the login to be
|
||||
# completed. Once the login is complete, the user will be redirected back to
|
||||
# $return_to and any parameters in the current CGI.pm object will be passed
|
||||
# to the new script.
|
||||
#
|
||||
sub requireLogin {
|
||||
my $return_to = shift;
|
||||
my $admin_login_required = shift;
|
||||
my $cgi = Litmus->cgi();
|
||||
|
||||
# see if we are already logged in:
|
||||
my $user = getCurrentUser();
|
||||
return $user if $user; # well, that was easy...
|
||||
|
||||
my $vars = {
|
||||
title => "Login",
|
||||
return_to => $return_to,
|
||||
adminrequired => $admin_login_required,
|
||||
params => $cgi,
|
||||
};
|
||||
|
||||
print $cgi->header();
|
||||
Litmus->template()->process("auth/login.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
# Used by a CGI in much the same way as requireLogin() when the user must
|
||||
# be an admin to proceed.
|
||||
sub requireAdmin {
|
||||
my $return_to = shift;
|
||||
my $cgi = Litmus->cgi();
|
||||
|
||||
my $user = requireLogin($return_to, 1);
|
||||
if (!$user || !$user->is_admin()) {
|
||||
print $cgi->header();
|
||||
basicError("You must be a Litmus administrator to perform this function.");
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
# Returns the current Litmus::DB::Session object corresponding to the current
|
||||
# logged-in user, or 0 if no valid session exists
|
||||
sub getCurrentSession() {
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
# we're actually processing the login form right now, so the cookie hasn't
|
||||
# been sent yet...
|
||||
if (Litmus->request_cache->{'curSession'}) {
|
||||
return Litmus->request_cache->{'curSession'};
|
||||
}
|
||||
|
||||
my $sessionCookie = $c->cookie($logincookiename);
|
||||
if (! $sessionCookie) {
|
||||
return 0
|
||||
}
|
||||
|
||||
my @sessions = Litmus::DB::Session->search(sessioncookie => $sessionCookie);
|
||||
my $session = $sessions[0];
|
||||
if (! $session) { return 0 }
|
||||
|
||||
# see if it's still valid and that the user hasn't been disabled
|
||||
if (! $session->isValid()) { return 0 }
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
# Returns the Litmus::User object corresponding to the current logged-in
|
||||
# user, or 0 if no valid login cookie exists
|
||||
sub getCurrentUser() {
|
||||
my $session = getCurrentSession();
|
||||
|
||||
if ($session) {
|
||||
return $session->user_id();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# ONLY NON-PUBLIC API BEYOND THIS POINT
|
||||
#
|
||||
|
||||
# Processes data from a login form (auth/login.html.tmpl) using data
|
||||
# from the current Litmus::CGI object in use. When complete, returns the
|
||||
# flow of control to the script the user wanted to reach before the login,
|
||||
# setting a login cookie for the user.
|
||||
sub processLoginForm {
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
my $type = $c->param("login_type");
|
||||
|
||||
if ($c->param("accountCreated") &&
|
||||
$c->param("accountCreated") eq "true") {
|
||||
# make sure they really are logged in and didn't just set
|
||||
# the accountCreated flag:
|
||||
requireLogin("index.cgi");
|
||||
return; # we're done here
|
||||
}
|
||||
|
||||
if ($type eq "litmus") {
|
||||
my $username = $c->param("email");
|
||||
my $password = $c->param("password");
|
||||
|
||||
my $user = validate_login($username, $password);
|
||||
|
||||
if (!$user) {
|
||||
loginError($c, "Username/Password incorrect. Please try again.");
|
||||
}
|
||||
|
||||
my $session = makeSession($user);
|
||||
$c->storeCookie(makeCookie($session));
|
||||
|
||||
} elsif ($type eq "newaccount") {
|
||||
my $email = $c->param("email");
|
||||
my $name = $c->param("realname");
|
||||
my $password = $c->param("password");
|
||||
my $nickname = $c->param("irc_nickname");
|
||||
|
||||
# some basic form-field validation:
|
||||
my $emailregexp = q:^[\\w\\.\\+\\-=]+@[\\w\\.\\-]+\\.[\\w\\-]+$:;
|
||||
if (! $email || ! $email =~ /$emailregexp/) {
|
||||
loginError($c, "You must enter a valid email address");
|
||||
}
|
||||
if (! $password eq $c->param("password_confirm")) {
|
||||
loginError($c, "Passwords do not match. Please try again.");
|
||||
}
|
||||
|
||||
my @users = Litmus::DB::User->search(email => $email);
|
||||
if ($users[0]) {
|
||||
loginError($c, "User ".$users[0]->email() ." already exists.");
|
||||
}
|
||||
if ($nickname and $nickname ne '') {
|
||||
@users = Litmus::DB::User->search(irc_nickname => $nickname);
|
||||
if ($users[0]) {
|
||||
loginError($c, "An account with that IRC nickname already exists.");
|
||||
}
|
||||
} else {
|
||||
$nickname = undef;
|
||||
}
|
||||
|
||||
my $userobj =
|
||||
Litmus::DB::User->create({email => $email,
|
||||
password => bz_crypt($password),
|
||||
bugzilla_uid => 0,
|
||||
realname => $name,
|
||||
enabled => 1,
|
||||
is_admin => 0,
|
||||
irc_nickname => $nickname
|
||||
});
|
||||
|
||||
my $session = makeSession($userobj);
|
||||
$c->storeCookie(makeCookie($session));
|
||||
|
||||
my $vars = {
|
||||
title => "Account Created",
|
||||
email => $email,
|
||||
realname => $name,
|
||||
return_to => $c->param("login_loc"),
|
||||
params => $c
|
||||
};
|
||||
|
||||
print $c->header();
|
||||
Litmus->template()->process("auth/accountcreated.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit;
|
||||
|
||||
} elsif ($type eq "bugzilla") {
|
||||
my $username = $c->param("username");
|
||||
my $password = $c->param("password");
|
||||
|
||||
|
||||
} elsif ($type eq "convert") {
|
||||
# convert an old-school Litmus account (pre authentication system)
|
||||
# to a new one with a password:
|
||||
my $username = $c->param("email");
|
||||
|
||||
my @userobjs = Litmus::DB::User->search(email => $username);
|
||||
my $userobj = $userobjs[0];
|
||||
if (! $userobj || $userobj->email() ne $username) {
|
||||
loginError($c, "User $username does not exist.");
|
||||
}
|
||||
|
||||
if ($userobj->password() ne "") {
|
||||
# already a new-style account
|
||||
loginError($c, "User $username has already been updated.");
|
||||
}
|
||||
|
||||
# display a "convert login" form to get the rest of the information
|
||||
print $c->header();
|
||||
my $return_to = $c->param("login_loc") || "";
|
||||
unsetFields();
|
||||
my $vars = {
|
||||
title => "Update Login",
|
||||
email => $username,
|
||||
return_to => $return_to,
|
||||
params => $c,
|
||||
};
|
||||
|
||||
Litmus->template()->process("auth/convertaccount.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
exit;
|
||||
} elsif ($type eq "reallyconvert") {
|
||||
my $username = $c->param("email");
|
||||
my $realname = $c->param("realname");
|
||||
my $password = $c->param("password");
|
||||
my $password_confirm = $c->param("password_confirm");
|
||||
my $nickname = $c->param("irc_nickname");
|
||||
|
||||
if (! $password eq $password_confirm) {
|
||||
loginError($c, "Passwords do not match. Please try again.");
|
||||
}
|
||||
|
||||
my @userobjs = Litmus::DB::User->search(email => $username);
|
||||
my $userobj = $userobjs[0];
|
||||
|
||||
# just to be safe:
|
||||
if (! $userobj || $userobj->email() ne $username) {
|
||||
loginError($c, "User $username does not exist.");
|
||||
}
|
||||
|
||||
if ($userobj->password() ne "" && ($userobj->bugzilla_uid() == 0 ||
|
||||
!$userobj->bugzilla_uid())) {
|
||||
# already a new-style account
|
||||
loginError($c, "User $username has already been updated.");
|
||||
}
|
||||
my ($nickname_exists) =
|
||||
Litmus::DB::User->search(irc_nickname => $nickname);
|
||||
if ($nickname_exists) {
|
||||
loginError($c,
|
||||
"An account with that IRC nickname already exists.",
|
||||
"auth/convertaccount.html.tmpl",
|
||||
"Update Login");
|
||||
}
|
||||
|
||||
# do the upgrade:
|
||||
$userobj->password(bz_crypt($password));
|
||||
$userobj->bugzilla_uid("0");
|
||||
$userobj->realname($realname);
|
||||
$userobj->enabled(1);
|
||||
# $userobj->is_admin(0);
|
||||
$userobj->irc_nickname($nickname);
|
||||
$userobj->update();
|
||||
|
||||
my $session = makeSession($userobj);
|
||||
$c->storeCookie(makeCookie($session));
|
||||
|
||||
my $vars = {
|
||||
title => "Account Created",
|
||||
email => $username,
|
||||
realname => $realname,
|
||||
return_to => $c->param("login_loc"),
|
||||
params => $c
|
||||
};
|
||||
|
||||
print $c->header();
|
||||
Litmus->template()->process("auth/accountcreated.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit;
|
||||
|
||||
} else {
|
||||
internalError("Unknown login scheme attempted");
|
||||
}
|
||||
}
|
||||
|
||||
sub changePassword {
|
||||
my $userobj = shift;
|
||||
my $password = shift;
|
||||
$userobj->password(bz_crypt($password));
|
||||
$userobj->update();
|
||||
|
||||
my @sessions = $userobj->sessions();
|
||||
foreach my $session (@sessions) {
|
||||
$session->makeExpire();
|
||||
}
|
||||
}
|
||||
|
||||
# Given a userobj, process the login and return a session object
|
||||
sub makeSession {
|
||||
my $userobj = shift;
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
my $expires = localtime() + ONE_DAY * $cookie_expire_days;
|
||||
|
||||
my $sessioncookie = randomToken(64);
|
||||
|
||||
my $session = Litmus::DB::Session->create({
|
||||
user_id => $userobj,
|
||||
sessioncookie => $sessioncookie,
|
||||
expires => $expires});
|
||||
|
||||
Litmus->request_cache->{'curSession'} = $session;
|
||||
return $session;
|
||||
}
|
||||
|
||||
# Given a session, create a login cookie to go with it
|
||||
sub makeCookie {
|
||||
my $session = shift;
|
||||
|
||||
my $cookie = Litmus->cgi()->cookie(
|
||||
-name => $logincookiename,
|
||||
-value => $session->sessioncookie(),
|
||||
-domain => $main::ENV{"HTTP_HOST"},
|
||||
-expires => $session->expires(),
|
||||
);
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
sub loginError {
|
||||
my $c = shift;
|
||||
my $message = shift;
|
||||
my $template = shift;
|
||||
my $title = shift;
|
||||
|
||||
if (!$template) {
|
||||
$template = "auth/login.html.tmpl";
|
||||
}
|
||||
if (!$title) {
|
||||
$title = "Login";
|
||||
}
|
||||
|
||||
print $c->header();
|
||||
|
||||
my $return_to = $c->param("login_loc") || "";
|
||||
my $email = $c->param("email") || "";
|
||||
|
||||
unsetFields();
|
||||
|
||||
my $vars = {
|
||||
title => $title,
|
||||
return_to => $return_to,
|
||||
email => $email,
|
||||
params => $c,
|
||||
onload => "toggleMessage('failure','$message')",
|
||||
};
|
||||
|
||||
Litmus->template()->process($template, $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
sub unsetFields() {
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
# We need to unset some params in $c since otherwise we end up with
|
||||
# a hidden form field set for "email" and friends and madness results:
|
||||
$c->param('email', '');
|
||||
$c->param('username', '');
|
||||
$c->param('login_type', '');
|
||||
$c->param('login_loc', '');
|
||||
$c->param('realname', '');
|
||||
$c->param('password', '');
|
||||
$c->param('password_confirm', '');
|
||||
|
||||
}
|
||||
|
||||
# Like crypt(), but with a random salt. Thanks to Bugzilla for this.
|
||||
sub bz_crypt {
|
||||
my ($password) = @_;
|
||||
|
||||
# The list of characters that can appear in a salt. Salts and hashes
|
||||
# are both encoded as a sequence of characters from a set containing
|
||||
# 64 characters, each one of which represents 6 bits of the salt/hash.
|
||||
# The encoding is similar to BASE64, the difference being that the
|
||||
# BASE64 plus sign (+) is replaced with a forward slash (/).
|
||||
my @saltchars = (0..9, 'A'..'Z', 'a'..'z', '.', '/');
|
||||
|
||||
# Generate the salt. We use an 8 character (48 bit) salt for maximum
|
||||
# security on systems whose crypt uses MD5. Systems with older
|
||||
# versions of crypt will just use the first two characters of the salt.
|
||||
my $salt = '';
|
||||
for ( my $i=0 ; $i < 8 ; ++$i ) {
|
||||
$salt .= $saltchars[rand(64)];
|
||||
}
|
||||
|
||||
# Crypt the password.
|
||||
my $cryptedpassword = crypt($password, $salt);
|
||||
|
||||
# Return the crypted password.
|
||||
return $cryptedpassword;
|
||||
}
|
||||
|
||||
sub randomToken {
|
||||
my $size = shift || 10; # default to 10 chars if nothing specified
|
||||
return join("", map{ ('0'..'9','a'..'z','A'..'Z')[rand 62] } (1..$size));
|
||||
}
|
||||
|
||||
# Deprecated:
|
||||
# DO NOT USE
|
||||
sub setCookie {
|
||||
my $user = shift;
|
||||
my $expires = shift;
|
||||
|
||||
my $user_id = 0;
|
||||
if ($user) {
|
||||
$user_id = $user->user_id();
|
||||
}
|
||||
|
||||
if (!$expires or $expires eq '') {
|
||||
$expires = '+3d';
|
||||
}
|
||||
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
my $cookie = $c->cookie(
|
||||
-name => $logincookiename,
|
||||
-value => $user_id,
|
||||
-domain => $main::ENV{"HTTP_HOST"},
|
||||
-expires => $expires,
|
||||
);
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
# Deprecated:
|
||||
sub getCookie() {
|
||||
return getCurrentUser();
|
||||
}
|
||||
|
||||
sub istrusted($) {
|
||||
my $userobj = shift;
|
||||
|
||||
return 0 if (!$userobj);
|
||||
|
||||
if ($userobj->istrusted()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub canEdit($) {
|
||||
my $userobj = shift;
|
||||
|
||||
return $userobj->istrusted();
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# logout()
|
||||
#
|
||||
# Unset the user's cookie
|
||||
#########################################################################
|
||||
sub logout() {
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
my $cookie = $c->cookie(
|
||||
-name => $logincookiename,
|
||||
-value => '',
|
||||
-domain => $main::ENV{"HTTP_HOST"},
|
||||
-expires => '-1d'
|
||||
);
|
||||
$c->storeCookie($cookie);
|
||||
|
||||
# invalidate the session behind the cookie as well:
|
||||
my $session = getCurrentSession();
|
||||
if ($session) { $session->makeExpire() }
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::BugzillaDBI;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Litmus::Config;
|
||||
use Litmus::Error;
|
||||
use Memoize;
|
||||
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
BEGIN {
|
||||
unless ($Litmus::Config::bugzilla_auth_enabled) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
my $dsn = "dbi:mysql:$Litmus::Config::bugzilla_db:$Litmus::Config::bugzilla_host";
|
||||
|
||||
Litmus::BugzillaDBI->set_db('Main',
|
||||
$dsn,
|
||||
$Litmus::Config::bugzilla_user,
|
||||
$Litmus::Config::bugzilla_pass);
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::CGI;
|
||||
|
||||
use strict;
|
||||
use base 'CGI';
|
||||
|
||||
# Subclass of CGI.pm that can store cookies in advance and output them
|
||||
# later when the header() method is called. This feature should probably
|
||||
# be submitted as a patch to CGI.pm itself.
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my @args = @_;
|
||||
|
||||
my $self = $class->SUPER::new(@args);
|
||||
$self->{'litmusCookieStore'} = [];
|
||||
return $self;
|
||||
}
|
||||
|
||||
# Stores a cookie to be set later by the header() method
|
||||
sub storeCookie {
|
||||
my $self = shift;
|
||||
my $cookie = shift;
|
||||
|
||||
# "we're like kids in a candy shop"
|
||||
my @cookieStore = @{$self->{'litmusCookieStore'}};
|
||||
push(@cookieStore, $cookie);
|
||||
$self->{'litmusCookieStore'} = \@cookieStore;
|
||||
}
|
||||
|
||||
sub header {
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
|
||||
foreach my $cur ($self->{'litmusCookieStore'}) {
|
||||
push(@args, {-cookie => $cur});
|
||||
}
|
||||
|
||||
$self->SUPER::header(@args);
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,125 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::Cache;
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus;
|
||||
use Data::JavaScript;
|
||||
use Litmus::DB::Product;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
@Litmus::Cache::EXPORT = qw(
|
||||
rebuildCache
|
||||
);
|
||||
|
||||
# generate a new litmusconfig.js file because something has updated:
|
||||
sub rebuildCache {
|
||||
unless (-e "data") { system("mkdir", "data") }
|
||||
open(CACHE, ">data/litmusconfig.js.new");
|
||||
|
||||
print CACHE "// Litmus configuration information\n";
|
||||
print CACHE "// Do not edit this file directly. It is autogenerated from the database\n";
|
||||
print CACHE "\n";
|
||||
|
||||
# we build up @litmusconfig, a big perl data structure, and spit the
|
||||
# whole thing out as javascript with Data::JavaScript
|
||||
# shield your eyes, we're in for a long trip
|
||||
my @litmusconfig;
|
||||
my @products = Litmus::DB::Product->search(enabled => 1);
|
||||
my $prodcount = 0;
|
||||
foreach my $curproduct (@products) {
|
||||
my $prodrow = \%{$litmusconfig[$prodcount]};
|
||||
$prodrow->{"name"} = $curproduct->name();
|
||||
$prodrow->{"id"} = $curproduct->product_id();
|
||||
|
||||
my $brancharray = \@{$prodrow->{"branches"}};
|
||||
my $branchcount = 0;
|
||||
foreach my $curbranch ($curproduct->branches(enabled => 1)) {
|
||||
my $branchrow = \%{$brancharray->[$branchcount]};
|
||||
$branchrow->{"name"} = $curbranch->name();
|
||||
$branchrow->{"id"} = $curbranch->branch_id();
|
||||
$branchcount++;
|
||||
}
|
||||
|
||||
my $platformarray = \@{$prodrow->{"platforms"}};
|
||||
my $platformcount = 0;
|
||||
foreach my $curplat (Litmus::DB::Platform->search_ByProduct($curproduct->product_id())) {
|
||||
my $platrow = \%{$platformarray->[$platformcount]};
|
||||
$platrow->{"name"} = $curplat->name();
|
||||
$platrow->{"id"} = $curplat->platform_id();
|
||||
|
||||
my $opsysarray = \@{$platrow->{"opsyses"}};
|
||||
my $opsyscount = 0;
|
||||
foreach my $curopsys ($curplat->opsyses()) {
|
||||
my $opsysrow = \%{$opsysarray->[$opsyscount]};
|
||||
$opsysrow->{"name"} = $curopsys->name();
|
||||
$opsysrow->{"id"} = $curopsys->opsys_id();
|
||||
$opsyscount++;
|
||||
}
|
||||
$platformcount++;
|
||||
}
|
||||
|
||||
my $grouparray = \@{$prodrow->{"testgroups"}};
|
||||
my $groupcount = 0;
|
||||
foreach my $curgroup ($curproduct->testgroups()) {
|
||||
next if (!$curgroup->enabled);
|
||||
my $grouprow = \%{$grouparray->[$groupcount]};
|
||||
$grouprow->{"name"} = $curgroup->name();
|
||||
$grouprow->{"id"} = $curgroup->testgroup_id();
|
||||
$groupcount++;
|
||||
|
||||
my $subgrouparray = \@{$grouprow->{"subgroups"}};
|
||||
my $subgroupcount = 0;
|
||||
foreach my $cursubgroup (Litmus::DB::Subgroup->search_EnabledByTestgroup($curgroup->testgroup_id())) {
|
||||
next if (!$cursubgroup->enabled);
|
||||
my $subgrouprow = \%{$subgrouparray->[$subgroupcount]};
|
||||
$subgrouprow->{"name"} = $cursubgroup->name();
|
||||
$subgrouprow->{"id"} = $cursubgroup->subgroup_id();
|
||||
$subgroupcount++;
|
||||
}
|
||||
}
|
||||
|
||||
$prodcount++;
|
||||
}
|
||||
|
||||
|
||||
my $data = jsdump('litmusconfig', \@litmusconfig);
|
||||
$data =~ s/new Object;/new Array\(\);/g;
|
||||
print CACHE $data;
|
||||
close(CACHE);
|
||||
system("mv", "data/litmusconfig.js.new", "data/litmusconfig.js");
|
||||
#system("chmod", "-R", "755", "data/");
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::Config;
|
||||
|
||||
use strict;
|
||||
|
||||
do 'localconfig';
|
||||
|
||||
our $version = "0.6";
|
||||
|
||||
# if true, then Litmus will not accept any requests
|
||||
our $disabled = 0;
|
||||
|
||||
our $datadir = "data/";
|
||||
|
||||
# Set/unset this to display inline debugging value/code.
|
||||
our $DEBUG = 0;
|
||||
|
||||
1;
|
||||
@@ -1,48 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Branch;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Branch->table('branches');
|
||||
|
||||
Litmus::DB::Branch->columns(All => qw/branch_id product_id name detect_regexp enabled/);
|
||||
Litmus::DB::Branch->columns(Essential => qw/branch_id product_id name detect_regexp enabled/);
|
||||
|
||||
Litmus::DB::Branch->column_alias("product_id", "product");
|
||||
|
||||
Litmus::DB::Branch->has_many(test_results => "Litmus::DB::Testresult");
|
||||
Litmus::DB::Branch->has_a(product => "Litmus::DB::Product");
|
||||
|
||||
1;
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::BugzillaUser;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::BugzillaDBI';
|
||||
|
||||
Litmus::DB::BugzillaUser->table('profiles');
|
||||
|
||||
Litmus::DB::BugzillaUser->columns(All => qw/userid login_name cryptpassword realname
|
||||
disabledtext mybugslink refreshed_when extern_id/);
|
||||
|
||||
|
||||
1;
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::BuildType;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::BuildType->table('build_type_lookup');
|
||||
|
||||
Litmus::DB::BuildType->columns(All => qw/build_type_id name/);
|
||||
|
||||
Litmus::DB::BuildType->has_many(test_results => "Litmus::DB::Testresult");
|
||||
|
||||
1;
|
||||
@@ -1,53 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Comment;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Time::Piece;
|
||||
|
||||
Litmus::DB::Comment->table('test_result_comments');
|
||||
|
||||
Litmus::DB::Comment->columns(All => qw/comment_id test_result_id last_updated submission_time user_id comment/);
|
||||
|
||||
Litmus::DB::Comment->column_alias("test_result_id", "test_result");
|
||||
Litmus::DB::Comment->column_alias("user_id", "user");
|
||||
|
||||
Litmus::DB::Comment->has_a(test_result => "Litmus::DB::Testresult");
|
||||
Litmus::DB::Comment->has_a(user => "Litmus::DB::User");
|
||||
|
||||
Litmus::DB::Comment->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::ExitStatus;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::ExitStatus->table('exit_status_lookup');
|
||||
|
||||
Litmus::DB::ExitStatus->columns(All => qw/exit_status_id name/);
|
||||
|
||||
Litmus::DB::ExitStatus->has_many(test_results => "Litmus::DB::Testresult");
|
||||
|
||||
1;
|
||||
@@ -1,46 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Format;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Format->table('test_format_lookup');
|
||||
|
||||
Litmus::DB::Format->columns(All => qw/format_id name/);
|
||||
|
||||
Litmus::DB::Format->column_alias("format_id", "formatid");
|
||||
|
||||
Litmus::DB::Format->has_many(testcases => "Litmus::DB::Testcase");
|
||||
|
||||
1;
|
||||
@@ -1,52 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Locale;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Locale->table('locale_lookup');
|
||||
|
||||
Litmus::DB::Locale->columns(All => qw/abbrev name/);
|
||||
|
||||
Litmus::DB::Locale->column_alias("abbrev", "locale");
|
||||
|
||||
Litmus::DB::Locale->has_many(test_results => "Litmus::DB::Testresult");
|
||||
|
||||
__PACKAGE__->set_sql(RetrieveAll => qq{
|
||||
SELECT __ESSENTIAL__
|
||||
FROM __TABLE__
|
||||
ORDER BY abbrev ASC
|
||||
});
|
||||
|
||||
1;
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Log;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Log->table('test_result_logs');
|
||||
|
||||
Litmus::DB::Log->columns(All => qw/log_id last_updated submission_time log_type_id log_text/);
|
||||
|
||||
Litmus::DB::Log->column_alias("test_results", "testresults");
|
||||
Litmus::DB::Log->column_alias("log_type_id", "log_type");
|
||||
|
||||
Litmus::DB::Log->has_a(log_type => "Litmus::DB::LogType");
|
||||
Litmus::DB::Log->has_many(test_results => ["Litmus::DB::LogTestresult" => 'test_result']);
|
||||
|
||||
Litmus::DB::Testresult->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
1;
|
||||
@@ -1,47 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::LogTestresult;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::LogTestresult->table('testresult_logs_join');
|
||||
|
||||
Litmus::DB::LogTestresult->columns(Primary => qw/test_result_id log_id/);
|
||||
|
||||
Litmus::DB::LogTestresult->column_alias("test_result_id", "test_result");
|
||||
|
||||
Litmus::DB::LogTestresult->has_a(test_result => "Litmus::DB::Testresult");
|
||||
Litmus::DB::LogTestresult->has_a(log_id => "Litmus::DB::Log");
|
||||
|
||||
1;
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::LogType;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::LogType->table('log_type_lookup');
|
||||
|
||||
Litmus::DB::LogType->columns(All => qw/log_type_id name/);
|
||||
|
||||
Litmus::DB::LogType->has_many(test_result_logs => "Litmus::DB::Log");
|
||||
|
||||
1;
|
||||
@@ -1,48 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Opsys;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Opsys->table('opsyses');
|
||||
|
||||
Litmus::DB::Opsys->columns(All => qw/opsys_id platform_id name detect_regexp/);
|
||||
Litmus::DB::Opsys->columns(Essential => qw/opsys_id platform_id name detect_regexp/);
|
||||
|
||||
Litmus::DB::Opsys->column_alias("platform_id", "platform");
|
||||
|
||||
Litmus::DB::Opsys->has_many(test_results => "Litmus::DB::Testresult");
|
||||
Litmus::DB::Opsys->has_a(platform => "Litmus::DB::Platform");
|
||||
|
||||
1;
|
||||
@@ -1,105 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Platform;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
use CGI;
|
||||
|
||||
Litmus::DB::Platform->table('platforms');
|
||||
|
||||
Litmus::DB::Platform->columns(All => qw/platform_id name detect_regexp iconpath/);
|
||||
Litmus::DB::Platform->columns(Essential => qw/platform_id name detect_regexp iconpath/);
|
||||
|
||||
Litmus::DB::Platform->column_alias("platform_id", "platformid");
|
||||
|
||||
Litmus::DB::Platform->has_many(opsyses => "Litmus::DB::Opsys");
|
||||
|
||||
Litmus::DB::Platform->set_sql(ByProduct => qq{
|
||||
SELECT pl.*
|
||||
FROM platforms pl, platform_products plpr
|
||||
WHERE plpr.product_id=? AND plpr.platform_id=pl.platform_id
|
||||
});
|
||||
|
||||
Litmus::DB::Platform->set_sql(ByProductAndName => qq{
|
||||
SELECT pl.*
|
||||
FROM platforms pl, platform_products plpr
|
||||
WHERE plpr.product_id=? AND plpr.platform_id=pl.platform_id
|
||||
AND pl.name=?
|
||||
});
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_products() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from platform_products WHERE platform_id=?";
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->platform_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_with_refs() {
|
||||
my $self = shift;
|
||||
|
||||
$self->delete_from_products();
|
||||
|
||||
# XXX: How to handle opsyses?
|
||||
|
||||
return $self->delete;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_products() {
|
||||
my $self = shift;
|
||||
my $new_product_ids = shift;
|
||||
|
||||
if (scalar @$new_product_ids) {
|
||||
# Failing to delete products is _not_ fatal when adding a new subgroup.
|
||||
my $rv = $self->delete_from_products();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO platform_products (platform_id,product_id) VALUES (?,?)";
|
||||
foreach my $new_product_id (@$new_product_ids) {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->platform_id,
|
||||
$new_product_id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
@@ -1,108 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Product;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Product->table('products');
|
||||
|
||||
Litmus::DB::Product->columns(All => qw/product_id name iconpath enabled/);
|
||||
Litmus::DB::Product->columns(Essential => qw/product_id name iconpath enabled/);
|
||||
|
||||
Litmus::DB::Product->column_alias("product_id", "productid");
|
||||
|
||||
Litmus::DB::Product->has_many(testcases => "Litmus::DB::Testcase",
|
||||
{ order_by => 'testcase_id' });
|
||||
Litmus::DB::Product->has_many(subgroups => "Litmus::DB::Subgroup",
|
||||
{ order_by => 'name' });
|
||||
Litmus::DB::Product->has_many(testgroups => "Litmus::DB::Testgroup",
|
||||
{ order_by => 'name' });
|
||||
Litmus::DB::Product->has_many(branches => "Litmus::DB::Branch",
|
||||
{ order_by => 'name' });
|
||||
|
||||
__PACKAGE__->set_sql(ByPlatform => qq{
|
||||
SELECT pr.*
|
||||
FROM products pr, platform_products plpr
|
||||
WHERE plpr.platform_id=? AND plpr.product_id=pr.product_id
|
||||
ORDER BY pr.name ASC
|
||||
});
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_platforms() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from platform_products WHERE product_id=?";
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->product_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_with_refs() {
|
||||
my $self = shift;
|
||||
$self->delete_from_platforms();
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "UPDATE testgroups SET product_id=0,enabled=0 WHERE product_id=?";
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->product_id
|
||||
);
|
||||
|
||||
# Remove references to product in other entities.
|
||||
# Disable those entities for good measure.
|
||||
$sql = "UPDATE subgroups SET product_id=0,enabled=0 WHERE product_id=?";
|
||||
$rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->product_id
|
||||
);
|
||||
|
||||
$sql = "UPDATE testcases SET product_id=0,enabled=0,community_enabled=0 WHERE product_id=?";
|
||||
$rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->product_id
|
||||
);
|
||||
|
||||
$sql = "UPDATE branches SET product_id=0,enabled=0 WHERE product_id=?";
|
||||
$rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->product_id
|
||||
);
|
||||
|
||||
return $self->delete;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,44 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::ResultStatus;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::ResultStatus->table('test_result_status_lookup');
|
||||
|
||||
Litmus::DB::ResultStatus->columns(All => qw/result_status_id name class_name/);
|
||||
|
||||
Litmus::DB::ResultStatus->has_many(test_results => "Litmus::DB::Testresult");
|
||||
|
||||
1;
|
||||
@@ -1,54 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Resultbug;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Time::Piece;
|
||||
|
||||
Litmus::DB::Resultbug->table('test_result_bugs');
|
||||
|
||||
Litmus::DB::Resultbug->columns(Primary => qw/test_result_id bug_id/);
|
||||
Litmus::DB::Resultbug->columns(All => qw/last_updated submission_time user_id/);
|
||||
|
||||
Litmus::DB::Resultbug->column_alias("test_result_id", "test_result");
|
||||
Litmus::DB::Resultbug->column_alias("test_result_id", "testresult");
|
||||
Litmus::DB::Resultbug->column_alias("user_id", "user");
|
||||
|
||||
Litmus::DB::Resultbug->has_a(test_result => "Litmus::DB::Testresult");
|
||||
Litmus::DB::Resultbug->has_a(user => "Litmus::DB::User");
|
||||
|
||||
Litmus::DB::Resultbug->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
1;
|
||||
@@ -1,69 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Session;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Time::Piece;
|
||||
|
||||
Litmus::DB::Session->table('sessions');
|
||||
|
||||
Litmus::DB::Session->columns(All => qw/session_id user_id sessioncookie expires/);
|
||||
|
||||
Litmus::DB::Session->has_a(user_id => "Litmus::DB::User");
|
||||
|
||||
Litmus::DB::Session->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
# expire the current Session object
|
||||
sub makeExpire {
|
||||
my $self = shift;
|
||||
$self->delete();
|
||||
}
|
||||
|
||||
sub isValid {
|
||||
my $self = shift;
|
||||
|
||||
if ($self->expires() <= localtime()) {
|
||||
$self->makeExpire();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$self->user_id()->enabled() || $self->user_id()->enabled() == 0) {
|
||||
$self->makeExpire();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,306 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Subgroup;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Time::Piece::MySQL;
|
||||
#use Litmus::DB::Testresult;
|
||||
|
||||
Litmus::DB::Subgroup->table('subgroups');
|
||||
|
||||
Litmus::DB::Subgroup->columns(All => qw/subgroup_id name testrunner_group_id enabled product_id/);
|
||||
Litmus::DB::Subgroup->columns(Essential => qw/subgroup_id name testrunner_group_id enabled product_id/);
|
||||
|
||||
Litmus::DB::Subgroup->column_alias("subgroup_id", "subgroupid");
|
||||
|
||||
Litmus::DB::Subgroup->has_a(product => "Litmus::DB::Product");
|
||||
|
||||
__PACKAGE__->set_sql(EnabledByTestgroup => qq{
|
||||
SELECT sg.*
|
||||
FROM subgroups sg, subgroup_testgroups sgtg
|
||||
WHERE sgtg.testgroup_id=? AND sgtg.subgroup_id=sg.subgroup_id AND sg.enabled=1
|
||||
ORDER BY sgtg.sort_order ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(ByTestgroup => qq{
|
||||
SELECT sg.*
|
||||
FROM subgroups sg, subgroup_testgroups sgtg
|
||||
WHERE sgtg.testgroup_id=? AND sgtg.subgroup_id=sg.subgroup_id
|
||||
ORDER BY sgtg.sort_order ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(NumEnabledTestcases => qq{
|
||||
SELECT count(tc.testcase_id) as num_testcases
|
||||
FROM testcases tc, testcase_subgroups tcsg
|
||||
WHERE tcsg.subgroup_id=? AND tcsg.testcase_id=tc.testcase_id AND tc.enabled=1 AND tc.community_enabled=1
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(EnabledByTestcase => qq{
|
||||
SELECT sg.*
|
||||
FROM subgroups sg, testcase_subgroups tcsg
|
||||
WHERE tcsg.testcase_id=? AND tcsg.subgroup_id=sg.subgroup_id AND sg.enabled=1
|
||||
ORDER by sg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(ByTestcase => qq{
|
||||
SELECT sg.*
|
||||
FROM subgroups sg, testcase_subgroups tcsg
|
||||
WHERE tcsg.testcase_id=? AND tcsg.subgroup_id=sg.subgroup_id
|
||||
ORDER by sg.name ASC
|
||||
});
|
||||
|
||||
#########################################################################
|
||||
sub coverage() {
|
||||
my $self = shift;
|
||||
my $platform = shift;
|
||||
my $build_id = shift;
|
||||
my $locale = shift;
|
||||
my $community_only = shift;
|
||||
my $user = shift;
|
||||
|
||||
my $sql = "SELECT COUNT(t.testcase_id) FROM testcase_subgroups tsg, testcases t WHERE tsg.subgroup_id=? AND tsg.testcase_id=t.testcase_id AND t.enabled=1";
|
||||
if ($community_only) {
|
||||
$sql .= " AND t.community_enabled=1";
|
||||
}
|
||||
my $dbh = $self->db_Main();
|
||||
my $sth = $dbh->prepare_cached($sql);
|
||||
$sth->execute(
|
||||
$self->{'subgroup_id'},
|
||||
);
|
||||
my ($num_testcases) = $sth->fetchrow_array;
|
||||
|
||||
$sth->finish;
|
||||
|
||||
if (!$num_testcases or
|
||||
$num_testcases == 0) { return "N/A" }
|
||||
|
||||
|
||||
$sql = "SELECT t.testcase_id, count(tr.testresult_id) AS num_results
|
||||
FROM testcase_subgroups tsg JOIN testcases t ON (tsg.testcase_id=t.testcase_id) LEFT JOIN test_results tr ON (tr.testcase_id=t.testcase_id) JOIN opsyses o ON (tr.opsys_id=o.opsys_id)
|
||||
WHERE tsg.subgroup_id=? AND tr.build_id=? AND tr.locale_abbrev=? AND o.platform_id=?";
|
||||
if ($community_only) {
|
||||
$sql .= " AND t.community_enabled=1";
|
||||
}
|
||||
if ($user) {
|
||||
$sql .= " AND tr.user_id=" . $user->{'user_id'};
|
||||
}
|
||||
|
||||
$sql .= " GROUP BY tr.testcase_id";
|
||||
|
||||
$sth = $dbh->prepare_cached($sql);
|
||||
$sth->execute(
|
||||
$self->{'subgroup_id'},
|
||||
$build_id,
|
||||
$locale,
|
||||
$platform->{'platform_id'}
|
||||
);
|
||||
my @test_results = $self->sth_to_objects($sth);
|
||||
|
||||
$sth->finish;
|
||||
|
||||
if (@test_results == 0) { return "0" }
|
||||
|
||||
my $num_completed = 0;
|
||||
foreach my $curtest (@test_results) {
|
||||
if ($curtest->{'num_results'} > 0) {
|
||||
$num_completed++;
|
||||
}
|
||||
}
|
||||
|
||||
my $result = $num_completed/($num_testcases) * 100;
|
||||
unless ($result) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
return sprintf("%d",$result);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub clone() {
|
||||
my $self = shift;
|
||||
|
||||
my $new_subgroup = $self->copy;
|
||||
if (!$new_subgroup) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Propagate testgroup membership;
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO subgroup_testgroups (subgroup_id,testgroup_id,sort_order) SELECT ?,testgroup_id,sort_order FROM subgroup_testgroups WHERE subgroup_id=?";
|
||||
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_subgroup->subgroup_id,
|
||||
$self->subgroup_id
|
||||
);
|
||||
if (! $rows) {
|
||||
# XXX: Do we need to throw a warning here?
|
||||
# What happens when we clone a subgroup that doesn't belong to
|
||||
# any testgroups?
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO testcase_subgroups (testcase_id,subgroup_id,sort_order) SELECT testcase_id,?,sort_order FROM testcase_subgroups WHERE subgroup_id=?";
|
||||
|
||||
$rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_subgroup->subgroup_id,
|
||||
$self->subgroup_id
|
||||
);
|
||||
if (! $rows) {
|
||||
# XXX: Do we need to throw a warning here?
|
||||
}
|
||||
|
||||
return $new_subgroup;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_testgroups() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from subgroup_testgroups WHERE subgroup_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->subgroup_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_testgroup() {
|
||||
my $self = shift;
|
||||
my $testgroup_id = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from subgroup_testgroups WHERE subgroup_id=? AND testgroup_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->subgroup_id,
|
||||
$testgroup_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_testcases() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from testcase_subgroups WHERE subgroup_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->subgroup_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_with_refs() {
|
||||
my $self = shift;
|
||||
$self->delete_from_testgroups();
|
||||
$self->delete_from_testcases();
|
||||
return $self->delete;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_testgroups() {
|
||||
my $self = shift;
|
||||
my $new_testgroup_ids = shift;
|
||||
|
||||
if (scalar @$new_testgroup_ids) {
|
||||
# Failing to delete testgroups is _not_ fatal when adding a new subgroup.
|
||||
my $rv = $self->delete_from_testgroups();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO subgroup_testgroups (subgroup_id,testgroup_id,sort_order) VALUES (?,?,1)";
|
||||
foreach my $new_testgroup_id (@$new_testgroup_ids) {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->subgroup_id,
|
||||
$new_testgroup_id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_testgroup() {
|
||||
my $self = shift;
|
||||
my $testgroup_id = shift;
|
||||
my $sort_order = shift;
|
||||
|
||||
# Sort order defaults to 1.
|
||||
if (!$sort_order) {
|
||||
$sort_order = 1;
|
||||
}
|
||||
|
||||
my $rv = $self->delete_from_testgroup($testgroup_id);
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO subgroup_testgroups (subgroup_id,testgroup_id,sort_order) VALUES (?,?,?)";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->subgroup_id,
|
||||
$testgroup_id,
|
||||
$sort_order
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_testcases() {
|
||||
my $self = shift;
|
||||
my $new_testcase_ids = shift;
|
||||
|
||||
if (scalar @$new_testcase_ids) {
|
||||
# Failing to delete testcases is _not_ fatal when adding a new subgroup.
|
||||
my $rv = $self->delete_from_testcases();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testcase_subgroups (testcase_id,subgroup_id,sort_order) VALUES (?,?,?)";
|
||||
my $sort_order = 1;
|
||||
foreach my $new_testcase_id (@$new_testcase_ids) {
|
||||
next if (!$new_testcase_id);
|
||||
# Log any failures/duplicate keys to STDERR.
|
||||
eval {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_testcase_id,
|
||||
$self->subgroup_id,
|
||||
$sort_order
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
print STDERR $@;
|
||||
}
|
||||
$sort_order++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,61 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::TestRun;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Time::Piece;
|
||||
use Time::Seconds;
|
||||
|
||||
Litmus::DB::TestRun->table('test_runs');
|
||||
|
||||
Litmus::DB::TestRun->columns(All => qw/test_run_id testgroup_id name description start_timestamp finish_timestamp enabled/);
|
||||
|
||||
Litmus::DB::TestRun->column_alias("testgroup_id", "testgroup");
|
||||
|
||||
Litmus::DB::TestRun->has_a(testgroup => "Litmus::DB::Testgroup");
|
||||
Litmus::DB::TestRun->has_many(subgroups =>
|
||||
[ "Litmus::DB::SubgroupTestgroup" => "testgroup" ]);
|
||||
|
||||
Litmus::DB::TestRun->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,377 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Testcase;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Date::Manip;
|
||||
#use Litmus::DB::Testresult;
|
||||
use Memoize;
|
||||
#use Litmus::Error;
|
||||
|
||||
our $default_relevance_threshold = 1.0;
|
||||
our $default_match_limit = 25;
|
||||
our $default_num_days = 7;
|
||||
|
||||
Litmus::DB::Testcase->table('testcases');
|
||||
|
||||
Litmus::DB::Testcase->columns(Primary => qw/testcase_id/);
|
||||
Litmus::DB::Testcase->columns(Essential => qw/summary details enabled community_enabled format_id regression_bug_id product_id steps expected_results author_id creation_date last_updated version testrunner_case_id testrunner_case_version/);
|
||||
|
||||
Litmus::DB::Testcase->column_alias("testcase_id", "testid");
|
||||
Litmus::DB::Testcase->column_alias("testcase_id", "test_id");
|
||||
Litmus::DB::Testcase->column_alias("testcase_id", "id");
|
||||
Litmus::DB::Testcase->column_alias("community_enabled", "communityenabled");
|
||||
Litmus::DB::Testcase->column_alias("format_id", "format");
|
||||
Litmus::DB::Testcase->column_alias("author_id", "author");
|
||||
Litmus::DB::Testcase->column_alias("product_id", "product");
|
||||
|
||||
Litmus::DB::Testcase->has_a("format" => "Litmus::DB::Format");
|
||||
Litmus::DB::Testcase->has_a("author" => "Litmus::DB::User");
|
||||
Litmus::DB::Testcase->has_a("product" => "Litmus::DB::Product");
|
||||
|
||||
__PACKAGE__->set_sql(EnabledBySubgroup => qq{
|
||||
SELECT t.*
|
||||
FROM testcases t, testcase_subgroups tsg
|
||||
WHERE tsg.subgroup_id=? AND tsg.testcase_id=t.testcase_id AND t.enabled=1
|
||||
ORDER BY tsg.sort_order ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(BySubgroup => qq{
|
||||
SELECT t.*
|
||||
FROM testcases t, testcase_subgroups tsg
|
||||
WHERE
|
||||
tsg.subgroup_id=? AND
|
||||
tsg.testcase_id=t.testcase_id
|
||||
ORDER BY tsg.sort_order ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(ByTestgroup => qq{
|
||||
SELECT t.*
|
||||
FROM testcases t, testcase_subgroups tsg, subgroup_testgroups sgtg
|
||||
WHERE
|
||||
tsg.testcase_id=t.testcase_id AND
|
||||
tsg.subgroup_id=sgtg.subgroup_id AND
|
||||
sgtg.testgroup_id = ?
|
||||
ORDER BY tsg.sort_order ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(CommunityEnabledBySubgroup => qq{
|
||||
SELECT t.*
|
||||
FROM testcases t, testcase_subgroups tsg
|
||||
WHERE tsg.subgroup_id=? AND tsg.testcase_id=t.testcase_id AND t.enabled=1 AND t.community_enabled=1
|
||||
ORDER BY tsg.sort_order ASC, t.testcase_id ASC
|
||||
});
|
||||
|
||||
Litmus::DB::Testcase->has_many(test_results => "Litmus::DB::Testresult", {order_by => 'submission_time DESC'});
|
||||
|
||||
Litmus::DB::Testcase->has_many(subgroups =>
|
||||
["Litmus::DB::TestcaseSubgroup" => 'subgroup']);
|
||||
|
||||
#########################################################################
|
||||
# is_completed($$$$$)
|
||||
#
|
||||
# Check whether we have test results for the current test that correspond
|
||||
# to the provided platform, build_id, and user(optional).
|
||||
#########################################################################
|
||||
memoize('is_completed');
|
||||
sub is_completed {
|
||||
my $self = shift;
|
||||
my $platform = shift;
|
||||
my $build_id = shift;
|
||||
my $locale = shift;
|
||||
my $user = shift; # optional
|
||||
|
||||
my @results;
|
||||
if ($user) {
|
||||
@results = Litmus::DB::Testresult->search_CompletedByUser(
|
||||
$self->{'testcase_id'},
|
||||
$build_id,
|
||||
$locale->{'abbrev'},
|
||||
$platform->{'platform_id'},
|
||||
$user->{'user_id'},
|
||||
);
|
||||
} else {
|
||||
@results = Litmus::DB::Testresult->search_Completed(
|
||||
$self->{'testcase_id'},
|
||||
$build_id,
|
||||
$locale->{'abbrev'},
|
||||
$platform->{'platform_id'},
|
||||
);
|
||||
}
|
||||
|
||||
return @results;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getFullTextMatches() {
|
||||
my $self = shift;
|
||||
my $text_snippet = shift;
|
||||
my $match_limit = shift;
|
||||
my $relevance_threshold = shift;
|
||||
|
||||
if (!$match_limit) {
|
||||
$match_limit = $default_match_limit;
|
||||
}
|
||||
if (!$relevance_threshold) {
|
||||
$relevance_threshold = $default_relevance_threshold
|
||||
}
|
||||
|
||||
__PACKAGE__->set_sql(FullTextMatches => qq{
|
||||
SELECT testcase_id, summary, creation_date, last_updated, MATCH (summary,steps,expected_results) AGAINST (?) AS relevance
|
||||
FROM testcases
|
||||
WHERE MATCH (summary,steps,expected_results) AGAINST (?) HAVING relevance > ?
|
||||
ORDER BY relevance DESC, summary ASC
|
||||
LIMIT $match_limit
|
||||
});
|
||||
|
||||
|
||||
return $self->search_FullTextMatches(
|
||||
$text_snippet,
|
||||
$text_snippet,
|
||||
$relevance_threshold
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getNewTestcases() {
|
||||
my $self = shift;
|
||||
my $num_days = shift;
|
||||
my $match_limit = shift;
|
||||
|
||||
if (!$num_days) {
|
||||
$num_days = $default_num_days;
|
||||
}
|
||||
|
||||
if (!$match_limit) {
|
||||
$match_limit = $default_match_limit;
|
||||
}
|
||||
|
||||
__PACKAGE__->set_sql(NewTestcases => qq{
|
||||
SELECT testcase_id, summary, creation_date, last_updated
|
||||
FROM testcases
|
||||
WHERE creation_date>=?
|
||||
ORDER BY creation_date DESC
|
||||
LIMIT $match_limit
|
||||
});
|
||||
|
||||
my $err;
|
||||
my $new_datestamp=&UnixDate(DateCalc("now","- $num_days days"),"%q");
|
||||
return $self->search_NewTestcases($new_datestamp);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getRecentlyUpdated() {
|
||||
my $self = shift;
|
||||
my $num_days = shift;
|
||||
my $match_limit = shift;
|
||||
|
||||
if (!$num_days) {
|
||||
$num_days = $default_num_days;
|
||||
}
|
||||
|
||||
if (!$match_limit) {
|
||||
$match_limit = $default_match_limit;
|
||||
}
|
||||
|
||||
__PACKAGE__->set_sql(RecentlyUpdated => qq{
|
||||
SELECT testcase_id, summary, creation_date, last_updated
|
||||
FROM testcases
|
||||
WHERE last_updated>=? AND last_updated>creation_date
|
||||
ORDER BY last_updated DESC
|
||||
LIMIT $match_limit
|
||||
});
|
||||
|
||||
my $err;
|
||||
my $new_datestamp=&UnixDate(DateCalc("now","- $num_days days"),"%q");
|
||||
return $self->search_RecentlyUpdated($new_datestamp);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getDefaultMatchLimit() {
|
||||
return $default_match_limit;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getDefaultRelevanceThreshold() {
|
||||
return $default_relevance_threshold;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getDefaultNumDays() {
|
||||
return $default_num_days;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub clone() {
|
||||
my $self = shift;
|
||||
|
||||
my $new_testcase = $self->copy;
|
||||
if (!$new_testcase) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Update dates to now.
|
||||
my $now = &UnixDate("today","%q");
|
||||
$new_testcase->creation_date($now);
|
||||
$new_testcase->last_updated($now);
|
||||
$new_testcase->update();
|
||||
|
||||
# Propagate subgroup membership;
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testcase_subgroups (testcase_id,subgroup_id,sort_order) SELECT ?,subgroup_id,sort_order FROM testcase_subgroups WHERE testcase_id=?";
|
||||
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_testcase->testcase_id,
|
||||
$self->testcase_id
|
||||
);
|
||||
if (! $rows) {
|
||||
# XXX: Do we need to throw a warning here?
|
||||
# What happens when we clone a testcase that doesn't belong to
|
||||
# any subgroups?
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO related_testcases (testcase_id, related_testcase_id) VALUES (?,?)";
|
||||
$rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id,
|
||||
$new_testcase->testcase_id
|
||||
);
|
||||
if (! $rows) {
|
||||
# XXX: Do we need to throw a warning here?
|
||||
}
|
||||
|
||||
return $new_testcase;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_subgroups() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from testcase_subgroups WHERE testcase_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_subgroup() {
|
||||
my $self = shift;
|
||||
my $subgroup_id = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from testcase_subgroups WHERE testcase_id=? AND subgroup_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id,
|
||||
$subgroup_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_related() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from related_testcases WHERE testcase_id=? OR related_testcase_id=?";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id,
|
||||
$self->testcase_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_with_refs() {
|
||||
my $self = shift;
|
||||
$self->delete_from_subgroups();
|
||||
$self->delete_from_related();
|
||||
return $self->delete;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_subgroups() {
|
||||
my $self = shift;
|
||||
my $new_subgroup_ids = shift;
|
||||
|
||||
if (scalar @$new_subgroup_ids) {
|
||||
# Failing to delete subgroups is _not_ fatal when adding a new testcase.
|
||||
my $rv = $self->delete_from_subgroups();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testcase_subgroups (testcase_id,subgroup_id,sort_order) VALUES (?,?,1)";
|
||||
foreach my $new_subgroup_id (@$new_subgroup_ids) {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id,
|
||||
$new_subgroup_id
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_subgroup() {
|
||||
my $self = shift;
|
||||
my $subgroup_id = shift;
|
||||
my $sort_order = shift;
|
||||
|
||||
# Sort order defaults to 1.
|
||||
if (!$sort_order) {
|
||||
$sort_order = 1;
|
||||
}
|
||||
|
||||
my $rv = $self->delete_from_subgroup($subgroup_id);
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testcase_subgroups (testcase_id,subgroup_id,sort_order) VALUES (?,?,?)";
|
||||
return $dbh->do($sql,
|
||||
undef,
|
||||
$self->testcase_id,
|
||||
$subgroup_id,
|
||||
$sort_order
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::TestcaseSubgroup;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::TestcaseSubgroup->table('testcase_subgroups');
|
||||
|
||||
Litmus::DB::TestcaseSubgroup->columns(All => qw/testcase_id subgroup_id/);
|
||||
|
||||
Litmus::DB::TestcaseSubgroup->has_a(testcase_id => "Litmus::DB::Testcase");
|
||||
Litmus::DB::TestcaseSubgroup->has_a(subgroup_id => "Litmus::DB::Subgroup");
|
||||
|
||||
Litmus::DB::TestcaseSubgroup->column_alias("testcase_id", "testcase");
|
||||
Litmus::DB::TestcaseSubgroup->column_alias("testcase_id", "test");
|
||||
Litmus::DB::TestcaseSubgroup->column_alias("subgroup_id", "subgroup");
|
||||
|
||||
1;
|
||||
@@ -1,260 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Testgroup;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::Testgroup->table('testgroups');
|
||||
|
||||
Litmus::DB::Testgroup->columns(All => qw/testgroup_id product_id name enabled testrunner_plan_id/);
|
||||
Litmus::DB::Testgroup->columns(Essential => qw/testgroup_id product_id name enabled testrunner_plan_id/);
|
||||
|
||||
Litmus::DB::Testgroup->column_alias("product_id", "product");
|
||||
|
||||
Litmus::DB::Testgroup->has_a(product => "Litmus::DB::Product");
|
||||
|
||||
__PACKAGE__->set_sql(EnabledByBranch => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, testgroup_branches tgb
|
||||
WHERE tgb.branch_id=? AND tgb.testgroup_id=tg.testgroup_id AND tg.enabled=1 ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(ByBranch => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, testgroup_branches tgb
|
||||
WHERE tgb.branch_id=? AND tgb.testgroup_id=tg.testgroup_id ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(EnabledBySubgroup => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, subgroup_testgroups sgtg
|
||||
WHERE sgtg.subgroup_id=? AND sgtg.testgroup_id=tg.testgroup_id AND tg.enabled=1 ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(BySubgroup => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, subgroup_testgroups sgtg
|
||||
WHERE sgtg.subgroup_id=? AND sgtg.testgroup_id=tg.testgroup_id ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(EnabledByTestcase => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, subgroup_testgroups sgtg, testcase_subgroups tcsg
|
||||
WHERE tcsg.testcase_id=? AND tcsg.subgroup_id=sgtg.subgroup_id AND sgtg.testgroup_id=tg.testgroup_id AND tg.enabled=1 ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(ByTestcase => qq{
|
||||
SELECT tg.*
|
||||
FROM testgroups tg, subgroup_testgroups sgtg, testcase_subgroups tcsg
|
||||
WHERE tcsg.testcase_id=? AND tcsg.subgroup_id=sgtg.subgroup_id AND sgtg.testgroup_id=tg.testgroup_id ORDER by tg.name ASC
|
||||
});
|
||||
|
||||
#########################################################################
|
||||
sub coverage {
|
||||
my $self = shift;
|
||||
my $platform = shift;
|
||||
my $build_id = shift;
|
||||
my $locale = shift;
|
||||
my $community_only = shift;
|
||||
my $user = shift;
|
||||
|
||||
my $percent_completed = 0;
|
||||
|
||||
my @subgroups = Litmus::DB::Subgroup->search_EnabledByTestgroup($self->testgroup_id);
|
||||
my $num_empty_subgroups = 0;
|
||||
foreach my $subgroup (@subgroups) {
|
||||
my $subgroup_percent = $subgroup->coverage(
|
||||
$platform,
|
||||
$build_id,
|
||||
$locale,
|
||||
$community_only,
|
||||
$user,
|
||||
);
|
||||
if ($subgroup_percent eq "N/A") {
|
||||
$num_empty_subgroups++;
|
||||
} else {
|
||||
$percent_completed += $subgroup_percent;
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar(@subgroups) - $num_empty_subgroups == 0) {
|
||||
return "N/A"
|
||||
}
|
||||
my $total_percentage = $percent_completed /
|
||||
(scalar @subgroups - $num_empty_subgroups);
|
||||
|
||||
return sprintf("%d",$total_percentage);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub clone() {
|
||||
my $self = shift;
|
||||
|
||||
my $new_testgroup = $self->copy;
|
||||
if (!$new_testgroup) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Propagate testgroup membership;
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO subgroup_testgroups (subgroup_id,testgroup_id,sort_order) SELECT subgroup_id,?,sort_order FROM subgroup_testgroups WHERE testgroup_id=?";
|
||||
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_testgroup->testgroup_id,
|
||||
$self->testgroup_id
|
||||
);
|
||||
if (! $rows) {
|
||||
# XXX: Do we need to throw a warning here?
|
||||
}
|
||||
|
||||
return $new_testgroup;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_subgroups() {
|
||||
my $self = shift;
|
||||
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "DELETE from subgroup_testgroups WHERE testgroup_id=?";
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->testgroup_id
|
||||
);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_from_test_runs() {
|
||||
my $self = shift;
|
||||
|
||||
# XXX: Placeholder for test runs.
|
||||
return;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub delete_with_refs() {
|
||||
my $self = shift;
|
||||
$self->delete_from_subgroups();
|
||||
$self->delete_from_test_runs();
|
||||
return $self->delete;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_subgroups() {
|
||||
my $self = shift;
|
||||
my $new_subgroup_ids = shift;
|
||||
|
||||
if (scalar @$new_subgroup_ids) {
|
||||
# Failing to delete subgroups is _not_ fatal when adding a new testgroup.
|
||||
my $rv = $self->delete_from_subgroups();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO subgroup_testgroups (subgroup_id,testgroup_id,sort_order) VALUES (?,?,?)";
|
||||
my $sort_order = 1;
|
||||
foreach my $new_subgroup_id (@$new_subgroup_ids) {
|
||||
next if (!$new_subgroup_id);
|
||||
# Log any failures/duplicate keys to STDERR.
|
||||
eval {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$new_subgroup_id,
|
||||
$self->testgroup_id,
|
||||
$sort_order
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
print STDERR $@;
|
||||
}
|
||||
$sort_order++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub update_branches() {
|
||||
my $self = shift;
|
||||
my $new_branch_ids = shift;
|
||||
|
||||
if (scalar @$new_branch_ids) {
|
||||
# Failing to delete branches is _not_ fatal when adding a new testgroup.
|
||||
my $rv = $self->delete_from_branches();
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testgroup_branches (testgroup_id,branch_id) VALUES (?,?)";
|
||||
foreach my $new_branch_id (@$new_branch_ids) {
|
||||
next if (!$new_branch_id);
|
||||
# Log any failures/duplicate keys to STDERR.
|
||||
eval {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->testgroup_id,
|
||||
$new_branch_id,
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
print STDERR $@;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub add_branch() {
|
||||
my $self = shift;
|
||||
my $new_branch_id = shift;
|
||||
|
||||
# Failure to insert isn't fatal in the case of a collision, but we do want
|
||||
# to log it.
|
||||
my $dbh = __PACKAGE__->db_Main();
|
||||
my $sql = "INSERT INTO testgroup_branches (testgroup_id,branch_id) VALUES (?,?)";
|
||||
# Log any failures/duplicate keys to STDERR.
|
||||
eval {
|
||||
my $rows = $dbh->do($sql,
|
||||
undef,
|
||||
$self->testgroup_id,
|
||||
$new_branch_id,
|
||||
);
|
||||
};
|
||||
if ($@) {
|
||||
print STDERR $@;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,390 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::Testresult;
|
||||
|
||||
use strict;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
use Date::Manip;
|
||||
use Time::Piece;
|
||||
use Time::Seconds;
|
||||
use Memoize;
|
||||
|
||||
our $_num_results_default = 15;
|
||||
|
||||
Litmus::DB::Testresult->table('test_results');
|
||||
|
||||
Litmus::DB::Testresult->columns(All => qw/testresult_id testcase_id last_updated submission_time user_id opsys_id branch_id build_id user_agent result_status_id build_type_id machine_name exit_status_id duration_ms talkback_id valid vetted validated_by_user_id vetted_by_user_id validated_timestamp vetted_timestamp locale_abbrev is_automated_result/);
|
||||
|
||||
Litmus::DB::Testresult->column_alias("testcase_id", "testcase");
|
||||
Litmus::DB::Testresult->column_alias("submission_time", "timestamp");
|
||||
Litmus::DB::Testresult->column_alias("user_id", "user");
|
||||
Litmus::DB::Testresult->column_alias("opsys_id", "opsys");
|
||||
Litmus::DB::Testresult->column_alias("branch_id", "branch");
|
||||
Litmus::DB::Testresult->column_alias("user_agent", "useragent");
|
||||
Litmus::DB::Testresult->column_alias("result_status_id", "result_status");
|
||||
Litmus::DB::Testresult->column_alias("build_type_id", "build_type");
|
||||
Litmus::DB::Testresult->column_alias("exit_status_id", "exit_status");
|
||||
Litmus::DB::Testresult->column_alias("validity_id", "validity");
|
||||
Litmus::DB::Testresult->column_alias("vetting_status_id", "vetting_status");
|
||||
Litmus::DB::Testresult->column_alias("locale_abbrev", "locale");
|
||||
Litmus::DB::Testresult->column_alias("is_automated_result", "isAutomated");
|
||||
|
||||
Litmus::DB::Testresult->has_a(opsys => "Litmus::DB::Opsys");
|
||||
Litmus::DB::Testresult->has_a(branch => "Litmus::DB::Branch");
|
||||
Litmus::DB::Testresult->has_a(testcase => "Litmus::DB::Testcase");
|
||||
Litmus::DB::Testresult->has_a(result_status => "Litmus::DB::ResultStatus");
|
||||
Litmus::DB::Testresult->has_a(user => "Litmus::DB::User");
|
||||
Litmus::DB::Testresult->has_a(useragent => "Litmus::UserAgentDetect");
|
||||
Litmus::DB::Testresult->has_a(build_type => "Litmus::DB::BuildType");
|
||||
Litmus::DB::Testresult->has_a(exit_status => "Litmus::DB::ExitStatus");
|
||||
Litmus::DB::Testresult->has_a(locale => "Litmus::DB::Locale");
|
||||
Litmus::DB::Testresult->has_a(platform =>
|
||||
[ "Litmus::DB::Opsys" => "platform" ]);
|
||||
|
||||
Litmus::DB::Testresult->has_many(logs =>
|
||||
["Litmus::DB::LogTestresult" => 'log_id']);
|
||||
Litmus::DB::Testresult->has_many(comments => "Litmus::DB::Comment", {order_by => 'comment_id ASC, submission_time ASC'});
|
||||
Litmus::DB::Testresult->has_many(bugs => "Litmus::DB::Resultbug", {order_by => 'bug_id ASC, submission_time DESC'});
|
||||
|
||||
Litmus::DB::Testresult->autoinflate(dates => 'Time::Piece');
|
||||
|
||||
Litmus::DB::Testresult->set_sql(DefaultTestResults => qq{
|
||||
SELECT tr.testresult_id,tr.testcase_id,t.summary,tr.submission_time AS created,p.name AS platform_name,pr.name as product_name,trsl.name AS result_status,trsl.class_name result_status_class,b.name AS branch_name,tg.name AS test_group_name, tr.locale_abbrev, u.email
|
||||
FROM test_results tr, testcases t, platforms p, opsyses o, branches b, products pr, test_result_status_lookup trsl, testgroups tg, subgroups sg, users u, testcase_subgroups tcsg, subgroup_testgroups sgtg
|
||||
WHERE tr.testcase_id=t.testcase_id AND tr.opsys_id=o.opsys_id AND o.platform_id=p.platform_id AND tr.branch_id=b.branch_id AND b.product_id=pr.product_id AND tr.result_status_id=trsl.result_status_id AND tcsg.testcase_id=tr.testcase_id AND tcsg.subgroup_id=sg.subgroup_id AND sg.subgroup_id=sgtg.subgroup_id AND sgtg.testgroup_id=tg.testgroup_id AND tr.user_id=u.user_id AND tr.valid=1
|
||||
ORDER BY tr.submission_time DESC, t.testcase_id DESC
|
||||
LIMIT $_num_results_default
|
||||
});
|
||||
|
||||
Litmus::DB::Testresult->set_sql(CommonResults => qq{
|
||||
SELECT COUNT(tr.testcase_id) AS num_results, tr.testcase_id, t.summary, MAX(tr.submission_time) AS most_recent, MAX(tr.testresult_id) AS max_id
|
||||
FROM test_results tr, testcases t, test_result_status_lookup trsl
|
||||
WHERE tr.testcase_id=t.testcase_id AND tr.result_status_id=trsl.result_status_id AND trsl.class_name=?
|
||||
GROUP BY tr.testcase_id
|
||||
ORDER BY num_results DESC, tr.testresult_id DESC
|
||||
LIMIT 15
|
||||
});
|
||||
|
||||
Litmus::DB::Testresult->set_sql(Completed => qq{
|
||||
SELECT tr.*
|
||||
FROM test_results tr, opsyses o
|
||||
WHERE tr.testcase_id=? AND
|
||||
tr.build_id=? AND
|
||||
tr.locale_abbrev=? AND
|
||||
tr.opsys_id=o.opsys_id AND
|
||||
o.platform_id=?
|
||||
ORDER BY tr.submission_time DESC
|
||||
});
|
||||
|
||||
Litmus::DB::Testresult->set_sql(CompletedByUser => qq{
|
||||
SELECT tr.*
|
||||
FROM test_results tr, opsyses o
|
||||
WHERE tr.testcase_id=? AND
|
||||
tr.build_id=? AND
|
||||
tr.locale_abbrev=? AND
|
||||
tr.opsys_id=o.opsys_id AND
|
||||
o.platform_id=? AND
|
||||
tr.user_id=?
|
||||
ORDER BY tr.submission_time DESC
|
||||
});
|
||||
|
||||
#########################################################################
|
||||
# for historical reasons, note() is a shorthand way of saying "the text of
|
||||
# the first comment on this result if that comment was submitted by the
|
||||
# result submitter"
|
||||
#########################################################################
|
||||
sub note {
|
||||
my $self = shift;
|
||||
|
||||
my @comments = $self->comments();
|
||||
|
||||
if (@comments && $comments[0] &&
|
||||
$comments[0]->user() == $self->user()) {
|
||||
return $comments[0]->comment();
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# is this test result from a trusted user?
|
||||
#########################################################################
|
||||
sub istrusted {
|
||||
my $self = shift;
|
||||
|
||||
if ($self->user()->istrusted()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# &getDefaultTestResults($)
|
||||
#
|
||||
#########################################################################
|
||||
sub getDefaultTestResults($) {
|
||||
my $self = shift;
|
||||
my @rows = $self->search_DefaultTestResults();
|
||||
my $criteria = "Default<br/>Ordered by Created<br/>Limit to $_num_results_default results";
|
||||
return $criteria, \@rows;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# &getTestResults($\@\@$)
|
||||
#
|
||||
#########################################################################
|
||||
sub getTestResults($\@\@$) {
|
||||
my ($self,$where_criteria,$order_by_criteria,$limit_value) = @_;
|
||||
|
||||
my $select = 'SELECT tr.testresult_id,tr.testcase_id,t.summary,tr.submission_time AS created,p.name AS platform_name,pr.name as product_name,trsl.name AS result_status,trsl.class_name AS result_status_class,b.name AS branch_name,tg.name AS test_group_name, tr.locale_abbrev, u.email';
|
||||
|
||||
my $from = 'FROM test_results tr, testcases t, platforms p, opsyses o, branches b, products pr, test_result_status_lookup trsl, testgroups tg, subgroups sg, users u, testcase_subgroups tcsg, subgroup_testgroups sgtg';
|
||||
|
||||
my $where = 'WHERE tr.testcase_id=t.testcase_id AND tr.opsys_id=o.opsys_id AND o.platform_id=p.platform_id AND tr.branch_id=b.branch_id AND b.product_id=pr.product_id AND tr.result_status_id=trsl.result_status_id AND tcsg.testcase_id=tr.testcase_id AND tcsg.subgroup_id=sg.subgroup_id AND sg.subgroup_id=sgtg.subgroup_id AND sgtg.testgroup_id=tg.testgroup_id AND tr.user_id=u.user_id AND tr.valid=1';
|
||||
|
||||
my $limit = 'LIMIT ';
|
||||
|
||||
foreach my $criterion (@$where_criteria) {
|
||||
$criterion->{'value'} =~ s/'/\'/g;
|
||||
if ($criterion->{'field'} eq 'branch') {
|
||||
$where .= " AND b.name='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'locale') {
|
||||
$where .= " AND tr.locale_abbrev='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'product') {
|
||||
$where .= " AND pr.name='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'platform') {
|
||||
$where .= " AND p.name='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'test_group') {
|
||||
$where .= " AND tg.name='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'testcase_id') {
|
||||
$where .= " AND tr.testcase_id='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'summary') {
|
||||
$where .= ' AND t.summary LIKE \'%%' . $criterion->{'value'} . '%%\'';
|
||||
} elsif ($criterion->{'field'} eq 'email') {
|
||||
$where .= ' AND u.email LIKE \'%%' . $criterion->{'value'} . '%%\'';
|
||||
} elsif ($criterion->{'field'} eq 'result_status') {
|
||||
$where .= " AND trsl.class_name='" . $criterion->{'value'} . "'";
|
||||
} elsif ($criterion->{'field'} eq 'trusted_only') {
|
||||
if ($from !~ /users u/) {
|
||||
$from .= ", users u";
|
||||
}
|
||||
$where .= " AND u.user_id=tr.user_id AND u.is_admin=1";
|
||||
} elsif ($criterion->{'field'} eq 'start_date') {
|
||||
my $start_timestamp = &Date::Manip::UnixDate(&Date::Manip::ParseDateString($criterion->{'value'}),"%q");
|
||||
if ($start_timestamp !~ /^\d\d\d\d\d\d\d\d\d\d\d\d\d\d$/) {
|
||||
print STDERR "Unable to parse a valid start date from '$criterion->{'value'},' ignoring.\n";
|
||||
} else {
|
||||
$where .= " AND tr.submission_time>=$start_timestamp";
|
||||
}
|
||||
} elsif ($criterion->{'field'} eq 'end_date') {
|
||||
my $end_timestamp = &Date::Manip::UnixDate(&Date::Manip::ParseDateString($criterion->{'value'}),"%q");
|
||||
if ($end_timestamp !~ /^\d\d\d\d\d\d\d\d\d\d\d\d\d\d$/) {
|
||||
print STDERR "Unable to parse a valid end date from '$criterion->{'value'},' ignoring.\n";
|
||||
} else {
|
||||
$where .= " AND tr.submission_time<=$end_timestamp";
|
||||
}
|
||||
} elsif ($criterion->{'field'} eq 'timespan') {
|
||||
next if ($criterion->{'value'} eq 'all');
|
||||
my $day_delta = $criterion->{'value'};
|
||||
my $err;
|
||||
my $timestamp =
|
||||
&Date::Manip::UnixDate(&Date::Manip::DateCalc("now",
|
||||
"$day_delta days",
|
||||
\$err),
|
||||
"%q");
|
||||
$where .= " AND tr.submission_time>=$timestamp";
|
||||
|
||||
} elsif ($criterion->{'field'} eq 'search_field') {
|
||||
($from,$where) = &_processSearchField($criterion,$from,$where);
|
||||
} else {
|
||||
# Skip unknown field
|
||||
}
|
||||
}
|
||||
|
||||
my $order_by = 'ORDER BY ';
|
||||
foreach my $criterion (@$order_by_criteria) {
|
||||
# Skip empty fields.
|
||||
next if (!$criterion or !$criterion->{'field'});
|
||||
|
||||
if ($criterion->{'field'} eq 'created') {
|
||||
$order_by .= "tr.submission_time $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'product') {
|
||||
$order_by .= "pr.name $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'platform') {
|
||||
$order_by .= "p.name $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'test_group') {
|
||||
$order_by .= "tg.name $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'testcase_id') {
|
||||
$order_by .= "tr.testcase_id $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'summary') {
|
||||
$order_by .= "t.summary $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'result_status') {
|
||||
$order_by .= "trsl.class_name $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'branch') {
|
||||
$order_by .= "b.name $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'locale') {
|
||||
$order_by .= "tr.locale_abbrev $criterion->{'direction'},";
|
||||
} elsif ($criterion->{'field'} eq 'email') {
|
||||
$order_by .= "u.email $criterion->{'direction'},";
|
||||
} else {
|
||||
# Skip unknown field
|
||||
}
|
||||
}
|
||||
if ($order_by eq 'ORDER BY ') {
|
||||
$order_by .= 'tr.submission_time DESC';
|
||||
} else {
|
||||
chop($order_by);
|
||||
}
|
||||
|
||||
if ($limit_value and $limit_value ne '') {
|
||||
$limit .= "$limit_value";
|
||||
} else {
|
||||
$limit .= "$_num_results_default";
|
||||
}
|
||||
|
||||
my $sql = "$select $from $where $order_by $limit";
|
||||
#print $sql,"<br/>\n";
|
||||
Litmus::DB::Testresult->set_sql(TestResults => qq{
|
||||
$sql
|
||||
});
|
||||
|
||||
my @rows = $self->search_TestResults();
|
||||
|
||||
return \@rows;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# &_processSearchField(\%\$\$)
|
||||
#
|
||||
#########################################################################
|
||||
sub _processSearchField(\%) {
|
||||
my ($search_field,$from,$where) = @_;
|
||||
|
||||
my $table_field = "";
|
||||
if ($search_field->{'search_field'} eq 'build_id') {
|
||||
$table_field='tr.build_id';
|
||||
} elsif ($search_field->{'search_field'} eq 'comments') {
|
||||
$table_field='c.comment';
|
||||
} elsif ($search_field->{'search_field'} eq 'locale') {
|
||||
$table_field='tr.locale_abbrev';
|
||||
} elsif ($search_field->{'search_field'} eq 'opsys') {
|
||||
$table_field='o.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'platform') {
|
||||
$table_field='p.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'product') {
|
||||
$table_field='pr.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'result_status') {
|
||||
$table_field='trsl.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'subgroup') {
|
||||
$table_field='sg.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'email') {
|
||||
if ($from !~ /users u/) {
|
||||
$from .= ", users u";
|
||||
$where .= " AND tr.user_id=u.user_id";
|
||||
}
|
||||
$table_field='u.email';
|
||||
} elsif ($search_field->{'search_field'} eq 'summary') {
|
||||
$table_field='t.summary';
|
||||
} elsif ($search_field->{'search_field'} eq 'test_group') {
|
||||
$table_field='tg.name';
|
||||
} elsif ($search_field->{'search_field'} eq 'user_agent') {
|
||||
$table_field='tr.user_agent';
|
||||
} else {
|
||||
return ($from,$where);
|
||||
}
|
||||
|
||||
if ($search_field->{'match_criteria'} eq 'contains_all' or
|
||||
$search_field->{'match_criteria'} eq 'contains_any' or
|
||||
$search_field->{'match_criteria'} eq 'not_contain_any') {
|
||||
|
||||
my $join = "";
|
||||
if ($search_field->{'match_criteria'} eq 'contains_all') {
|
||||
$join = 'AND';
|
||||
} else {
|
||||
$join = 'OR';
|
||||
}
|
||||
|
||||
my @words = split(/ /,$search_field->{'value'});
|
||||
if ($search_field->{'match_criteria'} eq 'not_contain_any') {
|
||||
$where .= " AND NOT (";
|
||||
} else {
|
||||
$where .= " AND (";
|
||||
}
|
||||
my $first_pass = 1;
|
||||
foreach my $word (@words) {
|
||||
if ( $first_pass ) {
|
||||
$where .= "UPPER($table_field) LIKE UPPER('%%" . $word . "%%')";
|
||||
$first_pass = 0;
|
||||
} else {
|
||||
$where .= " $join UPPER($table_field) LIKE UPPER('%%" . $word . "%%')";
|
||||
}
|
||||
}
|
||||
$where .= ")";
|
||||
} elsif ($search_field->{'match_criteria'} eq 'contains') {
|
||||
$where .= " AND UPPER($table_field) LIKE UPPER('%%" . $search_field->{'value'} . "%%')";
|
||||
} elsif ($search_field->{'match_criteria'} eq 'contains_case') {
|
||||
$where .= " AND $table_field LIKE '%%" . $search_field->{'value'} . "%%'";
|
||||
} elsif ($search_field->{'match_criteria'} eq 'not_contain') {
|
||||
$where .= " AND UPPER($table_field) NOT LIKE UPPER('%%" . $search_field->{'value'} . "%%')";
|
||||
} elsif ($search_field->{'match_criteria'} eq 'regexp') {
|
||||
$where .= " AND $table_field REGEXP '" . $search_field->{'value'} . "'";
|
||||
} elsif ($search_field->{'match_criteria'} eq 'not_regexp') {
|
||||
$where .= " AND $table_field NOT REGEXP '" . $search_field->{'value'} . "'";
|
||||
} else {
|
||||
# Ignore unknown match criteria.
|
||||
return ($from,$where);
|
||||
}
|
||||
|
||||
return ($from,$where);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
#########################################################################
|
||||
sub getCommonResults($$) {
|
||||
my ($self,$status,$limit_value) = @_;
|
||||
|
||||
if (!$status) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
if (!$limit_value) {
|
||||
$limit_value = $_num_results_default;
|
||||
}
|
||||
|
||||
my @rows = $self->search_CommonResults($status);
|
||||
return \@rows;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,119 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DB::User;
|
||||
|
||||
use strict;
|
||||
use Litmus::Config;
|
||||
use base 'Litmus::DBI';
|
||||
|
||||
Litmus::DB::User->table('users');
|
||||
|
||||
Litmus::DB::User->columns(All => qw/user_id bugzilla_uid email password realname irc_nickname enabled is_admin authtoken/);
|
||||
|
||||
Litmus::DB::User->column_alias("is_trusted", "istrusted");
|
||||
Litmus::DB::User->column_alias("is_admin", "is_trusted");
|
||||
|
||||
Litmus::DB::User->has_many(test_results => "Litmus::DB::Testresult");
|
||||
Litmus::DB::User->has_many(sessions => "Litmus::DB::Session");
|
||||
|
||||
# ZLL: only load BugzillaUser if Bugzilla Auth is actually enabled
|
||||
if ($Litmus::Config::bugzilla_auth_enabled) {
|
||||
Litmus::DB::User->has_a(bugzilla_uid => "Litmus::DB::BugzillaUser");
|
||||
}
|
||||
|
||||
__PACKAGE__->set_sql(RetrieveAll => qq{
|
||||
SELECT __ESSENTIAL__
|
||||
FROM __TABLE__
|
||||
ORDER BY email ASC
|
||||
});
|
||||
|
||||
__PACKAGE__->set_sql(TopTesters => qq{
|
||||
SELECT users.user_id, users.email, count(*) AS num_results
|
||||
FROM users, test_results
|
||||
WHERE users.user_id=test_results.user_id
|
||||
GROUP BY user_id
|
||||
ORDER BY num_results DESC
|
||||
LIMIT 15
|
||||
});
|
||||
|
||||
# the COLLATE latin1_general_ci sillyness forces a case-insensitive match
|
||||
# removed a LIMIT 300 to work around a mysql bug in the ancient version
|
||||
# on rodan
|
||||
__PACKAGE__->set_sql(FullTextMatches => q{
|
||||
SELECT *
|
||||
FROM __TABLE__
|
||||
WHERE
|
||||
email COLLATE latin1_general_ci like concat('%%',?,'%%') OR
|
||||
irc_nickname COLLATE latin1_general_ci like concat('%%',?,'%%') OR
|
||||
realname COLLATE latin1_general_ci like concat('%%',?,'%%')
|
||||
ORDER BY email ASC
|
||||
});
|
||||
|
||||
|
||||
|
||||
#########################################################################
|
||||
# returns the crypt'd password from a linked Bugzilla account if it
|
||||
# exists or the Litmus user account
|
||||
sub getRealPasswd {
|
||||
my $self = shift;
|
||||
if ($self->bugzilla_uid()) {
|
||||
return $self->bugzilla_uid()->cryptpassword();
|
||||
} else {
|
||||
return $self->password();
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getDisplayName() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->irc_nickname if ($self->irc_nickname and
|
||||
$self->irc_nickname ne '');
|
||||
return $self->realname if ($self->realname and
|
||||
$self->realname ne '');
|
||||
|
||||
if ($self->email and
|
||||
$self->email ne '') {
|
||||
my $display_name = $self->email;
|
||||
$display_name =~ s/\@.*$//g;
|
||||
return $display_name
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::DBI;
|
||||
|
||||
require Apache::DBI;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Litmus::Config;
|
||||
use Memoize;
|
||||
|
||||
use base 'Class::DBI::mysql';
|
||||
|
||||
our $dsn = "dbi:mysql:database=$Litmus::Config::db_name;host=$Litmus::Config::db_host;port=3306";
|
||||
|
||||
|
||||
|
||||
our %column_aliases;
|
||||
|
||||
Litmus::DBI->connection( $dsn,
|
||||
$Litmus::Config::db_user,
|
||||
$Litmus::Config::db_pass,
|
||||
{AutoCommit=>1}
|
||||
);
|
||||
Litmus::DBI->autoupdate(1);
|
||||
|
||||
# In some cases, we have column names that make sense from a database perspective
|
||||
# (i.e. subgroup_id), but that don't make sense from a class/object perspective
|
||||
# (where subgroup would be more appropriate). To handle this, we allow for
|
||||
# Litmus::DBI's subclasses to set column aliases with the column_alias() sub.
|
||||
# Takes the database column name and the alias name.
|
||||
sub column_alias {
|
||||
my ($self, $db_name, $alias_name) = @_;
|
||||
|
||||
$column_aliases{$alias_name} = $db_name;
|
||||
}
|
||||
|
||||
# here's where the actual work happens. We consult our alias list
|
||||
# (as created by calls to column_alias()) and substitute the
|
||||
# database column if we find a match
|
||||
memoize('find_column');
|
||||
sub find_column {
|
||||
my $self = shift;
|
||||
my $wanted = shift;
|
||||
|
||||
if (ref $self) {
|
||||
$wanted =~ s/^.*::(\w+)$/$1/;
|
||||
}
|
||||
if ($column_aliases{$wanted}) {
|
||||
return $column_aliases{$wanted};
|
||||
} else {
|
||||
# not an alias, so we use the normal
|
||||
# find_column() from Class::DBI
|
||||
$self->SUPER::find_column($wanted);
|
||||
}
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
my $name = our $AUTOLOAD;
|
||||
|
||||
my $col = $self->find_column($name);
|
||||
if (!$col) {
|
||||
internalError("tried to call Litmus::DBI method $name which does not exist");
|
||||
}
|
||||
|
||||
return $self->$col(@args);
|
||||
}
|
||||
|
||||
sub _croak {
|
||||
my ($self, $message, %info) = @_;
|
||||
internalError($message);
|
||||
return;
|
||||
}
|
||||
|
||||
# Get Class::DBI's default dbh options
|
||||
my $db_options = { __PACKAGE__->_default_attributes };
|
||||
|
||||
__PACKAGE__->_remember_handle('Main'); # so dbi_commit works
|
||||
|
||||
# override default to avoid using Ima::DBI closure
|
||||
sub db_Main {
|
||||
my $dbh;
|
||||
if ( $ENV{'MOD_PERL'} and !$Apache::ServerStarting ) {
|
||||
$dbh = Apache->request()->pnotes('dbh');
|
||||
}
|
||||
if ( !$dbh ) {
|
||||
$dbh = DBI->connect(
|
||||
$dsn, $Litmus::Config::db_user,
|
||||
$Litmus::Config::db_pass, $db_options
|
||||
);
|
||||
if ( $ENV{'MOD_PERL'} and !$Apache::ServerStarting ) {
|
||||
Apache->request()->pnotes( 'dbh', $dbh );
|
||||
}
|
||||
}
|
||||
return $dbh;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
|
||||
# Utility functions (based on those from Bugzilla's checksetup.pl to
|
||||
# create new fields and indicies to the schema when upgrading an installation.
|
||||
|
||||
package Litmus::DBTools;
|
||||
|
||||
use strict;
|
||||
|
||||
#########################################################################
|
||||
sub new {
|
||||
my ($class, $dbh) = @_;
|
||||
my $self = {};
|
||||
$self->{'dbh'} = $dbh;
|
||||
bless($self);
|
||||
return $self;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub ChangeFieldType {
|
||||
my ($self, $table, $field, $newtype) = @_;
|
||||
|
||||
my $ref = $self->GetFieldDef($table, $field);
|
||||
#print "0: $$ref[0] 1: $$ref[1] 2: $$ref[2] 3: $$ref[3] 4: $$ref[4]\n";
|
||||
|
||||
my $oldtype = $ref->[1];
|
||||
if (! $ref->[2]) {
|
||||
$oldtype .= qq{ not null};
|
||||
}
|
||||
if ($ref->[4]) {
|
||||
$oldtype .= qq{ default "$ref->[4]"};
|
||||
}
|
||||
|
||||
if ($oldtype ne $newtype) {
|
||||
print "Updating field type $field in table $table ...\n";
|
||||
print "old: $oldtype\n";
|
||||
print "new: $newtype\n";
|
||||
# 'not null' should be passed as part of the call to ChangeFieldType()
|
||||
# $newtype .= " NOT NULL" if $$ref[3];
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
CHANGE $field
|
||||
$field $newtype");
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub RenameTable {
|
||||
my ($self, $table, $newname) = @_;
|
||||
|
||||
my $ref = $self->TableExists($table);
|
||||
return unless $ref; # already renamed?
|
||||
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
RENAME TO $newname");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub RenameField {
|
||||
my ($self, $table, $field, $newname) = @_;
|
||||
|
||||
my $ref = $self->GetFieldDef($table, $field);
|
||||
return unless $ref; # already fixed?
|
||||
#print "0: $$ref[0] 1: $$ref[1] 2: $$ref[2] 3: $$ref[3] 4: $$ref[4]\n";
|
||||
|
||||
if ($$ref[1] ne $newname) {
|
||||
print "Updating field $field in table $table ...\n";
|
||||
my $type = $$ref[1];
|
||||
$type .= " NOT NULL" if !$$ref[2];
|
||||
$type .= " auto_increment" if $$ref[5] =~ /auto_increment/;
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
CHANGE $field
|
||||
$newname $type");
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub AddField {
|
||||
my ($self, $table, $field, $definition) = @_;
|
||||
|
||||
my $ref = $self->GetFieldDef($table, $field);
|
||||
return if $ref; # already added?
|
||||
|
||||
print "Adding new field $field to table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
ADD COLUMN $field $definition");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub AddKey {
|
||||
my ($self, $table, $field, $definition) = @_;
|
||||
|
||||
my $ref = $self->GetIndexDef($table, $field);
|
||||
return if $ref; # already added?
|
||||
|
||||
print "Adding new key $field to table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
ADD KEY $field $definition");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub AddUniqueKey {
|
||||
my ($self, $table, $field, $definition) = @_;
|
||||
|
||||
my $ref = $self->GetIndexDef($table, $field);
|
||||
return if $ref; # already added?
|
||||
|
||||
print "Adding new key $field to table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
ADD UNIQUE KEY $field $definition");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub AddFullText {
|
||||
my ($self, $table, $index, $definition) = @_;
|
||||
|
||||
my $ref = $self->GetIndexDef($table, $index);
|
||||
return if $ref; # already added?
|
||||
|
||||
print "Adding new fulltext $index to table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
ADD FULLTEXT $index $definition");
|
||||
}
|
||||
|
||||
|
||||
#########################################################################
|
||||
sub DropField {
|
||||
my ($self, $table, $field) = @_;
|
||||
|
||||
my $ref = $self->GetFieldDef($table, $field);
|
||||
return unless $ref; # already dropped?
|
||||
|
||||
print "Deleting unused field $field from table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
DROP COLUMN $field");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub DropTable {
|
||||
my ($self, $table, $field) = @_;
|
||||
|
||||
my $ref = $self->TableExists($table);
|
||||
return unless $ref; # already dropped?
|
||||
|
||||
print "Deleting unused table $table ...\n";
|
||||
$self->{'dbh'}->do("DROP TABLE $table");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
# this uses a mysql specific command.
|
||||
sub TableExists {
|
||||
my ($self, $table) = @_;
|
||||
my @tables;
|
||||
my $dbtable;
|
||||
my $exists = 0;
|
||||
my $sth = $self->{'dbh'}->prepare("SHOW TABLES");
|
||||
$sth->execute;
|
||||
while ( ($dbtable) = $sth->fetchrow_array ) {
|
||||
if ($dbtable eq $table) {
|
||||
$exists = 1;
|
||||
}
|
||||
}
|
||||
$sth->finish;
|
||||
return $exists;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub GetFieldDef {
|
||||
my ($self, $table, $field) = @_;
|
||||
my $sth = $self->{'dbh'}->prepare("SHOW COLUMNS FROM $table");
|
||||
$sth->execute;
|
||||
|
||||
while (my $ref = $sth->fetchrow_arrayref) {
|
||||
next if $$ref[0] ne $field;
|
||||
$sth->finish;
|
||||
return $ref;
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub GetIndexDef {
|
||||
my ($self, $table, $field) = @_;
|
||||
my $sth = $self->{'dbh'}->prepare("SHOW INDEX FROM $table");
|
||||
$sth->execute;
|
||||
|
||||
while (my $ref = $sth->fetchrow_arrayref) {
|
||||
next if $$ref[2] ne $field;
|
||||
$sth->finish;
|
||||
return $ref;
|
||||
}
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub CountIndexes {
|
||||
my ($self, $table) = @_;
|
||||
|
||||
my $sth = $self->{'dbh'}->prepare("SHOW INDEX FROM $table");
|
||||
$sth->execute;
|
||||
|
||||
if ( $sth->rows == -1 ) {
|
||||
$sth->finish;
|
||||
die ("Unexpected response while counting indexes in $table:" .
|
||||
" \$sth->rows == -1");
|
||||
}
|
||||
|
||||
my $rows = $sth->rows;
|
||||
$sth->finish;
|
||||
return ($rows);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub DropIndex {
|
||||
my ($self, $table, $index) = @_;
|
||||
|
||||
my $ref = $self->GetIndexDef($table, $index);
|
||||
return unless $ref; # no matching index?
|
||||
|
||||
print "Removing index $index from table $table ...\n";
|
||||
$self->{'dbh'}->do("ALTER TABLE $table
|
||||
DROP INDEX $index");
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub DropIndexes {
|
||||
my ($self, $table) = @_;
|
||||
my %SEEN;
|
||||
|
||||
# get the list of indexes
|
||||
#
|
||||
my $sth = $self->{'dbh'}->prepare("SHOW INDEX FROM $table");
|
||||
$sth->execute;
|
||||
|
||||
# drop each index
|
||||
#
|
||||
while ( my $ref = $sth->fetchrow_arrayref) {
|
||||
|
||||
# note that some indexes are described by multiple rows in the
|
||||
# index table, so we may have already dropped the index described
|
||||
# in the current row.
|
||||
#
|
||||
next if exists $SEEN{$$ref[2]};
|
||||
|
||||
if ($$ref[2] eq 'PRIMARY') {
|
||||
# The syntax for dropping a PRIMARY KEY is different
|
||||
# from the normal DROP INDEX syntax.
|
||||
$self->{'dbh'}->do("ALTER TABLE $table DROP PRIMARY KEY");
|
||||
}
|
||||
else {
|
||||
$self->{'dbh'}->do("ALTER TABLE $table DROP INDEX $$ref[2]");
|
||||
}
|
||||
$SEEN{$$ref[2]} = 1;
|
||||
|
||||
}
|
||||
$sth->finish;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,84 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
# General error reporting
|
||||
|
||||
package Litmus::Error;
|
||||
|
||||
use strict;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
@Litmus::Error::EXPORT = qw(
|
||||
basicError
|
||||
invalidInputError
|
||||
internalError
|
||||
lastDitchError
|
||||
);
|
||||
|
||||
# just a general run of the mill error
|
||||
sub basicError {
|
||||
my $message = shift;
|
||||
_doError($message);
|
||||
exit;
|
||||
}
|
||||
|
||||
# used to alert the user when an unexpected input value is found
|
||||
sub invalidInputError($) {
|
||||
my $message = shift;
|
||||
_doError("Invalid Input - $message");
|
||||
exit;
|
||||
}
|
||||
|
||||
sub internalError($) {
|
||||
my $message = shift;
|
||||
_doError("Litmus has suffered an internal error - $message");
|
||||
exit;
|
||||
}
|
||||
|
||||
# an error type that does not use a template error message. Used if we
|
||||
# can't even process the error template.
|
||||
sub lastDitchError($) {
|
||||
my $message = shift;
|
||||
print "Error - Litmus has suffered a serious fatal internal error - $message";
|
||||
exit;
|
||||
}
|
||||
|
||||
sub _doError($) {
|
||||
my $message = shift;
|
||||
my $vars = {
|
||||
message => $message,
|
||||
};
|
||||
Litmus->template()->process("error/error.html.tmpl", $vars) ||
|
||||
lastDitchError(Litmus->template()->error());
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,342 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::FormWidget;
|
||||
use strict;
|
||||
|
||||
BEGIN {
|
||||
use Exporter ();
|
||||
use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
|
||||
$VERSION = 0.01;
|
||||
@ISA = qw (Exporter);
|
||||
#Give a hoot don't pollute, do not export more than needed by default
|
||||
@EXPORT = qw ( getProducts );
|
||||
@EXPORT_OK = qw ();
|
||||
%EXPORT_TAGS = ();
|
||||
}
|
||||
|
||||
use DBI;
|
||||
use Litmus::DBI;
|
||||
|
||||
our $_dbh = Litmus::DBI->db_Main();
|
||||
|
||||
#########################################################################
|
||||
=head1 NAME
|
||||
|
||||
Litmus::FormWidget - Create value lists to be used in HTML forms
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Litmus::FormWidget
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Litmus::FormWidget creates value lists to be used in HTML forms.
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Chris Cooper
|
||||
CPAN ID: CCOOPER
|
||||
Mozilla Corporation
|
||||
ccooper@deadsquid.com
|
||||
http://litmus.mozilla.org/
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
perl(1).
|
||||
|
||||
=cut
|
||||
|
||||
#########################################################################
|
||||
|
||||
#sub new
|
||||
#{
|
||||
# my ($class, %parameters) = @_;
|
||||
# my $self = bless ({}, ref ($class) || $class);
|
||||
# return ($self);
|
||||
#}
|
||||
|
||||
#########################################################################
|
||||
|
||||
=head2 getProducts
|
||||
|
||||
Usage : How to use this function/method
|
||||
Purpose : What it does
|
||||
Returns : What it returns
|
||||
Argument : What it wants to know
|
||||
Throws : Exceptions and other anomolies
|
||||
Comments : This is a sample subroutine header.
|
||||
: It is polite to include more pod and fewer comments.
|
||||
|
||||
See Also :
|
||||
|
||||
=cut
|
||||
|
||||
#########################################################################
|
||||
sub getProducts()
|
||||
{
|
||||
my $sql = "SELECT name, product_id FROM products ORDER BY name";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getUniquePlatforms()
|
||||
{
|
||||
my $sql = "SELECT DISTINCT(name), platform_id FROM platforms ORDER BY name";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getPlatforms()
|
||||
{
|
||||
my $sql = "SELECT platform_id, name from platforms ORDER BY name ASC";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getBranches()
|
||||
{
|
||||
my $sql = "SELECT name, branch_id FROM branches ORDER BY name ASC";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getUniqueBranches()
|
||||
{
|
||||
my $sql = "SELECT DISTINCT(name) FROM branches ORDER BY name ASC";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getOpsyses()
|
||||
{
|
||||
my $sql = "SELECT name, opsys_id FROM opsyses ORDER BY name ASC";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getUniqueOpsyses()
|
||||
{
|
||||
my $sql = "SELECT DISTINCT(name) FROM opsyses ORDER BY name ASC";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getLogTypes()
|
||||
{
|
||||
my $sql = "SELECT DISTINCT(name) FROM log_type_lookup ORDER BY name";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getTestStatuses()
|
||||
{
|
||||
my @TestStatuses = ({name => 'Enabled'},
|
||||
{name => 'Disabled'});
|
||||
return \@TestStatuses;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getResultStatuses()
|
||||
{
|
||||
my $sql = "SELECT result_status_id,class_name FROM test_result_status_lookup ORDER BY result_status_id";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getTestcaseIDs()
|
||||
{
|
||||
my $sql = "SELECT testcase_id FROM testcases ORDER BY testcase_id";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getTestcases()
|
||||
{
|
||||
my $sql = "SELECT testcase_id, summary, product_id FROM testcases ORDER BY testcase_id";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getSubgroups()
|
||||
{
|
||||
my $sql = "SELECT subgroup_id, name, product_id FROM subgroups ORDER BY name, subgroup_id";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getTestgroups()
|
||||
{
|
||||
my $sql = "SELECT testgroup_id, name, product_id FROM testgroups ORDER BY name, testgroup_id";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
|
||||
#########################################################################
|
||||
sub getLocales()
|
||||
{
|
||||
my @locales = Litmus::DB::Locale->retrieve_all();
|
||||
return \@locales;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getUsers()
|
||||
{
|
||||
my @users = Litmus::DB::User->retrieve_all();
|
||||
return \@users;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getAuthors()
|
||||
{
|
||||
my $sql = "SELECT user_id, email FROM users WHERE is_admin=1 ORDER BY email";
|
||||
return _getValues($sql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#########################################################################
|
||||
sub getFields()
|
||||
{
|
||||
my @fields = (
|
||||
{ name => 'build_id',
|
||||
display_string => "Build ID", },
|
||||
{ name => 'comment',
|
||||
display_string => "Comments", },
|
||||
{ name => 'locale',
|
||||
display_string => "Locale", },
|
||||
{ name => 'opsys',
|
||||
display_string => "Operating System", },
|
||||
{ name => 'platform',
|
||||
display_string => "Platform", },
|
||||
{ name => 'product',
|
||||
display_string => "Product", },
|
||||
{ name => 'result_status',
|
||||
display_string => "Result Status", },
|
||||
{ name => 'subgroup',
|
||||
display_string => "Subgroup", },
|
||||
{ name => 'email',
|
||||
display_string => "Submitted By", },
|
||||
{ name => 'summary',
|
||||
display_string => "Summary", },
|
||||
{ name => 'testgroup',
|
||||
display_string => "Testgroup", },
|
||||
{ name => 'user_agent',
|
||||
display_string => "User Agent", },
|
||||
);
|
||||
return \@fields;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getMatchCriteria()
|
||||
{
|
||||
my @match_criteria = (
|
||||
{ name => "contains_all",
|
||||
display_string => "contains all of the words/strings" },
|
||||
{ name => "contains_any",
|
||||
display_string => "contains any of the words/strings" },
|
||||
{ name => "contains",
|
||||
display_string => "contains the word/string" },
|
||||
{ name => "contains_case",
|
||||
display_string => "contains the word/string (exact case)" },
|
||||
{ name => "not_contain",
|
||||
display_string => "does not contains the word/string" },
|
||||
{ name => "not_contain_any",
|
||||
display_string => "does not contains any of the words/string" },
|
||||
{ name => "regexp",
|
||||
display_string => "matches the regexp" },
|
||||
{ name => "not_regexp",
|
||||
display_string => "does not match the regexp" },
|
||||
);
|
||||
return \@match_criteria;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub getSortFields()
|
||||
{
|
||||
my @sort_fields = (
|
||||
{ name => "branch",
|
||||
display_string => "Branch"},
|
||||
{ name => "created",
|
||||
display_string => "Date"},
|
||||
{ name => "locale",
|
||||
display_string => "Locale"},
|
||||
{ name => "platform",
|
||||
display_string => "Platform"},
|
||||
{ name => "product",
|
||||
display_string => "Product"},
|
||||
{ name => "email",
|
||||
display_string => "Submitted By"},
|
||||
{ name => "summary",
|
||||
display_string => "Summary"},
|
||||
{ name => "result_status",
|
||||
display_string => "Status"},
|
||||
{ name => "testcase_id",
|
||||
display_string => "Testcase ID#"},
|
||||
{ name => "testgroup",
|
||||
display_string => "Testgroup"},
|
||||
);
|
||||
return \@sort_fields;
|
||||
}
|
||||
|
||||
#########################################################################
|
||||
sub _getValues($)
|
||||
{
|
||||
my ($sql) = @_;
|
||||
my $sth = $_dbh->prepare_cached($sql);
|
||||
$sth->execute();
|
||||
my @rows;
|
||||
while (my $data = $sth->fetchrow_hashref) {
|
||||
push @rows, $data;
|
||||
}
|
||||
return \@rows;
|
||||
$sth->finish();
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::StripScripts;
|
||||
use base qw(HTML::StripScripts::Parser);
|
||||
|
||||
# Override broken href validation code.
|
||||
sub validate_href_attribute {
|
||||
my ($self, $text) = @_;
|
||||
|
||||
$self->SUPER::validate_href_attribute or $text =~ m<^((https?|ftp|mailto)://[\w\-\.]{1,100}(?:\:\d{1,5})?(?:/(?:[\w\-.!~*|;:/?=+\$\,%#]|&){0,100})?)$>x ? $1 : undef;
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,263 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::SysConfig;
|
||||
|
||||
use strict;
|
||||
|
||||
require Exporter;
|
||||
use Litmus;
|
||||
use Litmus::DB::Locale;
|
||||
use Litmus::DB::Product;
|
||||
use Litmus::Error;
|
||||
use Litmus::Utils;
|
||||
use CGI;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw();
|
||||
|
||||
my $configcookiename = $Litmus::Config::sysconfig_cookiename;
|
||||
|
||||
sub new {
|
||||
my ($class, $product, $platform, $opsys, $branch, $build_id, $locale) = @_;
|
||||
|
||||
my $self = {};
|
||||
bless($self);
|
||||
|
||||
$self->{"product"} = $product;
|
||||
$self->{"platform"} = $platform;
|
||||
$self->{"opsys"} = $opsys;
|
||||
$self->{"branch"} = $branch;
|
||||
$self->{"build_id"} = $build_id;
|
||||
$self->{"locale"} = $locale;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub setCookie {
|
||||
my $self = shift;
|
||||
|
||||
my %cookiedata;
|
||||
|
||||
my $c = Litmus->cgi();
|
||||
my $cookie = $c->cookie(
|
||||
-name => $configcookiename.'_'.$self->{"product"}->product_id(),
|
||||
-value => join('|', $self->{"product"}->product_id(), $self->{"platform"}->platform_id(),
|
||||
$self->{"opsys"}->opsys_id(), $self->{"branch"}->branch_id(), $self->{"build_id"}, $self->{"locale"}->abbrev()),
|
||||
-domain => $main::ENV{"HTTP_HOST"},
|
||||
);
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
sub getCookie {
|
||||
my $self = shift;
|
||||
my $c = Litmus->cgi();
|
||||
my $product = shift;
|
||||
|
||||
return Litmus::SysConfig->
|
||||
realGetCookie($configcookiename.'_'.$product->product_id());
|
||||
|
||||
}
|
||||
|
||||
# returns sysconfig objects corresponding to all sysconfig cookies the user
|
||||
# has set
|
||||
sub getAllCookies {
|
||||
my $self = shift;
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
my @cookies = ();
|
||||
my @names = $c->cookie();
|
||||
foreach my $cur (@names) {
|
||||
if ($cur =~ /^\Q$configcookiename\E_/) {
|
||||
push(@cookies, Litmus::SysConfig->realGetCookie($cur));
|
||||
}
|
||||
}
|
||||
if (@cookies == 0) { push(@cookies, undef) }
|
||||
return @cookies;
|
||||
}
|
||||
|
||||
sub realGetCookie {
|
||||
my $self = shift;
|
||||
my $cookiename = shift;
|
||||
|
||||
my $c = Litmus->cgi();
|
||||
my $cookie = $c->cookie($cookiename);
|
||||
if (! $cookie) {
|
||||
return;
|
||||
}
|
||||
|
||||
my @sysconfig = split(/\|/, $cookie);
|
||||
|
||||
return new(undef,
|
||||
Litmus::DB::Product->retrieve($sysconfig[0]),
|
||||
Litmus::DB::Platform->retrieve($sysconfig[1]),
|
||||
Litmus::DB::Opsys->retrieve($sysconfig[2]),
|
||||
Litmus::DB::Branch->retrieve($sysconfig[3]),
|
||||
$sysconfig[4],
|
||||
Litmus::DB::Locale->retrieve($sysconfig[5])
|
||||
);
|
||||
}
|
||||
|
||||
sub product() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"product"};
|
||||
}
|
||||
|
||||
sub platform() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"platform"};
|
||||
}
|
||||
|
||||
sub opsys() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"opsys"};
|
||||
}
|
||||
|
||||
sub branch() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"branch"};
|
||||
}
|
||||
|
||||
sub build_id() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"build_id"};
|
||||
}
|
||||
|
||||
sub locale() {
|
||||
my $self = shift;
|
||||
|
||||
return $self->{"locale"};
|
||||
}
|
||||
|
||||
|
||||
# display the system configuration form
|
||||
# optionally takes the product to configure for
|
||||
# and requires a url to load when done. this
|
||||
# url should call processForm() to
|
||||
# set the sysconfig cookie and do
|
||||
# error handling.
|
||||
# optionaly, pass a CGI object and its
|
||||
# data will be stored in the form so
|
||||
# the receiving script can access it.
|
||||
sub displayForm {
|
||||
my $self = shift;
|
||||
my $product = shift;
|
||||
my $goto = shift;
|
||||
my $c = shift;
|
||||
|
||||
my @products;
|
||||
# if we already know the product, then just send it on:
|
||||
if ($product) {
|
||||
$products[0] = $product;
|
||||
} else {
|
||||
# we need to ask the user for the product then
|
||||
@products = Litmus::DB::Product->retrieve_all();
|
||||
}
|
||||
|
||||
my @locales = Litmus::DB::Locale->retrieve_all(
|
||||
{ order_by => 'abbrev' }
|
||||
);
|
||||
my $vars = {
|
||||
locales => \@locales,
|
||||
products => \@products,
|
||||
ua => Litmus::UserAgentDetect->new(),
|
||||
"goto" => $goto,
|
||||
cgidata => $c,
|
||||
};
|
||||
|
||||
# if the user already has a cookie set for this product, then
|
||||
# load those values as defaults:
|
||||
if ($product && Litmus::SysConfig->getCookie($product)) {
|
||||
my $sysconfig = Litmus::SysConfig->getCookie($product);
|
||||
$vars->{"defaultplatform"} = $sysconfig->platform();
|
||||
$vars->{"defaultopsys"} = $sysconfig->opsys();
|
||||
$vars->{"defaultbranch"} = $sysconfig->branch();
|
||||
$vars->{"defaultlocale"} = $sysconfig->locale();
|
||||
}
|
||||
|
||||
# send a default build id if we have one:
|
||||
my @cookies = Litmus::SysConfig->getAllCookies();
|
||||
if ($cookies[0]) { $vars->{"defaultbuildid"} = $cookies[0]->build_id() }
|
||||
|
||||
my $cookie = Litmus::Auth::getCurrentUser();
|
||||
$vars->{"defaultemail"} = $cookie;
|
||||
$vars->{"show_admin"} = Litmus::Auth::istrusted($cookie);
|
||||
|
||||
$vars->{"title"} = "Run Tests";
|
||||
|
||||
Litmus->template()->process("runtests/sysconfig.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
}
|
||||
|
||||
# process a form containing sysconfig information.
|
||||
# takes a CGI object containing param data
|
||||
sub processForm {
|
||||
my $self = shift;
|
||||
my $c = shift;
|
||||
|
||||
my $product = Litmus::DB::Product->retrieve($c->param("product"));
|
||||
my $platform = Litmus::DB::Platform->retrieve($c->param("platform"));
|
||||
my $opsys = Litmus::DB::Opsys->retrieve($c->param("opsys"));
|
||||
my $branch = Litmus::DB::Branch->retrieve($c->param("branch"));
|
||||
my $build_id = $c->param("build_id");
|
||||
my $locale = Litmus::DB::Locale->retrieve($c->param("locale"));
|
||||
|
||||
requireField("product", $product);
|
||||
requireField("platform", $platform);
|
||||
requireField("opsys", $opsys);
|
||||
requireField("branch", $branch);
|
||||
requireField("build_id", $build_id);
|
||||
requireField("locale", $locale);
|
||||
|
||||
# set a cookie with the user's testing details:
|
||||
my $prod = Litmus::DB::Product->retrieve($c->param("product"));
|
||||
my $sysconfig = Litmus::SysConfig->new(
|
||||
$product,
|
||||
$platform,
|
||||
$opsys,
|
||||
$branch,
|
||||
$build_id,
|
||||
$locale
|
||||
);
|
||||
|
||||
return $sysconfig;
|
||||
}
|
||||
1;
|
||||
|
||||
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
||||
# Dan Mosedale <dmose@mozilla.org>
|
||||
# Jacob Steenhagen <jake@bugzilla.org>
|
||||
# Bradley Baetz <bbaetz@student.usyd.edu.au>
|
||||
# Christopher Aillon <christopher@aillon.com>
|
||||
# Tobias Burnus <burnus@net-b.de>
|
||||
# Myk Melez <myk@mozilla.org>
|
||||
# Max Kanat-Alexander <mkanat@bugzilla.org>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
# This is mostly a placeholder. At some point in the future, we might
|
||||
# want to be more like Bugzilla and support multiple languages and
|
||||
# other fine features, so we keep this around now so that adding new
|
||||
# things later won't require changing every source file.
|
||||
|
||||
package Litmus::Template;
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus::Config;
|
||||
use Litmus::StripScripts;
|
||||
use Text::Markdown;
|
||||
|
||||
use base qw(Template);
|
||||
|
||||
my $template_include_path;
|
||||
|
||||
$Template::Directive::WHILE_MAX = 30000;
|
||||
|
||||
# Returns the path to the templates based on the Accept-Language
|
||||
# settings of the user and of the available languages
|
||||
# If no Accept-Language is present it uses the defined default
|
||||
sub getTemplateIncludePath () {
|
||||
return "templates/en/default";
|
||||
}
|
||||
|
||||
# Constants:
|
||||
my %constants = {};
|
||||
$constants{litmus_version} = $Litmus::Config::version;
|
||||
|
||||
# html tag stripper:
|
||||
my $strip = Litmus::StripScripts->new(
|
||||
{
|
||||
AllowHref => 1,
|
||||
AllowSrc => 1,
|
||||
Context => 'Document'
|
||||
},
|
||||
strict_names => 1,
|
||||
);
|
||||
|
||||
###############################################################################
|
||||
# Templatization Code
|
||||
|
||||
# Use the Toolkit Template's Stash module to add utility pseudo-methods
|
||||
# to template variables.
|
||||
use Template::Stash;
|
||||
|
||||
# Add "contains***" methods to list variables that search for one or more
|
||||
# items in a list and return boolean values representing whether or not
|
||||
# one/all/any item(s) were found.
|
||||
$Template::Stash::LIST_OPS->{ contains } =
|
||||
sub {
|
||||
my ($list, $item) = @_;
|
||||
return grep($_ eq $item, @$list);
|
||||
};
|
||||
|
||||
$Template::Stash::LIST_OPS->{ containsany } =
|
||||
sub {
|
||||
my ($list, $items) = @_;
|
||||
foreach my $item (@$items) {
|
||||
return 1 if grep($_ eq $item, @$list);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
# Allow us to still get the scalar if we use the list operation ".0" on it
|
||||
$Template::Stash::SCALAR_OPS->{ 0 } =
|
||||
sub {
|
||||
return $_[0];
|
||||
};
|
||||
|
||||
# Add a "substr" method to the Template Toolkit's "scalar" object
|
||||
# that returns a substring of a string.
|
||||
$Template::Stash::SCALAR_OPS->{ substr } =
|
||||
sub {
|
||||
my ($scalar, $offset, $length) = @_;
|
||||
return substr($scalar, $offset, $length);
|
||||
};
|
||||
|
||||
# Add a "truncate" method to the Template Toolkit's "scalar" object
|
||||
# that truncates a string to a certain length.
|
||||
$Template::Stash::SCALAR_OPS->{ truncate } =
|
||||
sub {
|
||||
my ($string, $length, $ellipsis) = @_;
|
||||
$ellipsis ||= "";
|
||||
|
||||
return $string if !$length || length($string) <= $length;
|
||||
|
||||
my $strlen = $length - length($ellipsis);
|
||||
my $newstr = substr($string, 0, $strlen) . $ellipsis;
|
||||
return $newstr;
|
||||
};
|
||||
|
||||
# Create the template object that processes templates and specify
|
||||
# configuration parameters that apply to all templates.
|
||||
sub create {
|
||||
my $class = shift;
|
||||
return $class->new({
|
||||
INCLUDE_PATH => &getTemplateIncludePath,
|
||||
CONSTANTS => \%constants,
|
||||
PRE_PROCESS => "variables.none.tmpl",
|
||||
POST_CHOMP => 1,
|
||||
EVAL_PERL => 1,
|
||||
|
||||
COMPILE_DIR => $Litmus::Config::datadir,
|
||||
|
||||
FILTERS => {
|
||||
# disallow all html in testcase data except for non-evil tags
|
||||
testdata => sub {
|
||||
my ($data) = @_;
|
||||
|
||||
$strip->parse($data);
|
||||
$strip->eof();
|
||||
|
||||
return $strip->filtered_document;
|
||||
},
|
||||
|
||||
# process the text with the markdown text processor
|
||||
markdown => sub {
|
||||
my ($data) = @_;
|
||||
$data = Text::Markdown::markdown($data);
|
||||
return $data;
|
||||
},
|
||||
|
||||
# Returns the text with backslashes, single/double quotes,
|
||||
# and newlines/carriage returns escaped for use in JS strings.
|
||||
# thanks to bugzilla!
|
||||
js => sub {
|
||||
my ($var) = @_;
|
||||
$var =~ s/([\\\'\"\/])/\\$1/g;
|
||||
$var =~ s/\n/\\n/g;
|
||||
$var =~ s/\r/\\r/g;
|
||||
$var =~ s/\@/\\x40/g; # anti-spam for email addresses
|
||||
return $var;
|
||||
},
|
||||
|
||||
# anti-spam filtering of email addresses
|
||||
email => sub {
|
||||
my ($var) = @_;
|
||||
$var =~ s/\@/\@/g;
|
||||
return $var;
|
||||
},
|
||||
|
||||
# dummy filter when we don't actually need to filter anything
|
||||
none => sub {
|
||||
my ($var) = @_;
|
||||
return $var;
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
# override the process() method to sneak defaultemail into all template
|
||||
# variable spaces
|
||||
sub process {
|
||||
my ($self, $template, $vars, $outstream, @opts) = @_;
|
||||
my %vars = %$vars;
|
||||
|
||||
$vars{defaultemail} = $vars{defaultemail} ? $vars{defaultemail} :
|
||||
Litmus->getCurrentUser();
|
||||
|
||||
$vars{show_admin} = Litmus->getCurrentUser() ?
|
||||
Litmus->getCurrentUser()->is_admin() : 0;
|
||||
|
||||
$self->SUPER::process($template, \%vars, $outstream, @opts);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::Testlist;
|
||||
|
||||
use strict;
|
||||
|
||||
use base qw(Exporter);
|
||||
@Litmus::Testlist::EXPORT = qw(
|
||||
makeHotlist
|
||||
);
|
||||
|
||||
sub makeHotlist {
|
||||
my $numtests = shift;
|
||||
my $state = shift;
|
||||
my @tests = @_;
|
||||
|
||||
my @potentialtests;
|
||||
foreach my $curtest (@tests) {
|
||||
if ($curtest->isrecent()) {
|
||||
foreach my $curplat ($curtest->subgroup()->testgroup()->product()->platforms()) {
|
||||
my $found;
|
||||
my $curstate = $curtest->state($curplat);
|
||||
if ($curstate && $curstate->resultid() == $state->resultid()) {
|
||||
push(@potentialtests, $curtest);
|
||||
$found++;
|
||||
}
|
||||
if ($found) {next}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@potentialtests = sort{$b->num_recent_results() <=> $a->num_recent_results()}
|
||||
@potentialtests;
|
||||
|
||||
return @potentialtests;
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
# Handle detection of system information from the UA string
|
||||
|
||||
package Litmus::UserAgentDetect;
|
||||
|
||||
use strict;
|
||||
|
||||
require Exporter;
|
||||
use Litmus;
|
||||
use Litmus::DB::Platform;
|
||||
use Litmus::DB::Opsys;
|
||||
use Litmus::DB::Branch;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(detectBuildID);
|
||||
|
||||
# define some SQL queries we will use:
|
||||
Litmus::DB::Platform->set_sql(detectplatform => qq{
|
||||
SELECT p.platform_id
|
||||
FROM platforms p, platform_products pp
|
||||
WHERE
|
||||
? REGEXP detect_regexp AND
|
||||
p.platform_id=pp.platform_id AND
|
||||
pp.product_id LIKE ?
|
||||
});
|
||||
Litmus::DB::Branch->set_sql(detectbranch => qq{
|
||||
SELECT __ESSENTIAL__
|
||||
FROM __TABLE__
|
||||
WHERE
|
||||
? REGEXP detect_regexp AND
|
||||
product_id LIKE ?
|
||||
});
|
||||
|
||||
# constructor. Optionally you can pass a UA string
|
||||
# and it will be used. Otherwise the default is the
|
||||
# current useragent.
|
||||
sub new {
|
||||
my $self = {};
|
||||
my $class = shift;
|
||||
my $ua = shift;
|
||||
|
||||
bless($self);
|
||||
$self->{ua} = $main::ENV{"HTTP_USER_AGENT"};
|
||||
if ($ua) { $self->{ua} = $ua }
|
||||
return $self;
|
||||
}
|
||||
|
||||
# default stringification is to return the ua:
|
||||
use overload
|
||||
'""' => \&ua;
|
||||
|
||||
|
||||
sub ua {
|
||||
my $self = shift;
|
||||
|
||||
# we pad the UA with a space since some of our regexp matches expect
|
||||
# to match things at the end of the string. This is quite possibly
|
||||
# a bug.
|
||||
return $self->{ua}." ";
|
||||
}
|
||||
|
||||
sub build_id {
|
||||
my $self = shift;
|
||||
my $ua = $self->{ua};
|
||||
|
||||
# mozilla products only
|
||||
unless ($ua =~ /Mozilla\/5\.0/) {
|
||||
return undef;
|
||||
}
|
||||
$ua =~ /(200\d*)/;
|
||||
return $1;
|
||||
}
|
||||
|
||||
sub locale {
|
||||
my $self = shift;
|
||||
my $ua = $self->{ua};
|
||||
|
||||
# mozilla products only
|
||||
unless ($ua =~ /Mozilla\/5\.0/) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Format (e.g.):
|
||||
# Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8) Gecko/20051111 Firefox/1.5
|
||||
$ua =~ /Mozilla\/5\.0 \([^;]*; [^;]*; [^;]*; ([^;]*); [^;]*\)/;
|
||||
return $1;
|
||||
}
|
||||
|
||||
sub platform {
|
||||
my $self = shift;
|
||||
my $product = shift; # optionally, just lookup for one product
|
||||
|
||||
if (! $product) { $product = '%' }
|
||||
|
||||
my @platforms = Litmus::DB::Platform->search_detectplatform($self->ua, $product);
|
||||
return @platforms;
|
||||
}
|
||||
|
||||
sub branch {
|
||||
my $self = shift;
|
||||
my $product = shift; # optionally, just lookup for one branch
|
||||
|
||||
if (! $product) { $product = '%' }
|
||||
|
||||
my @branches = Litmus::DB::Branch->search_detectbranch($self->ua, $product);
|
||||
return @branches;
|
||||
}
|
||||
|
||||
# from the legacy API before we had an OO interface:
|
||||
sub detectBuildId() {
|
||||
my $self = Litmus::UserAgentDetect->new($main::ENV{"HTTP_USER_AGENT"});
|
||||
|
||||
return $self->build_id();
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,61 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
# General utility functions
|
||||
|
||||
package Litmus::Utils;
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus;
|
||||
use Litmus::Error;
|
||||
use CGI;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
@Litmus::Utils::EXPORT = qw(
|
||||
requireField
|
||||
);
|
||||
|
||||
|
||||
# requireField - checks that $field contains data (other than ---) and throws
|
||||
# an invalidInputError if it does not.
|
||||
sub requireField {
|
||||
my ($fieldname, $field) = @_;
|
||||
|
||||
unless($field && $field ne "---") {
|
||||
my $c = Litmus->cgi();
|
||||
print $c->header();
|
||||
invalidInputError("You must make a valid selection for field ".$fieldname.".");
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -1,419 +0,0 @@
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License
|
||||
# Version 1.1 (the "License"); you may not use this file except in
|
||||
# compliance with the License. You may obtain a copy of the License
|
||||
# at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS"
|
||||
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
# the License for the specific language governing rights and
|
||||
# limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
=cut
|
||||
|
||||
package Litmus::XML;
|
||||
|
||||
# Litmus XML Interface
|
||||
# For further details, see the web services specification at
|
||||
# http://wiki.mozilla.org/Litmus:Web_Services
|
||||
|
||||
use strict;
|
||||
|
||||
use XML::XPath;
|
||||
use XML::XPath::XMLParser;
|
||||
|
||||
use Litmus::DB::User;
|
||||
use Litmus::UserAgentDetect;
|
||||
use Date::Manip;
|
||||
|
||||
use CGI::Carp qw(set_message fatalsToBrowser);
|
||||
|
||||
# if we die for some reason, make sure we give a fatal error per spec
|
||||
BEGIN {
|
||||
set_message(sub {
|
||||
print "Fatal error: internal server error\n";
|
||||
});
|
||||
}
|
||||
|
||||
no warnings;
|
||||
no diagnostics;
|
||||
|
||||
sub new {
|
||||
my $self = {};
|
||||
bless($self);
|
||||
return $self;
|
||||
}
|
||||
|
||||
# process XML test result data as described by
|
||||
# the spec at http://wiki.mozilla.org/Litmus:Web_Services
|
||||
sub processResults {
|
||||
my $self = shift;
|
||||
my $data = shift;
|
||||
|
||||
$self->parseResultFile($data) ? 1 : return 0;
|
||||
|
||||
unless ($self->authenticate()) { return 0} # login failure
|
||||
|
||||
$self->validateResults() ? 1 : return 0;
|
||||
|
||||
# at this point, everything is valid, so if we're just validating the
|
||||
# results, we can return an ok:
|
||||
if ($self->{'action'} eq 'validate') {
|
||||
unless ($self->{'response'}) { $self->respOk() }
|
||||
return 1;
|
||||
}
|
||||
|
||||
# add so-called 'global logs' that apply to all the results
|
||||
# we save them in @globallogs so we can map them to the results later
|
||||
my @globallogs;
|
||||
foreach my $log (@{$self->{'logs'}}) {
|
||||
# the submission time is the timestamp of the first testresult:
|
||||
my $newlog = Litmus::DB::Log->create({
|
||||
submission_time => $self->{'results'}->[0]->{'timestamp'},
|
||||
log_type => $log->{'type'},
|
||||
log_text => $log->{'data'},
|
||||
});
|
||||
push(@globallogs, $newlog);
|
||||
}
|
||||
|
||||
# now actually add the new results to the db:
|
||||
foreach my $result (@{$self->{'results'}}) {
|
||||
my $newres = Litmus::DB::Testresult->create({
|
||||
testcase => $result->{'testid'},
|
||||
user_agent => new Litmus::UserAgentDetect($self->{'useragent'}),
|
||||
user => $self->{'user'},
|
||||
opsys => $self->{'sysconfig'}->{'opsys'},
|
||||
branch => $self->{'sysconfig'}->{'branch'},
|
||||
locale => $self->{'sysconfig'}->{'locale'},
|
||||
build_id => $self->{'sysconfig'}->{'buildid'},
|
||||
machine_name => $self->{'machinename'},
|
||||
result_status => $result->{'resultstatus'},
|
||||
timestamp => $result->{'timestamp'},
|
||||
exit_status => $result->{'exitstatus'},
|
||||
duration_ms => $result->{'duration'},
|
||||
valid => 1,
|
||||
isAutomated => $result->{'isAutomated'},
|
||||
});
|
||||
|
||||
if (!$newres) { $self->respErrResult($result->{'testid'}); next; }
|
||||
|
||||
# add any bug ids:
|
||||
foreach my $bug (@{$result->{'bugs'}}) {
|
||||
my $newbug = Litmus::DB::Resultbug->create({
|
||||
test_result_id => $newres,
|
||||
bug_id => $bug,
|
||||
submission_time => $result->{'timestamp'},
|
||||
user => $self->{'user'},
|
||||
});
|
||||
}
|
||||
|
||||
# add any comments:
|
||||
foreach my $comment (@{$result->{'comments'}}) {
|
||||
my $newcomment = Litmus::DB::Comment->create({
|
||||
test_result => $newres,
|
||||
submission_time => $result->{'timestamp'},
|
||||
user => $self->{'user'},
|
||||
comment => $comment,
|
||||
});
|
||||
}
|
||||
|
||||
# add logs:
|
||||
my @resultlogs;
|
||||
push(@resultlogs, @globallogs); # all results get the global logs
|
||||
foreach my $log (@{$result->{'logs'}}) {
|
||||
my $newlog = Litmus::DB::Log->create({
|
||||
submission_time => $result->{'timestamp'},
|
||||
log_type => $log->{'type'},
|
||||
log_text => $log->{'data'},
|
||||
});
|
||||
push(@resultlogs, $newlog);
|
||||
}
|
||||
|
||||
# now we map the logs to the current result:
|
||||
foreach my $log (@resultlogs) {
|
||||
Litmus::DB::LogTestresult->create({
|
||||
test_result => $newres,
|
||||
log_id => $log,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
unless ($self->{'response'}) { $self->respOk() }
|
||||
|
||||
#$self->{'response'} = $self->{'results'}->[0]->{'resultstatus'};
|
||||
|
||||
}
|
||||
|
||||
sub parseResultFile {
|
||||
my $self = shift;
|
||||
my $data = shift;
|
||||
my $x = XML::XPath->new(xml => $data, standalone => 1);
|
||||
$self->{'useragent'} = $x->findvalue('/litmusresults/@useragent');
|
||||
$self->{'machinename'} = $x->findvalue('litmusresults/@machinename');
|
||||
$self->{'action'} = $x->findvalue('/litmusresults/@action');
|
||||
$self->{'user'}->{'username'} = $x->findvalue(
|
||||
'/litmusresults/testresults/@username');
|
||||
$self->{'user'}->{'token'} = $x->findvalue(
|
||||
'/litmusresults/testresults/@authtoken');
|
||||
|
||||
$self->{'sysconfig'}->{'product'} = $x->findvalue('/litmusresults/testresults/@product');
|
||||
$self->{'sysconfig'}->{'platform'} = $x->findvalue('/litmusresults/testresults/@platform');
|
||||
$self->{'sysconfig'}->{'opsys'} = $x->findvalue('/litmusresults/testresults/@opsys');
|
||||
$self->{'sysconfig'}->{'branch'} = $x->findvalue('/litmusresults/testresults/@branch');
|
||||
$self->{'sysconfig'}->{'buildid'} = $x->findvalue('/litmusresults/testresults/@buildid');
|
||||
$self->{'sysconfig'}->{'locale'} = $x->findvalue('/litmusresults/testresults/@locale');
|
||||
|
||||
my @glogs = $x->find('/litmusresults/testresults/log')->get_nodelist();
|
||||
my $l_ct = 0;
|
||||
foreach my $log (@glogs) {
|
||||
my $type = $x->findvalue('@logtype', $log);
|
||||
my $logdata = stripWhitespace($log->string_value());
|
||||
$self->{'logs'}->[$l_ct]->{'type'} = $type;
|
||||
$self->{'logs'}->[$l_ct]->{'data'} = $logdata;
|
||||
$l_ct++;
|
||||
}
|
||||
|
||||
my @results = $x->find('/litmusresults/testresults/result')->get_nodelist();
|
||||
my $c = 0;
|
||||
foreach my $result (@results) {
|
||||
$self->{'results'}->[$c]->{'testid'} = $x->findvalue('@testid', $result);
|
||||
$self->{'results'}->[$c]->{'isAutomated'} = $x->findvalue('@is_automated_result', $result);
|
||||
$self->{'results'}->[$c]->{'resultstatus'} = $x->findvalue('@resultstatus', $result);
|
||||
$self->{'results'}->[$c]->{'exitstatus'} = $x->findvalue('@exitstatus', $result);
|
||||
$self->{'results'}->[$c]->{'duration'} = $x->findvalue('@duration', $result);
|
||||
$self->{'results'}->[$c]->{'timestamp'} =
|
||||
&Date::Manip::UnixDate($x->findvalue('@timestamp', $result), "%q");
|
||||
|
||||
|
||||
my @comments = $x->find('comment', $result)->get_nodelist();
|
||||
my $com_ct = 0;
|
||||
foreach my $comment (@comments) {
|
||||
$comment = stripWhitespace($comment->string_value());
|
||||
$self->{'results'}->[$c]->{'comments'}->[$com_ct] = $comment;
|
||||
$com_ct++;
|
||||
}
|
||||
|
||||
my @bugs = $x->find('bugnumber', $result)->get_nodelist();
|
||||
my $bug_ct = 0;
|
||||
foreach my $bug (@bugs) {
|
||||
$bug = stripWhitespace($bug->string_value());
|
||||
$self->{'results'}->[$c]->{'bugs'}->[$bug_ct];
|
||||
$bug_ct++;
|
||||
}
|
||||
|
||||
my @logs = $x->find('log', $result)->get_nodelist();
|
||||
my $log_ct = 0;
|
||||
foreach my $log (@logs) {
|
||||
my $type = $x->findvalue('@logtype', $log);
|
||||
my $logdata = stripWhitespace($log->string_value());
|
||||
$self->{'results'}->[$c]->{'logs'}->[$log_ct]->{'type'} = $type;
|
||||
$self->{'results'}->[$c]->{'logs'}->[$log_ct]->{'data'} = $logdata;
|
||||
$log_ct++;
|
||||
}
|
||||
$c++;
|
||||
}
|
||||
|
||||
$self->{'x'} = $x;
|
||||
}
|
||||
|
||||
# validate the result data, and resolve references to various tables
|
||||
# the correct objects, looking up id numbers as needed
|
||||
sub validateResults {
|
||||
my $self = shift;
|
||||
|
||||
my $action = $self->{'action'};
|
||||
if ($action ne 'submit' && $action ne 'validate') {
|
||||
$self->respErrFatal("Action must be either 'submit' or 'validate'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @users = Litmus::DB::User->search(email => $self->{'user'}->{'username'});
|
||||
$self->{'user'} = $users[0];
|
||||
|
||||
|
||||
unless ($self->{'useragent'}) {
|
||||
$self->respErrFatal("You must specify a useragent");
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @prods = Litmus::DB::Product->search(name => $self->{'sysconfig'}->{'product'});
|
||||
unless ($prods[0]) {
|
||||
$self->respErrFatal("Invalid product: ".$self->{'sysconfig'}->{'product'});
|
||||
return 0;
|
||||
}
|
||||
$self->{'sysconfig'}->{'product'} = $prods[0];
|
||||
|
||||
my @platforms = Litmus::DB::Platform->search_ByProductAndName(
|
||||
$self->{'sysconfig'}->{'product'},
|
||||
$self->{'sysconfig'}->{'platform'});
|
||||
unless ($platforms[0]) {
|
||||
$self->respErrFatal("Invalid platform: ".$self->{'sysconfig'}->{'platform'});
|
||||
return 0;
|
||||
}
|
||||
$self->{'sysconfig'}->{'platform'} = $platforms[0];
|
||||
|
||||
my @opsyses = Litmus::DB::Opsys->search(
|
||||
name => $self->{'sysconfig'}->{'opsys'},
|
||||
platform => $self->{'sysconfig'}->{'platform'});
|
||||
unless ($opsyses[0]) {
|
||||
$self->respErrFatal("Invalid opsys: ".$self->{'sysconfig'}->{'opsys'});
|
||||
return 0;
|
||||
}
|
||||
$self->{'sysconfig'}->{'opsys'} = $opsyses[0];
|
||||
|
||||
my @branches = Litmus::DB::Branch->search(
|
||||
name => $self->{'sysconfig'}->{'branch'},
|
||||
product => $self->{'sysconfig'}->{'product'});
|
||||
unless ($branches[0]) {
|
||||
$self->respErrFatal("Invalid branch: ".$self->{'sysconfig'}->{'branch'});
|
||||
return 0;
|
||||
}
|
||||
$self->{'sysconfig'}->{'branch'} = $branches[0];
|
||||
|
||||
unless ($self->{'sysconfig'}->{'buildid'}) {
|
||||
$self->respErrFatal("Invalid build id: ".$self->{'sysconfig'}->{'buildid'});
|
||||
return 0;
|
||||
}
|
||||
|
||||
my @locales = Litmus::DB::Locale->search(
|
||||
locale => $self->{'sysconfig'}->{'locale'});
|
||||
unless ($locales[0]) {
|
||||
$self->respErrFatal("Invalid locale: ".$self->{'sysconfig'}->{'locale'});
|
||||
return 0;
|
||||
}
|
||||
$self->{'sysconfig'}->{'locale'} = $locales[0];
|
||||
|
||||
foreach my $log (@{$self->{'logs'}}) {
|
||||
my @types = Litmus::DB::LogType->search(name => $log->{'type'});
|
||||
unless ($types[0]) {
|
||||
$self->respErrFatal("Invalid log type: ".$log->{'type'});
|
||||
return 0;
|
||||
}
|
||||
$log->{'type'} = $types[0];
|
||||
}
|
||||
|
||||
foreach my $result (@{$self->{'results'}}) {
|
||||
my @tests = Litmus::DB::Testcase->search(
|
||||
test_id => $result->{'testid'});
|
||||
unless ($tests[0]) {
|
||||
$self->respErrResult('unknown', "Invalid test id");
|
||||
next;
|
||||
}
|
||||
$result->{'testid'} = $tests[0];
|
||||
|
||||
# assume it's an automated test result if not specified
|
||||
($result->{'isAutomated'} eq '0' || $result->{'isAutomated'} ne undef) ?
|
||||
$result->{'isAutomated'} = 0 : $result->{'isAutomated'} = 1;
|
||||
|
||||
my @results = Litmus::DB::ResultStatus->search(
|
||||
name => $result->{'resultstatus'});
|
||||
unless ($results[0]) {
|
||||
$self->respErrResult($result->{'testid'}, "Invalid resultstatus");
|
||||
next;
|
||||
}
|
||||
$result->{'resultstatus'} = $results[0];
|
||||
|
||||
my @es = Litmus::DB::ExitStatus->search(
|
||||
name => $result->{'exitstatus'});
|
||||
unless ($es[0]) {
|
||||
$self->respErrResult($result->{'testid'}, "Invalid exitstatus");
|
||||
next;
|
||||
}
|
||||
$result->{'exitstatus'} = $es[0];
|
||||
|
||||
# if there's no duration, then it's just 0:
|
||||
unless ($result->{'duration'}) {
|
||||
$result->{'duration'} = 0;
|
||||
}
|
||||
|
||||
# if there's no timestamp, then it's now:
|
||||
unless ($result->{'timestamp'}) {
|
||||
$result->{'timestamp'} = &Date::Manip::UnixDate("now","%q");
|
||||
}
|
||||
|
||||
foreach my $log (@{$result->{'logs'}}) {
|
||||
my @types = Litmus::DB::LogType->search(name => $log->{'type'});
|
||||
unless ($types[0]) {
|
||||
$self->respErrResult($result->{'testid'},
|
||||
"Invalid log type: ".$log->{'type'});
|
||||
next;
|
||||
}
|
||||
$log->{'type'} = $types[0];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub response {
|
||||
my $self = shift;
|
||||
return $self->{'response'};
|
||||
}
|
||||
|
||||
|
||||
# ONLY NON-PUBLIC API BELOW THIS POINT
|
||||
|
||||
sub authenticate {
|
||||
my $self = shift;
|
||||
|
||||
my @users = Litmus::DB::User->search(email => $self->{'user'}->{'username'});
|
||||
my $user = $users[0];
|
||||
|
||||
unless ($user) { $self->respErrFatal("User does not exist"); return 0 }
|
||||
|
||||
unless ($user->enabled()) { $self->respErrFatal("User disabled"); return 0 }
|
||||
|
||||
if ($user->authtoken() ne $self->{'user'}->{'token'}) {
|
||||
respErrFatal("Invalid authentication token for user ".
|
||||
$self->{'user'}->{'username'});
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub respOk {
|
||||
my $self = shift;
|
||||
$self->{'response'} = 'ok';
|
||||
}
|
||||
|
||||
sub respErrFatal {
|
||||
my $self = shift;
|
||||
my $error = shift;
|
||||
$self->{'response'} = "Fatal error: $error\n";
|
||||
}
|
||||
|
||||
sub respErrResult {
|
||||
my $self = shift;
|
||||
my $testid = shift;
|
||||
my $error = shift;
|
||||
$self->{'response'} .= "Error processing result for test $testid: $error\n";
|
||||
}
|
||||
|
||||
# remove leading and trailing whitespace from logs and comments
|
||||
sub stripWhitespace {
|
||||
my $txt = shift;
|
||||
$txt =~ s/^\s+//;
|
||||
$txt =~ s/\s+$//;
|
||||
return $txt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
@@ -1,56 +0,0 @@
|
||||
# Litmus Makefile
|
||||
|
||||
PERL=perl
|
||||
|
||||
install: templates
|
||||
$(PERL) populatedb.pl
|
||||
|
||||
# precompile all templates with the Template Toolkit
|
||||
# to speed things up a good bit.
|
||||
# This ought to be done in a more "makelike" way, but
|
||||
# various difficulties prevent that unless we use a configure
|
||||
# script to generate the Makefile, at which point we could have
|
||||
# been done already...
|
||||
|
||||
%.tmpl:
|
||||
$(PERL) -e " \
|
||||
eval('use CGI qw(-no_debug)'); \
|
||||
use Litmus::Template;use diagnostics; \
|
||||
\$$template = Litmus::Template->create(); \
|
||||
\$$template->context()->template('$@'); \
|
||||
"
|
||||
|
||||
templates: index.html.tmpl
|
||||
$(PERL) -e " \
|
||||
use File::Find; \
|
||||
find({ wanted => sub { \
|
||||
\$$name = \$$File::Find::name; \
|
||||
return if (-d \$$name); \
|
||||
return if (\$$name =~ /\/CVS\//); \
|
||||
return if (\$$name !~ /\.tmpl\$$/); \
|
||||
\$$name =~ s/templates\/en\/default\///; \
|
||||
if (-M 'templates/en/default/'.\$$name < -M 'data/templates/en/default/'.\$$name \
|
||||
|| ! -e 'data/templates/en/default/'.\$$name \
|
||||
|| -M 'Litmus/Template.pm' < -M 'data/templates/en/default/'.\$$name) { \
|
||||
system("make", "\$$name"); \
|
||||
} \
|
||||
}, no_chdir => 1 }, 'templates/en/default'); \
|
||||
"
|
||||
|
||||
# tags: generate ctags style hints for ease of editing
|
||||
# requires Exuberant Ctags to be installed (http://ctags.sf.net/)
|
||||
ctags:
|
||||
`which ctags` --excmd=number --tag-relative=no --fields=+a+m+n+S -R `pwd`
|
||||
|
||||
tags: ctags
|
||||
|
||||
test:
|
||||
$(PERL) runtests.pl
|
||||
|
||||
cache:
|
||||
$(PERL) -MLitmus -MLitmus::Cache -e "Litmus::Cache::rebuildCache();"
|
||||
@echo "Done";
|
||||
|
||||
clean:
|
||||
rm -rf data
|
||||
make install
|
||||
@@ -1,47 +0,0 @@
|
||||
===Litmus===
|
||||
|
||||
If you're reading this, you've downloaded, received, or simply conjured
|
||||
out of thin air, a copy of the Litmus testcase management system.
|
||||
Presumably, you're reading this file because you have some sort of
|
||||
question about Litmus. Hopefully, if we've done our job right, this file
|
||||
ought to answer your questions.
|
||||
|
||||
Q: What is Litmus?
|
||||
A: Litmus is a testcase management system. Its goal is to allow users to
|
||||
enter software tests, run them, and view and manage the results. Along
|
||||
the way, users can expect to be able to do queries and reports and have
|
||||
access all the usual features they expect from a first-class web
|
||||
application. The reality may be somewhat different than this goal.
|
||||
Litmus is developed by mozilla.org.
|
||||
|
||||
Q: How do I install this dang thing?
|
||||
A: You probably want the file called INSTALL.
|
||||
|
||||
Q: Where is the real documentation?
|
||||
A: Hahahaha. What is this "documentation" you speak of? You might want
|
||||
to check out the Litmus Wiki, which may or may not contain useful
|
||||
information. See http://wiki.mozilla.org/Litmus.
|
||||
|
||||
Q: What needs to be done?
|
||||
A: See http://wiki.mozilla.org/Litmus:Todo
|
||||
|
||||
Q: How much does it cost?
|
||||
A: Nothing. Litmus is Free Software, licensed under the Mozilla Public
|
||||
License.
|
||||
|
||||
Q: Wait. Isn't "testcase" two words?
|
||||
A: Not here it isn't.
|
||||
|
||||
Q: Waaaaaaah. Why is Litmus written in Perl and not
|
||||
PHP/Python/Java/Objective Pascal/Latin?
|
||||
A: Because I know Perl. Duh. Also because Litmus uses some code from
|
||||
Bugzilla, and it wouldn't be able to do this if it was written in some
|
||||
other language. Camels are also some of the least buggy animals around,
|
||||
as they swat flies away with their tails.
|
||||
|
||||
Q: I'm still confused. You didn't answer my question. I don't know what
|
||||
to do. Help!
|
||||
A: First of all, that's not a question. In any case, your best bet is
|
||||
probably to email Zach Lipton <zach@zachlipton.com>, and if you ask
|
||||
nicely and don't make too much of a pest of yourself, he'd be glad to
|
||||
get you on the right track.
|
||||
@@ -1,246 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus;
|
||||
use Litmus::Auth;
|
||||
use Litmus::Error;
|
||||
use Litmus::DB::Testresult;
|
||||
use Litmus::FormWidget;
|
||||
|
||||
use CGI;
|
||||
use Time::Piece::MySQL;
|
||||
|
||||
Litmus->init();
|
||||
my $c = Litmus->cgi();
|
||||
print $c->header();
|
||||
|
||||
|
||||
|
||||
# Hash refs for maintaining state in the search form.
|
||||
my $defaults = undef;
|
||||
my $order_bys = undef;
|
||||
|
||||
my $MAX_SORT_FIELDS = 10;
|
||||
my $MAX_SEARCH_FIELDS = 10;
|
||||
|
||||
my $criteria = "Custom<br/>";
|
||||
my $results;
|
||||
my @where;
|
||||
my @order_by;
|
||||
my $limit;
|
||||
my $where_criteria = "";
|
||||
my $order_by_criteria = "";
|
||||
my $limit_criteria = "";
|
||||
|
||||
if ($c->param) {
|
||||
|
||||
foreach my $param ($c->param) {
|
||||
next if ($c->param($param) eq '');
|
||||
|
||||
if ($param =~ /sort_field(\d+)/) {
|
||||
# We slot sort fields into the @order_by array based on their
|
||||
# field_num. Empty array slots will be ignored when the SQL
|
||||
# is built. We set an upper limit on the number of sort fields
|
||||
# we can handle to prevent abuse.
|
||||
my $field_num = $1;
|
||||
next if ($field_num > $MAX_SORT_FIELDS);
|
||||
my $sort_field = $c->param($param);
|
||||
my $sort_order = 'ASC';
|
||||
if ($c->param("sort_order$field_num")) {
|
||||
$sort_order = $c->param("sort_order$field_num");
|
||||
}
|
||||
$order_by[$field_num] = { field => $sort_field,
|
||||
direction => $sort_order};
|
||||
|
||||
} elsif ($param =~ /search_field(\d+)/) {
|
||||
# We set an upper limit on the number of search fields
|
||||
# we can handle to prevent abuse.
|
||||
my $field_num = $1;
|
||||
next if ($field_num > $MAX_SEARCH_FIELDS);
|
||||
my $search_field = $c->param($param);
|
||||
my $match_criteria = $c->param("match_criteria$field_num");
|
||||
my $value = $c->param("search_value$field_num");
|
||||
push @where, { 'field' => 'search_field',
|
||||
'search_field' => $search_field,
|
||||
'match_criteria' => $match_criteria,
|
||||
'value' => $value};
|
||||
$where_criteria .= "$search_field $match_criteria '$value'<br/>";
|
||||
|
||||
} elsif ($param eq 'start_date') {
|
||||
my $start_date = $c->param($param);
|
||||
$start_date =~ s/[^0-9A-Za-z ]/ /g;
|
||||
my $end_date;
|
||||
# Use 'now' as the default end date.
|
||||
if ($c->param('end_date') and $c->param('end_date') ne '') {
|
||||
$end_date = $c->param('end_date');
|
||||
$end_date =~ s/[^0-9A-Za-z ]/ /g;
|
||||
} else {
|
||||
$end_date = 'Now';
|
||||
}
|
||||
push @where, { field => 'start_date',
|
||||
value => $start_date};
|
||||
push @where, { field => 'end_date',
|
||||
value => $end_date};
|
||||
$where_criteria .= "Date between '$start_date' and '$end_date'<br/>";
|
||||
} elsif ($param eq 'trusted_only') {
|
||||
push @where, {field => 'trusted_only',
|
||||
value => 1};
|
||||
$limit_criteria .= "Display trusted results only<br/>";
|
||||
} elsif ($param eq "limit") {
|
||||
$limit = $c->param($param);
|
||||
next if ($limit == $Litmus::DB::Testresult::_num_results_default);
|
||||
$limit_criteria .= "Limit to $limit results<br/>";
|
||||
} elsif ($param eq 'branch') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Branch is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{branch} = $c->param($param);
|
||||
} elsif ($param eq 'locale') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => 'locale',
|
||||
value => $value};
|
||||
$where_criteria .= "Locale is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{locale} = $c->param($param);
|
||||
} elsif ($param eq 'email') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => 'email',
|
||||
value => $value};
|
||||
$where_criteria .= "Submitted By is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{locale} = $c->param($param);
|
||||
} elsif ($param eq 'product') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Product is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{product} = $c->param($param);
|
||||
} elsif ($param eq 'platform') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Platform is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{platform} = $c->param($param);
|
||||
} elsif ($param eq 'test_group') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Test group is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{test_group} = $c->param($param);
|
||||
} elsif ($param eq 'test_id') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Testcase ID# is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{test_id} = $c->param($param);
|
||||
} elsif ($param eq 'summary') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Summary like \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{summary} = $c->param($param);
|
||||
} elsif ($param eq 'result_status') {
|
||||
my $value = $c->param($param);
|
||||
push @where, {field => $param,
|
||||
value => $value};
|
||||
$where_criteria .= "Status is \'".$c->param($param)."\'<br/>";
|
||||
$defaults->{result_status} = $c->param($param);
|
||||
} else {
|
||||
# Skip unknown field
|
||||
}
|
||||
}
|
||||
if ($where_criteria eq '' and
|
||||
scalar(@order_by) == 0 and
|
||||
$limit_criteria eq '') {
|
||||
($criteria,$results) =
|
||||
Litmus::DB::Testresult->getDefaultTestResults;
|
||||
} else {
|
||||
foreach my $order_by_field (@order_by) {
|
||||
next if (!$order_by_field);
|
||||
$order_by_criteria .= "Order by $order_by_field->{field} $order_by_field->{direction}<br/>";
|
||||
}
|
||||
|
||||
$criteria .= $where_criteria . $order_by_criteria . $limit_criteria;
|
||||
$criteria =~ s/_/ /g;
|
||||
$results = Litmus::DB::Testresult->getTestResults(\@where,
|
||||
\@order_by,
|
||||
$limit);
|
||||
}
|
||||
} else {
|
||||
($criteria,$results) =
|
||||
Litmus::DB::Testresult->getDefaultTestResults;
|
||||
}
|
||||
|
||||
# Populate each of our form widgets for select/input.
|
||||
# Set a default value as appropriate.
|
||||
my $products = Litmus::FormWidget->getProducts;
|
||||
my $platforms = Litmus::FormWidget->getUniquePlatforms;
|
||||
my $test_groups = Litmus::FormWidget->getTestgroups;
|
||||
my $testcases = Litmus::FormWidget->getTestcaseIDs;
|
||||
my $result_statuses = Litmus::FormWidget->getResultStatuses;
|
||||
my $branches = Litmus::FormWidget->getBranches;
|
||||
my $locales = Litmus::FormWidget->getLocales;
|
||||
my $users = Litmus::FormWidget->getUsers;
|
||||
|
||||
my $fields = Litmus::FormWidget->getFields;
|
||||
my $match_criteria = Litmus::FormWidget->getMatchCriteria;
|
||||
my $sort_fields = Litmus::FormWidget->getSortFields;
|
||||
|
||||
my $title = 'Advanced Search';
|
||||
|
||||
my $vars = {
|
||||
title => $title,
|
||||
criteria => $criteria,
|
||||
products => $products,
|
||||
platforms => $platforms,
|
||||
test_groups => $test_groups,
|
||||
testcases => $testcases,
|
||||
result_statuses => $result_statuses,
|
||||
branches => $branches,
|
||||
locales => $locales,
|
||||
users => $users,
|
||||
fields => $fields,
|
||||
match_criteria => $match_criteria,
|
||||
sort_fields => $sort_fields,
|
||||
};
|
||||
|
||||
# Only include results if we have them.
|
||||
if ($results and scalar @$results > 0) {
|
||||
$vars->{results} = $results;
|
||||
}
|
||||
|
||||
my $cookie = Litmus::Auth::getCookie();
|
||||
$vars->{"defaultemail"} = $cookie;
|
||||
$vars->{"show_admin"} = Litmus::Auth::istrusted($cookie);
|
||||
|
||||
Litmus->template()->process("reporting/advanced_search.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit 0;
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- mode: cperl; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
||||
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Chris Cooper <ccooper@deadsquid.com>
|
||||
# Zach Lipton <zach@zachlipton.com>
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
use strict;
|
||||
$|++;
|
||||
|
||||
use Litmus;
|
||||
use Litmus::Auth;
|
||||
use Litmus::Error;
|
||||
use Litmus::DB::Testresult;
|
||||
use Litmus::FormWidget;
|
||||
|
||||
|
||||
use CGI;
|
||||
use Time::Piece::MySQL;
|
||||
|
||||
Litmus->init();
|
||||
my $c = Litmus->cgi();
|
||||
print $c->header();
|
||||
|
||||
my $results;
|
||||
if ($c->param and $c->param('status')) {
|
||||
if ($c->param('status') =~ /pass/i or
|
||||
$c->param('status') =~ /fail/i or
|
||||
$c->param('status') =~ /unclear/i) {
|
||||
$results = Litmus::DB::Testresult->getCommonResults($c->param('status'));
|
||||
} else {
|
||||
internalError("You must provide a valid status type: pass|fail|unclear");
|
||||
exit 1;
|
||||
}
|
||||
} else {
|
||||
internalError("You must provide a status type: pass|fail|unclear");
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $title;
|
||||
if ($c->param('status') eq 'pass') {
|
||||
$title = "Most Commonly Passed Testcases";
|
||||
} elsif ($c->param('status') eq 'fail') {
|
||||
$title = "Most Common Failures";
|
||||
} elsif ($c->param('status') eq 'unclear') {
|
||||
$title = "Testcases Most Frequently Marked As Unclear";
|
||||
}
|
||||
|
||||
my $vars = {
|
||||
title => $title,
|
||||
status => $c->param('status'),
|
||||
};
|
||||
|
||||
# Only include results if we have them.
|
||||
if ($results and scalar @$results > 0) {
|
||||
$vars->{results} = $results;
|
||||
}
|
||||
|
||||
$vars->{"defaultemail"} = Litmus::Auth::getCookie();
|
||||
|
||||
Litmus->template()->process("reporting/common_results.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 791 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 261 B |
|
Before Width: | Height: | Size: 249 B |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 396 B |
@@ -1,105 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Zach Lipton <zach@zachlipton.com>
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus;
|
||||
use Litmus::Error;
|
||||
use Litmus::DB::Product;
|
||||
use Litmus::DB::TestcaseSubgroup;
|
||||
use Litmus::Auth;
|
||||
use Litmus::Utils;
|
||||
|
||||
use CGI;
|
||||
use Time::Piece::MySQL;
|
||||
|
||||
Litmus->init();
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
# obviously, you need to be an admin to edit users...
|
||||
Litmus::Auth::requireAdmin('edit_users.cgi');
|
||||
|
||||
if ($c->param('search_string')) {
|
||||
# search for users:
|
||||
my $users = Litmus::DB::User->search_FullTextMatches(
|
||||
$c->param('search_string'),
|
||||
$c->param('search_string'),
|
||||
$c->param('search_string'));
|
||||
my $vars = {
|
||||
users => $users,
|
||||
};
|
||||
print $c->header();
|
||||
Litmus->template()->process("admin/edit_users/search_results.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
} elsif ($c->param('id')) {
|
||||
# lookup a given user
|
||||
my $uid = $c->param('id');
|
||||
my $user = Litmus::DB::User->retrieve($uid);
|
||||
print $c->header();
|
||||
if (! $user) {
|
||||
invalidInputError("Invalid user id: $uid");
|
||||
}
|
||||
my $vars = {
|
||||
user => $user,
|
||||
};
|
||||
Litmus->template()->process("admin/edit_users/edit_user.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
} elsif ($c->param('user_id')) {
|
||||
# process changes to a user:
|
||||
my $user = Litmus::DB::User->retrieve($c->param('user_id'));
|
||||
print $c->header();
|
||||
if (! $user) {
|
||||
invalidInputError("Invalid user id: " . $c->param('user_id'));
|
||||
}
|
||||
$user->bugzilla_uid($c->param('bugzilla_uid'));
|
||||
$user->email($c->param('edit_email'));
|
||||
|
||||
if ($c->param('edit_password') ne 'unchanged') {
|
||||
# they changed the password, so let the auth folks know:
|
||||
Litmus::Auth::changePassword($user, $c->param('edit_password'));
|
||||
}
|
||||
$user->realname($c->param('realname'));
|
||||
$user->irc_nickname($c->param('irc_nickname'));
|
||||
if ($c->param('enabled')) {
|
||||
$user->enabled(1);
|
||||
}
|
||||
if ($c->param('is_admin')) {
|
||||
$user->is_admin(1);
|
||||
}
|
||||
$user->authtoken($c->param('authtoken'));
|
||||
$user->update();
|
||||
my $vars = {
|
||||
user => $user,
|
||||
};
|
||||
Litmus->template()->process("admin/edit_users/user_edited.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
} else {
|
||||
# we're here for the first time, so display the search form
|
||||
my $vars = {
|
||||
};
|
||||
print $c->header();
|
||||
Litmus->template()->process("admin/edit_users/search_users.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Litmus.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Zach Lipton <zach@zachlipton.com>
|
||||
|
||||
use strict;
|
||||
|
||||
use Litmus;
|
||||
use Litmus::Error;
|
||||
use Litmus::DB::Product;
|
||||
use Litmus::DB::TestcaseSubgroup;
|
||||
use Litmus::Auth;
|
||||
use Litmus::Utils;
|
||||
|
||||
use CGI;
|
||||
use Time::Piece::MySQL;
|
||||
use Date::Manip;
|
||||
|
||||
Litmus->init();
|
||||
my $c = Litmus->cgi();
|
||||
|
||||
# for the moment, you must be an admin to enter tests:
|
||||
Litmus::Auth::requireAdmin('enter_test.cgi');
|
||||
|
||||
# if we're here for the first time, display the enter testcase form,
|
||||
# otherwise, process the results:
|
||||
|
||||
if (! $c->param('enteringTestcase')) {
|
||||
my $vars = {
|
||||
|
||||
};
|
||||
|
||||
print $c->header();
|
||||
Litmus->template()->process("enter/enter.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
} else {
|
||||
requireField('product', $c->param('product'));
|
||||
requireField('test group', $c->param('testgroup'));
|
||||
requireField('subgroup', $c->param('subgroup'));
|
||||
requireField('summary', $c->param('summary'));
|
||||
|
||||
my $newtest = Litmus::DB::Testcase->create({
|
||||
product => $c->param('product'),
|
||||
summary => $c->param('summary'),
|
||||
steps => $c->param('steps') ? $c->param('steps') : '',
|
||||
expected_results => $c->param('expectedResults') ?
|
||||
$c->param('expectedResults') : '',
|
||||
author => Litmus::Auth::getCurrentUser(),
|
||||
creation_date => &Date::Manip::UnixDate("now","%q"),
|
||||
version => 1,
|
||||
});
|
||||
|
||||
my $newtsg = Litmus::DB::TestcaseSubgroup->create({
|
||||
test => $newtest,
|
||||
subgroup => $c->param('subgroup'),
|
||||
});
|
||||
|
||||
my $vars = {
|
||||
test => $newtest,
|
||||
};
|
||||
|
||||
print $c->header();
|
||||
Litmus->template()->process("enter/enterComplete.html.tmpl", $vars) ||
|
||||
internalError(Litmus->template()->error());
|
||||
}
|
||||
|
Before Width: | Height: | Size: 580 B |
|
Before Width: | Height: | Size: 3.6 KiB |