<commit_before># coding: utf-8

import sqlite3

import lglass.database.base
import lglass.rpsl

@lglass.database.base.register("sqlite3")
class SQLite3Database(lglass.database.base.Database):
	""" This database backend operates on a SQLite3 database and supports generic
	RPSL types. Additional, it provides fast access support for the standard RPSL
	types by allocating one table per standard type. Non-standard types are saved
	in the generic "objects" table. """

	SQL_SCHEMA = ("""
CREATE TABLE IF NOT EXISTS 'objects' (
	'id' INTEGER PRIMARY KEY,
	'type' STRING NOT NULL,
	'primary_key' STRING NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS 'objects_idx_type_primary_key' ON 'objects' (
	'type', 'primary_key'
);
CREATE TABLE IF NOT EXISTS 'kvpairs' (
	'id' INTEGER PRIMARY KEY,
	'object_id' INTEGER NOT NULL,
	'key' STRING NOT NULL,
	'value' STRING NOT NULL,
	'order' INTEGER NOT NULL,
	FOREIGN KEY ('object_id') REFERENCES 'objects' ('id') ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS 'kvpairs_idx_object_id' ON 'kvpairs' (
	'object_id'
);
PRAGMA foreign_keys = ON;
""")

	def __init__(self, sql):
		if isinstance(sql, sqlite3.Connection):
			self.connection = sql
		elif isinstance(sql, str):
			self.connection = sqlite3.connect(sql)
		elif isinstance(sql, tuple):
			self.connection = sqlite3.connect(*sql)
		else:
			raise TypeError("Expected sql to be tuple, str or sqlite3.Connection, got {}".format(type(sql)))
		self.install_schema()

	def install_schema(self):
		c = self.connection.cursor()
		c.executescript(self.SQL_SCHEMA)
		c.close()

	def get(self, type, primary_key):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT id, primary_key, type FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))

			col = cur.fetchone()
			if col is None:
				raise KeyError(repr((type, primary_key)))

			obj = lglass.rpsl.Object()
			cur.execute("SELECT key, value FROM 'kvpairs' WHERE \"object_id\" = ? ORDER BY \"order\"", (col[0], ))

			obj.add(type, primary_key)
			if col[1] != primary_key:
				obj.real_primary_key = col[1]
			if col[2] != type:
				obj.real_type = col[2]

			for row in cur.fetchall():
				obj.add(row[0], row[1])

			cur.close()
			return obj

	def list(self):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT type, primary_key FROM 'objects'")

			for obj in cur.fetchall():
				yield (obj[0], obj[1])
			cur.close()

	def delete(self, type, primary_key):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("DELETE FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))
			cur.close()

	def save(self, object):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT id FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (object.real_type, object.real_primary_key))
			f = cur.fetchone()
			if f is not None:
				cur.execute("DELETE FROM 'objects' WHERE \"id\" = ?", (f[0], ))

			cur.execute("INSERT INTO 'objects' ('type', 'primary_key') VALUES (?, ?)", (object.real_type, object.real_primary_key))
			new_id = cur.lastrowid

			for offset, (key, value) in enumerate(object[1:]):
				cur.execute("INSERT INTO 'kvpairs' ('object_id', 'key', 'value', 'order') VALUES (?, ?, ?, ?)",
					(new_id, key, value, offset))
			cur.close()

	def find(self, primary_key, types=None):
		specs = []

		with self.connection:
			cur = self.connection.cursor()
			if types is not None:
				for type in types:
					cur.execute("SELECT id FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))
					f = cur.fetchone()
					if f is not None:
						specs.append((type, primary_key))
			else:
				cur.execute("SELECT type, id FROM 'objects' WHERE \"primary_key\" = ?", (primary_key, ))
				for col in cur.fetchall():
					specs.append((col[0], primary_key))
			cur.close()

		return [self.get(*spec) for spec in specs]

	@classmethod
	def from_url(cls, url):
		return cls(url.path)

<commit_msg>Should not generate ImportError if sqlite3 is not available<commit_after># coding: utf-8

try:
	import sqlite3
except ImportError:
	sqlite3 = None

import lglass.database.base
import lglass.rpsl

@lglass.database.base.register("sqlite3")
class SQLite3Database(lglass.database.base.Database):
	""" This database backend operates on a SQLite3 database and supports generic
	RPSL types. Additional, it provides fast access support for the standard RPSL
	types by allocating one table per standard type. Non-standard types are saved
	in the generic "objects" table. """

	SQL_SCHEMA = ("""
CREATE TABLE IF NOT EXISTS 'objects' (
	'id' INTEGER PRIMARY KEY,
	'type' STRING NOT NULL,
	'primary_key' STRING NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS 'objects_idx_type_primary_key' ON 'objects' (
	'type', 'primary_key'
);
CREATE TABLE IF NOT EXISTS 'kvpairs' (
	'id' INTEGER PRIMARY KEY,
	'object_id' INTEGER NOT NULL,
	'key' STRING NOT NULL,
	'value' STRING NOT NULL,
	'order' INTEGER NOT NULL,
	FOREIGN KEY ('object_id') REFERENCES 'objects' ('id') ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS 'kvpairs_idx_object_id' ON 'kvpairs' (
	'object_id'
);
PRAGMA foreign_keys = ON;
""")

	def __init__(self, sql):
		if isinstance(sql, sqlite3.Connection):
			self.connection = sql
		elif isinstance(sql, str):
			self.connection = sqlite3.connect(sql)
		elif isinstance(sql, tuple):
			self.connection = sqlite3.connect(*sql)
		else:
			raise TypeError("Expected sql to be tuple, str or sqlite3.Connection, got {}".format(type(sql)))
		self.install_schema()

	def install_schema(self):
		c = self.connection.cursor()
		c.executescript(self.SQL_SCHEMA)
		c.close()

	def get(self, type, primary_key):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT id, primary_key, type FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))

			col = cur.fetchone()
			if col is None:
				raise KeyError(repr((type, primary_key)))

			obj = lglass.rpsl.Object()
			cur.execute("SELECT key, value FROM 'kvpairs' WHERE \"object_id\" = ? ORDER BY \"order\"", (col[0], ))

			obj.add(type, primary_key)
			if col[1] != primary_key:
				obj.real_primary_key = col[1]
			if col[2] != type:
				obj.real_type = col[2]

			for row in cur.fetchall():
				obj.add(row[0], row[1])

			cur.close()
			return obj

	def list(self):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT type, primary_key FROM 'objects'")

			for obj in cur.fetchall():
				yield (obj[0], obj[1])
			cur.close()

	def delete(self, type, primary_key):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("DELETE FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))
			cur.close()

	def save(self, object):
		with self.connection:
			cur = self.connection.cursor()
			cur.execute("SELECT id FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (object.real_type, object.real_primary_key))
			f = cur.fetchone()
			if f is not None:
				cur.execute("DELETE FROM 'objects' WHERE \"id\" = ?", (f[0], ))

			cur.execute("INSERT INTO 'objects' ('type', 'primary_key') VALUES (?, ?)", (object.real_type, object.real_primary_key))
			new_id = cur.lastrowid

			for offset, (key, value) in enumerate(object[1:]):
				cur.execute("INSERT INTO 'kvpairs' ('object_id', 'key', 'value', 'order') VALUES (?, ?, ?, ?)",
					(new_id, key, value, offset))
			cur.close()

	def find(self, primary_key, types=None):
		specs = []

		with self.connection:
			cur = self.connection.cursor()
			if types is not None:
				for type in types:
					cur.execute("SELECT id FROM 'objects' WHERE \"type\" = ? AND \"primary_key\" = ?", (type, primary_key))
					f = cur.fetchone()
					if f is not None:
						specs.append((type, primary_key))
			else:
				cur.execute("SELECT type, id FROM 'objects' WHERE \"primary_key\" = ?", (primary_key, ))
				for col in cur.fetchall():
					specs.append((col[0], primary_key))
			cur.close()

		return [self.get(*spec) for spec in specs]

	@classmethod
	def from_url(cls, url):
		return cls(url.path)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '0be4daf96ecd'
down_revision = '3acb947457ed'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    integrations_table = op.create_table(
        'integrations',
        sa.Column('name', sa.Unicode(), nullable=False),
        sa.Column('description', sa.Unicode(), nullable=True),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.PrimaryKeyConstraint('name')
    )
    op.create_table(
        'integration_users',
        sa.Column('integration_name', sa.Unicode(), nullable=False),
        sa.Column('user_id', sa.Unicode(), nullable=False),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.Column('conf', postgresql.JSONB(), nullable=True),
        sa.ForeignKeyConstraint(
            ['integration_name'], ['integrations.name'], ondelete='CASCADE',
            name='integration_users_integrations_fkey'),
        sa.ForeignKeyConstraint(
            ['user_id'], ['users.id'], ondelete='CASCADE',
            name='integration_users_users_fkey'),
        sa.PrimaryKeyConstraint('integration_name', 'user_id')
    )
    op.create_table(
        'sources',
        sa.Column('id', sa.Unicode(), nullable=False),
        sa.Column('name', sa.Unicode(), nullable=True),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.Column('updated', sa.DateTime(timezone=True), nullable=False),
        sa.Column('integration_name', sa.Unicode(), nullable=True),
        sa.Column('conf', postgresql.JSONB()),
        sa.ForeignKeyConstraint(
            ['integration_name'], ['integrations.name'],
            name='sources_integrations_fkey'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_table(
        'source_users',
        sa.Column('source_id', sa.Unicode(), nullable=False),
        sa.Column('user_id', sa.Unicode(), nullable=False),
        sa.Column('role', sa.Unicode(), nullable=False),
        sa.ForeignKeyConstraint(
            ['source_id'], ['sources.id'], ondelete='CASCADE',
            name='source_users_sources_fkey'),
        sa.ForeignKeyConstraint(
            ['user_id'], ['users.id'], ondelete='CASCADE',
            name='source_users_users_fkey'),
        sa.PrimaryKeyConstraint('source_id', 'user_id')
    )
    op.add_column('jobs', sa.Column('source_id', sa.Unicode(), nullable=True))
    op.create_foreign_key(
        'jobs_sources_fkey', 'jobs', 'sources', ['source_id'], ['id'])
    op.create_foreign_key(
        'jobs_integrations_fkey', 'jobs', 'integrations',
        ['integration_name'], ['name'])

    op.alter_column('jobs', 'integration_conf', new_column_name='conf')
    # ### end Alembic commands ###

    op.bulk_insert(integrations_table, [
        {'name': 'api', 'description': '', 'active': True},
        {'name': 'github', 'description': '', 'active': True},
        {'name': 's3', 'description': '', 'active': True},
    ])

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('jobs', 'conf', new_column_name='integration_conf')
    op.drop_constraint('jobs_sources_fkey', 'jobs', type_='foreignkey')
    op.drop_constraint('jobs_integrations_fkey', 'jobs', type_='foreignkey')
    op.drop_column('jobs', 'source_id')
    op.drop_table('source_users')
    op.drop_table('sources')
    op.drop_table('integration_users')
    op.drop_table('integrations')
    # ### end Alembic commands ###
<commit_msg>Fix integrations table creation<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '0be4daf96ecd'
down_revision = '3acb947457ed'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    integrations_table = op.create_table(
        'integrations',
        sa.Column('name', sa.Unicode(), nullable=False),
        sa.Column('description', sa.Unicode(), nullable=True),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.PrimaryKeyConstraint('name')
    )

    op.bulk_insert(integrations_table, [
        {'name': 'api', 'description': '', 'active': True},
        {'name': 'github', 'description': '', 'active': True},
        {'name': 's3', 'description': '', 'active': True},
    ])

    op.create_table(
        'integration_users',
        sa.Column('integration_name', sa.Unicode(), nullable=False),
        sa.Column('user_id', sa.Unicode(), nullable=False),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.Column('conf', postgresql.JSONB(), nullable=True),
        sa.ForeignKeyConstraint(
            ['integration_name'], ['integrations.name'], ondelete='CASCADE',
            name='integration_users_integrations_fkey'),
        sa.ForeignKeyConstraint(
            ['user_id'], ['users.id'], ondelete='CASCADE',
            name='integration_users_users_fkey'),
        sa.PrimaryKeyConstraint('integration_name', 'user_id')
    )
    op.create_table(
        'sources',
        sa.Column('id', sa.Unicode(), nullable=False),
        sa.Column('name', sa.Unicode(), nullable=True),
        sa.Column('active', sa.Boolean(), nullable=False),
        sa.Column('updated', sa.DateTime(timezone=True), nullable=False),
        sa.Column('integration_name', sa.Unicode(), nullable=True),
        sa.Column('conf', postgresql.JSONB()),
        sa.ForeignKeyConstraint(
            ['integration_name'], ['integrations.name'],
            name='sources_integrations_fkey'),
        sa.PrimaryKeyConstraint('id')
    )
    op.create_table(
        'source_users',
        sa.Column('source_id', sa.Unicode(), nullable=False),
        sa.Column('user_id', sa.Unicode(), nullable=False),
        sa.Column('role', sa.Unicode(), nullable=False),
        sa.ForeignKeyConstraint(
            ['source_id'], ['sources.id'], ondelete='CASCADE',
            name='source_users_sources_fkey'),
        sa.ForeignKeyConstraint(
            ['user_id'], ['users.id'], ondelete='CASCADE',
            name='source_users_users_fkey'),
        sa.PrimaryKeyConstraint('source_id', 'user_id')
    )
    op.add_column('jobs', sa.Column('source_id', sa.Unicode(), nullable=True))
    op.create_foreign_key(
        'jobs_sources_fkey', 'jobs', 'sources', ['source_id'], ['id'])
    op.create_foreign_key(
        'jobs_integrations_fkey', 'jobs', 'integrations',
        ['integration_name'], ['name'])

    op.alter_column('jobs', 'integration_conf', new_column_name='conf')
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column('jobs', 'conf', new_column_name='integration_conf')
    op.drop_constraint('jobs_sources_fkey', 'jobs', type_='foreignkey')
    op.drop_constraint('jobs_integrations_fkey', 'jobs', type_='foreignkey')
    op.drop_column('jobs', 'source_id')
    op.drop_table('source_users')
    op.drop_table('sources')
    op.drop_table('integration_users')
    op.drop_table('integrations')
    # ### end Alembic commands ###
<|endoftext|>


<commit_before># Settings for Zulip Voyager

### MANDATORY SETTINGS
#
# These settings MUST be set in production. In a development environment,
# sensible default values will be used.

# The user-accessible Zulip hostname for this installation, e.g.
# zulip.example.com
EXTERNAL_HOST = 'zulip.example.com'

# The email address for the person or team who maintain the Zulip
# Voyager installation. Will also get support emails. (e.g. zulip-admin@example.com)
ZULIP_ADMINISTRATOR = 'zulip-admin@example.com'

# The domain for your organization, e.g. example.com
ADMIN_DOMAIN = 'example.com'

# Enable at least one of the following authentication backends.
AUTHENTICATION_BACKENDS = (
#                           'zproject.backends.EmailAuthBackend', # Email and password
#                           'zproject.backends.ZulipRemoteUserBackend', # Local SSO
#                           'zproject.backends.GoogleMobileOauth2Backend', # Google Apps, setup below
    )

# Google Oauth requires a bit of configuration; you will need to go to
# https://console.developers.google.com, setup an Oauth2 client ID
# that allows redirects to
# e.g. https://zulip.example.com/accounts/login/google/done/ put your
# client secret as "google_oauth2_client_secret" in
# zulip-secrets.conf, and your cleitn ID here:
# GOOGLE_OAUTH2_CLIENT_ID=<your client ID from Google>

# If you are using the ZulipRemoteUserBackend authentication backend,
# set this to your domain (e.g. if REMOTE_USER is "username" and the
# corresponding email address is "username@example.com", set
# SSO_APPEND_DOMAIN = "example.com")
SSO_APPEND_DOMAIN = None

# Configure the outgoing SMTP server below. For outgoing email
# via a GMail SMTP server, EMAIL_USE_TLS must be True and the
# outgoing port must be 587. The EMAIL_HOST is prepopulated
# for GMail servers, change it for other hosts, or leave it unset
# or empty to skip sending email.
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_PORT = 587
EMAIL_USE_TLS = True

# The email From address to be used for automatically generated emails
DEFAULT_FROM_EMAIL = "Zulip <zulip@example.com>"
# The noreply address to be used as Reply-To for certain generated emails.
# Messages sent to this address should not be delivered anywhere.
NOREPLY_EMAIL_ADDRESS = "noreply@example.com"

# A list of strings representing the host/domain names that this
# Django site can serve. You should reset it to be a list of
# domains/IP addresses for your site. This is a security measure to
# prevent an attacker from poisoning caches and triggering password
# reset emails with links to malicious hosts by submitting requests
# with a fake HTTP Host header.
ALLOWED_HOSTS = ['*']

### OPTIONAL SETTINGS

# Controls whether session cookies expire when the browser closes
SESSION_EXPIRE_AT_BROWSER_CLOSE = False

# Session cookie expiry in seconds after the last page load
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # 2 weeks

# Controls whether or not there is a feedback button in the UI.
ENABLE_FEEDBACK = False

# By default, the feedback button will submit feedback to the Zulip
# developers.  If you set FEEDBACK_EMAIL to be an email address
# (e.g. ZULIP_ADMINISTRATOR), feedback sent by your users will instead
# be sent to that email address.
FEEDBACK_EMAIL = ZULIP_ADMINISTRATOR

# Controls whether or not error reports are sent to Zulip.  Error
# reports are used to improve the quality of the product and do not
# include message contents; please contact Zulip support with any
# questions.
ERROR_REPORTING = True

# Controls whether or not Zulip will provide inline image preview when
# a link to an image is referenced in a message.
INLINE_IMAGE_PREVIEW = True

# By default, files uploaded by users and user avatars are stored
# directly on the Zulip server.  If file storage in Amazon S3 (or
# elsewhere, e.g. your corporate fileshare) is desired, please contact
# Zulip Support (support@zulip.com) for further instructions on
# setting up the appropriate integration.
LOCAL_UPLOADS_DIR = "/home/zulip/uploads"

# Controls whether name changes are completely disabled for this installation
# This is useful in settings where you're syncing names from an integrated LDAP/Active Directory
NAME_CHANGES_DISABLED = False

# Controls whether users who have not uploaded an avatar will receive an avatar
# from gravatar.com.
ENABLE_GRAVATAR = True

# To override the default avatar image if ENABLE_GRAVATAR is False, place your
# custom default avatar image at /home/zulip/local-static/default-avatar.png
# and uncomment the following line.
#DEFAULT_AVATAR_URI = '/local-static/default-avatar.png'

### TWITTER INTEGRATION

# Zulip supports showing inline Tweet previews when a tweet is linked
# to in a message.  To support this, Zulip must have access to the
# Twitter API via OAuth.  To obtain the various access tokens needed
# below, you must register a new application under your Twitter
# account by doing the following:
#
# 1. Log in to http://dev.twitter.com.
# 2. In the menu under your username, click My Applications. From this page, create a new application.
# 3. Click on the application you created and click "create my access token". Fill in the requested values.
TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''
TWITTER_ACCESS_TOKEN_KEY = ''
TWITTER_ACCESS_TOKEN_SECRET = ''

### EMAIL GATEWAY INTEGRATION

# The email gateway provides, for each stream, an email address that
# you can send email to in order to have the email's content be posted
# to that stream.  Emails received at the per-stream email address
# will be converted into a Zulip message

# There are two ways to make use of local email mirroring:
#  1. Local delivery: A MTA runs locally and passes mail directly to Zulip
#  2. Polling: Checks an IMAP inbox every minute for new messages.

# A Puppet manifest for local delivery via Postfix is available in
# puppet/zulip/manifests/postfix_localmail.pp. To use the manifest, add it to
# puppet_classes in /etc/zulip/zulip.conf. This manifest assumes you'll receive
# mail addressed to the hostname of your Zulip server.
#
# Users of other mail servers will need to configure it to pass mail to the
# email mirror; see `python manage.py email-mirror --help` for details.

# The email address pattern to use for auto-generated stream emails
# The %s will be replaced with a unique token, and the resulting email
# must be delivered to the EMAIL_GATEWAY_IMAP_FOLDER of the
# EMAIL_GATEWAY_LOGIN account below, or piped in to the email-mirror management
# command as indicated above.
#
# Example: zulip+%s@example.com
EMAIL_GATEWAY_PATTERN = ""

# The following options are relevant if you're using mail polling.
#
# A sample cron job for mail polling is available at puppet/zulip/files/cron.d/email-mirror
#
# The Zulip username of the bot that the email pattern should post as.
# Example: emailgateway@example.com
EMAIL_GATEWAY_BOT = ""

# Configuration of the email mirror mailbox
# The IMAP login and password
EMAIL_GATEWAY_LOGIN = ""
EMAIL_GATEWAY_PASSWORD = ""
# The IMAP server & port to connect to
EMAIL_GATEWAY_IMAP_SERVER = ""
EMAIL_GATEWAY_IMAP_PORT = 993
# The IMAP folder name to check for emails. All emails sent to EMAIL_GATEWAY_PATTERN above
# must be delivered to this folder
EMAIL_GATEWAY_IMAP_FOLDER = "INBOX"

### LDAP integration configuration
# Zulip supports retrieving information about users via LDAP, and optionally
# using LDAP as an authentication mechanism.

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

# URI of your LDAP server. If set, LDAP is used to prepopulate a user's name in
# Zulip. Example: "ldaps://ldap.example.com"
AUTH_LDAP_SERVER_URI = ""

# This DN and password will be used to bind to your server. If unset, anonymous
# binds are performed.
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""

# Specify the search base and the property to filter on that corresponds to the
# username.
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
    ldap.SCOPE_SUBTREE, "(uid=%(user)s)")

# If the value of a user's "uid" (or similar) property is not their email
# address, specify the domain to append here.
LDAP_APPEND_DOMAIN = ADMIN_DOMAIN

# This map defines how to populate attributes of a Zulip user from LDAP.
AUTH_LDAP_USER_ATTR_MAP = {
# Populate the Django user's name from the LDAP directory.
    "full_name": "cn",
}

CAMO_URI = ''
<commit_msg>Remove confusing EMAIL_HOST_PASSWORD setting in SMTP configuration.<commit_after># Settings for Zulip Voyager

### MANDATORY SETTINGS
#
# These settings MUST be set in production. In a development environment,
# sensible default values will be used.

# The user-accessible Zulip hostname for this installation, e.g.
# zulip.example.com
EXTERNAL_HOST = 'zulip.example.com'

# The email address for the person or team who maintain the Zulip
# Voyager installation. Will also get support emails. (e.g. zulip-admin@example.com)
ZULIP_ADMINISTRATOR = 'zulip-admin@example.com'

# The domain for your organization, e.g. example.com
ADMIN_DOMAIN = 'example.com'

# Enable at least one of the following authentication backends.
AUTHENTICATION_BACKENDS = (
#                           'zproject.backends.EmailAuthBackend', # Email and password
#                           'zproject.backends.ZulipRemoteUserBackend', # Local SSO
#                           'zproject.backends.GoogleMobileOauth2Backend', # Google Apps, setup below
    )

# Google Oauth requires a bit of configuration; you will need to go to
# https://console.developers.google.com, setup an Oauth2 client ID
# that allows redirects to
# e.g. https://zulip.example.com/accounts/login/google/done/ put your
# client secret as "google_oauth2_client_secret" in
# zulip-secrets.conf, and your cleitn ID here:
# GOOGLE_OAUTH2_CLIENT_ID=<your client ID from Google>

# If you are using the ZulipRemoteUserBackend authentication backend,
# set this to your domain (e.g. if REMOTE_USER is "username" and the
# corresponding email address is "username@example.com", set
# SSO_APPEND_DOMAIN = "example.com")
SSO_APPEND_DOMAIN = None

# Configure the outgoing SMTP server below. For outgoing email
# via a GMail SMTP server, EMAIL_USE_TLS must be True and the
# outgoing port must be 587. The EMAIL_HOST is prepopulated
# for GMail servers, change it for other hosts, or leave it unset
# or empty to skip sending email.
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = ''
# If you're using password auth, you will need to put the password in
# /etc/zulip/zulip-secrets.conf as email_host_password.
EMAIL_PORT = 587
EMAIL_USE_TLS = True

# The email From address to be used for automatically generated emails
DEFAULT_FROM_EMAIL = "Zulip <zulip@example.com>"
# The noreply address to be used as Reply-To for certain generated emails.
# Messages sent to this address should not be delivered anywhere.
NOREPLY_EMAIL_ADDRESS = "noreply@example.com"

# A list of strings representing the host/domain names that this
# Django site can serve. You should reset it to be a list of
# domains/IP addresses for your site. This is a security measure to
# prevent an attacker from poisoning caches and triggering password
# reset emails with links to malicious hosts by submitting requests
# with a fake HTTP Host header.
ALLOWED_HOSTS = ['*']

### OPTIONAL SETTINGS

# Controls whether session cookies expire when the browser closes
SESSION_EXPIRE_AT_BROWSER_CLOSE = False

# Session cookie expiry in seconds after the last page load
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # 2 weeks

# Controls whether or not there is a feedback button in the UI.
ENABLE_FEEDBACK = False

# By default, the feedback button will submit feedback to the Zulip
# developers.  If you set FEEDBACK_EMAIL to be an email address
# (e.g. ZULIP_ADMINISTRATOR), feedback sent by your users will instead
# be sent to that email address.
FEEDBACK_EMAIL = ZULIP_ADMINISTRATOR

# Controls whether or not error reports are sent to Zulip.  Error
# reports are used to improve the quality of the product and do not
# include message contents; please contact Zulip support with any
# questions.
ERROR_REPORTING = True

# Controls whether or not Zulip will provide inline image preview when
# a link to an image is referenced in a message.
INLINE_IMAGE_PREVIEW = True

# By default, files uploaded by users and user avatars are stored
# directly on the Zulip server.  If file storage in Amazon S3 (or
# elsewhere, e.g. your corporate fileshare) is desired, please contact
# Zulip Support (support@zulip.com) for further instructions on
# setting up the appropriate integration.
LOCAL_UPLOADS_DIR = "/home/zulip/uploads"

# Controls whether name changes are completely disabled for this installation
# This is useful in settings where you're syncing names from an integrated LDAP/Active Directory
NAME_CHANGES_DISABLED = False

# Controls whether users who have not uploaded an avatar will receive an avatar
# from gravatar.com.
ENABLE_GRAVATAR = True

# To override the default avatar image if ENABLE_GRAVATAR is False, place your
# custom default avatar image at /home/zulip/local-static/default-avatar.png
# and uncomment the following line.
#DEFAULT_AVATAR_URI = '/local-static/default-avatar.png'

### TWITTER INTEGRATION

# Zulip supports showing inline Tweet previews when a tweet is linked
# to in a message.  To support this, Zulip must have access to the
# Twitter API via OAuth.  To obtain the various access tokens needed
# below, you must register a new application under your Twitter
# account by doing the following:
#
# 1. Log in to http://dev.twitter.com.
# 2. In the menu under your username, click My Applications. From this page, create a new application.
# 3. Click on the application you created and click "create my access token". Fill in the requested values.
TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''
TWITTER_ACCESS_TOKEN_KEY = ''
TWITTER_ACCESS_TOKEN_SECRET = ''

### EMAIL GATEWAY INTEGRATION

# The email gateway provides, for each stream, an email address that
# you can send email to in order to have the email's content be posted
# to that stream.  Emails received at the per-stream email address
# will be converted into a Zulip message

# There are two ways to make use of local email mirroring:
#  1. Local delivery: A MTA runs locally and passes mail directly to Zulip
#  2. Polling: Checks an IMAP inbox every minute for new messages.

# A Puppet manifest for local delivery via Postfix is available in
# puppet/zulip/manifests/postfix_localmail.pp. To use the manifest, add it to
# puppet_classes in /etc/zulip/zulip.conf. This manifest assumes you'll receive
# mail addressed to the hostname of your Zulip server.
#
# Users of other mail servers will need to configure it to pass mail to the
# email mirror; see `python manage.py email-mirror --help` for details.

# The email address pattern to use for auto-generated stream emails
# The %s will be replaced with a unique token, and the resulting email
# must be delivered to the EMAIL_GATEWAY_IMAP_FOLDER of the
# EMAIL_GATEWAY_LOGIN account below, or piped in to the email-mirror management
# command as indicated above.
#
# Example: zulip+%s@example.com
EMAIL_GATEWAY_PATTERN = ""

# The following options are relevant if you're using mail polling.
#
# A sample cron job for mail polling is available at puppet/zulip/files/cron.d/email-mirror
#
# The Zulip username of the bot that the email pattern should post as.
# Example: emailgateway@example.com
EMAIL_GATEWAY_BOT = ""

# Configuration of the email mirror mailbox
# The IMAP login and password
EMAIL_GATEWAY_LOGIN = ""
EMAIL_GATEWAY_PASSWORD = ""
# The IMAP server & port to connect to
EMAIL_GATEWAY_IMAP_SERVER = ""
EMAIL_GATEWAY_IMAP_PORT = 993
# The IMAP folder name to check for emails. All emails sent to EMAIL_GATEWAY_PATTERN above
# must be delivered to this folder
EMAIL_GATEWAY_IMAP_FOLDER = "INBOX"

### LDAP integration configuration
# Zulip supports retrieving information about users via LDAP, and optionally
# using LDAP as an authentication mechanism.

import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

# URI of your LDAP server. If set, LDAP is used to prepopulate a user's name in
# Zulip. Example: "ldaps://ldap.example.com"
AUTH_LDAP_SERVER_URI = ""

# This DN and password will be used to bind to your server. If unset, anonymous
# binds are performed.
AUTH_LDAP_BIND_DN = ""
AUTH_LDAP_BIND_PASSWORD = ""

# Specify the search base and the property to filter on that corresponds to the
# username.
AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com",
    ldap.SCOPE_SUBTREE, "(uid=%(user)s)")

# If the value of a user's "uid" (or similar) property is not their email
# address, specify the domain to append here.
LDAP_APPEND_DOMAIN = ADMIN_DOMAIN

# This map defines how to populate attributes of a Zulip user from LDAP.
AUTH_LDAP_USER_ATTR_MAP = {
# Populate the Django user's name from the LDAP directory.
    "full_name": "cn",
}

CAMO_URI = ''
<|endoftext|>


<commit_before><commit_msg>small changes<commit_after><|endoftext|>


<commit_before>import sys

resolver = None

if sys.platform == "linux2":
    from . import linux
    resolver = linux.Resolver
elif sys.platform == "darwin":
    from . import osx
    resolver = osx.Resolver
elif sys.platform.startswith("freebsd"):
    from . import osx
    resolver = osx.Resolver
elif sys.platform == "win32":
    from . import windows
    resolver = windows.Resolver
<commit_msg>Fix platform import on Linux using python3<commit_after>import sys
import re

resolver = None

if re.match(r"linux(?:2)?", sys.platform):
    from . import linux
    resolver = linux.Resolver
elif sys.platform == "darwin":
    from . import osx
    resolver = osx.Resolver
elif sys.platform.startswith("freebsd"):
    from . import osx
    resolver = osx.Resolver
elif sys.platform == "win32":
    from . import windows
    resolver = windows.Resolver
<|endoftext|>


<commit_before>try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO
import glob
import os
import re

from django.apps import apps
from django.core import management
from django.core.management import BaseCommand
from django.core.management.base import CommandError
from django.db.migrations import writer

class Command(BaseCommand):
    help = "Locate initial_data.* files and create data migrations for them."

    def handle(self, *args, **options):
        # Loop through all apps
        for app in apps.get_app_configs():
            # Look for initial_data.* files
            for fixture_path in glob.glob(os.path.join(app.path, 'fixtures', 'initial_data.*')):
                # Ensure the app has at least an initial migration
                if not glob.glob(os.path.join(app.path, 'migrations', '0001*')):
                    self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app.label) + "\n")
                    self.stdout.write("  %s\n" % (self.style.WARNING("Ignoring '%s' - not migrated." % os.path.basename(fixture_path)),))
                    continue

                if self.migration_exists(app, fixture_path):
                    self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app.label) + "\n")
                    self.stdout.write("  %s\n" % (self.style.NOTICE("Ignoring '%s' - migration already exists." % os.path.basename(fixture_path)),))
                    continue

                # Finally create our data migration
                self.create_migration(app, fixture_path)

    def monkey_patch_migration_template(self, app, fixture_path):
        """
        Monkey patch the django.db.migrations.writer.MIGRATION_TEMPLATE

        Monkey patching django.db.migrations.writer.MIGRATION_TEMPLATE means that we
        don't have to do any complex regex or reflection.

        It's hacky... but works atm.
        """
        self._MIGRATION_TEMPLATE = writer.MIGRATION_TEMPLATE
        module_split = app.module.__name__.split('.')

        if len(module_split) == 1:
            module_import = "import {}\n".format(module_split[0])
        else:
            module_import = "from {} import {}\n".format(
                '.'.join(module_split[:-1]),
                module_split[-1:][0],
            )

        writer.MIGRATION_TEMPLATE = writer.MIGRATION_TEMPLATE\
            .replace(
                '%(imports)s',
                "%(imports)s" + "\nfrom django_migration_fixture import fixture\n%s" % module_import
            )\
            .replace(
                '%(operations)s',
                "        migrations.RunPython(**fixture(%s, ['%s'])),\n" % (
                    app.label,
                    os.path.basename(fixture_path)
                ) + "%(operations)s\n"
            )

    def restore_migration_template(self):
        """
        Restore the migration template.
        """
        writer.MIGRATION_TEMPLATE = self._MIGRATION_TEMPLATE

    def migration_exists(self, app, fixture_path):
        """
        Return true if it looks like a migration already exists.
        """
        base_name = os.path.basename(fixture_path)
        # Loop through all migrations
        for migration_path in glob.glob(os.path.join(app.path, 'migrations', '*.py')):
            if base_name in open(migration_path).read():
                return True
        return False

    def create_migration(self, app, fixture_path):
        """
        Create a data migration for app that uses fixture_path.
        """
        self.monkey_patch_migration_template(app, fixture_path)

        out = StringIO()
        management.call_command('makemigrations', app.label, empty=True, stdout=out)

        self.restore_migration_template()

        self.stdout.write(out.getvalue())
