<commit_before># REST Framework
from rest_framework import generics, permissions, status
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.test import APIRequestFactory, APITestCase

# User class from django
from django.contrib.auth.models import User, UserManager

# Models and Serializers
from main.serializers import UserSerializer, TopicSerializer, FeedSerializer, PostSerializer
from main.models import Topic, Feed, Post
from django.forms.models import model_to_dict

## Transaction Management
from django.db import transaction

# Python built-ins required for tests
import time
import datetime
import pytz
import traceback

def FeedSearchTests(APITestCase):
    @classmethod
    def setUpClass(cls):

        # init user
        cls.user = User(username = "Lucia")
        cls.user.save()

        #init videogame Feeds
        cls.f1 = Feed.createByURL("http://penny-arcade.com/feed")
        cls.f1.save()
        cls.f2 = Feed.createByURL("http://thepunchlineismachismo.com/feed")
        cls.f2.save()
        cls.f3 = Feed.createByURL("http://www.vgcats.com/vgcats.rdf.xml")
        cls.f3.save()

    def tearDownClass(cls):
        cls.user.delete()
        cls.f1.delete()
        cls.f2.delete()
        cls.f3.delete

    def test_search_feeds(cls):
        """No Topics - the search should return a list of Feeds"""
        cls.assertEqual(True, False)
        response = cls.client.get("/search", {"searchString":"video games"})
        cls.assertEqual(response.status_code, 200)
        cls.assertEqual(response.data, "blugh")

    def test_search_feeds_and_topics(cls):
        """Topics exist - the search should still return a list of Feeds"""
        #init "videogames" Topic, with f1 and f2
        videogames = Topic(name = "videogames", user = cls.user)
        videogames.save()
        videogames.addFeed(cls.f1)
        videogames.addFeed(cls.f2)

        response = cls.client.get("/search", {"searchString":"video games"})
        cls.assertEqual(response.status_code, 200)
        cls.assertEqual(response.data, "blugh")
<commit_msg>wrote the first draft of search tests, none of which work<commit_after># REST Framework
from rest_framework import generics, permissions, status
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.test import APIRequestFactory, APITestCase

# User class from django
from django.contrib.auth.models import User, UserManager
from django.core.management import call_command

# Models and Serializers
from main.serializers import UserSerializer, TopicSerializer, FeedSerializer, PostSerializer
from main.models import Topic, Feed, Post
from django.forms.models import model_to_dict

## Transaction Management
from django.db import transaction

# Python built-ins required for tests
import time
import datetime
import pytz
import traceback

#import watson
import watson
from watson.registration import RegistrationError, get_backend, SearchEngine
from watson.models import SearchEntry

class SearchTests(APITestCase):
    @classmethod
    def setUpClass(cls):
        call_command("installwatson", verbosity=0)
        cls.registered_models = watson.get_registered_models()
        # Remove all the current registered models.
        for model in cls.registered_models:
            watson.unregister(model)
        # Register the test models.
        watson.register(Feed)
        watson.register(Post)
        watson.register(Topic)

        # init user
        cls.user = User(username = "Lucia")
        cls.user.save()

        #init videogame Feeds
        Feed.createByURL("http://penny-arcade.com/feed").save()
        Feed.createByURL("http://thepunchlineismachismo.com/feed").save()
        Feed.createByURL("http://rss.escapistmagazine.com/articles/comicsandcosplay/comics/critical-miss.xml").save()
        Feed.createByURL("http://xkcd.com/rss.xml").save()
        Feed.createByURL("http://rss.nytimes.com/services/xml/rss/nyt/Golf.xml").save()

        cls.f1_m = Feed.objects.get(URL = "http://penny-arcade.com/feed")
        cls.f1 = FeedSerializer(cls.f1_m).data

        cls.f2_m = Feed.objects.get(URL = "http://thepunchlineismachismo.com/feed")
        cls.f2 = FeedSerializer(cls.f2_m).data

        cls.f3_m = Feed.objects.get(URL = "http://rss.escapistmagazine.com/articles/comicsandcosplay/comics/critical-miss.xml")
        cls.f3 = FeedSerializer(cls.f3_m).data

        cls.f4_m = Feed.objects.get(URL = "http://xkcd.com/rss.xml")
        cls.f4 = FeedSerializer(cls.f4_m).data

        cls.f5_m = Feed.objects.get(URL = "http://rss.nytimes.com/services/xml/rss/nyt/Golf.xml")
        cls.f5 = FeedSerializer(cls.f5_m).data

    @classmethod
    def tearDownClass(cls):
        #Unregister test models.
        watson.unregister(Feed)
        watson.unregister(Post)
        watson.unregister(Topic)
        # Re-register the old registered models.
        for model in cls.registered_models:
            watson.register(model)
        # Unregister the test models.
        cls.user.delete()
        cls.f1_m.delete()
        cls.f2_m.delete()
        cls.f3_m.delete()
        cls.f4_m.delete()

    def test_search_feeds(cls):
        """Confirms that search covers Feed titles"""
        #f1, f2, and f3 titles contain words "Penny", "Manly", and "Critical"
        #Tests that search works with half of word, different capitalization
        response = cls.client.post("/search", {"searchString":"Penny manl cRITical"})
        cls.assertEqual(response.status_code, 200)
        cls.assertItemsEqual(response.data, [cls.f1, cls.f2, cls.f3])

    def test_search_feeds_and_topics(cls):
        """Topics exist - the search should search Topics and Feeds, and return a list of Feeds"""
        #init "videogames" Topic, with f1 and f2
        webcomics = Topic(name = "webcomics", user = cls.user)
        webcomics.save()

        # Add NYT's Golf RSS to webcomics
        webcomics.addFeed(cls.f5_m)

        #Topic and f2 and f4 fields both contain word "webcomic"
        #NYT, by virtue of being under "webcomic" is returned
        response = cls.client.post("/search", {"searchString":"webcomic"})
        cls.assertEqual(response.status_code, 200)
        cls.assertItemsEqual(response.data, [cls.f2, cls.f4, cls.f5])

    def test_search_posts(cls):
        """Search covers post content"""
        #"he" does not occur in Feed names or Feed content
        response = cls.client.post("/search", {"searchString" : "he"})
        cls.assertEqual(response.status_code, 200)
        cls.assertItemsEqual(response.data, [cls.f1, cls.f2, cls.f3, cls.f4, cls.f5])

    def test_users_discarded(cls):
        """Should discard user results"""
        user2 = User(username = "webcomic")
        user2.save()

        response = cls.client.post("/search", {"searchString":"webcomic"})
        cls.assertEqual(response.status_code, 200)
        cls.assertItemsEqual(response.data, [cls.f2, cls.f4])

    def test_empty_return_list(cls):
        """Should return an empty list"""
        response = cls.client.post("/search", {"searchString":"ethics in journalism"})
        cls.assertEqual(response.status_code, 200)
        cls.assertEqual(response.data, [])

    def test_broken_url(cls):
        """Should return list of Feeds given an approximate url"""
        response = cls.client.post("/search", {"searchString":"http://xkcd.com/rss."})
        cls.assertEqual(response.status_code, 200)
        cls.assertEqual(response.data, [cls.f4])
<|endoftext|>


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

import logging
import json
from source import Source
from server import Server

from lib.memcached.helper.data_helper import MemcachedClientHelper

class MemcachedSource(Source):

    META_FILE = "./metadata/stats.json"
    MC_STATS = ["", "allocator", "checkpoint", "config", "dispatcher",
                "hash", "kvstore", "kvtimings", "memory", "prev-vbucket",
                "tap", "tapagg", "timings", "vbucket", "vbucket-details"]

    def __init__(self, server, bucket, meta_file=META_FILE, mc=None):
        self.server = server        # @class: Server
        self.bucket = bucket
        self.mc = mc
        self.data = {}
        self.meta = self.get_meta(meta_file)

    def get_meta(self, meta_file):
        with open(meta_file) as f:
            return json.loads(f.read())

    def connect(self):
        if not self.server or \
            not isinstance(self.server, Server):
            return False

        self.mc = MemcachedClientHelper.direct_client(
            self.server, self.bucket)

        return True

    def feed(self):
        if not self.mc and not self.connect():
            logging.error("unable to connect to server : %s" % self.server)
            return None

        self.data = {}
        for key in MemcachedSource.MC_STATS:
            try:
                if key != "":
                    self.data[key] = self.mc.stats(key)
                else:
                    self.data["all"] = self.mc.stats(key)
            except Exception, e:
                logging.error("exception for key %s : %s" % (key, e))

        return self.data

    def disconnect(self):
        self.mc.close()

    def gen_stats(self):
        """
        Generate individual stats
        """
        for data in self.data.itervalues():
            for key_val in data.iteritems():
                yield key_val<commit_msg>apply filters to store slow and fast mc stats<commit_after>#!/usr/bin/env python

import logging
import json
from source import Source
from server import Server

from lib.memcached.helper.data_helper import MemcachedClientHelper

