<commit_before>import logging
import re
import urllib.parse
import urllib.request
import urllib.error
import sys
import time
import xml.etree.ElementTree

from prismriver import util

class Plugin:
    def __init__(self, plugin_id, plugin_name):
        self.plugin_id = plugin_id
        self.plugin_name = plugin_name

    def search(self, artist, title):
        pass

    def is_valid_request(self, artist, title):
        return artist and title

    def quote_uri(self, value):
        return urllib.parse.quote(value)

    def download_webpage(self, url):
        start = time.time()

        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20150101 Firefox/20.0 (Chrome)'})
        try:
            with urllib.request.urlopen(req) as response:
                the_page = response.read()
                page_size = sys.getsizeof(the_page)
                logging.debug('Download web-page from "{}", {}, {}'.format(url, util.format_file_size(page_size),
                                                                           util.format_time_ms(time.time() - start)))
                return the_page
        except urllib.error.HTTPError as err:
            logging.debug('Failed to download web-page from "{}", error: {}, {}'.format(url, err.code, err.reason))
            return None
        except ConnectionResetError as err:
            logging.debug('Failed to download web-page from "{}", error: {}, {}'.format(url, err.errno, err.strerror))
            return None

    def download_xml(self, url):
        page = self.download_webpage(url)
        if page:
            xml_string = page.decode("utf-8")
            xml_string = re.sub(' xmlns="[^"]+"', '', xml_string, count=1)
            root = xml.etree.ElementTree.fromstring(xml_string)
            return root

    def sanitize_lyrics(self, lyrics):
        if lyrics:
            sanitized = []
            for lyric in lyrics:
                if lyric:
                    sanitized.append(lyric.strip())

            return sanitized
        else:
            return None
<commit_msg>Temporary add logging for downloaded webpages<commit_after>import logging
import re
import urllib.parse
import urllib.request
import urllib.error
import sys
import time
import xml.etree.ElementTree

from prismriver import util

class Plugin:
    def __init__(self, plugin_id, plugin_name):
        self.plugin_id = plugin_id
        self.plugin_name = plugin_name

    def search(self, artist, title):
        pass

    def is_valid_request(self, artist, title):
        return artist and title

    def quote_uri(self, value):
        return urllib.parse.quote(value)

    def download_webpage(self, url):
        start = time.time()

        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20150101 Firefox/20.0 (Chrome)'})
        try:
            with urllib.request.urlopen(req) as response:
                the_page = response.read()
                page_size = sys.getsizeof(the_page)
                logging.debug('Download web-page from "{}", {}, {}'.format(url, util.format_file_size(page_size),
                                                                           util.format_time_ms(time.time() - start)))

                logging.debug('Web-page:\n {}'.format(the_page.decode("utf-8")))

                return the_page
        except urllib.error.HTTPError as err:
            logging.debug('Failed to download web-page from "{}", error: {}, {}'.format(url, err.code, err.reason))
            return None
        except ConnectionResetError as err:
            logging.debug('Failed to download web-page from "{}", error: {}, {}'.format(url, err.errno, err.strerror))
            return None

    def download_xml(self, url):
        page = self.download_webpage(url)
        if page:
            xml_string = page.decode("utf-8")
            xml_string = re.sub(' xmlns="[^"]+"', '', xml_string, count=1)
            root = xml.etree.ElementTree.fromstring(xml_string)
            return root

    def sanitize_lyrics(self, lyrics):
        if lyrics:
            sanitized = []
            for lyric in lyrics:
                if lyric:
                    sanitized.append(lyric.strip())

            return sanitized
        else:
            return None
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#  privacyIDEA is a fork of LinOTP
#
#  2018-12-14 Cornelius Kölbel <cornelius.koelbel@netknights.it>
#             Add censor-password functionality
#  2016-04-08 Cornelius Kölbel <cornelius@privacyidea.org>
#             simplify repetetive unequal checks
#
#  Nov 27, 2014 Cornelius Kölbel <cornelius@privacyidea.org>
#               Migration to flask
#               Rewrite of methods
#               100% test code coverage
#
#  May 08, 2014 Cornelius Kölbel
#  License:  AGPLv3
#  contact:  http://www.privacyidea.org
#
#  Copyright (C) 2010 - 2014 LSE Leading Security Experts GmbH
#  License:  AGPLv3
#  contact:  http://www.linotp.org
#            http://www.lsexperts.de
#            linotp@lsexperts.de
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
# License as published by the Free Software Foundation; either
# version 3 of the License, or any later version.
#
# This code 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 AFFERO GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
This is the library for creating new resolvers in the database and
deleting existing ones.
Also can create a resolver object of a class like LDAP, SQL or Passwd.