<commit_msg>Revert un-needed string format change.<commit_after>try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO
import glob
import os
import re

from django.apps import apps
from django.core import management
from django.core.management import BaseCommand
from django.core.management.base import CommandError
from django.db.migrations import writer

class Command(BaseCommand):
    help = "Locate initial_data.* files and create data migrations for them."

    def handle(self, *args, **options):
        # Loop through all apps
        for app in apps.get_app_configs():
            # Look for initial_data.* files
            for fixture_path in glob.glob(os.path.join(app.path, 'fixtures', 'initial_data.*')):
                # Ensure the app has at least an initial migration
                if not glob.glob(os.path.join(app.path, 'migrations', '0001*')):
                    self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app.label) + "\n")
                    self.stdout.write("  %s\n" % (self.style.WARNING("Ignoring '%s' - not migrated." % os.path.basename(fixture_path)),))
                    continue

                if self.migration_exists(app, fixture_path):
                    self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app.label) + "\n")
                    self.stdout.write("  %s\n" % (self.style.NOTICE("Ignoring '%s' - migration already exists." % os.path.basename(fixture_path)),))
                    continue

                # Finally create our data migration
                self.create_migration(app, fixture_path)

    def monkey_patch_migration_template(self, app, fixture_path):
        """
        Monkey patch the django.db.migrations.writer.MIGRATION_TEMPLATE

        Monkey patching django.db.migrations.writer.MIGRATION_TEMPLATE means that we
        don't have to do any complex regex or reflection.

        It's hacky... but works atm.
        """
        self._MIGRATION_TEMPLATE = writer.MIGRATION_TEMPLATE
        module_split = app.module.__name__.split('.')

        if len(module_split) == 1:
            module_import = "import %s\n" % module_split[0]
        else:
            module_import = "from %s import %s\n" % (
                '.'.join(module_split[:-1]),
                module_split[-1:][0],
            )

        writer.MIGRATION_TEMPLATE = writer.MIGRATION_TEMPLATE\
            .replace(
                '%(imports)s',
                "%(imports)s" + "\nfrom django_migration_fixture import fixture\n%s" % module_import
            )\
            .replace(
                '%(operations)s',
                "        migrations.RunPython(**fixture(%s, ['%s'])),\n" % (
                    app.label,
                    os.path.basename(fixture_path)
                ) + "%(operations)s\n"
            )

    def restore_migration_template(self):
        """
        Restore the migration template.
        """
        writer.MIGRATION_TEMPLATE = self._MIGRATION_TEMPLATE

    def migration_exists(self, app, fixture_path):
        """
        Return true if it looks like a migration already exists.
        """
        base_name = os.path.basename(fixture_path)
        # Loop through all migrations
        for migration_path in glob.glob(os.path.join(app.path, 'migrations', '*.py')):
            if base_name in open(migration_path).read():
                return True
        return False

    def create_migration(self, app, fixture_path):
        """
        Create a data migration for app that uses fixture_path.
        """
        self.monkey_patch_migration_template(app, fixture_path)

        out = StringIO()
        management.call_command('makemigrations', app.label, empty=True, stdout=out)

        self.restore_migration_template()

        self.stdout.write(out.getvalue())
