<commit_before>#-*- coding: UTF-8 -*-

# The MIT License (MIT)
#
# Copyright (c) 2014 Mack Stone
#
# 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.

# How to use it
# open script editor and run
#
# import cmdReporterHighlighter as crHighlighter
# crHighlighter.highlightCmdReporter()

import sys
import os
import keyword

from PySide import QtGui, QtCore
from maya import cmds

def getMayaWindowWidget():
	'''get maya window widget for Qt'''
	mwin = None
	mapp = QtGui.QApplication.instance()
	for widget in mapp.topLevelWidgets():
		if widget.objectName() == 'MayaWindow':
			mwin = widget
			break
	return mwin

def highlightCmdReporter():
	'''find cmdScrollFieldReporter and highlight it'''
	mwin = getMayaWindowWidget()
	cmdReporters = cmds.lsUI(type='cmdScrollFieldReporter')
	if not cmdReporters: return
	# only setup for the first one
	cmdReporter = mwin.findChild(QtGui.QTextEdit, cmdReporters[0])
	highlighter = Highlighter(parent=mwin)
	highlighter.setDocument(cmdReporter.document())

class Highlighter(QtGui.QSyntaxHighlighter):
	"""syntax highlighter"""
	def __init__(self, parent=None):
		super(Highlighter, self).__init__(parent)

		self.__rules = []

		# keywords color
		self._keywordColor = QtGui.QColor(0, 128, 255)

		self._keywordFormat()
		# too slow need disable it
		#self._cmdsFunctionFormat()

		# maya api format
		mapiFormat = QtGui.QTextCharFormat()
		mapiFormat.setForeground(self._keywordColor)
		self.__rules.append(('\\bM\\w+\\b', mapiFormat))
		# Qt
		self.__rules.append(('\\bQ\\w+\\b', mapiFormat))

		# sing line comment
		self._commentFormat = QtGui.QTextCharFormat()
		# orange red
		self._commentFormat.setForeground(QtGui.QColor(255, 128, 64))
		# // mel comment
		self.__rules.append(('//[^\n]*', self._commentFormat))
		# # python comment
		self.__rules.append(('#[^\n]*', self._commentFormat))

		# quotation
		self._quotationFormat = QtGui.QTextCharFormat()
		self._quotationFormat.setForeground(QtCore.Qt.green)
		# quote: ""
		self.__rules.append(('".*"', self._quotationFormat))
		# single quotes for python: ''
		self.__rules.append(("'.*'", self._quotationFormat))

		# function and class format
		funcFormat = QtGui.QTextCharFormat()
		funcFormat.setFontWeight(QtGui.QFont.Bold)
		self.__rules.append(('\\b(\\w+)\(.*\):', funcFormat))

		# mel warning
		warningFormat = QtGui.QTextCharFormat()
		warningFormat.setForeground(QtGui.QColor('#FF9ACD32'))
		warningFormat.setBackground(QtCore.Qt.yellow)
		warningFormat.setFontWeight(QtGui.QFont.Bold)
		self.__rules.append(('// Warning:[^\n]*//', warningFormat))

		# mel error
		errorFormat = QtGui.QTextCharFormat()
		errorFormat.setForeground(QtGui.QColor('#FF9ACD32'))
		errorFormat.setBackground(QtCore.Qt.red)
		errorFormat.setFontWeight(QtGui.QFont.Bold)
		self.__rules.append(('// Error:[^\n]*//', errorFormat))

		# blocks: start : end
		self._blockRegexp = {
							# mel multi-line comment: /*  */
							'/\\*' : ('\\*/', self._commentFormat),
							# python  multi-line string: """   """
							'"""\\*' : ('\\*"""', self._quotationFormat),
							# python  multi-line string: '''   '''
							"'''\\*" : ("\\*'''", self._quotationFormat),
							}

	def _keywordFormat(self):
		'''set up keyword format'''
		# mel keyword
		melKeywords = ['false', 'float', 'int', 'matrix', 'off', 'on', 'string',
					'true', 'vector', 'yes', 'alias', 'case', 'catch', 'break',
					'case', 'continue', 'default', 'do', 'else', 'for', 'if', 'in',
					'while', 'alias', 'case', 'catch', 'global', 'proc', 'return', 'source', 'switch']
		# python keyword
		pyKeywords = keyword.kwlist + ['False', 'True', 'None']

		keywords = {}.fromkeys(melKeywords)
		keywords.update({}.fromkeys(pyKeywords))
		# keyword format
		keywordFormat = QtGui.QTextCharFormat()
		keywordFormat.setForeground(self._keywordColor)
		keywordFormat.setFontWeight(QtGui.QFont.Bold)
		self.__rules += [('\\b%s\\b' % word, keywordFormat) for
						word in keywords]

	def _cmdsFunctionFormat(self):
		'''set up maya.cmds functions'''
		mayaBinDir = os.path.dirname(sys.executable)
		cmdsList = os.path.join(mayaBinDir, 'commandList')
		functions = []
		with open(cmdsList) as phile:
			[functions.append(line.split(' ')[0]) for line in phile]

		# global MEL procedures
		functions += cmds.melInfo()

		# TODO: should update it when a plug-in was load.
		# function from plug-ins
		plugins = cmds.pluginInfo(q=1, listPlugins=1)
		for plugin in plugins:
			funcFromPlugin = cmds.pluginInfo(plugin, q=1, command=1)
			if funcFromPlugin:
				functions.extend(funcFromPlugin)

		# function format
		funcFormat = QtGui.QTextCharFormat()
		funcFormat.setForeground(self._keywordColor)
		self.__rules += [('\\b%s\\b' % func, funcFormat) for
						func in functions]

	def highlightBlock(self, text):
		'''highlight text'''
		for pattern, tformat in self.__rules:
			regExp = QtCore.QRegExp(pattern)
			index = regExp.indexIn(text)
			while index >= 0:
				length = regExp.matchedLength()
				self.setFormat(index, length, tformat)
				index = regExp.indexIn(text, index + length)

		# blocks
		textLength = len(text)
		blockIndex = 1
		for startBlock in self._blockRegexp:
			startIndex = 0
			startRegExp = QtCore.QRegExp(startBlock)
			endRegExp = QtCore.QRegExp(self._blockRegexp[startBlock][0])
			if self.previousBlockState() != blockIndex:
				startIndex = startRegExp.indexIn(text)

			while startIndex >= 0:
				endIndex = endRegExp.indexIn(text, startIndex)
				if endIndex == -1:
					self.setCurrentBlockState(blockIndex)
					blockLength = textLength - startIndex
				else:
					blockLength = endIndex - startIndex + endRegExp.matchedLength()

				self.setFormat(startIndex, blockLength, self._blockRegexp[startBlock][1])
				startIndex = startRegExp.indexIn(text, startIndex + blockLength)
			blockIndex += 1
<commit_msg>conver tabs to spaces<commit_after># -*- coding: UTF-8 -*-

# The MIT License (MIT)
#
# Copyright (c) 2014 Mack Stone
#
# 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.

# How to use it
# open script editor and run
#
# import cmdReporterHighlighter as crHighlighter
# crHighlighter.highlightCmdReporter()

import sys
import os
import keyword

from PySide import QtGui, QtCore
from maya import cmds

def getMayaWindowWidget():
    '''get maya window widget for Qt'''
    mwin = None
    mapp = QtGui.QApplication.instance()
    for widget in mapp.topLevelWidgets():
        if widget.objectName() == 'MayaWindow':
            mwin = widget
            break
    return mwin

def highlightCmdReporter():
    '''find cmdScrollFieldReporter and highlight it'''
    mwin = getMayaWindowWidget()
    cmdReporters = cmds.lsUI(type='cmdScrollFieldReporter')
    if not cmdReporters: return
    # only setup for the first one
    cmdReporter = mwin.findChild(QtGui.QTextEdit, cmdReporters[0])
    highlighter = Highlighter(parent=mwin)
    highlighter.setDocument(cmdReporter.document())

