<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import gnucashxml
import datetime
import logging
import collections
import decimal

def account_full_name(account):
    name = account.name
    parent = account.parent
    while parent.name != "Root Account":
        name = parent.name + ":" + name
        parent = parent.parent
    return name.encode("utf-8")

def check_splits_sanity(splits):
    if (len(splits) != 2):
        message = "check_splits_sanity ("
        for split in splits:
            message += "split (" + account_full_name(split.account) + ", " + \
                str(float(split.value)) + "), "
        message += ")"
        print message
        raise Exception(message)

def start(flux, name, i, periods):
    si = str(i)
    par = "(D" + si + ":" + column(periods) + si + ")"
    flux.write(name + ",=AVERAGE" + par + ",=SPARKLINE" + par)

def column(j):
    c = ''
    j += 4
    while j > 0:
        c = chr(ord('A') - 1 + + j % 26) + c
        j /= 26
    return c

class PeriodStr(object):
    def __init__(self, date):
        self.period_str = date.strftime("%Y")

    def __eq__(self, obj):
        return self.period_str.__eq__(obj.period_str)

    def __lt__(self, obj):
        return self.period_str.__lt__(obj.period_str)

    def __le__(self, obj):
        return self.period_str.__le__(obj.period_str)

    def __gt__(self, obj):
        return self.period_str.__gt__(obj.period_str)

    def __ge__(self, obj):
        return self.period_str.__ge__(obj.period_str)

    def __hash__(self):
        return self.period_str.__hash__()

    def __int__(self):
        return int(self.period_str)

    def __str__(self):
        return self.period_str

class Assets(object):
    def __init__(self, assets_path):
        self.assets_path = assets_path
        self.assets = None

    def read_assets(self):
        self.assets = []
        with open(self.assets_path) as f:
            for line in f:
                asset = line.strip()
                if asset:
                    self.assets.append(asset)

    def is_asset(self, name):
        for asset in self.assets:
            if name.startswith(asset):
                return True
        return False

class Account(object):
    def __init__(self, name):
        self.name = name
        self.periods = {}

    def add_key(self, period):
        if period not in self.periods:
            self.periods[period] = 0

    def read_transaction(self, period, value):
        self.add_key(period)
        self.periods[period] += value

    def print_line(self, flux, periods, i):
        start(flux, self.name, i, len(periods))
        for period in sorted(periods):
            if period in self.periods:
                value = self.periods[period]
            else:
                value = 0
            flux.write("," + str(value))
        flux.write("\n")

class Periods(object):
    def __init__(self):
        self.periods = set()
        self.current_period = PeriodStr(datetime.date.today())

    def add_key(self, period):
        if period == self.current_period:
            return False
        logging.debug(
            "Periods.add_key: period (" + str(period) +
            ") < self.current_period (" + str(self.current_period) + ")")
        self.periods.add(period)
        return True

    def print_periods(self, flux):
        flux.write(",Average,Line")
        for period in sorted(self.periods):
            flux.write("," + str(period))
        flux.write("\n")

    def print_header(self, flux, pos, neg):
        self.print_periods(flux)
        self.print_sum(flux, "Total", 2, 0, pos + neg)
        self.print_sum(flux, "Positive", 3, 0, pos)
        self.print_sum(flux, "Negative", 4, pos, pos + neg)

    def print_sum(self, flux, name, i, begin, end):
        start(flux, name, i, len(self.periods))
        for j in range(len(self.periods)):
            c = column(j)
            flux.write(
                ",=SUM(" + c + str(5 + begin) + ":" + c + str(5 + end - 1) + ")")
        flux.write("\n")

    def print_percent(self, flux, name, num, den, i):
        start(flux, name, i, len(self.periods))
        for j in range(len(self.periods)):
            c = column(j)
            flux.write(",=" + c + str(num) + " / " + c + str(den))
        flux.write("\n")

class Table(object):
    def __init__(self, flux_path):
        self.flux_path = flux_path
        self.periods = Periods()
        self.pos = {}
        self.neg = {}

    def add_pos(self, account):
        logging.debug("Table.add_pos(" + account + ")")
        if account not in self.pos:
            self.pos[account] = Account(account)

    def add_neg(self, account):
        logging.debug("Table.add_neg(" + account + ")")
        if account not in self.neg:
            self.neg[account] = Account(account)

    def read_transaction(self, account, period, value):
        if not self.periods.add_key(period):
            return
        if value > 0:
            self.add_pos(account)
            self.pos[account].read_transaction(period, value)
        if value < 0:
            self.add_neg(account)
            self.neg[account].read_transaction(period, value)

    def print_accounts(self, flux):
        i = 5
        for account in sorted(self.pos):
            self.pos[account].print_line(flux, self.periods.periods, i)
            i += 1
        for account in sorted(self.neg):
            self.neg[account].print_line(flux, self.periods.periods, i)
            i += 1
        for account in sorted(self.pos):
            self.periods.print_percent(flux, account, i - len(self.pos) - len(self.neg), 3, i)
            i += 1
        for account in sorted(self.neg):
            self.periods.print_percent(flux, account, i - len(self.pos) - len(self.neg), 4, i)
            i += 1

    def print_table(self):
        with open(self.flux_path, "w") as flux:
            self.periods.print_header(flux, len(self.pos), len(self.neg))
            self.print_accounts(flux)

class Application(object):
    def __init__(self, gnucash_path, assets_path, flux_path):
        self.gnucash_path = gnucash_path
        self.assets = Assets(assets_path)
        self.table = Table(flux_path)

    def get_other_account(self, splits):
        logging.debug("get_other_account()")
        name_from = account_full_name(splits[0].account)
        name_to = account_full_name(splits[1].account)
        from_is_asset = self.assets.is_asset(name_from)
        to_is_asset = self.assets.is_asset(name_to)
        if from_is_asset and to_is_asset:
            logging.debug("Both assets: " + name_from + ", " + name_to)
            return None, None
        if from_is_asset:
            logging.debug("Asset: " + name_from + ", other: " + name_to)
            return name_to, 0
        if to_is_asset:
            logging.debug("Asset: " + name_to + ", other: " + name_from)
            return name_from, 1
        logging.debug("None are assets: " + name_from + ", " + name_to)
        return None, None

    def read_transaction(self, transaction):
        splits = transaction.splits
        check_splits_sanity(splits)
        account, i = self.get_other_account(splits)
        if account is None:
            return
        value = float(splits[i].value) / 12.0
        currency = transaction.currency.name
        if currency == "USD":
            value *= 3.1671
        elif currency == "EUR":
            value *= 3.9195
        period = PeriodStr(transaction.date)
        self.table.read_transaction(account, period, value)

    def main(self):
        book = gnucashxml.from_filename(self.gnucash_path)
        self.assets.read_assets()
        for transaction in book.transactions:
            self.read_transaction(transaction)
        self.table.print_table()

def main():
    logging.basicConfig(filename="flux.log", level=logging.DEBUG)
    app = Application("/home/marcots/gastos/gastos.gnucash", "assets.txt", "flux.csv")
    app.main()

if __name__ == "__main__":
    main()
<commit_msg>month<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import gnucashxml
import datetime
import logging
import collections
import decimal

def account_full_name(account):
    name = account.name
    parent = account.parent
    while parent.name != "Root Account":
        name = parent.name + ":" + name
        parent = parent.parent
    return name.encode("utf-8")

def check_splits_sanity(splits):
    if (len(splits) != 2):
        message = "check_splits_sanity ("
        for split in splits:
            message += "split (" + account_full_name(split.account) + ", " + \
                str(float(split.value)) + "), "
        message += ")"
        print message
        raise Exception(message)

def start(flux, name, i, periods):
    si = str(i)
    par = "(D" + si + ":" + column(periods) + si + ")"
    flux.write(name + ",=AVERAGE" + par + ",=SPARKLINE" + par)

def column(j):
    c = ''
    j += 4
    while j > 0:
        c = chr(ord('A') - 1 + + j % 26) + c
        j /= 26
    return c

class PeriodStr(object):
    def __init__(self, date):
        self.period_str = date.strftime("%Y-%m")

    def __eq__(self, obj):
        return self.period_str.__eq__(obj.period_str)

    def __lt__(self, obj):
        return self.period_str.__lt__(obj.period_str)

    def __le__(self, obj):
        return self.period_str.__le__(obj.period_str)

    def __gt__(self, obj):
        return self.period_str.__gt__(obj.period_str)

    def __ge__(self, obj):
        return self.period_str.__ge__(obj.period_str)

    def __hash__(self):
        return self.period_str.__hash__()

    def __int__(self):
        return int(self.period_str)

    def __str__(self):
        return self.period_str

class Assets(object):
    def __init__(self, assets_path):
        self.assets_path = assets_path
        self.assets = None

    def read_assets(self):
        self.assets = []
        with open(self.assets_path) as f:
            for line in f:
                asset = line.strip()
                if asset:
                    self.assets.append(asset)

    def is_asset(self, name):
        for asset in self.assets:
            if name.startswith(asset):
                return True
        return False

