<commit_before>import sys
import random
import configparser
import entities.enemies as enemies
import entities.npc as npc

class MapTile:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.visited = 0
        self.type = ''

    def intro_text(self):
        raise NotImplementedError("Create a subclass instead!")

    def modify_player(self, player):
        pass

class StartTile(MapTile):
    def intro_text(self):
        print("LEVEL 1: The Cave")
        return """
        You find yourself in a cave with a flickering torch on the wall.
        You can make out four paths, each equally as dark and foreboding.
        """

class BoringTile(MapTile):
    def intro_text(self):
        return """
        This is a very boring part of the cave. Fuck all happens here
        """

class VictoryTile(MapTile):
    def modify_player(self, player):
        player.victory = True

    def intro_text(self):
        return """
        You see a bright light in the distance...
        ... it grows as you get closer! It's sunlight!

        Victory is yours!
        """

class EnemyTile(MapTile):
    def __init__(self, x, y):
        encounter_type = random.random()

        if encounter_type < 0.50:
            self.enemy = enemies.GiantSpider()
            self.alive_text = "\nA giant spider jumps down from " \
                              "its web and lands right in front " \
                              "of you!"
            self.dead_text = "\nThe lifeless corpse of the spider " \
                             "slumps in the corner. Creepy."
        elif encounter_type < 0.80:
            self.enemy = enemies.Ogre()
            self.alive_text = "\nA ogre blocks your path!"
            self.dead_text = "\nThe oger died convinietly off of " \
                             "the path, out of the way."
        elif encounter_type < 0.95:
            self.enemy = enemies.BatColony()
            self.alive_text = "\nBats. Eeshk..."
            self.dead_text = "\nThe furry bastards are dead"
        else:
            self.enemy = enemies.RockMonster()
            self.alive_text = "\nIs it a bird? Is it a plane? no " \
                              "it's a rock monster!"
            self.dead_text = "\nYou killed a rock. " \
                             "Now thats dedication!!"

        super().__init__(x, y)

    def intro_text(self):
        if self.enemy.is_alive():
            return self.alive_text
        else:
            return self.dead_text

    def modify_player(self, player):
        if self.enemy.is_alive():
            player.hp = player.hp - self.enemy.damage
            print("Enemy does {} damage. You have {} HP remaining."
                  .format(self.enemy.damage, player.hp))

class TraderTile(MapTile):
    def __init__(self, x, y):
        self.trader = npc.Trader()
        super().__init__(x, y)

    def trade(self, buyer, seller):
        for i, item in enumerate(seller.inventory, 1):
            print("{}. {} - {} Gold".format(i, item.name, item.value))

        while True:
            user_input = input("\nChoose an item or press Q to exit: ")

            if user_input in ['Q', 'q']:
                return
            else:
                try:
                    choice = int(user_input)
                    to_swap = seller.inventory[choice - 1]
                    self.swap(seller, buyer, to_swap)
                except ValueError:
                    print("Invalid choice!")

    def swap(self, seller, buyer, item):
        if item.value > buyer.gold:
            print("That's too expensive")
            return

        seller.inventory.remove(item)
        buyer.inventory.append(item)
        seller.gold = seller.gold + item.value
        buyer.gold = buyer.gold - item.value
        print("Trade complete!")

    def check_if_trade(self, player):
        while True:
            print("Would you like to (B)uy, (S)ell, or (Q)uit?")
            user_input = input()

            if user_input in ['Q', 'q']:
                return
            elif user_input in ['B', 'b']:
                print("Here's whats available to buy:\n")
                self.trade(buyer=player, seller=self.trader)
            elif user_input in ['S', 's']:
                print("Here's whats available to sell:\n")
                self.trade(buyer=self.trader, seller=player)
            else:
                print("Invalid choice!")

    def intro_text(self):
        return """
        A frail not-quite-human, not-quite-creature squats in the corner
        clinking his gold coins together. He looks willing to trade.
        """

class FindGoldTile(MapTile):
    def __init__(self, x, y):
        self.gold = random.randint(1, 50)
        self.gold_claimed = False
        super().__init__(x, y)

    def modify_player(self, player):
        if not self.gold_claimed:
            self.gold_claimed = True
            player.gold = player.gold + self.gold
            print("+{} gold added.".format(self.gold))

    def intro_text(self):
        if self.gold_claimed:
            return """
            Another unremarkable part of the cave. You must forge onwards.
            """
        else:
            return """
            Someone dropped some gold. You pick it up.
            """

world_map = []

start_tile_location = None

tile_type_dict = {"VT": VictoryTile,
                  "EN": EnemyTile,
                  "ST": StartTile,
                  "NA": BoringTile,
                  "FG": FindGoldTile,
                  "TT": TraderTile,
                  "  ": None}

def is_dsl_valid(dsl):
    if dsl.count("|ST|") != 1:
        return False

    if dsl.count("|VT|") == 0:
        return False

    lines = dsl.splitlines()
    lines = [l for l in lines if l]
    pipe_counts = [line.count("|") for line in lines]

    for count in pipe_counts:
        if count != pipe_counts[0]:
            return False

    return True

def parse_world_dsl(map_file):
    level_map = open(map_file, 'r').read()

    if not is_dsl_valid(level_map):
        sys.exit("Rumtime error: unable to parse map file")

    dsl_lines = level_map.splitlines()
    dsl_lines = [x for x in dsl_lines if x]

    for y, dsl_row in enumerate(dsl_lines):
        row = []
        dsl_cells = dsl_row.split("|")
        dsl_cells = [c for c in dsl_cells if c]

        for x, dsl_cell in enumerate(dsl_cells):
            if dsl_cell not in tile_type_dict:
                sys.exit("Map parse error: Invalid room type in map")
                break

            tile_type = tile_type_dict[dsl_cell]
            if tile_type == StartTile:
                global start_tile_location
                start_tile_location = x, y
            row.append(tile_type(x, y) if tile_type else None)

        world_map.append(row)

def tile_at(x, y):
    if x < 0 or y < 0:
        return None

    try:
        return world_map[y][x]
    except IndexError:
        return None
<commit_msg>Made script exit when victory tile reached<commit_after>import sys
import random
import configparser
import entities.enemies as enemies
import entities.npc as npc

class MapTile:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.visited = 0
        self.type = ''

    def intro_text(self):
        raise NotImplementedError("Create a subclass instead!")

    def modify_player(self, player):
        pass

class StartTile(MapTile):
    def intro_text(self):
        print("LEVEL 1: The Cave")
        return """
        You find yourself in a cave with a flickering torch on the wall.
        You can make out four paths, each equally as dark and foreboding.
        """

class BoringTile(MapTile):
    def intro_text(self):
        return """
        This is a very boring part of the cave. Fuck all happens here
        """

class VictoryTile(MapTile):
    def modify_player(self, player):
        player.victory = True
        exit()

    def intro_text(self):
        return """
        You see a bright light in the distance...
        ... it grows as you get closer! It's sunlight!

        Victory is yours!
        """

class EnemyTile(MapTile):
    def __init__(self, x, y):
        encounter_type = random.random()

        if encounter_type < 0.50:
            self.enemy = enemies.GiantSpider()
            self.alive_text = "\nA giant spider jumps down from " \
                              "its web and lands right in front " \
                              "of you!"
            self.dead_text = "\nThe lifeless corpse of the spider " \
                             "slumps in the corner. Creepy."
        elif encounter_type < 0.80:
            self.enemy = enemies.Ogre()
            self.alive_text = "\nA ogre blocks your path!"
            self.dead_text = "\nThe oger died convinietly off of " \
                             "the path, out of the way."
        elif encounter_type < 0.95:
            self.enemy = enemies.BatColony()
            self.alive_text = "\nBats. Eeshk..."
            self.dead_text = "\nThe furry bastards are dead"
        else:
            self.enemy = enemies.RockMonster()
            self.alive_text = "\nIs it a bird? Is it a plane? no " \
                              "it's a rock monster!"
            self.dead_text = "\nYou killed a rock. " \
                             "Now thats dedication!!"

        super().__init__(x, y)

    def intro_text(self):
        if self.enemy.is_alive():
            return self.alive_text
        else:
            return self.dead_text

    def modify_player(self, player):
        if self.enemy.is_alive():
            player.hp = player.hp - self.enemy.damage
            print("Enemy does {} damage. You have {} HP remaining."
                  .format(self.enemy.damage, player.hp))