class Highlighter(QtGui.QSyntaxHighlighter):
    """syntax highlighter"""
    def __init__(self, parent=None):
        super(Highlighter, self).__init__(parent)

        self.__rules = []

        # keywords color
        self._keywordColor = QtGui.QColor(0, 128, 255)

        self._keywordFormat()
        # too slow need disable it
        # self._cmdsFunctionFormat()

        # maya api format
        mapiFormat = QtGui.QTextCharFormat()
        mapiFormat.setForeground(self._keywordColor)
        self.__rules.append(('\\bM\\w+\\b', mapiFormat))
        # Qt
        self.__rules.append(('\\bQ\\w+\\b', mapiFormat))

        # sing line comment
        self._commentFormat = QtGui.QTextCharFormat()
        # orange red
        self._commentFormat.setForeground(QtGui.QColor(255, 128, 64))
        # // mel comment
        self.__rules.append(('//[^\n]*', self._commentFormat))
        # # python comment
        self.__rules.append(('#[^\n]*', self._commentFormat))

        # quotation
        self._quotationFormat = QtGui.QTextCharFormat()
        self._quotationFormat.setForeground(QtCore.Qt.green)
        # quote: ""
        self.__rules.append(('".*"', self._quotationFormat))
        # single quotes for python: ''
        self.__rules.append(("'.*'", self._quotationFormat))

        # function and class format
        funcFormat = QtGui.QTextCharFormat()
        funcFormat.setFontWeight(QtGui.QFont.Bold)
        self.__rules.append(('\\b(\\w+)\(.*\):', funcFormat))

        # mel warning
        warningFormat = QtGui.QTextCharFormat()
        warningFormat.setForeground(QtGui.QColor('#FF9ACD32'))
        warningFormat.setBackground(QtCore.Qt.yellow)
        warningFormat.setFontWeight(QtGui.QFont.Bold)
        self.__rules.append(('// Warning:[^\n]*//', warningFormat))

        # mel error
        errorFormat = QtGui.QTextCharFormat()
        errorFormat.setForeground(QtGui.QColor('#FF9ACD32'))
        errorFormat.setBackground(QtCore.Qt.red)
        errorFormat.setFontWeight(QtGui.QFont.Bold)
        self.__rules.append(('// Error:[^\n]*//', errorFormat))

        # blocks: start : end
        self._blockRegexp = {
                            # mel multi-line comment: /*  */
                            '/\\*' : ('\\*/', self._commentFormat),
                            # python  multi-line string: """   """
                            '"""\\*' : ('\\*"""', self._quotationFormat),
                            # python  multi-line string: '''   '''
                            "'''\\*" : ("\\*'''", self._quotationFormat),
                            }

    def _keywordFormat(self):
        '''set up keyword format'''
        # mel keyword
        melKeywords = ['false', 'float', 'int', 'matrix', 'off', 'on', 'string',
                    'true', 'vector', 'yes', 'alias', 'case', 'catch', 'break',
                    'case', 'continue', 'default', 'do', 'else', 'for', 'if', 'in',
                    'while', 'alias', 'case', 'catch', 'global', 'proc', 'return', 'source', 'switch']
        # python keyword
        pyKeywords = keyword.kwlist + ['False', 'True', 'None']

        keywords = {}.fromkeys(melKeywords)
        keywords.update({}.fromkeys(pyKeywords))
        # keyword format
        keywordFormat = QtGui.QTextCharFormat()
        keywordFormat.setForeground(self._keywordColor)
        keywordFormat.setFontWeight(QtGui.QFont.Bold)
        self.__rules += [('\\b%s\\b' % word, keywordFormat) for
                        word in keywords]

    def _cmdsFunctionFormat(self):
        '''set up maya.cmds functions'''
        mayaBinDir = os.path.dirname(sys.executable)
        cmdsList = os.path.join(mayaBinDir, 'commandList')
        functions = []
        with open(cmdsList) as phile:
            [functions.append(line.split(' ')[0]) for line in phile]

        # global MEL procedures
        functions += cmds.melInfo()

        # TODO: should update it when a plug-in was load.
        # function from plug-ins
        plugins = cmds.pluginInfo(q=1, listPlugins=1)
        for plugin in plugins:
            funcFromPlugin = cmds.pluginInfo(plugin, q=1, command=1)
            if funcFromPlugin:
                functions.extend(funcFromPlugin)

        # function format
        funcFormat = QtGui.QTextCharFormat()
        funcFormat.setForeground(self._keywordColor)
        self.__rules += [('\\b%s\\b' % func, funcFormat) for
                        func in functions]

    def highlightBlock(self, text):
        '''highlight text'''
        for pattern, tformat in self.__rules:
            regExp = QtCore.QRegExp(pattern)
            index = regExp.indexIn(text)
            while index >= 0:
                length = regExp.matchedLength()
                self.setFormat(index, length, tformat)
                index = regExp.indexIn(text, index + length)

        # blocks
        textLength = len(text)
        blockIndex = 1
        for startBlock in self._blockRegexp:
            startIndex = 0
            startRegExp = QtCore.QRegExp(startBlock)
            endRegExp = QtCore.QRegExp(self._blockRegexp[startBlock][0])
            if self.previousBlockState() != blockIndex:
                startIndex = startRegExp.indexIn(text)

            while startIndex >= 0:
                endIndex = endRegExp.indexIn(text, startIndex)
                if endIndex == -1:
                    self.setCurrentBlockState(blockIndex)
                    blockLength = textLength - startIndex
                else:
                    blockLength = endIndex - startIndex + endRegExp.matchedLength()

                self.setFormat(startIndex, blockLength, self._blockRegexp[startBlock][1])
                startIndex = startRegExp.indexIn(text, startIndex + blockLength)
            blockIndex += 1
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Mon Aug 31 10:17:09 2015

@author: mje
"""
import mne
from mne.minimum_norm import (apply_inverse_epochs, read_inverse_operator)
from mne.time_frequency import morlet
import numpy as np
import sys

from my_settings import *

subject = sys.argv[1]

# Using the same inverse operator when inspecting single trials Vs. evoked
snr = 1.0  # Standard assumption for average data but using it for single trial
lambda2 = 1.0 / snr**2
method = "dSPM"  # use dSPM method (could also be MNE or sLORETA)
freqs = np.arange(8, 13, 1)
n_cycle = freqs / 3.

conditions = ["ent/left", "ctl/left", "ent/right", "ctl/right"]

# Load data
labels = mne.read_labels_from_annot(
    subject, parc='PALS_B12_Brodmann', regexp="Bro", subjects_dir=subjects_dir)
labels_sel = [labels[6], labels[7]]

inverse_operator = read_inverse_operator(mne_folder + "%s-inv.fif" % subject)
src = mne.read_source_spaces(subjects_dir + "%s/bem/%s-oct-6-src.fif" % (
    subject, subject))
epochs = mne.read_epochs(epochs_folder + "%s_trial_start-epo.fif" % subject)
# epochs.drop_bad_epochs(reject_params)
# epochs.resample(250, n_jobs=4)

for condition in conditions[:1]:
    stcs = apply_inverse_epochs(
        epochs[condition],
        inverse_operator,
        lambda2,
        method,
        pick_ori="normal")

    for label in labels_sel:
        label_ts = []
        for j in range(len(stcs[:1])):
            ts = mne.extract_label_time_course(
                stcs[j], labels=label, src=src, mode="pca_flip")
            ts = np.squeeze(ts)
            ts *= np.sign(ts[np.argmax(np.abs(ts))])
            label_ts.append(ts)

        label_ts = np.asarray(label_ts)
        tfr = morlet(
            label_ts,
            epochs.info["sfreq"],
            freqs,
            # use_fft=True,
            n_cycles=n_cycle)

        np.save(tf_folder + "%s_%s_%s_%s_%s-tfr" %
                (subject, condition[:3], condition[4:], label.name, method),
                tfr)
        np.save(tf_folder + "%s_%s_%s_%s_%s-ts" %
                (subject, condition[:3], condition[4:], label.name, method),
                label_ts)

    del stcs
    del tfr
<commit_msg>updates PEP8, save name<commit_after># -*- coding: utf-8 -*-
"""
Created on Mon Aug 31 10:17:09 2015