class Account(object):
    def __init__(self, name):
        self.name = name
        self.periods = {}

    def add_key(self, period):
        if period not in self.periods:
            self.periods[period] = 0

    def read_transaction(self, period, value):
        self.add_key(period)
        self.periods[period] += value

    def print_line(self, flux, periods, i):
        start(flux, self.name, i, len(periods))
        for period in sorted(periods):
            if period in self.periods:
                value = self.periods[period]
            else:
                value = 0
            flux.write("," + str(value))
        flux.write("\n")

class Periods(object):
    def __init__(self):
        self.periods = set()
        self.current_period = PeriodStr(datetime.date.today())

    def add_key(self, period):
        if period == self.current_period:
            return False
        logging.debug(
            "Periods.add_key: period (" + str(period) +
            ") < self.current_period (" + str(self.current_period) + ")")
        self.periods.add(period)
        return True

    def print_periods(self, flux):
        flux.write(",Average,Line")
        for period in sorted(self.periods):
            flux.write("," + str(period))
        flux.write("\n")

    def print_header(self, flux, pos, neg):
        self.print_periods(flux)
        self.print_sum(flux, "Total", 2, 0, pos + neg)
        self.print_sum(flux, "Positive", 3, 0, pos)
        self.print_sum(flux, "Negative", 4, pos, pos + neg)

    def print_sum(self, flux, name, i, begin, end):
        start(flux, name, i, len(self.periods))
        for j in range(len(self.periods)):
            c = column(j)
            flux.write(
                ",=SUM(" + c + str(5 + begin) + ":" + c + str(5 + end - 1) + ")")
        flux.write("\n")

    def print_percent(self, flux, name, num, den, i):
        start(flux, name, i, len(self.periods))
        for j in range(len(self.periods)):
            c = column(j)
            flux.write(",=" + c + str(num) + " / " + c + str(den))
        flux.write("\n")

class Table(object):
    def __init__(self, flux_path):
        self.flux_path = flux_path
        self.periods = Periods()
        self.pos = {}
        self.neg = {}

    def add_pos(self, account):
        logging.debug("Table.add_pos(" + account + ")")
        if account not in self.pos:
            self.pos[account] = Account(account)

    def add_neg(self, account):
        logging.debug("Table.add_neg(" + account + ")")
        if account not in self.neg:
            self.neg[account] = Account(account)

    def read_transaction(self, account, period, value):
        if not self.periods.add_key(period):
            return
        if value > 0:
            self.add_pos(account)
            self.pos[account].read_transaction(period, value)
        if value < 0:
            self.add_neg(account)
            self.neg[account].read_transaction(period, value)

    def print_accounts(self, flux):
        i = 5
        for account in sorted(self.pos):
            self.pos[account].print_line(flux, self.periods.periods, i)
            i += 1
        for account in sorted(self.neg):
            self.neg[account].print_line(flux, self.periods.periods, i)
            i += 1
        for account in sorted(self.pos):
            self.periods.print_percent(flux, account, i - len(self.pos) - len(self.neg), 3, i)
            i += 1
        for account in sorted(self.neg):
            self.periods.print_percent(flux, account, i - len(self.pos) - len(self.neg), 4, i)
            i += 1

    def print_table(self):
        with open(self.flux_path, "w") as flux:
            self.periods.print_header(flux, len(self.pos), len(self.neg))
            self.print_accounts(flux)

class Application(object):
    def __init__(self, gnucash_path, assets_path, flux_path):
        self.gnucash_path = gnucash_path
        self.assets = Assets(assets_path)
        self.table = Table(flux_path)

    def get_other_account(self, splits):
        logging.debug("get_other_account()")
        name_from = account_full_name(splits[0].account)
        name_to = account_full_name(splits[1].account)
        from_is_asset = self.assets.is_asset(name_from)
        to_is_asset = self.assets.is_asset(name_to)
        if from_is_asset and to_is_asset:
            logging.debug("Both assets: " + name_from + ", " + name_to)
            return None, None
        if from_is_asset:
            logging.debug("Asset: " + name_from + ", other: " + name_to)
            return name_to, 0
        if to_is_asset:
            logging.debug("Asset: " + name_to + ", other: " + name_from)
            return name_from, 1
        logging.debug("None are assets: " + name_from + ", " + name_to)
        return None, None

    def read_transaction(self, transaction):
        splits = transaction.splits
        check_splits_sanity(splits)
        account, i = self.get_other_account(splits)
        if account is None:
            return
        value = float(splits[i].value) / 12.0
        currency = transaction.currency.name
        if currency == "USD":
            value *= 3.1671
        elif currency == "EUR":
            value *= 3.9195
        period = PeriodStr(transaction.date)
        self.table.read_transaction(account, period, value)

    def main(self):
        book = gnucashxml.from_filename(self.gnucash_path)
        self.assets.read_assets()
        for transaction in book.transactions:
            self.read_transaction(transaction)
        self.table.print_table()

def main():
    logging.basicConfig(filename="flux.log", level=logging.DEBUG)
    app = Application("/home/marcots/gastos/gastos.gnucash", "assets.txt", "flux.csv")
    app.main()

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>from django.conf.urls import patterns, include, url
from django.utils.translation import ugettext_lazy as _
from django.contrib.sitemaps.views import sitemap

import contracts.urls
import deputies.urls
import law.urls
from . import views
from .sitemaps import Sitemap

sitemaps = {
    'sitemaps': Sitemap,
}

urlpatterns = patterns('',
                       (r'^i18n/', include('django.conf.urls.i18n')),
                       url(r'^$', views.home, name='home'),
                       url(r'^%s$' % _('about'), views.about, name='about'),
                       url(r'^', include(contracts.urls, app_name='contracts')),
                       url(r'^', include(deputies.urls, app_name='deputies')),
                       url(r'^', include(law.urls, app_name='law')),
                       (r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}),
                       (r'^robots\.txt$', views.robots),
                       )

from django.conf import settings
if settings.DEBUG:
    import debug_toolbar
    urlpatterns += patterns('',
                            url(r'^__debug__/', include(debug_toolbar.urls)),
                            )
<commit_msg>Removed unused app_name in urls.<commit_after>from django.conf.urls import patterns, include, url
from django.utils.translation import ugettext_lazy as _
from django.contrib.sitemaps.views import sitemap

import contracts.urls
import deputies.urls
import law.urls
from . import views
from .sitemaps import Sitemap

sitemaps = {
    'sitemaps': Sitemap,
}

urlpatterns = patterns('',
                       (r'^i18n/', include('django.conf.urls.i18n')),
                       url(r'^$', views.home, name='home'),
                       url(r'^%s$' % _('about'), views.about, name='about'),
                       url(r'^', include(contracts.urls)),
                       url(r'^', include(deputies.urls)),
                       url(r'^', include(law.urls)),
                       (r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}),
                       (r'^robots\.txt$', views.robots),
                       )

from django.conf import settings
if settings.DEBUG:
    import debug_toolbar
    urlpatterns += patterns('',
                            url(r'^__debug__/', include(debug_toolbar.urls)),
                            )
<|endoftext|>


<commit_before>from . import Socket, Server<commit_msg>Fixed something with the new classing<commit_after>from Socket import Socket
from Server import Server<|endoftext|>


<commit_before>#  Copyright 2015 Google Inc. 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 random

import numpy as np
import tensorflow as tf

from sklearn.base import BaseEstimator, ClassifierMixin, RegressorMixin

from skflow.trainer import TensorFlowTrainer
from skflow.ops import mean_squared_error_regressor, softmax_classifier

class LinearRegression(object):
    """Linear Regression TensorFlow model."""

    def __init__(self, input_shape, graph):
        with graph.as_default():
            self.global_step = tf.Variable(0, name="global_step", trainable=False)
            self.inp = tf.placeholder(tf.float32, [None, input_shape], name="input")
            self.out = tf.placeholder(tf.float32, [None], name="output")
            self.weights = tf.get_variable("weights", [input_shape, 1])
            self.bias = tf.get_variable("bias", [1])
            self.predictions, self.loss = mean_squared_error_regressor(
                self.inp, self.out, self.weights, self.bias)

class LogisticRegression(object):
    """Logistic Regression TensorFlow model."""

    def __init__(self, n_classes, input_shape, graph):
        with graph.as_default():
            self.global_step = tf.Variable(0, name="global_step", trainable=False)
            self.inp = tf.placeholder(tf.float32, [None, input_shape], name="input")
            self.out = tf.placeholder(tf.float32, [None, n_classes], name="output")
            self.weights = tf.get_variable("weights", [input_shape, n_classes])
            self.bias = tf.get_variable("bias", [n_classes])
            self.predictions, self.loss = softmax_classifier(
                self.inp, self.out, self.weights, self.bias)

