Mini Shell

Direktori : /opt/imh-python/lib/python2.7/site-packages/rads/
Upload File :
Current File : //opt/imh-python/lib/python2.7/site-packages/rads/userdata.py

#!/opt/imh-python/bin/python2.7
"""Code for parsing /var/cpanel/userdata"""

from __future__ import absolute_import, unicode_literals
import os
import yaml
from rads.exceptions import UserDataError

def _read_userdata_yaml(user, domfile, required):
    """Internal helper function for UserData to strictly parse YAML files"""
    path = os.path.join('/var/cpanel/userdata', user, domfile)
    try:
        with open(path) as handle:
            data = yaml.load(handle)
            assert isinstance(data, dict)
    except IOError:
        raise UserDataError('{0!r} could not be opened'.format(path))
    except ValueError:
        raise UserDataError('{0!r} could not be parsed as YAML'.format(path))
    except AssertionError:
        raise UserDataError('{0!r} is invalid; not a YAML dict'.format(path))
    for key, req_type in required.iteritems():
        if key not in data:
            raise UserDataError('{0!r} is missing {1!r}'.format(path, key))
        if not isinstance(data[key], req_type):
            raise UserDataError(
                '{0!r} contains invalid data for {1!r}'.format(path, key)
            )
    data['has_ssl'] = os.path.isfile('{}_SSL'.format(path))
    return data

class UserData(object):
    """Object representing the data parsed from userdata.
    
    vars() can be run on this object to convert it into a dict.
    
    Raises rads.exceptions.UserDataError on invalid userdata
    
    Attributes:
      user: username
      primary: UserDomain object for the main domain
      addon: list of UserDomain objects for addon domains
      parked: list of UserDomain objects for parked domains
      subs: list of UserDomain objects for subdomains
      merged_roots: list of merged, top-level docroots"""
    def __init__(self, user):
        """Initializes a UserData object given a cPanel username"""
        self.user = user
        main_data = _read_userdata_yaml(
            user=user,
            domfile='main',
            required={
                'main_domain': str,
                'addon_domains': dict,
                'parked_domains': list,
                'sub_domains': list
            }
        )
        dom_data = _read_userdata_yaml(
            user=user,
            domfile=main_data['main_domain'],
            required={'documentroot': str}
        )
        # populate primary domain
        self.primary = UserDomain(
            domain=main_data['main_domain'],
            has_ssl=dom_data['has_ssl'],
            docroot=dom_data['documentroot']
        )
        # populate addon domains
        self.addons = []
        for addon, addon_file in main_data['addon_domains'].iteritems():
            addon_data = _read_userdata_yaml(
                user=user,
                domfile=addon_file,
                required={'documentroot': str}
            )
            self.addons.append(UserDomain(
                domain=addon,
                has_ssl=addon_data['has_ssl'],
                docroot=addon_data['documentroot']
            ))
        # populate parked domains
        self.parked = []
        for parked in main_data['parked_domains']:
            self.parked.append(UserDomain(
                domain=parked,
                has_ssl=False,
                docroot=self.primary.docroot
            ))
        # populate subdomains
        self.subs = []
        for sub in main_data['sub_domains']:
            sub_data = _read_userdata_yaml(
                user=user,
                domfile=sub,
                required={'documentroot': str}
            )
            self.subs.append(UserDomain(
                domain=sub,
                has_ssl=sub_data['has_ssl'],
                docroot=sub_data['documentroot']
            ))
    def __repr__(self):
        return 'UserData({0.user!r})'.format(self)
    @property
    def __dict__(self):
        return {
            'user': self.user,
            'primary': vars(self.primary),
            'addons': [vars(x) for x in self.addons],
            'parked': [vars(x) for x in self.parked],
            'subs': [vars(x) for x in self.subs]
        }
    @property
    def all_roots(self):
        """All site document roots"""
        all_dirs = set([self.primary.docroot])
        all_dirs.update([x.docroot for x in self.subs])
        all_dirs.update([x.docroot for x in self.addons])
        return list(all_dirs)
    @property
    def merged_roots(self):
        """Merged, top-level document roots for a user"""
        merged = []
        for test_path in sorted(self.all_roots):
            head, tail = os.path.split(test_path)
            while head and tail:
                if head in merged:
                    break
                head, tail = os.path.split(head)
            else:
                if test_path not in merged:
                    merged.append(test_path)
        return merged

class UserDomain(object):
    """Object representing a cPanel domain.
    
    vars() can be run on this object to convert it into a dict.
    
    Attributes:
      domain: domain name
      has_ssl: True/False if the domain has ssl
      docroot: document root on the disk"""
    def __init__(self, domain, has_ssl, docroot):
        self.domain = domain
        self.has_ssl = has_ssl
        self.docroot = docroot
    def __repr__(self):
        return (
            "UserDomain(domain={0.domain!r}, has_ssl={0.has_ssl!r}, "
            "docroot={0.docroot!r})".format(self)
        )
    @property
    def __dict__(self):
        myvars = {}
        for attr in ('domain', 'has_ssl', 'docroot'):
            myvars[attr] = getattr(self, attr)
        return myvars

Zerion Mini Shell 1.0