Its only dependencies are to the database model.py and to the
config.py, so this can be tested standalone without realms, tokens and
webservice!
"""

import logging

from .log import log_with
from .config import (get_resolver_types, get_resolver_classes, update_config_object)
from privacyidea.lib.usercache import delete_user_cache
from privacyidea.lib.framework import get_request_local_store
from ..models import (Resolver,
                      ResolverConfig)
from ..api.lib.utils import required
from ..api.lib.utils import getParam
from .error import ConfigAdminError
from sqlalchemy import func
from .crypto import encryptPassword, decryptPassword
from privacyidea.lib.utils import sanity_name_check
from privacyidea.lib.utils import is_true

CENSORED = "__CENSORED__"
log = logging.getLogger(__name__)

# Hide the keyswords BINDPW and Password in params
@log_with(log, hide_args_keywords={0: ["BINDPW", "Password"]})
def save_resolver(params):
    """
    create a new resolver from request parameters
    and save the resolver in the database.

    If the resolver already exist, it is updated.
    If you update a resolver, you do not need to provide all parameters.
    Parameters you do not provide are left untouched.
    When updating a resolver you must not change the type!
    You do not need to specify the type, but if you specify a wrong type,
    it will produce an error.

    :param params: request parameters like "name" and "type" and the
                   configuration parameters of the resolver config.
    :type params: dict
    :return: the database ID of the resolver
    :rtype: int
    """
    # before we create the resolver in the database, we need to check
    # for the name and type thing...
    resolvername = getParam(params, 'resolver', required)
    resolvertype = getParam(params, 'type', required)
    update_resolver = False
    # check the name
    sanity_name_check(resolvername)
    # check the type
    resolvertypes = get_resolver_types()
    if resolvertype not in resolvertypes:
            raise Exception("resolver type : {0!s} not in {1!s}".format(resolvertype, unicode(resolvertypes)))

    # check the name
    resolvers = get_resolver_list(filter_resolver_name=resolvername)
    for r_name, resolver in resolvers.items():
        if resolver.get("type") == resolvertype:
            # We found the resolver with the same name and the same type,
            # So we will update this resolver
            update_resolver = True
        else:
            raise Exception("resolver with similar name and other type already "
                            "exists: %s" % r_name)

    # create a dictionary for the ResolverConfig
    resolver_config = get_resolver_config_description(resolvertype)
    config_description = resolver_config.get(resolvertype).get('config', {})

    types = {}
    desc = {}
    data = {}
    for k in params:
        if k not in ['resolver', 'type']:
            if k.startswith('type.') is True:
                key = k[len('type.'):]
                types[key] = params.get(k)
            elif k.startswith('desc.') is True:
                key = k[len('desc.'):]
                desc[key] = params.get(k)
            else:
                data[k] = params.get(k)
                if k in config_description:
                    types[k] = config_description.get(k)
                else:
                    log.warn("the passed key %r is not a "
                             "parameter for the resolver %r" % (k,
                                                                resolvertype))

    # Check that there is no type or desc without the data itself.
    # i.e. if there is a type.BindPW=password, then there must be a
    # BindPW=....
    _missing = False
    for t in types:
        if t not in data:
            _missing = True
    for t in desc:
        if t not in data:
            _missing = True
    if _missing:
        raise Exception("type or description without necessary data! {0!s}".format(
                        unicode(params)))

    # Everything passed. So lets actually create the resolver in the DB
    if update_resolver:
        resolver_id = Resolver.query.filter(func.lower(Resolver.name) ==
                                  resolvername.lower()).first().id
    else:
        resolver = Resolver(params.get("resolver"),
                            params.get("type"))
        resolver_id = resolver.save()
    # create the config
    for key, value in data.items():
        if types.get(key) == "password":
            if value == CENSORED:
                continue
            else:
                value = encryptPassword(value)

        ResolverConfig(resolver_id=resolver_id,
                       Key=key,
                       Value=value,
                       Type=types.get(key, ""),
                       Description=desc.get(key, "")).save()

    # Remove corresponding entries from the user cache
    delete_user_cache(resolver=resolvername)

    return resolver_id

@log_with(log, log_exit=False)
#@cache.memoize(10)
def get_resolver_list(filter_resolver_type=None,
                      filter_resolver_name=None,
                      editable=None,
                      censor=False):
    """
    Gets the list of configured resolvers from the database

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: basestring
    :param filter_resolver_name: Get the distinct resolver
    :type filter_resolver_name: basestring
    :param editable: Whether only return editable resolvers
    :type editable: bool
    :param censor: censor sensitive data. Each resolver class decides on its own,
        which data should be censored.
    :type censor: bool
    :rtype: Dictionary of the resolvers and their configuration
    """
    # We need to check if we need to update the config object
    config_object = update_config_object()
    resolvers = config_object.resolver
    if filter_resolver_type:
        reduced_resolvers = {}
        for reso_name, reso in resolvers.items():
            if reso.get("type") == filter_resolver_type:
                reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if filter_resolver_name:
        reduced_resolvers = {}
        for reso_name in resolvers:
            if reso_name.lower() == filter_resolver_name.lower():
                reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if editable is not None:
        reduced_resolvers = {}
        if editable is True:
            for reso_name, reso in resolvers.items():
                check_editable = is_true(reso["data"].get("Editable")) or \
                                 is_true(reso["data"].get("EDITABLE"))
                if check_editable:
                    reduced_resolvers[reso_name] = resolvers[reso_name]
        elif editable is False:
            for reso_name, reso in resolvers.items():
                check_editable = is_true(reso["data"].get("Editable")) or \
                                 is_true(reso["data"].get("EDITABLE"))
                if not check_editable:
                    reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if censor:
        for reso_name, reso in resolvers.items():
            for censor_key in reso.get("__CENSOR_KEYS__", []):
                reso["data"][censor_key] = CENSORED

    return resolvers

@log_with(log)
def delete_resolver(resolvername):
    """
    delete a resolver and all related ResolverConfig entries
    If there was no resolver, that could be deleted, it returns -1

    :param resolvername: the name of the to be deleted resolver
    :type resolvername: string
    :return: The Id of the resolver
    :rtype: int
    """
    ret = -1

    reso = Resolver.query.filter_by(name=resolvername).first()
    if reso:
        if reso.realm_list:
            # The resolver is still contained in a realm! We must not delete it
            realmname = reso.realm_list[0].realm.name
            raise ConfigAdminError("The resolver %r is still contained in "
                                   "realm %r." % (resolvername, realmname))
        reso.delete()
        ret = reso.id
    # Delete resolver object from cache
    store = get_request_local_store()
    if 'resolver_objects' in store:
        if resolvername in store['resolver_objects']:
            del store['resolver_objects'][resolvername]

    # Remove corresponding entries from the user cache
    delete_user_cache(resolver=resolvername)

    return ret

@log_with(log, log_exit=False)
#@cache.memoize(10)
def get_resolver_config(resolvername):
    """
    return the complete config of a given resolver from the database
    :param resolvername: the name of the resolver
    :type resolvername: string
    :return: the config of the resolver
    :rtype: dict
    """
    reso = get_resolver_list(filter_resolver_name=resolvername)
    return reso.get(resolvername, {}).get("data", {})

@log_with(log)
#@cache.memoize(10)
def get_resolver_config_description(resolver_type):
    """
    get the configuration description of a resolver

    :param resolver_type: the type of the resolver. Something like
                          "passwdresolver".
    :type resolver_type: string
    :return: configuration description dict
             This should contain a key "config" that contains a dictionary
             and a key "clazz":
             {'passwdresolver': {'config': {'fileName': 'string'},
                                 'clazz': 'useridresolver.PasswdIdResolver'
                                          '.IdResolver'}}

    """
    descriptor = None
    resolver_class = get_resolver_class(resolver_type)

    if resolver_class is not None:
        descriptor = resolver_class.getResolverClassDescriptor()

    return descriptor

#@cache.memoize(10)
def get_resolver_class(resolver_type):
    """
    return the class object for a resolver type
    :param resolver_type: string specifying the resolver
                          fully qualified or abreviated
    :return: resolver object class
    """
    ret = None
    resolver_clazzes = get_resolver_classes()
    for k in resolver_clazzes:
        if k.getResolverClassType() == resolver_type:
            ret = k
            break
    return ret

#@cache.memoize(10)
def get_resolver_type(resolvername):
    """
    return the type of a resolvername

    :param resolvername: THe name of the resolver
    :return: The type of the resolver
    :rtype: string
    """
    reso_list = get_resolver_list(filter_resolver_name=resolvername)
    r_type = reso_list.get(resolvername, {}).get("type")
    return r_type

@log_with(log)
#@cache.memoize(10)
def get_resolver_object(resolvername):
    """
    Return the cached resolver object for the given resolver name (stored in the request context).
    If no resolver object is cached, create it and add it to the cache.

    :param resolvername: the resolver string as from the token including
                         the config as last part
    :return: instance of the resolver with the loaded config

    """
    r_type = get_resolver_type(resolvername)
    r_obj_class = get_resolver_class(r_type)

    if r_obj_class is None:
        log.error("Can not find resolver with name {0!s} ".format(resolvername))
        return None
    else:
        store = get_request_local_store()
        if 'resolver_objects' not in store:
            store['resolver_objects'] = {}
        resolver_objects = store['resolver_objects']
        if resolvername not in resolver_objects:
            # create the resolver instance and load the config
            r_obj = resolver_objects[resolvername] = r_obj_class()
            if r_obj is not None:
                resolver_config = get_resolver_config(resolvername)
                r_obj.loadConfig(resolver_config)
        return resolver_objects[resolvername]

@log_with(log)
def pretestresolver(resolvertype, params):
    """
    This tests, if the params will create a working resolver.
    This function can be called before a resolver is created.

    :param resolvertype:
    :param params:
    :type params: dict
    :return:
    """
    # If an already saved resolver is tested again, the password
    # could be "__CENSORED__". In this case we use the old, saved password.
    if params.get("resolver"):
        old_config_list = get_resolver_list(filter_resolver_name=params.get("resolver")) or {}
        old_config = old_config_list.get(params.get("resolver")) or {}
        for key in old_config.get("__CENSOR_KEYS__"):
            if params.get(key) == CENSORED:
                # Overwrite with the value from the database
                params[key] = old_config.get("data").get(key)

    # determine the class by the given type
    r_obj_class = get_resolver_class(resolvertype)
    (success, desc) = r_obj_class.testconnection(params)
    return success, desc
<commit_msg>make a deep copy in case of censoring the resolver config<commit_after># -*- coding: utf-8 -*-
#  privacyIDEA is a fork of LinOTP
#
#  2018-12-14 Cornelius Kölbel <cornelius.koelbel@netknights.it>
#             Add censor-password functionality
#  2016-04-08 Cornelius Kölbel <cornelius@privacyidea.org>
#             simplify repetetive unequal checks
#
#  Nov 27, 2014 Cornelius Kölbel <cornelius@privacyidea.org>
#               Migration to flask
#               Rewrite of methods
#               100% test code coverage
#
#  May 08, 2014 Cornelius Kölbel
#  License:  AGPLv3
#  contact:  http://www.privacyidea.org
#
#  Copyright (C) 2010 - 2014 LSE Leading Security Experts GmbH
#  License:  AGPLv3
#  contact:  http://www.linotp.org
#            http://www.lsexperts.de
#            linotp@lsexperts.de
#
# This code is free software; you can redistribute it and/or
# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
# License as published by the Free Software Foundation; either
# version 3 of the License, or any later version.
#
# This code 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 AFFERO GENERAL PUBLIC LICENSE for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
This is the library for creating new resolvers in the database and
deleting existing ones.
Also can create a resolver object of a class like LDAP, SQL or Passwd.

Its only dependencies are to the database model.py and to the
config.py, so this can be tested standalone without realms, tokens and
webservice!
"""

import logging

from .log import log_with
from .config import (get_resolver_types, get_resolver_classes, update_config_object)
from privacyidea.lib.usercache import delete_user_cache
from privacyidea.lib.framework import get_request_local_store
from ..models import (Resolver,
                      ResolverConfig)
from ..api.lib.utils import required
from ..api.lib.utils import getParam
from .error import ConfigAdminError
from sqlalchemy import func
from .crypto import encryptPassword, decryptPassword
from privacyidea.lib.utils import sanity_name_check
from privacyidea.lib.utils import is_true
import copy

CENSORED = "__CENSORED__"
log = logging.getLogger(__name__)