class TensorFlowEstimator(BaseEstimator):
  """Base class for all TensorFlow estimators.

  Parameters:
      tf_master: TensorFlow master. Empty string is default for local.
      batch_size: Mini batch size.
      steps: Number of steps to run over data.
      optimizer: Optimizer name (or class), for example "SGD", "Adam",
                 "Adagrad".
      learning_rate: Learning rate for optimizer.
  """

  def __init__(self, n_classes, tf_master="", batch_size=32, steps=50, optimizer="SGD",
               learning_rate=0.1):
    self.n_classes = n_classes
    self.tf_master = tf_master
    self.batch_size = batch_size
    self.steps = steps
    self.optimizer = optimizer
    self.learning_rate = learning_rate

  def _get_feed_dict_fn(self, model, X, y):

    def _feed_dict():
      inp = np.zeros([self.batch_size, X.shape[1]])
      if self.n_classes > 1:
        out = np.zeros([self.batch_size, self.n_classes])
      else:
        out = np.zeros([self.batch_size])
      for i in xrange(self.batch_size):
        sample = random.randint(0, X.shape[0] - 1)
        inp[i, :] = X[sample, :]
        if self.n_classes > 1:
          out[i, y[sample]] = 1.0
        else:
          out[i] = y[sample]
      return {model.inp.name: inp, model.out.name: out,}

    return _feed_dict

  def fit(self, X, y):
    with tf.Graph().as_default() as graph:
      if self.n_classes > 1:
        self._model = LogisticRegression(self.n_classes, X.shape[1], graph)
      else:
        self._model = LinearRegression(X.shape[1], graph)
      self._trainer = TensorFlowTrainer(self._model, self.optimizer, self.learning_rate)
      self._session = tf.Session(self.tf_master)
      self._trainer.initialize(self._session)
      self._trainer.train(self._session,
                          self._get_feed_dict_fn(self._model, X, y), self.steps)

  def predict(self, X):
    pred = self._session.run(self._model.predictions,
                             feed_dict={
                                 self._model.inp.name: X
                             })
    if self.n_classes < 2:
      return pred
    return pred.argmax(axis=1)

class TensorFlowRegressor(TensorFlowEstimator, RegressorMixin):
  pass

class TensorFlowClassifier(TensorFlowEstimator, ClassifierMixin):
  pass

<commit_msg>Moved out get_feed_dict_fn into a DataFeeder to allow customize it later<commit_after>#  Copyright 2015 Google Inc. 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 random

import numpy as np
import tensorflow as tf

from sklearn.base import BaseEstimator, ClassifierMixin, RegressorMixin

from skflow.trainer import TensorFlowTrainer
from skflow.ops import mean_squared_error_regressor, softmax_classifier

class LinearRegression(object):
    """Linear Regression TensorFlow model."""

    def __init__(self, input_shape, graph):
        with graph.as_default():
            self.global_step = tf.Variable(0, name="global_step", trainable=False)
            self.inp = tf.placeholder(tf.float32, [None, input_shape], name="input")
            self.out = tf.placeholder(tf.float32, [None], name="output")
            self.weights = tf.get_variable("weights", [input_shape, 1])
            self.bias = tf.get_variable("bias", [1])
            self.predictions, self.loss = mean_squared_error_regressor(
                self.inp, self.out, self.weights, self.bias)

class LogisticRegression(object):
    """Logistic Regression TensorFlow model."""

    def __init__(self, n_classes, input_shape, graph):
        with graph.as_default():
            self.global_step = tf.Variable(0, name="global_step", trainable=False)
            self.inp = tf.placeholder(tf.float32, [None, input_shape], name="input")
            self.out = tf.placeholder(tf.float32, [None, n_classes], name="output")
            self.weights = tf.get_variable("weights", [input_shape, n_classes])
            self.bias = tf.get_variable("bias", [n_classes])
            self.predictions, self.loss = softmax_classifier(
                self.inp, self.out, self.weights, self.bias)

class DataFeeder(object):
    """Data feeder is an example class to sample data for TF trainer.

    Parameters:
        X: feature matrix.
        y: target vector, either floats for regression or class id for
            classification.
        n_classes: number of classes, 0 and 1 are considered regression.
        batch_size: mini batch size to accumulate.
    """

    def __init__(self, X, y, n_classes, batch_size):
        self.X = X
        self.y = y
        self.n_classes = n_classes
        self.batch_size = batch_size

    def get_feed_dict_fn(self, input_placeholder, output_placeholder):
        """Returns a function, that will sample data and provide it to given
        placeholders.

        Args:
            input_placeholder: tf.Placeholder for input features mini batch.
            output_placeholder: tf.Placeholder for output targets.
        Returns:
            A function that when called samples a random subset of batch size
            from X and y.
        """
        def _feed_dict_fn():
            inp = np.zeros([self.batch_size, self.X.shape[1]])
            if self.n_classes > 1:
                out = np.zeros([self.batch_size, self.n_classes])
            else:
                out = np.zeros([self.batch_size])
            for i in xrange(self.batch_size):
                sample = random.randint(0, self.X.shape[0] - 1)
                inp[i, :] = self.X[sample, :]
                if self.n_classes > 1:
                    out[i, self.y[sample]] = 1.0
                else:
                    out[i] = self.y[sample]
            return {input_placeholder.name: inp, output_placeholder.name: out}
        return _feed_dict_fn

class TensorFlowEstimator(BaseEstimator):
    """Base class for all TensorFlow estimators.

    Parameters:
        tf_master: TensorFlow master. Empty string is default for local.
        batch_size: Mini batch size.
        steps: Number of steps to run over data.
        optimizer: Optimizer name (or class), for example "SGD", "Adam",
                   "Adagrad".
        learning_rate: Learning rate for optimizer.
    """

    def __init__(self, n_classes, tf_master="", batch_size=32, steps=50, optimizer="SGD",
                 learning_rate=0.1):
        self.n_classes = n_classes
        self.tf_master = tf_master
        self.batch_size = batch_size
        self.steps = steps
        self.optimizer = optimizer
        self.learning_rate = learning_rate

    def fit(self, X, y):
        with tf.Graph().as_default() as graph:
            if self.n_classes > 1:
                self._model = LogisticRegression(self.n_classes, X.shape[1], graph)
            else:
                self._model = LinearRegression(X.shape[1], graph)
            self._data_feeder = DataFeeder(X, y, self.n_classes, self.batch_size)
            self._trainer = TensorFlowTrainer(self._model, self.optimizer, self.learning_rate)
            self._session = tf.Session(self.tf_master)
            self._trainer.initialize(self._session)
            self._trainer.train(self._session,
                                self._data_feeder.get_feed_dict_fn(self._model.inp,
                                                             self._model.out), self.steps)

    def predict(self, X):
        pred = self._session.run(self._model.predictions,
                                 feed_dict={
                                     self._model.inp.name: X
                                 })
        if self.n_classes < 2:
            return pred
        return pred.argmax(axis=1)

class TensorFlowRegressor(TensorFlowEstimator, RegressorMixin):
  pass

class TensorFlowClassifier(TensorFlowEstimator, ClassifierMixin):
  pass

<|endoftext|>


<commit_before>import sys
import re
from types import FunctionType
from should_dsl import native_matchers

_predicate_regexes = set(['is_(.+)', 'is(.+)'])

