EDI over FTP help

321 views
Skip to first unread message

David

unread,
May 16, 2013, 1:09:47 PM5/16/13
to bots...@googlegroups.com
Bit of a tricky one this.

Basically I have to send/retrieve some EDI files via an FTP server. Great, easy etc.

Except its not really an FTP server its an EDI mailbox pretending to be an FTP server so all of the standard responses are incorrect.

Firstly it falls over on asking for the current directory as it doesn't get a response it recognises from the pwd command, if you manually ftp you can see why

C:\ >ftp EDI.TEST.HOST
Connected to EDI.TEST.HOST. 
220 Enterprise FTP server ready. 
User (EDI.TEST.HOST:(none)): <username> 
331 User name okay, need password. 
Password: 
230-User logged in, proceed. 
Current Default Relationship - Recv: XXXXXMSOUT APRF: *BINARY 
Get option: single 
230 
ftp> pwd 
200-Command Okay. 
ID: XXXXXMSOUT, Current TR - Recv: NAKANMSOUT, APRF: *BINARY, Dir: S. 
Get option: single. 
200 
ftp>


Now I've traced that pwd back to communication.py

def set_cwd(self):
self.dirpath = self.session.pwd()

   if self.channeldict['path']:
      self.dirpath = posixpath.normpath(posixpath.join(self.dirpath,self.channeldict['path']))
      try:
         self.session.cwd(self.dirpath) #set right path on ftp-server
      except:
         self.session.mkd(self.dirpath) #set right path on ftp-server; no nested directories
         self.session.cwd(self.dirpath) #set right path on ftp-server


Now if I remove the line "self.dirpath = self.session.pwd()" it 'works'[1] but that is obviously *not* the way to do this properly so either I have to prevent the set_cwd(self) from running or write a total custom communication script to do ftp.

What is the best way round this? Does anyone have an ftp communication script to replace the build in ftp that they're willing to share?

Regards

David

[1] Kind of, overall it still reports a fail but it does upload the file, it just gives an error of

AttributeError: 'ftp' object has no attribute 'dirpath'




henk-jan ebbers

unread,
May 16, 2013, 2:03:13 PM5/16/13
to bots...@googlegroups.com
yes, met a simular thing once - but slighty different.
ftp-system was 'posten' - a swedisch VAN.

when using communiationscript looks like:
class UserCommunicationClass(communication.ftp):
@botslib.log_session
def incommunicate(self):
#rest of code, I usually copy from communication.py


guess you cna not set a directory in ftp-session?


kind regards,
henk-jan
> --
> You received this message because you are subscribed to the Google Groups "Bots Open Source EDI Translator" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

David

unread,
May 16, 2013, 3:35:15 PM5/16/13
to bots...@googlegroups.com
You can set a directory on uploads, there is a 'mailbox' but the CWD/PWD doesn't work, not sure about downloads, there aren't any directories there!

I'm afraid I don't know python, so might be totally wrong but something basically along these lines:

import os
import sys
import posixpath
import time
import datetime
import ftplib
#Bots modules
import botslib
import botsglobal
from botsconfig import *

class UserCommunicationClass(communication.ftp): 
     @botslib.log_session 

     def connect(self):
        botslib.settimeout(botsglobal.ini.getint('settings','ftptimeout',10))
        self.session = ftplib.FTP()
        self.session.set_debuglevel(botsglobal.ini.getint('settings','ftpdebug',0))   #set debug level (0=no, 1=medium, 2=full debug)
        self.session.set_pasv(not self.channeldict['ftpactive']) #active or passive ftp
        self.session.connect(host=self.channeldict['host'],port=int(self.channeldict['port']))
        self.session.login(user=self.channeldict['username'],passwd=self.channeldict['secret'],acct=self.channeldict['ftpaccount'])

    def outcommunicate(self): 
       #get right filename_mask 
       filename_mask = self.channeldict['filename'] if self.channeldict['filename'] else '*'
       mode = 'STOR ' # APPEnd fails
       for row in botslib.query('''SELECT idta,filename,numberofresends
                                    FROM ta
                                    WHERE idta>%(rootidta)s
                                      AND status=%(status)s
                                      AND statust=%(statust)s
                                      AND tochannel=%(tochannel)s
                                        ''',
                                    {'tochannel':self.channeldict['idchannel'],'rootidta':botslib.get_minta4query(),
                                    'status':FILEOUT,'statust':OK}):
            try:
                ta_from = botslib.OldTransaction(row['idta'])
                ta_to = ta_from.copyta(status=EXTERNOUT)
                tofilename = self.filename_formatter(filename_mask,ta_from)
                fromfile = botslib.opendata(row['filename'], 'rb')
                self.session.storbinary(mode + tofilename, fromfile)
                fromfile.close() 
            except:
                txt = botslib.txtexc()
                # It immediately drops connection on success, need to pick up the output and find out if it is actually a success.
                # For now leave in existing error handling.                
                ta_to.update(statust=ERROR,errortext=txt,filename='ftp:/'+posixpath.join(self.dirpath,tofilename),numberofresends=row['numberofresends']+1)
            else:
                ta_to.update(statust=DONE,filename='ftp:/'+posixpath.join(self.dirpath,tofilename),numberofresends=row['numberofresends']+1)
            finally:
                ta_from.update(statust=DONE)

    def disconnect(self):
        try:
            self.session.quit()
        except:
            self.session.close()
        botslib.settimeout(botsglobal.ini.getint('settings','globaltimeout',10))