# Hide the keyswords BINDPW and Password in params
@log_with(log, hide_args_keywords={0: ["BINDPW", "Password"]})
def save_resolver(params):
    """
    create a new resolver from request parameters
    and save the resolver in the database.

    If the resolver already exist, it is updated.
    If you update a resolver, you do not need to provide all parameters.
    Parameters you do not provide are left untouched.
    When updating a resolver you must not change the type!
    You do not need to specify the type, but if you specify a wrong type,
    it will produce an error.

    :param params: request parameters like "name" and "type" and the
                   configuration parameters of the resolver config.
    :type params: dict
    :return: the database ID of the resolver
    :rtype: int
    """
    # before we create the resolver in the database, we need to check
    # for the name and type thing...
    resolvername = getParam(params, 'resolver', required)
    resolvertype = getParam(params, 'type', required)
    update_resolver = False
    # check the name
    sanity_name_check(resolvername)
    # check the type
    resolvertypes = get_resolver_types()
    if resolvertype not in resolvertypes:
            raise Exception("resolver type : {0!s} not in {1!s}".format(resolvertype, unicode(resolvertypes)))

    # check the name
    resolvers = get_resolver_list(filter_resolver_name=resolvername)
    for r_name, resolver in resolvers.items():
        if resolver.get("type") == resolvertype:
            # We found the resolver with the same name and the same type,
            # So we will update this resolver
            update_resolver = True
        else:
            raise Exception("resolver with similar name and other type already "
                            "exists: %s" % r_name)

    # create a dictionary for the ResolverConfig
    resolver_config = get_resolver_config_description(resolvertype)
    config_description = resolver_config.get(resolvertype).get('config', {})

    types = {}
    desc = {}
    data = {}
    for k in params:
        if k not in ['resolver', 'type']:
            if k.startswith('type.') is True:
                key = k[len('type.'):]
                types[key] = params.get(k)
            elif k.startswith('desc.') is True:
                key = k[len('desc.'):]
                desc[key] = params.get(k)
            else:
                data[k] = params.get(k)
                if k in config_description:
                    types[k] = config_description.get(k)
                else:
                    log.warn("the passed key %r is not a "
                             "parameter for the resolver %r" % (k,
                                                                resolvertype))

    # Check that there is no type or desc without the data itself.
    # i.e. if there is a type.BindPW=password, then there must be a
    # BindPW=....
    _missing = False
    for t in types:
        if t not in data:
            _missing = True
    for t in desc:
        if t not in data:
            _missing = True
    if _missing:
        raise Exception("type or description without necessary data! {0!s}".format(
                        unicode(params)))

    # Everything passed. So lets actually create the resolver in the DB
    if update_resolver:
        resolver_id = Resolver.query.filter(func.lower(Resolver.name) ==
                                  resolvername.lower()).first().id
    else:
        resolver = Resolver(params.get("resolver"),
                            params.get("type"))
        resolver_id = resolver.save()
    # create the config
    for key, value in data.items():
        if types.get(key) == "password":
            if value == CENSORED:
                continue
            else:
                value = encryptPassword(value)

        ResolverConfig(resolver_id=resolver_id,
                       Key=key,
                       Value=value,
                       Type=types.get(key, ""),
                       Description=desc.get(key, "")).save()

    # Remove corresponding entries from the user cache
    delete_user_cache(resolver=resolvername)

    return resolver_id

@log_with(log, log_exit=False)
#@cache.memoize(10)
def get_resolver_list(filter_resolver_type=None,
                      filter_resolver_name=None,
                      editable=None,
                      censor=False):
    """
    Gets the list of configured resolvers from the database

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: basestring
    :param filter_resolver_name: Get the distinct resolver
    :type filter_resolver_name: basestring
    :param editable: Whether only return editable resolvers
    :type editable: bool
    :param censor: censor sensitive data. Each resolver class decides on its own,
        which data should be censored.
    :type censor: bool
    :rtype: Dictionary of the resolvers and their configuration
    """
    # We need to check if we need to update the config object
    config_object = update_config_object()
    if censor:
        resolvers = copy.deepcopy(config_object.resolver)
    else:
        resolvers = config_object.resolver
    if filter_resolver_type:
        reduced_resolvers = {}
        for reso_name, reso in resolvers.items():
            if reso.get("type") == filter_resolver_type:
                reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if filter_resolver_name:
        reduced_resolvers = {}
        for reso_name in resolvers:
            if reso_name.lower() == filter_resolver_name.lower():
                reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if editable is not None:
        reduced_resolvers = {}
        if editable is True:
            for reso_name, reso in resolvers.items():
                check_editable = is_true(reso["data"].get("Editable")) or \
                                 is_true(reso["data"].get("EDITABLE"))
                if check_editable:
                    reduced_resolvers[reso_name] = resolvers[reso_name]
        elif editable is False:
            for reso_name, reso in resolvers.items():
                check_editable = is_true(reso["data"].get("Editable")) or \
                                 is_true(reso["data"].get("EDITABLE"))
                if not check_editable:
                    reduced_resolvers[reso_name] = resolvers[reso_name]
        resolvers = reduced_resolvers
    if censor:
        for reso_name, reso in resolvers.items():
            for censor_key in reso.get("__CENSOR_KEYS__", []):
                reso["data"][censor_key] = CENSORED

    return resolvers

@log_with(log)
def delete_resolver(resolvername):
    """
    delete a resolver and all related ResolverConfig entries
    If there was no resolver, that could be deleted, it returns -1

    :param resolvername: the name of the to be deleted resolver
    :type resolvername: string
    :return: The Id of the resolver
    :rtype: int
    """
    ret = -1

    reso = Resolver.query.filter_by(name=resolvername).first()
    if reso:
        if reso.realm_list:
            # The resolver is still contained in a realm! We must not delete it
            realmname = reso.realm_list[0].realm.name
            raise ConfigAdminError("The resolver %r is still contained in "
                                   "realm %r." % (resolvername, realmname))
        reso.delete()
        ret = reso.id
    # Delete resolver object from cache
    store = get_request_local_store()
    if 'resolver_objects' in store:
        if resolvername in store['resolver_objects']:
            del store['resolver_objects'][resolvername]

    # Remove corresponding entries from the user cache
    delete_user_cache(resolver=resolvername)

    return ret

@log_with(log, log_exit=False)
#@cache.memoize(10)
def get_resolver_config(resolvername):
    """
    return the complete config of a given resolver from the database
    :param resolvername: the name of the resolver
    :type resolvername: string
    :return: the config of the resolver
    :rtype: dict
    """
    reso = get_resolver_list(filter_resolver_name=resolvername)
    return reso.get(resolvername, {}).get("data", {})

@log_with(log)
#@cache.memoize(10)
def get_resolver_config_description(resolver_type):
    """
    get the configuration description of a resolver

    :param resolver_type: the type of the resolver. Something like
                          "passwdresolver".
    :type resolver_type: string
    :return: configuration description dict
             This should contain a key "config" that contains a dictionary
             and a key "clazz":
             {'passwdresolver': {'config': {'fileName': 'string'},
                                 'clazz': 'useridresolver.PasswdIdResolver'
                                          '.IdResolver'}}

    """
    descriptor = None
    resolver_class = get_resolver_class(resolver_type)

    if resolver_class is not None:
        descriptor = resolver_class.getResolverClassDescriptor()

    return descriptor

#@cache.memoize(10)
def get_resolver_class(resolver_type):
    """
    return the class object for a resolver type
    :param resolver_type: string specifying the resolver
                          fully qualified or abreviated
    :return: resolver object class
    """
    ret = None
    resolver_clazzes = get_resolver_classes()
    for k in resolver_clazzes:
        if k.getResolverClassType() == resolver_type:
            ret = k
            break
    return ret

#@cache.memoize(10)
def get_resolver_type(resolvername):
    """
    return the type of a resolvername

    :param resolvername: THe name of the resolver
    :return: The type of the resolver
    :rtype: string
    """
    reso_list = get_resolver_list(filter_resolver_name=resolvername)
    r_type = reso_list.get(resolvername, {}).get("type")
    return r_type

@log_with(log)
#@cache.memoize(10)
def get_resolver_object(resolvername):
    """
    Return the cached resolver object for the given resolver name (stored in the request context).
    If no resolver object is cached, create it and add it to the cache.

    :param resolvername: the resolver string as from the token including
                         the config as last part
    :return: instance of the resolver with the loaded config

    """
    r_type = get_resolver_type(resolvername)
    r_obj_class = get_resolver_class(r_type)

    if r_obj_class is None:
        log.error("Can not find resolver with name {0!s} ".format(resolvername))
        return None
    else:
        store = get_request_local_store()
        if 'resolver_objects' not in store:
            store['resolver_objects'] = {}
        resolver_objects = store['resolver_objects']
        if resolvername not in resolver_objects:
            # create the resolver instance and load the config
            r_obj = resolver_objects[resolvername] = r_obj_class()
            if r_obj is not None:
                resolver_config = get_resolver_config(resolvername)
                r_obj.loadConfig(resolver_config)
        return resolver_objects[resolvername]

@log_with(log)
def pretestresolver(resolvertype, params):
    """
    This tests, if the params will create a working resolver.
    This function can be called before a resolver is created.

    :param resolvertype:
    :param params:
    :type params: dict
    :return:
    """
    # If an already saved resolver is tested again, the password
    # could be "__CENSORED__". In this case we use the old, saved password.
    if params.get("resolver"):
        old_config_list = get_resolver_list(filter_resolver_name=params.get("resolver")) or {}
        old_config = old_config_list.get(params.get("resolver")) or {}
        for key in old_config.get("__CENSOR_KEYS__"):
            if params.get(key) == CENSORED:
                # Overwrite with the value from the database
                params[key] = old_config.get("data").get(key)

    # determine the class by the given type
    r_obj_class = get_resolver_class(resolvertype)
    (success, desc) = r_obj_class.testconnection(params)
    return success, desc
<|endoftext|>


<commit_before>"""
Hello
"""
import time
import json
import hmac
import hashlib
from functools import wraps

import util
import config

def sign(sign_msg, k):
    return hmac.new(k.encode('utf-8'), sign_msg.encode('utf-8'), hashlib.sha1).digest().hex()