class Should(object):

    def __init__(self, negate=False, be=False, have=False):
        self._negate = negate
        self._have = have
        self._matchers_by_name = dict()
        if have or be:
            self._set_default_matcher()
        self._identifiers_named_equal_matchers = dict()

    def _evaluate(self, value):
        if self._negate:
            return not value
        return value

    def __ror__(self, lvalue):
        self._lvalue = lvalue
        self._create_function_matchers()
        return self

    def __or__(self, rvalue):
        self._destroy_function_matchers()
        if not hasattr(self, '_old_style_call'):
            self._rvalue = rvalue
            if not hasattr(rvalue, 'match'):
                self._convert_deprecated_style(rvalue)
        else:
            self._convert_deprecated_style(rvalue)
        return self._check_expectation()

    def _destroy_function_matchers(self):
        self._remove_matchers_from_namespace()
        self._put_original_identifiers_back()

    def _remove_matchers_from_namespace(self):
        self._remove_regular_matchers_from_namespace()
        self._remove_predicate_matchers_from_namespace()

    def _remove_regular_matchers_from_namespace(self):
        f_globals = self._especific_namespace_level(5)
        for matcher_name in list(self._matchers_by_name.keys()):
            del f_globals[matcher_name]

    def _remove_predicate_matchers_from_namespace(self):
        f_globals = self._especific_namespace_level(5)
        attr_names = [attr_name for attr_name in dir(self._lvalue) if not attr_name.startswith('_')]
        for attr_name in attr_names:
            del f_globals['be_' + attr_name]

    def _put_original_identifiers_back(self):
        f_globals = self._especific_namespace_level(4)
        for attr_name, attr_ref in self._identifiers_named_equal_matchers.items():
            f_globals[attr_name] = attr_ref
        self._identifiers_named_equal_matchers.clear()

    def _especific_namespace_level(self, level):
        return sys._getframe(level).f_globals

    def _check_expectation(self):
        if not self._evaluate(self._rvalue.match(self._lvalue)):
            raise ShouldNotSatisfied(self._negate and self._rvalue.message_for_failed_should_not() or self._rvalue.message_for_failed_should())

    def add_matcher(self, matcher_object):
        if (hasattr(matcher_object, 'func_name') or
            isinstance(matcher_object, FunctionType)):
            function, message = matcher_object()
            class GeneratedMatcher(object):
                name = matcher_object.__name__
                def __init__(self):
                    self._function, self._message = function, message
                def __call__(self, arg):
                    self.arg = arg
                    return self
                def match(self, value):
                    self._value = value
                    return self._function(self._value, self.arg)
                def message_for_failed_should(self):
                    return self._message % (self._value, "not ", self.arg)
                def message_for_failed_should_not(self):
                    return self._message % (self._value, "", self.arg)
            matcher_object = GeneratedMatcher
            name = GeneratedMatcher.name
        else:
            name = matcher_object.name
        self._validate_matcher(matcher_object)
        self._matchers_by_name[name] = matcher_object

    def _validate_matcher(self, matcher_object):
        try:
            matcher_object()
        except TypeError:
            e = sys.exc_info()[1]
            if str(e).startswith('__init__() takes exactly'):
                raise TypeError('matcher class constructor cannot have arguments')
            else:
                raise

    def _create_function_matchers(self):
        self._save_clashed_identifiers()
        self._put_matchers_on_namespace()

    def _save_clashed_identifiers(self):
        f_globals = self._especific_namespace_level(4)
        predicate_matcher_names = ['be_' + attr_name for attr_name in dir(self._lvalue) if not attr_name.startswith('_')]
        for matcher_name in list(self._matchers_by_name.keys()) + predicate_matcher_names:
            if matcher_name in f_globals:
                self._identifiers_named_equal_matchers[matcher_name] = f_globals[matcher_name]

    def _put_matchers_on_namespace(self):
        self._put_regular_matchers_on_namespace()
        self._put_predicate_matchers_on_namespace()

    def _put_regular_matchers_on_namespace(self):
        f_globals = self._especific_namespace_level(5)
        for matcher_name, matcher_function in self._matchers_by_name.items():
            matcher_function = self._matchers_by_name[matcher_name]
            f_globals[matcher_name] = matcher_function()

    def _put_predicate_matchers_on_namespace(self):
        f_globals = self._especific_namespace_level(5)
        predicate_and_matcher_names = []
        public_names = self._get_all_public_attr_names(self._lvalue)
        for attr_name in public_names:
            for regex in _predicate_regexes:
                r = re.match(regex, attr_name)
                if r:
                    predicate_and_matcher_names.append((r.group(1), attr_name))
        predicate_and_matcher_names += [(attr_name, attr_name) for attr_name in public_names]
        for predicate_name, attr_name in predicate_and_matcher_names:
            f_globals['be_' + predicate_name] = _PredicateMatcher(attr_name)

    def _get_all_public_attr_names(self, obj):
        return [attr_name for attr_name in dir(obj) if not attr_name.startswith('_')]

    # deprecated behaviour
    def __getattr__(self, method_name):
        if method_name not in self._matchers_by_name:
            raise AttributeError("%s object has no matcher '%s'" % (
                self.__class__.__name__, method_name))
        return self._prepare_to_receive_rvalue(method_name)

    def _prepare_to_receive_rvalue(self, method_name):
        should = Should(negate=self._negate, have=self._have, be=not self._have)
        should._matchers_by_name = self._matchers_by_name
        should._old_style_call = True
        should._matcher = self._matchers_by_name[method_name]
        return should

    def _set_default_matcher(self):
        '''The default behavior for a should object, called on constructor'''
        if self._have:
            self._turn_into_should_have()
        else:
            self._turn_into_should_be()

    def _turn_into_should_have(self):
        self._matcher = native_matchers.NativeHaveMatcher

    def _turn_into_should_be(self):
        self._matcher = native_matchers.NativeBeMatcher

    def _convert_deprecated_style(self, rvalue):
        self._rvalue = self._matcher()
        self._rvalue.arg = rvalue

class _PredicateMatcher(object):

    def __init__(self, attr_name):
        self._attr_name = attr_name

    def __call__(self, *params):
        self._params = params
        return self

    def match(self, value):
        self._value = value
        attr_value = getattr(self._value, self._attr_name)
        if self._is_method(attr_value):
            if self._has_param():
                attr_value = attr_value(*self._params)
            else:
                attr_value = attr_value()
        return attr_value

    def message_for_failed_should(self):
        return "expected %s to %s True, got False" % (
            self._display_attr(self._attr_name),
            self._display_verb(self._attr_name))

    def message_for_failed_should_not(self):
        return "expected %s to %s False, got True" % (
            self._display_attr(self._attr_name),
            self._display_verb(self._attr_name))

    def _is_method(self, object_):
        return (hasattr(object_, 'im_func') or hasattr(object_, '__func__'))

    def _display_attr(self, attr_name):
        if self._is_method(getattr(self._value, attr_name)):
            if self._has_param():
                repr_params = [repr(param) for param in self._params]
                param = ", ".join(repr_params)
            else:
                param = ""
            return "%s(%s)" % (attr_name, param)
        else:
            return attr_name

    def _display_verb(self, attr_name):
        return self._is_method(getattr(self._value, attr_name)) \
            and "return" or "be"

    def _has_param(self):
        return hasattr(self, '_params')

class ShouldNotSatisfied(AssertionError):
    '''Extends AssertionError for unittest compatibility'''

should = Should(negate=False)
should_not = Should(negate=True)

# should objects for backwards compatibility
should_be = Should(be=True)
should_not_be = Should(negate=True, be=True)
should_have = Should(negate=False, have=True)
should_not_have = Should(negate=True, have=True)

def matcher(matcher_object):
    '''Create customer should_be matchers. We recommend you use it as a decorator'''
    should_objects = (should, should_not, should_be, should_not_be, should_have,
                      should_not_have)
    for should_object in should_objects:
        should_object.add_matcher(matcher_object)
    return matcher_object

def add_predicate_regex(regex):
    _predicate_regexes.update([regex])
<commit_msg>fixed `especific/specific` typo<commit_after>import sys
import re
from types import FunctionType
from should_dsl import native_matchers

_predicate_regexes = set(['is_(.+)', 'is(.+)'])

class Should(object):

    def __init__(self, negate=False, be=False, have=False):
        self._negate = negate
        self._have = have
        self._matchers_by_name = dict()
        if have or be:
            self._set_default_matcher()
        self._identifiers_named_equal_matchers = dict()

    def _evaluate(self, value):
        if self._negate:
            return not value
        return value

    def __ror__(self, lvalue):
        self._lvalue = lvalue
        self._create_function_matchers()
        return self

    def __or__(self, rvalue):
        self._destroy_function_matchers()
        if not hasattr(self, '_old_style_call'):
            self._rvalue = rvalue
            if not hasattr(rvalue, 'match'):
                self._convert_deprecated_style(rvalue)
        else:
            self._convert_deprecated_style(rvalue)
        return self._check_expectation()

    def _destroy_function_matchers(self):
        self._remove_matchers_from_namespace()
        self._put_original_identifiers_back()

    def _remove_matchers_from_namespace(self):
        self._remove_regular_matchers_from_namespace()
        self._remove_predicate_matchers_from_namespace()

    def _remove_regular_matchers_from_namespace(self):
        f_globals = self._specific_namespace_level(5)
        for matcher_name in list(self._matchers_by_name.keys()):
            del f_globals[matcher_name]

    def _remove_predicate_matchers_from_namespace(self):
        f_globals = self._specific_namespace_level(5)
        attr_names = [attr_name for attr_name in dir(self._lvalue) if not attr_name.startswith('_')]
        for attr_name in attr_names:
            del f_globals['be_' + attr_name]

    def _put_original_identifiers_back(self):
        f_globals = self._specific_namespace_level(4)
        for attr_name, attr_ref in self._identifiers_named_equal_matchers.items():
            f_globals[attr_name] = attr_ref
        self._identifiers_named_equal_matchers.clear()

    def _specific_namespace_level(self, level):
        return sys._getframe(level).f_globals

    def _check_expectation(self):
        if not self._evaluate(self._rvalue.match(self._lvalue)):
            raise ShouldNotSatisfied(self._negate and self._rvalue.message_for_failed_should_not() or self._rvalue.message_for_failed_should())

    def add_matcher(self, matcher_object):
        if (hasattr(matcher_object, 'func_name') or
            isinstance(matcher_object, FunctionType)):
            function, message = matcher_object()
            class GeneratedMatcher(object):
                name = matcher_object.__name__
                def __init__(self):
                    self._function, self._message = function, message
                def __call__(self, arg):
                    self.arg = arg
                    return self
                def match(self, value):
                    self._value = value
                    return self._function(self._value, self.arg)
                def message_for_failed_should(self):
                    return self._message % (self._value, "not ", self.arg)
                def message_for_failed_should_not(self):
                    return self._message % (self._value, "", self.arg)
            matcher_object = GeneratedMatcher
            name = GeneratedMatcher.name
        else:
            name = matcher_object.name
        self._validate_matcher(matcher_object)
        self._matchers_by_name[name] = matcher_object

    def _validate_matcher(self, matcher_object):
        try:
            matcher_object()
        except TypeError:
            e = sys.exc_info()[1]
            if str(e).startswith('__init__() takes exactly'):
                raise TypeError('matcher class constructor cannot have arguments')
            else:
                raise

    def _create_function_matchers(self):
        self._save_clashed_identifiers()
        self._put_matchers_on_namespace()

    def _save_clashed_identifiers(self):
        f_globals = self._specific_namespace_level(4)
        predicate_matcher_names = ['be_' + attr_name for attr_name in dir(self._lvalue) if not attr_name.startswith('_')]
        for matcher_name in list(self._matchers_by_name.keys()) + predicate_matcher_names:
            if matcher_name in f_globals:
                self._identifiers_named_equal_matchers[matcher_name] = f_globals[matcher_name]

    def _put_matchers_on_namespace(self):
        self._put_regular_matchers_on_namespace()
        self._put_predicate_matchers_on_namespace()

    def _put_regular_matchers_on_namespace(self):
        f_globals = self._specific_namespace_level(5)
        for matcher_name, matcher_function in self._matchers_by_name.items():
            matcher_function = self._matchers_by_name[matcher_name]
            f_globals[matcher_name] = matcher_function()

    def _put_predicate_matchers_on_namespace(self):
        f_globals = self._specific_namespace_level(5)
        predicate_and_matcher_names = []
        public_names = self._get_all_public_attr_names(self._lvalue)
        for attr_name in public_names:
            for regex in _predicate_regexes:
                r = re.match(regex, attr_name)
                if r:
                    predicate_and_matcher_names.append((r.group(1), attr_name))
        predicate_and_matcher_names += [(attr_name, attr_name) for attr_name in public_names]
        for predicate_name, attr_name in predicate_and_matcher_names:
            f_globals['be_' + predicate_name] = _PredicateMatcher(attr_name)

    def _get_all_public_attr_names(self, obj):
        return [attr_name for attr_name in dir(obj) if not attr_name.startswith('_')]

    # deprecated behaviour
    def __getattr__(self, method_name):
        if method_name not in self._matchers_by_name:
            raise AttributeError("%s object has no matcher '%s'" % (
                self.__class__.__name__, method_name))
        return self._prepare_to_receive_rvalue(method_name)

    def _prepare_to_receive_rvalue(self, method_name):
        should = Should(negate=self._negate, have=self._have, be=not self._have)
        should._matchers_by_name = self._matchers_by_name
        should._old_style_call = True
        should._matcher = self._matchers_by_name[method_name]
        return should

    def _set_default_matcher(self):
        '''The default behavior for a should object, called on constructor'''
        if self._have:
            self._turn_into_should_have()
        else:
            self._turn_into_should_be()

    def _turn_into_should_have(self):
        self._matcher = native_matchers.NativeHaveMatcher

    def _turn_into_should_be(self):
        self._matcher = native_matchers.NativeBeMatcher

    def _convert_deprecated_style(self, rvalue):
        self._rvalue = self._matcher()
        self._rvalue.arg = rvalue

