1

Тема: Работа с MIME в Lotus

Есть у  меня кнопка для переименования вложений, которая дергает мою функцию GetEmbedObject - в которой я хочу переименовать вложение с помощью NotesMIMEEntity.

Sub Click(Source As Button)     '  Через МИМЕ - не пашет
    On Error Goto ErrH
    Dim session As New NotesSession, ws As New NotesUIWorkspace, db As NotesDatabase, sview As NotesView, dc As NotesDocumentCollection
    Dim uidoc As NotesUIDocument, doc As NotesDocument, templdoc As NotesDocument, DocTemp As NotesDocument
    Dim picklist As Variant, mes As String
    Dim rtitem As NotesRichTextItem
    Dim Name_Stncl_List()  ' все имена вложений
    
    
    
    Set doc = ws.CurrentDocument.Document
    Set uidoc=ws.CurrentDocument
    Call uidoc.save
    
    Set rtitem = doc.GetFirstItem("attach")
    
    Dim xxxx As  Integer
    i=0
    If ( rtitem.Type = RICHTEXT ) Then 
        If Not Isempty(rtitem.EmbeddedObjects) Then  
            Forall obj In rtitem.EmbeddedObjects
                If obj.Type = EMBED_ATTACHMENT Then   ' шаг 1 имена вложений в массив
                    If obj.FileSize=0 Then
                        xxxx =     Messagebox     ({"Приложение:  } & obj.Source & { имеет размер 0 байт.} & Chr(13) & Chr(13)   & {Удалить?"}, 1 , "Удаление нулевого вложения." ) 
                        If xxxx = 1 Then
                            doc.history= Cstr(Now)   + " "+ session.CommonUserName + " удалено приложение размером 0 байт ("  + obj.Source + ") "   &Chr(13) & " "&Chr(13) &  doc.history(0)
                            Call  obj.Remove
                            doc.ReplaceItemValue({SaveOptions},{0}).SaveToDisk=False
                            Call doc.save (True,False)
                            Call uidoc.Close
                            Call ws.EditDocument(True, doc)  '  False - чтение
                            Exit Sub
                        End If
                        
                    Else
                        Redim Preserve Name_Stncl_List(i)        
                        Name_Stncl_List(i)=    obj.Source    &  {|}&   obj.Name '    в Name_Stncl_List вносим имена вложений (Source) и   альясы (Name)
                        
                        i=i+1
                    End If
                End If                
            End Forall
        End If
    End If        
    
    If i>0 Then        'есть  хоть одно вложение в поле атач
        Set DocTemp = doc.ParentDatabase.CreateDocument
        DocTemp.ReplaceItemValue  "Name_ListAttach", Name_Stncl_List   ' скрытое поле Name_ListAttach на диалог формне с  Source   |  Name
        
        If Not    ws.DialogBox("ChooseDlg",True,True,False,False,False,False,"Переименовать ",doctemp, True) Then Exit Sub
        
        nameobj2 =  doctemp.ListAttach(0)
        Print "---"
        Print nameobj2         '  псевдоним Name
    End If
    
    datapatch$ = "C:\XML\"
    If  Dir$ (datapatch$ ,16 )="" Then 
        Mkdir datapatch$
    End If
    
    i=1 
    Forall obj In rtitem.EmbeddedObjects
        If obj.Name = nameobj2  Then   ' nameobj2 - ямя выбранного вложения (псевдоним)
            Dim object3 As NotesEmbeddedObject
            Set object3 =     rtitem.GetEmbeddedObject(nameobj2)
            Print "object3.Source " object3.Source
            new_nameobj=Trim(Inputbox$("Введите новое имя приложения "  & i ,"Ввод названия приложения",Strleftback(object3.Source,".")   ))       '  строка слева от первой точки ( без расширения)
            If new_nameobj="" Then Exit Sub
            
            new_nameobj = new_nameobj & "." & Strrightback (object3.Source,".")    '   имя + расширение файла
            
            If new_nameobj<>nameobj2 Then   '  надо переименовать
                Call obj.ExtractFile( datapatch$ & nameobj2) 
                Name datapatch$ & nameobj2   As  datapatch$ & new_nameobj   '  переименовать файл nameobj на диске в new_nameobj
                
                'Call rtitem.EmbedObject ( EMBED_ATTACHMENT, "", datapatch$ & new_nameobj)    СЛЕТАЕТ ИКОНКА
                Call    GetEmbedObject ("attach",   datapatch$ & new_nameobj, doc )
                
            '    Msgbox object.Name 
            '    Call  object.Remove
                Kill  datapatch$ & new_nameobj
            End If
            
        End If
        i=i+1 
    End Forall
    
    Call doc.ComputeWithForm(False, False)
    
    Call    doc.Save(1,0)
    Call uidoc.save
    Print "11."