def add_sign(cmd_msg, convid=None, action=None, peerids=None):
    peerid = cmd_msg['peerId']
    ts = time.time()
    nonce = cmd_msg.get('nonce', util.generate_id())
    peerid = peerid if convid is None else ':'.join([peerid, convid])
    peerids = '' if peerids is None else ':'.join(sorted(peerids))
    sign_msg = ':'.join([config.APP_ID, peerid, peerids, str(ts), nonce])
    sign_msg = sign_msg if action is None else ':'.join([sign_msg, action])
    cmd_msg['t'] = ts
    cmd_msg['n'] = nonce
    cmd_msg['s'] = sign(sign_msg, config.APP_MASTER_KEY)
    return cmd_msg

def with_sign(cid_field_name = None, pids_field_name = None, action_name = None):
    def sign_decorator(fn):
        @wraps(fn)
        def wrap_sign(self, cmd_msg):
            [cid, pids] = map(cmd_msg.get, [cid_field_name, pids_field_name])
            cmd_msg = add_sign(cmd_msg, convid=cid, peerids=pids, action=action_name)
            return fn(self, cmd_msg)
        return wrap_sign
    return sign_decorator

class Command:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    def process(self, router, msg):
        print("< ", json.dumps(msg))

    def build(self, cmd_msg):
        return cmd_msg

    def is_interactive_cmd(self):
        return True

class CommandWithOp(Command):
    def __init__(self, name):
        Command.__init__(self, name)
        self.sub_commands = dict()

    def add(self, sub_command):
        name = sub_command.name
        self.sub_commands[name] = sub_command

    def remove(self, sub_command):
        self.sub_commands.pop(sub_command.name, None)

    def process(self, router, msg):
        op_field = msg.get('op')
        if op_field is None or op_field not in self.sub_commands:
            super().process(router, msg)
        else:
            self.sub_commands[op_field].process(router, msg)

    def build(self, cmd_msg):
        op_field = cmd_msg.get('op')
        msg = None
        if op_field is None or self.sub_commands.get(op_field) is None:
            msg = cmd_msg
        else:
            msg = self.sub_commands[op_field].build(cmd_msg)
        msg['cmd'] = self.name
        return msg

class DirectCommand(Command):
    _name = "direct"
    def __init__(self):
        super().__init__(DirectCommand._name)

class ConvCommand(CommandWithOp):
    _name = "conv"
    def __init__(self):
        super().__init__(ConvCommand._name)

class ConvStartCommand(Command):
    _op_name = "start"
    def __init__(self):
        super().__init__(ConvStartCommand._op_name)

    @with_sign(pids_field_name='m')
    def build(self, cmd_msg):
        cmd_msg['unique'] = cmd_msg.get('unique', True)
        return cmd_msg

class ConvAddCommand(Command):
    _op_name = "add"
    def __init__(self):
        super().__init__(ConvAddCommand._op_name)

    @with_sign(pids_field_name='m', cid_field_name='cid', action_name='invite')
    def build(self, cmd_msg):
        return cmd_msg

class ConvRemoveCommand(Command):
    _op_name = "remove"
    def __init__(self):
        super().__init__(ConvRemoveCommand._op_name)

    @with_sign(pids_field_name='m', cid_field_name='cid', action_name='kick')
    def build(self, cmd_msg):
        return cmd_msg

class SessionCommand(CommandWithOp):
    _name = "session"
    def __init__(self):
        super().__init__(SessionCommand._name)

class SessionOpenCommand(Command):
    _op_name = "open"
    def __init__(self):
        super().__init__(SessionOpenCommand._op_name)

    @with_sign()
    def build(self, cmd_msg):
        cmd_msg['ua'] = cmd_msg.get('ua', config.CLIENT_UA)
        cmd_msg['configBitmap'] = 0xFFFF
        return cmd_msg

class SessionCloseCommand(Command):
    _op_name = "close"
    def __init__(self):
        super().__init__(SessionCloseCommand._op_name)

def register_session_commands():
    session_cmd = SessionCommand()
    session_cmd.add(SessionOpenCommand())
    session_cmd.add(SessionCloseCommand())

    return session_cmd

def register_conv_commands():
    conv_cmd = ConvCommand()
    conv_cmd.add(ConvStartCommand())
    conv_cmd.add(ConvAddCommand())
    conv_cmd.add(ConvRemoveCommand())

    return conv_cmd

class CommandsManager:
    def __init__(self, appid, peerid):
        cmd = register_session_commands()
        self.commands = {cmd.name: cmd}
        cmd = register_conv_commands()
        self.commands[cmd.name] = cmd
        self._next_serial_id = 1
        self._appid = appid
        self._peerid = peerid

    def process(self, router, msg):
        cmd_in_msg = msg.get('cmd')
        if cmd_in_msg is not None:
            cmd = self.commands.get(cmd_in_msg)
            if cmd is None:
                print("< ", json.dumps(msg))
            else:
                cmd.process(router, msg)
        else:
            raise RuntimeError("Receive msg without 'cmd': %s" % msg)

    def build(self, cmd_msg):
        cmd = cmd_msg['cmd']
        cmd_builder = self.commands.get(cmd)
        if cmd_builder is None:
            cmd_msg['cmd'] = cmd
            return cmd_msg
        else:
            cmd_msg['appId'] = self._appid
            cmd_msg['peerId'] = self._peerid
            msg = cmd_builder.build(cmd_msg)
            if cmd_builder.is_interactive_cmd():
                msg['i'] = self._next_serial_id
                self._next_serial_id += 1
            return msg
<commit_msg>(feat) register commands<commit_after>"""
Hello
"""
import time
import json
import hmac
import hashlib
from functools import wraps

import util
import config

def sign(sign_msg, k):
    return hmac.new(k.encode('utf-8'), sign_msg.encode('utf-8'), hashlib.sha1).digest().hex()

def add_sign(cmd_msg, convid=None, action=None, peerids=None):
    peerid = cmd_msg['peerId']
    ts = time.time()
    nonce = cmd_msg.get('nonce', util.generate_id())
    peerid = peerid if convid is None else ':'.join([peerid, convid])
    peerids = '' if peerids is None else ':'.join(sorted(peerids))
    sign_msg = ':'.join([config.APP_ID, peerid, peerids, str(ts), nonce])
    sign_msg = sign_msg if action is None else ':'.join([sign_msg, action])
    cmd_msg['t'] = ts
    cmd_msg['n'] = nonce
    cmd_msg['s'] = sign(sign_msg, config.APP_MASTER_KEY)
    return cmd_msg

def with_sign(cid_field_name = None, pids_field_name = None, action_name = None):
    def sign_decorator(fn):
        @wraps(fn)
        def wrap_sign(self, cmd_msg):
            [cid, pids] = map(cmd_msg.get, [cid_field_name, pids_field_name])
            cmd_msg = add_sign(cmd_msg, convid=cid, peerids=pids, action=action_name)
            return fn(self, cmd_msg)
        return wrap_sign
    return sign_decorator

class Command:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    def process(self, router, msg):
        print("< ", json.dumps(msg))

    def build(self, cmd_msg):
        return cmd_msg

    def is_interactive_cmd(self):
        return True

class CommandWithOp(Command):
    def __init__(self, name):
        Command.__init__(self, name)
        self.sub_commands = dict()

    def add(self, sub_command):
        name = sub_command.name
        self.sub_commands[name] = sub_command

    def remove(self, sub_command):
        self.sub_commands.pop(sub_command.name, None)

    def process(self, router, msg):
        op_field = msg.get('op')
        if op_field is None or op_field not in self.sub_commands:
            super().process(router, msg)
        else:
            self.sub_commands[op_field].process(router, msg)

    def build(self, cmd_msg):
        op_field = cmd_msg.get('op')
        msg = None
        if op_field is None or self.sub_commands.get(op_field) is None:
            msg = cmd_msg
        else:
            msg = self.sub_commands[op_field].build(cmd_msg)
        msg['cmd'] = self.name
        return msg

COMMANDS = dict()

def register_command(parent_name = None):
    def wrapper(cls):
        if parent_name is None:
            parents = COMMANDS.get('_parents', list())
            parents.append(cls)
            COMMANDS['_parents'] = parents
        else:
            sub_cmds = COMMANDS.get('_subcmds', dict())
            cmds = sub_cmds.get(parent_name, list())
            cmds.append(cls)
            sub_cmds[parent_name] = cmds
            COMMANDS['_subcmds'] = sub_cmds
        return cls
    return wrapper

def init_commands():
    commands = dict()
    for parent_cls in COMMANDS.get('_parents'):
        cmd = parent_cls()
        commands[cmd.name] = cmd

    for parent_name, cmd_classes in COMMANDS.get('_subcmds', dict()).items():
        for cmd_cls in cmd_classes:
            cmd = cmd_cls()
            parent_cmd = commands[parent_name]
            parent_cmd.add(cmd)
    return commands

@register_command()
class DirectCommand(Command):
    _name = "direct"
    def __init__(self):
        super().__init__(DirectCommand._name)

@register_command()
class ConvCommand(CommandWithOp):
    _name = "conv"
    def __init__(self):
        super().__init__(ConvCommand._name)

@register_command(parent_name = "conv")
class ConvStartCommand(Command):
    _op_name = "start"
    def __init__(self):
        super().__init__(ConvStartCommand._op_name)

    @with_sign(pids_field_name='m')
    def build(self, cmd_msg):
        cmd_msg['unique'] = cmd_msg.get('unique', True)
        return cmd_msg

