forthebadge forthebadge Gem Version

FtpParadise - Introduction

This README file contains FTP-related information about the ruby scripts that are part of the FtpParadise project.

Currently the most important part of the FTP Paradise project is the Library around the Ruby-FTP base library, and an interactive component that can check on the given user-input.

A simple GUI also exists to support the extended FTP functionality, but this GUI is extremely limited - I recommend to use the commandline variant instead. (The commandline variant is also significantly faster, in my experience.)

Since as of March 2014 a web-interface of some sorts is available too, currently being offered as a sinatra-app and a .cgi file. This is also limited, so again: prefer to use the commandline variant whenever possible.

The interactive component can be used to connect to remote websites by making use of the script called iftp at bin/iftp. This file is distributed with the project.

The name iftp indicates towards "interactive_ftp", which describes its functionality best - it allows you to interactively enter commands, which will then be evaluated in the context of FTP. (Evidently you have to first connect to the remote website via your FTP login credentials, so make sure to do that first before inputting commands.)

Requiring the FtpParadise library

Simply do the following in order to require this project:

require 'ftp_paradise'

Please do note that rather than the various .set_ methods, you could also use traditional = methods instead.

So, for instance:

set_port()

is the very same as using a direct setter method such as:

port=

This is mostly for convenience. Use in your code whatever you prefer. Most may prefer foo=, I like to read a leading set_ though, visually.

Autoconnecting (Added as of December 2017)

This presently works only on my home system, by checking whether the environment variable IS_ROEBE was set. If it was set, and if an upload event occurs before we have connected somewhere, then we will first connect.

This functionality could be changed to include any way to auto-connect, but for now, this has to suffice.

In September 2018, an additional option has been added. The file automatically_connect_on-statup_of_the_interactive_ftp_shell.yml has been created. If its content is set to true, and if we are on roebe, and we start the interactive ftp-shell, then we will automatically connect to the remote shevy-FTP site.

This obviously is only useful on my home system, but it could in theory be expanded to include other FTP sites as well.

Readline support

The interactive component of the FtpParadise project will try to make use of the readline module, if it is available. Not every ruby version installed may have support for Readline, though, so this must be optional.

If you do not want to use readline or do not need it, you can pass the flag --no-readline to disable this for the current invocation.

iftp --no-readline

(Where iftp stands short for interactive ftp.)

Using FTP Paradise it in a project:

First, you must require this gem, as stated above:

require 'ftp_paradise'

Then you can use Ruby code such as this one here:

_ = FtpParadise::Connection.new("science_news")
_.set_user 'the_name_of_your_user_here' # <-- this is optional
_.set_port '21'                         # <-- this is also optional
_.connect_to 'insert_the_ftp_host_here'
_.run # Start transation (as in, try to login).

Note that most of the above is completely optional and thus can be omitted.

It simply allows you to fine tune when you need to set these entries.

Convenience methods exist of course, for instance:

  FtpParadise.connect to: 'url here'

A much simpler alternative to the above is to provide a Hash with all that required information instead.

If you don't want to connect the very moment a new Library class is instantiated, then you can do the following:

  _ = FtpParadise::Connection.new :dont_run

You can also directly upload a file, by using a class_method such as this one here:

  FtpParadise.upload(this, to)

Class methods (or rather, module methods in this case), will be stored in the file module.rb.

A pure commandline-program also exists, called:

  ftp_upload

Check it's --help option for its available options.

Uploading content to a remote FTP server

Remember that you can do all of this via the official ruby FTP bindings already - I only wanted to be able to do so interactively as well.

Uploading from the interactive FTP paradise executable can be done by giving numbers. The FTP paradise project will assume that any numbers given, will refer to the index position of the current working directory.

That is, index 7 would mean file position at 7 in the current directory:

upload 7,8

The above instructions would try to upload file number 7 and 8 to the remote host. Of course you could use the file name instead directly - the numbers are just there for convenience. Less to type when in an interactive mode.

Also note that this refers only to files. Directories will be ignored for this purpose. This behaviour may change in the future, but then again it may not. (The default is mostly what is the most convenient and most used behaviour; for me it is a LOT more common to just quickly upload files to a remote ftp server, so the number support above prefers files too.)

To upload files do:

upload foo.txt

You can upload several files by using , as a delimiter:

upload 6,7

This would upload file 6 and file 7.

If you wish to batch-upload some .pdf files, you can try this:

upload *pdf

To simply batch-upload the content of the current working directory, this should suffice:

upload *

General use cases for the interactive FTP component - using the interactive component

The interactive FTP component allows you to do several ftp-related commands via an interactive interface. I needed this functionality so that I can connect to remote FTP servers and quickly do things such as creating a directory, removing it, renaming files, uploading and downloading content.

Once you are all set and finished working with the Interactive Ftp component of the ftp_paradise project, you can type q or quit to exit from it again - or simply hit Ctrl-D, which achieves the same, more or less.

To start the interactive ftp component, you can issue a command such as:

_ = FtpParadise::InteractiveFtp.new

This should start the interactive component of the FtpParadise project.

If you want a simplified API call, you can also use:

_ = FtpParadise.interactive

instead. This variant has the benefit of being more succinct.

Once inside the main loop there, the one that will continually fetch user input, you can issue "help" to get help.

The same syntax that is used via uploading content, can also be used by downloading, such as via:

download 8
download 8,9
download 1,2,3

In short, we can use positional numbers to handle files and directories. The number 3 means "whatever is at the third position", be it a file or a directory.

You can also specifically download a binary file by issuing:

download_remote_file test.bin

