fileshack

drop your items

fileshack allows you to create your own simple, hosted web file storage

Getting Started

Installation

Fileshack can be hosted on your own server. Fileshack is based on the web development framework Django. In order to deploy fileshack on your server, you first need to have a working web server such as nginx. For installation on nginx, follow the sections Built-in server setup and then nginx and gunicorn. The instructions assume that the operating system is Linux or BSD.

In the instructions below, substitute /home/user/www/fs/ with your installation directory and fileshack.example.org with the domain name of your server. The domain name has to be correctly configured in the DNS to resolve to the server's IP address.

Built-in server setup

  1. Install Python 3 from you distribution package repositories. On APT:
    apt install python3
  2. Create a new Python virtual environment (venv):
    mkdir -p /home/user/www
    cd /home/user/www
    python3 -m venv fs
    cd fs
    . bin/activate
  3. Install django inside the virtual environment:
    pip3 install django
  4. Clone the fileshackproject repository:
    git clone git://github.com/peterkuma/fileshackproject.git
    cd fileshackproject
  5. Copy and customize the local settings example file:
    cp fileshackproject/settings_local-example.py fileshackproject/settings_local.py
    vi fileshackproject/settings_local.py
    Normally, you do not need to modify anything except for ADMINS, SECRET_KEY, and uncommenting DEBUG = False once your installation works properly.
  6. Initialize database:
    ./manage.py migrate --run-syncdb
    ./manage.py createsuperuser
    You will be asked to create a superuser account, by which you can later log in to the administration interface at http://fileshack.example.org/admin/. This command also creates a default store.
  7. Collect static files into the static directory:
    ./manage.py collectstatic --noinput
  8. At this point you can try to run fileshack with the integrated development server:
    ./manage.py runserver
    The default store should be accessible at http://localhost:8000. If everything works fine, continue with setting up nginx.

nginx and gunicorn

This configuration below assumes installation on a Debian-derived Linux distribution with systemd.
  1. Install nginx and gunicorn3 from your distribution package repositories. On APT:
    apt install nginx gunicorn3
  2. Add the domain on which you want to host the fileshack to ALLOWED_HOSTS in the configuration file fileshackproject/settings_local.py:
    ALLOWED_HOSTS = ['fileshack.example.org']
  3. Create a new gunicorn systemd service /etc/systemd/system/gunicorn-fileshack.service:
    [Unit]
    Description=gunicorn-fileshack
    After=network.target
    [Install]
    WantedBy=multi-user.target
    [Service]
    User=user
    Group=user
    Restart=always
    ExecStart=/usr/bin/gunicorn3 --workers=4 --log-file=/home/user/www/fs/gunicorn-fileshack.log --bind unix:/home/user/www/fs/fileshack.sock --timeout 300 fileshackproject.wsgi
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s TERM $MAINPID
    WorkingDirectory=/home/user/www/fs/fileshackproject/
    Environment=PYTHONPATH=/home/user/www/fs/lib/python3.x/site-packages
    PrivateTmp=true
    In the configuration above, change user to the user under which you want to run fileshack, and change python3.x to the version Python version installed on your system. Register and start the systemd service.
    systemctl enable gunicorn-fileshack
    systemctl start gunicorn-fileshack
  4. Create a new site in nginx configuration /etc/nginx/sites-available/fileshack:
    server {
        listen 80;
        listen [::]:80;
        root /home/user/www/fs/;
        server_name fileshack.example.org;
        client_max_body_size 0;
        location / {
            proxy_pass http://unix:/home/user/www/fs/fileshack.sock;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_read_timeout 300s;
        }
        location /static/ {
            alias /home/user/www/fs/fileshackproject/static/;
        }
        location /media/ {
            alias /home/user/www/fs/fileshackproject/media/;
        }
    }
    Create a symlink to the site configuration in nginx sites-enabled:
    ln -s /etc/nginx/sites-available/fileshack /etc/nginx/sites-enabled/
    Test and reload nginx with:
    service nginx testconfig
    service nginx reload

Fileshack should now be accessible at http://fileshack.example.org. You can manage stores in the administration interface at http://fileshack.example.org/admin/. It is highly recommended that you also set up an SSL certificate for the domain, such as with Let's Encrypt, and set up an access code on the default store.

Do not forget to set DEBUG = False in settings_local.py before going public. Otherwise, users are presented with ugly HTTP 404 and HTTP 500 pages, potentially revealing sensitive information.

If you encounter any problems, please send an e-mail to the mailing list at fileshack-general@lists.sourceforge.net.

Store watching (optional)

Fileshack allows users to opt in to receive e-mail notifications when new files are uploaded. When enabled, a Watch button is displayed next to the Logout button, allowing users to enter an e-mail address to which to send notifications. However, several more steps need to be taken in order to support this feature.

Cron

If you want your fileshack installation to support store watching, you have to set up periodic requests to the service which sends the notifications:

http://fileshack.example.org/cron/

For security reasons, access to this URL is allowed only from hosts specified in the configuration variable FILESHACK_CRON_HOSTS, or to those who present with the shared secret FILESHACK_CRON_SECRET.

On Linux and other unix-like systems, periodic requests to a URL can be accomplished by a scheduled command in the system daemon cron. In order to schedule such a request every 10 minutes, create a file /etc/cron.d/fileshack:

# Run scheduled tasks of the web application fileshack.
#
*/10 * * * * user python3 -c 'import sys; import urllib.request; f=urllib.request.urlopen("http://fileshack.example.org/cron/", b"secret=yoursecret"); f.status==200 or sys.stdout.buffer.write(f.read())'

Replace user with your username, and fileshack.example.org with the correct hostname of your fileshack installation.

If the hostname is not localhost, you will have to set up a shared secret. Replace yoursecret in the command above with your chosen secret, and set FILESHACK_CRON_SECRET in fileshackproject/settings_local.py to the same value.

Alternatively, you can add the IP address of the cron machine to FILESHACK_CRON_HOSTS. In this case, you do not have to supply the shared secret. By default, FILESHACK_CRON_HOSTS contains only localhost.

If anything goes wrong with the cron command, you should receive an e-mail with the command output on your user account from cron. In any case, you can test by executing the python command above in the console. Alternatively, the same can be accomplised more simply with:
curl -d secret=yoursecret http://fileshack.example.org/cron/
Settings

Store watching requires several configuration variables to be set up properly — mail server settings EMAIL_*, FILESHACK_EMAIL_FROM and SECRET_KEY in fileshackproject/settings_local.py. Mail server settings are described in detail in the django documentation.

You have reload the gunicorn-fileshack service in order for the new settings to be applied:
service gunicorn-fileshack restart
If you do not set SECRET_KEY, users will not be able to unsubscribe via a link in notification messages. These links are protected by HMAC, which requires a private secret.
Admin

In Sites, modify the example.org domain to reflect your domain setting.

Finally, you can enable Allow watch in your chosen stores. To prevent bothering users with copious amounts of messages, at most one notification is sent per 6-hour period to a particular e-mail address. This can be tuned by the Watch delay option.

Compatibility

Fileshack is known to work with at least the following browsers:

Drag & Drop and progress indication are not supported in all browsers.

Release Notes

Fileshack 1.0.2(9 August 2021)

  • Fixed store watching.

Fileshack 1.0.1(4 August 2021)

  • Various fixes required to run on modern browsers and with nginx/gunicorn.

Fileshack 1.0(3 August 2021)

  • Migration to Python 3 and Django 3.1.

Fileshack 0.9(25 June 2012)

  • Files are not read into memory in full, but uploaded by File.slice() if available. This greatly reduces memory footprint and improves performance when uploading large files.
  • It is now possible to upload multiple files at once.
  • Fixed handling of unicode characters in file names.
  • Sessions now last until the browser is closed.
  • Fixed error message in Opera on expired session.

Fileshack 0.8(27 April 2012)

  • Store watching.
  • Fixed HTTP 404 page.
  • Logout is now protected against CSRF.
  • Django 1.4 timezone support.

Fileshack 0.7(18 April 2012)

  • Fixed uploading to custom (non-default) stores.
  • Fixed enforcement of store size limit.
  • Fixed error dialog placement.
  • Improved uploading in IE. Items are now replaced in-place without a refresh, and errors are reported in the usual way via an error dialog.
  • Open stores with an empty access code are now allowed.

Fileshack 0.6(29 March 2012)

  • Fixed uploading in Safari 5 on Snow Leopard.
  • Fixed regression in IE and Firefox 3.5.
  • Tweaked style to better support small screens.

Fileshack 0.5(28 March 2012)

  • Fixed uploading in Firefox 3.5.
  • Fixed style in some legacy browsers.

Fileshack 0.4(27 March 2012)

  • Fixed upload indication in IE 8 and 9.
  • Fixed dropbox text in IE 7.
  • Fixed delete in IE 7 and 8.

Fileshack 0.3(26 March 2012)

  • Fixed upload by Drag & Drop in Safari.
  • Fixed dropbox text when Drag & Drop is not supported.

Fileshack 0.2(25 March 2012)

  • Support for Safari and IE6-9.

Fileshack 0.1(20 March 2012)

  • Initial release.

How does it work?

Fileshack uses one of the following methods of uploading a file, listed from the most sophisticated to the least sophisticated:

  1. XMLHttpRequest with File API. File is read into browser memory by FileReader and uploaded by chunks. During upload, chunk size is tuned so that an optimal upload time is achieved. If upload fails, it can be resumed by starting from the last uploaded chunk. File upload progress is show. This method is supported by Firefox, Google Chrome and Opera. However, as Opera does not support XMLHttpRequest.upload, upload progress is coarse (by chunks).
  2. XMLHttpRequest with FormData. File is upload in full by XMLHttpRequest.send(FormData). Resume of a failed upload is not supported. Upload progress is indicated. This method is chosen for browers not supporting File API, such as Safari.
  3. Submitting a hidden iframe. This is a trick allowing submitting a file without displaying a file input element. Click on the dropbox is delegated to a file input element inside a hidden iframe, in order to circumvent a security check in IE not allowing to submit a form when a click was delegated. No progress indication is supported. This method is supported by browsers such as IE8 and IE9.
  4. Explicit file input element. An input element is displayed inside the dropbox. This method is chosen for browsers such as IE7.

Contributing

You can contribute by reporting issues, forking or joining the project as a developer on github. Thank you!