@register_command(parent_name = "conv")
class ConvAddCommand(Command):
    _op_name = "add"
    def __init__(self):
        super().__init__(ConvAddCommand._op_name)

    @with_sign(pids_field_name='m', cid_field_name='cid', action_name='invite')
    def build(self, cmd_msg):
        return cmd_msg

@register_command(parent_name = "conv")
class ConvRemoveCommand(Command):
    _op_name = "remove"
    def __init__(self):
        super().__init__(ConvRemoveCommand._op_name)

    @with_sign(pids_field_name='m', cid_field_name='cid', action_name='kick')
    def build(self, cmd_msg):
        return cmd_msg

@register_command()
class SessionCommand(CommandWithOp):
    _name = "session"
    def __init__(self):
        super().__init__(SessionCommand._name)

@register_command(parent_name = "session")
class SessionOpenCommand(Command):
    _op_name = "open"
    def __init__(self):
        super().__init__(SessionOpenCommand._op_name)

    @with_sign()
    def build(self, cmd_msg):
        cmd_msg['ua'] = cmd_msg.get('ua', config.CLIENT_UA)
        cmd_msg['configBitmap'] = 0xFFFF
        return cmd_msg

@register_command(parent_name = "session")
class SessionCloseCommand(Command):
    _op_name = "close"
    def __init__(self):
        super().__init__(SessionCloseCommand._op_name)

class CommandsManager:
    def __init__(self, appid, peerid):
        self.commands = init_commands()
        self._next_serial_id = 1
        self._appid = appid
        self._peerid = peerid

    def process(self, router, msg):
        cmd_in_msg = msg.get('cmd')
        if cmd_in_msg is not None:
            cmd = self.commands.get(cmd_in_msg)
            if cmd is None:
                print("< ", json.dumps(msg))
            else:
                cmd.process(router, msg)
        else:
            raise RuntimeError("Receive msg without 'cmd': %s" % msg)

    def build(self, cmd_msg):
        cmd = cmd_msg['cmd']
        cmd_builder = self.commands.get(cmd)
        if cmd_builder is None:
            cmd_msg['cmd'] = cmd
            return cmd_msg
        else:
            cmd_msg['appId'] = self._appid
            cmd_msg['peerId'] = self._peerid
            msg = cmd_builder.build(cmd_msg)
            if cmd_builder.is_interactive_cmd():
                msg['i'] = self._next_serial_id
                self._next_serial_id += 1
            return msg
<|endoftext|>


<commit_before>from controller import Controller

class MTS50(Controller):
  """
  A controller for a MTS50/M-Z8 stage.
  """
  def __init__(self,*args, **kwargs):
    super(MTS50, self).__init__(*args, **kwargs)

    # http://www.thorlabs.co.uk/thorProduct.cfm?partNumber=MTS50/M-Z8
    # Note that these values are pulled from the APT User software,
    # as they agree with the real limits of the stage better than
    # what the website or the user manual states
    self.max_velocity = 0.45
    self.max_acceleration = 0.45

    # from private communication with thorlabs tech support:
    # steps per revolution: 48
    # gearbox ratio: 256
    # pitch: 0.5 mm
    # thus to advance 1 mm you need to turn 48*256*2 times
    self.position_scale = 48 * 256 * 2
    self.velocity_scale = 366511.111
    self.acceleration_scale = 1/0.006

    self.linear_range = (0,50)

<commit_msg>Updates scaling factors for MTS50<commit_after>from controller import Controller

class MTS50(Controller):
  """
  A controller for a MTS50/M-Z8 stage.
  """
  def __init__(self,*args, **kwargs):
    super(MTS50, self).__init__(*args, **kwargs)

    # http://www.thorlabs.co.uk/thorProduct.cfm?partNumber=MTS50/M-Z8
    # Note that these values are pulled from the APT User software,
    # as they agree with the real limits of the stage better than
    # what the website or the user manual states
    self.max_velocity = 0.45
    self.max_acceleration = 0.45

    # from private communication with thorlabs tech support:
    # steps per revolution: 48
    # gearbox ratio: 256
    # pitch: 0.5 mm
    # thus to advance 1 mm you need to turn 48*256*2 times
    enccnt = 48*256*2
    T = 2048/6e6

    # these equations are taken from the APT protocol manual
    self.position_scale = enccnt
    self.velocity_scale = enccnt * T * 65536
    self.acceleration_scale = enccnt * T * T * 65536

    self.linear_range = (0,50)

<|endoftext|>


<commit_before>#!/usr/bin/env python

from __future__ import print_function
from builtins import input

""" Python 2.7 & 3.4 disk wiping utility for use on Linux operating systems. RUN AS ROOT. """

import sys              # For interpreter variables & associated functions
import os               # For operating system dependent functions
import re               # For regular expression parsing

""" Define functions """

def osCheck():
    """ Check if OS is 'Linux' """
    if not sys.platform.startswith('linux'):
        print("This program was designed for Linux. Exiting.")
        sys.exit()

def listDevices():
    """ List mounted device(s) / partition(s) """

    print(22 * "-", "DEVICES & PARTITIONS", 22 * "-")                                      # Header

    return os.system('lsblk /dev/sd* --nodeps --output NAME,MODEL,VENDOR,SIZE,TYPE,STATE') # lsblk -d -o NAME,MODEL,VENDOR...

def defineDevice():
    """ Prompt user to define device or partition to wipe """

    while True:
        try:
            device = str(input("Enter letter [and number] of device/partition to wipe,\ne.g. to wipe '/dev/sdb' enter 'b': "))

            if not re.match("^[a-z]$|^[a-z]\d$", device):
                raise ValueError()
            return device

        except ValueError:
            print("Sorry, that's not a valid device or partition. Try again.")

def appendDevice():
    """ Append user-defined device/partition to /dev/sd """

    letter = defineDevice()

    return '/dev/sd' + letter

def numberOfWipes():
    """ Prompt user for number of wipes to perform """

    while True:
        try:
            wipes = int(input("How many times do you want to wipe the device or partition?: "))

            if not wipes > 0:
                raise ValueError()
            return wipes

        except ValueError:
            print("Sorry, that's not a valid number. Try again.")

def confirmWipe():
    """ Prompt user to confirm disk erasure """

    print("WARNING!!! WRITING CHANGES TO DISK WILL RESULT IN IRRECOVERABLE DATA LOSS.")

    while True:
        try:
            reply = str(input("Are you sure you want to proceed? (Yes/No): ")).lower().strip()

            if reply == 'yes':
                return True
            elif reply == 'no':
                print("Exiting pyWype.")
                sys.exit()

        except ValueError:
            print("Sorry, that's not a valid entry. Try again: ")

def zerosToDevice():
    """ Write zeros to device/partition """

    append = appendDevice()
    num = numberOfWipes()
    confirm = confirmWipe()

    passes = 1

    for int in range(num):
        print("Processing pass count {} of {} ... ".format(passes, num))
        os.system(('dd if=/dev/zero |pv --progress --time --rate --bytes| dd of={} bs=4096'.format(append))) # pv -ptrb
        passes += 1

def randomToDevice():
    """ Write random zeros and ones to device/partition """

    append = appendDevice()
    num = numberOfWipes()
    confirm = confirmWipe()

    passes = 1

    for int in range(num):
        print("Processing pass count {} of {} ... ".format(passes, num))
        os.system(('dd if=/dev/random |pv --progress --time --rate --bytes| dd of={} bs=4096'.format(append))) # pv -ptrb
        passes += 1

def menu():
    """ Menu prompt for use to select program option """

    devices = listDevices()

    while True:
        print(30 * "-", "MENU", 30 * "-")
        print("1. Overwrite device or partition with 0's \n(faster, less secure).")
        print("2. Overwrite device or partition with random 0\'s & 1\'s \n(slower, more secure).")
        print("3. Quit.")
        choice = input("Select an option (1, 2 or 3): ")

        if choice in ('1', '2', '3'):
            return choice

def interactiveMode():
    """ Display menu-driven options and run function based on selection """
    while True:
        choice = menu()

        if choice == '3':
            sys.exit()
        elif choice == '1':
            zerosToDevice()
        elif choice == '2':
            randomToDevice()

def wipeDevice():
    """ Program to Wipe drive """

    osCheck()
    interactiveMode()

if __name__ == '__main__':
    print(28 * '-', " pyWype ", 28 * '-')
    print("PYTHON DISK & PARTITION  WIPING UTILITY FOR LINUX.\nTHIS WILL IRRECOVERABLY WIPE DATA FROM DRIVE.\nPROCEED WITH CAUTION.")

    wipeDevice()
<commit_msg>change "^[a-z]$|^[a-z]\d$" to "^[a-z][0-9]?$"<commit_after>#!/usr/bin/env python

from __future__ import print_function
from builtins import input

""" Python 2.7 & 3.4 disk wiping utility for use on Linux operating systems. RUN AS ROOT. """

import sys              # For interpreter variables & associated functions
import os               # For operating system dependent functions
import re               # For regular expression parsing

""" Define functions """

def osCheck():
    """ Check if OS is 'Linux' """
    if not sys.platform.startswith('linux'):
        print("This program was designed for Linux. Exiting.")
        sys.exit()