class TraderTile(MapTile):
    def __init__(self, x, y):
        self.trader = npc.Trader()
        super().__init__(x, y)

    def trade(self, buyer, seller):
        for i, item in enumerate(seller.inventory, 1):
            print("{}. {} - {} Gold".format(i, item.name, item.value))

        while True:
            user_input = input("\nChoose an item or press Q to exit: ")

            if user_input in ['Q', 'q']:
                return
            else:
                try:
                    choice = int(user_input)
                    to_swap = seller.inventory[choice - 1]
                    self.swap(seller, buyer, to_swap)
                except ValueError:
                    print("Invalid choice!")

    def swap(self, seller, buyer, item):
        if item.value > buyer.gold:
            print("That's too expensive")
            return

        seller.inventory.remove(item)
        buyer.inventory.append(item)
        seller.gold = seller.gold + item.value
        buyer.gold = buyer.gold - item.value
        print("Trade complete!")

    def check_if_trade(self, player):
        while True:
            print("Would you like to (B)uy, (S)ell, or (Q)uit?")
            user_input = input()

            if user_input in ['Q', 'q']:
                return
            elif user_input in ['B', 'b']:
                print("Here's whats available to buy:\n")
                self.trade(buyer=player, seller=self.trader)
            elif user_input in ['S', 's']:
                print("Here's whats available to sell:\n")
                self.trade(buyer=self.trader, seller=player)
            else:
                print("Invalid choice!")

    def intro_text(self):
        return """
        A frail not-quite-human, not-quite-creature squats in the corner
        clinking his gold coins together. He looks willing to trade.
        """

class FindGoldTile(MapTile):
    def __init__(self, x, y):
        self.gold = random.randint(1, 50)
        self.gold_claimed = False
        super().__init__(x, y)

    def modify_player(self, player):
        if not self.gold_claimed:
            self.gold_claimed = True
            player.gold = player.gold + self.gold
            print("+{} gold added.".format(self.gold))

    def intro_text(self):
        if self.gold_claimed:
            return """
            Another unremarkable part of the cave. You must forge onwards.
            """
        else:
            return """
            Someone dropped some gold. You pick it up.
            """

world_map = []

start_tile_location = None

tile_type_dict = {"VT": VictoryTile,
                  "EN": EnemyTile,
                  "ST": StartTile,
                  "NA": BoringTile,
                  "FG": FindGoldTile,
                  "TT": TraderTile,
                  "  ": None}

def is_dsl_valid(dsl):
    if dsl.count("|ST|") != 1:
        return False

    if dsl.count("|VT|") == 0:
        return False

    lines = dsl.splitlines()
    lines = [l for l in lines if l]
    pipe_counts = [line.count("|") for line in lines]

    for count in pipe_counts:
        if count != pipe_counts[0]:
            return False

    return True

def parse_world_dsl(map_file):
    level_map = open(map_file, 'r').read()

    if not is_dsl_valid(level_map):
        sys.exit("Rumtime error: unable to parse map file")

    dsl_lines = level_map.splitlines()
    dsl_lines = [x for x in dsl_lines if x]

    for y, dsl_row in enumerate(dsl_lines):
        row = []
        dsl_cells = dsl_row.split("|")
        dsl_cells = [c for c in dsl_cells if c]

        for x, dsl_cell in enumerate(dsl_cells):
            if dsl_cell not in tile_type_dict:
                sys.exit("Map parse error: Invalid room type in map")
                break

            tile_type = tile_type_dict[dsl_cell]
            if tile_type == StartTile:
                global start_tile_location
                start_tile_location = x, y
            row.append(tile_type(x, y) if tile_type else None)

        world_map.append(row)

def tile_at(x, y):
    if x < 0 or y < 0:
        return None

    try:
        return world_map[y][x]
    except IndexError:
        return None
<|endoftext|>


<commit_before>#! /usr/bin/env python3.4
# -*- coding: utf-8 -*-
# Adds my copyright notice to photos.
#
# Author: R.F. Smith <rsmith@xs4all.nl>
# $Date$
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to markphotos.py. This work is published from
# the Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/

__version__ = '$Revision$'[11:-2]

import sys
import subprocess
from multiprocessing import Pool, Lock
from os import utime
import os.path
from time import mktime

globallock = Lock()

def checkfor(args, rv=0):
    """Make sure that a program necessary for using this script is
    available.

    :param args: String or list of strings of commands. A single string may
    not contain spaces.
    :param rv: Expected return value from evoking the command.
    """
    if isinstance(args, str):
        if ' ' in args:
            raise ValueError('no spaces in single command allowed')
        args = [args]
    try:
        with open(os.devnull, 'w') as bb:
            rc = subprocess.call(args, stdout=bb, stderr=bb)
        if rc != rv:
            raise OSError
    except OSError as oops:
        outs = "Required program '{}' not found: {}."
        print(outs.format(args[0], oops.strerror))
        sys.exit(1)

def processfile(name):
    args = ['exiftool', '-CreateDate', name]
    createdate = subprocess.check_output(args).decode()
    fields = createdate.split(":")
    year = int(fields[1])
    cr = "R.F. Smith <rsmith@xs4all.nl> http://rsmith.home.xs4all.nl/"
    cmt = "Copyright © {} {}".format(year, cr)
    args = ['exiftool', '-Copyright="Copyright (C) {} {}"'.format(year, cr),
            '-Comment="{}"'.format(cmt), '-overwrite_original', '-q', name]
    rv = subprocess.call(args)
    modtime = int(mktime((year, int(fields[2]), int(fields[3][:2]),
                          int(fields[3][3:]), int(fields[4]), int(fields[5]),
                          0, 0, -1)))
    utime(name, (modtime, modtime))
    globallock.acquire()
    if rv == 0:
        print("File '{}' processed.".format(name))
    else:
        print("Error when processing file '{}'".format(name))
    globallock.release()

def main(argv):
    """Main program.

    Keyword arguments:
    argv -- command line arguments
    """
    if len(argv) == 1:
        binary = os.path.basename(argv[0])
        print("{} version {}".format(binary, __version__), file=sys.stderr)
        print("Usage: {} [file ...]".format(binary), file=sys.stderr)
        sys.exit(0)
    checkfor(['exiftool',  '-ver'])
    p = Pool()
    p.map(processfile, argv[1:])
    p.close()

if __name__ == '__main__':
    main(sys.argv)
<commit_msg>Changed encoding line in Python scripts.<commit_after>#! /usr/bin/env python3.4
# vim:fileencoding=utf-8:ft=python
# Adds my copyright notice to photos.
#
# Author: R.F. Smith <rsmith@xs4all.nl>
# $Date$
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to markphotos.py. This work is published from
# the Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/

__version__ = '$Revision$'[11:-2]

import sys
import subprocess
from multiprocessing import Pool, Lock
from os import utime
import os.path
from time import mktime

globallock = Lock()

def checkfor(args, rv=0):
    """Make sure that a program necessary for using this script is
    available.

    :param args: String or list of strings of commands. A single string may
    not contain spaces.
    :param rv: Expected return value from evoking the command.
    """
    if isinstance(args, str):
        if ' ' in args:
            raise ValueError('no spaces in single command allowed')
        args = [args]
    try:
        with open(os.devnull, 'w') as bb:
            rc = subprocess.call(args, stdout=bb, stderr=bb)
        if rc != rv:
            raise OSError
    except OSError as oops:
        outs = "Required program '{}' not found: {}."
        print(outs.format(args[0], oops.strerror))
        sys.exit(1)

def processfile(name):
    args = ['exiftool', '-CreateDate', name]
    createdate = subprocess.check_output(args).decode()
    fields = createdate.split(":")
    year = int(fields[1])
    cr = "R.F. Smith <rsmith@xs4all.nl> http://rsmith.home.xs4all.nl/"
    cmt = "Copyright © {} {}".format(year, cr)
    args = ['exiftool', '-Copyright="Copyright (C) {} {}"'.format(year, cr),
            '-Comment="{}"'.format(cmt), '-overwrite_original', '-q', name]
    rv = subprocess.call(args)
    modtime = int(mktime((year, int(fields[2]), int(fields[3][:2]),
                          int(fields[3][3:]), int(fields[4]), int(fields[5]),
                          0, 0, -1)))
    utime(name, (modtime, modtime))
    globallock.acquire()
    if rv == 0:
        print("File '{}' processed.".format(name))
    else:
        print("Error when processing file '{}'".format(name))
    globallock.release()