@author: mje
"""
import mne
from mne.minimum_norm import (apply_inverse_epochs, read_inverse_operator)
from mne.time_frequency import morlet
import numpy as np
import sys

from my_settings import (tf_folder, subjects_dir, epochs_folder, mne_folder)

subject = sys.argv[1]

# Using the same inverse operator when inspecting single trials Vs. evoked
snr = 1.0  # Standard assumption for average data but using it for single trial
lambda2 = 1.0 / snr**2
method = "dSPM"  # use dSPM method (could also be MNE or sLORETA)
freqs = np.arange(8, 13, 1)
n_cycle = 4.  # freqs / 3.

conditions = ["ent/left", "ctl/left", "ent/right", "ctl/right"]

# Load data
labels = mne.read_labels_from_annot(
    subject, parc='PALS_B12_Brodmann', regexp="Bro", subjects_dir=subjects_dir)
labels_sel = [labels[6], labels[7]]

inverse_operator = read_inverse_operator(mne_folder + "%s-inv.fif" % subject)
src = mne.read_source_spaces(subjects_dir + "%s/bem/%s-oct-6-src.fif" % (
    subject, subject))
epochs = mne.read_epochs(epochs_folder + "%s_trial_start-epo.fif" % subject)
# epochs.drop_bad_epochs(reject_params)
# epochs.resample(250, n_jobs=4)

for condition in conditions[:1]:
    stcs = apply_inverse_epochs(
        epochs[condition],
        inverse_operator,
        lambda2,
        method,
        pick_ori="normal")

    for label in labels_sel:
        label_ts = []
        for j in range(len(stcs[:1])):
            ts = mne.extract_label_time_course(
                stcs[j], labels=label, src=src, mode="pca_flip")
            ts = np.squeeze(ts)
            ts *= np.sign(ts[np.argmax(np.abs(ts))])
            label_ts.append(ts)

        label_ts = np.asarray(label_ts)
        tfr = morlet(
            label_ts,
            epochs.info["sfreq"],
            freqs,
            # use_fft=True,
            n_cycles=n_cycle)

        np.save(tf_folder + "%s_%s_%s_%s_%s_pca-tfr" %
                (subject, condition[:3], condition[4:], label.name, method),
                tfr)
        np.save(tf_folder + "%s_%s_%s_%s_%s_pca-ts" %
                (subject, condition[:3], condition[4:], label.name, method),
                label_ts)

    del stcs
    del tfr
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from django import forms
from django.core.exceptions import ImproperlyConfigured
from django.forms.models import ModelForm
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _

from cms.api import create_page
from cms.constants import TEMPLATE_INHERITANCE_MAGIC
from cms.models import Page, UserSettings
from cms.test_utils.testcases import CMSTestCase, TransactionCMSTestCase
from cms.wizards.wizard_base import Wizard
from cms.wizards.wizard_pool import wizard_pool, AlreadyRegisteredException

class WizardForm(forms.Form):
    pass

class ModelWizardForm(ModelForm):
    class Meta:
        model = UserSettings
        exclude = []

class BadModelForm(ModelForm):
    class Meta:
        pass

class WizardTestMixin(object):
    page_wizard = None
    title_wizard = None

    def assertSequencesEqual(self, seq_a, seq_b):
        seq_a = list(seq_a)
        seq_b = list(seq_b)
        zipped = list(zip(seq_a, seq_b))
        if len(zipped) < len(seq_a) or len(zipped) < len(seq_b):
            self.fail("Sequence lengths are not the same.")
        for idx, (a, b) in enumerate(zipped):
            if a != b:
                self.fail("Sequences differ at index {0}".format(idx))

    @classmethod
    def setUpClass(cls):
        super(WizardTestMixin, cls).setUpClass()
        # This prevents auto-discovery, which would otherwise occur as soon as
        # tests start, creating unexpected starting conditions.
        wizard_pool._discovered = True

        class PageWizard(Wizard):
            pass

        # This is a basic Wizard
        cls.page_wizard = PageWizard(
            title=_(u"Page"),
            weight=100,
            form=WizardForm,
            model=Page,
            template_name='my_template.html',  # This doesn't exist anywhere
        )

        class SettingsWizard(Wizard):
            pass

        # This is a Wizard that uses a ModelForm to define the model
        cls.user_settings_wizard = SettingsWizard(
            title=_(u"UserSettings"),
            weight=200,
            form=ModelWizardForm,
        )

        class TitleWizard(Wizard):
            pass

        # This is a bad wizard definition as it neither defines a model, nor
        # uses a ModelForm that has model defined in Meta
        cls.title_wizard = TitleWizard(
            title=_(u"Page"),
            weight=100,
            form=BadModelForm,
            template_name='my_template.html',  # This doesn't exist anywhere
        )

class TestWizardBase(WizardTestMixin, TransactionCMSTestCase):

    def test_str(self):
        self.assertEqual(str(self.page_wizard), self.page_wizard.title)

    def test_repr(self):
        self.assertEqual(self.page_wizard.__repr__(), 'Wizard: "Page"')

    def test_user_has_add_permission(self):
        # Test does not have permission
        user = self.get_staff_user_with_no_permissions()
        self.assertFalse(self.page_wizard.user_has_add_permission(user))

        # Test has permission
        user = self.get_superuser()
        self.assertTrue(self.page_wizard.user_has_add_permission(user))

    def test_get_success_url(self):
        user = self.get_superuser()
        page = create_page(
            title="Sample Page",
            template=TEMPLATE_INHERITANCE_MAGIC,
            language="en",
            created_by=smart_text(user),
            parent=None,
            in_navigation=True,
            published=False
        )
        url = page.get_absolute_url(language="en")
        self.assertEqual(self.page_wizard.get_success_url(
            page, language="en"), "{0}?edit=".format(url))

        # Now again without a language code
        url = page.get_absolute_url()
        self.assertEqual(self.page_wizard.get_success_url(page), url)

    def test_get_model(self):
        self.assertEqual(self.page_wizard.get_model(), Page)
        self.assertEqual(self.user_settings_wizard.get_model(), UserSettings)
        with self.assertRaises(ImproperlyConfigured):
            self.title_wizard.get_model()

class TestWizardPool(WizardTestMixin, CMSTestCase):

    def test_discover(self):
        wizard_pool._reset()
        self.assertFalse(wizard_pool._discovered)
        self.assertEqual(len(wizard_pool._entries), 0)
        wizard_pool._discover()
        self.assertTrue(wizard_pool._discovered)

    def test_register_unregister_isregistered(self):
        wizard_pool._clear()
        self.assertEqual(len(wizard_pool._entries), 0)
        wizard_pool.register(self.page_wizard)
        # Now, try to register the same thing
        with self.assertRaises(AlreadyRegisteredException):
            wizard_pool.register(self.page_wizard)

        self.assertEqual(len(wizard_pool._entries), 1)
        self.assertTrue(wizard_pool.is_registered(self.page_wizard))
        self.assertTrue(wizard_pool.unregister(self.page_wizard))
        self.assertEqual(len(wizard_pool._entries), 0)

        # Now, try to unregister something that is not registered
        self.assertFalse(wizard_pool.unregister(self.user_settings_wizard))

    def test_get_entry(self):
        wizard_pool._clear()
        wizard_pool.register(self.page_wizard)
        entry = wizard_pool.get_entry(self.page_wizard)
        self.assertEqual(entry, self.page_wizard)

    def test_get_entries(self):
        """
        Test that the registered entries are returned in weight-order, no matter
        which order they were added.
        """
        wizard_pool._clear()
        wizard_pool.register(self.page_wizard)
        wizard_pool.register(self.user_settings_wizard)
        wizards = [self.page_wizard, self.user_settings_wizard]
        wizards = sorted(wizards, key=lambda e: getattr(e, 'weight'))
        entries = wizard_pool.get_entries()
        self.assertSequencesEqual(entries, wizards)

        wizard_pool._clear()
        wizard_pool.register(self.user_settings_wizard)
        wizard_pool.register(self.page_wizard)
        wizards = [self.page_wizard, self.user_settings_wizard]
        wizards = sorted(wizards, key=lambda e: getattr(e, 'weight'))
        entries = wizard_pool.get_entries()
        self.assertSequencesEqual(entries, wizards)
<commit_msg>Another test-fix<commit_after># -*- coding: utf-8 -*-

from django import forms
from django.core.exceptions import ImproperlyConfigured
from django.forms.models import ModelForm
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _

from cms.api import create_page
from cms.constants import TEMPLATE_INHERITANCE_MAGIC
from cms.models import Page, UserSettings
from cms.test_utils.testcases import CMSTestCase, TransactionCMSTestCase
from cms.wizards.wizard_base import Wizard
from cms.wizards.wizard_pool import wizard_pool, AlreadyRegisteredException

class WizardForm(forms.Form):
    pass

class ModelWizardForm(ModelForm):
    class Meta:
        model = UserSettings
        exclude = []

class BadModelForm(ModelForm):
    class Meta:
        pass

class WizardTestMixin(object):
    page_wizard = None
    title_wizard = None

    def assertSequencesEqual(self, seq_a, seq_b):
        seq_a = list(seq_a)
        seq_b = list(seq_b)
        zipped = list(zip(seq_a, seq_b))
        if len(zipped) < len(seq_a) or len(zipped) < len(seq_b):
            self.fail("Sequence lengths are not the same.")
        for idx, (a, b) in enumerate(zipped):
            if a != b:
                self.fail("Sequences differ at index {0}".format(idx))

    @classmethod
    def setUpClass(cls):
        super(WizardTestMixin, cls).setUpClass()
        # This prevents auto-discovery, which would otherwise occur as soon as
        # tests start, creating unexpected starting conditions.
        wizard_pool._discovered = True

        class PageWizard(Wizard):
            pass

        # This is a basic Wizard
        cls.page_wizard = PageWizard(
            title=_(u"Page"),
            weight=100,
            form=WizardForm,
            model=Page,
            template_name='my_template.html',  # This doesn't exist anywhere
        )

        class SettingsWizard(Wizard):
            pass

        # This is a Wizard that uses a ModelForm to define the model
        cls.user_settings_wizard = SettingsWizard(
            title=_(u"UserSettings"),
            weight=200,
            form=ModelWizardForm,
        )

        class TitleWizard(Wizard):
            pass

        # This is a bad wizard definition as it neither defines a model, nor
        # uses a ModelForm that has model defined in Meta
        cls.title_wizard = TitleWizard(
            title=_(u"Page"),
            weight=100,
            form=BadModelForm,
            template_name='my_template.html',  # This doesn't exist anywhere
        )

class TestWizardBase(WizardTestMixin, TransactionCMSTestCase):

    def test_str(self):
        self.assertEqual(str(self.page_wizard), self.page_wizard.title)

    def test_repr(self):
        self.assertEqual(self.page_wizard.__repr__(), 'Wizard: "Page"')

    def test_user_has_add_permission(self):
        # Test does not have permission
        user = self.get_staff_user_with_no_permissions()
        self.assertFalse(self.page_wizard.user_has_add_permission(user))

        # Test has permission
        user = self.get_superuser()
        self.assertTrue(self.page_wizard.user_has_add_permission(user))

    def test_get_success_url(self):
        user = self.get_superuser()
        page = create_page(
            title="Sample Page",
            template=TEMPLATE_INHERITANCE_MAGIC,
            language="en",
            created_by=smart_text(user),
            parent=None,
            in_navigation=True,
            published=False
        )
        url = "{0}?edit=".format(page.get_absolute_url(language="en"))
        self.assertEqual(self.page_wizard.get_success_url(
            page, language="en"), url)

        # Now again without a language code
        url = "{0}?edit=".format(page.get_absolute_url())
        self.assertEqual(self.page_wizard.get_success_url(page), url)

    def test_get_model(self):
        self.assertEqual(self.page_wizard.get_model(), Page)
        self.assertEqual(self.user_settings_wizard.get_model(), UserSettings)
        with self.assertRaises(ImproperlyConfigured):
            self.title_wizard.get_model()

class TestWizardPool(WizardTestMixin, CMSTestCase):

    def test_discover(self):
        wizard_pool._reset()
        self.assertFalse(wizard_pool._discovered)
        self.assertEqual(len(wizard_pool._entries), 0)
        wizard_pool._discover()
        self.assertTrue(wizard_pool._discovered)

    def test_register_unregister_isregistered(self):
        wizard_pool._clear()
        self.assertEqual(len(wizard_pool._entries), 0)
        wizard_pool.register(self.page_wizard)
        # Now, try to register the same thing
        with self.assertRaises(AlreadyRegisteredException):
            wizard_pool.register(self.page_wizard)

        self.assertEqual(len(wizard_pool._entries), 1)
        self.assertTrue(wizard_pool.is_registered(self.page_wizard))
        self.assertTrue(wizard_pool.unregister(self.page_wizard))
        self.assertEqual(len(wizard_pool._entries), 0)

        # Now, try to unregister something that is not registered
        self.assertFalse(wizard_pool.unregister(self.user_settings_wizard))

    def test_get_entry(self):
        wizard_pool._clear()
        wizard_pool.register(self.page_wizard)
        entry = wizard_pool.get_entry(self.page_wizard)
        self.assertEqual(entry, self.page_wizard)

    def test_get_entries(self):
        """
        Test that the registered entries are returned in weight-order, no matter
        which order they were added.
        """
        wizard_pool._clear()
        wizard_pool.register(self.page_wizard)
        wizard_pool.register(self.user_settings_wizard)
        wizards = [self.page_wizard, self.user_settings_wizard]
        wizards = sorted(wizards, key=lambda e: getattr(e, 'weight'))
        entries = wizard_pool.get_entries()
        self.assertSequencesEqual(entries, wizards)

        wizard_pool._clear()
        wizard_pool.register(self.user_settings_wizard)
        wizard_pool.register(self.page_wizard)
        wizards = [self.page_wizard, self.user_settings_wizard]
        wizards = sorted(wizards, key=lambda e: getattr(e, 'weight'))
        entries = wizard_pool.get_entries()
        self.assertSequencesEqual(entries, wizards)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# ###
# Copyright (c) 2013, Rice University
# This software is subject to the provisions of the GNU Affero General
# Public License version 3 (AGPLv3).
# See LICENCE.txt for details.
# ###
"""Conversion callables"""
import os
import logging
import subprocess
from io import FileIO

here = os.path.abspath(os.path.dirname(__file__))
OOCONVERT = os.path.join(here, 'helper-scripts', 'ooconvert.py')
logger = logging.getLogger('cnxtransforms')

class File(FileIO):
    """file stream"""
    filename = None
    basepath = None

    def __init__(self, *args, **kwargs):
        super(File, self).__init__(*args, **kwargs)
        self.filename = os.path.basename(self.name)
        self.basepath = os.path.abspath(os.path.dirname(self.name))

    def __repr__(self):
        return "<{} instance of '{}'>".format(self.__class__.__name__,
                                              self.filepath)

    @property
    def filepath(self):
        return os.path.join(self.basepath, self.filename)

def word_to_ooo(file, output=None, server_address=None, page_count_limit=0):
    """MS Word document to OpenOffice.org (OOo) document.

    :param file: An IO object to be converted.
    :type file: cnxtransforms.File
    :param output: An IO object to send the output.
    :type output: cnxtransforms.File
    :param server_address: Host and port of running *Office server
    :type server_address: string
    :param page_count_limit: ???
    :type page_count_limit: integer
    :returns: The output object used to write to output to.
    :rtype: cnxtransforms.File

    """
    # Sending *office the name of the imported word file (saved locally).
    command = [OOCONVERT, file.filepath]
    if server_address:
        command.extend(['--address', server_address])
    if page_count_limit:
        command.extend(['--pagecount', page_count_limit])
    logger.info("Invoking converter: {}".format(' '.join(command)))

    if output is None:
        output = File("{}.odt".format(file.filepath), 'w')

    # TODO Send the document as binary via the input pipe,
    #      like how the result is returned.
    proc = subprocess.Popen(command,
                            stdin=subprocess.PIPE,
                            stdout=output,
                            stderr=subprocess.PIPE,
                            )
    # TODO A timeout parameter was added to communicate in Python 3.3.
    #      ...communicate(timeout=seconds)
    junk, stderr = proc.communicate()
    del junk

    if proc.returncode != 0:
        # Check to see if the document was too big.
        if stderr.startswith('Error (<class uno.com.sun.star.uno.Exception'):
            # sniff X for:  Input document has X pages which exceeeds
            #   the page count limit of Y.
            if re.match('.*Input document has ', stderr):
                msg = stderr[re.match('.*Input document has ', stderr).end():]
                if len(msg) > 0:
                    actual_page_count = msg.split(' ')[0]
                    if actual_page_count != msg:

                        raise Exception("Input word document contains {} "
                            "pages which exceeds the page count limit of {}. "
                            "The way forward (and best practice) is to "
                            "divide your doccument into smaller chunks. For "
                            "reference, the page count of an average word "
                            "import is about 5 pages." \
                            .format(actual_page_count, page_count_limit))
            raise Exception("Unknown error, stderr:\n{}".format(stderr))
        else:
            raise Exception("Unknown error, stderr:\n{}".format(stderr))

    return output
<commit_msg>Slight import change and the use of the File object should be limited to user beginning and end point usage and internal usage when the process requires a file.<commit_after># -*- coding: utf-8 -*-
# ###
# Copyright (c) 2013, Rice University
# This software is subject to the provisions of the GNU Affero General
# Public License version 3 (AGPLv3).
# See LICENCE.txt for details.
# ###
"""Conversion callables"""
import os
import io
import logging
import subprocess

here = os.path.abspath(os.path.dirname(__file__))
OOCONVERT = os.path.join(here, 'helper-scripts', 'ooconvert.py')
logger = logging.getLogger('cnxtransforms')

class File(io.FileIO):
    """file stream"""
    filename = None
    basepath = None

    def __init__(self, *args, **kwargs):
        super(File, self).__init__(*args, **kwargs)
        self.filename = os.path.basename(self.name)
        self.basepath = os.path.abspath(os.path.dirname(self.name))

    def __repr__(self):
        return "<{} instance of '{}'>".format(self.__class__.__name__,
                                              self.filepath)

    @property
    def filepath(self):
        return os.path.join(self.basepath, self.filename)

def word_to_odt(input, output=None, server_address=None, page_count_limit=0):
    """MS Word document to OpenOffice.org (OOo) document.

    :param input: An IO object to be converted.
    :type input: cnxtransforms.File
    :param output: An IO object to send the output.
    :type output: io.BytesIO
    :param server_address: Host and port of running *Office server
    :type server_address: string
    :param page_count_limit: ???
    :type page_count_limit: integer
    :returns: The output object used to write to output to.
    :rtype: cnxtransforms.File

    """
    # Sending *office the name of the imported word file (saved
    #  locally).
    file = input
    command = [OOCONVERT, file.filepath]
    if server_address:
        command.extend(['--address', server_address])
    if page_count_limit:
        command.extend(['--pagecount', page_count_limit])
    logger.info("Invoking converter: {}".format(' '.join(command)))

    if output is None:
        output = io.BytesIO()

    # TODO Send the document as binary via the input pipe,
    #      like how the result is returned.
    #      We are prevented from doing this now, because the ooconvert
    #      script is setup to accept a file rather than stdin.
    proc = subprocess.Popen(command,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            )
    # TODO A timeout parameter was added to communicate in Python 3.3.
    #      ...communicate(timeout=seconds)
    stdout, stderr = proc.communicate(file.read())
    output.write(stdout)

    if proc.returncode != 0:
        # Check to see if the document was too big.
        if stderr.startswith('Error (<class uno.com.sun.star.uno.Exception'):
            # sniff X for:  Input document has X pages which exceeeds
            #   the page count limit of Y.
            if re.match('.*Input document has ', stderr):
                msg = stderr[re.match('.*Input document has ', stderr).end():]
                if len(msg) > 0:
                    actual_page_count = msg.split(' ')[0]
                    if actual_page_count != msg:

                        raise Exception("Input word document contains {} "
                            "pages which exceeds the page count limit of {}. "
                            "The way forward (and best practice) is to "
                            "divide your doccument into smaller chunks. For "
                            "reference, the page count of an average word "
                            "import is about 5 pages." \
                            .format(actual_page_count, page_count_limit))
            raise Exception("Unknown error, stderr:\n{}".format(stderr))
        else:
            raise Exception("Unknown error, stderr:\n{}".format(stderr))

    return output
<|endoftext|>


<commit_before>"""
This module contains controller application to manage
a set of OpenFlow switches
"""
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER, DEAD_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_4 as ofp
from ryu.ofproto import ofproto_v1_4_parser as parser
from ryu.lib.mac import haddr_to_bin

from fabric.network import Network
from fabric.network import TopologyDB as topo
import fabric.packet as pack
import fabric.flows as fl

IDLE_TIMEOUT = 10  #: Timeout for dynamic flows
DEF_PRI = 0
LOW_PRI = 1
HIGH_PRI = 2

class NetworkManager(app_manager.RyuApp):
    """
    Core class of this package, NetworkManager is a top-level Ryu application
    """

    def __init__(self, *args, **kwargs):
        super(NetworkManager, self).__init__(*args, **kwargs)
        self.net = Network()  #: Init the Network instance

	self.port_list={}
	self.switch_connected={}
	self.lsdb={}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def _handle_switch_features(self, ev):
        """
        Handle new switches connecting to the network, their ports
        and initiates a round of LLDP discovery.

        Feeds all port statuses to `self.net` and sends out LLDP discovery.

        TODO: Investigate if it is needed. Possibly better to handle
        switch state in `self._handle_state_change` and port state
        in `self._handle_port_status`

        """
        msg = ev.msg
        datapath=msg.datapath fl.install_default_flow(datapath)
        port_list=msg.ports.keys()
        port_list.remove(65534)
        self.switch_connected[datapath.id]=datapath
        self.port_state[(datapath.id]

        for key in port_list:
        	self.features_dict[(msg.datapath_id,key)]=(0,msg.ports[key].hw_addr)

	for key in switch_connected:
		self.send_lldp(switch_connected[key])

    @set_ev_cls(ofp_event.EventOFPStateChange, [DEAD_DISPATCHER])
    def _handle_state_change(self, ev):
        """
        Handle switch going down and performs a topology update.

        Unlike OFPSwitchFeatures, this event doesn't carry ports state,
        but is fired also on switch going down.

        :param ev: datapath description and reason for state change
        :type ev: `ofp_event.EventOFPStateChange`,
                  where datapath can be None if negotiation didn't
                  end successfully.
        """
        del switch_connected[ev.datapath]
        for key in switch_connected:
            self.send_lldp(key)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _handle_packet_in(self, ev):
        """
        Parses incoming packet and calls a method that corresponds to dl_type.

        :param ev: packet contents and match structure to describe its
                   headers.
        :type ev: `ofp_event.EventOFPPacketIn`
        """
        msg=ev.msg
        pkt=packet.Packet(msg.data)
        datapath=msg.datapath
        in_port=msg.in_port
        descr=pack.parse(msg.data,datapath.id,in_port)

        pkt_arp=pkt.get_protocol(arp.arp)
        if pkt_arp:
            descr=pack.parse_arp(descr,msg.data)
	    key=descr["nl_dst"]
	    if key in self.net.ip_to_mac:
	    	dl_dst=self.net.ip_to_mac[key]
		arp_dict={"nl_src":descr["nl_src"],"nl_dst":descr["nl_dst"],"dl_src":descr["dl_src"],"dl_dst":dl_dst}
		self.reply_to_arp(datapath.id,arp_dict)
		return

	self.net.mac_to_port[descr["dl_src"]]=msg.in_port

        dst=descr["dl_dst"]
        if dst in self.net.mac_to_port:
            out_port=self.net.mac_to_port[dst]
        else:
            out_port=ofp.OFPP_FLOOD

        actions=[datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofp.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,actions=actions)
	datapath.send_msg(out)

        pkt_lldp=pkt.get_protocol(lldp.lldp)
        if pkt_lldp:
            descr=pack.parse_lldp(descr,msg.data)
            self.lsdb[(descr["dpid_src"],descr["port_src"])]=(2,descr["dpid_dst"])
	    try:
	        new_topology = self.topo.spf(self.lsdb)
	   except:
	   	pass

    @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
    def _handle_port_status(self, ev):
        """
        Depending on `ev.msg.reason` adds or deletes port entry
        in `self.net` and starts another round of LLDP discovery.

        :param ev: port description and reason for state change
        :type ev: `ofp_event.EventOFPPortStatus`
        """
        msg = ev.msg
        datapath=msg.datapath
        dpid = datapath.id
        reason = msg.reason
        port_no = msg.desc.port_no

        if reason == ofp.OFPPR_ADD:
            self.logger.info("port added %s", port_no)
            send_lldp_all() #Will flood an LLDP message from every switch connected (switch_features maintains this list). Packet_IN will handle the rest (will add it to the database)

        elif reason == ofp.OFPPR_DELETE:
            self.logger.info("port deleted %s", port_no)

            port_type = lsdb[(dpid, port_no)][0] #Getting a type of the port that went down

            if port_type == 2: #If the port is a core port or a learning
                del lsdb[dpid, port_no] # Deleting this port from the lsdb database
                send_lldp_all() #Will flood an LLDP message from every switch connected in order to discover the topology again

            elif port_type == 1:
                del lsdb[dpid, port_no] # Deleting this port from the lsdb database. Since this is an EDGE port we don't need to fire another round of LLDP

        else:
            self.logger.info("Illeagal port state %s %s", port_no, reason)

    def reply_to_arp(dp, pkt):
        """
        Responds to incoming ARP request using `self.net.mac_of` dict

        :param dp: datapath object that corresponds to originating switch
        :type dp: `ryu.controller.controller.Datapath`

        :param pkt: parsed eth and ARP headers of the request
        :type pkt: dict
        """
        dl_dst, nl_dst, nl_src = pkt["dl_src"], pkt["nl_src"],pkt["nl_dst"]
        dl_src = self.net.ip_to_mac[nl_src]
        out_port = dp.ofproto.OFPP_LOCAL

        pkt = create_arp( dl_src,dl_dst,nl_src,nl_dst)

        fl.send_out_packet(dp,pkt,out_port)

    def send_lldp(datapath):
        """
        Sends LLDP broadcast from a given switch

        :param datapath: datapath object that corresponds to originating switch
        :type datapath: `ryu.controller.controller.Datapath`

        """

    	pkt_lldp=pack.create_lldp(datapath.id)
    	msg=fl.send_out_packet(datapath,pkt_lldp,ofp.OFPP_FLOOD)
    	datapath.send_msg(msg)

    def send_lldp_all():
        """
        Sends LLDP broadcast to all switches that are registered on the controller

        """
        for switch in self.switch_connected.keys(): # Every key is a DPID of the switch registered on the controller
        	send_lldp(self.switch_connected[switch]) # Sending (flood) an LLDP packet for aech switch in the list. "self.switch_connected[switch]" returns a datapath object

<commit_msg>Update app.py<commit_after>"""
This module contains controller application to manage
a set of OpenFlow switches
"""
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER, DEAD_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_4 as ofp
from ryu.ofproto import ofproto_v1_4_parser as parser
from ryu.lib.mac import haddr_to_bin

from fabric.network import Network
from fabric.network import TopologyDB as topo
import fabric.packet as pack
import fabric.flows as fl

IDLE_TIMEOUT = 10  #: Timeout for dynamic flows
DEF_PRI = 0
LOW_PRI = 1
HIGH_PRI = 2

class NetworkManager(app_manager.RyuApp):
    """
    Core class of this package, NetworkManager is a top-level Ryu application
    """

    def __init__(self, *args, **kwargs):
        super(NetworkManager, self).__init__(*args, **kwargs)
        self.net = Network()  #: Init the Network instance

	self.port_list={}
	self.switch_connected={}
	self.lsdb={}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def _handle_switch_features(self, ev):
        """
        Handle new switches connecting to the network, their ports
        and initiates a round of LLDP discovery.

        Feeds all port statuses to `self.net` and sends out LLDP discovery.

        TODO: Investigate if it is needed. Possibly better to handle
        switch state in `self._handle_state_change` and port state
        in `self._handle_port_status`

        """
        msg = ev.msg
        datapath=msg.datapath fl.install_default_flow(datapath)
        port_list=msg.ports.keys()
        port_list.remove(65534)
        self.switch_connected[datapath.id]=datapath
        self.port_state[(datapath.id]

        for key in port_list:
        	self.features_dict[(msg.datapath_id,key)]=(0,msg.ports[key].hw_addr)

	for key in switch_connected:
		self.send_lldp(switch_connected[key])

    @set_ev_cls(ofp_event.EventOFPStateChange, [DEAD_DISPATCHER])
    def _handle_state_change(self, ev):
        """
        Handle switch going down and performs a topology update.

        Unlike OFPSwitchFeatures, this event doesn't carry ports state,
        but is fired also on switch going down.

        :param ev: datapath description and reason for state change
        :type ev: `ofp_event.EventOFPStateChange`,
                  where datapath can be None if negotiation didn't
                  end successfully.
        """
        del switch_connected[ev.datapath]
        for key in switch_connected:
            self.send_lldp(key)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _handle_packet_in(self, ev):
        """
        Parses incoming packet and calls a method that corresponds to dl_type.

        :param ev: packet contents and match structure to describe its
                   headers.
        :type ev: `ofp_event.EventOFPPacketIn`
        """
        msg=ev.msg
        pkt=packet.Packet(msg.data)
        datapath=msg.datapath
        in_port=msg.match['in_port']
        descr=pack.parse(msg.data,datapath.id,in_port)

        pkt_arp=pkt.get_protocol(arp.arp)
        if pkt_arp:
            descr=pack.parse_arp(descr,msg.data)
	    key=descr["nl_dst"]
	    if key in self.net.ip_to_mac:
	    	dl_dst=self.net.ip_to_mac[key]
		arp_dict={"nl_src":descr["nl_src"],"nl_dst":descr["nl_dst"],"dl_src":descr["dl_src"],"dl_dst":dl_dst}
		self.reply_to_arp(datapath.id,arp_dict)
		return

	self.net.mac_to_port[descr["dl_src"]]=in_port

        dst=descr["dl_dst"]
        if dst in self.net.mac_to_port:
            out_port=self.net.mac_to_port[dst]
        else:
            out_port=ofp.OFPP_FLOOD

        actions=[datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofp.OFPP_FLOOD:
            self.add_flow(datapath, in_port, dst, actions)

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,actions=actions)
	datapath.send_msg(out)

        pkt_lldp=pkt.get_protocol(lldp.lldp)
        if pkt_lldp:
            descr=pack.parse_lldp(descr,msg.data)
            self.lsdb[(descr["dpid_src"],descr["port_src"])]=(2,descr["dpid_dst"])
	    try:
	        new_topology = self.topo.spf(self.lsdb)
	   except:
	   	pass

    @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER)
    def _handle_port_status(self, ev):
        """
        Depending on `ev.msg.reason` adds or deletes port entry
        in `self.net` and starts another round of LLDP discovery.

        :param ev: port description and reason for state change
        :type ev: `ofp_event.EventOFPPortStatus`
        """
        msg = ev.msg
        datapath=msg.datapath
        dpid = datapath.id
        reason = msg.reason
        port_no = msg.desc.port_no

        if reason == ofp.OFPPR_ADD:
            self.logger.info("port added %s", port_no)
            send_lldp_all() #Will flood an LLDP message from every switch connected (switch_features maintains this list). Packet_IN will handle the rest (will add it to the database)

        elif reason == ofp.OFPPR_DELETE:
            self.logger.info("port deleted %s", port_no)

            port_type = lsdb[(dpid, port_no)][0] #Getting a type of the port that went down

            if port_type == 2: #If the port is a core port or a learning
                del lsdb[dpid, port_no] # Deleting this port from the lsdb database
                send_lldp_all() #Will flood an LLDP message from every switch connected in order to discover the topology again

            elif port_type == 1:
                del lsdb[dpid, port_no] # Deleting this port from the lsdb database. Since this is an EDGE port we don't need to fire another round of LLDP

        else:
            self.logger.info("Illeagal port state %s %s", port_no, reason)

    def reply_to_arp(dp, pkt):
        """
        Responds to incoming ARP request using `self.net.mac_of` dict

        :param dp: datapath object that corresponds to originating switch
        :type dp: `ryu.controller.controller.Datapath`

        :param pkt: parsed eth and ARP headers of the request
        :type pkt: dict
        """
        dl_dst, nl_dst, nl_src = pkt["dl_src"], pkt["nl_src"],pkt["nl_dst"]
        dl_src = self.net.ip_to_mac[nl_src]
        out_port = dp.ofproto.OFPP_LOCAL

        pkt = create_arp( dl_src,dl_dst,nl_src,nl_dst)

        fl.send_out_packet(dp,pkt,out_port)

    def send_lldp(datapath):
        """
        Sends LLDP broadcast from a given switch

        :param datapath: datapath object that corresponds to originating switch
        :type datapath: `ryu.controller.controller.Datapath`

        """

    	pkt_lldp=pack.create_lldp(datapath.id)
    	msg=fl.send_out_packet(datapath,pkt_lldp,ofp.OFPP_FLOOD)
    	datapath.send_msg(msg)

    def send_lldp_all():
        """
        Sends LLDP broadcast to all switches that are registered on the controller

        """
        for switch in self.switch_connected.keys(): # Every key is a DPID of the switch registered on the controller
        	send_lldp(self.switch_connected[switch]) # Sending (flood) an LLDP packet for aech switch in the list. "self.switch_connected[switch]" returns a datapath object

<|endoftext|>


<commit_before>"""A set of utility functions to evaluate expressions.

