FTP repository, like Git... sort of...


FTP repository, like Git... sort of...

I want to be able to access many of my scripts/projects, from everywhere. So, uploading them to a server is the only solution. Until now, i was using Git repositories. For sure it's the best way to do so, but there is only one problem. I don't want all of my projects to be visible/accessible by others. Make them private, you would say... sure. But then you have to login every time and use two way authentication, all the time, which is safe, but it gets in my nerves, specially if you have to do so, multiple times.

Simple FTP is not the safest way to store things. Use it on your own risk.

The solution for me, is to use an FTP server and create something like Github, but in a more simpler way. If you don't know, there is also FTP Git, that uses FTP server to store repositories, exactly like Github, but because i wanted a simpler solution, i preferred another way...

So, i created fgitish a BASH script, that uses the Linux ftp program, to upload/download my projects, on a private FTP server, with parameters like Git and some twists. The main principle is to store each project in a .zip file, into a default directory on the ftp server. The directory, except the .zip files, will also contain an index.txt file, like the old FTP sites, that will store the name of the project and a small one line description, just to keep track, of what is what.

Below is the syntax for the script. When you want to store a project, just from within the directory of the project, you enter fgitish push. The script will create a .zip file, with the name of the current directory and store it, on the ftp directory, you set up.

If you want to download or clone a project, you can use the clone, flist, index commands to do so. Each one has a twist and its usefulness. To keep track of the files/projects, you can use the index.txt file. Give fgitish edit to create or edit the file, to add descriptions to each project.

Usage: fgitish <command> [args]

 From Remote to Local
   clone <file>  Clone file into current directory
   get <file>    Get specific file (don't extract)
   edit          Edit the index file
   remove        Remove remote file

 List Projects/Files
   list          List Files in remote directory
   flist         Lists files and select one to download
   index         Show Index file and select file to download

 From Local to Remote
   push          Uploads current dir as an archive to remote server

You can get the script below. Make sure to enter your ftp username, password, host and directory to store your files/projects. You can also store the username/password values in a separate file, if you don't want them to be in the script file. You could also use a method to encrypt/decrypt them on the fly and store them encrypted in that file.

#!/bin/bash
script="${0##*/}"
#script="${script%.*}"
DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# server settings
HOST='ftp.host.com'
FTPDIR='fgitish'

# user password
if [ -f ~/scripts/ftppassword.asc ]; then
  source ~/scripts/ftppassword.asc
else
  USER='username'
  PASSWD='password'
fi

# other settings
EDITOR="nano"

#yellow start 
    C14="\e[1;33m"
#blue start 
    C01="\e[0;34m"
#color end
    CE="\e[0m"
#red start
    C04="\e[1;31m"
#black start
    C00="\e[0;30m"
#dark gray start
    C08="\e[1;30m"
#light blue start
    C09="\e[1;34m"
#green start
    C02="\e[0;32m"
#light green start
    C10="\e[1;32m"
#cyan start
    C03="\e[0;36m"
#light cyan start
    C11="\e[1;36m"
#light red start
    C12="\e[0;31m"
#purple start
    C05="\e[0;35m"
#light purple start
    C13="\e[1;35m"
#brown start
    C06="\e[0;33m"
#light gray start
    C07="\e[0;37m"
#white 
    C15="\e[1;37m"

#setting frequent stings
    YNYES="("$C14"Y"$CE"/"$C14"n"$CE")("$C14"Enter"$CE"=yes)"
    YNNO="("$C14"y"$CE"/"$C14"N"$CE")("$C14"Enter"$CE"=no)"

VERSION=1.0.0
READAK="read -n 1"

function msg() {
  ts=$(date +"%Y/%m/%d %H:%M:%S")
  echo -e $C03"[$ts] "$C14"$1"$CE
}

function error() {
  ts=$(date +"%Y/%m/%d %H:%M:%S")
  echo -e $C03"[$ts] "$C04"$1"$CE
}

function presskey() {
  echo ""
  echo "Press a key to continue..."
  read -n 1
}

prompt_confirm_no() {
  while true; do
    echo -e -n "${1:-Continue?} ${YNNO}: "
    read -e -r -n 1 REPLY
    case $REPLY in
      [yY]) echo ; return 0 ;;
      [nN]) echo; echo "Going back..."; sleep 1; return 1 ;;
      $'\0A') echo; echo "Going back..."; sleep 1; return 1 ;;
      *) printf " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

prompt_confirm_yes() {
  while true; do
    echo -e -n "${1:-Continue?} $YNYES: "
    read -e -r -n 1 REPLY
    case $REPLY in
      [yY]) echo ; return 0 ;;
      [nN]) echo; echo "Going back..."; return 1 ;;
      $'\0A') echo; echo "Accepted..."; return 0 ;;
      *) printf " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

