Search This Blog

Friday, September 10, 2010

Photo Upload interface code

Use the code below in an application engine, peoplecode step, as per your requirement.

Function PutPhotoInit:

This function initializes employee photo processing. It initializes PSOPTIONS.MAXCHUNKSIZE. The point of the initialization is to select a chunk size that is larger than the largest photo that will be processed. The processing chunksize is currently set to 1MB. The program would need to be updated if a larger photo is to be loaded. The original chunksize should be noted as it is possible for the program to abend without restoring the original chunksize (28K as of this writing).

Function PutPhotoInit()
SQLExec("SELECT MAXCHUNKSIZE FROM PSOPTIONS", &iOriginalChunkSize);
&iPhotoChunkSize = 1000000;
If &iOriginalChunkSize < &iPhotoChunkSize Then SQLExec("UPDATE PSOPTIONS set MAXCHUNKSIZE = :1", &iPhotoChunkSize); End-If; &recEMPL_PHOTO = CreateRecord(Record.EMPL_PHOTO); End-Function;


Function PutPhotoTerm:

This function terminates employee photo processing. It restores PSOPTIONS.MAXCHUNKSIZE to the value that it had when processing began. The original chunksize should be noted as it is possible for the program to abend without restoring the original chunksize (28K as of this writing).

Function PutPhotoTerm()
If &iOriginalChunkSize < &iPhotoChunkSize Then SQLExec("UPDATE PSOPTIONS set MAXCHUNKSIZE = :1", &iOriginalChunkSize); End-If; MessageBox(0, "", 0, 0, &iPhotoCnt " employee photos committed."); CommitWork(); End-Function;


Function PutPhoto:

This function actually loads the photo.
1)The photo file is first loaded to PSFILE_ATTDET using the PutAttachment function.
2)The blob data of the photo is then selected into a variable using SQLExec();
3)The photo file row is then deleted from PSFILE_ATTDET.
4)PS_EMPL_PHOTO.PSIMAGEVER is set to the number of seconds since 01-JAN-2000. This method was found in sample code obtained by Brady Dunn from an Oracle mailing list.
5)The row is is updated or inserted on PS_EMPL_PHOTO depending on whether the employee ID already exists.
6)A commit is performed every 50 rows.

Function PutPhoto()
Local integer &iVersion, &iResult;
Local string &strAttachFileName;
Local string &strMsg;
Local any &anyPhotoBlob;
Local boolean &bFound;

&recEMPL_PHOTO.SetDefault();
&strAttachFileName = &strImageEmplid ".txt";
&iResult = PutAttachment("record://PSFILE_ATTDET", &strAttachFileName, &strImageFileFullName);
If &iResult <> 0 Then
MessageBox(0, "", 0, 0, "*** Start Message ***");
MessageBox(0, "", 0, 0, "PutAttachement failed");
MessageBox(0, "", 0, 0, "Return Code=" &iResult);
MessageBox(0, "", 0, 0, "Image File=" &strImageFileFullName);
MessageBox(0, "", 0, 0, "Blob File=" &strAttachFileName);
MessageBox(0, "", 0, 0, "*** End Message ***");
CommitWork();
End-If;
SQLExec("SELECT FILE_DATA FROM PSFILE_ATTDET WHERE ATTACHSYSFILENAME = :1 AND VERSION = 1", &strAttachFileName, &anyPhotoBlob);
SQLExec("DELETE FROM PSFILE_ATTDET WHERE ATTACHSYSFILENAME = :1 AND VERSION = 1", &strAttachFileName);
REM MessageBox(0, "", 0, 0, "&strImageEmplid=" &strImageEmplid);
&recEMPL_PHOTO.EMPLID.Value = &strImageEmplid;
&bFound = &recEMPL_PHOTO.SelectByKey();
&recEMPL_PHOTO.EMPLID.Value = &strImageEmplid;
&recEMPL_PHOTO.EMPLOYEE_PHOTO.Value = &anyPhotoBlob;
/* Set the version to seconds from year 2000 */
&recEMPL_PHOTO.PSIMAGEVER.Value = (Days365(Date3(1999, 12, 31), %Date) * 86400) + (%Time - Time3(0, 0, 0));

If &bFound Then
&recEMPL_PHOTO.Update();
Else
&recEMPL_PHOTO.Insert();
End-If;
If Mod(&iPhotoCnt, 50) = 0 Then
MessageBox(0, "", 0, 0, &iPhotoCnt " employee photos committed.");
CommitWork();
End-If;
End-Function;


Function GetEmplidFromFileName:

This function is passed a filename. As mentioned earlier, that filename contains the first and last name of the employee
1) The extension (.jpg) is removed from the file name.
2) The remainder is separated into first and last name;
3) For Japan, we are unsure whether the name was in firstname-lastname or lastname-firstname format. So the PS_NAMES table is searched for a match with either format.
4) If one and only one match is found on PS_NAMES, the corresponding EMPLID is returned.