You can show the full path to a file, both remote or local, if you wish to.

For this do either of:

toggle show show_names

If you wish to remove all remote entries from a remote directory, do issue this command:

remote_remove *

You can also upload from the commandline, by using the script ftp_upload:

ftp_upload file_that_should_exist_comes_here.txt
ftp_upload *

The latter command would simply upload all the found files in the current directory.

You can also do the above in binary mode:

ftp_upload file --binary

Editor

You can query which editor is in use, in the interactive FTP component of the FtpParadise project, by issuing this command:

editor?

You can also assign another editor in use, via:

set_editor vim # Use "vim" as the editor.

This value is used when you wish to quickly modify a file from within the interactive_ftp component. The latter is triggered via:

edit NAME_OF_THE_FILE_HERE
edit foobar.md # <- an example

Remote Hosts

If you need to determine the remote host, you can use this toplevel method:

FtpParadise.remote_host?

This will return nil if no connection has been made as of yet.

FtpParadise::Entry

This small class will represent a remote entry, that is, the entries that you get via .list() from a FTP-object.

It contains useful methods such as .is_a_directory? or .is_a_file?.

The graphical user interface (ruby-gtk3)

There exists a small ruby-gtk3 client for the ftp_paradise gem.

In July 2022 the project was rewritten from scratch, with the ruby-gtk3 client as the new primary focus for this gem.

In order to use this client, you first have to install the gtk3 gem, and then do:

gem install gtk_paradise

For selecting a local file, you currently have to double-click. At some later point I will extend this to one-click only.

A screenshot follows next, showcasing this GUI:

The difference between .putbinaryfile() and .puttextfile()

.putbinaryfile() is used for a file transfer to the remote server in binary mode.

.puttextfile() is used to transfer a local file to the remote server in ASCII (aka text) mode.

So what is the difference?

Well, first we have to determine whether there is a difference. Yes, there is - meaning you may end up receiving corrupt files during FTP transfer if the upload was handled incorrectly, aka the wrong mode was used.

Ok, so we now know that we have to use the correct mode if possible.

An example for a binary file is an image file such as foobar.jpg. Note that TYPE I means I for Image, which is the same thing as binary, as far as the FTP protocol is concerned.

The TYPE A command, on the other hand, where A stands for ASCII, is to be used if the transfer mode should be in ASCII.

So which files should be transferred in binary mode?

The following "table" gives a few examples here:

Image files:   .jpg, .bmp, .png
Sound files:   .mp3, .avi, .wma
Video files:   .flv, .mkv, .mov, .mp4 
Archive files: .zip, .rar, .tar
Other files:   .exe, .doc, .xls, .pdf

Note that typically binary mode is the default.

So when to use the ASCII transfer mode?

Well - it is is recommended to use it only if you want to transfer text files, such as a .md file or a .txt file.

Text files that use UTF-8 character encoding should not be transferred via ASCII mode. Examples for these are Japanese or Chinese text files.

But why is it necessary to use the ASCII transfer mode?

This is due to the way end-of-lines (EOLs) are handled. In FTP, EOLs in ASCII files (such as text files) are denoted by carriage return+line feed (CRLF) pairs (see RFC959).

The FtpParadise::Shell - the interactive component of the FTP Paradise

The interactive component of the FtpParadise project will properly tell the user whether he/she is connected to a remote host or whether the user is not connected, since as of the version 1.0.35.

You can start the interactive shell via:

bin/ftp_paradise_shell
ftp_paradise_shell # <- This works if you have that file added to your $PATH

If you need to determine manually whether you are connected, do input this command in the interactive shell:

connected?

Licence

The licence for this gem is the MIT licence.

Basically the most important part of the MIT licence is that, aside from you being able to use the project as you see fit, is the no warranty disclaimer to avoid any potential misuse from the use of the software at hand.

You can read up on this licence here:

https://opensource.org/licenses/MIT

The usual copyright assignment is:

Copyright 2023 Robert Heiler

Contact information and mandatory 2FA coming up in 2022

If your creative mind has ideas and specific suggestions to make this gem more useful in general, feel free to drop me an email at any time, via:

shevy@inbox.lt

Before that email I used an email account at Google gmail, but in 2021 I decided to slowly abandon gmail, for various reasons. In order to limit the explanation here, allow me to just briefly state that I do not feel as if I want to promote any Google service anymore when the user becomes the product (such as via data collection by upstream services). I feel this is a hugely flawed business model.

Do keep in mind that responding to emails may take some time, depending on the amount of work I may have at that moment.

In 2022 rubygems.org, or rather the corporate overlords who control the rubygems.org infrastructure these days, decided to make 2FA mandatory for every gem owner eventually: see https://blog.rubygems.org/2022/06/13/making-packages-more-secure.html

Mandatory 2FA will eventually be extended to all rubygems.org developers and maintainers. As I can not use 2FA, for reasons I will skip explaining here, this means that my projects will eventually be taken over by shopify (or, correspondingly, whoever effectively controls the rubygems.org ecosystem). At that point, I no longer have any control what is done to my projects since shopify (respectively those controlling the gems ecosystem) took away control here. Not sure at which point ruby became corporate-controlled - that was not the case several years ago.

Ruby also only allows 2FA users to participate on the issue tracker these days:

https://bugs.ruby-lang.org/issues/18800

(Note that this was changed a few months ago, so the last part is no longer valid - it is possible to register again without mandating 2FA. I will retain the above notice for a bit longer, though, as I feel we should not restrict communication via mandatory authentification in general. Fighting spam is a noble goal, but when it also means you lock out real human people then this is definitely NOT good.)