<|endoftext|>


<commit_before># Donsol game
import random
import sys
from time import time
import logging

HEART = 1
DIAMOND = 2
SPADE = 3
CLUB = 4
JOKER = 5

SUIT_NAMES = {HEART: "Hearts",
              SPADE: "Spades",
              DIAMOND: "Diamonds",
              CLUB: "Clubs",
              JOKER: "Joker"}

SUIT_TYPES = {HEART: "Potion",
              SPADE: "Monster",
              DIAMOND: "Shield",
              CLUB: "Monster",
              JOKER: "Donsol"}

VALUES = {HEART:   [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11],
          DIAMOND: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11],
          CLUB:    [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17],
          SPADE:   [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17],
          JOKER:   [21, 21]}

CARD_POSITIONS = {
    'j': 0,
    'k': 1,
    'l': 2,
    ';': 3
}

SUIT_ART = {
    SPADE:
    [
    "   ∭∭  ",
    " ◢ ⁕ ) ",
    "  ╖▓▓╖ ",
    " m▟ m▟ ",
    ]
    ,
    CLUB:
    [
    "   ∭∭  ",
    " ◢ ⁕ ) ",
    "  ╖▓▓╖ ",
    " m▟ m▟ ",
    ]
    ,
    JOKER:
    [
    "   ╱ ╲  ",
    "  [ ۞ ] ",
    "   ╲ ╱  ",
    "   ҈ ҈ ҈ ҈  ",
    ]
    ,
    HEART:
    [
    "  ╮◎╭  ",
    "  ┋⇡┋  ",
    " ╭╛ ╘╮ ",
    " ╰━━━╯ ",
    ]
    ,
    DIAMOND:
    [
    "  ▞▲▚  ",
    " ╱┏ ┓╲ ",
    " ╲┗ ┛╱ ",
    "  ▚▼▞  ",
    ]
    ,
}

