#!/usr/libexec/platform-python

"""
    workspace++

    ws_register

    python version of ws_register command, no privileges necessary

    create links for all workspaces in a selected directory, delete
    links to no longer valid workspaces.
    Reads new YAML configuration files and new YAML workspace database.

    differences to old workspace version
    - usage if YAML file format
    - more options for administrator (configured and root)
            + list expired/moved workspaces

    (c) Holger Berger 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020
    (c) Bernd Krisckok 2017

    workspace++ is based on workspace by Holger Berger, Thomas Beisel and Martin Hecht

    workspace++ is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    workspace++ is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with workspace++.  If not, see <http://www.gnu.org/licenses/>.

"""

from __future__ import print_function

import os, os.path, pwd, grp, sys
import glob, time
from optparse import OptionParser

# read a single line from ws.conf of the form: pythonpath: /path/to/python
def read_python_conf():
    for l in open("/etc/ws.conf","r"):
        if 'pythonpath' in l:
            key=l.split(":")[0].strip()
            value=l.split(":")[1].strip()
            if key == 'pythonpath':
                if os.path.isdir(value):
                    sys.path.insert(0,value)
                    break
                else:
                    print("Warning: Invalid pythonpath in ws.conf", file=sys.stderr)

read_python_conf()

import yaml


# who are we?
uid = os.getuid()
gid = os.getgid()
user = pwd.getpwuid(uid)[0]
group = grp.getgrgid(gid)[0]
groups = [grp.getgrgid(gid_tmp)[0] for gid_tmp in os.getgroups()]


# load config file
config = yaml.load(open('/etc/ws.conf'))


usage="Usage: ws_restore [options] directory"

# option configuration
parser = OptionParser(usage=usage)
parser.add_option('-F', '--filesystem', dest='filesystem', help='filesystem to search workspaces in')
(options, args) = parser.parse_args()

if len(args)==0:
    print(usage, file=sys.stderr)
    sys.exit(-1)

dirname = args[0]


# all filesystems or a selected one?
if(options.filesystem): 
    if options.filesystem in config['workspaces']:
        filesystems = [options.filesystem]
    else:
        print("Error: no such filesystem.", file=sys.stderr)
        sys.exit(-1)
else:
    filesystems = config['workspaces'].keys()

# reduce list to allowed filesystems
legal=[]
for f in filesystems:
    userok=True
    if 'user_acl' in config['workspaces'][f] or 'group_acl' in config['workspaces'][f]:
        userok=False
    if 'group_acl' in config['workspaces'][f]:
        for g in groups:
            if g in config['workspaces'][f]['group_acl']:
                userok=True
                break
            if group in config['workspaces'][f]['group_acl']:
                userok=True
    if 'user_acl' in config['workspaces'][f]:
            if user in config['workspaces'][f]['user_acl']:
                userok=True
    # admin can see workspaces from anywhere, but can also restrict
    if userok:
        legal.append(f)


# main loop


if not os.path.isdir(dirname):
    os.mkdir(dirname)

for fs in legal:
    keeplist=[]
    dbfilename='%s/%s-*' % (config["workspaces"][fs]['database'], user)
    wsdirs=[]
    if not os.path.isdir(dirname+"/"+fs):
        os.mkdir(dirname+"/"+fs)
    for fname in glob.glob(dbfilename):
        f=yaml.load(open(fname)) 
        try:
            wsname=f['workspace']
        except TypeError:
            f=open(fname).readines()
            wsname=f[1][:-1]
        keeplist.append(dirname+"/"+fs+"/"+os.path.basename(wsname))
        if not (os.path.exists(dirname+"/"+fs+"/"+os.path.basename(wsname)) or 
                       (os.path.islink(dirname+"/"+fs+"/"+os.path.basename(wsname)))):
            os.symlink(wsname,dirname+"/"+fs+"/"+os.path.basename(wsname))
    # delete links not beeing workspaces anymore
    for f in glob.glob(dirname+"/"+fs+"/*"):
        if os.path.islink(f):
            if not f in keeplist:
                os.unlink(f)
            else:
                print("keep",f)