class _PredicateMatcher(object):

    def __init__(self, attr_name):
        self._attr_name = attr_name

    def __call__(self, *params):
        self._params = params
        return self

    def match(self, value):
        self._value = value
        attr_value = getattr(self._value, self._attr_name)
        if self._is_method(attr_value):
            if self._has_param():
                attr_value = attr_value(*self._params)
            else:
                attr_value = attr_value()
        return attr_value

    def message_for_failed_should(self):
        return "expected %s to %s True, got False" % (
            self._display_attr(self._attr_name),
            self._display_verb(self._attr_name))

    def message_for_failed_should_not(self):
        return "expected %s to %s False, got True" % (
            self._display_attr(self._attr_name),
            self._display_verb(self._attr_name))

    def _is_method(self, object_):
        return (hasattr(object_, 'im_func') or hasattr(object_, '__func__'))

    def _display_attr(self, attr_name):
        if self._is_method(getattr(self._value, attr_name)):
            if self._has_param():
                repr_params = [repr(param) for param in self._params]
                param = ", ".join(repr_params)
            else:
                param = ""
            return "%s(%s)" % (attr_name, param)
        else:
            return attr_name

    def _display_verb(self, attr_name):
        return self._is_method(getattr(self._value, attr_name)) \
            and "return" or "be"

    def _has_param(self):
        return hasattr(self, '_params')

class ShouldNotSatisfied(AssertionError):
    '''Extends AssertionError for unittest compatibility'''

should = Should(negate=False)
should_not = Should(negate=True)

# should objects for backwards compatibility
should_be = Should(be=True)
should_not_be = Should(negate=True, be=True)
should_have = Should(negate=False, have=True)
should_not_have = Should(negate=True, have=True)

def matcher(matcher_object):
    '''Create customer should_be matchers. We recommend you use it as a decorator'''
    should_objects = (should, should_not, should_be, should_not_be, should_have,
                      should_not_have)
    for should_object in should_objects:
        should_object.add_matcher(matcher_object)
    return matcher_object

def add_predicate_regex(regex):
    _predicate_regexes.update([regex])
<|endoftext|>


<commit_before>import sublime, sublime_plugin
import json, threading, time, sys, os, time
from Fuse.interop import *
from Fuse.cmd_parser import *
from Fuse.fuse_util import *
from Fuse.go_to_definition import *
from Fuse.build_results import *
from Fuse.output_view import *
from Fuse.build_output import *

items = None
isUpdatingCache = False
autoCompleteEvent = None
closeEvent = None
interop = None
buildResults = None
outputView = OutputView()
buildOutput = BuildOutputView()
connectThread = None

def Recv(msg):
	try:
		parsedRes = CmdParser.ParseCommand(msg)
		name = parsedRes[0]
		args = parsedRes[1]

		if name == "NewFileCreated":
			HandleNewFileCreated(args)
		if name == "SetCodeSuggestions":
			HandleCodeSuggestion(args)
		if name == "WriteToConsole":
			WriteToConsole(args)
		if name == "Error":
			Error(args)
		if name == "GoToDefinitionResponse":
			GoToDefinition(args)
		if name == "BuildEventRaised":
			BuildEventRaised(args)
		if name == "NewBuild":
			global buildResults
			buildResults = BuildResults(sublime.active_window())
	except:
		print(sys.exc_info()[0])

def Error(cmd):
	print("Fuse - Error: " + cmd["ErrorString"])
	autoCompleteEvent.set()
	autoCompleteEvent.clear()

def WriteToConsole(args):
	typeOfConsole = args["Type"]
	if typeOfConsole == "DebugLog":
		outputView.Write(args["Text"])
	elif typeOfConsole == "BuildLog":
		buildOutput.Write(args["Text"])

def BuildEventRaised(cmd):
	buildResults.Add(cmd)

# Rebuild a sequence as a list of n-tuples
def Group(lst, n):
    return zip(*[lst[i::n] for i in range(n)])

def TrimType(typeDesc):
	return typeDesc.rpartition(".")[2]

# Parse a method or constructor into tab completion text, type hint and verbose hint
def ParseMethod(access, methodName, arguments, returntype, asCtor):
	args = Group(arguments, 2)
	verboseHintText = " ".join(access)
	methodText = methodName+"("

	if asCtor:
		typeHint = "Class ("
	else:
		typeHint = "("

	count = 1
	for arg in args:
		if(count>1):
			methodText += ", "
			typeHint += ", "
		argName = arg[1]
		isOut = argName.find("&") > -1
		if isOut:
			argName = argName.replace("&", "")
			methodText += "out ${" + str(count) + ":" + argName + "}"
			typeHint += "out ";
		else:
			methodText += "${" + str(count) + ":" + argName + "}"

		typeHint += TrimType(arg[0]) + " " + argName
		count += 1

	if asCtor:
		typeHint += ")"
	else:
		typeHint += "):" + TrimType(returntype)
	methodText += ")"

	return (methodText, typeHint, verboseHintText)

def HandleNewFileCreated(cmd):
	filePath = cmd["FilePath"]
	active_window.open_file(filePath)

def HandleCodeSuggestion(cmd):
	suggestions = cmd["CodeSuggestions"]

	global items
	global isUpdatingCache
	isUpdatingCache = cmd["IsUpdatingCache"]
	items = []

	print("Received "+str(len(suggestions)))
	for suggestion in suggestions:

		suggestionText = suggestion["Suggestion"]
		memberType = suggestion["Type"]
		# new stuff
		accessModifiers = suggestion["AccessModifiers"]
		fieldModifiers = suggestion["FieldModifiers"]
		descriptionText = suggestion["TypeDescription"]
		arguments = suggestion["MethodArguments"]

		verboseHintText = ""

		if descriptionText == "":
			descriptionText = memberType

		outtext = suggestionText

		if memberType == "Method" or memberType == "Constructor":
			# Build sublime tab completion, type hint and verbose type hint
			parsedMethod = ParseMethod(accessModifiers, suggestionText, arguments, descriptionText, memberType == "Constructor")
			suggestionText = parsedMethod[0]
			descriptionText = parsedMethod[1]
			verboseHintText = parsedMethod[2]

		if memberType == "Field" or memberType == "Property":
			descriptionText = TrimType(descriptionText)

		if suggestion["PreText"] != "":
			suggestionText = suggestion["PreText"] + suggestion["PostText"]

		outtext += "\t" + descriptionText

		items.append((outtext, suggestionText))

	autoCompleteEvent.set()
	autoCompleteEvent.clear()