class Card:

    def __init__(self, suit, value, name=None):
        self.suit = suit
        self.name = name or suit
        self.value = value

    def is_monster(self):
        return self.suit in [SPADE, CLUB, JOKER]

    def __str__(self):
        if self.suit == JOKER:
            return "Joker"
        return "{} of {}".format(self.value, SUIT_NAMES[self.suit])

    def __repr__(self):
        return str(self)

class Player:

    def __init__(self):
        self.max_health = 21
        self.health = self.max_health
        self.shield = None
        self.can_drink_potion = True
        self.escaped_last_room = False

    def handle_monster(self, monster_value):
        damage = monster_value
        if self.shield:
            broken, damage = self.shield.handle_monster(monster_value)
            if broken:
                self.shield = None
        self.health = max(0, self.health - damage)
        logging.getLogger('history').info('Fought %s monster, took %s damage' % (monster_value,damage))
        self.can_drink_potion = True

    def equip_shield(self, value):
        self.shield = Shield(value)
        logging.getLogger('history').info('Equipped %s shield' % value)
        self.can_drink_potion = True

    def drink_potion(self, potion_value):
        if self.can_drink_potion:
            previous_health = self.health
            self.health = min(self.max_health, self.health+potion_value)
            #Log it
            msg = 'Drank potion, plus %s health' % (self.health - previous_health)
            logging.getLogger('history').info(msg)
            self.can_drink_potion = False
        else:
            logging.getLogger('history').info('Potion had no effect…')
            pass

    def enter_new_room(self, fled=False):
        self.escaped_last_room = fled