Function GetEmplidFromFileName(&fileName As string) Returns string
Local integer &iSepPos, &iRowCnt;
Local string &strFirstNameFirst, &strLastNameFirst, &strLeftPart, &strRightPart, &strPersonName, &strFirstNameSrch, &strLastNameSrch;
Local string &strSQL, &strEmplID, &strDebug;
&strPersonName = LTrim(RTrim(&fileName));
REM MessageBox(0, "", 0, 0, "&strPersonName=" &strPersonName);
If None(&strPersonName) Then
MessageBox(0, "", 0, 0, "NO EMPLID:&strPersonName (from &fileName) is blank");
Return "";
End-If;
<* chop off file extension *>
&strPersonName = Left(&strPersonName, (Len(&strPersonName) - 4));
If None(&strPersonName) Then
MessageBox(0, "", 0, 0, "NO EMPLID:&strPersonName (chop extension) is blank, &fileName=" &fileName);
Return "";
End-If;
<* find the position of the separator, underscore, blank, or dot *>
&iSepPos = Find(" ", &strPersonName);
If &iSepPos <= 0 Then &iSepPos = Find(".", &strPersonName); End-If; If &iSepPos <= 0 Then &iSepPos = Find("_", &strPersonName); End-If; If &iSepPos <= 0 Then &iSepPos = Find("-", &strPersonName); End-If; If &iSepPos <= 0 Then MessageBox(0, "", 0, 0, "NO EMPLID:&iSepPos=" &iSepPos ", separator not found, &strPersonName=" &strPersonName); Return ""; End-If; <* separate the name into left and right hand parts *>
&strLeftPart = Left(&strPersonName, (&iSepPos - 1));
&strRightPart = Right(&strPersonName, (Len(&strPersonName) - &iSepPos));
<* find emplid by first and last name, assume incoming file name was in last name first format *>
/*
&strLastNameFirst = Upper(&strLeftPart &strRightPart);
&strFirstNameFirst = Upper(&strRightPart &strLeftPart);
&strSQL = "select count(1), EMPLID from PS_NAMES where LAST_NAME_SRCH in (:1, :2) and FIRST_NAME_SRCH in (:1, :2) group by EMPLID";
SQLExec(&strSQL, &strLastNameFirst, &strFirstNameFirst, &iRowCnt, &strEmplID);
*/
&strLastNameSrch = Upper(&strRightPart);
&strFirstNameSrch = Upper(&strLeftPart);
&strSQL = "select count(1), EMPLID from PS_NAMES where ((LAST_NAME_SRCH = :1 and FIRST_NAME_SRCH = :2) or (LAST_NAME_SRCH = :3 and FIRST_NAME_SRCH = :4)) group by EMPLID";
SQLExec(&strSQL, &strLastNameSrch, &strFirstNameSrch, &strFirstNameSrch, &strLastNameSrch, &iRowCnt, &strEmplID);
&strDebug = "DEBUG: ";
&strDebug = &strDebug "&iRowCnt=" &iRowCnt ", ";
&strDebug = &strDebug "&strEmplID=" &strEmplID ", ";
&strDebug = &strDebug "&strPersonName=" &strPersonName ", ";
&strDebug = &strDebug "&strLastNameSrch=" &strLastNameSrch ", ";
&strDebug = &strDebug "&strFirstNameSrch=" &strFirstNameSrch;
If &iRowCnt <> 1 Then
MessageBox(0, "", 0, 0, "NO EMPLID:&iRowCnt=" &iRowCnt ", should equal 1");
MessageBox(0, "", 0, 0, &strDebug);
Return "";
End-If;
Return &strEmplID;End-Function;


Main processing (not within any function):

This code drives the program. It
1) Retrieves an array of the filenames in C:\EMPL_PHOTO that have a (.jpg) extension.
2) If no files are found the processing is complete.
3) On the first loop iteration, PutPhotoInit() is called to prepare for images to be inserted.
4) For each file name in the array
a) The array entries contain the full path, e.g., C:\EMPL_PHOTO\John_Doe.jpg. The directory is removed leaving only the filename John_Doe.jpg.
b) The filename is passed to the function GetEmplidFromFileName().
c) If an employee ID is returned the image file is saved to the database by calling PutPhoto();
5) After the loop is complete PutPhotoTerm() is called to reset back to pre-run state.


<* Load list of image file names into array *>
&arrImageFileList = FindFiles("C:\EMPL_PHOTO\*.JPG", %FilePath_Absolute);
If &arrImageFileList = Null Then
MessageBox(0, "", 0, 0, "No files found");
Else
MessageBox(0, "", 0, 0, "found " &arrImageFileList.Len " photo files.");
For &iIdx = 1 To &arrImageFileList.Len
&strImageFileFullName = &arrImageFileList [&iIdx];
&strImageFileName = &strImageFileFullName;
If &iPhotoCnt <= 0 Then PutPhotoInit(); &iPhotoCnt = 1; Else &iPhotoCnt = &iPhotoCnt + 1; End-If; MessageBox(0, "", 0, 0, "Processing file " &iPhotoCnt ":" &strImageFileFullName); &strImageEmplid = ""; <* remove the path to extract the simple file name *>
&iStartPos = Find("\", &strImageFileName);
If &iStartPos > 0 Then
&iLastSlashFoundPos = &iStartPos;
&iStartPos = &iStartPos + 1;
Else
&iLastSlashFoundPos = 0;
End-If;
While &iStartPos > 0
&iStartPos = Find("\", &strImageFileName, &iStartPos);
If &iStartPos > 0 Then
&iLastSlashFoundPos = &iStartPos;
&iStartPos = &iStartPos + 1;
Else
Break;
End-If;
End-While;
If &iLastSlashFoundPos > 0 Then
&strImageFileName = Substring(&strImageFileFullName, (&iLastSlashFoundPos + 1), Len(&strImageFileFullName));
&strImageDir = Left(&strImageFileFullName, (&iLastSlashFoundPos - 1));
Else
&strImageFileName = &strImageFileFullName;
&strImageDir = "";
End-If;
&strImageEmplid = GetEmplidFromFileName(&strImageFileName);
If All(&strImageEmplid) Then
PutPhoto();
End-If;
<* not sure that we are going to want to delete the files &fImage = GetFile(&strImageFileFullName, "E", %FilePath_Absolute); &fImage.Delete(); &fImage.Close(); *>
End-For;
PutPhotoTerm();
End-If;


Lokesh Madnavat

No comments:

Post a Comment