Thanks

David

henk-jan ebbers

unread,
May 16, 2013, 5:27:09 PM5/16/13
to bots...@googlegroups.com
hi David,

when looking at ftp class in communication.py think you only need to change the set_cwd method in it?
what this says:
class UserCommunicationClass(communication.ftp):
is that you use a class that inherets from the normal ftp-class (in communciation.py).
something like:
class UserCommunicationClass(communication.ftp):
def set_cwd(self):
self.dirpath = ''

hope this helps,
henk-jan

btw, whose 'ftp'-server is this?
> > To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com <javascript:>.
> > For more options, visit https://groups.google.com/groups/opt_out <https://groups.google.com/groups/opt_out>.

David

unread,
May 17, 2013, 5:44:28 AM5/17/13
to bots...@googlegroups.com
Hi,

I'll give that a go although I think that the lack of proper responses may also be an issue.

Its GXS, see details here:

Regards

David

henk-jan ebbers

unread,
May 17, 2013, 6:15:52 AM5/17/13
to bots...@googlegroups.com
will have a look at it.

I worked with these guys in 1989 (called GEIS).
not after 1994, without regret ;-)

when I worked with GXS in 2005, I was shocked to see that they still worked the saem.
this is judged to be insufficient (and too expensive) in 1994...

but there is no way you can avoid them.

another way might be: do they support FTPS pr SFTP?


kind regards,
henk-jan
> > > For more options, visit https://groups.google.com/groups/opt_out <https://groups.google.com/groups/opt_out> <https://groups.google.com/groups/opt_out

henk-jan ebbers

unread,
May 17, 2013, 6:27:15 AM5/17/13
to bots...@googlegroups.com
hi David,

docs says they do support he pwd command.

henk-jan

On 05/16/2013 07:09 PM, David wrote:

David

unread,
May 17, 2013, 6:34:13 AM5/17/13
to bots...@googlegroups.com
Hi,

Yes, if I change

self.dirpath = self.session.pwd() 
to
self.dirpath = '' 

It works

My communicationscript is

# imports needed for functions below
import os
import time
import ftplib
import bots.botslib as botslib
import bots.botsglobal as botsglobal
from bots.botsconfig import *

# Don't try to get CWD from ftp server (wrong response so it fails).

class UserCommunicationClass(communication.ftp): 
     def set_cwd(self): 
         self.dirpath = '' 

# Take inv ref from filename and replace '*' in filename with it. 

def filename(channeldict,ta,filename):
    ta_list = botslib.trace_origin(ta=ta,where={'status':EXTERNIN})
    filename_in = os.path.basename(ta_list[0].filename) # just filename, remove path
    invoice = filename_in[4:10]
    return channeldict['filename'].replace('*', invoice)

but it errors with the following error:

ScriptImportError: Error in "C:\Python27\lib\site-packages\bots\bots.usersys\communicationscripts\OCI_GXS_test_ftp_out", error: NameError: name 'communication' is not defined

I'm missing defining something but I'm not sure what!

Regards

David

On Thursday, 16 May 2013 22:27:09 UTC+1, eppye wrote:

David

unread,
May 17, 2013, 6:36:08 AM5/17/13
to bots...@googlegroups.com
Hi

Yes, they support it but it doesn't reply with anything meaningful!
This is the response you get:

ftp> pwd 
200-Command Okay. 
ID: XXXXXMSOUT, Current TR - Recv: XXXXXMSOUT, APRF: *BINARY, Dir: S. 

Get option: single. 
200 
ftp>

regards

David

henk-jan ebbers

unread,
May 17, 2013, 9:24:04 AM5/17/13
to bots...@googlegroups.com
yes, think I see what happens.

python's ftp-lib expects a 257 response. see: http://www.ietf.org/rfc/rfc959.txt

like this:

ftp> pwd
257 "/web" is the current directory.
ftp




kind regards,
henk-jan
> > To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com <javascript:>.
> > For more options, visit https://groups.google.com/groups/opt_out <https://groups.google.com/groups/opt_out>.

henk-jan ebbers

unread,
Jun 12, 2013, 5:22:47 AM6/12/13
to bots...@googlegroups.com
hi David,

did you find out something about this?

would be nice to handle this is default ftp communication.

kind regards,
henk-jan

On 05/17/2013 12:36 PM, David wrote:
> > To unsubscribe from this group and stop receiving emails from it, send an email to botsmail+u...@googlegroups.com <javascript:>.
> > For more options, visit https://groups.google.com/groups/opt_out <https://groups.google.com/groups/opt_out>.
Reply all
Reply to author
Forward
0 new messages