class Shield:

    def __init__(self, value):
        self.value = value
        self.previous_value = None

    def handle_monster(self, monster_value):
        """Return tuple of broken boolean and damage taken"""
        broken = False
        if (self.previous_value is not None and
                monster_value >= self.previous_value):
            logging.getLogger('history').info('Shield Broke!')
            broken = True
            self.value = 0
        self.previous_value = monster_value
        return (broken, max(0, monster_value - self.value))

class Room:

    def __init__(self, cards, player_escaped_previous_room=False):
        self.slots = dict(zip('jkl;', cards))
        self.player_escaped_previous_room = player_escaped_previous_room

    def flee(self):
        """
        Fleeing returns None if unable to flee, else returns the set of
        cards to return to the deck
        """
        if self.escapable():
            #TODO: print flavor text here
            logging.getLogger('history').info('Fleeing the room')
            return self.slots.values()
        return None

    def select_card(self, key):
        """
        Return the card at 'key' from the room, and remove it from the rooms'
        storage. If given an invalid key, return None
        """
        try:
            return self.slots.pop(key)
        except KeyError:
            return None

    def completed(self):
        if self.slots:
            return False
        return True

    def escapable(self):
        """Check whether or not the room is escapable"""
        if self.player_escaped_previous_room:
            monsters_remain = any(c.is_monster() for c in self.slots.values())
            if monsters_remain:
                return False
        return True

class Deck:
    """A deck holds an ordered set of cards and can pop or shuffle them"""

    def __init__(self, cards, seed=None):
        """Optionally accept a seed to make the deck deterministic"""
        self.cards = cards
        self.random = random.Random()
        if seed is None:
            seed = time()

        self.random.seed(seed)
        logging.getLogger('history').info("Deck's random seed is: {}".format(seed))
        #print("Deck's random seed is: {}".format(seed))

    def count(self):
        """Return how many cards remain in the deck"""
        return len(self.cards)

    def draw(self, count):
        """
        Draw <count> cards from the deck, or as many as are available.
        return a list of cards drawn.
        """
        drawn = []
        while len(drawn) < count:
            try:
                drawn.append(self.cards.pop())
            except IndexError:
                break
        return drawn

    def shuffle(self):
        self.random.shuffle(self.cards)

    def add(self, cards):
        """Add the passed list of cards to the deck"""
        self.cards.extend(cards)

def make_standard_deck():
    cards = []
    for suit in VALUES.keys():
        for value in VALUES[suit]:
            cards.append(Card(suit, value))
    return cards

class Dungeon:
    """Handle deck, room and player creation and interaction"""

    def __init__(self, cards=None, seed=None):
        if not cards:
            cards = make_standard_deck()
        self.deck = Deck(cards=cards, seed=seed)
        self.deck.shuffle()
        self.player = Player()
        self.room_history = []
        #self.event_history = []
        self.generate_room()

    def generate_room(self, fled=False):
        self.player.enter_new_room(fled=fled)
        self.room_history.append(Room(self.deck.draw(4), fled))

    def handle_input(self, input):
        if input == 'q':
            sys.exit()
        elif input in ['j', 'k', 'l', ';'] and self.player.health > 0:
            card = self.room_history[-1].select_card(input)
            if card:
                self.handle_card(card)
            if self.room_history[-1].completed():
                self.generate_room()
        elif input == 'f' and self.room_history[-1].escapable() and self.player.health > 0:
            cards = self.room_history[-1].flee()
            self.handle_flee(cards)
            self.generate_room(fled=True)
        else:
            pass

    def handle_card(self, card):
        if card.suit == HEART:
            self.player.drink_potion(card.value)
        elif card.suit == DIAMOND:
            self.player.equip_shield(card.value)
        else:
            self.player.handle_monster(card.value)

        if self.player.health == 0:
            logging.getLogger('history').info('You died!')

        if self.deck.count() == 0:
            logging.getLogger('history').info('You WON!')

    def handle_flee(self, cards):
        self.deck.add(cards)
        self.deck.shuffle()

class GameLogHandler(logging.Handler):
    """Keep track of what is going on in the Dungeon"""

    def __init__(self, *args, **kwargs):
        super(GameLogHandler, self).__init__(*args, **kwargs)
        self.history = []

    def get_history(self):
        return self.history

    def emit(self, record):
        self.history.append(record.getMessage())

class Renderer:
    """Render the dungeon and controls"""

    def __init__(self, dungeon, terminal, margin = 6, card_spacing = 18):
        self.dungeon = dungeon
        self.term = terminal

        # card positions:
        self.margin = margin
        self.spacing = card_spacing

        self.palette = {HEART: self.term.white,
                        SPADE: self.term.bright_red,
                        DIAMOND: self.term.white,
                        CLUB: self.term.bright_red,
                        JOKER: self.term.bright_blue}

        self.history_handler = GameLogHandler()
        logging.getLogger('history').setLevel(logging.INFO)
        logging.getLogger('history').addHandler(self.history_handler)

    def render(self):
        print(self.term.clear)

        slots = self.dungeon.room_history[-1].slots

        """
        Print artwork
        """

        for slot in slots:
            card = slots[slot]
            pos = CARD_POSITIONS[slot] * self.spacing
            color = self.palette[card.suit]

            for (y, line) in enumerate(SUIT_ART[card.suit]):
                print(self.term.move(1+y,self.margin + pos) + color(line))

        """
        Print card information
        """

        for slot in slots:
            card = slots[slot]
            pos = CARD_POSITIONS[slot] * self.spacing
            color = self.palette[card.suit]
            #info = str(card.name).capitalize() + " " + str(card)
            #
            # for (y, line) in enumerate(SUIT_ART[card.suit]):
            #     print(self.term.move(1+y,pos[0]) + line)

            print(
                self.term.move(self.margin, self.margin + pos) +
                    self.term.black_on_white (slot + '>') +
                    color(' ' + str(SUIT_TYPES[card.suit]) + ' ' +
                    str(card.value)) +
                self.term.move(self.margin + 1, self.margin + pos) +
                    self.term.blue (str(slots[slot]))
                )

        #flee command
        if self.dungeon.room_history[-1].escapable():
            print(
                self.term.move(self.margin + 5, self.margin) +
                self.term.black_on_white('f> flee') )
        else:
            print(
                self.term.move(self.margin + 5, self.margin) +
                self.term.red('Can\'t flee') )

        """
        Print stats like shield, health, etc
        """

        # shield
        if self.dungeon.player.shield:
            if self.dungeon.player.shield.previous_value:
                print(self.term.move(self.margin + 7, self.margin) +
                    "Shield: "
                    + str(self.dungeon.player.shield.value) + " "
                    + self.term.move_x(self.margin + 12) + '#' * self.dungeon.player.shield.value
                    + self.term.red(" ≠" + str(self.dungeon.player.shield.previous_value)))
            else:
                print(
                    self.term.move(self.margin + 7, self.margin) + "Shield: " +
                    str(self.dungeon.player.shield.value) +
                    self.term.move_x(self.margin + 12) +  '#' * self.dungeon.player.shield.value)

        # health
        if self.dungeon.player:
            print(self.term.move(self.margin + 8, self.margin) +
                "Health: "
                + str(self.dungeon.player.health) + " "
                + self.term.move_x(self.margin + 12) + '#' * self.dungeon.player.health)

        if self.dungeon.deck:
            print(self.term.move(self.margin + 9, self.margin) +
                "Cards Remaining: "
                + str(self.dungeon.deck.count()))

        #Print event history
        print(self.term.move(self.margin + 12, self.margin) + "History:")
        for index,x in enumerate(self.history_handler.get_history()[-4:]):
            print(self.term.move(self.margin + 12 + index, self.margin) +
            x)
<commit_msg>Fix win condition<commit_after># Donsol game
import random
import sys
from time import time
import logging

HEART = 1
DIAMOND = 2
SPADE = 3
CLUB = 4
JOKER = 5

SUIT_NAMES = {HEART: "Hearts",
              SPADE: "Spades",
              DIAMOND: "Diamonds",
              CLUB: "Clubs",
              JOKER: "Joker"}

SUIT_TYPES = {HEART: "Potion",
              SPADE: "Monster",
              DIAMOND: "Shield",
              CLUB: "Monster",
              JOKER: "Donsol"}

VALUES = {HEART:   [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11],
          DIAMOND: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11],
          CLUB:    [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17],
          SPADE:   [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17],
          JOKER:   [21, 21]}

CARD_POSITIONS = {
    'j': 0,
    'k': 1,
    'l': 2,
    ';': 3
}