class MemcachedSource(Source):

    META_FILE = "./metadata/stats.json"
    MC_STATS = ["", "allocator", "checkpoint", "config", "dispatcher",
                "hash", "kvstore", "kvtimings", "memory", "prev-vbucket",
                "tap", "tapagg", "timings", "vbucket", "vbucket-details"]

    def __init__(self, server, bucket, meta_file=META_FILE, mc=None):
        self.server = server        # @class: Server
        self.bucket = bucket
        self.mc = mc
        self.data = {}
        self.meta = self.get_meta(meta_file)
        self.slow = {"mc-host": server.ip, "mc-bucket": bucket}
        self.fast = {"mc-host": server.ip, "mc-bucket": bucket}

    def get_meta(self, meta_file):
        with open(meta_file) as f:
            return json.loads(f.read())

    def filter(self, stats):
        if not stats or not self.meta:
            logging.error("unable to apply filter: invalid data or meta")
            return False

        for key in stats:
            mkey = "mc-%s" % key
            if mkey in self.meta and "visit" in self.meta[mkey]:
                if self.meta[mkey]["visit"] == "slow":
                    self.slow[mkey] = stats[key]
                elif self.meta[mkey]["visit"] == "fast":
                    self.fast[mkey] = stats[key]

    def connect(self):
        if not self.server or \
            not isinstance(self.server, Server):
            return False

        self.mc = MemcachedClientHelper.direct_client(
            self.server, self.bucket)

        return True

    def feed(self):
        if not self.mc and not self.connect():
            logging.error("unable to connect to server : %s" % self.server)
            return None

        self.data = {}
        for key in MemcachedSource.MC_STATS:
            try:
                stats = self.mc.stats(key)
                if key != "":
                    self.data[key] = stats
                else:
                    self.data["all"] = stats
                self.filter(stats)
            except Exception, e:
                logging.error("exception for key %s : %s" % (key, e))

        return self.data

    def disconnect(self):
        self.mc.close()

    def gen_stats(self):
        """
        Generate individual stats
        """
        for data in self.data.itervalues():
            for key_val in data.iteritems():
                yield key_val<|endoftext|>


<commit_before># Copyright 2014,  Doug Wiegley,  A10 Networks.
#
#    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 acos_client.v21.base as base

class Member(base.BaseV21):

    def _write(self, action, service_group_name, server_name, server_port,
               status=None, **kwargs):
        params = {
            "name": service_group_name,
            "member": self.minimal_dict({
                "server": server_name,
                "port": int(server_port),
                "status": status
            })
        }
        self._post(action, params, **kwargs)

    def create(self, service_group_name, server_name, server_port, status=1,
               **kwargs):
        self._write("slb.service_group.member.create", service_group_name,
                    server_name, server_port, status, **kwargs)

    def update(self, service_group_name, server_name, server_port, status=1,
               **kwargs):
        self._write("slb.service_group.member.update", service_group_name,
                    server_name, server_port, status, **kwargs)

    def delete(self, service_group_name, server_name, server_port, **kwargs):
        self._write("slb.service_group.member.delete", service_group_name,
                    server_name, int(server_port), **kwargs)

    def get_oper(self, service_group_name, server_name, server_port, **kwargs):
        return self._post("slb.service_group.member.oper", service_group_name,
                          server_name, int(server_port), **kwargs)

<commit_msg>Correct oper implementation v21 members<commit_after># Copyright 2014,  Doug Wiegley,  A10 Networks.
#
#    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 acos_client.v21.base as base

class Member(base.BaseV21):

    def _write(self, action, service_group_name, server_name, server_port,
               status=None, **kwargs):
        params = {
            "name": service_group_name,
            "member": self.minimal_dict({
                "server": server_name,
                "port": int(server_port),
                "status": status
            })
        }
        self._post(action, params, **kwargs)

    def create(self, service_group_name, server_name, server_port, status=1,
               **kwargs):
        self._write("slb.service_group.member.create", service_group_name,
                    server_name, server_port, status, **kwargs)

    def update(self, service_group_name, server_name, server_port, status=1,
               **kwargs):
        self._write("slb.service_group.member.update", service_group_name,
                    server_name, server_port, status, **kwargs)

    def delete(self, service_group_name, server_name, server_port, **kwargs):
        self._write("slb.service_group.member.delete", service_group_name,
                    server_name, int(server_port), **kwargs)

    def get_oper(self, service_group_name, server_name, server_port, **kwargs):
        sg_stats = self._post("slb.service_group.fetchStatistics",
                              {"name": service_group_name}, **kwargs)
        members_stats = sg_stats["service_group_stat"]["member_stat_list"]
        member_stats = filter(lambda x: x["name"] == server_name)
<|endoftext|>


<commit_before>import numpy as np
from PIL import Image, ImageFont, ImageDraw
from nltk.book import text7
import h5py
from downsampling import downsample_letter

word = text7[0]
Nwords = 100
text = text7[0:Nwords]
store_directory = './wall_street/'

# Define the font
font_source = './secrcode.ttf'
# font_source = './Cocomat Ultralight-trial.ttf'
font_source = './Chunk.ttf'

font = ImageFont.truetype(font=font_source, size=80)

# The 100 is the pixels, the 256 is the color, 1 is for only one pixel
pixels = 100
coord_x = 18
coord_y = 18

# Parameters
space = True
save = False
to_list = True
renormalize = True

counter = 0
image_list = []

for word in text:
    # Go through the low caps version of the word
    for letter in word.lower():
        counter += 1
        # Create the image and draw the letter
        img = Image.new('1', (pixels, pixels), 256)
        d = ImageDraw.Draw(img)
        d.text((coord_x, coord_y), letter, font=font)

        if save:
            img.save(store_directory + str(counter) + '.png')

        if to_list:
            pix = np.array(img.getdata()).reshape(img.size[0], img.size[1])
            pix = downsample_letter(pix, 40, renormalize)
            image_list.append(pix)

    # Add a space
    if space:
        counter += 1
        # Create the image and draw the letter
        img = Image.new('1', (pixels, pixels), 256)
        d = ImageDraw.Draw(img)
        letter = ' '
        d.text((coord_x,coord_y), letter, font=font)

        if save:
            img.save(store_directory + str(counter) + '.png')

        if to_list:
            pix = np.array(img.getdata()).reshape(img.size[0], img.size[1])
            pix = downsample_letter(pix, 40, renormalize)
            image_list.append(pix)

# Transform the list into a signal
signal = np.array(image_list)

# Save this to a hdf5 data base using a context manager
save_filename = './wall_street_data.hdf5_small'
with h5py.File(save_filename, 'a') as f:
    f.create_dataset('signal', data=signal, dtype=np.int8)

<commit_msg>wall street corpus now working<commit_after>import numpy as np
from PIL import Image, ImageFont, ImageDraw
from nltk.book import text7
import h5py
from aux_functions import downsample_letter

word = text7[0]
Nwords = 100
text = text7[0:Nwords]
store_directory = './wall_street/'

# Define the font
font_source = './secrcode.ttf'
# font_source = './Cocomat Ultralight-trial.ttf'
font_source = './Chunk.ttf'

font = ImageFont.truetype(font=font_source, size=80)

# The 100 is the pixels, the 256 is the color, 1 is for only one pixel
pixels = 100
coord_x = 18
coord_y = 18

# Parameters
space = True
save = False
to_list = True
renormalize = True

counter = 0
image_list = []

for word in text:
    # Go through the low caps version of the word
    for letter in word.lower():
        counter += 1
        # Create the image and draw the letter
        img = Image.new('1', (pixels, pixels), 256)
        d = ImageDraw.Draw(img)
        d.text((coord_x, coord_y), letter, font=font)

        if save:
            img.save(store_directory + str(counter) + '.png')

        if to_list:
            pix = np.array(img.getdata()).reshape(img.size[0], img.size[1])
            pix = downsample_letter(pix, 40, renormalize)
            image_list.append(pix)

    # Add a space
    if space:
        counter += 1
        # Create the image and draw the letter
        img = Image.new('1', (pixels, pixels), 256)
        d = ImageDraw.Draw(img)
        letter = ' '
        d.text((coord_x,coord_y), letter, font=font)

        if save:
            img.save(store_directory + str(counter) + '.png')

        if to_list:
            pix = np.array(img.getdata()).reshape(img.size[0], img.size[1])
            pix = downsample_letter(pix, 40, renormalize)
            image_list.append(pix)

# Transform the list into a signal
signal = np.array(image_list)

# Save this to a hdf5 data base using a context manager
save_filename = './wall_street_data.hdf5_small'
with h5py.File(save_filename, 'a') as f:
    f.create_dataset('signal', data=signal, dtype=np.int8)

<|endoftext|>