function fzz() {
  #"right,50%,:wrap"
  fzf --ansi --bind 'enter:execute(echo {1})+abort' --bind 'end:last' --bind 'home:first' --header $"Listing: $FTPDIR | ENTER: Accept | ESC: Abort"
  }

function list(){
  msg "Connecting..."
  ftp -V -i -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
ls
quit
END_SCRIPT
if [ $? -ne 0 ]; then
  error "Connection... Failed!"
  return 1
fi
msg "Success!"  
}

function flist(){
  msg "Connecting..."
  ftp -V -i -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
ls . /tmp/listing.txt
quit
END_SCRIPT
if [ $? -ne 0 ]; then
  error "Connection... Failed!"
  return 1
fi

fn="$(cat /tmp/listing.txt | awk '{print $9}' | fzz)"
if [ ! -z "$fn" ]; then
  get "$fn"
fi
}

function get(){
  msg "Connecting..."
  fn="$1"
  if [ "${fn: -4}" != ".zip" ]; then
    fn="$fn".zip
  fi
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
  msg "Success!"
else
  error "Failed!"
fi  
}

function remove(){
  msg "Connecting..."
  fn="$1"
  if [ "${fn: -4}" != ".zip" ]; then
    fn="$fn".zip
  fi
  ftp -i -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
mdelete "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
  msg "File removed!"
else
  error "Failed!"
fi  
}

function index(){
  msg "Connecting..."
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get index.txt
quit
END_SCRIPT
if [ $? == 0 ]; then
  msg "Success!"
else
  error "Failed!"
fi  
  sel=$(cat index.txt | fzz | cut -f1 -d' ')
  if [ ! -z $sel ]; then
    clone $sel
  fi
  rm index.txt
}

function edit(){
  msg "Getting file..."
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get index.txt
quit
END_SCRIPT

if [ -f index.txt ]; then
  msg "Edit file..."
  $EDITOR index.txt
  msg "Uploading file..."
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
put index.txt
quit
END_SCRIPT
  if [ $? == 0 ]; then
    msg "File uploaded successful!"
    rm ./index.txt
  else
    error "Failed to upload file"
  fi
else
  error "File not found or couldn't be downloaded!"
fi

}

function clone(){
fn="$1"
if [ ! "$fn" == "*.zip" ]; then
  fn="$fn".zip
fi
msg "Connecting..."
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
get "$fn"
quit
END_SCRIPT
if [ $? -ne 0 ]; then
  error "Connection... Failed!"
  return 1
fi
msg "Connection... Success!"
dr="${fn%.*}"
msg "Cloning in: $dr"
mkdir $dr
msg "Extracting content..."
unzip "$1" -d ./$dr
rm "$fn"
msg "Done!"
}

function send(){
  fn="$(basename "$PWD")".zip
  zip -r "/tmp/$fn" .
  cd /tmp
  msg "Uploading file..."
  ftp -V -n $HOST <<END_SCRIPT
user ${USER} ${PASSWD}
cd ${FTPDIR}
put "$fn"
quit
END_SCRIPT
if [ $? == 0 ]; then
  msg "Success!"
else
  error "Failed!"
fi  
rm "$fn"
}

if [ $# -eq 0 ]; then
    echo " "
    echo "Usage: fgitsh <command> [args]"
    echo " "
    echo -e $C14" From Remote to Local"$CE
    echo -e $C15"   clone <file> $C07 Clone file into current directory"$CE
    echo -e $C15"   get <file>   $C07 Get specific file (don't extract)"$CE
    echo -e $C15"   edit         $C07 Edit the index file"$CE
    echo -e $C15"   remove       $C07 Remove remote file"$CE
    echo " "
    echo -e $C14" List Projects/Files"$CE
    echo -e $C15"   list         $C07 List Files in remote directory"$CE
    echo -e $C15"   flist        $C07 Lists files and select one to download"$CE
    echo -e $C15"   index        $C07 Show Index file and select file to download"$CE
    echo " "
    echo -e $C14" From Local to Remote"$CE
    echo -e $C15"   push         $C07 Uploads current dir as an archive to remote server"$CE
    echo " "
    exit 1
fi

case "$1" in
  "list") list;;
  "push") send;;
  "flist") flist;;
  "clone") clone "$2";;
  "get") get "$2";;
  "edit") edit;;
  "index") index;;
  "remove") remove "$2";;
  *) echo "Unknown command!";;
esac

Add a comment

Previous