SUIT_ART = {
    SPADE:
    [
    "   ∭∭  ",
    " ◢ ⁕ ) ",
    "  ╖▓▓╖ ",
    " m▟ m▟ ",
    ]
    ,
    CLUB:
    [
    "   ∭∭  ",
    " ◢ ⁕ ) ",
    "  ╖▓▓╖ ",
    " m▟ m▟ ",
    ]
    ,
    JOKER:
    [
    "   ╱ ╲  ",
    "  [ ۞ ] ",
    "   ╲ ╱  ",
    "   ҈ ҈ ҈ ҈  ",
    ]
    ,
    HEART:
    [
    "  ╮◎╭  ",
    "  ┋⇡┋  ",
    " ╭╛ ╘╮ ",
    " ╰━━━╯ ",
    ]
    ,
    DIAMOND:
    [
    "  ▞▲▚  ",
    " ╱┏ ┓╲ ",
    " ╲┗ ┛╱ ",
    "  ▚▼▞  ",
    ]
    ,
}

class Card:

    def __init__(self, suit, value, name=None):
        self.suit = suit
        self.name = name or suit
        self.value = value

    def is_monster(self):
        return self.suit in [SPADE, CLUB, JOKER]

    def __str__(self):
        if self.suit == JOKER:
            return "Joker"
        return "{} of {}".format(self.value, SUIT_NAMES[self.suit])

    def __repr__(self):
        return str(self)

class Player:

    def __init__(self):
        self.max_health = 21
        self.health = self.max_health
        self.shield = None
        self.can_drink_potion = True
        self.escaped_last_room = False

    def handle_monster(self, monster_value):
        damage = monster_value
        if self.shield:
            broken, damage = self.shield.handle_monster(monster_value)
            if broken:
                self.shield = None
        self.health = max(0, self.health - damage)
        logging.getLogger('history').info('Fought %s monster, took %s damage' % (monster_value,damage))
        self.can_drink_potion = True

    def equip_shield(self, value):
        self.shield = Shield(value)
        logging.getLogger('history').info('Equipped %s shield' % value)
        self.can_drink_potion = True

    def drink_potion(self, potion_value):
        if self.can_drink_potion:
            previous_health = self.health
            self.health = min(self.max_health, self.health+potion_value)
            #Log it
            msg = 'Drank potion, plus %s health' % (self.health - previous_health)
            logging.getLogger('history').info(msg)
            self.can_drink_potion = False
        else:
            logging.getLogger('history').info('Potion had no effect…')
            pass

    def enter_new_room(self, fled=False):
        self.escaped_last_room = fled

class Shield:

    def __init__(self, value):
        self.value = value
        self.previous_value = None

    def handle_monster(self, monster_value):
        """Return tuple of broken boolean and damage taken"""
        broken = False
        if (self.previous_value is not None and
                monster_value >= self.previous_value):
            logging.getLogger('history').info('Shield Broke!')
            broken = True
            self.value = 0
        self.previous_value = monster_value
        return (broken, max(0, monster_value - self.value))

class Room:

    def __init__(self, cards, player_escaped_previous_room=False):
        self.slots = dict(zip('jkl;', cards))
        self.player_escaped_previous_room = player_escaped_previous_room

    def flee(self):
        """
        Fleeing returns None if unable to flee, else returns the set of
        cards to return to the deck
        """
        if self.escapable():
            #TODO: print flavor text here
            logging.getLogger('history').info('Fleeing the room')
            return self.slots.values()
        return None

    def select_card(self, key):
        """
        Return the card at 'key' from the room, and remove it from the rooms'
        storage. If given an invalid key, return None
        """
        try:
            return self.slots.pop(key)
        except KeyError:
            return None

    def completed(self):
        if self.slots:
            return False
        return True

    def escapable(self):
        """Check whether or not the room is escapable"""
        if self.player_escaped_previous_room:
            monsters_remain = any(c.is_monster() for c in self.slots.values())
            if monsters_remain:
                return False
        return True

class Deck:
    """A deck holds an ordered set of cards and can pop or shuffle them"""

    def __init__(self, cards, seed=None):
        """Optionally accept a seed to make the deck deterministic"""
        self.cards = cards
        self.random = random.Random()
        if seed is None:
            seed = time()

        self.random.seed(seed)
        logging.getLogger('history').info("Deck's random seed is: {}".format(seed))
        #print("Deck's random seed is: {}".format(seed))

    def count(self):
        """Return how many cards remain in the deck"""
        return len(self.cards)

    def draw(self, count):
        """
        Draw <count> cards from the deck, or as many as are available.
        return a list of cards drawn.
        """
        drawn = []
        while len(drawn) < count:
            try:
                drawn.append(self.cards.pop())
            except IndexError:
                break
        return drawn

    def shuffle(self):
        self.random.shuffle(self.cards)

    def add(self, cards):
        """Add the passed list of cards to the deck"""
        self.cards.extend(cards)

def make_standard_deck():
    cards = []
    for suit in VALUES.keys():
        for value in VALUES[suit]:
            cards.append(Card(suit, value))
    return cards

class Dungeon:
    """Handle deck, room and player creation and interaction"""

    def __init__(self, cards=None, seed=None):
        if not cards:
            cards = make_standard_deck()
        self.deck = Deck(cards=cards, seed=seed)
        self.deck.shuffle()
        self.player = Player()
        self.room_history = []
        #self.event_history = []
        self.generate_room()

    def generate_room(self, fled=False):
        if self.deck.count() == 0 and self.player.health > 0:
            logging.getLogger('history').info('You WON!')
        else:
            self.player.enter_new_room(fled=fled)
            self.room_history.append(Room(self.deck.draw(4), fled))

    def handle_input(self, input):
        if input == 'q':
            sys.exit()
        elif input in ['j', 'k', 'l', ';'] and self.player.health > 0:
            card = self.room_history[-1].select_card(input)
            if card:
                self.handle_card(card)
            if self.room_history[-1].completed():
                self.generate_room()
        elif input == 'f' and self.room_history[-1].escapable() and self.player.health > 0:
            cards = self.room_history[-1].flee()
            self.handle_flee(cards)
            self.generate_room(fled=True)
        else:
            pass

    def handle_card(self, card):
        if card.suit == HEART:
            self.player.drink_potion(card.value)
        elif card.suit == DIAMOND:
            self.player.equip_shield(card.value)
        else:
            self.player.handle_monster(card.value)

        if self.player.health == 0:
            logging.getLogger('history').info('You died!')

    def handle_flee(self, cards):
        self.deck.add(cards)
        self.deck.shuffle()

class GameLogHandler(logging.Handler):
    """Keep track of what is going on in the Dungeon"""

    def __init__(self, *args, **kwargs):
        super(GameLogHandler, self).__init__(*args, **kwargs)
        self.history = []

    def get_history(self):
        return self.history

    def emit(self, record):
        self.history.append(record.getMessage())

class Renderer:
    """Render the dungeon and controls"""

    def __init__(self, dungeon, terminal, margin = 6, card_spacing = 18):
        self.dungeon = dungeon
        self.term = terminal

        # card positions:
        self.margin = margin
        self.spacing = card_spacing

        self.palette = {HEART: self.term.white,
                        SPADE: self.term.bright_red,
                        DIAMOND: self.term.white,
                        CLUB: self.term.bright_red,
                        JOKER: self.term.bright_blue}

        self.history_handler = GameLogHandler()
        logging.getLogger('history').setLevel(logging.INFO)
        logging.getLogger('history').addHandler(self.history_handler)

    def render(self):
        print(self.term.clear)

        slots = self.dungeon.room_history[-1].slots

        """
        Print artwork
        """

        for slot in slots:
            card = slots[slot]
            pos = CARD_POSITIONS[slot] * self.spacing
            color = self.palette[card.suit]

            for (y, line) in enumerate(SUIT_ART[card.suit]):
                print(self.term.move(1+y,self.margin + pos) + color(line))

        """
        Print card information
        """

        for slot in slots:
            card = slots[slot]
            pos = CARD_POSITIONS[slot] * self.spacing
            color = self.palette[card.suit]
            #info = str(card.name).capitalize() + " " + str(card)
            #
            # for (y, line) in enumerate(SUIT_ART[card.suit]):
            #     print(self.term.move(1+y,pos[0]) + line)

            print(
                self.term.move(self.margin, self.margin + pos) +
                    self.term.black_on_white (slot + '>') +
                    color(' ' + str(SUIT_TYPES[card.suit]) + ' ' +
                    str(card.value)) +
                self.term.move(self.margin + 1, self.margin + pos) +
                    self.term.blue (str(slots[slot]))
                )

        #flee command
        if self.dungeon.room_history[-1].escapable():
            print(
                self.term.move(self.margin + 5, self.margin) +
                self.term.black_on_white('f> flee') )
        else:
            print(
                self.term.move(self.margin + 5, self.margin) +
                self.term.red('Can\'t flee') )

        """
        Print stats like shield, health, etc
        """

        # shield
        if self.dungeon.player.shield:
            if self.dungeon.player.shield.previous_value:
                print(self.term.move(self.margin + 7, self.margin) +
                    "Shield: "
                    + str(self.dungeon.player.shield.value) + " "
                    + self.term.move_x(self.margin + 12) + '#' * self.dungeon.player.shield.value
                    + self.term.red(" ≠" + str(self.dungeon.player.shield.previous_value)))
            else:
                print(
                    self.term.move(self.margin + 7, self.margin) + "Shield: " +
                    str(self.dungeon.player.shield.value) +
                    self.term.move_x(self.margin + 12) +  '#' * self.dungeon.player.shield.value)

        # health
        if self.dungeon.player:
            print(self.term.move(self.margin + 8, self.margin) +
                "Health: "
                + str(self.dungeon.player.health) + " "
                + self.term.move_x(self.margin + 12) + '#' * self.dungeon.player.health)

        if self.dungeon.deck:
            print(self.term.move(self.margin + 9, self.margin) +
                "Cards Remaining: "
                + str(self.dungeon.deck.count()))

        #Print event history
        print(self.term.move(self.margin + 12, self.margin) + "History:")
        for index,x in enumerate(self.history_handler.get_history()[-4:]):
            print(self.term.move(self.margin + 12 + index, self.margin) +
            x)
<|endoftext|>


<commit_before># Copyright 2012 Rackspace
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import logging

import mock
import unittest2

from bark import handlers
from bark import middleware

class SimpleFormatterTest(unittest2.TestCase):
    def test_format(self):
        fmt = handlers.SimpleFormatter()
        record = logging.LogRecord('bark', logging.INFO, __file__, 27,
                                   'a test message', (), None, 'test_format')

        result = fmt.format(record)

        self.assertEqual(result, 'a test message')