<commit_before># Copyright 2018 Carlos Dauden - Tecnativa <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
    "name": "Sales commissions by pricelist",
    "version": "13.0.1.0.0",
    "author": "Tecnativa, " "Odoo Community Association (OCA)",
    "category": "Sales Management",
    "website": "https://github.com/OCA/commission",
    "license": "AGPL-3",
    "depends": ["sale_commission"],
    "data": ["views/product_pricelist_view.xml"],
    "installable": True,
}
<commit_msg>sale_commission_pricelist 13.0.1.1.0<commit_after># Copyright 2018 Carlos Dauden - Tecnativa <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
    "name": "Sales commissions by pricelist",
    "version": "13.0.1.1.0",
    "author": "Tecnativa, " "Odoo Community Association (OCA)",
    "category": "Sales Management",
    "website": "https://github.com/OCA/commission",
    "license": "AGPL-3",
    "depends": ["sale_commission"],
    "data": ["views/product_pricelist_view.xml"],
    "installable": True,
}
<|endoftext|>


<commit_before>"""
Provides a class that represents an adversarial example.

"""

import numpy as np
import numbers

from .distances import MSE

class Adversarial(object):
    """Defines an adversarial that should be found and stores the result.

    The :class:`Adversarial` class represents a single adversarial example
    for a given model, criterion and reference image. It can be passed to
    an adversarial attack to find the actual adversarial.

    Parameters
    ----------
    model : a :class:`Model` instance
        The model that should be fooled by the adversarial.
    criterion : a :class:`Criterion` instance
        The criterion that determines which images are adversarial.
    original_image : a :class:`numpy.ndarray`
        The original image to which the adversarial image should
        be as close as possible.
    original_class : int
        The ground-truth label of the original image.
    distance : a :class:`Distance` class
        The measure used to quantify similarity between images.

    """
    def __init__(
            self,
            model,
            criterion,
            original_image,
            original_class,
            distance=MSE,
            verbose=False):

        self.__model = model
        self.__criterion = criterion
        self.__original_image = original_image
        self.__original_image_for_distance = original_image
        self.__original_class = original_class
        self.__distance = distance
        self.verbose = verbose

        self.__best_adversarial = None
        self.__best_distance = distance(value=np.inf)

        self._total_prediction_calls = 0
        self._total_gradient_calls = 0

        self._best_prediction_calls = 0
        self._best_gradient_calls = 0

        # check if the original image is already adversarial
        self.predictions(original_image)

    def _reset(self):
        self.__best_adversarial = None
        self.__best_distance = self.__distance(value=np.inf)

        self._best_prediction_calls = 0
        self._best_gradient_calls = 0

        self.predictions(self.__original_image)

    @property
    def image(self):
        return self.__best_adversarial

    @property
    def distance(self):
        return self.__best_distance

    @property
    def original_image(self):
        return self.__original_image

    @property
    def original_class(self):
        return self.__original_class

    @property
    def _model(self):  # pragma: no cover
        """Should not be used."""
        return self.__model

    @property
    def _criterion(self):  # pragma: no cover
        """Should not be used."""
        return self.__criterion

    @property
    def _distance(self):  # pragma: no cover
        """Should not be used."""
        return self.__distance

    def set_distance_dtype(self, dtype):
        assert dtype >= self.__original_image.dtype
        self.__original_image_for_distance = self.__original_image.astype(
            dtype, copy=False)

    def reset_distance_dtype(self):
        self.__original_image_for_distance = self.__original_image

    def normalized_distance(self, image):
        """Calculates the distance of a given image to the
        original image.

        Parameters
        ----------
        image : `numpy.ndarray`
            The image that should be compared to the original image.

        Returns
        -------
        :class:`Distance`
            The distance between the given image and the original image.

        """
        return self.__distance(
            self.__original_image_for_distance,
            image,
            bounds=self.bounds())

    def __new_adversarial(self, image, in_bounds):
        distance = self.normalized_distance(image)
        if in_bounds and self.__best_distance > distance:
            # new best adversarial
            if self.verbose:
                print('new best adversarial: {}'.format(distance))

            self.__best_adversarial = image
            self.__best_distance = distance

            self._best_prediction_calls = self._total_prediction_calls
            self._best_gradient_calls = self._total_gradient_calls

            return True, distance
        return False, distance

    def __is_adversarial(self, image, predictions, in_bounds):
        """Interface to criterion.is_adverarial that calls
        __new_adversarial if necessary.

        Parameters
        ----------
        predictions : :class:`numpy.ndarray`
            A vector with the pre-softmax predictions for some image.
        label : int
            The label of the unperturbed reference image.

        """
        is_adversarial = self.__criterion.is_adversarial(
            predictions, self.__original_class)
        if is_adversarial:
            is_best, distance = self.__new_adversarial(image, in_bounds)
        else:
            is_best = False
            distance = None
        assert isinstance(is_adversarial, bool) or \
            isinstance(is_adversarial, np.bool_)
        return is_adversarial, is_best, distance

    def target_class(self):
        """Interface to criterion.target_class for attacks.

        """
        try:
            target_class = self.__criterion.target_class()
        except AttributeError:
            target_class = None
        return target_class

    def num_classes(self):
        n = self.__model.num_classes()
        assert isinstance(n, numbers.Number)
        return n

    def bounds(self):
        min_, max_ = self.__model.bounds()
        assert isinstance(min_, numbers.Number)
        assert isinstance(max_, numbers.Number)
        assert min_ < max_
        return min_, max_

    def in_bounds(self, input_):
        min_, max_ = self.bounds()
        return min_ <= input_.min() and input_.max() <= max_

    def channel_axis(self, batch):
        """Interface to model.channel_axis for attacks.

        Parameters
        ----------
        batch : bool
            Controls whether the index of the axis for a batch of images
            (4 dimensions) or a single image (3 dimensions) should be returned.

        """
        axis = self.__model.channel_axis()
        if not batch:
            axis = axis - 1
        return axis

    def has_gradient(self):
        """Returns true if _backward and _forward_backward can be called
        by an attack, False otherwise.

        """
        try:
            self.__model.gradient
            self.__model.predictions_and_gradient
        except AttributeError:
            return False
        else:
            return True

    def predictions(self, image, strict=True, return_details=False):
        """Interface to model.predictions for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        in_bounds = self.in_bounds(image)
        assert not strict or in_bounds

        self._total_prediction_calls += 1
        predictions = self.__model.predictions(image)
        is_adversarial, is_best, distance = self.__is_adversarial(
            image, predictions, in_bounds)

        assert predictions.ndim == 1
        if return_details:
            return predictions, is_adversarial, is_best, distance
        else:
            return predictions, is_adversarial

    def batch_predictions(
            self, images, greedy=False, strict=True, return_details=False):
        """Interface to model.batch_predictions for attacks.

        Parameters
        ----------
        images : `numpy.ndarray`
            Batch of images with shape (batch size, height, width, channels).
        greedy : bool
            Whether the first adversarial should be returned.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        if strict:
            in_bounds = self.in_bounds(images)
            assert in_bounds

        self._total_prediction_calls += len(images)
        predictions = self.__model.batch_predictions(images)

        assert predictions.ndim == 2
        assert predictions.shape[0] == images.shape[0]

        if return_details:
            assert greedy

        adversarials = []
        for i in range(len(predictions)):
            if strict:
                in_bounds_i = True
            else:
                in_bounds_i = self.in_bounds(images[i])
            is_adversarial, is_best, distance = self.__is_adversarial(
                images[i], predictions[i], in_bounds_i)
            if is_adversarial and greedy:
                if return_details:
                    return predictions, is_adversarial, i, is_best, distance
                else:
                    return predictions, is_adversarial, i
            adversarials.append(is_adversarial)

        if greedy:  # pragma: no cover
            # no adversarial found
            if return_details:
                return predictions, False, None, False, None
            else:
                return predictions, False, None

        is_adversarial = np.array(adversarials)
        assert is_adversarial.ndim == 1
        assert is_adversarial.shape[0] == images.shape[0]

        return predictions, is_adversarial

    def gradient(self, image=None, label=None, strict=True):
        """Interface to model.gradient for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
            Defaults to the original image.
        label : int
            Label used to calculate the loss that is differentiated.
            Defaults to the original label.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        assert self.has_gradient()

        if image is None:
            image = self.__original_image
        if label is None:
            label = self.__original_class

        assert not strict or self.in_bounds(image)

        self._total_gradient_calls += 1
        gradient = self.__model.gradient(image, label)

        assert gradient.shape == image.shape
        return gradient

    def predictions_and_gradient(
            self, image=None, label=None, strict=True, return_details=False):
        """Interface to model.predictions_and_gradient for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
            Defaults to the original image.
        label : int
            Label used to calculate the loss that is differentiated.
            Defaults to the original label.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        assert self.has_gradient()

        if image is None:
            image = self.__original_image
        if label is None:
            label = self.__original_class

        in_bounds = self.in_bounds(image)
        assert not strict or in_bounds

        self._total_prediction_calls += 1
        self._total_gradient_calls += 1
        predictions, gradient = self.__model.predictions_and_gradient(image, label)  # noqa: E501
        is_adversarial, is_best, distance = self.__is_adversarial(
            image, predictions, in_bounds)

        assert predictions.ndim == 1
        assert gradient.shape == image.shape
        if return_details:
            return predictions, gradient, is_adversarial, is_best, distance
        else:
            return predictions, gradient, is_adversarial

    def backward(self, gradient, image=None, strict=True):
        assert self.has_gradient()
        assert gradient.ndim == 1

        if image is None:
            image = self.__original_image

        assert not strict or self.in_bounds(image)

        self._total_gradient_calls += 1
        gradient = self.__model.backward(gradient, image)

        assert gradient.shape == image.shape
        return gradient