'    Set rtitem = doc.GetFirstItem("attach")
'    Forall obj In rtitem.EmbeddedObjects
'        Print  object.Source
'        For i = 1 To Len(object.Source)
'            ch = Mid$(object3.Source, i, 1)
'            Print "Символ=" & ch & ",  Код(Asc)=" & Asc(ch)
'        Next    
'    End Forall
    
    
    Print "Сохранили."
'    doc.history= Cstr(Now)      + " "+  session.CommonUserName + " переименовано  приложение ("  + nameobj  + ") "   &Chr(13) & " "&Chr(13) &  doc.history(0)
    
'    doc.ReplaceItemValue({SaveOptions},{0}).SaveToDisk=False
'    Call doc.save (True,False)
'    Call uidoc.Close
'    Call ws.EditDocument(True, doc)  '  False - чтение
    Exit Sub
ErrH:
    Print "Ошибка " & Error(Err) & " в строке " & Erl    
    Exit Sub
End Sub

Поделиться

2

Re: Работа с MIME в Lotus

Вот сама функция GetEmbedObject, которая пытается сделать следующее:
в коде - fName2 - это имя файла с путем  к нему на винте, выгрузили на диск в основной кнопке.
docR - временный документ по форме "work form" у которой обязательно наличие поля "Body".


Функции и свойства, которые по факту никак не влияют на работу NotesMIMEEntity, но в документации указаны.
session.ConvertMIME = False

Любая NotesMIME запись состоит из трех заголовков.
Content-Type
Content-Disposition
Content-Transfer-Encoding


Call child.SetContentFromBytes(streamIn, |application/msword; name="| & b64Text$ & |"|, ENC_IDENTITY_BINARY)
параметры
поток / Content-Type / Content-Transfer-Encoding ENC_IDENTITY_BINARY)   ' ENC_IDENTITY_BINARY  ENC_BASE64  ENC_NONE ENC_QUOTED_PRINTABLE


При этом можно указывать
Set header = child.CreateHeader("Content-Type")
Set header = child.CreateHeader("Content-Transfer-Encoding")
Call child.EncodeContent (ENC_BASE64)

но нет смысла, так как эти же заголовки указано в SetContentFromBytes