class WrapLogHandlerTest(unittest2.TestCase):
    @mock.patch.object(handlers, 'SimpleFormatter', return_value='simple')
    @mock.patch('inspect.getsourcefile', return_value='bark/middleware.py')
    @mock.patch('inspect.getsourcelines', return_value=([], 127))
    def test_wrap_log_handler(self, mock_getsourcelines, mock_getsourcefile,
                              mock_SimpleFormatter):
        handler = mock.Mock(**{'emit.__name__': 'emit'})
        emit = handlers.wrap_log_handler(handler)

        mock_SimpleFormatter.assert_called_once_with()
        handler.setFormatter.assert_called_once_with('simple')
        self.assertFalse(handler.emit.called)

        emit("test message")

        self.assertEqual(handler.emit.call_count, 1)

        record = handler.emit.call_args[0][0]
        self.assertEqual(record.name, 'bark')
        self.assertEqual(record.levelno, logging.INFO)
        self.assertEqual(record.filename, 'middleware.py')
        self.assertEqual(record.module, 'middleware')
        self.assertEqual(record.lineno, 127)
        self.assertEqual(record.msg, 'test message')
        self.assertEqual(record.args, ())
        self.assertEqual(record.exc_info, None)
        self.assertEqual(record.funcName, '__call__')

class ArgTypesTest(unittest2.TestCase):
    def test_arg_types(self):
        @handlers.arg_types(foo=1, bar=2)
        @handlers.arg_types(bar=3, baz=4)
        def test():
            pass

        self.assertEqual(test._bark_types, dict(foo=1, bar=2, baz=4))

class BooleanTest(unittest2.TestCase):
    def test_boolean_true(self):
        for text in ['1', '1000', 't', 'T', 'TrUe', 'oN', 'yEs']:
            self.assertEqual(handlers.boolean(text), True)

    def test_boolean_false(self):
        for text in ['0', '0000', 'f', 'F', 'FaLsE', 'oFf', 'No']:
            self.assertEqual(handlers.boolean(text), False)

    def test_boolean_invalid(self):
        for text in ['tT', 'fF', 'tRu', 'FaL', 'o', 'yEs/nO']:
            self.assertRaises(ValueError, handlers.boolean, text)

class CommaTest(unittest2.TestCase):
    def test_comma_singular(self):
        self.assertEqual(handlers.comma('test'), ['test'])

    def test_comma_multiple(self):
        self.assertEqual(handlers.comma('test1,test2,test3'),
                         ['test1', 'test2', 'test3'])

    def test_comma_strip(self):
        self.assertEqual(handlers.comma('test1   ,   test2'),
                         ['test1', 'test2'])

class AddressTest(unittest2.TestCase):
    def test_address_noport(self):
        self.assertEqual(handlers.address('/dev/log'), '/dev/log')

    def test_address_withport(self):
        self.assertEqual(handlers.address('1:2:3'), ('1:2', 3))

    def test_address_badport(self):
        self.assertRaises(ValueError, handlers.address, '1:2:port')

