1

How do we send or upload a data file to a server on Pharo. I saw some example of sending file from a directory on the machine. It works fine.

ZnClient new
  url: MyUrl;
  uploadEntityfrom: FileLocator home /Path to the file;
  put

In my case I don't want to send/upload file downloaded on a machine but instead I want to send/upload a file hosted somewhere or data I retrieved over the network and send it attached to another server. How can we do that ?

ludo
  • 543
  • 3
  • 14

1 Answers1

3

Based on your previous questions I presume you are using linux. The issue here is not within Smalltak/Pharo, but the network mapping.

FTP

If you want to have a ftp, don't forget it is sending password in plaintext, set-up it a way you can mount it. There are probably plenty of ways to do this but you can try using curlftpfs. You need kernel module fuse for that, make sure you have it loaded. If it is not loaded you can do so via modprobe fuse.

The usage would be:

curlftpfs ftp.yoursite.net /mnt/ftp/ -o user=username:password,allow_other

where you fill username/password. The option allow_other allows other users at the system to use your mount. (for more details you can see arch wiki and its curlftpfs)

Webdav

For webdav I would use the same approach, this time using davfs

You would manually mount it via mount command:

mount -t davfs https://yoursite.net:<port>/path /mnt/webdav

There are two reasonable way to setup it - systemd or fstab. The information below is taken from davfs2 Arch wiki:

For systemd:

/etc/systemd/system/mnt-webdav-service.mount

[Unit]
Description=Mount WebDAV Service
After=network-online.target
Wants=network-online.target

[Mount]
What=http(s)://address:<port>/path
Where=/mnt/webdav/service
Options=uid=1000,file_mode=0664,dir_mode=2775,grpid
Type=davfs
TimeoutSec=15

[Install]
WantedBy=multi-user.target

You can create an systemd automount unit to set a timeout:

/etc/systemd/system/mnt-webdav-service.automount

[Unit]
Description=Mount WebDAV Service
After=network-online.target
Wants=network-online.target

[Automount]
Where=/mnt/webdav
TimeoutIdleSec=300

[Install]
WantedBy=remote-fs.target

For the fstab way it is easy if you have edited fstab before (it behaves same as any other fstab entry):

/etc/fstab

https://webdav.example/path /mnt/webdav davfs rw,user,uid=username,noauto 0 0

For webdav you can even store the credentials securely:

Create a secrets file to store credentials for a WebDAV-service using ~/.davfs2/secrets for user, and /etc/davfs2/secrets for root:

/etc/davfs2/secrets

https://webdav.example/path davusername davpassword

Make sure the secrets file contains the correct permissions, for root mounting:

# chmod 600 /etc/davfs2/secrets
# chown root:root /etc/davfs2/secrets

And for user mounting:

$ chmod 600 ~/.davfs2/secrets

Back to your Pharo/Smalltalk code:

I presume you read the above and have either /mnt/ftp or /mnt/webdav mounted.

For e.g. ftp your code would simply take from the mounted directory:

ZnClient new
  url: MyUrl;
  uploadEntityfrom: FileLocator '/mnt/ftp/your_file_to_upload';
  put

Edit Bassed on the comments.

The issue is that the configuration of the ZnClient is in the Pharo itself and the json file is also generated there.

One quick and dirty solution - would be to use above mentined with a shell command:

With ftp for example:

| commandOutput |

commandOutput := (PipeableOSProcess command: 'curlftpfs ftp.yoursite.net /mnt/ftp/ -o user=username:password,allow_other') output.
Transcript show: commandOutput.

Other approach is more sensible. Is to use Pharo FTP or WebDav support via FileSystemNetwork.

To load ftp only:

Gofer it
    smalltalkhubUser: 'UdoSchneider' project: 'FileSystemNetwork';
    configuration;
    load.
#ConfigurationOfFileSystemNetwork asClass project stableVersion load: 'FTP'

to load Webdav only:

Gofer it
    smalltalkhubUser: 'UdoSchneider' project: 'FileSystemNetwork';
    configuration;
    load.
#ConfigurationOfFileSystemNetwork asClass project stableVersion load: 'Webdav'

To get everything including tests:

Gofer it
    smalltalkhubUser: 'UdoSchneider' project: 'FileSystemNetwork';
    configuration;
    loadStable.

With that you should be able to get a file for example for ftp:

| ftpConnection wDir file |

"Open a connection"
ftpConnection := FileSystem ftp: 'ftp://ftp.sh.cvut.cz/'.
"Getting working directory"
wDir := ftpConnection workingDirectory.
file := '/Arch/lastsync' asFileReference.
"Close connection - do always!"
ftpConnection close.

Then your upload via (ftp) would look like this:

| ftpConnection wDir file |

"Open connection"
ftpConnection := FileSystem ftp: 'ftp://your_ftp'.
"Getting working directory"
wDir := ftpConnection workingDirectory.
file := '/<your_file_path' asFileReference.
ZnClient new
     url: MyUrl;
     uploadEntityfrom: FileLocator file;
     put
"Close connection - do always!"
ftpConnection close.

The Webdav would be similar.

Community
  • 1
  • 1
tukan
  • 17,050
  • 1
  • 20
  • 48
  • In my case I retrieve a json file that is saved into a variable. Using the fileLocator I can't seem to assign a directory this way – ludo Sep 04 '18 at 10:18
  • @ludo Ah, that is completely different workflow than I imagined. Could you please be more specific at your question. How do you get your `json` file and how to you intend to use it. – tukan Sep 04 '18 at 11:20
  • Yes sure. I have a canvas where I can draw a rectangle. Then with Pharo I am able to collect the cords of this rectangle which I convert to a json. Now I need to send or upload this json as attachment to a server using a PUT request. So here I have a variable containing the Json. – ludo Sep 04 '18 at 11:29
  • @ludo Ok, where do you have do you then store the connection information to your FTP or WebDav? – tukan Sep 04 '18 at 12:10
  • I would normally use a simple ZnClient however I don't see much how to attach the json data. – ludo Sep 04 '18 at 12:30
  • @ludo Ah, I see. I thought you have this information stored externally (outside Pharo). I'll edit the answer. – tukan Sep 04 '18 at 12:45
  • No only internally. Thanks – ludo Sep 04 '18 at 13:14