Sample Usage:
    print(SgExpression.ExtractTokensFromExpression("name + issues_url"))
    print(SgExpression.ExtractTokensFromExpressions(["name + issues_url", "issues_url - id"]))
    table = tb.SgTable()
    table.SetFields([u"a", u"b", u"a_b", u"c"])
    table.Append([1, 2, 3, u"A"])
    table.Append([2, 4, 6, u"BB"])
    table.Append([3, 6, 9, u"CCC"])
    table.Append([4, 8, 12, u"ABC"])
    print(SgExpression.EvaluateExpression(table, u"CONCAT(\"a\", c, \"ccc\", -7 + 8)"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a)"))
    print(SgExpression.EvaluateExpression(table, u"a LIKE \"ttt\""))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"a * (b - a_b)"))
    print(SgExpression.EvaluateExpression(table, u"MIN(a * (b - a_b))"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a * (b - a_b))"))
    print(SgExpression.EvaluateExpression(table, u"-7 + a*(b-a_b)"))
    print(SgExpression.EvaluateExpression(table, u"max(a*(b-a_b))"))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"a * b - a_b + a_b % a"))
    print(SgExpression.EvaluateExpression(table, u"MIN(a * b - a_b + a_b % a)"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a * b - a_b + a_b % a)"))
    print(SgExpression.EvaluateExpression(table, u"a*b-a_b+a_b%a"))
    print(SgExpression.EvaluateExpression(table, u"max(a*b-a_b+a_b%a)"))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"3 + 2 = 5"))
    print(SgExpression.EvaluateExpression(table, u"6 = 3 + 2"))
    print(SgExpression.EvaluateExpression(table, u"a_b * a_b - b > 10"))
    print(SgExpression.EvaluateExpression(table, u"\"aaa\" is \"aaa\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"%\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"%A\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"C_C\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"A\""))
    print(SgExpression.EvaluateExpression(table, u"c regexp \"B*\""))
    print(SgExpression.EvaluateExpression(table, u"c regexp \"[B-C]*\""))
    print(SgExpression.EvaluateExpression(table, u"\"BB\" in (\"A\", \"B\", c)"))
    print("---")
    print(SgExpression.EvaluateExpression(table, "not a + 2 >= b"))
    print(SgExpression.EvaluateExpression(table, "not a + 2 >= b and a_b > 10"))
    print(SgExpression.EvaluateExpression(table, "b < 5 || a_b > 10"))
