Security fix: uploaded files are renamed into hashed filename.

This solves unrestricted file upload vulnerability with the Media system (for example, by uploading a class document ending in .php).

Uploaded files are renamed to a hash of their generated URL (which includes the date and the filename; for class documents the class ID is prepended) before saving. When downloading, a response is used that includes file content but also the original filename so that it saves properly.
Merge branch 'safemedia' of github.com:uakfdotb/ESP-Website into safemediatmp
Merge branch 'main' of github.com:learning-unlimited/ESP-Website into safemediatmp
Allow administrators to view all QSDMedia files
Use os.path.join so media files can be fetched on different platforms
Add a migration for existing qsdmedia objects to hashed names

The new naming system applies to all files that get uploaded.  However,
the server has a lot of existing files that need to be converted in order
for links to work.
Update migration to rename instead of re-save files

The qsdmedia migration just added was using target_file.save() to give the
file a new name.  Not only was this leaving the previous file in place, it
was assigning a new directory to the file based on the current date.  That
meant all uploaded files were being moved from their separate directories
(one per month) into just one directory, named for the current month.
Using os.rename() and directly modifying the target_file database field
fixes this.
Simplify Media.safe_filename()
Use os.path.join correctly in qsdmedia2 view
Merge pull request #658 from learning-unlimited/safemedia

Upload files with hashed filename - updated