def listDevices():
    """ List mounted device(s) / partition(s) """

    print(22 * "-", "DEVICES & PARTITIONS", 22 * "-")                                      # Header

    return os.system('lsblk /dev/sd* --nodeps --output NAME,MODEL,VENDOR,SIZE,TYPE,STATE') # lsblk -d -o NAME,MODEL,VENDOR...

def defineDevice():
    """ Prompt user to define device or partition to wipe """

    while True:
        try:
            device = str(input("Enter letter [and number] of device/partition to wipe,\ne.g. to wipe '/dev/sdb' enter 'b': "))

            # if not re.match("^[a-z]$|^[a-z]\d$", device):
            if not re.match("^[a-z][0-9]?$", device):
                raise ValueError()
            return device

        except ValueError:
            print("Sorry, that's not a valid device or partition. Try again.")

def appendDevice():
    """ Append user-defined device/partition to /dev/sd """

    letter = defineDevice()

    return '/dev/sd' + letter

def numberOfWipes():
    """ Prompt user for number of wipes to perform """

    while True:
        try:
            wipes = int(input("How many times do you want to wipe the device or partition?: "))

            if not wipes > 0:
                raise ValueError()
            return wipes

        except ValueError:
            print("Sorry, that's not a valid number. Try again.")

def confirmWipe():
    """ Prompt user to confirm disk erasure """

    print("WARNING!!! WRITING CHANGES TO DISK WILL RESULT IN IRRECOVERABLE DATA LOSS.")

    while True:
        try:
            reply = str(input("Are you sure you want to proceed? (Yes/No): ")).lower().strip()

            if reply == 'yes':
                return True
            elif reply == 'no':
                print("Exiting pyWype.")
                sys.exit()

        except ValueError:
            print("Sorry, that's not a valid entry. Try again: ")

def zerosToDevice():
    """ Write zeros to device/partition """

    append = appendDevice()
    num = numberOfWipes()
    confirm = confirmWipe()

    passes = 1

    for int in range(num):
        print("Processing pass count {} of {} ... ".format(passes, num))
        os.system(('dd if=/dev/zero |pv --progress --time --rate --bytes| dd of={} bs=4096'.format(append))) # pv -ptrb
        passes += 1

def randomToDevice():
    """ Write random zeros and ones to device/partition """

    append = appendDevice()
    num = numberOfWipes()
    confirm = confirmWipe()

    passes = 1

    for int in range(num):
        print("Processing pass count {} of {} ... ".format(passes, num))
        os.system(('dd if=/dev/random |pv --progress --time --rate --bytes| dd of={} bs=4096'.format(append))) # pv -ptrb
        passes += 1

def menu():
    """ Menu prompt for use to select program option """

    devices = listDevices()

    while True:
        print(30 * "-", "MENU", 30 * "-")
        print("1. Overwrite device or partition with 0's \n(faster, less secure).")
        print("2. Overwrite device or partition with random 0\'s & 1\'s \n(slower, more secure).")
        print("3. Quit.")
        choice = input("Select an option (1, 2 or 3): ")

        if choice in ('1', '2', '3'):
            return choice

def interactiveMode():
    """ Display menu-driven options and run function based on selection """
    while True:
        choice = menu()

        if choice == '3':
            sys.exit()
        elif choice == '1':
            zerosToDevice()
        elif choice == '2':
            randomToDevice()

def wipeDevice():
    """ Program to Wipe drive """

    osCheck()
    interactiveMode()

if __name__ == '__main__':
    print(28 * '-', " pyWype ", 28 * '-')
    print("PYTHON DISK & PARTITION  WIPING UTILITY FOR LINUX.\nTHIS WILL IRRECOVERABLY WIPE DATA FROM DRIVE.\nPROCEED WITH CAUTION.")

    wipeDevice()
<|endoftext|>


<commit_before>"""
Python wrapper around the Core Audio Windows API.
"""
import comtypes
from enum import Enum
from ctypes import HRESULT, POINTER, c_float, c_void_p
from ctypes.wintypes import BOOL, DWORD, UINT, INT, LPWSTR
from comtypes import GUID, COMMETHOD

IID_IAudioEndpointVolume = GUID(
    '{5CDF2C82-841E-4546-9722-0CF74078229A}')
IID_IMMDevice = GUID(
    '{D666063F-1587-4E43-81F1-B948E807363F}')
IID_IMMDeviceCollection = GUID(
    '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}')
IID_IMMDeviceEnumerator = GUID(
    '{A95664D2-9614-4F35-A746-DE8DB63617E6}')
IID_IAudioSessionEnumerator = GUID(
    '{E2F5BB11-0570-40CA-ACDD-3AA01277DEE8}')
IID_IAudioSessionManager = GUID(
    '{BFA971F1-4d5e-40bb-935e-967039bfbee4}')
IID_IAudioSessionManager2 = GUID(
    '{77aa99a0-1bd6-484f-8bc7-2c654c9a9b6f}')
IID_IAudioSessionControl = GUID(
    '{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}')
IID_IAudioSessionControl2 = GUID(
    '{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}')

CLSID_MMDeviceEnumerator = GUID(
    '{BCDE0395-E52F-467C-8E3D-C4579291692E}')

class ERole(Enum):
    eConsole = 0
    eMultimedia = 1
    eCommunications = 2
    ERole_enum_count = 3

class EDataFlow(Enum):
    eRender = 0
    eCapture = 1
    eAll = 2
    EDataFlow_enum_count = 3