"""

import re

import definition as df
import table as tb

class SgExpression:
    """A set of utility functions to evaluate expressions."""

    # (?:something) means a non-capturing group
    # Matches anything word that isn't prefixed with a '"' (not a string literal) and postfixed with a '(' (not a function name)
    # Adding a non-alpha character as matching prefix/postfix to prevent cases like 'www(' having a match 'ww'
    _TOKEN_BODY = r"([\w_]+)"
    _TOKEN_POST = r"(?:[^\(\w_]|$)"
    _TOKEN_REGEX = _TOKEN_BODY + _TOKEN_POST

    @staticmethod
    def ExtractTokensFromExpressions(exprs):
        ret_set = set()
        for expr in exprs:
            expr_rem = re.sub(r"\"[^\"]*\"", r"", expr)
            expr_rem = re.sub(r"\'[^\']*\'", r"", expr_rem)  # string literal removed
            for token in re.findall(SgExpression._TOKEN_REGEX, expr_rem):
                if not token in df.ALL_TOKENS:
                    ret_set.add(token)
        return list(ret_set)

    @staticmethod
    def _IsFieldTokenCharacter(ch):
        return ch.isalpha() or ch == u"_"

    @staticmethod
    def _IsOperatorCharacter(ch):
        return not ch.isspace()

    @staticmethod
    def _IsNumericCharacter(ch):
        return ch.isdigit() or ch == u"."

    @staticmethod
    def _GetPrecedence(opr):
        return df.PRECEDENCE[opr] if opr else -100

    @staticmethod
    def _EvaluateOperatorBack(opds, oprs):
        opr = oprs[-1]
        oprs.pop()
        rows = len(opds)
        if opr == u",":  # special case: have to process every u","
            for i in range(rows):
                opds[i] = opds[i][:-2] + [opds[i][-2] + [opds[i][-1]]]
        elif opr == u"*":
            for i in range(rows):
                res = opds[i][-2] * opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"/":
            for i in range(rows):
                res = opds[i][-2] / opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"%":
            for i in range(rows):
                res = opds[i][-2] % opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"+":
            for i in range(rows):
                res = opds[i][-2] + opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"-":
            for i in range(rows):
                res = opds[i][-2] - opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"==":  # shouldn't work with None but it does now
            for i in range(rows):
                res = opds[i][-2] == opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u">=":
            for i in range(rows):
                res = opds[i][-2] >= opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u">":
            for i in range(rows):
                res = opds[i][-2] > opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<=":
            for i in range(rows):
                res = opds[i][-2] <= opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<":
            for i in range(rows):
                res = opds[i][-2] < opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<>":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"!=":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"is":
            for i in range(rows):
                res = opds[i][-2] == opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"like":
            for i in range(rows):
                regex = r""
                for ch in opds[i][-1]:
                    if ch == "%":
                        regex += ".*"
                    elif ch == "_":
                        regex += "."
                    else:
                        regex += re.escape(ch)
                regex += r"$"
                res = True if opds[i][-2] and re.match(regex, opds[i][-2]) else False
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"regexp":
            for i in range(rows):
                regex = re.compile(opds[i][-1] + "$")
                res = True if opds[i][-2] and re.match(regex, opds[i][-2]) else False
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"in":
            for i in range(rows):
                res = opds[i][-2] in opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"not":
            for i in range(rows):
                opds[i][-1] = not opds[i][-1]
        elif opr in (u"and", u"&&"):
            for i in range(rows):
                res = opds[i][-2] and opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == "xor":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]  # assumes both are boolean's
                opds[i] = opds[i][:-2] + [res]
        elif opr in (u"or", u"||"):
            for i in range(rows):
                res = opds[i][-2] or opds[i][-1]
                opds[i] = opds[i][:-2] + [res]

    @staticmethod
    def _EvaluateFunction(opds, func):
        # print(opds, func)
        rows = len(opds)
        if func == "max":
            mx = max(row[-1] for row in opds)
            res = []
            for i in range(rows):
                res.append(mx)
            return res
        elif func == "min":
            mn = min(row[-1] for row in opds)
            res = []
            for i in range(rows):
                res.append(mn)
            return res
        else:
            res = [row[-1] for row in opds]
            return res

    @staticmethod
    def _EvaluateOperator(opds, oprs, opr=None):
        prec = SgExpression._GetPrecedence(opr)
        rows = len(opds)
        if opr == u"(":
            oprs.append(u"")
            oprs.append(opr)
        elif opr == u")":
            while oprs and oprs[-1] != u"(":
                SgExpression._EvaluateOperatorBack(opds, oprs)
            oprs.pop()
            func = oprs.pop().lower()
            if func:
                res = SgExpression._EvaluateFunction(opds, func)
                for i in range(rows):
                    opds[i][-1] = res[i]
        elif opr == u",":
            while oprs and SgExpression._GetPrecedence(oprs[-1]) >= prec and oprs[-1] != ",":
                SgExpression._EvaluateOperatorBack(opds, oprs)
            if (not oprs) or (oprs and oprs[-1] != ","):
                for i in range(rows):
                    opds[i][-1] = [opds[i][-1]]
            else:
                oprs.pop()
                for i in range(rows):
                    opds[i] = opds[i][:-2] + [opds[i][-2] + [opds[i][-1]]]
            oprs.append(opr)
        else:
            while oprs and SgExpression._GetPrecedence(oprs[-1]) >= prec :
                SgExpression._EvaluateOperatorBack(opds, oprs)
            if opr:
                oprs.append(opr)

    @staticmethod
    def _ProcessOperator(is_start, opds, oprs, token):
        rows = len(opds)
        token = token.lower()
        if token == u"-":
            token = u"--" if is_start else u"-"
        elif token == u"=":
            token = u"=="
        SgExpression._EvaluateOperator(opds, oprs, token)

    @staticmethod
    def EvaluateExpression(table, expr):
        rows = len(table)
        opds = []
        oprs = []
        for _ in range(rows):
            opds.append([])
        reading = None  # None = nothing, 0 = operator, 1 = field tokens (can be operator too), 2 = number, 3 = string
        is_start = True
        token = u""
        expr += u" "  # add a terminating character (to end token parsing)
        for ch in expr:
            if reading == 3:  # string
                if ch in (u"\"", u"\'"):
                    for i in range(rows):
                        opds[i].append(token)
                    token = u""
                    reading = None
                else:
                    token += ch
            elif reading == 2:  # number
                if SgExpression._IsNumericCharacter(ch):
                    token += ch
                else:
                    num = float(token) if u"." in token else int(token)
                    for i in range(rows):
                        opds[i].append(num)
                    token = u""
                    if SgExpression._IsOperatorCharacter(ch):
                        reading = 0
                        token = ch
                    else:
                        reading = None
            elif reading == 1:
                if SgExpression._IsFieldTokenCharacter(ch):
                    token += ch
                else:
                    if token.lower() in df.OPERATOR_TOKENS:
                        SgExpression._ProcessOperator(is_start, opds, oprs, token)
                        token = u""
                        if ch.isspace():
                            reading = None
                        else:
                            token = ch
                            if ch in (u"\"", "\'"):
                                reading = 3
                                token = u""
                            elif SgExpression._IsNumericCharacter(ch):
                                reading = 2
                            elif SgExpression._IsFieldTokenCharacter(ch):
                                reading = 1
                            elif SgExpression._IsOperatorCharacter(ch):
                                reading = 0
                    elif ch == u"(":  # function
                        oprs.append(token)
                        oprs.append(ch)
                        is_start = True
                        token = u""
                        reading = None
                    else:
                        vals = table.GetVals(token)
                        for i in range(rows):
                            opds[i].append(vals[i])
                        token = u""
                        if SgExpression._IsOperatorCharacter(ch):
                            reading = 0
                            token = ch
                        else:
                            reading = None
            elif reading == 0:
                if token == u"":
                    is_opr = True
                elif token == u")":
                    is_opr = False  # just to terminate the current segment
                elif token == u"(":
                    is_opr = False
                elif token.isalpha():
                    is_opr = ch.isalpha()
                else:
                    is_opr = (not ch.isalnum()) and (not ch.isspace())

                if is_opr:
                    token += ch
                else:
                    SgExpression._ProcessOperator(is_start, opds, oprs, token)
                    if token == ",":
                        is_start = True
                    token = u""
                    if ch.isspace():
                        reading = None
                    else:
                        token = ch
                        if ch in (u"\"", "\'"):
                            reading = 3
                            token = u""
                        elif SgExpression._IsNumericCharacter(ch):
                            reading = 2
                        elif SgExpression._IsFieldTokenCharacter(ch):
                            reading = 1
                        elif SgExpression._IsOperatorCharacter(ch):
                            reading = 0
            else:  # None
                if ch.isspace():
                    reading = None
                else:
                    token += ch
                    if ch in (u"\"", u"\'"):
                        reading = 3
                        token = u""
                    elif SgExpression._IsNumericCharacter(ch) or (ch == u"-" and is_start):
                        reading = 2
                    elif SgExpression._IsFieldTokenCharacter(ch):
                        reading = 1
                    elif SgExpression._IsOperatorCharacter(ch):
                        reading = 0
                    is_start = False
            # print(opds, oprs)
        SgExpression._EvaluateOperator(opds, oprs)  # opr = None
        return [row[0] for row in opds]

    @staticmethod
    def EvaluateExpressions(table, exprs):
        ret = tb.SgTable()
        ret.SetFields(exprs)
        rows = len(table)
        for _ in range(rows):
            ret.Append([])
        for expr in exprs:
            res = SgExpression.EvaluateExpression(table, expr)
            for i, val in enumerate(res):
                # TODO(lnishan): Fix the cheat here.
                ret._table[i].append(val)
        return ret
<commit_msg>Fix re used to match tokens. \w also matches numeric characters<commit_after>"""A set of utility functions to evaluate expressions.