class ChoiceTest(unittest2.TestCase):
    def test_init(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertEqual(ch.choices, set(['foo', 'bar', 'baz']))

    def test_call_accept(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertEqual(ch('foo'), 'foo')
        self.assertEqual(ch('bar'), 'bar')
        self.assertEqual(ch('baz'), 'baz')

    def test_call_reject(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertRaises(ValueError, ch, 'spam')

class ArgMapTest(unittest2.TestCase):
    def test_init(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertEqual(am.argmap, dict(foo=1, bar=2, baz=3))

    def test_call_accept(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertEqual(am('foo'), 1)
        self.assertEqual(am('bar'), 2)
        self.assertEqual(am('baz'), 3)

    def test_call_reject(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertRaises(ValueError, am, 'spam')

class CredentialsTest(unittest2.TestCase):
    def test_credentials_nocolon(self):
        self.assertEqual(handlers.credentials('user'), ('user', ''))

    def test_credentials_emptypass(self):
        self.assertEqual(handlers.credentials('user:'), ('user', ''))

    def test_credentials_emptyuser(self):
        self.assertEqual(handlers.credentials(':pass'), ('', 'pass'))

    def test_credentials_full(self):
        self.assertEqual(handlers.credentials('user:pass'), ('user', 'pass'))
<commit_msg>Add tests on all the defined handlers.<commit_after># Copyright 2012 Rackspace
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import logging
import logging.handlers
import sys

import mock
import unittest2

from bark import handlers
from bark import middleware

class SimpleFormatterTest(unittest2.TestCase):
    def test_format(self):
        fmt = handlers.SimpleFormatter()
        record = logging.LogRecord('bark', logging.INFO, __file__, 27,
                                   'a test message', (), None, 'test_format')

        result = fmt.format(record)

        self.assertEqual(result, 'a test message')

class WrapLogHandlerTest(unittest2.TestCase):
    @mock.patch.object(handlers, 'SimpleFormatter', return_value='simple')
    @mock.patch('inspect.getsourcefile', return_value='bark/middleware.py')
    @mock.patch('inspect.getsourcelines', return_value=([], 127))
    def test_wrap_log_handler(self, mock_getsourcelines, mock_getsourcefile,
                              mock_SimpleFormatter):
        handler = mock.Mock(**{'emit.__name__': 'emit'})
        emit = handlers.wrap_log_handler(handler)

        mock_SimpleFormatter.assert_called_once_with()
        handler.setFormatter.assert_called_once_with('simple')
        self.assertFalse(handler.emit.called)

        emit("test message")

        self.assertEqual(handler.emit.call_count, 1)

        record = handler.emit.call_args[0][0]
        self.assertEqual(record.name, 'bark')
        self.assertEqual(record.levelno, logging.INFO)
        self.assertEqual(record.filename, 'middleware.py')
        self.assertEqual(record.module, 'middleware')
        self.assertEqual(record.lineno, 127)
        self.assertEqual(record.msg, 'test message')
        self.assertEqual(record.args, ())
        self.assertEqual(record.exc_info, None)
        self.assertEqual(record.funcName, '__call__')

class ArgTypesTest(unittest2.TestCase):
    def test_arg_types(self):
        @handlers.arg_types(foo=1, bar=2)
        @handlers.arg_types(bar=3, baz=4)
        def test():
            pass

        self.assertEqual(test._bark_types, dict(foo=1, bar=2, baz=4))

class BooleanTest(unittest2.TestCase):
    def test_boolean_true(self):
        for text in ['1', '1000', 't', 'T', 'TrUe', 'oN', 'yEs']:
            self.assertEqual(handlers.boolean(text), True)

    def test_boolean_false(self):
        for text in ['0', '0000', 'f', 'F', 'FaLsE', 'oFf', 'No']:
            self.assertEqual(handlers.boolean(text), False)

    def test_boolean_invalid(self):
        for text in ['tT', 'fF', 'tRu', 'FaL', 'o', 'yEs/nO']:
            self.assertRaises(ValueError, handlers.boolean, text)

class CommaTest(unittest2.TestCase):
    def test_comma_singular(self):
        self.assertEqual(handlers.comma('test'), ['test'])

    def test_comma_multiple(self):
        self.assertEqual(handlers.comma('test1,test2,test3'),
                         ['test1', 'test2', 'test3'])

    def test_comma_strip(self):
        self.assertEqual(handlers.comma('test1   ,   test2'),
                         ['test1', 'test2'])

class AddressTest(unittest2.TestCase):
    def test_address_noport(self):
        self.assertEqual(handlers.address('/dev/log'), '/dev/log')

    def test_address_withport(self):
        self.assertEqual(handlers.address('1:2:3'), ('1:2', 3))

    def test_address_badport(self):
        self.assertRaises(ValueError, handlers.address, '1:2:port')

class ChoiceTest(unittest2.TestCase):
    def test_init(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertEqual(ch.choices, set(['foo', 'bar', 'baz']))

    def test_call_accept(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertEqual(ch('foo'), 'foo')
        self.assertEqual(ch('bar'), 'bar')
        self.assertEqual(ch('baz'), 'baz')

    def test_call_reject(self):
        ch = handlers.choice('foo', 'bar', 'baz')

        self.assertRaises(ValueError, ch, 'spam')

class ArgMapTest(unittest2.TestCase):
    def test_init(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertEqual(am.argmap, dict(foo=1, bar=2, baz=3))

    def test_call_accept(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertEqual(am('foo'), 1)
        self.assertEqual(am('bar'), 2)
        self.assertEqual(am('baz'), 3)

    def test_call_reject(self):
        am = handlers.argmap(dict(foo=1, bar=2, baz=3))

        self.assertRaises(ValueError, am, 'spam')

class CredentialsTest(unittest2.TestCase):
    def test_credentials_nocolon(self):
        self.assertEqual(handlers.credentials('user'), ('user', ''))

    def test_credentials_emptypass(self):
        self.assertEqual(handlers.credentials('user:'), ('user', ''))

    def test_credentials_emptyuser(self):
        self.assertEqual(handlers.credentials(':pass'), ('', 'pass'))

    def test_credentials_full(self):
        self.assertEqual(handlers.credentials('user:pass'), ('user', 'pass'))

class NullHandlerTest(unittest2.TestCase):
    def test_handler(self):
        emit = handlers.null_handler('null', 'test')

        self.assertTrue(callable(emit))

        # Make sure it doesn't raise any failures
        emit('this is a test')

class StdOutHandlerTest(unittest2.TestCase):
    @mock.patch('logging.StreamHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_StreamHandler):
        emit = handlers.stdout_handler('stdout', 'test')

        self.assertTrue(callable(emit))
        mock_StreamHandler.assert_called_once_with(sys.stdout)

class StdErrHandlerTest(unittest2.TestCase):
    @mock.patch('logging.StreamHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_StreamHandler):
        emit = handlers.stderr_handler('stderr', 'test')

        self.assertTrue(callable(emit))
        mock_StreamHandler.assert_called_once_with(sys.stderr)

class FileHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.file_handler._bark_types,
                         dict(delay=handlers.boolean))

    @mock.patch('logging.FileHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_FileHandler):
        args = dict(filename='filename', mode='b', encoding='encoding',
                    delay=True)
        emit = handlers.file_handler('file', 'test', **args)

        self.assertTrue(callable(emit))
        mock_FileHandler.assert_called_once_with(
            'filename', mode='b', encoding='encoding', delay=True)

class WatchedFileHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.watched_file_handler._bark_types,
                         dict(delay=handlers.boolean))

    @mock.patch('logging.handlers.WatchedFileHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_WatchedFileHandler):
        args = dict(filename='filename', mode='b', encoding='encoding',
                    delay=True)
        emit = handlers.watched_file_handler('watched_file', 'test', **args)

        self.assertTrue(callable(emit))
        mock_WatchedFileHandler.assert_called_once_with(
            'filename', mode='b', encoding='encoding', delay=True)

class RotatingFileHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.rotating_file_handler._bark_types,
                         dict(maxBytes=int, backupCount=int,
                              delay=handlers.boolean))

    @mock.patch('logging.handlers.RotatingFileHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_RotatingFileHandler):
        args = dict(filename='filename', mode='b', maxBytes=23,
                    backupCount=14, encoding='encoding', delay=True)
        emit = handlers.rotating_file_handler('rotating_file', 'test', **args)

        self.assertTrue(callable(emit))
        mock_RotatingFileHandler.assert_called_once_with(
            'filename', mode='b', maxBytes=23, backupCount=14,
            encoding='encoding', delay=True)

class TimedRotatingFileHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.timed_rotating_file_handler._bark_types,
                         dict(interval=int, backupCount=int,
                              delay=handlers.boolean, utc=handlers.boolean))

    @mock.patch('logging.handlers.TimedRotatingFileHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_TimedRotatingFileHandler):
        args = dict(filename='filename', when='b', interval=23,
                    backupCount=14, encoding='encoding', delay=True, utc=True)
        emit = handlers.timed_rotating_file_handler('timed_rotating_file',
                                                    'test', **args)

        self.assertTrue(callable(emit))
        mock_TimedRotatingFileHandler.assert_called_once_with(
            'filename', when='b', interval=23, backupCount=14,
            encoding='encoding', delay=True, utc=True)

class SocketHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.socket_handler._bark_types,
                         dict(port=int))

    @mock.patch('logging.handlers.SocketHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_SocketHandler):
        args = dict(host='host', port=4005)
        emit = handlers.socket_handler('socket', 'test', **args)

        self.assertTrue(callable(emit))
        mock_SocketHandler.assert_called_once_with(
            'host', 4005)

class DatagramHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.datagram_handler._bark_types,
                         dict(port=int))

    @mock.patch('logging.handlers.DatagramHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_DatagramHandler):
        args = dict(host='host', port=4005)
        emit = handlers.datagram_handler('datagram', 'test', **args)

        self.assertTrue(callable(emit))
        mock_DatagramHandler.assert_called_once_with('host', 4005)

class SysLogHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        types = handlers.syslog_handler._bark_types
        self.assertEqual(types.keys(), ['address', 'facility'])
        self.assertEqual(types['address'], handlers.address)
        self.assertIsInstance(types['facility'], handlers.argmap)
        self.assertEqual(types['facility'].argmap,
                         logging.handlers.SysLogHandler.facility_names)

    @mock.patch('logging.handlers.SysLogHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_SysLogHandler):
        args = dict(address='address', facility='facility')
        emit = handlers.syslog_handler('syslog', 'test', **args)

        self.assertTrue(callable(emit))
        mock_SysLogHandler.assert_called_once_with(
            address='address', facility='facility')

class NTEventLogHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        types = handlers.nt_event_log_handler._bark_types
        self.assertEqual(types.keys(), ['logtype'])
        self.assertIsInstance(types['logtype'], handlers.choice)
        self.assertEqual(types['logtype'].choices,
                         set(['Application', 'System', 'Security']))

    @mock.patch('logging.handlers.NTEventLogHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_NTEventLogHandler):
        args = dict(appname='appname', dllname='dllname', logtype='logtype')
        emit = handlers.nt_event_log_handler('nt_event_log', 'test', **args)

        self.assertTrue(callable(emit))
        mock_NTEventLogHandler.assert_called_once_with(
            'appname', dllname='dllname', logtype='logtype')

class SMTPHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        self.assertEqual(handlers.smtp_handler._bark_types,
                         dict(mailhost=handlers.address,
                              toaddrs=handlers.comma,
                              credentials=handlers.credentials))

    @mock.patch('logging.handlers.SMTPHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_SMTPHandler):
        args = dict(mailhost='mailhost', fromaddr='fromaddr',
                    toaddrs='toaddrs', subject='subject',
                    credentials='credentials')
        emit = handlers.smtp_handler('smtp', 'test', **args)

        self.assertTrue(callable(emit))
        mock_SMTPHandler.assert_called_once_with(
            'mailhost', 'fromaddr', 'toaddrs', 'subject',
            credentials='credentials')

class HTTPHandlerTest(unittest2.TestCase):
    def test_arg_types(self):
        types = handlers.http_handler._bark_types
        self.assertEqual(types.keys(), ['method'])
        self.assertIsInstance(types['method'], handlers.choice)
        self.assertEqual(types['method'].choices, set(['GET', 'POST']))

    @mock.patch('logging.handlers.HTTPHandler',
                return_value=mock.Mock(**{'emit.__name__': 'emit'}))
    def test_handler(self, mock_HTTPHandler):
        args = dict(host='host', url='url', method='method')
        emit = handlers.http_handler('http', 'test', **args)

        self.assertTrue(callable(emit))
        mock_HTTPHandler.assert_called_once_with(
            'host', 'url', method='method')
<|endoftext|>


<commit_before>from fabric.api import task, local

from fabfile.travis import Test

class Rubyspecs(Test):
    def __init__(self, files, options, translated=True):
        self.exe = "`pwd`/bin/%s" % ("topaz" if translated else "topaz_untranslated.py")
        self.files = files
        self.options = options
        self.download_mspec()
        self.download_rubyspec()

    def mspec(self, args):
        local("../mspec/bin/mspec %s -t %s --config=topaz.mspec %s" % (args, self.exe, self.files))

    def run(self):
        self.mspec("run -G fails %s" % self.options)

    def tag(self):
        self.mspec("tag --add fails -G fails -f spec %s" % self.options)

    def untag(self):
        self.mspec("tag --del fails -g fails -f spec %s" % self.options)

def generate_task(mode, taskname):
    def task(files="", options=""):
        runner = Rubyspecs(files, options, translated=(mode == "translated"))
        getattr(runner, taskname)()
    task.__name__ = "%s_%s" % (taskname, mode)
    return task

for mode in ["translated", "untranslated"]:
    for taskname in ["run", "tag", "untag"]:
        taskfun = generate_task(mode, taskname)
        globals()[taskfun.__name__] = task(taskfun)
<commit_msg>just make running untranslated an argument<commit_after>from fabric.api import task, local

from fabfile.travis import Test

class Rubyspecs(Test):
    def __init__(self, files, options, translated=True):
        self.exe = "`pwd`/bin/%s" % ("topaz" if translated else "topaz_untranslated.py")
        self.files = files
        self.options = options
        self.download_mspec()
        self.download_rubyspec()

    def mspec(self, args):
        local("../mspec/bin/mspec %s -t %s --config=topaz.mspec %s" % (args, self.exe, self.files))

    def run(self):
        self.mspec("run -G fails %s" % self.options)

    def tag(self):
        self.mspec("tag --add fails -G fails -f spec %s" % self.options)

    def untag(self):
        self.mspec("tag --del fails -g fails -f spec %s" % self.options)

def generate_task(taskname):
    def task(files="", options="", translated=True):
        runner = Rubyspecs(files, options, translated=(translated != "False"))
        getattr(runner, taskname)()
    task.__name__ = taskname
    return task

for taskname in ["run", "tag", "untag"]:
    taskfun = generate_task(taskname)
    globals()[taskfun.__name__] = task(taskfun)
<|endoftext|>


<commit_before>
# pylint: disable=wildcard-import, missing-docstring, protected-access
# pylint: disable=attribute-defined-outside-init, invalid-name, no-self-use
# pylint: disable=wrong-import-order, unused-wildcard-import

from .utils import *
from contact_map.dask_runner import *

class TestDaskContactFrequency(object):
    def test_dask_integration(self):
        # this is an integration test to check that dask works
        dask = pytest.importorskip('dask')  # pylint: disable=W0612
        distributed = pytest.importorskip('dask.distributed')
        client = distributed.Client(timeout=120)
        filename = find_testfile("trajectory.pdb")

        dask_freq = DaskContactFrequency(client, filename, cutoff=0.075,
                                         n_neighbors_ignored=0)
        client.close()
        assert dask_freq.n_frames == 5
<commit_msg>fix by only spin up 4 workers instead of 31<commit_after>
# pylint: disable=wildcard-import, missing-docstring, protected-access
# pylint: disable=attribute-defined-outside-init, invalid-name, no-self-use
# pylint: disable=wrong-import-order, unused-wildcard-import

from .utils import *
from contact_map.dask_runner import *

class TestDaskContactFrequency(object):
    def test_dask_integration(self):
        # this is an integration test to check that dask works
        dask = pytest.importorskip('dask')  # pylint: disable=W0612
        distributed = pytest.importorskip('dask.distributed')
        # Explicitly set only 4 workers on Travis instead of 31
        # Fix copied from https://github.com/spencerahill/aospy/pull/220/files
        cluster = distributed.LocalCluster(n_workers=4)
        client = distributed.Client(cluster)
        filename = find_testfile("trajectory.pdb")

        dask_freq = DaskContactFrequency(client, filename, cutoff=0.075,
                                         n_neighbors_ignored=0)
        client.close()
        assert dask_freq.n_frames == 5
<|endoftext|>


<commit_before><commit_msg>test path_for<commit_after><|endoftext|>