def plugin_loaded():
	global items
	global autoCompleteEvent
	global closeEvent
	global interop
	global buildResults

	items = []
	autoCompleteEvent = threading.Event()
	closeEvent = threading.Event()
	interop = Interop(Recv, SendHandshake)
	buildResults = BuildResults(sublime.active_window())

	global connectThread
	connectThread = threading.Thread(target = TryConnect)
	connectThread.daemon = True
	connectThread.start()

	s = sublime.load_settings("Preferences.sublime-settings")
	if GetSetting("fuse_open_files_in_same_window"):
		s.set("open_files_in_new_window", False)
	else:
		s.set("open_files_in_new_window", True)

def plugin_unloaded():
	closeEvent.set()
	connectThread.join(1)

	global interop
	interop = None

def TryConnect():
	try:
		while not closeEvent.is_set():
			if GetSetting("fuse_enabled") == True and not interop.IsConnected():
				interop.Connect()
				if interop.IsConnected():
					SendHandshake()

			time.sleep(1)
	finally:
		interop.Disconnect()

def SendHandshake():
	interop.Send(json.dumps({"Command":"SetFeatures", "Arguments":
		{"Features":[{"Name":"CodeCompletion"},
		{"Name": "Console"},
		{"Name": "BuildEvent"},
		{"Name": "ShortcutFeature"}]}}))

class FuseEventListener(sublime_plugin.EventListener):
	def RequestAutoComplete(self, view, prefix, syntaxName):
		fileName = view.file_name()
		text = view.substr(sublime.Region(0,view.size()))
		caret = view.sel()[0].a
		interop.Send(json.dumps({"Command":"RequestCodeCompletion", "Arguments":{
			"QueryId": 0,
			"Path": fileName, "Text": text,
			"Type": syntaxName, "CaretPosition": GetRowCol(view, caret)}}))

	def on_query_completions(self, view, prefix, locations):
		global items

		if GetSetting("fuse_completion") == False or not interop.IsConnected():
			return

		syntaxName = GetExtension(view.settings().get("syntax"))
		if not IsSupportedSyntax(syntaxName):
			return

		self.RequestAutoComplete(view, prefix, syntaxName)

		autoCompleteEvent.wait(0.2)

		data = (items, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS)
		if len(items) == 0:
			if isUpdatingCache == True:
				return ([("Updating suggestion cache...", "_"), ("", "")], sublime.INHIBIT_WORD_COMPLETIONS)

			if GetSetting("fuse_if_no_completion_use_sublime") == False:
				return ([("", "")], sublime.INHIBIT_WORD_COMPLETIONS)
			else:
				return

		items = []
		return data

class DisconnectCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		interop.Disconnect()

class ToggleBuildresCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		buildResults.ToggleShow()

class ToggleOutputviewCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		outputView.ToggleShow()

class ToggleBuildoutputCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		buildOutput.ToggleShow()

class GotoDefinitionCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		view = self.view

		syntaxName = GetExtension(view.settings().get("syntax"))
		if not IsSupportedSyntax(syntaxName) or len(view.sel()) == 0:
			return

		text = view.substr(sublime.Region(0,view.size()))
		caret = view.sel()[0].a

		interop.Send(json.dumps({"Command": "GotoDefinition", "Arguments":{
			"Path": view.file_name(),
			"Text": text,
			"Type": syntaxName,
			"CaretPosition": GetRowCol(view, caret),
			"QueryId": 0}}))

class FuseRefreshCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		interop.Send(json.dumps({"Command": "RefreshViewports"}))<commit_msg>Removed temp NewFileCreated command. Cleaned up some formatting and naming.<commit_after>import sublime, sublime_plugin
import json, threading, time, sys, os, time
from Fuse.interop import *
from Fuse.cmd_parser import *
from Fuse.fuse_util import *
from Fuse.go_to_definition import *
from Fuse.build_results import *
from Fuse.output_view import *
from Fuse.build_output import *

items = None
isUpdatingCache = False
autoCompleteEvent = None
closeEvent = None
interop = None
buildResults = None
outputView = OutputView()
buildOutput = BuildOutputView()
connectThread = None

def Recv(msg):
	try:
		parsedRes = CmdParser.ParseCommand(msg)
		name = parsedRes[0]
		args = parsedRes[1]

		if name == "SetCodeSuggestions":
			HandleCodeSuggestion(args)
		if name == "WriteToConsole":
			WriteToConsole(args)
		if name == "Error":
			Error(args)
		if name == "GoToDefinitionResponse":
			GoToDefinition(args)
		if name == "BuildEventRaised":
			BuildEventRaised(args)
		if name == "NewBuild":
			global buildResults
			buildResults = BuildResults(sublime.active_window())
	except:
		print(sys.exc_info()[0])

def Error(cmd):
	print("Fuse - Error: " + cmd["ErrorString"])
	autoCompleteEvent.set()
	autoCompleteEvent.clear()

def WriteToConsole(args):
	typeOfConsole = args["Type"]
	if typeOfConsole == "DebugLog":
		outputView.Write(args["Text"])
	elif typeOfConsole == "BuildLog":
		buildOutput.Write(args["Text"])

def BuildEventRaised(cmd):
	buildResults.Add(cmd)

# Rebuild a sequence as a list of n-tuples
def Group(lst, n):
    return zip(*[lst[i::n] for i in range(n)])

def TrimType(typeDesc):
	return typeDesc.rpartition(".")[2]

# Parse a method or constructor into tab completion text, type hint and verbose hint
def ParseMethod(access, methodName, arguments, returntype, asCtor):
	args = Group(arguments, 2)
	verboseHintText = " ".join(access)
	methodText = methodName+"("

	if asCtor:
		typeHint = "Class ("
	else:
		typeHint = "("

	count = 1
	for arg in args:
		if(count>1):
			methodText += ", "
			typeHint += ", "
		argName = arg[1]
		isOut = argName.find("&") > -1
		if isOut:
			argName = argName.replace("&", "")
			methodText += "out ${" + str(count) + ":" + argName + "}"
			typeHint += "out ";
		else:
			methodText += "${" + str(count) + ":" + argName + "}"

		typeHint += TrimType(arg[0]) + " " + argName
		count += 1

	if asCtor:
		typeHint += ")"
	else:
		typeHint += "):" + TrimType(returntype)
	methodText += ")"

	return (methodText, typeHint, verboseHintText)

def HandleCodeSuggestion(cmd):
	suggestions = cmd["CodeSuggestions"]

	global items
	global isUpdatingCache
	isUpdatingCache = cmd["IsUpdatingCache"]
	items = []

	for suggestion in suggestions:

		suggestionText = suggestion["Suggestion"]
		suggestionType = suggestion["Type"]

		accessModifiers = suggestion["AccessModifiers"]
		fieldModifiers = suggestion["FieldModifiers"]
		hintText = suggestion["ReturnType"]
		arguments = suggestion["MethodArguments"]

		verboseHintText = ""

		if hintText == "":
			hintText = suggestionType

		outText = suggestionText

		if suggestionType == "Method" or suggestionType == "Constructor":
			# Build sublime tab completion, type hint and verbose type hint
			parsedMethod = ParseMethod(accessModifiers, suggestionText, arguments, hintText, suggestionType == "Constructor")
			suggestionText = parsedMethod[0]
			hintText = parsedMethod[1]
			verboseHintText = parsedMethod[2]

		if suggestionType == "Field" or suggestionType == "Property":
			hintText = TrimType(hintText)

		if suggestion["PreText"] != "":
			suggestionText = suggestion["PreText"] + suggestion["PostText"]

		outText += "\t" + hintText

		items.append((outText, suggestionText))

	autoCompleteEvent.set()
	autoCompleteEvent.clear()

def plugin_loaded():
	global items
	global autoCompleteEvent
	global closeEvent
	global interop
	global buildResults

	items = []
	autoCompleteEvent = threading.Event()
	closeEvent = threading.Event()
	interop = Interop(Recv, SendHandshake)
	buildResults = BuildResults(sublime.active_window())

	global connectThread
	connectThread = threading.Thread(target = TryConnect)
	connectThread.daemon = True
	connectThread.start()

	s = sublime.load_settings("Preferences.sublime-settings")
	if GetSetting("fuse_open_files_in_same_window"):
		s.set("open_files_in_new_window", False)
	else:
		s.set("open_files_in_new_window", True)

def plugin_unloaded():
	closeEvent.set()
	connectThread.join(1)

	global interop
	interop = None

def TryConnect():
	try:
		while not closeEvent.is_set():
			if GetSetting("fuse_enabled") == True and not interop.IsConnected():
				interop.Connect()
				if interop.IsConnected():
					SendHandshake()

			time.sleep(1)
	finally:
		interop.Disconnect()

def SendHandshake():
	interop.Send(json.dumps({"Command":"SetFeatures", "Arguments":
		{"Features":[{"Name":"CodeCompletion"},
		{"Name": "Console"},
		{"Name": "BuildEvent"},
		{"Name": "ShortcutFeature"}]}}))