def main(argv):
    """Main program.

    Keyword arguments:
    argv -- command line arguments
    """
    if len(argv) == 1:
        binary = os.path.basename(argv[0])
        print("{} version {}".format(binary, __version__), file=sys.stderr)
        print("Usage: {} [file ...]".format(binary), file=sys.stderr)
        sys.exit(0)
    checkfor(['exiftool',  '-ver'])
    p = Pool()
    p.map(processfile, argv[1:])
    p.close()

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


<commit_before>#!/usr/bin/env python
"""The Gaphor code generator CLI.

Provides the CLI for the code generator which transforms a Gaphor models
(with .gaphor file extension) in to a data model in Python.
"""

import argparse
from distutils.util import byte_compile
from pathlib import Path

from gaphor.codegen import profile_coder, uml_coder

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("modelfile", type=Path, help="gaphor model filename")
    parser.add_argument("outfile", type=Path, help="python data model filename")
    parser.add_argument("overrides", type=Path, help="override filename")
    parser.add_argument(
        "--uml_profile", help="generate a UML profile", action="store_true"
    )
    parser.add_argument(
        "--sysml_profile", help="generate a SysML profile", action="store_true"
    )
    args = parser.parse_args()
    print(f"Generating {args.outfile} from {args.modelfile}...")
    print("  (warnings can be ignored)")
    if args.uml_profile:
        profile_coder.generate(args.modelfile, args.outfile, args.overrides)
    elif args.sysml_profile:
        profile_coder.generate(args.modelfile, args.outfile, args.overrides, True)
    else:
        uml_coder.generate(args.modelfile, args.outfile, args.overrides)
    byte_compile([str(args.outfile)])

if __name__ == "__main__":
    main()
<commit_msg>Use positional argument to improve clarity<commit_after>#!/usr/bin/env python
"""The Gaphor code generator CLI.

Provides the CLI for the code generator which transforms a Gaphor models
(with .gaphor file extension) in to a data model in Python.
"""

import argparse
from distutils.util import byte_compile
from pathlib import Path

from gaphor.codegen import profile_coder, uml_coder

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("modelfile", type=Path, help="gaphor model filename")
    parser.add_argument("outfile", type=Path, help="python data model filename")
    parser.add_argument("overrides", type=Path, help="override filename")
    parser.add_argument(
        "--uml_profile", help="generate a UML profile", action="store_true"
    )
    parser.add_argument(
        "--sysml_profile", help="generate a SysML profile", action="store_true"
    )
    args = parser.parse_args()
    print(f"Generating {args.outfile} from {args.modelfile}...")
    print("  (warnings can be ignored)")
    if args.uml_profile:
        profile_coder.generate(args.modelfile, args.outfile, args.overrides)
    elif args.sysml_profile:
        profile_coder.generate(
            args.modelfile, args.outfile, args.overrides, includes_sysml=True
        )
    else:
        uml_coder.generate(args.modelfile, args.outfile, args.overrides)
    byte_compile([str(args.outfile)])

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


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

# Generate docs/options.html

import json
import glob
import re
import sys

# Set this to the path to a test file to get debug output for just that test
# file. Can be helpful to figure out why a test is not being shown for a
# particular option.
debug_tests = []  # [ 'tests/zoom.html' ]

# Pull options reference JSON out of dygraph.js
js = ''
in_json = False
for line in file('dygraph-options-reference.js'):
  if '<JSON>' in line:
    in_json = True
  elif '</JSON>' in line:
    in_json = False
  elif in_json:
    js += line

# TODO(danvk): better errors here.
assert js
docs = json.loads(js)

# Go through the tests and find uses of each option.
for opt in docs:
  docs[opt]['tests'] = []

# This is helpful for differentiating uses of options like 'width' and 'height'
# from appearances of identically-named options in CSS.
def find_braces(txt):
  """Really primitive method to find text inside of {..} braces.
  Doesn't work if there's an unmatched brace in a string, e.g. '{'. """
  out = ''
  level = 0
  for char in txt:
    if char == '{':
      level += 1
    if level >= 1:
      out += char
    if char == '}':
      level -= 1
  return out

# Find text followed by a colon. These won't all be options, but those that
# have the same name as a Dygraph option probably will be.
prop_re = re.compile(r'\b([a-zA-Z0-9]+) *:')
tests = debug_tests or glob.glob('tests/*.html')
for test_file in tests:
  braced_html = find_braces(file(test_file).read())
  if debug_tests:
    print braced_html

  ms = re.findall(prop_re, braced_html)
  for opt in ms:
    if debug_tests: print '\n'.join(ms)
    if opt in docs and test_file not in docs[opt]['tests']:
      docs[opt]['tests'].append(test_file)

if debug_tests: sys.exit(0)

# Extract a labels list.
labels = []
for nu, opt in docs.iteritems():
  for label in opt['labels']:
    if label not in labels:
      labels.append(label)

print """<!DOCTYPE HTML>

  <title>Dygraphs Options Reference</title>
  <link rel="stylesheet" href="style.css">

"""

print """

Dygraphs

Home

Data Formats

Annotations

Options Reference

Usage
"""
for label in sorted(labels):
  print '
%s\n' % (label, label)
print '
\n
\n\n'

def name(f):
  """Takes 'tests/demo.html' -> 'demo'"""
  return f.replace('tests/', '').replace('.html', '')

print """

Options Reference

Dygraphs tries to do a good job of displaying your data without any further configuration. But inevitably, you're going to want to tinker. Dygraphs provides a rich set of options for configuring its display and behavior.

Usage

You specify options in the third parameter to the dygraphs constructor:

g = new Dygraph(div,
                data,
                {
                  option1: value1,
                  option2: value2,
                  ...
                });

After you've created a Dygraph, you can change an option by calling the updateOptions method:

g.updateOptions({
                  new_option1: value1,
                  new_option2: value2
                });

And, without further ado, here's the complete list of options:

"""
for label in sorted(labels):
  print '