class IAudioEndpointVolume(comtypes.IUnknown):
    _iid_ = IID_IAudioEndpointVolume
    _methods_ = (
        # HRESULT RegisterControlChangeNotify(
        # [in] IAudioEndpointVolumeCallback *pNotify);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterControlChangeNotify(
        # [in] IAudioEndpointVolumeCallback *pNotify);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetChannelCount([out] UINT *pnChannelCount);
        COMMETHOD([], HRESULT, 'GetChannelCount',
                  (['out'], POINTER(UINT), 'pnChannelCount')),
        # HRESULT SetMasterVolumeLevel(
        # [in] float fLevelDB, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMasterVolumeLevel',
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT SetMasterVolumeLevelScalar(
        # [in] float fLevel, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMasterVolumeLevelScalar',
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetMasterVolumeLevel([out] float *pfLevelDB);
        COMMETHOD([], HRESULT, 'GetMasterVolumeLevel',
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT GetMasterVolumeLevelScalar([out] float *pfLevel);
        COMMETHOD([], HRESULT, 'GetMasterVolumeLevelScalar',
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT SetChannelVolumeLevel(
        # [in] UINT nChannel,
        # [in] float fLevelDB,
        # [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetChannelVolumeLevel',
                  (['in'], UINT, 'nChannel'),
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT SetChannelVolumeLevelScalar(
        # [in] UINT nChannel,
        # [in] float fLevel,
        # [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetChannelVolumeLevelScalar',
                  (['in'], DWORD, 'nChannel'),
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetChannelVolumeLevel(
        # [in]  UINT nChannel,
        # [out] float *pfLevelDB);
        COMMETHOD([], HRESULT, 'GetChannelVolumeLevel',
                  (['in'], UINT, 'nChannel'),
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT GetChannelVolumeLevelScalar(
        # [in]  UINT nChannel,
        # [out] float *pfLevel);
        COMMETHOD([], HRESULT, 'GetChannelVolumeLevelScalar',
                  (['in'], DWORD, 'nChannel'),
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT SetMute([in] BOOL bMute, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMute',
                  (['in'], BOOL, 'bMute'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetMute([out] BOOL *pbMute);
        COMMETHOD([], HRESULT, 'GetMute',
                  (['out'], POINTER(BOOL), 'pbMute')),
        # HRESULT GetVolumeStepInfo(
        # [out] UINT *pnStep,
        # [out] UINT *pnStepCount);
        COMMETHOD([], HRESULT, 'GetVolumeStepInfo',
                  (['out'], POINTER(c_float), 'pnStep'),
                  (['out'], POINTER(c_float), 'pnStepCount')),
        # HRESULT VolumeStepUp([in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'VolumeStepUp',
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT VolumeStepDown([in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'VolumeStepDown',
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT QueryHardwareSupport([out] DWORD *pdwHardwareSupportMask);
        COMMETHOD([], HRESULT, 'QueryHardwareSupport',
                  (['out'], POINTER(DWORD), 'pdwHardwareSupportMask')),
        # HRESULT GetVolumeRange(
        # [out] float *pfLevelMinDB,
        # [out] float *pfLevelMaxDB,
        # [out] float *pfVolumeIncrementDB);
        COMMETHOD([], HRESULT, 'GetVolumeRange',
                  (['out'], POINTER(c_float), 'pfMin'),
                  (['out'], POINTER(c_float), 'pfMax'),
                  (['out'], POINTER(c_float), 'pfIncr')))

class IMMDeviceCollection(comtypes.IUnknown):
    _iid_ = IID_IMMDeviceCollection
    _methods_ = (
        # HRESULT GetCount([out] UINT *pcDevices);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT Item([in] UINT nDevice, [out] IMMDevice **ppDevice);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class IAudioSessionControl(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionControl
    _methods_ = (
        # HRESULT GetState ([out] AudioSessionState *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetDisplayName([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'GetDisplayName',
                  (['out'], POINTER(LPWSTR), 'pRetVal')),
        # HRESULT SetDisplayName(
        # [in] LPCWSTR Value,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetIconPath([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl3'),
        # HRESULT SetIconPath(
        # [in] LPCWSTR Value,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl4'),
        # HRESULT GetGroupingParam([out] GUID *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl5'),
        # HRESULT SetGroupingParam(
        # [in] LPCGUID Grouping,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl6'),
        # HRESULT RegisterAudioSessionNotification(
        # [in] IAudioSessionEvents *NewNotifications);
        COMMETHOD([], HRESULT, 'NotImpl7'),
        # HRESULT UnregisterAudioSessionNotification(
        # [in] IAudioSessionEvents *NewNotifications);
        COMMETHOD([], HRESULT, 'NotImpl8'))

class IAudioSessionControl2(IAudioSessionControl):
    _iid_ = IID_IAudioSessionControl2
    _methods_ = (
        # HRESULT GetSessionIdentifier([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetSessionInstanceIdentifier([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetProcessId([out] DWORD *pRetVal);
        COMMETHOD([], HRESULT, 'GetProcessId',
                  (['out'], POINTER((DWORD)), 'pRetVal')),
        # HRESULT IsSystemSoundsSession();
        COMMETHOD([], HRESULT, 'IsSystemSoundsSession'))

class IAudioSessionEnumerator(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionEnumerator
    _methods_ = (
        # HRESULT GetCount([out] int *SessionCount);
        COMMETHOD([], HRESULT, 'GetCount',
                  (['out'], POINTER(INT), 'SessionCount')),
        # HRESULT GetSession(
        # [in] int SessionCount,
        # [out] IAudioSessionControl **Session);
        COMMETHOD([], HRESULT, 'GetSession',
                  (['in'], INT, 'SessionCount'),
                  (['out'],
                   POINTER(POINTER(IAudioSessionControl)), 'Session')))

class IAudioSessionManager(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionManager
    _methods_ = (
        # HRESULT GetAudioSessionControl(
        # [in] LPCGUID AudioSessionGuid,
        # [in] DWORD StreamFlags,
        # [out] IAudioSessionControl **SessionControl);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetSimpleAudioVolume(
        # [in] LPCGUID AudioSessionGuid,
        # [in] DWORD CrossProcessSession,
        # [out] ISimpleAudioVolume **AudioVolume);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class IAudioSessionManager2(IAudioSessionManager):
    _iid_ = IID_IAudioSessionManager2
    _methods_ = (
        # HRESULT GetSessionEnumerator(
        # [out] IAudioSessionEnumerator **SessionList);
        COMMETHOD([], HRESULT, 'GetSessionEnumerator',
                  (['out'],
                  POINTER(POINTER(IAudioSessionEnumerator)), 'SessionList')),
        # HRESULT RegisterSessionNotification(
        # IAudioSessionNotification *SessionNotification);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterSessionNotification(
        # IAudioSessionNotification *SessionNotification);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT RegisterDuckNotification(
        # LPCWSTR SessionID,
        # IAudioVolumeDuckNotification *duckNotification);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterDuckNotification(
        # IAudioVolumeDuckNotification *duckNotification);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class IMMDevice(comtypes.IUnknown):
    _iid_ = IID_IMMDevice
    _methods_ = (
        # HRESULT Activate(
        # [in] REFIID iid,
        # [in] DWORD dwClsCtx,
        # [in] PROPVARIANT *pActivationParams,
        # [out] void **ppInterface);
        COMMETHOD([], HRESULT, 'Activate',
                  (['in'], POINTER(GUID), 'iid'),
                  (['in'], DWORD, 'dwClsCtx'),
                  (['in'], POINTER(DWORD), 'pActivationParams'),
                  (['out'], POINTER(c_void_p), 'ppInterface')),
        # HRESULT OpenPropertyStore(
        # [in] DWORD stgmAccess,
        # [out] IPropertyStore **ppProperties);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetId([out] LPWSTR *ppstrId);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetState([out] DWORD *pdwState);
        COMMETHOD([], HRESULT, 'NotImpl3'))

class IMMDeviceEnumerator(comtypes.IUnknown):
    _iid_ = IID_IMMDeviceEnumerator
    _methods_ = (
        # HRESULT EnumAudioEndpoints(
        # [in] EDataFlow dataFlow,
        # [in] DWORD dwStateMask,
        # [out] IMMDeviceCollection **ppDevices);
        COMMETHOD([], HRESULT, 'EnumAudioEndpoints',
                  (['in'], DWORD, 'dataFlow'),
                  (['in'], DWORD, 'dwStateMask'),
                  (['out'],
                  POINTER(POINTER(IMMDeviceCollection)), 'ppDevices')),
        # HRESULT GetDefaultAudioEndpoint(
        # [in] EDataFlow dataFlow,
        # [in] ERole role,
        # [out] IMMDevice **ppDevice);
        COMMETHOD([], HRESULT, 'GetDefaultAudioEndpoint',
                  (['in'], DWORD, 'dataFlow'),
                  (['in'], DWORD, 'role'),
                  (['out'], POINTER(POINTER(IMMDevice)), 'ppDevices')))
<commit_msg>IPropertyStore class draft support<commit_after>"""
Python wrapper around the Core Audio Windows API.
"""
import psutil
import comtypes
from enum import Enum
from ctypes import cast, HRESULT, POINTER, Structure, c_float, c_void_p
from ctypes.wintypes import BOOL, DWORD, UINT, INT, LPWSTR
from comtypes import GUID, COMMETHOD

IID_Empty = GUID(
    '{00000000-0000-0000-0000-000000000000}')
IID_IAudioEndpointVolume = GUID(
    '{5CDF2C82-841E-4546-9722-0CF74078229A}')
IID_IPropertyStore = GUID(
    '{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}')
IID_IMMDevice = GUID(
    '{D666063F-1587-4E43-81F1-B948E807363F}')
IID_IMMDeviceCollection = GUID(
    '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}')
IID_IMMDeviceEnumerator = GUID(
    '{A95664D2-9614-4F35-A746-DE8DB63617E6}')
IID_IAudioSessionEnumerator = GUID(
    '{E2F5BB11-0570-40CA-ACDD-3AA01277DEE8}')
IID_IAudioSessionManager = GUID(
    '{BFA971F1-4d5e-40bb-935e-967039bfbee4}')
IID_IAudioSessionManager2 = GUID(
    '{77aa99a0-1bd6-484f-8bc7-2c654c9a9b6f}')
IID_IAudioSessionControl = GUID(
    '{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}')
IID_IAudioSessionControl2 = GUID(
    '{BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D}')

CLSID_MMDeviceEnumerator = GUID(
    '{BCDE0395-E52F-467C-8E3D-C4579291692E}')

class PROPVARIANT(DWORD):
    pass

class ERole(Enum):
    eConsole = 0
    eMultimedia = 1
    eCommunications = 2
    ERole_enum_count = 3

class EDataFlow(Enum):
    eRender = 0
    eCapture = 1
    eAll = 2
    EDataFlow_enum_count = 3

class IAudioEndpointVolume(comtypes.IUnknown):
    _iid_ = IID_IAudioEndpointVolume
    _methods_ = (
        # HRESULT RegisterControlChangeNotify(
        # [in] IAudioEndpointVolumeCallback *pNotify);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterControlChangeNotify(
        # [in] IAudioEndpointVolumeCallback *pNotify);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetChannelCount([out] UINT *pnChannelCount);
        COMMETHOD([], HRESULT, 'GetChannelCount',
                  (['out'], POINTER(UINT), 'pnChannelCount')),
        # HRESULT SetMasterVolumeLevel(
        # [in] float fLevelDB, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMasterVolumeLevel',
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT SetMasterVolumeLevelScalar(
        # [in] float fLevel, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMasterVolumeLevelScalar',
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetMasterVolumeLevel([out] float *pfLevelDB);
        COMMETHOD([], HRESULT, 'GetMasterVolumeLevel',
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT GetMasterVolumeLevelScalar([out] float *pfLevel);
        COMMETHOD([], HRESULT, 'GetMasterVolumeLevelScalar',
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT SetChannelVolumeLevel(
        # [in] UINT nChannel,
        # [in] float fLevelDB,
        # [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetChannelVolumeLevel',
                  (['in'], UINT, 'nChannel'),
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT SetChannelVolumeLevelScalar(
        # [in] UINT nChannel,
        # [in] float fLevel,
        # [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetChannelVolumeLevelScalar',
                  (['in'], DWORD, 'nChannel'),
                  (['in'], c_float, 'fLevelDB'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetChannelVolumeLevel(
        # [in]  UINT nChannel,
        # [out] float *pfLevelDB);
        COMMETHOD([], HRESULT, 'GetChannelVolumeLevel',
                  (['in'], UINT, 'nChannel'),
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT GetChannelVolumeLevelScalar(
        # [in]  UINT nChannel,
        # [out] float *pfLevel);
        COMMETHOD([], HRESULT, 'GetChannelVolumeLevelScalar',
                  (['in'], DWORD, 'nChannel'),
                  (['out'], POINTER(c_float), 'pfLevelDB')),
        # HRESULT SetMute([in] BOOL bMute, [in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'SetMute',
                  (['in'], BOOL, 'bMute'),
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT GetMute([out] BOOL *pbMute);
        COMMETHOD([], HRESULT, 'GetMute',
                  (['out'], POINTER(BOOL), 'pbMute')),
        # HRESULT GetVolumeStepInfo(
        # [out] UINT *pnStep,
        # [out] UINT *pnStepCount);
        COMMETHOD([], HRESULT, 'GetVolumeStepInfo',
                  (['out'], POINTER(c_float), 'pnStep'),
                  (['out'], POINTER(c_float), 'pnStepCount')),
        # HRESULT VolumeStepUp([in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'VolumeStepUp',
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT VolumeStepDown([in] LPCGUID pguidEventContext);
        COMMETHOD([], HRESULT, 'VolumeStepDown',
                  (['in'], POINTER(GUID), 'pguidEventContext')),
        # HRESULT QueryHardwareSupport([out] DWORD *pdwHardwareSupportMask);
        COMMETHOD([], HRESULT, 'QueryHardwareSupport',
                  (['out'], POINTER(DWORD), 'pdwHardwareSupportMask')),
        # HRESULT GetVolumeRange(
        # [out] float *pfLevelMinDB,
        # [out] float *pfLevelMaxDB,
        # [out] float *pfVolumeIncrementDB);
        COMMETHOD([], HRESULT, 'GetVolumeRange',
                  (['out'], POINTER(c_float), 'pfMin'),
                  (['out'], POINTER(c_float), 'pfMax'),
                  (['out'], POINTER(c_float), 'pfIncr')))

class IMMDeviceCollection(comtypes.IUnknown):
    _iid_ = IID_IMMDeviceCollection
    _methods_ = (
        # HRESULT GetCount([out] UINT *pcDevices);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT Item([in] UINT nDevice, [out] IMMDevice **ppDevice);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class IAudioSessionControl(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionControl
    _methods_ = (
        # HRESULT GetState ([out] AudioSessionState *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetDisplayName([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'GetDisplayName',
                  (['out'], POINTER(LPWSTR), 'pRetVal')),
        # HRESULT SetDisplayName(
        # [in] LPCWSTR Value,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetIconPath([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl3'),
        # HRESULT SetIconPath(
        # [in] LPCWSTR Value,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl4'),
        # HRESULT GetGroupingParam([out] GUID *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl5'),
        # HRESULT SetGroupingParam(
        # [in] LPCGUID Grouping,
        # [in] LPCGUID EventContext);
        COMMETHOD([], HRESULT, 'NotImpl6'),
        # HRESULT RegisterAudioSessionNotification(
        # [in] IAudioSessionEvents *NewNotifications);
        COMMETHOD([], HRESULT, 'NotImpl7'),
        # HRESULT UnregisterAudioSessionNotification(
        # [in] IAudioSessionEvents *NewNotifications);
        COMMETHOD([], HRESULT, 'NotImpl8'))

class IAudioSessionControl2(IAudioSessionControl):
    _iid_ = IID_IAudioSessionControl2
    _methods_ = (
        # HRESULT GetSessionIdentifier([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetSessionInstanceIdentifier([out] LPWSTR *pRetVal);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetProcessId([out] DWORD *pRetVal);
        COMMETHOD([], HRESULT, 'GetProcessId',
                  (['out'], POINTER((DWORD)), 'pRetVal')),
        # HRESULT IsSystemSoundsSession();
        COMMETHOD([], HRESULT, 'IsSystemSoundsSession'))

class IAudioSessionEnumerator(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionEnumerator
    _methods_ = (
        # HRESULT GetCount([out] int *SessionCount);
        COMMETHOD([], HRESULT, 'GetCount',
                  (['out'], POINTER(INT), 'SessionCount')),
        # HRESULT GetSession(
        # [in] int SessionCount,
        # [out] IAudioSessionControl **Session);
        COMMETHOD([], HRESULT, 'GetSession',
                  (['in'], INT, 'SessionCount'),
                  (['out'],
                   POINTER(POINTER(IAudioSessionControl)), 'Session')))

class IAudioSessionManager(comtypes.IUnknown):
    _iid_ = IID_IAudioSessionManager
    _methods_ = (
        # HRESULT GetAudioSessionControl(
        # [in] LPCGUID AudioSessionGuid,
        # [in] DWORD StreamFlags,
        # [out] IAudioSessionControl **SessionControl);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT GetSimpleAudioVolume(
        # [in] LPCGUID AudioSessionGuid,
        # [in] DWORD CrossProcessSession,
        # [out] ISimpleAudioVolume **AudioVolume);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class IAudioSessionManager2(IAudioSessionManager):
    _iid_ = IID_IAudioSessionManager2
    _methods_ = (
        # HRESULT GetSessionEnumerator(
        # [out] IAudioSessionEnumerator **SessionList);
        COMMETHOD([], HRESULT, 'GetSessionEnumerator',
                  (['out'],
                  POINTER(POINTER(IAudioSessionEnumerator)), 'SessionList')),
        # HRESULT RegisterSessionNotification(
        # IAudioSessionNotification *SessionNotification);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterSessionNotification(
        # IAudioSessionNotification *SessionNotification);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT RegisterDuckNotification(
        # LPCWSTR SessionID,
        # IAudioVolumeDuckNotification *duckNotification);
        COMMETHOD([], HRESULT, 'NotImpl1'),
        # HRESULT UnregisterDuckNotification(
        # IAudioVolumeDuckNotification *duckNotification);
        COMMETHOD([], HRESULT, 'NotImpl2'))

class PROPERTYKEY(Structure):
    _fields_ = [
        ('fmtid', GUID),
        ('pid', DWORD),
    ]

class IPropertyStore(comtypes.IUnknown):
    _iid_ = IID_IPropertyStore
    _methods_ = (
        # HRESULT GetCount([out] DWORD *cProps);
        COMMETHOD([], HRESULT, 'GetAt',
                  (['out'], POINTER(DWORD), 'cProps')),
        # HRESULT GetAt(
        # [in] DWORD iProp,
        # [out] PROPERTYKEY *pkey);
        COMMETHOD([], HRESULT, 'GetAt',
                  (['in'], DWORD, 'iProp'),
                  (['out'], POINTER(PROPERTYKEY), 'pkey')),
        # HRESULT GetValue(
        # [in] REFPROPERTYKEY key,
        # [out] PROPVARIANT *pv);
        COMMETHOD([], HRESULT, 'GetValue',
                  # (['in'], REFPROPERTYKEY, 'key'),
                  (['in'], POINTER(PROPERTYKEY), 'key'),
                  (['out'], POINTER(PROPVARIANT), 'pv')),
        # HRESULT SetValue([out] LPWSTR *ppstrId);
        COMMETHOD([], HRESULT, 'SetValue',
                  (['out'], POINTER(LPWSTR), 'ppstrId')),
        # HRESULT Commit([out] DWORD *pdwState);
        COMMETHOD([], HRESULT, 'Commit',
                  (['out'], POINTER(DWORD), 'pdwState')))

class IMMDevice(comtypes.IUnknown):
    _iid_ = IID_IMMDevice
    _methods_ = (
        # HRESULT Activate(
        # [in] REFIID iid,
        # [in] DWORD dwClsCtx,
        # [in] PROPVARIANT *pActivationParams,
        # [out] void **ppInterface);
        COMMETHOD([], HRESULT, 'Activate',
                  (['in'], POINTER(GUID), 'iid'),
                  (['in'], DWORD, 'dwClsCtx'),
                  (['in'], POINTER(PROPVARIANT), 'pActivationParams'),
                  (['out'], POINTER(c_void_p), 'ppInterface')),
        # HRESULT OpenPropertyStore(
        # [in] DWORD stgmAccess,
        # [out] IPropertyStore **ppProperties);
        COMMETHOD([], HRESULT, 'OpenPropertyStore',
                  (['in'], DWORD, 'stgmAccess'),
                  (['out'],
                  POINTER(POINTER(IPropertyStore)), 'ppProperties')),
        # HRESULT GetId([out] LPWSTR *ppstrId);
        COMMETHOD([], HRESULT, 'NotImpl2'),
        # HRESULT GetState([out] DWORD *pdwState);
        COMMETHOD([], HRESULT, 'NotImpl3'))

class IMMDeviceEnumerator(comtypes.IUnknown):
    _iid_ = IID_IMMDeviceEnumerator
    _methods_ = (
        # HRESULT EnumAudioEndpoints(
        # [in] EDataFlow dataFlow,
        # [in] DWORD dwStateMask,
        # [out] IMMDeviceCollection **ppDevices);
        COMMETHOD([], HRESULT, 'EnumAudioEndpoints',
                  (['in'], DWORD, 'dataFlow'),
                  (['in'], DWORD, 'dwStateMask'),
                  (['out'],
                  POINTER(POINTER(IMMDeviceCollection)), 'ppDevices')),
        # HRESULT GetDefaultAudioEndpoint(
        # [in] EDataFlow dataFlow,
        # [in] ERole role,
        # [out] IMMDevice **ppDevice);
        COMMETHOD([], HRESULT, 'GetDefaultAudioEndpoint',
                  (['in'], DWORD, 'dataFlow'),
                  (['in'], DWORD, 'role'),
                  (['out'], POINTER(POINTER(IMMDevice)), 'ppDevices')))

<|endoftext|>