class FuseEventListener(sublime_plugin.EventListener):
	def RequestAutoComplete(self, view, prefix, syntaxName):
		fileName = view.file_name()
		text = view.substr(sublime.Region(0,view.size()))
		caret = view.sel()[0].a
		interop.Send(json.dumps({"Command":"RequestCodeCompletion", "Arguments":{
			"QueryId": 0,
			"Path": fileName, "Text": text,
			"Type": syntaxName, "CaretPosition": GetRowCol(view, caret)}}))

	def on_query_completions(self, view, prefix, locations):
		global items

		if GetSetting("fuse_completion") == False or not interop.IsConnected():
			return

		syntaxName = GetExtension(view.settings().get("syntax"))
		if not IsSupportedSyntax(syntaxName):
			return

		self.RequestAutoComplete(view, prefix, syntaxName)

		autoCompleteEvent.wait(0.2)

		data = (items, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS)
		if len(items) == 0:
			if isUpdatingCache == True:
				return ([("Updating suggestion cache...", "_"), ("", "")], sublime.INHIBIT_WORD_COMPLETIONS)

			if GetSetting("fuse_if_no_completion_use_sublime") == False:
				return ([("", "")], sublime.INHIBIT_WORD_COMPLETIONS)
			else:
				return

		items = []
		return data

class DisconnectCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		interop.Disconnect()

class ToggleBuildresCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		buildResults.ToggleShow()

class ToggleOutputviewCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		outputView.ToggleShow()

class ToggleBuildoutputCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		buildOutput.ToggleShow()

class GotoDefinitionCommand(sublime_plugin.TextCommand):
	def run(self, edit):
		view = self.view

		syntaxName = GetExtension(view.settings().get("syntax"))
		if not IsSupportedSyntax(syntaxName) or len(view.sel()) == 0:
			return

		text = view.substr(sublime.Region(0,view.size()))
		caret = view.sel()[0].a

		interop.Send(json.dumps({"Command": "GotoDefinition", "Arguments":{
			"Path": view.file_name(),
			"Text": text,
			"Type": syntaxName,
			"CaretPosition": GetRowCol(view, caret),
			"QueryId": 0}}))

class FuseRefreshCommand(sublime_plugin.ApplicationCommand):
	def run(self):
		interop.Send(json.dumps({"Command": "RefreshViewports"}))<|endoftext|>


<commit_before>import re
import unittest

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from host import Host
from main import main, VERSION

class TestMain(unittest.TestCase):
    @staticmethod
    def call(argv):
        host = Host()
        host.stdout = StringIO()
        host.stderr = StringIO()
        actual_returncode = main(host, argv)
        out = host.stdout.getvalue()
        err = host.stderr.getvalue()
        return actual_returncode, out, err

    def check(self, argv, returncode, out_regex, err_regex):
        actual_returncode, out, err = self.call(argv)
        if returncode is not None:
            self.assertEqual(actual_returncode, returncode)
        self.assertTrue(re.match(out_regex, out, re.MULTILINE),
                        '%s does not match %s' % (out_regex, out))
        self.assertTrue(re.match(err_regex, err, re.MULTILINE),
                        '%s does not match %s' % (err_regex, err))

    def test_bad_arg(self):
        self.check(['--bad-arg'], 2, '', '')

    def test_bad_dir(self):
        self.check(['-C', 'missing_dir'], 2, '', '"missing_dir" not found\n')

    def test_bad_file(self):
        self.check(['-f', 'missing_build.ninja'], 2, '',
                   '"missing_build.ninja" not found\n')

    def test_bad_tool(self):
        self.check(['-t', 'foo'], 2, '', 'unsupported tool "foo"\n')

    def test_list(self):
        self.check(['-t', 'list'], 0, '.+', '')

    def test_chdir(self):
        self.check(['-n', '-C', '.'], 0, '', '.*')

    def test_check(self):
        self.check(['-t', 'check'], 0, '', '.*')

    def test_clean(self):
        self.check(['-n', '-t', 'clean'], 0, '', '.*')

    def test_question(self):
        # pass returncode=None here because the result may vary.
        self.check(['-t', 'question'], None, '', '.*')

    def test_debug(self):
        self.check(['-d', 'foo'], 2, '', '-d is not supported yet\n')

    def test_dry_run(self):
        self.check(['-n'], 0, '.+', '')

    def test_usage(self):
        self.check(['--help'], 0, 'usage:.+', '')
        self.check(['-h'], 0, 'usage:.+', '')

    def test_version(self):
        self.check(['--version'], 0, VERSION + '\n', '')

if __name__ == '__main__':
    unittest.main()
<commit_msg>add end-to-end test to main_test<commit_after>import re
import textwrap
import unittest

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from host import Host
from host_fake import FakeHost
from main import main, VERSION

class TestArgs(unittest.TestCase):
    @staticmethod
    def call(argv):
        host = Host()
        host.stdout = StringIO()
        host.stderr = StringIO()
        actual_returncode = main(host, argv)
        out = host.stdout.getvalue()
        err = host.stderr.getvalue()
        return actual_returncode, out, err

    def check(self, argv, returncode, out_regex, err_regex):
        actual_returncode, out, err = self.call(argv)
        if returncode is not None:
            self.assertEqual(actual_returncode, returncode)
        self.assertTrue(re.match(out_regex, out, re.MULTILINE),
                        '%s does not match %s' % (out_regex, out))
        self.assertTrue(re.match(err_regex, err, re.MULTILINE),
                        '%s does not match %s' % (err_regex, err))

    def test_bad_arg(self):
        self.check(['--bad-arg'], 2, '', '')

    def test_bad_dir(self):
        self.check(['-C', 'missing_dir'], 2, '', '"missing_dir" not found\n')

    def test_bad_file(self):
        self.check(['-f', 'missing_build.ninja'], 2, '',
                   '"missing_build.ninja" not found\n')

    def test_bad_tool(self):
        self.check(['-t', 'foo'], 2, '', 'unsupported tool "foo"\n')

    def test_list(self):
        self.check(['-t', 'list'], 0, '.+', '')

    def test_chdir(self):
        self.check(['-n', '-C', '.'], 0, '', '.*')

    def test_check(self):
        self.check(['-t', 'check'], 0, '', '.*')

    def test_clean(self):
        self.check(['-n', '-t', 'clean'], 0, '', '.*')

    def test_question(self):
        # pass returncode=None here because the result may vary.
        self.check(['-t', 'question'], None, '', '.*')

    def test_debug(self):
        self.check(['-d', 'foo'], 2, '', '-d is not supported yet\n')

    def test_dry_run(self):
        self.check(['-n'], 0, '.+', '')

    def test_usage(self):
        self.check(['--help'], 0, 'usage:.+', '')
        self.check(['-h'], 0, 'usage:.+', '')

    def test_version(self):
        self.check(['--version'], 0, VERSION + '\n', '')

class EvalTest(unittest.TestCase):
    def files_to_ignore(self):
        # return ['.ninja_deps', '.ninja_log']
        return ['.pyn.db']

    def _call(self, files):
        host = FakeHost()

        def fake_call(arg_str):
            args = arg_str.split()
            if args[0] == 'echo' and args[2] == '>':
                host.write(host.join(host.cwd, args[3]), args[1] + '\n')
                return 0, '', ''
            return 1, '', ''

        host.call = fake_call

        try:
            orig_wd = host.getcwd()
            tmpdir = str(host.mkdtemp())
            host.chdir(tmpdir)
            for path, contents in list(files.items()):
                dirname = host.dirname(path)
                if dirname:
                    host.maybe_mkdir(dirname)
                host.write(path, contents)

            returncode = main(host, [])
            out_files = {}
            for f in host.files:
                if f.startswith(tmpdir):
                    out_files[f.replace(tmpdir + '/', '')] = host.files[f]
            return returncode, out_files
        finally:
            host.rmtree(tmpdir)
            host.chdir(orig_wd)

    def check(self, in_files, expected_out_files):
        returncode, actual_out_files = self._call(in_files)
        self.assertEqual(returncode, 0)
        for k, v in expected_out_files.items():
            self.assertEqual(expected_out_files[k], v)

        all_out_files = set(actual_out_files.keys()).difference(self.files_to_ignore())
        self.assertEqual(all_out_files, set(expected_out_files.keys()))

    def test_basic(self):
        in_files = {}
        in_files['build.ninja'] = textwrap.dedent("""
            rule echo_out
                command = echo $out > $out

            build foo : echo_out build.ninja

            default foo
            """)

        out_files = in_files.copy()
        out_files['foo'] = 'foo\n'
        self.check(in_files, out_files)

    def disabled_test_var_expansion(self):
        in_files = {}
        in_files['build.ninja'] = textwrap.dedent("""
            v = foo

            rule echo_out
                command = echo $out > $out

            build $v : echo_out build.ninja

            v = bar

            build $v : echo_out build.ninja
            """)

        out_files = in_files.copy()
        out_files['foo'] = 'foo\n'
        out_files['bar'] = 'bar\n'

        self.check(in_files, out_files)

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># Copyright (c) 2012 Ian C. Good
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