Function GetEmbedObject(FieldName  As String,    fName As String, doc As NotesDocument)
     ' получаем FieldName - поле на лотус-форме , fName - путь к файлу+ имя файла с расширением
    On Error Goto ErrH    
    Print "Start GetEmbedObject  "  + FieldName  +"  "  + fName 
    Dim session As New NotesSession, ws As New NotesUIWorkspace, CurDataBase As NotesDataBase
    Dim body As NotesMIMEEntity, header As NotesMIMEHeader ,  child As NotesMIMEEntity
    Dim fName2 As String
    Dim uidoc As NotesUIDocument
    Set CurDataBase=session.CurrentDataBase
    Dim docR As NotesDocument'документ TMP'
    Set uidoc =ws.CurrentDocument
    Set docR = New NotesDocument( CurDataBase ) ' создали новый док в базе роутер
    
    docR.Form="work form"   '    временная форма
    docR.header ="TEST TMP"
    docR.adresed = "1"
    docR.isp = "1"
    
    
    fName2 =  Strrightback (fName,"\") 
    fName2 = Replace(fName2, Chr(5), "")      '  попытка убадить спецсимвол &#5; с русских имен файла после прикрепления.
    Print "fName2:" fName2    '   имя файла без пути к файлу
    
    file_ext$ =  Strrightback (fName2,".")       ' расширение файла
    file_name$ =  Strleftback (fName2,".")      'имя файла
    
    session.ConvertMIME = False   ' будет ли Domino автоматически конвертировать MIME в RichText и обратно
    Dim streamIn As NotesStream
    Set streamIn =  session.CreateStream 
    Call streamIn.Open(fName,  "KOI8-R")    '    KOI8-R   
    
    Set body = docR.CreateMIMEEntity("Body")
    
    Dim b64 As New CBase64()  
    b64Text$ =  b64.encodeString (fName2)       '  КОДИРУЕМ В64  имя файла
    Print "//" + b64Text$  + "//"
    b64Text$  = "=?KOI8-R?B?" + b64Text$   +  "?="                 '  обернуть   имя файла с расширением   в  =?UTF-8?B?...?=       =?windows-1251?B?
     'b64Text$  = "=?KOI8-R?B?" + b64Text$   +  "?="  
    Print b64Text$ 
    
     '                           -------------------------------------------------------------   МИМЕ
    Set header = body.CreateHeader("Content-Type")
    Call header.SetHeaderVal({"multipart/mixed";}) 
    
    'Dim textPart As NotesMIMEEntity
    'Set textPart = body.CreateChildEntity()
    
    Dim stream As NotesStream
    Set stream = session.CreateStream
    'Call stream.WriteText("Text of message. 123 ПРОВЕРКАААА!")
    'Call textPart.SetContentFromText(stream, {text/html; charset="windows-1251"},ENC_NONE)  '  KOI8-R
    
    Set child = body.CreateChildEntity()       '  ФАЙЛ
    ' SetContentFromBytes - поток / Content-Type / Content-Transfer-Encoding ENC_IDENTITY_BINARY)   ' ENC_IDENTITY_BINARY  ENC_BASE64  ENC_NONE ENC_QUOTED_PRINTABLE 
    
    
    
    Set header = child.CreateHeader("Content-Disposition")     
    Call header.setHeaderVal( |attachment; filename="| & b64Text$ & |"|        )       ' ПРАВИЛЬНЫЙ ВАРИАНТ
    
    
'        Set header = child.CreateHeader("Content-Type")      '   ВТОРОЙ ПАРАМЕТР SetContentFromBytes - не надо менять
'        Call header.SetHeaderVal(|"application/octet-stream; name="| & b64Text$ & |"|)   
    
    Set header = child.CreateHeader("Content-Description")       '   дополнительно, не обязательно
    Call header.setHeaderVal( fName2 )
    
    Call child.SetContentFromBytes(streamIn, |application/msword; name="| & b64Text$ & |"|, ENC_IDENTITY_BINARY)
    
'    Set header = child.CreateHeader("Content-Transfer-Encoding")     ' — как закодированы данные ТРЕТИЙ  ПАРАМЕТР SetContentFromBytes - не надо менять
'    Call header.setHeaderVal( "binary")    'base64
    
      'Call child.EncodeContent (ENC_BASE64)      ' меняет заголовок Content-Transfer-Encoding , отрабатывает в ТРЕТЬЕМ ПАРАМЕТРЕ SetContentFromBytes 
    Messagebox child.Headers
    
    session.ConvertMIME = True
    flag = docR.Closemimeentities(True)
    Print  "flag " flag
    Call docR.Save(True, True    )
    
    Call streamIn.Close()
    
    Print "OK"
    
    Dim ftuidoc As NotesUIDocument
    Set ftuidoc = ws.EditDocument( True, docR , True ,  , True, False )'  временный док
    Call ftuidoc.GoToField( "Body" )
    Call ftuidoc.SelectAll
    Call ftuidoc.Copy
    Call ftuidoc.Close(True)'  временный док
    
    Call uidoc.GoToField(FieldName )    
    Call uidoc.Paste
    Call uidoc.Refresh    
    Call uidoc.Save
    
    
    Print "GetEmbedObject Конец"
    
    Exit Function
ErrH:
    Print "Ошибка GetEmbedObject" & Error(Err) & " в строке " & Erl    
    Exit Function
End Function

Поделиться

3

Re: Работа с MIME в Lotus

Вот как лотус хранит вложение абв.doc, если его прикрепить в рич-поле с включенным МИМЕ.

Field Name: $FILE
Data Type: Attached Object
Object Type: File
File Name: абв.doc
Host: MSDOS/OS2
Compression Type: LZ1 2
Encoding Type:

Field Name: Body
Data Type: MIME Part

"--=_mixed 0045D271C2258D09_=
Content-Type: application/octet-stream; name="=?KOI8-R?B?wcLXLmRvYw==?="
Content-Disposition: attachment; filename="=?KOI8-R?B?wcLXLmRvYw==?="
Content-Transfer-Encoding: binary

абв.doc"

Поделиться

4

Re: Работа с MIME в Lotus

А вот что получается при программном прикреплении файла с помощью NotesMIMEEntity в лотус 9.

Field Name: $FILE
Data Type: Attached Object
Object Type: File
File Name: 00000


Field Name: Body
Data Type: MIME Part
Data Length: 589 bytes
Seq Num: 1
Dup Item ID: 1
Field Flags: SIGN SEAL

"
--==IFJRGLKFGIR17547UHRUHIHD
Content-Type: application/msword; name="=?KOI8-R?B?MAQwBDAEMAQwBDAEMAQwBDAEMAQwBCAAIAAgADEEMQQxBDEEMQQxBDEEMQQxBDEEMQQxBCAAIAAg
Content-Disposition: attachment;
  filename="=?KOI8-R?B?MAQwBDAEMAQwBDAEMAQwBDAEMAQwBCAAIAAgADEEMQQxBDEEMQQxBDEEMQQxBDEEMQQxBCAAIAAgACAAMgQyBDIEMgQyBDIEMgQyBDIEMgQyBDIEMgQyBDIEMgQgACAAIAAzBDMEMwQzBDMEMwQzBDMEMwQzBDMELgBkAG8AYwA=?="
Content-Description:.doc

0000

Поделиться

5

Re: Работа с MIME в Lotus

В лотус клиенте 14 иконка отображается, но имя файла только в варианте
0╙0┘ 1╙1┘ 2╙2┘ 3╙3┘ 4╙4┘.doc

Такие символы  характерны для случая, когда KOI8-R или UTF-8 байты интерпретируются как CP866 (DOS) или CP437.

Поделиться