Sample Usage:
    print(SgExpression.ExtractTokensFromExpression("name + issues_url"))
    print(SgExpression.ExtractTokensFromExpressions(["name + issues_url", "issues_url - id"]))
    table = tb.SgTable()
    table.SetFields([u"a", u"b", u"a_b", u"c"])
    table.Append([1, 2, 3, u"A"])
    table.Append([2, 4, 6, u"BB"])
    table.Append([3, 6, 9, u"CCC"])
    table.Append([4, 8, 12, u"ABC"])
    print(SgExpression.EvaluateExpression(table, u"CONCAT(\"a\", c, \"ccc\", -7 + 8)"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a)"))
    print(SgExpression.EvaluateExpression(table, u"a LIKE \"ttt\""))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"a * (b - a_b)"))
    print(SgExpression.EvaluateExpression(table, u"MIN(a * (b - a_b))"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a * (b - a_b))"))
    print(SgExpression.EvaluateExpression(table, u"-7 + a*(b-a_b)"))
    print(SgExpression.EvaluateExpression(table, u"max(a*(b-a_b))"))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"a * b - a_b + a_b % a"))
    print(SgExpression.EvaluateExpression(table, u"MIN(a * b - a_b + a_b % a)"))
    print(SgExpression.EvaluateExpression(table, u"MAX(a * b - a_b + a_b % a)"))
    print(SgExpression.EvaluateExpression(table, u"a*b-a_b+a_b%a"))
    print(SgExpression.EvaluateExpression(table, u"max(a*b-a_b+a_b%a)"))
    print("---")
    print(SgExpression.EvaluateExpression(table, u"3 + 2 = 5"))
    print(SgExpression.EvaluateExpression(table, u"6 = 3 + 2"))
    print(SgExpression.EvaluateExpression(table, u"a_b * a_b - b > 10"))
    print(SgExpression.EvaluateExpression(table, u"\"aaa\" is \"aaa\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"%\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"%A\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"C_C\""))
    print(SgExpression.EvaluateExpression(table, u"c like \"A\""))
    print(SgExpression.EvaluateExpression(table, u"c regexp \"B*\""))
    print(SgExpression.EvaluateExpression(table, u"c regexp \"[B-C]*\""))
    print(SgExpression.EvaluateExpression(table, u"\"BB\" in (\"A\", \"B\", c)"))
    print("---")
    print(SgExpression.EvaluateExpression(table, "not a + 2 >= b"))
    print(SgExpression.EvaluateExpression(table, "not a + 2 >= b and a_b > 10"))
    print(SgExpression.EvaluateExpression(table, "b < 5 || a_b > 10"))