"""Module defining :class:`Envelope` for holding message data along with
metadata.

"""

from __future__ import absolute_import

import re
import copy
import cStringIO
from email.message import Message
from email.generator import Generator
from email.parser import Parser, FeedParser

__all__ = ['Envelope']

header_boundary = re.compile(r'\r?\n\r?\n')

class Envelope(object):
    """Class containing message data and metadata. This class acts like an
    envelope with the sending address, recipient(s), and the actual message.

    :param sender: The address that sent the message.
    :param recipients: List of addresses to receive the message.
    :param headers: The message headers.
    :type headers: :class:`email.message.Message`
    :param message: String containing the message contents after the headers.

    """

    def __init__(self, sender=None, recipients=None,
                 headers=None, message=None):
        #: Sending address of the message.
        self.sender = sender

        #: List of recipient addresses of the message.
        self.recipients = recipients or []

        #: :class:`email.message.Message` object for accessing and modifying
        #: message headers.
        self.headers = headers

        #: String of message data, not including headers.
        self.message = message

        #: Dictionary of information about the client that sent the message.
        #: Utilized keys include:
        #:
        #: - ``ip``: The IP of the client.
        #: - ``host``: The reverse-lookup of the client IP.
        #: - ``name``: The client name, as given by its ``EHLO`` or
        #:             alternative.
        #: - ``protocol``: The protocol used by the client, generally a variant
        #:                 of ``"SMTP"``.
        #: - ``auth``: The name the client successfully authenticated with, or
        #:             ``None``.
        self.client = {}

        #: Hostname of the :mod:`slimta` server that received the message.
        self.receiver = None

        #: Timestamp when the message was received.
        self.timestamp = None

    def copy(self):
        """Builds and returns an exact copy if the current object. This method
        uses a deep-copying so internal datastructures are not shared.

        :returns: An exact, deep copy of the current object.

        """
        return copy.deepcopy(self)

    def flatten(self):
        """Produces two strings representing the headers and message body.

        :returns: Tuple of two strings: ``(header_data, message_data)``

        """
        outfp = cStringIO.StringIO()
        Generator(outfp).flatten(self.headers, False)
        header_data = outfp.getvalue().replace('\r', '').replace('\n', '\r\n')
        return header_data, self.message

    def _encode_parts(self, header_data, msg_data, encoder):
        parser = FeedParser()
        parser.feed(header_data)
        parser.feed(msg_data)
        msg = parser.close()

        for part in msg.walk():
            if not part.is_multipart():
                payload = part.get_payload()
                try:
                    payload.encode('ascii')
                except UnicodeDecodeError:
                    del part['Content-Transfer-Encoding']
                    encoder(part)

        self.parse(msg)

    def encode_7bit(self, encoder=None):
        """Forces the message into 7-bit encoding such that it can be sent to
        SMTP servers that do not support the ``8BITMIME`` extension.

        If the ``encoder`` function is not given, this function is relatively
        cheap and will just check the message body for 8-bit characters
        (raising :py:exc:`UnicodeDecodeError` if any are found).  Otherwise,
        this method can be very expensive. It will parse the entire message
        into MIME parts in order to encode parts that are not 7-bit.

        :param encoder: Optional function from :mod:`email.encoders` used to
                        encode MIME parts that are not 7-bit.
        :raises: UnicodeDecodeError

        """
        header_data, msg_data = self.flatten()
        try:
            msg_data.encode('ascii')
        except UnicodeDecodeError:
            if not encoder:
                raise
            self._encode_parts(header_data, msg_data, encoder)

    def parse(self, data):
        """Parses the given string or :class:`~email.message.Message` to
        populate the :attr:`headers` and :attr:`message` attributes.

        :param data: The complete message, headers and message body.
        :type data: :py:obj:`str` or :class:`~email.message.Message`

        """
        if isinstance(data, Message):
            outfp = cStringIO.StringIO()
            Generator(outfp).flatten(data, False)
            data = outfp.getvalue()
        match = header_boundary.search(data)
        if not match:
            header_data = data
            payload = ''
        else:
            header_data = data[:match.end(0)]
            payload = data[match.end(0):]
        headers = Parser().parsestr(header_data, True)
        self.headers = headers
        self.message = payload

    def __repr__(self):
        template = '<Envelope at {0}, sender={sender!r}>'
        return template.format(hex(id(self)), **vars(self))

# vim:et:fdm=marker:sts=4:sw=4:ts=4
<commit_msg>cleanup and optimization<commit_after># Copyright (c) 2012 Ian C. Good
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

"""Module defining :class:`Envelope` for holding message data along with
metadata.

"""

from __future__ import absolute_import

import re
import copy
import cStringIO
from email.message import Message
from email.generator import Generator
from email.parser import Parser, FeedParser

__all__ = ['Envelope']

_HEADER_BOUNDARY = re.compile(r'\r?\n\r?\n')
_LINE_BREAK = re.compile(r'\r?\n')

class Envelope(object):
    """Class containing message data and metadata. This class acts like an
    envelope with the sending address, recipient(s), and the actual message.

    :param sender: The address that sent the message.
    :param recipients: List of addresses to receive the message.
    :param headers: The message headers.
    :type headers: :class:`email.message.Message`
    :param message: String containing the message contents after the headers.

    """

    def __init__(self, sender=None, recipients=None,
                 headers=None, message=None):
        #: Sending address of the message.
        self.sender = sender

        #: List of recipient addresses of the message.
        self.recipients = recipients or []

        #: :class:`email.message.Message` object for accessing and modifying
        #: message headers.
        self.headers = headers

        #: String of message data, not including headers.
        self.message = message

        #: Dictionary of information about the client that sent the message.
        #: Utilized keys include:
        #:
        #: - ``ip``: The IP of the client.
        #: - ``host``: The reverse-lookup of the client IP.
        #: - ``name``: The client name, as given by its ``EHLO`` or
        #:             alternative.
        #: - ``protocol``: The protocol used by the client, generally a variant
        #:                 of ``"SMTP"``.
        #: - ``auth``: The name the client successfully authenticated with, or
        #:             ``None``.
        self.client = {}

        #: Hostname of the :mod:`slimta` server that received the message.
        self.receiver = None

        #: Timestamp when the message was received.
        self.timestamp = None

    def copy(self):
        """Builds and returns an exact copy if the current object. This method
        uses a deep-copying so internal datastructures are not shared.

        :returns: An exact, deep copy of the current object.

        """
        return copy.deepcopy(self)

    def flatten(self):
        """Produces two strings representing the headers and message body.

        :returns: Tuple of two strings: ``(header_data, message_data)``

        """
        outfp = cStringIO.StringIO()
        Generator(outfp).flatten(self.headers, False)
        header_data = re.sub(_LINE_BREAK, '\r\n', outfp.getvalue())
        return header_data, self.message

    def _encode_parts(self, header_data, msg_data, encoder):
        """Encodes any MIME part in the current message that is 8-bit."""
        self.headers = None
        self.message = None

        parser = FeedParser()
        parser.feed(header_data)
        parser.feed(msg_data)
        msg = parser.close()

        for part in msg.walk():
            if not part.is_multipart():
                payload = part.get_payload()
                try:
                    payload.encode('ascii')
                except UnicodeDecodeError:
                    del part['Content-Transfer-Encoding']
                    encoder(part)

        self.parse(msg)

    def encode_7bit(self, encoder=None):
        """Forces the message into 7-bit encoding such that it can be sent to
        SMTP servers that do not support the ``8BITMIME`` extension.

        If the ``encoder`` function is not given, this function is relatively
        cheap and will just check the message body for 8-bit characters
        (raising :py:exc:`UnicodeDecodeError` if any are found).  Otherwise,
        this method can be very expensive. It will parse the entire message
        into MIME parts in order to encode parts that are not 7-bit.

        :param encoder: Optional function from :mod:`email.encoders` used to
                        encode MIME parts that are not 7-bit.
        :raises: UnicodeDecodeError

        """
        header_data, msg_data = self.flatten()
        try:
            msg_data.encode('ascii')
        except UnicodeDecodeError:
            if not encoder:
                raise
            self._encode_parts(header_data, msg_data, encoder)

    def parse(self, data):
        """Parses the given string or :class:`~email.message.Message` to
        populate the :attr:`headers` and :attr:`message` attributes.

        :param data: The complete message, headers and message body.
        :type data: :py:obj:`str` or :class:`~email.message.Message`

        """
        if isinstance(data, Message):
            outfp = cStringIO.StringIO()
            Generator(outfp).flatten(data, False)
            data = outfp.getvalue()
        match = re.search(_HEADER_BOUNDARY, data)
        if not match:
            header_data = data
            payload = ''
        else:
            header_data = data[:match.end(0)]
            payload = data[match.end(0):]
        headers = Parser().parsestr(header_data, True)
        self.headers = headers
        self.message = payload

    def __repr__(self):
        template = '<Envelope at {0}, sender={1!r}>'
        return template.format(hex(id(self)), self.sender)

# vim:et:fdm=marker:sts=4:sw=4:ts=4
<|endoftext|>