studip-fuse is a FUSE (file-system in user-space) driver that provides files from lectures in the course management tool Stud.IP on your computer.
studip-fuse uses the official Stud.IP REST API and authenticates via OAuth1, which will open a prompt in your browser on the first start.
Password-based login via the standard Stud.IP login (using HTTP Basic Auth --login-method basic
) or Shibboleth (--login-method shib
) is also possible.
All connections to the university servers transporting the login data are made via HTTPS and your credentials will not be copied or distributed in any other way.
Install the debian packages python3
(providing binary python3
version ≥ 3.6), python3-pip
(providing binary pip3
version ≥ 9) and fuse
on your system via apt:
sudo apt install python3 python3-pip fuse
And install the python package studip-fuse from GitHub for your current user.
pip3 install git+https://github.com/N-Coder/studip-fuse --user
Now you can try mounting your Stud.IP files (optionally pointing --studip-url
to the api.php
endpoint of your Stud.IP instance and providing the appropriate --login-method
):
mkdir Stud.IP
studip-fuse mueller123 ~/Stud.IP --pwfile=- --foreground
To mount the drive you can also use the standard mount
tool if you installed studip-fuse
globally:
$ sudo -i
# pip3 install git+https://github.com/N-Coder/studip-fuse
# mount -t fuse -o allow_other,uid=1000,gid=1000 "studip-fuse#mueller123" /home/user/Stud.IP
If you're running the driver in the background (i.e. by not passing the --foreground
option), all status messages (e.g. warnings about an invalid password) will be sent to the system log running under /dev/log
.
You can unmount the folder and kill the driver the usual way:
# umount /home/user/Stud.IP # or, alternatively also with user rights:
$ fusermount -u ~/Stud.IP
To display file status information emblems and add an "Open on Stud.IP" option menu entry in Nautilus, run the following command to install the plug-in:
$ studip-fuse-install-nautilus-plugin
Checking requirements...
Installing studip-fuse Nautilus extension to /home/user/.local/share/nautilus-python/extensions...
Copying script source code to /home/user/.local/share/nautilus-python/extensions/studip_fuse_nautilus_plugin.py...
Done installing, please restart Nautilus to enable the plugin.
This program has been tested on
- Ubuntu 18.04 using Python 3.6.7 and pip 9.0.1
- Fedora 29 using Python 3.7.2 and pip 18.1
using the Stud.IP instance of University of Passau (https://uni-passau.de/studip) and the Stud.IP Developer Instance (http://develop.studip.de/studip/).
Ubuntu 16.04 is no longer officially supported, because it only ships python 3.5.2, but aiohttp requires ≥ 3.5.3.
Currently, three different methods for logging in to Stud.IP are supported via --login-method
:
- `basic`
- This can be used if your Stud.IP instance uses the built-in authentication system. Use this, if your login page looks like this and/or the Basic Auth dialog popping up when you open the `api.php` URL accepts your credentials.
- `shib`
- This can be used if your Stud.IP instance uses Shibboleth Single Sign-On. Use this, if your login page looks like this. Please note that this login method parses the HTML responses of the Shibboleth server that corresponds to `--shib-url`, so things might break.
- `oauth`
- This should be available for any Stud.IP instance, as long as you registered an OAuth application with the administrator of the instance and provide the appropriate `--oauth-client-key`, or your instance provided built-in client keys in studip_fuse/launcher/oauth_tokens.py.
The following routes need to be available from the API defined by --studip-url
:
discovery
,user
,studip/settings
,studip/content_terms_of_use_list
,studip/file_system/folder_types
,extern/coursetypes
,semesters
,user/:user_id/courses
,course/:course_id/top_folder
,folder/:folder_id
,file/:file_ref_id
,file/:file_ref_id/download
The list is also checked at every startup, see REQUIRED_API_ENDPOINTS in studip_fuse/studipfs/api/session.py. If any of the routes is not available and a HTTP error 403 "route not activated" is returned, please contact the administrators of your Stud.IP instance.
Any of the following commands should work interchangeably for installing Stud.IP-FUSE
pip3 install --user git+https://github.com/N-Coder/studip-fuse
pip3 install --user --editable git+https://github.com/N-Coder/studip-fuse
or after a git clone
of this repository and cd
ing to that directory
pip3 install --user .
pip3 install --user --editable .
python3 ./setup.py install --user
python3 ./setup.py develop --user
If you think anything regarding your installation broke, try running pip3 uninstall studip-fuse
until the package is no longer found and then reinstalling.
$ studip-fuse -h
usage: studip-fuse [-h] [-o O [O ...]] [-d] [-v] [--debug-aio] [--format FORMAT] [--cache-dir CACHE_DIR]
[--studip-url STUDIP_URL] [--login-method {shib,oauth,basic}] [--pwfile PWFILE] [--shib-url SHIB_URL]
[--oauth-client-key OAUTH_CLIENT_KEY] [--oauth-session-token OAUTH_SESSION_TOKEN] [--oauth-no-login]
[--oauth-no-browser] [--oauth-no-store] [-f] [-s] [--allow-other] [--allow-root] [--nonempty]
[--umask UMASK] [--uid UID] [--gid GID] [--default-permissions] [--debug-fuse] [-V]
user mount
studip-fuse is a FUSE (file-system in user-space) driver that provides files from lectures in the course management
tool Stud.IP on your computer.
positional arguments:
user Stud.IP username
mount path to mount point
optional arguments:
-h, --help show this help message and exit
-o O [O ...] FUSE-like options (default: None)
-d, --debug turn on all debugging options (default: False)
-v, --debug-logging turn on debug logging (default: False)
--debug-aio turn on asyncio debug logging (default: False)
-V, --version show program's version number and exit
Stud.IP Driver Options:
--format FORMAT format specifier for virtual paths
(default: {semester-lexical}/{course-class}/{course}/{course-type}/{short-path}/{file-name})
--cache-dir CACHE_DIR, --cache CACHE_DIR
path to cache directory (default: /home/user/.cache/Stud.IP-Fuse)
--studip-url STUDIP_URL, --studip STUDIP_URL
Stud.IP API URL (default: https://studip.uni-passau.de/studip/api.php/)
Authentication Options:
--login-method {shib,oauth,basic}
method for logging in to Stud.IP session (default: oauth)
--pwfile PWFILE path to password file or '-' to read from stdin (for 'basic' and 'shib' auth)
(default: /home/user/.config/Stud.IP-Fuse/.studip-pw)
--shib-url SHIB_URL, --sso SHIB_URL
Stud.IP SSO URL (default: https://studip.uni-passau.de/studip/index.php?again=yes&sso=shib)
--oauth-client-key OAUTH_CLIENT_KEY
path to JSON file containing OAuth Client Key and Secret
(default: [internal key for given Stud.IP instance])
--oauth-session-token OAUTH_SESSION_TOKEN
path to file where the session keys should be read from/stored to
(default: /home/user/.config/Stud.IP-Fuse/.studip-oauth-session)
--oauth-no-login disable interactive OAuth authentication when no valid session token is found (default: False)
--oauth-no-browser don't automatically open the browser during interactive OAuth authentication (default: False)
--oauth-no-store don't store the new session token obtained after logging in (default: False)
FUSE Options:
-f, --foreground run in foreground (default: False)
-s, --nothreads single threads for FUSE (default: False)
--allow-other allow access by all users (default: False)
--allow-root allow access by root (default: False)
--nonempty allow mounts over non-empty file/dir (default: False)
--umask UMASK set file permissions (octal) (default: None)
--uid UID set file owner (default: None)
--gid GID set file group (default: None)
--default-permissions enable permission checking by kernel (default: False)
--debug-fuse enable FUSE debug mode (includes --foreground) (default: False)
Options can either be specified using --key=value
or -o key=value
, so the following to lines are identical regarding the option values:
studip-fuse mueller123 /home/user/Stud.IP --allow_root --uid=1000 --gid=1000
mount -t fuse -o allow_root,uid=1000,gid=1000 "studip-fuse#mueller123" /home/user/Stud.IP
You can use the following values in the format string for the generated paths:
- path
- path to the file, relative to the root folder of the course
Example: Hauptordner/Skript/PDF-Versionen - short-path
- path to the file, relative to the root folder of the course, stripped from common parts
Example: Skript/PDF-Versionen - semester
- full semester name
Example: Wintersemester 2018-2019 - semester-id
- system-internal hexadecimal UUID of the semester
Example: 36bd96b432c1169978c1594d2251e629 - semester-lexical
- full semester name, allowing alphabetic sorting
Example: 2018 WS -19 - semester-lexical-short
- shortened semester name, allowing alphabetic sorting
Example: 2018WS - semester-short
- shortened semester name
Example: WS 18-19 - course
- official name of the course, usually excluding its type
Example: Algorithmen und Datenstrukturen - course-abbrev
- abbreviation of the course name, generated from its initials
Example: AuD - course-class
- type of the course (teaching, community,...)
Example: Lehre - course-description
- optional description given for the course
- course-group
- user-assigned (color-)group of the course on the Stud.IP overview page
Example: 7 - course-id
- system-internal hexadecimal UUID of the course
Example: eceaf9871792e0339797d1be91f9015d - course-location
- room where the course is held
- course-number
- number assigned to the course in the course catalogue
Example: 5200 - course-subtitle
- optional subtitle assigned to the course
- course-type
- type of the course (lecture, exercise,...)
Example: Vorlesung - course-type-short
- abbreviated type of the course, usually the letter appended to the course number in the course catalogue
Example: V - file-description
- optional description given for the file
Example: Kapitel 1 - file-downloads
- number of times the file has been downloaded
Example: 3095 - file-id
- system-internal hexadecimal UUID of the file
Example: 8556e68de68b5e33d8d4572057431233 - file-mime-type
- file's mime-type detected by Stud.IP
Example: application-pdf - file-name
- (base-)name of the file, including its extension
Example: A+D141.pdf - file-size
- file size in bytes
Example: 3666701 - file-storage
- how the file is stored on the Stud.IP server
Example: disk - file-terms
- terms on which the file might be used
Example: SELFMADE_NONPUB
You can combine these formatting options in any way you like, e.g.:
studip-fuse mueller123 ~/Stud.IP --format="{semester-lexical-short}/{course-abbrev} {type-abbrev}/{short-path}/{author} - {name}"
Not all combinations have been tested, if you encounter any problems with a (sensible) combination, please open a bug report. Please note that depending on your path format, generating folder listings could become very slow. For example using the format "{course}/{semester-lexical-short} {type-abbrev}/{short-path}/{name}" would require listing all your courses from all your semesters, which might take a while.
To get more information on the files in your Stud.IP folder, have a look at their xargs:
$ attr -l '~/Stud.IP/2014 SS/Lehre/Algorithmen und Datenstrukturen/Vorlesung/Skript/PDF-Versionen/A+D141.pdf'
The following keys are available:
- "studip-fuse.known-tokens"
- JSON-object with all the tokens mentioned above and their corresponding values for the respective file
- "studip-fuse.json"
- big JSON-object with *all* the information we got from the Stud.IP REST API
- "studip-fuse.contents-status"
- string indicating whether the contents of the file or folder are available yet:
pending, available, failed, unknown or unavailable - "studip-fuse.contents-excpetion"
- exception that prevented the contents of the file or folder from being loaded
- "studip-fuse.url"
- absolute URL to the object in the Stud.IP web interface
This driver obeys the Unix philosophy of doing one thing well and working together with other programs. Advanced features, for which generic solutions already exists, haven't been implemented redundantly to keep the program simple.
For this reason, the following details are design-decisions and no bugs:
- the whole mount is read-only, so no modification to the downloaded files is possible.
- all information is cached in a static, but lazy way. This means that once you open a folder or file, its contents will be loaded once and stay the same throughout the whole lifetime of the program, even if they are changed online. To load the updated information, you need to restart the driver. Note: If a file didn't change online, its previously downloaded version may still be reused. Directories will always be loaded anew.
- the driver needs to have a working internet connection to load new directories or files. Making already loaded files and folder persistently available when working offline is not guaranteed.
- when mounting in background mode, problems with the Stud.IP API (e.g. wrong password) will only be detected after the program forks to background. This problem will be reported to the syslog and the program exits.
...but there are existing tools that fix this peculiarities:
- to keep all files available for offline use, just use a standard synchronization tool like rsync (example config) or syncthing (with the driver running on your server).
- to update information that has changed online, mount studip-fuse via autofs, so that it will be unmounted automatically once you don't need it anymore. Once you access the folder again, the driver will be started anew and load the new information.
- to make local changes to the files, use overlayfs to make the read-only studip-fuse filesystem writeable by storing the changes in a separate location (example config). This also enables you to delete (i.e. hide) and rename files and folders, while renamed entities will still update their contents when they are changed online.
- to wait for successful startup, check the file
studip-status.txt
in theuser_data_dir
, which will be appended once the driver completed starting up. See here on how to use usetail
andgrep
for this.