<commit_msg>keep copies instead of references to ensure consistency<commit_after>"""
Provides a class that represents an adversarial example.

"""

import numpy as np
import numbers

from .distances import MSE

class Adversarial(object):
    """Defines an adversarial that should be found and stores the result.

    The :class:`Adversarial` class represents a single adversarial example
    for a given model, criterion and reference image. It can be passed to
    an adversarial attack to find the actual adversarial.

    Parameters
    ----------
    model : a :class:`Model` instance
        The model that should be fooled by the adversarial.
    criterion : a :class:`Criterion` instance
        The criterion that determines which images are adversarial.
    original_image : a :class:`numpy.ndarray`
        The original image to which the adversarial image should
        be as close as possible.
    original_class : int
        The ground-truth label of the original image.
    distance : a :class:`Distance` class
        The measure used to quantify similarity between images.

    """
    def __init__(
            self,
            model,
            criterion,
            original_image,
            original_class,
            distance=MSE,
            verbose=False):

        self.__model = model
        self.__criterion = criterion
        self.__original_image = original_image
        self.__original_image_for_distance = original_image
        self.__original_class = original_class
        self.__distance = distance
        self.verbose = verbose

        self.__best_adversarial = None
        self.__best_distance = distance(value=np.inf)

        self._total_prediction_calls = 0
        self._total_gradient_calls = 0

        self._best_prediction_calls = 0
        self._best_gradient_calls = 0

        # check if the original image is already adversarial
        self.predictions(original_image)

    def _reset(self):
        self.__best_adversarial = None
        self.__best_distance = self.__distance(value=np.inf)

        self._best_prediction_calls = 0
        self._best_gradient_calls = 0

        self.predictions(self.__original_image)

    @property
    def image(self):
        return self.__best_adversarial

    @property
    def distance(self):
        return self.__best_distance

    @property
    def original_image(self):
        return self.__original_image

    @property
    def original_class(self):
        return self.__original_class

    @property
    def _model(self):  # pragma: no cover
        """Should not be used."""
        return self.__model

    @property
    def _criterion(self):  # pragma: no cover
        """Should not be used."""
        return self.__criterion

    @property
    def _distance(self):  # pragma: no cover
        """Should not be used."""
        return self.__distance

    def set_distance_dtype(self, dtype):
        assert dtype >= self.__original_image.dtype
        self.__original_image_for_distance = self.__original_image.astype(
            dtype, copy=False)

    def reset_distance_dtype(self):
        self.__original_image_for_distance = self.__original_image

    def normalized_distance(self, image):
        """Calculates the distance of a given image to the
        original image.

        Parameters
        ----------
        image : `numpy.ndarray`
            The image that should be compared to the original image.

        Returns
        -------
        :class:`Distance`
            The distance between the given image and the original image.

        """
        return self.__distance(
            self.__original_image_for_distance,
            image,
            bounds=self.bounds())

    def __new_adversarial(self, image, in_bounds):
        image = image.copy()  # to prevent inplace changes
        distance = self.normalized_distance(image)
        if in_bounds and self.__best_distance > distance:
            # new best adversarial
            if self.verbose:
                print('new best adversarial: {}'.format(distance))

            self.__best_adversarial = image
            self.__best_distance = distance

            self._best_prediction_calls = self._total_prediction_calls
            self._best_gradient_calls = self._total_gradient_calls

            return True, distance
        return False, distance

    def __is_adversarial(self, image, predictions, in_bounds):
        """Interface to criterion.is_adverarial that calls
        __new_adversarial if necessary.

        Parameters
        ----------
        predictions : :class:`numpy.ndarray`
            A vector with the pre-softmax predictions for some image.
        label : int
            The label of the unperturbed reference image.

        """
        is_adversarial = self.__criterion.is_adversarial(
            predictions, self.__original_class)
        if is_adversarial:
            is_best, distance = self.__new_adversarial(image, in_bounds)
        else:
            is_best = False
            distance = None
        assert isinstance(is_adversarial, bool) or \
            isinstance(is_adversarial, np.bool_)
        return is_adversarial, is_best, distance

    def target_class(self):
        """Interface to criterion.target_class for attacks.

        """
        try:
            target_class = self.__criterion.target_class()
        except AttributeError:
            target_class = None
        return target_class

    def num_classes(self):
        n = self.__model.num_classes()
        assert isinstance(n, numbers.Number)
        return n

    def bounds(self):
        min_, max_ = self.__model.bounds()
        assert isinstance(min_, numbers.Number)
        assert isinstance(max_, numbers.Number)
        assert min_ < max_
        return min_, max_

    def in_bounds(self, input_):
        min_, max_ = self.bounds()
        return min_ <= input_.min() and input_.max() <= max_

    def channel_axis(self, batch):
        """Interface to model.channel_axis for attacks.

        Parameters
        ----------
        batch : bool
            Controls whether the index of the axis for a batch of images
            (4 dimensions) or a single image (3 dimensions) should be returned.

        """
        axis = self.__model.channel_axis()
        if not batch:
            axis = axis - 1
        return axis

    def has_gradient(self):
        """Returns true if _backward and _forward_backward can be called
        by an attack, False otherwise.

        """
        try:
            self.__model.gradient
            self.__model.predictions_and_gradient
        except AttributeError:
            return False
        else:
            return True

    def predictions(self, image, strict=True, return_details=False):
        """Interface to model.predictions for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        in_bounds = self.in_bounds(image)
        assert not strict or in_bounds

        self._total_prediction_calls += 1
        predictions = self.__model.predictions(image)
        is_adversarial, is_best, distance = self.__is_adversarial(
            image, predictions, in_bounds)

        assert predictions.ndim == 1
        if return_details:
            return predictions, is_adversarial, is_best, distance
        else:
            return predictions, is_adversarial

    def batch_predictions(
            self, images, greedy=False, strict=True, return_details=False):
        """Interface to model.batch_predictions for attacks.

        Parameters
        ----------
        images : `numpy.ndarray`
            Batch of images with shape (batch size, height, width, channels).
        greedy : bool
            Whether the first adversarial should be returned.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        if strict:
            in_bounds = self.in_bounds(images)
            assert in_bounds

        self._total_prediction_calls += len(images)
        predictions = self.__model.batch_predictions(images)

        assert predictions.ndim == 2
        assert predictions.shape[0] == images.shape[0]

        if return_details:
            assert greedy

        adversarials = []
        for i in range(len(predictions)):
            if strict:
                in_bounds_i = True
            else:
                in_bounds_i = self.in_bounds(images[i])
            is_adversarial, is_best, distance = self.__is_adversarial(
                images[i], predictions[i], in_bounds_i)
            if is_adversarial and greedy:
                if return_details:
                    return predictions, is_adversarial, i, is_best, distance
                else:
                    return predictions, is_adversarial, i
            adversarials.append(is_adversarial)

        if greedy:  # pragma: no cover
            # no adversarial found
            if return_details:
                return predictions, False, None, False, None
            else:
                return predictions, False, None

        is_adversarial = np.array(adversarials)
        assert is_adversarial.ndim == 1
        assert is_adversarial.shape[0] == images.shape[0]

        return predictions, is_adversarial

    def gradient(self, image=None, label=None, strict=True):
        """Interface to model.gradient for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
            Defaults to the original image.
        label : int
            Label used to calculate the loss that is differentiated.
            Defaults to the original label.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        assert self.has_gradient()

        if image is None:
            image = self.__original_image
        if label is None:
            label = self.__original_class

        assert not strict or self.in_bounds(image)

        self._total_gradient_calls += 1
        gradient = self.__model.gradient(image, label)

        assert gradient.shape == image.shape
        return gradient

    def predictions_and_gradient(
            self, image=None, label=None, strict=True, return_details=False):
        """Interface to model.predictions_and_gradient for attacks.

        Parameters
        ----------
        image : `numpy.ndarray`
            Image with shape (height, width, channels).
            Defaults to the original image.
        label : int
            Label used to calculate the loss that is differentiated.
            Defaults to the original label.
        strict : bool
            Controls if the bounds for the pixel values should be checked.

        """
        assert self.has_gradient()

        if image is None:
            image = self.__original_image
        if label is None:
            label = self.__original_class

        in_bounds = self.in_bounds(image)
        assert not strict or in_bounds

        self._total_prediction_calls += 1
        self._total_gradient_calls += 1
        predictions, gradient = self.__model.predictions_and_gradient(image, label)  # noqa: E501
        is_adversarial, is_best, distance = self.__is_adversarial(
            image, predictions, in_bounds)

        assert predictions.ndim == 1
        assert gradient.shape == image.shape
        if return_details:
            return predictions, gradient, is_adversarial, is_best, distance
        else:
            return predictions, gradient, is_adversarial

    def backward(self, gradient, image=None, strict=True):
        assert self.has_gradient()
        assert gradient.ndim == 1

        if image is None:
            image = self.__original_image

        assert not strict or self.in_bounds(image)

        self._total_gradient_calls += 1
        gradient = self.__model.backward(gradient, image)

        assert gradient.shape == image.shape
        return gradient
<|endoftext|>


<commit_before>#!/usr/bin/python
#A script to add icons to an existing Openbox menu file
#This is untested and may not work at all as expected
#By Charles Bos

import sys
import os

def usage() :
    print('''Usage:
  obiconadder.py <path to menu file>''')

def getDotDesktop(item, identifier) :
    for x in dotDesktops :
        file = open(x, "r", encoding = "utf-8")
        fileText = file.read()
        file.close()
        idStart = fileText.find(identifier)
        idEnd = fileText.find("\n", idStart)
        if item == fileText[idStart + 5:idEnd] : return x
    #As a fallback position, try and match the execute line from the file with
    #the .desktop filename
    if identifier == "Exec=" :
        for x in dotDesktops :
            if item == x.split("/")[-1].split(".desktop")[0] : return x
    return None

def getIcon(dotDesktop) :
    file = open(dotDesktop, encoding = "utf-8")
    fileText = file.read()
    file.close()
    iconStart = fileText.find("Icon=")
    if iconStart != -1 :
        iconEnd = fileText.find("\n", iconStart)
        for x in iconsList :
            if fileText[iconStart + 5:iconEnd] == x.split("/")[-1].split(".")[0].split(" %")[0] :
                return x
        return None
    else : return None

def getIconTheme() :
    #Try and get the icon theme from ~/.gtkrc-2.0. If we cannot do this, try and
    #find the gnome-icon-theme instead.
    homeDir = os.path.expanduser('~')
    try :
        file = open(homeDir + "/.gtkrc-2.0", "r")
        fileText = file.read()
        file.close()
        contents = contents.split("\n")
        for x in contents :
            y = x.split("=")
            if y[0].strip() == "gtk-icon-theme-name" : theme = y[-1].strip().strip('"')
        if os.path.exists("/usr/share/icons/" + theme) : return theme
        elif os.path.exists("/usr/share/icons/gnome") : return "gnome"
        else : return None
    except IOError :
        if os.path.exists("/usr/share/icons/gnome") : return "gnome"
        else : return None

#Handle args
args = sys.argv
if (len(args) != 2) or (args[1] == '-h') or (args[1] == '--help') :
    usage()
    os._exit(0)
elif os.path.isfile(args[1]) : menuFile = args[1]
else :
    usage()
    os._exit(0)

#Get locations of icons and .desktops
iconDirs = ["/usr/share/pixmaps", "/usr/share/icons/hicolor/48x48"]
if getIconTheme() != None : iconDirs.append("/usr/share/icons/" + getIconTheme() + "/48x48")
iconsList = []
for x in iconDirs :
    for root, dirs, files in os.walk(x, topdown=False):
        for name in files:
            iconsList.append(os.path.join(root, name))
dotDesktops = os.listdir("/usr/share/applications")
for x in dotDesktops : dotDesktops[dotDesktops.index(x)] = "/usr/share/applications/" + x

#Start scanning menu file
file = open(menuFile, "r")
fileText = file.read()
file.close()
newFile = fileText[:]

#Get icons for applications
nameStart = fileText.find('<item label="')
nameEnd = fileText.find('">', nameStart)
while 0 <= nameStart <= len(fileText) :
    dotDesktop = getDotDesktop(fileText[nameStart + 13:nameEnd].split('" icon="')[0], "Name=")
    if dotDesktop != None : icon = getIcon(dotDesktop)
    else :
        #If identification by name fails, try by exec instead
        execStart = fileText.find("<execute>", nameEnd)
        execEnd = fileText.find("</execute>", execStart)
        dotDesktop = getDotDesktop(fileText[execStart + 9:execEnd], "Exec=")
        if dotDesktop != None : icon = getIcon(dotDesktop)
        else : icon = None
    if icon != None :
        newFile = newFile.replace(fileText[nameStart + 13:nameEnd], fileText[nameStart + 13:nameEnd].split('" icon="')[0] + '" icon="' + icon)
    nameStart = fileText.find('<item label="', nameEnd)
    nameEnd = fileText.find('">', nameStart)

#Get icons for categories
catStart = fileText.find('<menu id="')
catEnd = fileText.find('" ', catStart)
labelStart = fileText.find('label="', catEnd)
labelEnd = fileText.find('">', labelStart)
while 0 <= catStart <= len(fileText) :
    if getIconTheme() != None : icon = "/usr/share/icons/" + getIconTheme() + "/48x48/categories/applications-" + fileText[labelStart + 7:labelEnd].lower() + ".png"
    else : icon = None
    if (icon != None) and (os.path.isfile(icon)) :
        newFile = newFile.replace(fileText[catStart:labelStart - 1], fileText[catStart:catEnd + 1] + ' icon="' + icon + '"')
    catStart = fileText.find('<menu id="', labelEnd)
    catEnd = fileText.find('" ', catStart)
    labelStart = fileText.find('label="', catEnd)
    labelEnd = fileText.find('">', labelStart)

#Now add the icons
#This will replace the contents of the old file
file = open(menuFile, "w")
print(newFile.rstrip("\n"), file = file)
file.close()<commit_msg>obiconadder.py - fix variable names<commit_after>#!/usr/bin/python
#A script to add icons to an existing Openbox menu file
#This is untested and may not work at all as expected
#By Charles Bos

import sys
import os

def usage() :
    print('''Usage:
  obiconadder.py <path to menu file>''')

def getDotDesktop(item, identifier) :
    for x in dotDesktops :
        file = open(x, "r", encoding = "utf-8")
        fileText = file.read()
        file.close()
        idStart = fileText.find(identifier)
        idEnd = fileText.find("\n", idStart)
        if item == fileText[idStart + 5:idEnd] : return x
    #As a fallback position, try and match the execute line from the file with
    #the .desktop filename
    if identifier == "Exec=" :
        for x in dotDesktops :
            if item == x.split("/")[-1].split(".desktop")[0] : return x
    return None

def getIcon(dotDesktop) :
    file = open(dotDesktop, encoding = "utf-8")
    fileText = file.read()
    file.close()
    iconStart = fileText.find("Icon=")
    if iconStart != -1 :
        iconEnd = fileText.find("\n", iconStart)
        for x in iconsList :
            if fileText[iconStart + 5:iconEnd] == x.split("/")[-1].split(".")[0].split(" %")[0] :
                return x
        return None
    else : return None

def getIconTheme() :
    #Try and get the icon theme from ~/.gtkrc-2.0. If we cannot do this, try and
    #find the gnome-icon-theme instead.
    homeDir = os.path.expanduser('~')
    try :
        file = open(homeDir + "/.gtkrc-2.0", "r")
        fileText = file.read()
        file.close()
        fileText = fileText.split("\n")
        for x in fileText :
            y = x.split("=")
            if y[0].strip() == "gtk-icon-theme-name" : theme = y[-1].strip().strip('"')
        if os.path.exists("/usr/share/icons/" + theme) : return theme
        elif os.path.exists("/usr/share/icons/gnome") : return "gnome"
        else : return None
    except IOError :
        if os.path.exists("/usr/share/icons/gnome") : return "gnome"
        else : return None

#Handle args
args = sys.argv
if (len(args) != 2) or (args[1] == '-h') or (args[1] == '--help') :
    usage()
    os._exit(0)
elif os.path.isfile(args[1]) : menuFile = args[1]
else :
    usage()
    os._exit(0)

#Get locations of icons and .desktops
iconDirs = ["/usr/share/pixmaps", "/usr/share/icons/hicolor/48x48"]
if getIconTheme() != None : iconDirs.append("/usr/share/icons/" + getIconTheme() + "/48x48")
iconsList = []
for x in iconDirs :
    for root, dirs, files in os.walk(x, topdown=False):
        for name in files:
            iconsList.append(os.path.join(root, name))
dotDesktops = os.listdir("/usr/share/applications")
for x in dotDesktops : dotDesktops[dotDesktops.index(x)] = "/usr/share/applications/" + x

#Start scanning menu file
file = open(menuFile, "r")
fileText = file.read()
file.close()
newFile = fileText[:]

#Get icons for applications
nameStart = fileText.find('<item label="')
nameEnd = fileText.find('">', nameStart)
while 0 <= nameStart <= len(fileText) :
    dotDesktop = getDotDesktop(fileText[nameStart + 13:nameEnd].split('" icon="')[0], "Name=")
    if dotDesktop != None : icon = getIcon(dotDesktop)
    else :
        #If identification by name fails, try by exec instead
        execStart = fileText.find("<execute>", nameEnd)
        execEnd = fileText.find("</execute>", execStart)
        dotDesktop = getDotDesktop(fileText[execStart + 9:execEnd], "Exec=")
        if dotDesktop != None : icon = getIcon(dotDesktop)
        else : icon = None
    if icon != None :
        newFile = newFile.replace(fileText[nameStart + 13:nameEnd], fileText[nameStart + 13:nameEnd].split('" icon="')[0] + '" icon="' + icon)
    nameStart = fileText.find('<item label="', nameEnd)
    nameEnd = fileText.find('">', nameStart)

#Get icons for categories
catStart = fileText.find('<menu id="')
catEnd = fileText.find('" ', catStart)
labelStart = fileText.find('label="', catEnd)
labelEnd = fileText.find('">', labelStart)
while 0 <= catStart <= len(fileText) :
    if getIconTheme() != None : icon = "/usr/share/icons/" + getIconTheme() + "/48x48/categories/applications-" + fileText[labelStart + 7:labelEnd].lower() + ".png"
    else : icon = None
    if (icon != None) and (os.path.isfile(icon)) :
        newFile = newFile.replace(fileText[catStart:labelStart - 1], fileText[catStart:catEnd + 1] + ' icon="' + icon + '"')
    catStart = fileText.find('<menu id="', labelEnd)
    catEnd = fileText.find('" ', catStart)
    labelStart = fileText.find('label="', catEnd)
    labelEnd = fileText.find('">', labelStart)

#Now add the icons
#This will replace the contents of the old file
file = open(menuFile, "w")
print(newFile.rstrip("\n"), file = file)
file.close()<|endoftext|>


<commit_before>import binascii
import errno
import random
import subprocess
import sys
import os
import re
import socket
import argparse

import foomodules.Base as Base
import foomodules.utils as utils

class Say(Base.MessageHandler):
    def __init__(self, variableTo=False, **kwargs):
        super().__init__(**kwargs)
        self.variableTo = variableTo

    def __call__(self, msg, arguments, errorSink=None):
        if self.variableTo:
            try:
                to, mtype, body = arguments.split(" ", 2)
            except ValueError as err:
                raise ValueError("Too few arguments: {0}".format(str(err)))
        else:
            if msg["type"] == "groupchat":
                to = msg["from"].bare
            else:
                to = msg["from"]
            body = arguments
            mtype = None
        self.reply(msg, body, overrideTo=to, overrideMType=mtype)

class Fnord(Base.MessageHandler):
    fnordlist = [
        "Fnord ist verdampfter Kräutertee - ohne die Kräuter",
        "Fnord ist ein wirklich, wirklich hoher Berg",
        "Fnord ist der Ort wohin die Socken nach der Wäsche verschwinden",
        "Fnord ist das Gerät der Zahnärzte für schwierige Patienten",
        "Fnord ist der Eimer, wo sie die unbenutzen Serifen von Helvetica lagern",
        "Fnord ist das Echo der Stille",
        "Fnord ist Pacman ohne die Punkte",
        "Fnord ist eine Reihe von nervigen elektronischen Nachrichten",
        "Fnord ist das Yin ohne das Yang",
        "Fnord ist die Verkaufssteuer auf die Fröhlichkeit",
        "Fnord ist die Seriennummer auf deiner Cornflakes-Packung",
        "Fnord ist die Quelle aller Nullbits in deinem Computer",
        "Fnord ist der Grund, warum Lisp so viele Klammern hat",
        "Fnord ist weder ein Partikel noch eine Welle",
        "Fnord ist die kleinste Zahl grösser Null",
        "Fnord ist der Grund, warum Ärzte wollen, dass du hustest",
        "Fnord ist der unbenutzte Münzeinwurf am Spielautomaten",
        "Fnord ist der Klang einer einzelnen klatschenden Hand",
        "Fnord ist die Ignosekunde bevor du die Löschtaste im falschen Dokument drückst",
        "Fnord ist wenn du Nachts an der roten Ampel stehst",
        "Fnord ist das Gefühl in deinem Kopf, wenn du die Luft zu lange hältst",
        "Fnord ist die leeren Seiten am Ende deines Buches",
        "Fnord ist der kleine grüne Stein in deinem Schuh",
        "Fnord ist was du denkst wenn du nicht weisst was du denkst",
        "Fnord ist die Farbe die nur der Blinde sieht",
        "Fnord ist Morgens spät und Abends früh",
        "Fnord ist wo die Busse sich verstecken in der Nacht",
        "Fnord ist der Raum zwischen den Pixeln auf deinem Bildschirm",
        "Fnord ist das Pfeifen in deinem Ohr",
        "Fnord ist das pelzige Gefühl auf deinen Zähnen am nächsten Tag",
        "Fnord ist die Angst und ist die Erleichterung und ist die Angst",
        "Fnord schläft nie",
        "Fnord ist xand.",
    ]

    def __call__(self, msg, arguments, errorSink=None):
        if len(arguments.strip()) > 0:
            return
        self.reply(msg, random.choice(self.fnordlist))
        return True

class Host(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        proc = subprocess.Popen(
            ["host", arguments],
            stdout=subprocess.PIPE
        )
        output, _ = proc.communicate()
        output = output.decode().strip()

        self.reply(msg, output)

class Uptime(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        proc = subprocess.Popen(
            ["uptime"],
            stdout=subprocess.PIPE
        )
        output, _ = proc.communicate()
        output = output.decode().strip()

        self.reply(msg, output)

class Reload(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        self.xmpp.config.reload()

class REPL(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        import code
        namespace = dict(locals())
        namespace["xmpp"] = self.XMPP
        self.reply(msg, "Dropping into repl shell -- don't expect any further interaction until termination of shell access")
        code.InteractiveConsole(namespace).interact("REPL shell as requested")

class Respawn(Base.MessageHandler):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.argv = list(sys.argv)
        self.cwd = os.getcwd()

    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        print("disconnecting for respawn")
        self.XMPP.disconnect(reconnect=False, wait=True)
        print("preparing and running execv")
        os.chdir(self.cwd)
        os.execv(self.argv[0], self.argv)

class Peek(Base.ArgparseCommand):
    def __init__(self, timeout=3, command_name="peek", maxlen=256, **kwargs):
        super().__init__(command_name, **kwargs)
        self.timeout = timeout
        self.maxlen = maxlen
        self.argparse.add_argument(
            "-u", "--udp",
            action="store_true",
            dest="udp",
            default=False,
            help="Use UDP instead of TCP",
        )
        self.argparse.add_argument(
            "-6", "--ipv6",
            action="store_true",
            dest="ipv6",
            default=False,
            help="Use IPv6 sockets to connect to target"
        )
        self.argparse.add_argument(
            "host",
            help="Host or IP to connect to"
        )
        self.argparse.add_argument(
            "port",
            type=int,
            help="TCP/UDP port to connect to"
        )

    def recvline(self, sock):
        buf = b""
        while b"\n" not in buf and len(buf) < self.maxlen:
            try:
                data = sock.recv(1024)
                if len(data) == 0:
                    break  # this should not happen in non-blocking mode, but...
                buf += data
            except socket.error as err:
                if err.errno == errno.EAGAIN:
                    print("EAGAIN")
                    break
                raise
        return buf.split(b"\n", 1)[0]

    def _call(self, msg, args, errorSink=None):
        fam = socket.AF_INET6 if args.ipv6 else socket.AF_INET
        typ = socket.SOCK_DGRAM if args.udp else socket.SOCK_STREAM
        sock = socket.socket(fam, typ, 0)
        sock.settimeout(self.timeout)
        try:
            sock.connect((args.host, args.port))
        except socket.error as err:
            self.reply(msg, "connect error: {0!s}".format(err))
            return
        try:
            try:
                buf = self.recvline(sock)
            except socket.timeout as err:
                self.reply(msg, "error: didn't receive any data in time")
                return
        finally:
            sock.close()

        if not buf:
            self.reply(msg, "error: nothing received before first newline")
            return

        try:
            reply = buf.decode("utf-8").strip()
            if utils.evil_string(reply):
                reply = None
        except UnicodeDecodeError as err:
            reply = None

        if reply is None:
            reply = "hexdump: {0}".format(binascii.b2a_hex(buf).decode("ascii"))
        else:
            reply = "{host}:{port} says: {0}".format(reply, host=args.host,
                port=args.port)

        self.reply(msg, reply)

class Ping(Base.ArgparseCommand):
    packetline = re.compile("([0-9]+) packets transmitted, ([0-9]+) received(.*), ([0-9]+)% packet loss, time ([0-9]+)ms")
    rttline = re.compile("rtt min/avg/max/mdev = (([0-9.]+/){3}([0-9.]+)) ms")

    def __init__(self, count=4, interval=0.5, command_name="ping", **kwargs):
        super().__init__(command_name, **kwargs)
        self.argparse.add_argument(
            "-6", "--ipv6",
            action="store_true",
            dest="ipv6",
            default=False,
            help="Use ping6 instead of ping"
        )
        self.argparse.add_argument(
            "--alot",
            action="store_true",
            dest="alot",
            help="Send more pings"
        )
        self.argparse.add_argument(
            "host",
            help="Host which is to be pinged"
        )
        self.pingargs = [
            "-q",
            "-i{0:f}".format(interval)
        ]

    def _call(self, msg, args, errorSink=None):
        pingcmd = ["ping6" if args.ipv6 else "ping"]
        if args.alot:
            count = 20
        else:
            count = 5
        pingcmd.append("-c{0:d}".format(count))
        proc = subprocess.Popen(
            pingcmd + self.pingargs + [args.host],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE
        )
        out, err = proc.communicate()
        if proc.wait() != 0:
            message = err.decode().strip()
            if not message:
                self.reply(msg, "unknown error, timeout/blocked?")
            else:
                self.reply(msg, "error: {0}".format(message))
        else:
            lines = out.decode().strip().split("\n")
            packetinfo = self.packetline.match(lines[3])
            rttinfo = self.rttline.match(lines[4])
            if not packetinfo or not rttinfo:
                self.reply(msg, "unknown error, unable to parse ping output, dumping to stdout")
                print(out.decode())
            else:
                packetinfo = packetinfo.groups()
                rttinfo = rttinfo.group(1).split("/")
                try:
                    message = "{host}: {sent}/{recv} pckts., {loss}% loss, rtt ↓/-/↑/↕ = {rttmin}/{rttavg}/{rttmax}/{rttmdev}, time {time}ms".format(
                        host=args.host,
                        sent=int(packetinfo[0]),
                        recv=int(packetinfo[1]),
                        loss=int(packetinfo[3]),
                        rttmin=rttinfo[0],
                        rttavg=rttinfo[1],
                        rttmax=rttinfo[2],
                        rttmdev=rttinfo[3],
                        time=int(packetinfo[4])
                    )
                except ValueError:
                    self.reply(msg, "malformatted ping output, dumping to stdout")
                    print(out.decode())
                    return
                self.reply(
                    msg,
                    message
                )

class Roll(Base.MessageHandler):
    rollex_base = "([0-9]*)[dW]([0-9]+)"
    rollex_all = re.compile("^(({0}\s+)*{0})(\s+(each\s+)?\w+\s+([0-9]+))?\s*$".format(rollex_base), re.I)
    rollex = re.compile(rollex_base, re.I)

    def _too_much(self, msg):
        self.reply(msg, "yeah, right, I'll go and rob a dice factory")

    def __call__(self, msg, arguments, errorSink=None):
        matched = self.rollex_all.match(arguments)
        if not matched:
            self.reply(msg, "usage: XdY rolls a dY X times")
            return

        results = []
        die = matched.group(1)
        for match in self.rollex.finditer(die):
            if len(results) > 4000:
                self._too_much()
                return
            count, dice = match.groups()
            count = int(count) if count else 1
            dice = int(dice)
            if count < 1:
                self.reply(msg, "thats not a reasonable count: {}".format(count))
                return
            if dice <= 1:
                self.reply(msg, "thats not a reasonable die: {}".format(dice))
                return
            if count > 1000 or len(results) > 1000:
                self._too_much(msg)
                return
            results.extend(random.randint(1, dice) for i in range(count))

        against = matched.group(9)
        each = matched.group(8)
        suffix = ""
        print(repr(against))
        if against:
            against = int(against)
            if against >= sum(results):
                suffix = ": passed"
            else:
                suffix = ": failed"

        self.reply(msg, "results: {}, sum = {}{}".format(
            " ".join("{}".format(result) for result in results),
            sum(results),
            suffix
        ))

class Dig(Base.ArgparseCommand):
    def __init__(self, command_name="dig", **kwargs):
        super().__init__(command_name, **kwargs)
        self.argparse.add_argument(
            "-s", "--server", "--at",
            default=None,
            help="Server to ask for the record",
            dest="at"
        )
        self.argparse.add_argument(
            "kind",
            metavar="RECTYPE",
            nargs="?",
            default=None,
            type=lambda x: x.upper(),
            choices=["SRV", "A", "AAAA", "CNAME", "MX"],
            help="Record kind to ask for"
        )
        self.argparse.add_argument(
            "name",
            metavar="NAME",
            help="Record name to look up"
        )

    def _call(self, msg, args, errorSink=None):
        userargs = [args.name]
        kindstr = ""
        if args.kind is not None:
            kindstr = " ({})".format(args.kind)
            userargs.insert(0, args.kind)
        atstr = ""
        if args.at is not None:
            atstr = "@"+args.at
            userargs.append(atstr)

        call = ["dig", "+time=2", "+short"] + userargs

        proc = subprocess.Popen(
            call,
            stdout=subprocess.PIPE
        )
        stdout, _ = proc.communicate()
        if proc.wait() != 0:
            self.reply(msg, stdout.decode().strip(";").strip())
            return

        results = list(filter(bool, stdout.decode().strip().split("\n")))

        if results:
            resultstr = ", ".join(results)
        else:
            resultstr = "no records"
        self.reply(msg, "{host}{at}{kind}: {results}".format(
            host=args.name,
            at=atstr,
            kind=kindstr,
            results=resultstr
        ))
<commit_msg>Good point, rené $$<commit_after>import binascii
import errno
import random
import subprocess
import sys
import os
import re
import socket
import argparse

import foomodules.Base as Base
import foomodules.utils as utils

class Say(Base.MessageHandler):
    def __init__(self, variableTo=False, **kwargs):
        super().__init__(**kwargs)
        self.variableTo = variableTo

    def __call__(self, msg, arguments, errorSink=None):
        if self.variableTo:
            try:
                to, mtype, body = arguments.split(" ", 2)
            except ValueError as err:
                raise ValueError("Too few arguments: {0}".format(str(err)))
        else:
            if msg["type"] == "groupchat":
                to = msg["from"].bare
            else:
                to = msg["from"]
            body = arguments
            mtype = None
        self.reply(msg, body, overrideTo=to, overrideMType=mtype)

class Fnord(Base.MessageHandler):
    fnordlist = [
        "Fnord ist verdampfter Kräutertee - ohne die Kräuter",
        "Fnord ist ein wirklich, wirklich hoher Berg",
        "Fnord ist der Ort wohin die Socken nach der Wäsche verschwinden",
        "Fnord ist das Gerät der Zahnärzte für schwierige Patienten",
        "Fnord ist der Eimer, wo sie die unbenutzen Serifen von Helvetica lagern",
        "Fnord ist das Echo der Stille",
        "Fnord ist Pacman ohne die Punkte",
        "Fnord ist eine Reihe von nervigen elektronischen Nachrichten",
        "Fnord ist das Yin ohne das Yang",
        "Fnord ist die Verkaufssteuer auf die Fröhlichkeit",
        "Fnord ist die Seriennummer auf deiner Cornflakes-Packung",
        "Fnord ist die Quelle aller Nullbits in deinem Computer",
        "Fnord ist der Grund, warum Lisp so viele Klammern hat",
        "Fnord ist weder ein Partikel noch eine Welle",
        "Fnord ist die kleinste Zahl grösser Null",
        "Fnord ist der Grund, warum Ärzte wollen, dass du hustest",
        "Fnord ist der unbenutzte Münzeinwurf am Spielautomaten",
        "Fnord ist der Klang einer einzelnen klatschenden Hand",
        "Fnord ist die Ignosekunde bevor du die Löschtaste im falschen Dokument drückst",
        "Fnord ist wenn du Nachts an der roten Ampel stehst",
        "Fnord ist das Gefühl in deinem Kopf, wenn du die Luft zu lange hältst",
        "Fnord ist die leeren Seiten am Ende deines Buches",
        "Fnord ist der kleine grüne Stein in deinem Schuh",
        "Fnord ist was du denkst wenn du nicht weisst was du denkst",
        "Fnord ist die Farbe die nur der Blinde sieht",
        "Fnord ist Morgens spät und Abends früh",
        "Fnord ist wo die Busse sich verstecken in der Nacht",
        "Fnord ist der Raum zwischen den Pixeln auf deinem Bildschirm",
        "Fnord ist das Pfeifen in deinem Ohr",
        "Fnord ist das pelzige Gefühl auf deinen Zähnen am nächsten Tag",
        "Fnord ist die Angst und ist die Erleichterung und ist die Angst",
        "Fnord schläft nie",
        "Fnord ist xand.",
    ]

    def __call__(self, msg, arguments, errorSink=None):
        if len(arguments.strip()) > 0:
            return
        self.reply(msg, random.choice(self.fnordlist))
        return True

class Host(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        proc = subprocess.Popen(
            ["host", arguments],
            stdout=subprocess.PIPE
        )
        output, _ = proc.communicate()
        output = output.decode().strip()

        self.reply(msg, output)

class Uptime(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        proc = subprocess.Popen(
            ["uptime"],
            stdout=subprocess.PIPE
        )
        output, _ = proc.communicate()
        output = output.decode().strip()

        self.reply(msg, output)

class Reload(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        self.xmpp.config.reload()

class REPL(Base.MessageHandler):
    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        import code
        namespace = dict(locals())
        namespace["xmpp"] = self.XMPP
        self.reply(msg, "Dropping into repl shell -- don't expect any further interaction until termination of shell access")
        code.InteractiveConsole(namespace).interact("REPL shell as requested")

class Respawn(Base.MessageHandler):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.argv = list(sys.argv)
        self.cwd = os.getcwd()

    def __call__(self, msg, arguments, errorSink=None):
        if arguments.strip():
            return
        print("disconnecting for respawn")
        self.XMPP.disconnect(reconnect=False, wait=True)
        print("preparing and running execv")
        os.chdir(self.cwd)
        os.execv(self.argv[0], self.argv)

class Peek(Base.ArgparseCommand):
    def __init__(self, timeout=3, command_name="peek", maxlen=256, **kwargs):
        super().__init__(command_name, **kwargs)
        self.timeout = timeout
        self.maxlen = maxlen
        self.argparse.add_argument(
            "-u", "--udp",
            action="store_true",
            dest="udp",
            default=False,
            help="Use UDP instead of TCP",
        )
        self.argparse.add_argument(
            "-6", "--ipv6",
            action="store_true",
            dest="ipv6",
            default=False,
            help="Use IPv6 sockets to connect to target"
        )
        self.argparse.add_argument(
            "host",
            help="Host or IP to connect to"
        )
        self.argparse.add_argument(
            "port",
            type=int,
            help="TCP/UDP port to connect to"
        )

    def recvline(self, sock):
        buf = b""
        while b"\n" not in buf and len(buf) < self.maxlen:
            try:
                data = sock.recv(1024)
                if len(data) == 0:
                    break  # this should not happen in non-blocking mode, but...
                buf += data
            except socket.error as err:
                if err.errno == errno.EAGAIN:
                    print("EAGAIN")
                    break
                raise
        return buf.split(b"\n", 1)[0]

    def _call(self, msg, args, errorSink=None):
        fam = socket.AF_INET6 if args.ipv6 else socket.AF_INET
        typ = socket.SOCK_DGRAM if args.udp else socket.SOCK_STREAM
        sock = socket.socket(fam, typ, 0)
        sock.settimeout(self.timeout)
        try:
            sock.connect((args.host, args.port))
        except socket.error as err:
            self.reply(msg, "connect error: {0!s}".format(err))
            return
        try:
            try:
                buf = self.recvline(sock)
            except socket.timeout as err:
                self.reply(msg, "error: didn't receive any data in time")
                return
        finally:
            sock.close()

        if not buf:
            self.reply(msg, "error: nothing received before first newline")
            return

        try:
            reply = buf.decode("utf-8").strip()
            if utils.evil_string(reply):
                reply = None
        except UnicodeDecodeError as err:
            reply = None

        if reply is None:
            reply = "hexdump: {0}".format(binascii.b2a_hex(buf).decode("ascii"))
        else:
            reply = "{host}:{port} says: {0}".format(reply, host=args.host,
                port=args.port)

        self.reply(msg, reply)

class Ping(Base.ArgparseCommand):
    packetline = re.compile("([0-9]+) packets transmitted, ([0-9]+) received(.*), ([0-9]+)% packet loss, time ([0-9]+)ms")
    rttline = re.compile("rtt min/avg/max/mdev = (([0-9.]+/){3}([0-9.]+)) ms")

    def __init__(self, count=4, interval=0.5, command_name="ping", **kwargs):
        super().__init__(command_name, **kwargs)
        self.argparse.add_argument(
            "-6", "--ipv6",
            action="store_true",
            dest="ipv6",
            default=False,
            help="Use ping6 instead of ping"
        )
        self.argparse.add_argument(
            "--alot",
            action="store_true",
            dest="alot",
            help="Send more pings"
        )
        self.argparse.add_argument(
            "host",
            help="Host which is to be pinged"
        )
        self.pingargs = [
            "-q",
            "-i{0:f}".format(interval)
        ]

    def _call(self, msg, args, errorSink=None):
        pingcmd = ["ping6" if args.ipv6 else "ping"]
        if args.alot:
            count = 20
        else:
            count = 5
        pingcmd.append("-c{0:d}".format(count))
        proc = subprocess.Popen(
            pingcmd + self.pingargs + [args.host],
            stderr=subprocess.PIPE,
            stdout=subprocess.PIPE
        )
        out, err = proc.communicate()
        if proc.wait() != 0:
            message = err.decode().strip()
            if not message:
                self.reply(msg, "unknown error, timeout/blocked?")
            else:
                self.reply(msg, "error: {0}".format(message))
        else:
            lines = out.decode().strip().split("\n")
            packetinfo = self.packetline.match(lines[3])
            rttinfo = self.rttline.match(lines[4])
            if not packetinfo or not rttinfo:
                self.reply(msg, "unknown error, unable to parse ping output, dumping to stdout")
                print(out.decode())
            else:
                packetinfo = packetinfo.groups()
                rttinfo = rttinfo.group(1).split("/")
                try:
                    message = "{host}: {sent}/{recv} pckts., {loss}% loss, rtt ↓/-/↑/↕ = {rttmin}/{rttavg}/{rttmax}/{rttmdev}, time {time}ms".format(
                        host=args.host,
                        sent=int(packetinfo[0]),
                        recv=int(packetinfo[1]),
                        loss=int(packetinfo[3]),
                        rttmin=rttinfo[0],
                        rttavg=rttinfo[1],
                        rttmax=rttinfo[2],
                        rttmdev=rttinfo[3],
                        time=int(packetinfo[4])
                    )
                except ValueError:
                    self.reply(msg, "malformatted ping output, dumping to stdout")
                    print(out.decode())
                    return
                self.reply(
                    msg,
                    message
                )

class Roll(Base.MessageHandler):
    rollex_base = "([0-9]*)[dW]([0-9]+)"
    rollex_all = re.compile("^(({0}\s+)*{0})(\s+(each\s+)?\w+\s+([0-9]+))?\s*$".format(rollex_base), re.I)
    rollex = re.compile(rollex_base, re.I)

    def _too_much(self, msg):
        self.reply(msg, "yeah, right, I'll go and rob a die factory")

    def __call__(self, msg, arguments, errorSink=None):
        matched = self.rollex_all.match(arguments)
        if not matched:
            self.reply(msg, "usage: XdY rolls a dY X times")
            return

        results = []
        die = matched.group(1)
        for match in self.rollex.finditer(die):
            if len(results) > 4000:
                self._too_much()
                return
            count, dice = match.groups()
            count = int(count) if count else 1
            dice = int(dice)
            if count < 1:
                self.reply(msg, "thats not a reasonable count: {}".format(count))
                return
            if dice <= 1:
                self.reply(msg, "thats not a reasonable die: {}".format(dice))
                return
            if count > 1000 or len(results) > 1000:
                self._too_much(msg)
                return
            results.extend(random.randint(1, dice) for i in range(count))

        against = matched.group(9)
        each = matched.group(8)
        suffix = ""
        print(repr(against))
        if against:
            against = int(against)
            if against >= sum(results):
                suffix = ": passed"
            else:
                suffix = ": failed"

        self.reply(msg, "results: {}, sum = {}{}".format(
            " ".join("{}".format(result) for result in results),
            sum(results),
            suffix
        ))

class Dig(Base.ArgparseCommand):
    def __init__(self, command_name="dig", **kwargs):
        super().__init__(command_name, **kwargs)
        self.argparse.add_argument(
            "-s", "--server", "--at",
            default=None,
            help="Server to ask for the record",
            dest="at"
        )
        self.argparse.add_argument(
            "kind",
            metavar="RECTYPE",
            nargs="?",
            default=None,
            type=lambda x: x.upper(),
            choices=["SRV", "A", "AAAA", "CNAME", "MX"],
            help="Record kind to ask for"
        )
        self.argparse.add_argument(
            "name",
            metavar="NAME",
            help="Record name to look up"
        )

    def _call(self, msg, args, errorSink=None):
        userargs = [args.name]
        kindstr = ""
        if args.kind is not None:
            kindstr = " ({})".format(args.kind)
            userargs.insert(0, args.kind)
        atstr = ""
        if args.at is not None:
            atstr = "@"+args.at
            userargs.append(atstr)

        call = ["dig", "+time=2", "+short"] + userargs

        proc = subprocess.Popen(
            call,
            stdout=subprocess.PIPE
        )
        stdout, _ = proc.communicate()
        if proc.wait() != 0:
            self.reply(msg, stdout.decode().strip(";").strip())
            return

        results = list(filter(bool, stdout.decode().strip().split("\n")))

        if results:
            resultstr = ", ".join(results)
        else:
            resultstr = "no records"
        self.reply(msg, "{host}{at}{kind}: {results}".format(
            host=args.name,
            at=atstr,
            kind=kindstr,
            results=resultstr
        ))
<|endoftext|>