%s
\n' % (label, label)

  for opt_name in sorted(docs.keys()):
    opt = docs[opt_name]
    if label not in opt['labels']: continue
    tests = opt['tests']
    if not tests:
      examples_html = 'NONE'
    else:
      examples_html = ' '.join(
        '%s' % (f, name(f)) for f in tests)

    if 'parameters' in opt:
      parameters = opt['parameters']
      parameters_html = '\n'.join("%s: %s
" % (p[0], p[1]) for p in parameters)
      parameters_html = "\n
\n%s
" % (parameters_html);
    else:
      parameters_html = ''

    if not opt['type']: opt['type'] = '(missing)'
    if not opt['default']: opt['default'] = '(missing)'
    if not opt['description']: opt['description'] = '(missing)'

    print """

%(name)s

  %(desc)s

  Type: %(type)s
%(parameters)s
  Default: %(default)s

  Examples: %(examples_html)s

  """ % { 'name': opt_name,
          'type': opt['type'],
          'parameters': parameters_html,
          'default': opt['default'],
          'desc': opt['description'],
          'examples_html': examples_html}

print """

Point Properties

Some callbacks take a point argument. Its properties are:

xval/yval: The data coordinates of the point (with dates/times as millis since epoch)

canvasx/canvasy: The canvas coordinates at which the point is drawn.

name: The name of the data series to which the point belongs

"""

# This page was super-helpful:
# http://jsbeautifier.org/
<commit_msg>Support line continuation in JSON format.<commit_after>#!/usr/bin/env python

# Generate docs/options.html

import json
import glob
import re
import sys

# Set this to the path to a test file to get debug output for just that test
# file. Can be helpful to figure out why a test is not being shown for a
# particular option.
debug_tests = []  # [ 'tests/zoom.html' ]

# Pull options reference JSON out of dygraph.js
js = ''
in_json = False
for line in file('dygraph-options-reference.js'):
  if '<JSON>' in line:
    in_json = True
  elif '</JSON>' in line:
    in_json = False
  elif in_json:
    if line.endswith("\\\n"): # hacked in line continuation support with trailing \.
      line = line[:-2]
    js += line

# TODO(danvk): better errors here.
assert js
docs = json.loads(js)

# Go through the tests and find uses of each option.
for opt in docs:
  docs[opt]['tests'] = []

# This is helpful for differentiating uses of options like 'width' and 'height'
# from appearances of identically-named options in CSS.
def find_braces(txt):
  """Really primitive method to find text inside of {..} braces.
  Doesn't work if there's an unmatched brace in a string, e.g. '{'. """
  out = ''
  level = 0
  for char in txt:
    if char == '{':
      level += 1
    if level >= 1:
      out += char
    if char == '}':
      level -= 1
  return out

# Find text followed by a colon. These won't all be options, but those that
# have the same name as a Dygraph option probably will be.
prop_re = re.compile(r'\b([a-zA-Z0-9]+) *:')
tests = debug_tests or glob.glob('tests/*.html')
for test_file in tests:
  braced_html = find_braces(file(test_file).read())
  if debug_tests:
    print braced_html

  ms = re.findall(prop_re, braced_html)
  for opt in ms:
    if debug_tests: print '\n'.join(ms)
    if opt in docs and test_file not in docs[opt]['tests']:
      docs[opt]['tests'].append(test_file)

if debug_tests: sys.exit(0)

# Extract a labels list.
labels = []
for nu, opt in docs.iteritems():
  for label in opt['labels']:
    if label not in labels:
      labels.append(label)

print """<!DOCTYPE HTML>

  <title>Dygraphs Options Reference</title>
  <link rel="stylesheet" href="style.css">

"""

print """

Dygraphs

Home

Data Formats

Annotations

Options Reference

Usage
"""
for label in sorted(labels):
  print '
%s\n' % (label, label)
print '
\n
\n\n'

def name(f):
  """Takes 'tests/demo.html' -> 'demo'"""
  return f.replace('tests/', '').replace('.html', '')

print """

Options Reference

Dygraphs tries to do a good job of displaying your data without any further configuration. But inevitably, you're going to want to tinker. Dygraphs provides a rich set of options for configuring its display and behavior.

Usage

You specify options in the third parameter to the dygraphs constructor:

g = new Dygraph(div,
                data,
                {
                  option1: value1,
                  option2: value2,
                  ...
                });

After you've created a Dygraph, you can change an option by calling the updateOptions method:

g.updateOptions({
                  new_option1: value1,
                  new_option2: value2
                });

And, without further ado, here's the complete list of options:

"""
for label in sorted(labels):
  print '
%s
\n' % (label, label)

  for opt_name in sorted(docs.keys()):
    opt = docs[opt_name]
    if label not in opt['labels']: continue
    tests = opt['tests']
    if not tests:
      examples_html = 'NONE'
    else:
      examples_html = ' '.join(
        '%s' % (f, name(f)) for f in tests)

    if 'parameters' in opt:
      parameters = opt['parameters']
      parameters_html = '\n'.join("%s: %s
" % (p[0], p[1]) for p in parameters)
      parameters_html = "\n
\n%s
" % (parameters_html);
    else:
      parameters_html = ''

    if not opt['type']: opt['type'] = '(missing)'
    if not opt['default']: opt['default'] = '(missing)'
    if not opt['description']: opt['description'] = '(missing)'

    print """

%(name)s

  %(desc)s

  Type: %(type)s
%(parameters)s
  Default: %(default)s

  Examples: %(examples_html)s

  """ % { 'name': opt_name,
          'type': opt['type'],
          'parameters': parameters_html,
          'default': opt['default'],
          'desc': opt['description'],
          'examples_html': examples_html}

print """

Point Properties

Some callbacks take a point argument. Its properties are:

xval/yval: The data coordinates of the point (with dates/times as millis since epoch)

canvasx/canvasy: The canvas coordinates at which the point is drawn.

name: The name of the data series to which the point belongs

"""

# This page was super-helpful:
# http://jsbeautifier.org/
<|endoftext|>


<commit_before>import logging

from django.conf import settings
from django.http import HttpResponseForbidden, HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View
from django.utils.decorators import method_decorator
from firecares.tasks.cache import clear_cache as clear_cache_task
from firecares.tasks.slack import send_slack_message

logger = logging.getLogger(__name__)

class FireCARESSlack(View):
    """
    Class that routes and executes Slack commands.
    """
    http_method_names = ['post']
    commands = ['clear_cache']

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(FireCARESSlack, self).dispatch(*args, **kwargs)

    @property
    def help_text(self):
        """
        Returns a list of commands.
        """

        msg = """clear_cache: Nuclear option, clears the entire cache.
        """

        return {'text': msg}

    def clear_cache(self, request, *args, **kwargs):
        clear_cache_task.apply_async(link=send_slack_message.s(self.response_url, {'text': 'Cache successfully cleared!'}),
                                     link_error=send_slack_message.s(self.response_url, {'text': 'Cache clearing cache.'}))
        return HttpResponse()

    def parse_message(self):
        """
        Parses the incoming message from slack.
        """

        try:
            text = self.request.POST.get('text').split()
            self.command = text[0]
            self.command_args = text[1:]

        except IndexError:
            self.command = ''
            self.command_args = ''

        self.response_url = self.request.POST.get('response_url')
        self.token = self.request.POST.get('token')
        self.username = self.request.POST.get('user_name')
        self.user_id = self.request.POST.get('user_id')
        self.channel_name = self.request.POST.get('channel_name')
        self.channel_id = self.request.POST.get('channel_id')
        self.team_domain = self.request.POST.get('team_domain')
        self.team_id = self.request.POST.get('team_id')

    def command_dispatch(self, request, *args, **kwargs):
        command = self.command

        if not command:
            return JsonResponse(self.help_text)

        if command.lower() in self.commands:
            handler = getattr(self, command.lower(), self.command_not_allowed)
        else:
            handler = self.command_not_allowed

        return handler(request, *args, **kwargs)

    def command_not_allowed(self, request, *args, **kwargs):
        logger.warning('Command Not Allowed (%s): %s', self.command, request.path,
            extra={'status_code': 403, 'request': request}
        )
        return HttpResponseForbidden(self._allowed_commands())

    @property
    def valid_token(self):
        """
        Validates the slack token against the one in settings.
        """
        return self.request.POST.get('token') == getattr(settings, 'SLACK_FIRECARES_COMMAND_TOKEN', '')

    def _allowed_commands(self):
        return [m.upper() for m in self.commands if hasattr(self, m)]

    def post(self, request, *args, **kwargs):

        if not self.valid_token:
            return HttpResponseForbidden('Invalid token.')

        self.parse_message()
        return self.command_dispatch(request)

<commit_msg>Add command to count account requests.<commit_after>import logging

from django.conf import settings
from django.http import HttpResponseForbidden, HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View
from django.utils.decorators import method_decorator
from firecares.tasks.cache import clear_cache as clear_cache_task
from firecares.tasks.slack import send_slack_message
from firecares.firecares_core.models import AccountRequest

logger = logging.getLogger(__name__)

class FireCARESSlack(View):
    """
    Class that routes and executes Slack commands.
    """
    http_method_names = ['post']
    commands = ['clear_cache', 'account_requests']

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(FireCARESSlack, self).dispatch(*args, **kwargs)

    @property
    def help_text(self):
        """
        Returns a list of commands.
        """

        msg = """clear_cache: Nuclear option, clears the entire cache.
        account_requests: Returns the number of active account requests.
        """

        return {'text': msg}

    def clear_cache(self, request, *args, **kwargs):
        clear_cache_task.apply_async(link=send_slack_message.s(self.response_url, {'text': 'Cache successfully cleared!'}),
                                     link_error=send_slack_message.s(self.response_url, {'text': 'Cache clearing cache.'}))
        return HttpResponse()

    def account_requests(self, request, *args, **kwargs):
        return JsonResponse({'text': 'There are currently {0} pending account requests.'.format(AccountRequest.objects.count())})

    def parse_message(self):
        """
        Parses the incoming message from slack.
        """

        try:
            text = self.request.POST.get('text').split()
            self.command = text[0]
            self.command_args = text[1:]

        except IndexError:
            self.command = ''
            self.command_args = ''

        self.response_url = self.request.POST.get('response_url')
        self.token = self.request.POST.get('token')
        self.username = self.request.POST.get('user_name')
        self.user_id = self.request.POST.get('user_id')
        self.channel_name = self.request.POST.get('channel_name')
        self.channel_id = self.request.POST.get('channel_id')
        self.team_domain = self.request.POST.get('team_domain')
        self.team_id = self.request.POST.get('team_id')

    def command_dispatch(self, request, *args, **kwargs):
        command = self.command

        if not command:
            return JsonResponse(self.help_text)

        if command.lower() in self.commands:
            handler = getattr(self, command.lower(), self.command_not_allowed)
        else:
            handler = self.command_not_allowed

        return handler(request, *args, **kwargs)

    def command_not_allowed(self, request, *args, **kwargs):
        logger.warning('Command Not Allowed (%s): %s', self.command, request.path,
            extra={'status_code': 403, 'request': request}
        )
        return HttpResponseForbidden(self._allowed_commands())

    @property
    def valid_token(self):
        """
        Validates the slack token against the one in settings.
        """
        return self.request.POST.get('token') == getattr(settings, 'SLACK_FIRECARES_COMMAND_TOKEN', '')

    def _allowed_commands(self):
        return [m.upper() for m in self.commands if hasattr(self, m)]

    def post(self, request, *args, **kwargs):

        if not self.valid_token:
            return HttpResponseForbidden('Invalid token.')

        self.parse_message()
        return self.command_dispatch(request)

<|endoftext|>


<commit_before>from django import forms

class CampaignGeneralForm(forms.Form):

    TYPE_CHOICES = (
        ('', 'Select campaign type'),
        ('B', 'Bulk Message'),
        ('C', 'Conversation'),
    )

    name = forms.CharField(label="Campaign name", max_length=100)
    type = forms.ChoiceField(label="Which kind of campaign would you like?",
                             widget=forms.Select(), choices=TYPE_CHOICES)

class CampaignConfigurationForm(forms.Form):

    COUNTRY_CHOICES = (
        ('*', 'All Countries'),
        ('.ke', 'Kenya'),
        ('.za', 'South Africa'),
    )

    CHANNEL_CHOICES = (
        ('ussd', 'USSD'),
        ('gtalk', 'Google Talk'),
    )

    # more than likely a many to many field, or something similair in the riak
    # world. Whom I kidding, this is probably just a modelform?
    countries = forms.MultipleChoiceField(label="Destinations",
                                          widget=forms.Select(),
                                          choices=COUNTRY_CHOICES)

    channels = forms.MultipleChoiceField(label="Channels",
                                         widget=forms.Select(),
                                         choices=CHANNEL_CHOICES)

    keyword = forms.CharField(label="Keyword", max_length=100)

class CampaignBulkMessageForm(forms.Form):
    message = forms.CharField(label="Bulk message text", widget=forms.Textarea)
<commit_msg>more sensisble defaults for channels<commit_after>from django import forms

class CampaignGeneralForm(forms.Form):

    TYPE_CHOICES = (
        ('', 'Select campaign type'),
        ('B', 'Bulk Message'),
        ('C', 'Conversation'),
    )

    name = forms.CharField(label="Campaign name", max_length=100)
    type = forms.ChoiceField(label="Which kind of campaign would you like?",
                             widget=forms.Select(), choices=TYPE_CHOICES)

class CampaignConfigurationForm(forms.Form):

    COUNTRY_CHOICES = (
        ('*', 'All Countries'),
        ('.za', 'South Africa'),
    )

    CHANNEL_CHOICES = (
        ('ussd', 'USSD'),
        ('sms', 'SMS longcode'),
    )

    # more than likely a many to many field, or something similair in the riak
    # world. Whom I kidding, this is probably just a modelform?
    countries = forms.MultipleChoiceField(label="Destinations",
                                          widget=forms.Select(),
                                          choices=COUNTRY_CHOICES)

    channels = forms.MultipleChoiceField(label="Channels",
                                         widget=forms.Select(),
                                         choices=CHANNEL_CHOICES)

    keyword = forms.CharField(label="Keyword", max_length=100)

class CampaignBulkMessageForm(forms.Form):
    message = forms.CharField(label="Bulk message text", widget=forms.Textarea)
<|endoftext|>


<commit_before>import weibull

# the current run time of the test or the
# time that the test was suspended completely
current_run_time = 4200.0

fail_times = [77.8, 101.8, 105.9, 117.0, 126.9, 138.7,
              148.9, 157.3, 163.8, 207.0, 217.4]

suspended = [False] * len(fail_times)

analysis = weibull.Analysis(fail_times, suspended=suspended, unit='hour')
analysis.fit(method='mle')

analysis.probplot()
analysis.pdf()
analysis.sf()
analysis.hazard()
analysis.cdf()
analysis.fr()

print(f'beta: {analysis.beta}\teta: {analysis.eta}')
print(f'{analysis.stats}')
print(f'B2 life: {analysis.b(2):.02f}\nB10 life: {analysis.b(10):.02f}\nB50 life: {analysis.b(50):.02f}')
print(f'median: {analysis.median}')
print(f'mean: {analysis.mean}')
print(f'mttf: {analysis.mttf}')
<commit_msg>Replacing individual prints with single print to 'stats'<commit_after>import weibull

# the current run time of the test or the
# time that the test was suspended completely
current_run_time = 4200.0

fail_times = [77.8, 101.8, 105.9, 117.0, 126.9, 138.7,
              148.9, 157.3, 163.8, 207.0, 217.4]

suspended = [False] * len(fail_times)

analysis = weibull.Analysis(fail_times, suspended=suspended, unit='hour')
analysis.fit(method='mle', confidence_level=0.6)

analysis.probplot()
analysis.pdf()
analysis.sf()
analysis.hazard()
analysis.cdf()
analysis.fr()

print(analysis.stats)
<|endoftext|>


<commit_before># Copyright (C) 2010-2012 Cuckoo Sandbox Developers.
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
# See the file 'docs/LICENSE' for copying permission.

import os
import sys
import csv
import logging

from lib.cuckoo.common.abstracts import Processing
from lib.cuckoo.common.utils import convert_to_printable

log = logging.getLogger(__name__)

class ParseProcessLog:
    """Parses process log file."""

    def __init__(self, log_path):
        """@param log_path: log file path."""
        self._log_path = log_path
        self.process_id = None
        self.process_name = None
        self.parent_id = None
        self.process_first_seen = None
        self.calls = []

    def _parse(self, row):
        """Parse log row.
        @param row: row data.
        @return: parsed information dict.
        """
        call = {}
        arguments = []

        try:
            timestamp = row[0]    # Timestamp of current API call invocation.
            process_id = row[1]   # ID of the process that performed the call.
            process_name = row[2] # Name of the process.
            thread_id = row[3]    # Thread ID.
            parent_id = row[4]    # PID of the parent process.
            category = row[5]     # Win32 function category.
            api_name = row[6]     # Name of the Windows API.
            status_value = row[7] # Success or Failure?
            return_value = row[8] # Value returned by the function.
        except IndexError as e:
            log.debug("Unable to parse process log row: %s" % e)
            return False

        if not self.process_id:
            self.process_id = process_id

        if not self.process_name:
            self.process_name = process_name

        if not self.parent_id:
            self.parent_id = parent_id

        if not self.process_first_seen:
            self.process_first_seen = timestamp

        # Now walk through the remaining columns, which will contain API
        # arguments.
        for index in range(9, len(row)):
            argument = {}

            # Split the argument name with its value based on the separator.
            try:
                (arg_name, arg_value) = row[index].split("->", 1)
            except ValueError as e:
                log.debug("Unable to parse analysis row argument (row=%s): %s" % (row[index], e))
                continue

            argument["name"] = arg_name
            argument["value"] = convert_to_printable(arg_value).lstrip("\\??\\")
            arguments.append(argument)

        call["timestamp"] = timestamp
        call["thread_id"] = thread_id
        call["category"] = category
        call["api"] = api_name
        call["status"] = status_value
        call["return"] = convert_to_printable(return_value)
        call["arguments"] = arguments
        call["repeated"] = 0

        # Check if the current API call is a repetition of the previous one.
        if len(self.calls) > 0:
            if self.calls[-1]["api"] == call["api"] and \
               self.calls[-1]["status"] == call["status"] and \
               self.calls[-1]["arguments"] == call["arguments"] and \
               self.calls[-1]["return"] == call["return"]:
                self.calls[-1]["repeated"] += 1
                return True

        self.calls.append(call)

        return True

    def extract(self):
        """Get data from CSV file.
        @return: boolean with status of parsing process.
        """
        if not os.path.exists(self._log_path):
            log.error("Analysis logs folder does not exist at path \"%s\"."
                      % self._log_path)
            return False

        reader = csv.reader(open(self._log_path, "rb"))

        try:
            for row in reader:
                self._parse(row)
        except csv.Error as e:
            log.warning("Something went wrong while parsing analysis log: %s"
                        % e)

        return True

class Processes:
    """Processes analyzer."""

    def __init__(self, logs_path):
        """@param  logs_path: logs path."""
        self._logs_path = logs_path

    def run(self):
        """Run analysis.
        @return: processes infomartion list.
        """
        results = []

        if not os.path.exists(self._logs_path):
            log.error("Analysis results folder does not exist at path \"%s\"."
                      % self._logs_path)
            return results

        if len(os.listdir(self._logs_path)) == 0:
            log.error("Analysis results folder does not contain any file.")
            return results

        for file_name in os.listdir(self._logs_path):
            file_path = os.path.join(self._logs_path, file_name)

            if os.path.isdir(file_path):
                continue

            if not file_path.endswith(".csv"):
                continue

            # Invoke parsing of current log file.
            current_log = ParseProcessLog(file_path)
            current_log.extract()

            # If the current log actually contains any data, add its data to
            # the global results list.
            if len(current_log.calls) > 0:
                process = {}
                process["process_id"]   = current_log.process_id
                process["process_name"] = current_log.process_name
                process["parent_id"]    = current_log.parent_id
                process["first_seen"]   = current_log.process_first_seen
                process["calls"]        = current_log.calls

                results.append(process)

        # Sort the items in the results list chronologically. In this way we
        # can have a sequential order of spawned processes.
        results.sort(key=lambda process: process["first_seen"])

        return results

class Summary:
    """Generates summary information."""

    def __init__(self, proc_results):
        """@param oroc_results: enumerated processes results."""
        self.proc_results = proc_results

    def _gen_files(self):
        """Gets files calls.
        @return: information list.
        """
        files = []

        for entry in self.proc_results:
            for call in entry["calls"]:
                if call["category"] == "filesystem":
                    for argument in call["arguments"]:
                        if argument["name"] == "FileName":
                            value = argument["value"].strip()
                            if not value:
                                continue

                            if value not in files:
                                files.append(value)

        return files

    def _gen_keys(self):
        """Get registry calls.
        @return: keys information list.
        """
        keys = []

        def _check_registry(handles, registry, subkey, handle):
            for known_handle in handles:
                if handle != 0 and handle == known_handle["handle"]:
                    return None

            name = ""
            if registry == 0x80000000:
                name = "HKEY_CLASSES_ROOT\\"
            elif registry == 0x80000001:
                name = "HKEY_CURRENT_USER\\"
            elif registry == 0x80000002:
                name = "HKEY_LOCAL_MACHINE\\"
            elif registry == 0x80000003:
                name = "HKEY_USERS\\"
            elif registry == 0x80000004:
                name = "HKEY_PERFORMANCE_DATA\\"
            elif registry == 0x80000005:
                name = "HKEY_CURRENT_CONFIG\\"
            elif registry == 0x80000006:
                name = "HKEY_DYN_DATA\\"
            else:
                for known_handle in handles:
                    if registry == known_handle["handle"]:
                        name = known_handle["name"] + "\\"

            handles.append({"handle" : handle, "name" : name + subkey})
            return name + subkey

        def _remove_handle(handles, handle):
            for known_handle in handles:
                if handle != 0 and handle == known_handle["handle"]:
                    handles.remove(known_handle)

        for process in self.proc_results:
            handles = []

            for call in process["calls"]:
                if call["api"].startswith("RegOpenKeyEx") or call["api"].startswith("RegCreateKeyEx"):
                    registry = 0
                    subkey = ""
                    handle = 0

                    for argument in call["arguments"]:
                        if argument["name"] == "Registry":
                            registry = int(argument["value"], 16)
                        elif argument["name"] == "SubKey":
                            subkey = argument["value"]
                        elif argument["name"] == "Handle":
                            handle = int(argument["value"], 16)

                    name = _check_registry(handles, registry, subkey, handle)
                    if name and name not in keys:
                        keys.append(name)
                elif call["api"].startswith("RegCloseKey"):
                    handle = 0

                    for argument in call["arguments"]:
                        if argument["name"] == "Handle":
                            handle = int(argument["value"], 16)
                    _remove_handle(handles, handle)

        return keys

    def _gen_mutexes(self):
        """Get mutexes information.
        @return: Mutexes information list.
        """
        mutexes = []

        for entry in self.proc_results:
            for call in entry["calls"]:
                if call["category"] == "synchronization":
                    for argument in call["arguments"]:
                        if argument["name"] == "MutexName":
                            value = argument["value"].strip()
                            if not value:
                                continue

                            if value not in mutexes:
                                mutexes.append(value)

        return mutexes

    def run(self):
        """Run analysis.
        @return: information dict.
        """
        summary = {}
        summary["files"] = self._gen_files()
        summary["keys"] = self._gen_keys()
        summary["mutexes"] = self._gen_mutexes()

        return summary

class ProcessTree:
    """Creates process tree."""

    def __init__(self, proc_results):
        """@param proc_results: enumerated processes information."""
        self.proc_results = proc_results
        self.processes = []
        self.proctree = []

    def gen_proclist(self):
        """Generate processes list.
        @return: True.
        """
        for entry in self.proc_results:
            process = {}
            process["name"] = entry["process_name"]
            process["pid"] = int(entry["process_id"])
            process["children"] = []

            for call in entry["calls"]:
                if call["api"] == "CreateProcessInternalW":
                    for argument in call["arguments"]:
                        if argument["name"] == "ProcessId":
                            process["children"].append(int(argument["value"]))

            self.processes.append(process)

        return True

    def add_node(self, node, parent_id, tree):
        """Add a node to a tree.
        @param node: node to add.
        @param parent_id: parent node.
        @param tree: processes tree.
        @return: boolean with operation success status.
        """
        for process in tree:
            if process["pid"] == parent_id:
                new = {}
                new["name"] = node["name"]
                new["pid"] = node["pid"]
                new["children"] = []
                process["children"].append(new)
                return True
            self.add_node(node, parent_id, process["children"])

        return False

    def populate(self, node):
        """Populate tree.
        @param node: node to add.
        @return: True.
        """
        for children in node["children"]:
            for proc in self.processes:
                if int(proc["pid"]) == int(children):
                    self.add_node(proc, node["pid"], self.proctree)
                    self.populate(proc)

        return True

    def run(self):
        """Run analysis.
        @return: results dict or None.
        """
        if not self.proc_results or len(self.proc_results) == 0:
            return None

        self.gen_proclist()
        root = {}
        root["name"] = self.processes[0]["name"]
        root["pid"] = self.processes[0]["pid"]
        root["children"] = []
        self.proctree.append(root)
        self.populate(self.processes[0])

        return self.proctree

class BehaviorAnalysis(Processing):
    """Behavior Analyzer."""

    def run(self):
        """Run analysis.
        @return: results dict.
        """
        self.key = "behavior"

        behavior = {}
        behavior["processes"]   = Processes(self.logs_path).run()
        behavior["processtree"] = ProcessTree(behavior["processes"]).run()
        behavior["summary"]     = Summary(behavior["processes"]).run()

        return behavior
<commit_msg>Added unbuffered CSV reader<commit_after># Copyright (C) 2010-2012 Cuckoo Sandbox Developers.
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
# See the file 'docs/LICENSE' for copying permission.

import os
import sys
import csv
import logging

from lib.cuckoo.common.abstracts import Processing
from lib.cuckoo.common.utils import convert_to_printable

log = logging.getLogger(__name__)

class LineIteration:
    def __init__(self, csv):
        self.csv = csv

    def __iter__(self):
        return self

    def next(self):
        line = self.csv.readline()
        if line:
            return line
        else:
            raise StopIteration

class ParseProcessLog:
    """Parses process log file."""

    def __init__(self, log_path):
        """@param log_path: log file path."""
        self._log_path = log_path
        self.process_id = None
        self.process_name = None
        self.parent_id = None
        self.process_first_seen = None
        self.calls = []

    def _parse(self, row):
        """Parse log row.
        @param row: row data.
        @return: parsed information dict.
        """
        call = {}
        arguments = []

        try:
            timestamp = row[0]    # Timestamp of current API call invocation.
            process_id = row[1]   # ID of the process that performed the call.
            process_name = row[2] # Name of the process.
            thread_id = row[3]    # Thread ID.
            parent_id = row[4]    # PID of the parent process.
            category = row[5]     # Win32 function category.
            api_name = row[6]     # Name of the Windows API.
            status_value = row[7] # Success or Failure?
            return_value = row[8] # Value returned by the function.
        except IndexError as e:
            log.debug("Unable to parse process log row: %s" % e)
            return False

        if not self.process_id:
            self.process_id = process_id

        if not self.process_name:
            self.process_name = process_name

        if not self.parent_id:
            self.parent_id = parent_id

        if not self.process_first_seen:
            self.process_first_seen = timestamp

        # Now walk through the remaining columns, which will contain API
        # arguments.
        for index in range(9, len(row)):
            argument = {}

            # Split the argument name with its value based on the separator.
            try:
                (arg_name, arg_value) = row[index].split("->", 1)
            except ValueError as e:
                log.debug("Unable to parse analysis row argument (row=%s): %s" % (row[index], e))
                continue

            argument["name"] = arg_name
            argument["value"] = convert_to_printable(arg_value).lstrip("\\??\\")
            arguments.append(argument)

        call["timestamp"] = timestamp
        call["thread_id"] = thread_id
        call["category"] = category
        call["api"] = api_name
        call["status"] = status_value
        call["return"] = convert_to_printable(return_value)
        call["arguments"] = arguments
        call["repeated"] = 0

        # Check if the current API call is a repetition of the previous one.
        if len(self.calls) > 0:
            if self.calls[-1]["api"] == call["api"] and \
               self.calls[-1]["status"] == call["status"] and \
               self.calls[-1]["arguments"] == call["arguments"] and \
               self.calls[-1]["return"] == call["return"]:
                self.calls[-1]["repeated"] += 1
                return True

        self.calls.append(call)

        return True

    def extract(self):
        """Get data from CSV file.
        @return: boolean with status of parsing process.
        """
        if not os.path.exists(self._log_path):
            log.error("Analysis logs folder does not exist at path \"%s\"."
                      % self._log_path)
            return False

        reader = csv.reader(LineIteration(open(self._log_path, "rb")))

        try:
            for row in reader:
                self._parse(row)
        except csv.Error as e:
            log.warning("Something went wrong while parsing analysis log: %s"
                        % e)

        return True

class Processes:
    """Processes analyzer."""

    def __init__(self, logs_path):
        """@param  logs_path: logs path."""
        self._logs_path = logs_path

    def run(self):
        """Run analysis.
        @return: processes infomartion list.
        """
        results = []

        if not os.path.exists(self._logs_path):
            log.error("Analysis results folder does not exist at path \"%s\"."
                      % self._logs_path)
            return results

        if len(os.listdir(self._logs_path)) == 0:
            log.error("Analysis results folder does not contain any file.")
            return results

        for file_name in os.listdir(self._logs_path):
            file_path = os.path.join(self._logs_path, file_name)

            if os.path.isdir(file_path):
                continue

            if not file_path.endswith(".csv"):
                continue

            # Invoke parsing of current log file.
            current_log = ParseProcessLog(file_path)
            current_log.extract()

            # If the current log actually contains any data, add its data to
            # the global results list.
            if len(current_log.calls) > 0:
                process = {}
                process["process_id"]   = current_log.process_id
                process["process_name"] = current_log.process_name
                process["parent_id"]    = current_log.parent_id
                process["first_seen"]   = current_log.process_first_seen
                process["calls"]        = current_log.calls

                results.append(process)

        # Sort the items in the results list chronologically. In this way we
        # can have a sequential order of spawned processes.
        results.sort(key=lambda process: process["first_seen"])

        return results

class Summary:
    """Generates summary information."""

    def __init__(self, proc_results):
        """@param oroc_results: enumerated processes results."""
        self.proc_results = proc_results

    def _gen_files(self):
        """Gets files calls.
        @return: information list.
        """
        files = []

        for entry in self.proc_results:
            for call in entry["calls"]:
                if call["category"] == "filesystem":
                    for argument in call["arguments"]:
                        if argument["name"] == "FileName":
                            value = argument["value"].strip()
                            if not value:
                                continue

                            if value not in files:
                                files.append(value)

        return files

    def _gen_keys(self):
        """Get registry calls.
        @return: keys information list.
        """
        keys = []

        def _check_registry(handles, registry, subkey, handle):
            for known_handle in handles:
                if handle != 0 and handle == known_handle["handle"]:
                    return None

            name = ""
            if registry == 0x80000000:
                name = "HKEY_CLASSES_ROOT\\"
            elif registry == 0x80000001:
                name = "HKEY_CURRENT_USER\\"
            elif registry == 0x80000002:
                name = "HKEY_LOCAL_MACHINE\\"
            elif registry == 0x80000003:
                name = "HKEY_USERS\\"
            elif registry == 0x80000004:
                name = "HKEY_PERFORMANCE_DATA\\"
            elif registry == 0x80000005:
                name = "HKEY_CURRENT_CONFIG\\"
            elif registry == 0x80000006:
                name = "HKEY_DYN_DATA\\"
            else:
                for known_handle in handles:
                    if registry == known_handle["handle"]:
                        name = known_handle["name"] + "\\"

            handles.append({"handle" : handle, "name" : name + subkey})
            return name + subkey

        def _remove_handle(handles, handle):
            for known_handle in handles:
                if handle != 0 and handle == known_handle["handle"]:
                    handles.remove(known_handle)

        for process in self.proc_results:
            handles = []

            for call in process["calls"]:
                if call["api"].startswith("RegOpenKeyEx") or call["api"].startswith("RegCreateKeyEx"):
                    registry = 0
                    subkey = ""
                    handle = 0

                    for argument in call["arguments"]:
                        if argument["name"] == "Registry":
                            registry = int(argument["value"], 16)
                        elif argument["name"] == "SubKey":
                            subkey = argument["value"]
                        elif argument["name"] == "Handle":
                            handle = int(argument["value"], 16)

                    name = _check_registry(handles, registry, subkey, handle)
                    if name and name not in keys:
                        keys.append(name)
                elif call["api"].startswith("RegCloseKey"):
                    handle = 0

                    for argument in call["arguments"]:
                        if argument["name"] == "Handle":
                            handle = int(argument["value"], 16)
                    _remove_handle(handles, handle)

        return keys

    def _gen_mutexes(self):
        """Get mutexes information.
        @return: Mutexes information list.
        """
        mutexes = []

        for entry in self.proc_results:
            for call in entry["calls"]:
                if call["category"] == "synchronization":
                    for argument in call["arguments"]:
                        if argument["name"] == "MutexName":
                            value = argument["value"].strip()
                            if not value:
                                continue

                            if value not in mutexes:
                                mutexes.append(value)

        return mutexes

    def run(self):
        """Run analysis.
        @return: information dict.
        """
        summary = {}
        summary["files"] = self._gen_files()
        summary["keys"] = self._gen_keys()
        summary["mutexes"] = self._gen_mutexes()

        return summary

class ProcessTree:
    """Creates process tree."""

    def __init__(self, proc_results):
        """@param proc_results: enumerated processes information."""
        self.proc_results = proc_results
        self.processes = []
        self.proctree = []

    def gen_proclist(self):
        """Generate processes list.
        @return: True.
        """
        for entry in self.proc_results:
            process = {}
            process["name"] = entry["process_name"]
            process["pid"] = int(entry["process_id"])
            process["children"] = []

            for call in entry["calls"]:
                if call["api"] == "CreateProcessInternalW":
                    for argument in call["arguments"]:
                        if argument["name"] == "ProcessId":
                            process["children"].append(int(argument["value"]))

            self.processes.append(process)

        return True

    def add_node(self, node, parent_id, tree):
        """Add a node to a tree.
        @param node: node to add.
        @param parent_id: parent node.
        @param tree: processes tree.
        @return: boolean with operation success status.
        """
        for process in tree:
            if process["pid"] == parent_id:
                new = {}
                new["name"] = node["name"]
                new["pid"] = node["pid"]
                new["children"] = []
                process["children"].append(new)
                return True
            self.add_node(node, parent_id, process["children"])

        return False

    def populate(self, node):
        """Populate tree.
        @param node: node to add.
        @return: True.
        """
        for children in node["children"]:
            for proc in self.processes:
                if int(proc["pid"]) == int(children):
                    self.add_node(proc, node["pid"], self.proctree)
                    self.populate(proc)

        return True

    def run(self):
        """Run analysis.
        @return: results dict or None.
        """
        if not self.proc_results or len(self.proc_results) == 0:
            return None

        self.gen_proclist()
        root = {}
        root["name"] = self.processes[0]["name"]
        root["pid"] = self.processes[0]["pid"]
        root["children"] = []
        self.proctree.append(root)
        self.populate(self.processes[0])

        return self.proctree

class BehaviorAnalysis(Processing):
    """Behavior Analyzer."""

    def run(self):
        """Run analysis.
        @return: results dict.
        """
        self.key = "behavior"

        behavior = {}
        behavior["processes"]   = Processes(self.logs_path).run()
        behavior["processtree"] = ProcessTree(behavior["processes"]).run()
        behavior["summary"]     = Summary(behavior["processes"]).run()

        return behavior
<|endoftext|>


<commit_before>import numpy as np

import pytest

import dask.array as da
from dask.array.fft import (
    fft_wrap, fft
)
from dask.array.utils import assert_eq

def same_keys(a, b):
    def key(k):
        if isinstance(k, str):
            return (k, -1, -1, -1)
        else:
            return k
    return sorted(a.dask, key=key) == sorted(b.dask, key=key)

all_funcnames = [
    "fft",
    "ifft",
    "rfft",
    "irfft",
    "hfft",
    "ihfft",
]

nparr = np.arange(100).reshape(10, 10)
darr = da.from_array(nparr, chunks=(1, 10))
darr2 = da.from_array(nparr, chunks=(10, 1))

def test_cant_fft_chunked_axis():
    bad_darr = da.from_array(nparr, chunks=(5, 5))
    with pytest.raises(ValueError):
        fft(bad_darr)
    with pytest.raises(ValueError):
        fft(bad_darr, axis=0)

@pytest.mark.parametrize("funcname", all_funcnames)
def test_fft(funcname):
    da_fft = getattr(da.fft, funcname)
    np_fft = getattr(np.fft, funcname)

    assert_eq(da_fft(darr),
              np_fft(nparr))

@pytest.mark.parametrize("funcname", all_funcnames)
def test_fft_n_kwarg(funcname):
    da_fft = getattr(da.fft, funcname)
    np_fft = getattr(np.fft, funcname)

    assert_eq(da_fft(darr, 5),
              np_fft(nparr, 5))
    assert_eq(da_fft(darr, 13),
              np_fft(nparr, 13))
    assert_eq(da_fft(darr2, axis=0),
              np_fft(nparr, axis=0))
    assert_eq(da_fft(darr2, 5, axis=0),
              np_fft(nparr, 5, axis=0))
    assert_eq(da_fft(darr2, 13, axis=0),
              np_fft(nparr, 13, axis=0))
    assert_eq(da_fft(darr2, 12, axis=0),
              np_fft(nparr, 12, axis=0))

def test_fft_consistent_names():
    assert same_keys(fft(darr, 5), fft(darr, 5))
    assert same_keys(fft(darr2, 5, axis=0), fft(darr2, 5, axis=0))
    assert not same_keys(fft(darr, 5), fft(darr, 13))

def test_wrap_bad_kind():
    with pytest.raises(ValueError):
        fft_wrap(np.ones)

@pytest.mark.parametrize("modname", ["numpy.fft", "scipy.fftpack"])
@pytest.mark.parametrize("funcname", all_funcnames)
@pytest.mark.parametrize("dtype", ["float32", "float64"])
def test_wrap_ffts(modname, funcname, dtype):
    fft_mod = pytest.importorskip(modname)
    try:
        func = getattr(fft_mod, funcname)
    except AttributeError:
        pytest.skip("`%s` missing function `%s`." % (modname, funcname))

    darrc = darr.astype(dtype)
    darr2c = darr2.astype(dtype)
    nparrc = nparr.astype(dtype)

    if modname == "scipy.fftpack" and "rfft" in funcname:
        with pytest.raises(ValueError):
            fft_wrap(func)
    else:
        wfunc = fft_wrap(func)
        assert wfunc(darrc).dtype == func(nparrc).dtype
        assert wfunc(darrc).shape == func(nparrc).shape
        assert_eq(wfunc(darrc), func(nparrc))
        assert_eq(wfunc(darrc, axis=1), func(nparrc, axis=1))
        assert_eq(wfunc(darr2c, axis=0), func(nparrc, axis=0))
        assert_eq(wfunc(darrc, n=len(darrc) - 1),
                  func(nparrc, n=len(darrc) - 1))
        assert_eq(wfunc(darrc, axis=1, n=darrc.shape[1] - 1),
                  func(nparrc, n=darrc.shape[1] - 1))
        assert_eq(wfunc(darr2c, axis=0, n=darr2c.shape[0] - 1),
                  func(nparrc, axis=0, n=darr2c.shape[0] - 1))
<commit_msg>Parametrize some FFT tests (#2123)<commit_after>import numpy as np

import pytest

import dask.array as da
from dask.array.fft import fft_wrap
from dask.array.utils import assert_eq

def same_keys(a, b):
    def key(k):
        if isinstance(k, str):
            return (k, -1, -1, -1)
        else:
            return k
    return sorted(a.dask, key=key) == sorted(b.dask, key=key)

all_funcnames = [
    "fft",
    "ifft",
    "rfft",
    "irfft",
    "hfft",
    "ihfft",
]

nparr = np.arange(100).reshape(10, 10)
darr = da.from_array(nparr, chunks=(1, 10))
darr2 = da.from_array(nparr, chunks=(10, 1))

@pytest.mark.parametrize("funcname", all_funcnames)
def test_cant_fft_chunked_axis(funcname):
    da_fft = getattr(da.fft, funcname)

    bad_darr = da.from_array(nparr, chunks=(5, 5))
    for i in range(bad_darr.ndim):
        with pytest.raises(ValueError):
            da_fft(bad_darr, axis=i)

@pytest.mark.parametrize("funcname", all_funcnames)
def test_fft(funcname):
    da_fft = getattr(da.fft, funcname)
    np_fft = getattr(np.fft, funcname)

    assert_eq(da_fft(darr),
              np_fft(nparr))

@pytest.mark.parametrize("funcname", all_funcnames)
def test_fft_n_kwarg(funcname):
    da_fft = getattr(da.fft, funcname)
    np_fft = getattr(np.fft, funcname)

    assert_eq(da_fft(darr, 5),
              np_fft(nparr, 5))
    assert_eq(da_fft(darr, 13),
              np_fft(nparr, 13))
    assert_eq(da_fft(darr2, axis=0),
              np_fft(nparr, axis=0))
    assert_eq(da_fft(darr2, 5, axis=0),
              np_fft(nparr, 5, axis=0))
    assert_eq(da_fft(darr2, 13, axis=0),
              np_fft(nparr, 13, axis=0))
    assert_eq(da_fft(darr2, 12, axis=0),
              np_fft(nparr, 12, axis=0))

@pytest.mark.parametrize("funcname", all_funcnames)
def test_fft_consistent_names(funcname):
    da_fft = getattr(da.fft, funcname)

    assert same_keys(da_fft(darr, 5), da_fft(darr, 5))
    assert same_keys(da_fft(darr2, 5, axis=0), da_fft(darr2, 5, axis=0))
    assert not same_keys(da_fft(darr, 5), da_fft(darr, 13))

def test_wrap_bad_kind():
    with pytest.raises(ValueError):
        fft_wrap(np.ones)

@pytest.mark.parametrize("modname", ["numpy.fft", "scipy.fftpack"])
@pytest.mark.parametrize("funcname", all_funcnames)
@pytest.mark.parametrize("dtype", ["float32", "float64"])
def test_wrap_ffts(modname, funcname, dtype):
    fft_mod = pytest.importorskip(modname)
    try:
        func = getattr(fft_mod, funcname)
    except AttributeError:
        pytest.skip("`%s` missing function `%s`." % (modname, funcname))

    darrc = darr.astype(dtype)
    darr2c = darr2.astype(dtype)
    nparrc = nparr.astype(dtype)

    if modname == "scipy.fftpack" and "rfft" in funcname:
        with pytest.raises(ValueError):
            fft_wrap(func)
    else:
        wfunc = fft_wrap(func)
        assert wfunc(darrc).dtype == func(nparrc).dtype
        assert wfunc(darrc).shape == func(nparrc).shape
        assert_eq(wfunc(darrc), func(nparrc))
        assert_eq(wfunc(darrc, axis=1), func(nparrc, axis=1))
        assert_eq(wfunc(darr2c, axis=0), func(nparrc, axis=0))
        assert_eq(wfunc(darrc, n=len(darrc) - 1),
                  func(nparrc, n=len(darrc) - 1))
        assert_eq(wfunc(darrc, axis=1, n=darrc.shape[1] - 1),
                  func(nparrc, n=darrc.shape[1] - 1))
        assert_eq(wfunc(darr2c, axis=0, n=darr2c.shape[0] - 1),
                  func(nparrc, axis=0, n=darr2c.shape[0] - 1))
<|endoftext|>