"""

import re

import definition as df
import table as tb

class SgExpression:
    """A set of utility functions to evaluate expressions."""

    # (?:something) means a non-capturing group
    # Matches anything word that isn't prefixed with a '"' (not a string literal) and postfixed with a '(' (not a function name)
    # Adding a non-alpha character as matching prefix/postfix to prevent cases like 'www(' having a match 'ww'
    _TOKEN_BODY = r"([a-zA-Z_]+)"
    _TOKEN_POST = r"(?:[^\(a-zA-Z_]|$)"
    _TOKEN_REGEX = _TOKEN_BODY + _TOKEN_POST

    @staticmethod
    def ExtractTokensFromExpressions(exprs):
        ret_set = set()
        for expr in exprs:
            expr_rem = re.sub(r"\"[^\"]*\"", r"", expr)
            expr_rem = re.sub(r"\'[^\']*\'", r"", expr_rem)  # string literal removed
            for token in re.findall(SgExpression._TOKEN_REGEX, expr_rem):
                if not token in df.ALL_TOKENS:
                    ret_set.add(token)
        return list(ret_set)

    @staticmethod
    def _IsFieldTokenCharacter(ch):
        return ch.isalpha() or ch == u"_"

    @staticmethod
    def _IsOperatorCharacter(ch):
        return not ch.isspace()

    @staticmethod
    def _IsNumericCharacter(ch):
        return ch.isdigit() or ch == u"."

    @staticmethod
    def _GetPrecedence(opr):
        return df.PRECEDENCE[opr] if opr else -100

    @staticmethod
    def _EvaluateOperatorBack(opds, oprs):
        opr = oprs[-1]
        oprs.pop()
        rows = len(opds)
        if opr == u",":  # special case: have to process every u","
            for i in range(rows):
                opds[i] = opds[i][:-2] + [opds[i][-2] + [opds[i][-1]]]
        elif opr == u"*":
            for i in range(rows):
                res = opds[i][-2] * opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"/":
            for i in range(rows):
                res = opds[i][-2] / opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"%":
            for i in range(rows):
                res = opds[i][-2] % opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"+":
            for i in range(rows):
                res = opds[i][-2] + opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"-":
            for i in range(rows):
                res = opds[i][-2] - opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"==":  # shouldn't work with None but it does now
            for i in range(rows):
                res = opds[i][-2] == opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u">=":
            for i in range(rows):
                res = opds[i][-2] >= opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u">":
            for i in range(rows):
                res = opds[i][-2] > opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<=":
            for i in range(rows):
                res = opds[i][-2] <= opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<":
            for i in range(rows):
                res = opds[i][-2] < opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"<>":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"!=":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"is":
            for i in range(rows):
                res = opds[i][-2] == opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"like":
            for i in range(rows):
                regex = r""
                for ch in opds[i][-1]:
                    if ch == "%":
                        regex += ".*"
                    elif ch == "_":
                        regex += "."
                    else:
                        regex += re.escape(ch)
                regex += r"$"
                res = True if opds[i][-2] and re.match(regex, opds[i][-2]) else False
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"regexp":
            for i in range(rows):
                regex = re.compile(opds[i][-1] + "$")
                res = True if opds[i][-2] and re.match(regex, opds[i][-2]) else False
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"in":
            for i in range(rows):
                res = opds[i][-2] in opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == u"not":
            for i in range(rows):
                opds[i][-1] = not opds[i][-1]
        elif opr in (u"and", u"&&"):
            for i in range(rows):
                res = opds[i][-2] and opds[i][-1]
                opds[i] = opds[i][:-2] + [res]
        elif opr == "xor":
            for i in range(rows):
                res = opds[i][-2] != opds[i][-1]  # assumes both are boolean's
                opds[i] = opds[i][:-2] + [res]
        elif opr in (u"or", u"||"):
            for i in range(rows):
                res = opds[i][-2] or opds[i][-1]
                opds[i] = opds[i][:-2] + [res]

    @staticmethod
    def _EvaluateFunction(opds, func):
        # print(opds, func)
        rows = len(opds)
        if func == "max":
            mx = max(row[-1] for row in opds)
            res = []
            for i in range(rows):
                res.append(mx)
            return res
        elif func == "min":
            mn = min(row[-1] for row in opds)
            res = []
            for i in range(rows):
                res.append(mn)
            return res
        else:
            res = [row[-1] for row in opds]
            return res

    @staticmethod
    def _EvaluateOperator(opds, oprs, opr=None):
        prec = SgExpression._GetPrecedence(opr)
        rows = len(opds)
        if opr == u"(":
            oprs.append(u"")
            oprs.append(opr)
        elif opr == u")":
            while oprs and oprs[-1] != u"(":
                SgExpression._EvaluateOperatorBack(opds, oprs)
            oprs.pop()
            func = oprs.pop().lower()
            if func:
                res = SgExpression._EvaluateFunction(opds, func)
                for i in range(rows):
                    opds[i][-1] = res[i]
        elif opr == u",":
            while oprs and SgExpression._GetPrecedence(oprs[-1]) >= prec and oprs[-1] != ",":
                SgExpression._EvaluateOperatorBack(opds, oprs)
            if (not oprs) or (oprs and oprs[-1] != ","):
                for i in range(rows):
                    opds[i][-1] = [opds[i][-1]]
            else:
                oprs.pop()
                for i in range(rows):
                    opds[i] = opds[i][:-2] + [opds[i][-2] + [opds[i][-1]]]
            oprs.append(opr)
        else:
            while oprs and SgExpression._GetPrecedence(oprs[-1]) >= prec :
                SgExpression._EvaluateOperatorBack(opds, oprs)
            if opr:
                oprs.append(opr)

    @staticmethod
    def _ProcessOperator(is_start, opds, oprs, token):
        rows = len(opds)
        token = token.lower()
        if token == u"-":
            token = u"--" if is_start else u"-"
        elif token == u"=":
            token = u"=="
        SgExpression._EvaluateOperator(opds, oprs, token)

    @staticmethod
    def EvaluateExpression(table, expr):
        rows = len(table)
        opds = []
        oprs = []
        for _ in range(rows):
            opds.append([])
        reading = None  # None = nothing, 0 = operator, 1 = field tokens (can be operator too), 2 = number, 3 = string
        is_start = True
        token = u""
        expr += u" "  # add a terminating character (to end token parsing)
        for ch in expr:
            if reading == 3:  # string
                if ch in (u"\"", u"\'"):
                    for i in range(rows):
                        opds[i].append(token)
                    token = u""
                    reading = None
                else:
                    token += ch
            elif reading == 2:  # number
                if SgExpression._IsNumericCharacter(ch):
                    token += ch
                else:
                    num = float(token) if u"." in token else int(token)
                    for i in range(rows):
                        opds[i].append(num)
                    token = u""
                    if SgExpression._IsOperatorCharacter(ch):
                        reading = 0
                        token = ch
                    else:
                        reading = None
            elif reading == 1:
                if SgExpression._IsFieldTokenCharacter(ch):
                    token += ch
                else:
                    if token.lower() in df.OPERATOR_TOKENS:
                        SgExpression._ProcessOperator(is_start, opds, oprs, token)
                        token = u""
                        if ch.isspace():
                            reading = None
                        else:
                            token = ch
                            if ch in (u"\"", "\'"):
                                reading = 3
                                token = u""
                            elif SgExpression._IsNumericCharacter(ch):
                                reading = 2
                            elif SgExpression._IsFieldTokenCharacter(ch):
                                reading = 1
                            elif SgExpression._IsOperatorCharacter(ch):
                                reading = 0
                    elif ch == u"(":  # function
                        oprs.append(token)
                        oprs.append(ch)
                        is_start = True
                        token = u""
                        reading = None
                    else:
                        vals = table.GetVals(token)
                        for i in range(rows):
                            opds[i].append(vals[i])
                        token = u""
                        if SgExpression._IsOperatorCharacter(ch):
                            reading = 0
                            token = ch
                        else:
                            reading = None
            elif reading == 0:
                if token == u"":
                    is_opr = True
                elif token == u")":
                    is_opr = False  # just to terminate the current segment
                elif token == u"(":
                    is_opr = False
                elif token.isalpha():
                    is_opr = ch.isalpha()
                else:
                    is_opr = (not ch.isalnum()) and (not ch.isspace())

                if is_opr:
                    token += ch
                else:
                    SgExpression._ProcessOperator(is_start, opds, oprs, token)
                    if token == ",":
                        is_start = True
                    token = u""
                    if ch.isspace():
                        reading = None
                    else:
                        token = ch
                        if ch in (u"\"", "\'"):
                            reading = 3
                            token = u""
                        elif SgExpression._IsNumericCharacter(ch):
                            reading = 2
                        elif SgExpression._IsFieldTokenCharacter(ch):
                            reading = 1
                        elif SgExpression._IsOperatorCharacter(ch):
                            reading = 0
            else:  # None
                if ch.isspace():
                    reading = None
                else:
                    token += ch
                    if ch in (u"\"", u"\'"):
                        reading = 3
                        token = u""
                    elif SgExpression._IsNumericCharacter(ch) or (ch == u"-" and is_start):
                        reading = 2
                    elif SgExpression._IsFieldTokenCharacter(ch):
                        reading = 1
                    elif SgExpression._IsOperatorCharacter(ch):
                        reading = 0
                    is_start = False
            # print(opds, oprs)
        SgExpression._EvaluateOperator(opds, oprs)  # opr = None
        return [row[0] for row in opds]

    @staticmethod
    def EvaluateExpressions(table, exprs):
        ret = tb.SgTable()
        ret.SetFields(exprs)
        rows = len(table)
        for _ in range(rows):
            ret.Append([])
        for expr in exprs:
            res = SgExpression.EvaluateExpression(table, expr)
            for i, val in enumerate(res):
                # TODO(lnishan): Fix the cheat here.
                ret._table[i].append(val)
        return ret
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import os
import subprocess
import sys
import tempfile

import compose_deploy

DOCKER_HOST_PATH = os.path.join(os.environ['HOME'], '.docker-remote.sock')

LISTEN_STRING = 'UNIX-LISTEN:{},reuseaddr,fork'.format(DOCKER_HOST_PATH)

SSH_COMMAND = 'ssh {} "socat STDIO UNIX-CONNECT:/var/run/docker.sock"'
REMOTE_STRING = 'EXEC:{}'.format(SSH_COMMAND)

BASH_RC = """
PS1="docker remote shell on '{server}' $ "
"""

def remote(server, command=None):
    os.environ['DOCKER_HOST'] = 'unix://{}'.format(DOCKER_HOST_PATH)
    os.environ['VIRTUALENVWRAPPER_PYTHON'] = '/usr/bin/python'

    if command is None:
        print('Starting a new shell with remote docker environment variable,\n'
              'exit this shell (usually ^D) as normal when you\'re done\n',
              file=sys.stderr)

    socket_forward_process = subprocess.Popen(
        ' '.join(['socat',
                  LISTEN_STRING,
                  REMOTE_STRING.format(server)
                  ]),
        shell=True)

    to_run = [os.getenv('SHELL', '/bin/bash')]

    if command is not None:
        if isinstance(command, basestring):
            to_run.extend(['-c', command])
        else:
            to_run.extend(command)
    elif to_run[0].endswith('bash'):
        bashrc = tempfile.NamedTemporaryFile()
        bashrc.write(BASH_RC.format(server=server))
        bashrc.flush()
        to_run.extend(['--rcfile', bashrc.name])
    elif to_run[0].endswith('zsh'):
        os.environ['PS1'] = 'docker remote shell on "{}" $ '.format(server)
        to_run.extend(['-f', '-d'])

    shell_process = subprocess.Popen(
        to_run,
        stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)

    shell_process.wait()

    print("\nExited docker remote shell, cleaning up...", file=sys.stderr)

    socket_forward_process.terminate()
    socket_forward_process.wait()

    try:
        os.remove(DOCKER_HOST_PATH)
    except OSError:
        pass

    print("Done cleaning up", file=sys.stderr)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--version', '-V', action='store_true',
                        help='Print version number and exit')
    parser.add_argument('server',
                        help='Server to point docker at')
    args = parser.parse_args()

    if args.version:
        print(compose_deploy.__version__)
        return

    return remote(args.server)

if __name__ == '__main__':
    main()
<commit_msg>Namespace the socket files and be more sure of cleanup<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import argparse
import os
import subprocess
import sys
import tempfile

import compose_deploy

DOCKER_HOST_PATH = os.path.join(os.environ['HOME'], '.docker-remote.{}.sock')

LISTEN_STRING = 'UNIX-LISTEN:{},reuseaddr,fork'.format(DOCKER_HOST_PATH)

SSH_COMMAND = '\'ssh {} "socat STDIO UNIX-CONNECT:/var/run/docker.sock"\''
REMOTE_STRING = 'EXEC:{}'.format(SSH_COMMAND)

BASH_RC = """
PS1="docker remote shell on '{server}' $ "
"""

def remote(server, command=None):
    os.environ['DOCKER_HOST'] = 'unix://{}'.format(DOCKER_HOST_PATH.format(server))
    os.environ['VIRTUALENVWRAPPER_PYTHON'] = '/usr/bin/python'

    if command is None:
        print('Starting a new shell with remote docker environment variable,\n'
              'exit this shell (usually ^D) as normal when you\'re done\n',
              file=sys.stderr)

    shell_string = ' '.join(['socat',
                             LISTEN_STRING.format(server),
                             REMOTE_STRING.format(server)
                             ])

    socket_forward_process = subprocess.Popen(shell_string, shell=True)

    to_run = [os.getenv('SHELL', '/bin/bash')]

    if command is not None:
        if isinstance(command, basestring):
            to_run.extend(['-c', command])
        else:
            to_run.extend(command)
    elif to_run[0].endswith('bash'):
        bashrc = tempfile.NamedTemporaryFile()
        bashrc.write(BASH_RC.format(server=server))
        bashrc.flush()
        to_run.extend(['--rcfile', bashrc.name])
    elif to_run[0].endswith('zsh'):
        os.environ['PS1'] = 'docker remote shell on "{}" $ '.format(server)
        to_run.extend(['-f', '-d'])

    shell_process = subprocess.Popen(
        to_run,
        stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)

    shell_process.wait()

    print("\nExited docker remote shell, cleaning up...", file=sys.stderr)

    socket_forward_process.terminate()
    socket_forward_process.wait()

    try:
        os.remove(DOCKER_HOST_PATH.format(server))
    except OSError:
        pass

    print("Done cleaning up", file=sys.stderr)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--version', '-V', action='store_true',
                        help='Print version number and exit')
    parser.add_argument('server',
                        help='Server to point docker at')
    args = parser.parse_args()

    if args.version:
        print(compose_deploy.__version__)
        return

    return remote(args.server)

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