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

#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause

# Build/Use ----------------------------------------------------------------------------------------
#
# 1) SoC with regular UART and optional Ethernet connected to the CPU:
# Connect a USB/UART to J19: TX of the FPGA is DATA_LED-, RX of the FPGA is KEY+.
# ./colorlight_5a_75x.py --revision=7.0 (or 6.1)  --build (--with-ethernet to add Ethernet capability)
# Note: on revision 6.1, add --uart-baudrate=9600 to lower the baudrate.
# ./colorlight_5a_75x.py --load
# You should see the LiteX BIOS and be able to interact with it.
#
# 2) SoC with UART in crossover mode over Etherbone:
# ./colorlight_5a_75x.py --revision=7.0 (or 6.1) --uart-name=crossover --with-etherbone --csr-csv=csr.csv --build
# ./colorlight_5a_75x.py --load
# ping 192.168.1.50
# Get and install wishbone tool from: https://github.com/litex-hub/wishbone-utils/releases
# wishbone-tool --ethernet-host 192.168.1.50 --server terminal --csr-csv csr.csv
# You should see the LiteX BIOS and be able to interact with it.
#
# 3) SoC with USB-ACM UART (on V7.0):
# - Replace U23 with a SN74CBT3245APWR or remove U23 and place jumper wires to make the ports bi-directional.
# - Place a 15K resistor between J4 pin 2 and J4 pin 4.
# - Place a 15K resistor between J4 pin 3 and J4 pin 4.
# - Place a 1.5K resistor between J4 pin 1 and J4 pin 3.
# - Connect USB DP (Green) to J4 pin 3, USB DN (White) to J4 pin 2.
# ./colorlight_5a_75x.py --revision=7.0 --uart-name=usb_acm  --build
# ./colorlight_5a_75x.py --load
# You should see the LiteX BIOS and be able to interact with it.
#
# Note that you can also use a 5A-75E board:
# ./colorlight_5a_75x.py --board=5a-75e --revision=7.1 (or 6.0) --build
#
# Disclaimer: SoC 2) is still a Proof of Concept with large timings violations on the IP/UDP and
# Etherbone stack that need to be optimized. It was initially just used to validate the reversed
# pinout but happens to work on hardware...

import os
import argparse
import sys

from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.build.io import DDROutput

from litex_boards.platforms import colorlight_5a_75b, colorlight_5a_75e

from litex.build.lattice.trellis import trellis_args, trellis_argdict

from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser

from litedram.modules import M12L16161A, M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY

from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII

# CRG ----------------------------------------------------------------------------------------------

class _CRG(Module):
    def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
        self.rst = Signal()
        self.clock_domains.cd_sys    = ClockDomain()
        if sdram_rate == "1:2":
            self.clock_domains.cd_sys2x    = ClockDomain()
            self.clock_domains.cd_sys2x_ps = ClockDomain(reset_less=True)
        else:
            self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)

        # # #

        # Clk / Rst
        if not use_internal_osc:
            clk = platform.request("clk25")
            clk_freq = 25e6
        else:
            clk = Signal()
            div = 5
            self.specials += Instance("OSCG",
                                p_DIV = div,
                                o_OSC = clk)
            clk_freq = 310e6/div

        rst_n = 1 if not with_rst else platform.request("user_btn_n", 0)

        # PLL
        self.submodules.pll = pll = ECP5PLL()
        self.comb += pll.reset.eq(~rst_n | self.rst)
        pll.register_clkin(clk, clk_freq)
        pll.create_clkout(self.cd_sys,    sys_clk_freq)
        if sdram_rate == "1:2":
            pll.create_clkout(self.cd_sys2x,    2*sys_clk_freq)
            pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
        else:
           pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.

        # USB PLL
        if with_usb_pll:
            self.submodules.usb_pll = usb_pll = ECP5PLL()
            self.comb += usb_pll.reset.eq(~rst_n | self.rst)
            usb_pll.register_clkin(clk, clk_freq)
            self.clock_domains.cd_usb_12 = ClockDomain()
            self.clock_domains.cd_usb_48 = ClockDomain()
            usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
            usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0)

        # SDRAM clock
        sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
        self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)

# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCCore):
    def __init__(self, board, revision, sys_clk_freq=60e6, with_ethernet=False,
                 with_etherbone=False, eth_ip="192.168.1.50", eth_phy=0, with_led_chaser=True,
                 use_internal_osc=False, sdram_rate="1:1", **kwargs):
        board = board.lower()
        assert board in ["5a-75b", "5a-75e"]
        if board == "5a-75b":
            platform = colorlight_5a_75b.Platform(revision=revision)
        elif board == "5a-75e":
            platform = colorlight_5a_75e.Platform(revision=revision)

        if board == "5a-75e" and revision == "6.0" and (with_etherbone or with_ethernet):
            assert use_internal_osc, "You cannot use the 25MHz clock as system clock since it is provided by the Ethernet PHY and will stop during PHY reset."

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self, platform, int(sys_clk_freq),
            ident          = "LiteX SoC on Colorlight " + board.upper(),
            ident_version  = True,
            **kwargs)

        # CRG --------------------------------------------------------------------------------------
        with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n.
        with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
        self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate)

        # SDR SDRAM --------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:
            sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY
            self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"), sys_clk_freq)
            if board == "5a-75e" and revision == "6.0":
                sdram_cls  = M12L64322A
            else:
                sdram_cls  = M12L16161A
            self.add_sdram("sdram",
                phy                     = self.sdrphy,
                module                  = sdram_cls(sys_clk_freq, sdram_rate),
                l2_cache_size           = kwargs.get("l2_size", 8192),
                l2_cache_full_memory_we = False,

            )

        # Ethernet / Etherbone ---------------------------------------------------------------------
        if with_ethernet or with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads = self.platform.request("eth_clocks", eth_phy),
                pads       = self.platform.request("eth", eth_phy),
                tx_delay   = 0e-9)
            if with_ethernet:
                self.add_ethernet(phy=self.ethphy)
            if with_etherbone:
                self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)

        # Leds -------------------------------------------------------------------------------------
        # Disable leds when serial is used.
        if platform.lookup_request("serial", loose=True) is None and with_led_chaser:
            self.submodules.leds = LedChaser(
                pads         = platform.request_all("user_led_n"),
                sys_clk_freq = sys_clk_freq)

# Build --------------------------------------------------------------------------------------------

def main():
    parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X")
    parser.add_argument("--build",             action="store_true",              help="Build bitstream.")
    parser.add_argument("--load",              action="store_true",              help="Load bitstream.")
    parser.add_argument("--board",             default="5a-75b",                 help="Board type (5a-75b or 5a-75e).")
    parser.add_argument("--revision",          default="7.0", type=str,          help="Board revision (7.0, 6.0 or 6.1).")
    parser.add_argument("--sys-clk-freq",      default=60e6,                     help="System clock frequency")
    ethopts = parser.add_mutually_exclusive_group()
    ethopts.add_argument("--with-ethernet",    action="store_true",              help="Enable Ethernet support.")
    ethopts.add_argument("--with-etherbone",   action="store_true",              help="Enable Etherbone support.")
    parser.add_argument("--eth-ip",            default="192.168.1.50", type=str, help="Ethernet/Etherbone IP address.")
    parser.add_argument("--eth-phy",           default=0, type=int,              help="Ethernet PHY (0 or 1).")
    parser.add_argument("--use-internal-osc",  action="store_true",              help="Use internal oscillator.")
    parser.add_argument("--sdram-rate",        default="1:1",                    help="SDRAM Rate (1:1 Full Rate or 1:2 Half Rate).")
    builder_args(parser)
    soc_core_args(parser)
    trellis_args(parser)
    args = parser.parse_args()

    soc = BaseSoC(board=args.board, revision=args.revision,
        sys_clk_freq     = int(float(args.sys_clk_freq)),
        with_ethernet    = args.with_ethernet,
        with_etherbone   = args.with_etherbone,
        eth_ip           = args.eth_ip,
        eth_phy          = args.eth_phy,
        use_internal_osc = args.use_internal_osc,
        sdram_rate       = args.sdram_rate,
        **soc_core_argdict(args)
    )
    builder = Builder(soc, **builder_argdict(args))
    builder.build(**trellis_argdict(args), run=args.build)

    if args.load:
        prog = soc.platform.create_programmer()
        prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))

if __name__ == "__main__":
    main()
<commit_msg>targets/colorlight_5a_75x: List 8.0 in supported revision.<commit_after>#!/usr/bin/env python3

#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause

# Build/Use ----------------------------------------------------------------------------------------
#
# 1) SoC with regular UART and optional Ethernet connected to the CPU:
# Connect a USB/UART to J19: TX of the FPGA is DATA_LED-, RX of the FPGA is KEY+.
# ./colorlight_5a_75x.py --revision=7.0 (or 6.1)  --build (--with-ethernet to add Ethernet capability)
# Note: on revision 6.1, add --uart-baudrate=9600 to lower the baudrate.
# ./colorlight_5a_75x.py --load
# You should see the LiteX BIOS and be able to interact with it.
#
# 2) SoC with UART in crossover mode over Etherbone:
# ./colorlight_5a_75x.py --revision=7.0 (or 6.1) --uart-name=crossover --with-etherbone --csr-csv=csr.csv --build
# ./colorlight_5a_75x.py --load
# ping 192.168.1.50
# Get and install wishbone tool from: https://github.com/litex-hub/wishbone-utils/releases
# wishbone-tool --ethernet-host 192.168.1.50 --server terminal --csr-csv csr.csv
# You should see the LiteX BIOS and be able to interact with it.
#
# 3) SoC with USB-ACM UART (on V7.0):
# - Replace U23 with a SN74CBT3245APWR or remove U23 and place jumper wires to make the ports bi-directional.
# - Place a 15K resistor between J4 pin 2 and J4 pin 4.
# - Place a 15K resistor between J4 pin 3 and J4 pin 4.
# - Place a 1.5K resistor between J4 pin 1 and J4 pin 3.
# - Connect USB DP (Green) to J4 pin 3, USB DN (White) to J4 pin 2.
# ./colorlight_5a_75x.py --revision=7.0 --uart-name=usb_acm  --build
# ./colorlight_5a_75x.py --load
# You should see the LiteX BIOS and be able to interact with it.
#
# Note that you can also use a 5A-75E board:
# ./colorlight_5a_75x.py --board=5a-75e --revision=7.1 (or 6.0) --build
#
# Disclaimer: SoC 2) is still a Proof of Concept with large timings violations on the IP/UDP and
# Etherbone stack that need to be optimized. It was initially just used to validate the reversed
# pinout but happens to work on hardware...

import os
import argparse
import sys

from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.build.io import DDROutput

from litex_boards.platforms import colorlight_5a_75b, colorlight_5a_75e

from litex.build.lattice.trellis import trellis_args, trellis_argdict

from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser

from litedram.modules import M12L16161A, M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY

from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII

# CRG ----------------------------------------------------------------------------------------------

class _CRG(Module):
    def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
        self.rst = Signal()
        self.clock_domains.cd_sys    = ClockDomain()
        if sdram_rate == "1:2":
            self.clock_domains.cd_sys2x    = ClockDomain()
            self.clock_domains.cd_sys2x_ps = ClockDomain(reset_less=True)
        else:
            self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)

        # # #

        # Clk / Rst
        if not use_internal_osc:
            clk = platform.request("clk25")
            clk_freq = 25e6
        else:
            clk = Signal()
            div = 5
            self.specials += Instance("OSCG",
                                p_DIV = div,
                                o_OSC = clk)
            clk_freq = 310e6/div

        rst_n = 1 if not with_rst else platform.request("user_btn_n", 0)

        # PLL
        self.submodules.pll = pll = ECP5PLL()
        self.comb += pll.reset.eq(~rst_n | self.rst)
        pll.register_clkin(clk, clk_freq)
        pll.create_clkout(self.cd_sys,    sys_clk_freq)
        if sdram_rate == "1:2":
            pll.create_clkout(self.cd_sys2x,    2*sys_clk_freq)
            pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
        else:
           pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.

        # USB PLL
        if with_usb_pll:
            self.submodules.usb_pll = usb_pll = ECP5PLL()
            self.comb += usb_pll.reset.eq(~rst_n | self.rst)
            usb_pll.register_clkin(clk, clk_freq)
            self.clock_domains.cd_usb_12 = ClockDomain()
            self.clock_domains.cd_usb_48 = ClockDomain()
            usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
            usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0)

        # SDRAM clock
        sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
        self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)

# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCCore):
    def __init__(self, board, revision, sys_clk_freq=60e6, with_ethernet=False,
                 with_etherbone=False, eth_ip="192.168.1.50", eth_phy=0, with_led_chaser=True,
                 use_internal_osc=False, sdram_rate="1:1", **kwargs):
        board = board.lower()
        assert board in ["5a-75b", "5a-75e"]
        if board == "5a-75b":
            platform = colorlight_5a_75b.Platform(revision=revision)
        elif board == "5a-75e":
            platform = colorlight_5a_75e.Platform(revision=revision)

        if board == "5a-75e" and revision == "6.0" and (with_etherbone or with_ethernet):
            assert use_internal_osc, "You cannot use the 25MHz clock as system clock since it is provided by the Ethernet PHY and will stop during PHY reset."

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self, platform, int(sys_clk_freq),
            ident          = "LiteX SoC on Colorlight " + board.upper(),
            ident_version  = True,
            **kwargs)

        # CRG --------------------------------------------------------------------------------------
        with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n.
        with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
        self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate)

        # SDR SDRAM --------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:
            sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY
            self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"), sys_clk_freq)
            if board == "5a-75e" and revision == "6.0":
                sdram_cls  = M12L64322A
            else:
                sdram_cls  = M12L16161A
            self.add_sdram("sdram",
                phy                     = self.sdrphy,
                module                  = sdram_cls(sys_clk_freq, sdram_rate),
                l2_cache_size           = kwargs.get("l2_size", 8192),
                l2_cache_full_memory_we = False,

            )

        # Ethernet / Etherbone ---------------------------------------------------------------------
        if with_ethernet or with_etherbone:
            self.submodules.ethphy = LiteEthPHYRGMII(
                clock_pads = self.platform.request("eth_clocks", eth_phy),
                pads       = self.platform.request("eth", eth_phy),
                tx_delay   = 0e-9)
            if with_ethernet:
                self.add_ethernet(phy=self.ethphy)
            if with_etherbone:
                self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)

        # Leds -------------------------------------------------------------------------------------
        # Disable leds when serial is used.
        if platform.lookup_request("serial", loose=True) is None and with_led_chaser:
            self.submodules.leds = LedChaser(
                pads         = platform.request_all("user_led_n"),
                sys_clk_freq = sys_clk_freq)

# Build --------------------------------------------------------------------------------------------

def main():
    parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight 5A-75X")
    parser.add_argument("--build",             action="store_true",              help="Build bitstream.")
    parser.add_argument("--load",              action="store_true",              help="Load bitstream.")
    parser.add_argument("--board",             default="5a-75b",                 help="Board type (5a-75b or 5a-75e).")
    parser.add_argument("--revision",          default="7.0", type=str,          help="Board revision (6.0, 6.1, 7.0 or 8.0).")
    parser.add_argument("--sys-clk-freq",      default=60e6,                     help="System clock frequency")
    ethopts = parser.add_mutually_exclusive_group()
    ethopts.add_argument("--with-ethernet",    action="store_true",              help="Enable Ethernet support.")
    ethopts.add_argument("--with-etherbone",   action="store_true",              help="Enable Etherbone support.")
    parser.add_argument("--eth-ip",            default="192.168.1.50", type=str, help="Ethernet/Etherbone IP address.")
    parser.add_argument("--eth-phy",           default=0, type=int,              help="Ethernet PHY (0 or 1).")
    parser.add_argument("--use-internal-osc",  action="store_true",              help="Use internal oscillator.")
    parser.add_argument("--sdram-rate",        default="1:1",                    help="SDRAM Rate (1:1 Full Rate or 1:2 Half Rate).")
    builder_args(parser)
    soc_core_args(parser)
    trellis_args(parser)
    args = parser.parse_args()

    soc = BaseSoC(board=args.board, revision=args.revision,
        sys_clk_freq     = int(float(args.sys_clk_freq)),
        with_ethernet    = args.with_ethernet,
        with_etherbone   = args.with_etherbone,
        eth_ip           = args.eth_ip,
        eth_phy          = args.eth_phy,
        use_internal_osc = args.use_internal_osc,
        sdram_rate       = args.sdram_rate,
        **soc_core_argdict(args)
    )
    builder = Builder(soc, **builder_argdict(args))
    builder.build(**trellis_argdict(args), run=args.build)

    if args.load:
        prog = soc.platform.create_programmer()
        prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".svf"))

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


<commit_before>import gzip
import os

from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connection

def _newfile(counter):
    """Generate a new sitemap filename based on count."""
    name = '%s/sitemap-%s.xml.gz' % (settings.SITEMAPS_DIR,
        counter)
    fp = gzip.open(name, 'wb')
    fp.write("""<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""")
    return fp

def _newurl(counter):
    """Generate the <loc> URL for a sitemap file based on count."""
    return "%s/sitemap-%s.xml.gz" % (settings.SITEMAPS_BASE_URL, counter)

class Command(BaseCommand):
    help = 'Generate sitemap files'

    def handle(self, *args, **options):
        # first, clear out the existing files
        print 'Removing old files'
        for old_file in os.listdir(settings.SITEMAPS_DIR):
            os.remove('%s/%s' % (settings.SITEMAPS_DIR, old_file))
        print 'Generating maps'
        cursor = connection.cursor()
        query = """SELECT BIB_ID FROM bib_master
            WHERE SUPPRESS_IN_OPAC = 'N'
            """
        cursor.execute(query)
        index_file = '%s/sitemap-index.xml' % settings.SITEMAPS_DIR
        fp_index = open(index_file, 'wb')
        fp_index.write("""<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""")
        i = j = 0
        fp = _newfile(j)
        line = "<sitemap><loc>%s</loc></sitemap>\n" % _newurl(j)
        fp_index.write(line)
        row = cursor.fetchone()
        while row:
            line = '<url><loc>%s/item/%s</loc></url>\n' % \
                (settings.SITEMAPS_BASE_URL, row[0])
            fp.write(line)
            if i == 49990:
                i = 0
                j += 1
                fp.write('</urlset>')
                fp.close()
                fp = _newfile(j)
                line = "<sitemap><loc>%s</loc></sitemap>\n" % _newurl(j)
                fp_index.write(line)
                print '%s - %s' % (j, row[0])
            else:
                i += 1
            row = cursor.fetchone()
        if fp:
            fp.write('</urlset>\n')
            fp.close()
        fp_index.write("""</sitemapindex>\n""")
        fp_index.close()
<commit_msg>fix make_sitemaps to find voyager<commit_after>import gzip
import os

from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connections

def _newfile(counter):
    """Generate a new sitemap filename based on count."""
    name = '%s/sitemap-%s.xml.gz' % (settings.SITEMAPS_DIR,
        counter)
    fp = gzip.open(name, 'wb')
    fp.write("""<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""")
    return fp

def _newurl(counter):
    """Generate the <loc> URL for a sitemap file based on count."""
    return "%s/sitemap-%s.xml.gz" % (settings.SITEMAPS_BASE_URL, counter)

class Command(BaseCommand):
    help = 'Generate sitemap files'

    def handle(self, *args, **options):
        # first, clear out the existing files
        print 'Removing old files'
        for old_file in os.listdir(settings.SITEMAPS_DIR):
            os.remove('%s/%s' % (settings.SITEMAPS_DIR, old_file))
        print 'Generating maps'
        cursor = connections['voyager'].cursor()
        query = """SELECT BIB_ID FROM bib_master
            WHERE SUPPRESS_IN_OPAC = 'N'
            """
        cursor.execute(query)
        index_file = '%s/sitemap-index.xml' % settings.SITEMAPS_DIR
        fp_index = open(index_file, 'wb')
        fp_index.write("""<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n""")
        i = j = 0
        fp = _newfile(j)
        line = "<sitemap><loc>%s</loc></sitemap>\n" % _newurl(j)
        fp_index.write(line)
        row = cursor.fetchone()
        while row:
            line = '<url><loc>%s/item/%s</loc></url>\n' % \
                (settings.SITEMAPS_BASE_URL, row[0])
            fp.write(line)
            if i == 49990:
                i = 0
                j += 1
                fp.write('</urlset>')
                fp.close()
                fp = _newfile(j)
                line = "<sitemap><loc>%s</loc></sitemap>\n" % _newurl(j)
                fp_index.write(line)
                print '%s - %s' % (j, row[0])
            else:
                i += 1
            row = cursor.fetchone()
        if fp:
            fp.write('</urlset>\n')
            fp.close()
        fp_index.write("""</sitemapindex>\n""")
        fp_index.close()
<|endoftext|>


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

# internal imports
import tensorflow as tf

def run_training(build_graph_fn, train_dir, num_training_steps=None,
                 summary_frequency=10, save_checkpoint_secs=60,
                 checkpoints_to_keep=10, master='', task=0, num_ps_tasks=0):
  """Runs the training loop.

  Args:
    build_graph_fn: A function that builds the graph ops.
    train_dir: The path to the directory where checkpoints and summary events
        will be written to.
    num_training_steps: The number of steps to train for before exiting.
    summary_frequency: The number of steps between each summary. A summary is
        when graph values from the last step are logged to the console and
        written to disk.
    save_checkpoint_secs: The frequency at which to save checkpoints, in
        seconds.
    checkpoints_to_keep: The number of most recent checkpoints to keep in
       `train_dir`. Keeps all if set to 0.
    master: URL of the Tensorflow master.
    task: Task number for this worker.
    num_ps_tasks: Number of parameter server tasks.
  """
  with tf.Graph().as_default():
    with tf.device(tf.train.replica_device_setter(num_ps_tasks)):
      build_graph_fn()

      global_step = tf.train.get_or_create_global_step()
      loss = tf.get_collection('loss')[0]
      perplexity = tf.get_collection('metrics/perplexity')[0]
      accuracy = tf.get_collection('metrics/accuracy')[0]
      train_op = tf.get_collection('train_op')[0]

      logging_dict = {
          'Global Step': global_step,
          'Loss': loss,
          'Perplexity': perplexity,
          'Accuracy': accuracy
      }
      hooks = [
          tf.train.NanTensorHook(loss),
          tf.train.LoggingTensorHook(
              logging_dict, every_n_iter=summary_frequency),
          tf.train.StepCounterHook(
              output_dir=train_dir, every_n_steps=summary_frequency)
      ]
      if num_training_steps:
        hooks.append(tf.train.StopAtStepHook(num_training_steps))

      scaffold = tf.train.Scaffold(
          saver=tf.train.Saver(max_to_keep=checkpoints_to_keep))

      tf.logging.info('Starting training loop...')
      tf.contrib.training.train(
          train_op=train_op,
          logdir=train_dir,
          scaffold=scaffold,
          hooks=hooks,
          save_checkpoint_secs=save_checkpoint_secs,
          save_summaries_steps=summary_frequency,
          master=master,
          is_chief=task == 0)
      tf.logging.info('Training complete.')

# TODO(adarob): Limit to a single epoch each evaluation step.
def run_eval(build_graph_fn, train_dir, eval_dir, num_batches,
             timeout_secs=300):
  """Runs the training loop.

  Args:
    build_graph_fn: A function that builds the graph ops.
    train_dir: The path to the directory where checkpoints will be loaded
        from for evaluation.
    eval_dir: The path to the directory where the evaluation summary events
        will be written to.
    num_batches: The number of full batches to use for each evaluation step.
    timeout_secs: The number of seconds after which to stop waiting for a new
        checkpoint.
  """
  with tf.Graph().as_default():
    build_graph_fn()

    global_step = tf.train.get_or_create_global_step()
    loss = tf.get_collection('loss')[0]
    perplexity = tf.get_collection('metrics/perplexity')[0]
    accuracy = tf.get_collection('metrics/accuracy')[0]
    eval_ops = tf.get_collection('eval_ops')

    logging_dict = {
        'Global Step': global_step,
        'Loss': loss,
        'Perplexity': perplexity,
        'Accuracy': accuracy
    }
    hooks = [
        EvalLoggingTensorHook(logging_dict, every_n_iter=num_batches),
        tf.contrib.training.StopAfterNEvalsHook(num_batches),
        tf.contrib.training.SummaryAtEndHook(eval_dir),
    ]

    tf.contrib.training.evaluate_repeatedly(
        train_dir,
        eval_ops=eval_ops,
        hooks=hooks,
        eval_interval_secs=60,
        timeout=timeout_secs)

class EvalLoggingTensorHook(tf.train.LoggingTensorHook):
  """A revised version of LoggingTensorHook to use during evaluation.

  This version supports being reset and increments `_iter_count` before run
  instead of after run.
  """

  def begin(self):
    # Reset timer.
    self._timer.update_last_triggered_step(0)
    super(EvalLoggingTensorHook, self).begin()

  def before_run(self, run_context):
    self._iter_count += 1
    return super(EvalLoggingTensorHook, self).before_run(run_context)

  def after_run(self, run_context, run_values):
    super(EvalLoggingTensorHook, self).after_run(run_context, run_values)
    self._iter_count -= 1
<commit_msg>save a checkpoint every hour during training (#1185)<commit_after># Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Train and evaluate an event sequence RNN model."""

# internal imports
import tensorflow as tf

def run_training(build_graph_fn, train_dir, num_training_steps=None,
                 summary_frequency=10, save_checkpoint_secs=60,
                 checkpoints_to_keep=10, keep_checkpoint_every_n_hours=1,
                 master='', task=0, num_ps_tasks=0):
  """Runs the training loop.

  Args:
    build_graph_fn: A function that builds the graph ops.
    train_dir: The path to the directory where checkpoints and summary events
        will be written to.
    num_training_steps: The number of steps to train for before exiting.
    summary_frequency: The number of steps between each summary. A summary is
        when graph values from the last step are logged to the console and
        written to disk.
    save_checkpoint_secs: The frequency at which to save checkpoints, in
        seconds.
    checkpoints_to_keep: The number of most recent checkpoints to keep in
       `train_dir`. Keeps all if set to 0.
    keep_checkpoint_every_n_hours: Keep a checkpoint every N hours, even if it
        results in more checkpoints than checkpoints_to_keep.
    master: URL of the Tensorflow master.
    task: Task number for this worker.
    num_ps_tasks: Number of parameter server tasks.
  """
  with tf.Graph().as_default():
    with tf.device(tf.train.replica_device_setter(num_ps_tasks)):
      build_graph_fn()

      global_step = tf.train.get_or_create_global_step()
      loss = tf.get_collection('loss')[0]
      perplexity = tf.get_collection('metrics/perplexity')[0]
      accuracy = tf.get_collection('metrics/accuracy')[0]
      train_op = tf.get_collection('train_op')[0]

      logging_dict = {
          'Global Step': global_step,
          'Loss': loss,
          'Perplexity': perplexity,
          'Accuracy': accuracy
      }
      hooks = [
          tf.train.NanTensorHook(loss),
          tf.train.LoggingTensorHook(
              logging_dict, every_n_iter=summary_frequency),
          tf.train.StepCounterHook(
              output_dir=train_dir, every_n_steps=summary_frequency)
      ]
      if num_training_steps:
        hooks.append(tf.train.StopAtStepHook(num_training_steps))

      scaffold = tf.train.Scaffold(
          saver=tf.train.Saver(
              max_to_keep=checkpoints_to_keep,
              keep_checkpoint_every_n_hours=keep_checkpoint_every_n_hours))

      tf.logging.info('Starting training loop...')
      tf.contrib.training.train(
          train_op=train_op,
          logdir=train_dir,
          scaffold=scaffold,
          hooks=hooks,
          save_checkpoint_secs=save_checkpoint_secs,
          save_summaries_steps=summary_frequency,
          master=master,
          is_chief=task == 0)
      tf.logging.info('Training complete.')

# TODO(adarob): Limit to a single epoch each evaluation step.
def run_eval(build_graph_fn, train_dir, eval_dir, num_batches,
             timeout_secs=300):
  """Runs the training loop.

  Args:
    build_graph_fn: A function that builds the graph ops.
    train_dir: The path to the directory where checkpoints will be loaded
        from for evaluation.
    eval_dir: The path to the directory where the evaluation summary events
        will be written to.
    num_batches: The number of full batches to use for each evaluation step.
    timeout_secs: The number of seconds after which to stop waiting for a new
        checkpoint.
  """
  with tf.Graph().as_default():
    build_graph_fn()

    global_step = tf.train.get_or_create_global_step()
    loss = tf.get_collection('loss')[0]
    perplexity = tf.get_collection('metrics/perplexity')[0]
    accuracy = tf.get_collection('metrics/accuracy')[0]
    eval_ops = tf.get_collection('eval_ops')

    logging_dict = {
        'Global Step': global_step,
        'Loss': loss,
        'Perplexity': perplexity,
        'Accuracy': accuracy
    }
    hooks = [
        EvalLoggingTensorHook(logging_dict, every_n_iter=num_batches),
        tf.contrib.training.StopAfterNEvalsHook(num_batches),
        tf.contrib.training.SummaryAtEndHook(eval_dir),
    ]

    tf.contrib.training.evaluate_repeatedly(
        train_dir,
        eval_ops=eval_ops,
        hooks=hooks,
        eval_interval_secs=60,
        timeout=timeout_secs)

class EvalLoggingTensorHook(tf.train.LoggingTensorHook):
  """A revised version of LoggingTensorHook to use during evaluation.

  This version supports being reset and increments `_iter_count` before run
  instead of after run.
  """

  def begin(self):
    # Reset timer.
    self._timer.update_last_triggered_step(0)
    super(EvalLoggingTensorHook, self).begin()

  def before_run(self, run_context):
    self._iter_count += 1
    return super(EvalLoggingTensorHook, self).before_run(run_context)

  def after_run(self, run_context, run_values):
    super(EvalLoggingTensorHook, self).after_run(run_context, run_values)
    self._iter_count -= 1
<|endoftext|>


<commit_before>from pprint import pprint

from django.db import connections

from base.models import Colaborador
from systextil.models import Usuario as S_Usuario

from estoque import models

class ObjDocMovStq():

    def __init__(self, num_doc, descricao, user):
        self.num_doc = num_doc
        self.descricao = descricao
        self.user = user

        self.cursor = connections['so'].cursor()

        self.get_num_doc()

        self.valid_user()

    def get_num_doc(self):
        if self.num_doc == '0':
            self.cria_num_doc()
        else:
            self.valid_num_doc()
            self.valid_user()

    def valid_num_doc(self):
        docs_mov_stq = models.DocMovStq.objects.filter(
            num_doc=self.num_doc, usuario=self.user)
        if len(docs_mov_stq) == 0:
            raise ValueError('Número de documento não encontrado.')
        else:
            self.doc_mov_stq = docs_mov_stq[0]

    def cria_num_doc(self):
        self.valid_descricao()
        self.valid_user()

        self.doc_mov_stq = models.DocMovStq(
            descricao=self.descricao,
            usuario=self.user,
        )
        self.doc_mov_stq.save()
        self.num_doc = self.doc_mov_stq.get_num_doc

    def valid_descricao(self):
        if self.descricao.strip() == '':
            raise ValueError(
                'Não é possível criar um número de documento sem uma '
                'descrição.')

    def valid_user(self):
        try:
            colab = Colaborador.objects.get(user=self.user)
        except Colaborador.DoesNotExist as e:
            raise ValueError(
                'Não é possível utilizar um usuário que não está cadastrado '
                'como colaborador.')

        try:
            s_user = S_Usuario.objects.get(codigo_usuario=colab.matricula)
        except S_Usuario.DoesNotExist as e:
            raise ValueError(
                'Não é possível utilizar um colaborador sem matrícula válida '
                'ou inativo.')
<commit_msg>chamada de valid_user estava redundante<commit_after>from pprint import pprint

from django.db import connections

from base.models import Colaborador
from systextil.models import Usuario as S_Usuario

from estoque import models

class ObjDocMovStq():

    def __init__(self, num_doc, descricao, user):
        self.num_doc = num_doc
        self.descricao = descricao
        self.user = user

        self.cursor = connections['so'].cursor()

        self.get_num_doc()

    def get_num_doc(self):
        if self.num_doc == '0':
            self.cria_num_doc()
        else:
            self.valid_num_doc()
            self.valid_user()

    def valid_num_doc(self):
        docs_mov_stq = models.DocMovStq.objects.filter(
            num_doc=self.num_doc, usuario=self.user)
        if len(docs_mov_stq) == 0:
            raise ValueError('Número de documento não encontrado.')
        else:
            self.doc_mov_stq = docs_mov_stq[0]

    def cria_num_doc(self):
        self.valid_descricao()
        self.valid_user()

        self.doc_mov_stq = models.DocMovStq(
            descricao=self.descricao,
            usuario=self.user,
        )
        self.doc_mov_stq.save()
        self.num_doc = self.doc_mov_stq.get_num_doc

    def valid_descricao(self):
        if self.descricao.strip() == '':
            raise ValueError(
                'Não é possível criar um número de documento sem uma '
                'descrição.')

    def valid_user(self):
        try:
            colab = Colaborador.objects.get(user=self.user)
        except Colaborador.DoesNotExist as e:
            raise ValueError(
                'Não é possível utilizar um usuário que não está cadastrado '
                'como colaborador.')

        try:
            s_user = S_Usuario.objects.get(codigo_usuario=colab.matricula)
        except S_Usuario.DoesNotExist as e:
            raise ValueError(
                'Não é possível utilizar um colaborador sem matrícula válida '
                'ou inativo.')
<|endoftext|>


<commit_before>"""
Targeting logic
"""

from enum import IntEnum
from .enums import CardType, PlayReq
from .utils import CardList

# Requirements-based targeting
def isValidTarget(self, target, requirements=None):
	if target.type == CardType.MINION:
		if target.dead:
			return False
		if target.stealthed and self.controller != target.controller:
			return False
		if target.immune and self.controller != target.controller:
			return False
		if self.type == CardType.SPELL and target.cantBeTargetedByAbilities:
			return False
		if self.type == CardType.HERO_POWER and target.cantBeTargetedByHeroPowers:
			return False

	if requirements is None:
		requirements = self.requirements

	for req, param in requirements.items():
		if req == PlayReq.REQ_MINION_TARGET:
			if target.type != CardType.MINION:
				return False
		elif req == PlayReq.REQ_FRIENDLY_TARGET:
			if target.controller != self.controller:
				return False
		elif req == PlayReq.REQ_ENEMY_TARGET:
			if target.controller == self.controller:
				return False
		elif req == PlayReq.REQ_DAMAGED_TARGET:
			if not target.damage:
				return False
		elif req == PlayReq.REQ_TARGET_MAX_ATTACK:
			if target.atk > param or 0:
				return False
		elif req == PlayReq.REQ_NONSELF_TARGET:
			if target is self:
				return False
		elif req == PlayReq.REQ_TARGET_WITH_RACE:
			if target.type != CardType.MINION or target.race != param:
				return False
		elif req == PlayReq.REQ_HERO_TARGET:
			if target.type != CardType.HERO:
				return False
		elif req == PlayReq.REQ_TARGET_MIN_ATTACK:
			if target.atk < param or 0:
				return False
		elif req == PlayReq.REQ_MUST_TARGET_TAUNTER:
			if not target.taunt:
				return False
		elif req == PlayReq.REQ_UNDAMAGED_TARGET:
			if target.damage:
				return False

		# fireplace reqs
		elif req == PlayReq.REQ_SPELL_TARGET:
			if target.type != CardType.SPELL:
				return False
		elif req == PlayReq.REQ_WEAPON_TARGET:
			if target.type != CardType.WEAPON:
				return False
		elif req == PlayReq.REQ_NO_MINIONS_PLAYED_THIS_TURN:
			if self.controller.minionsPlayedThisTurn:
				return False
		elif req == PlayReq.REQ_TARGET_HAS_BATTLECRY:
			if not target.hasBattlecry:
				return False
		elif req == PlayReq.REQ_SOURCE_IS_ENRAGED:
			if not self.enraged:
				return False
	return True

class Selector:
	"""
	A Forth-like program consisting of methods of Selector and members of
	IntEnum classes. The IntEnums must have appropriate test() methods
	    def test(self, entity)
	returning a boolean, true if entity matches the condition.
	"""
	class MergeFilter:
		"""
		Signals the start of a merge: the following commands define the filter
		to be passed after Merge
		"""
		pass

	class Merge:
		"""
		Ops between Merge and Unmerge are classes with merge() methods
		    def merge(self, selector, entities)
		that operate on the full collection specified by the ops between
		MergeFilter and Merge.
		"""
		pass

	class Unmerge:
		pass

	def __init__(self, *args):
		self.program = []
		first = True
		for arg in args:
			self.program.append(arg)
			if not first:
				self.program.append(Selector._or)
			first = False

	def __repr__(self):
		prog = []
		for op in self.program:
			name = ""
			if hasattr(op, "__name__"):
				name = op.__name__
			elif isinstance(op, IntEnum):
				name = op.name
			else:
				name = repr(op)
			prog.append(name.lstrip("_"))
		return "<{}: {}>".format(self.__class__.__name__, " ".join(prog))

	def __or__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._or)
		return result

	def __add__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._and)
		return result

	def __sub__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program += [Selector._not, Selector._and]
		return result

	def eval(self, entities, source):
		self.opc = 0 # outer program counter
		result = []
		while self.opc < len(self.program):
			if self.program[self.opc] != Selector.MergeFilter:
				result += [e for e in entities if self.test(e, source)]
				self.opc = self.pc
				if self.opc >= len(self.program):
					break
			else:
				self.opc += 1
			# handle merge step:
			merge_input = CardList([e for e in entities if self.test(e, source)])
			self.opc = self.pc
			merge_output = CardList()
			while self.opc < len(self.program):
				op = self.program[self.opc]
				self.opc += 1
				if op == Selector.Unmerge:
					break
				merge_output += op.merge(self, merge_input)
			negated = False
			combined = False
			while self.opc < len(self.program):
				# special handling for operators on merged collections:
				op = self.program[self.opc]
				if op == Selector._or:
					result += [e for e in merge_output]
					combined = True
				elif op == Selector._and:
					result = [e for e in result if (e in merge_output) != negated]
					combined = True
				elif op == Selector._not:
					negated = not negated
				else:
					break
				self.opc += 1
			if not combined:
				# assume or
				result += merge_output
		return result

	def test(self, entity, source):
		stack = []
		self.pc = self.opc # program counter
		while self.pc < len(self.program):
			op = self.program[self.pc]
			self.pc += 1
			if op == Selector.Merge or op == Selector.MergeFilter:
				break
			if callable(op):
				op(self, stack)
			else:
				val = type(op).test(op, entity, source)
				stack.append(val)
		return stack[-1]

	# boolean ops:
	def _and(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a and b)

	def _or(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a or b)

	def _not(self, stack):
		stack.append(not stack.pop())
<commit_msg>Implement SelfSelector<commit_after>"""
Targeting logic
"""

from enum import IntEnum
from .enums import CardType, PlayReq
from .utils import CardList

# Requirements-based targeting
def isValidTarget(self, target, requirements=None):
	if target.type == CardType.MINION:
		if target.dead:
			return False
		if target.stealthed and self.controller != target.controller:
			return False
		if target.immune and self.controller != target.controller:
			return False
		if self.type == CardType.SPELL and target.cantBeTargetedByAbilities:
			return False
		if self.type == CardType.HERO_POWER and target.cantBeTargetedByHeroPowers:
			return False

	if requirements is None:
		requirements = self.requirements

	for req, param in requirements.items():
		if req == PlayReq.REQ_MINION_TARGET:
			if target.type != CardType.MINION:
				return False
		elif req == PlayReq.REQ_FRIENDLY_TARGET:
			if target.controller != self.controller:
				return False
		elif req == PlayReq.REQ_ENEMY_TARGET:
			if target.controller == self.controller:
				return False
		elif req == PlayReq.REQ_DAMAGED_TARGET:
			if not target.damage:
				return False
		elif req == PlayReq.REQ_TARGET_MAX_ATTACK:
			if target.atk > param or 0:
				return False
		elif req == PlayReq.REQ_NONSELF_TARGET:
			if target is self:
				return False
		elif req == PlayReq.REQ_TARGET_WITH_RACE:
			if target.type != CardType.MINION or target.race != param:
				return False
		elif req == PlayReq.REQ_HERO_TARGET:
			if target.type != CardType.HERO:
				return False
		elif req == PlayReq.REQ_TARGET_MIN_ATTACK:
			if target.atk < param or 0:
				return False
		elif req == PlayReq.REQ_MUST_TARGET_TAUNTER:
			if not target.taunt:
				return False
		elif req == PlayReq.REQ_UNDAMAGED_TARGET:
			if target.damage:
				return False

		# fireplace reqs
		elif req == PlayReq.REQ_SPELL_TARGET:
			if target.type != CardType.SPELL:
				return False
		elif req == PlayReq.REQ_WEAPON_TARGET:
			if target.type != CardType.WEAPON:
				return False
		elif req == PlayReq.REQ_NO_MINIONS_PLAYED_THIS_TURN:
			if self.controller.minionsPlayedThisTurn:
				return False
		elif req == PlayReq.REQ_TARGET_HAS_BATTLECRY:
			if not target.hasBattlecry:
				return False
		elif req == PlayReq.REQ_SOURCE_IS_ENRAGED:
			if not self.enraged:
				return False
	return True

class Selector:
	"""
	A Forth-like program consisting of methods of Selector and members of
	IntEnum classes. The IntEnums must have appropriate test() methods
	    def test(self, entity)
	returning a boolean, true if entity matches the condition.
	"""
	class MergeFilter:
		"""
		Signals the start of a merge: the following commands define the filter
		to be passed after Merge
		"""
		pass

	class Merge:
		"""
		Ops between Merge and Unmerge are classes with merge() methods
		    def merge(self, selector, entities)
		that operate on the full collection specified by the ops between
		MergeFilter and Merge.
		"""
		pass

	class Unmerge:
		pass

	def __init__(self, *args):
		self.program = []
		first = True
		for arg in args:
			self.program.append(arg)
			if not first:
				self.program.append(Selector._or)
			first = False

	def __repr__(self):
		prog = []
		for op in self.program:
			name = ""
			if hasattr(op, "__name__"):
				name = op.__name__
			elif isinstance(op, IntEnum):
				name = op.name
			else:
				name = repr(op)
			prog.append(name.lstrip("_"))
		return "<{}: {}>".format(self.__class__.__name__, " ".join(prog))

	def __or__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._or)
		return result

	def __add__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._and)
		return result

	def __sub__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program += [Selector._not, Selector._and]
		return result

	def eval(self, entities, source):
		self.opc = 0 # outer program counter
		result = []
		while self.opc < len(self.program):
			if self.program[self.opc] != Selector.MergeFilter:
				result += [e for e in entities if self.test(e, source)]
				self.opc = self.pc
				if self.opc >= len(self.program):
					break
			else:
				self.opc += 1
			# handle merge step:
			merge_input = CardList([e for e in entities if self.test(e, source)])
			self.opc = self.pc
			merge_output = CardList()
			while self.opc < len(self.program):
				op = self.program[self.opc]
				self.opc += 1
				if op == Selector.Unmerge:
					break
				merge_output += op.merge(self, merge_input)
			negated = False
			combined = False
			while self.opc < len(self.program):
				# special handling for operators on merged collections:
				op = self.program[self.opc]
				if op == Selector._or:
					result += [e for e in merge_output]
					combined = True
				elif op == Selector._and:
					result = [e for e in result if (e in merge_output) != negated]
					combined = True
				elif op == Selector._not:
					negated = not negated
				else:
					break
				self.opc += 1
			if not combined:
				# assume or
				result += merge_output
		return result

	def test(self, entity, source):
		stack = []
		self.pc = self.opc # program counter
		while self.pc < len(self.program):
			op = self.program[self.pc]
			self.pc += 1
			if op == Selector.Merge or op == Selector.MergeFilter:
				break
			if callable(op):
				op(self, stack)
			else:
				val = type(op).test(op, entity, source)
				stack.append(val)
		return stack[-1]

	# boolean ops:
	def _and(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a and b)

	def _or(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a or b)

	def _not(self, stack):
		stack.append(not stack.pop())

class SelfSelector(Selector):
	"""
	Selects the source.
	"""
	class IsSelf:
		def test(self, entity, source):
			return entity is source

	def __init__(self):
		self.program = [self.IsSelf()]

	def eval(self, entities, source):
		return [source]

	def test(self, entity, source):
		return entity is source

SELF = SelfSelector()
<|endoftext|>


<commit_before>"""
Targeting logic
"""

import random
from enum import IntEnum
from .enums import Affiliation, CardType, PlayReq, Race, Zone
from .utils import CardList

# Requirements-based targeting
def isValidTarget(self, target, requirements=None):
	if target.type == CardType.MINION:
		if target.dead:
			return False
		if target.stealthed and self.controller != target.controller:
			return False
		if target.immune and self.controller != target.controller:
			return False
		if self.type == CardType.SPELL and target.cantBeTargetedByAbilities:
			return False
		if self.type == CardType.HERO_POWER and target.cantBeTargetedByHeroPowers:
			return False

	if requirements is None:
		requirements = self.requirements

	for req, param in requirements.items():
		if req == PlayReq.REQ_MINION_TARGET:
			if target.type != CardType.MINION:
				return False
		elif req == PlayReq.REQ_FRIENDLY_TARGET:
			if target.controller != self.controller:
				return False
		elif req == PlayReq.REQ_ENEMY_TARGET:
			if target.controller == self.controller:
				return False
		elif req == PlayReq.REQ_DAMAGED_TARGET:
			if not target.damage:
				return False
		elif req == PlayReq.REQ_TARGET_MAX_ATTACK:
			if target.atk > param or 0:
				return False
		elif req == PlayReq.REQ_NONSELF_TARGET:
			if target is self:
				return False
		elif req == PlayReq.REQ_TARGET_WITH_RACE:
			if target.type != CardType.MINION or target.race != param:
				return False
		elif req == PlayReq.REQ_HERO_TARGET:
			if target.type != CardType.HERO:
				return False
		elif req == PlayReq.REQ_TARGET_MIN_ATTACK:
			if target.atk < param or 0:
				return False
		elif req == PlayReq.REQ_MUST_TARGET_TAUNTER:
			if not target.taunt:
				return False
		elif req == PlayReq.REQ_UNDAMAGED_TARGET:
			if target.damage:
				return False

		# fireplace reqs
		elif req == PlayReq.REQ_SPELL_TARGET:
			if target.type != CardType.SPELL:
				return False
		elif req == PlayReq.REQ_SECRET_TARGET:
			if target.type != CardType.SPELL or not target.secret:
				return False
		elif req == PlayReq.REQ_WEAPON_TARGET:
			if target.type != CardType.WEAPON:
				return False
		elif req == PlayReq.REQ_NO_MINIONS_PLAYED_THIS_TURN:
			if self.controller.minionsPlayedThisTurn:
				return False
		elif req == PlayReq.REQ_TARGET_HAS_BATTLECRY:
			if not target.hasBattlecry:
				return False
		elif req == PlayReq.REQ_SOURCE_IS_ENRAGED:
			if not self.enraged:
				return False
	return True

class Selector:
	"""
	A Forth-like program consisting of methods of Selector and members of
	IntEnum classes. The IntEnums must have appropriate test() methods
	    def test(self, entity)
	returning a boolean, true if entity matches the condition.
	"""
	class MergeFilter:
		"""
		Signals the start of a merge: the following commands define the filter
		to be passed after Merge
		"""
		pass

	class Merge:
		"""
		Ops between Merge and Unmerge are classes with merge() methods
		    def merge(self, selector, entities)
		that operate on the full collection specified by the ops between
		MergeFilter and Merge.
		"""
		pass

	class Unmerge:
		pass

	def __init__(self, *args):
		self.program = []
		first = True
		for arg in args:
			self.program.append(arg)
			if not first:
				self.program.append(Selector._or)
			first = False

	def __repr__(self):
		prog = []
		for op in self.program:
			name = ""
			if hasattr(op, "__name__"):
				name = op.__name__
			elif isinstance(op, IntEnum):
				name = op.name
			else:
				name = repr(op)
			prog.append(name.lstrip("_"))
		return "<{}: {}>".format(self.__class__.__name__, " ".join(prog))

	def __or__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._or)
		return result

	def __add__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._and)
		return result

	def __sub__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program += [Selector._not, Selector._and]
		return result

	def eval(self, entities, source):
		self.opc = 0 # outer program counter
		result = []
		while self.opc < len(self.program):
			if self.program[self.opc] != Selector.MergeFilter:
				result += [e for e in entities if self.test(e, source)]
				self.opc = self.pc
				if self.opc >= len(self.program):
					break
			else:
				self.opc += 1
			# handle merge step:
			merge_input = CardList([e for e in entities if self.test(e, source)])
			self.opc = self.pc
			merge_output = CardList()
			while self.opc < len(self.program):
				op = self.program[self.opc]
				self.opc += 1
				if op == Selector.Unmerge:
					break
				merge_output += op.merge(self, merge_input)
			negated = False
			combined = False
			while self.opc < len(self.program):
				# special handling for operators on merged collections:
				op = self.program[self.opc]
				if op == Selector._or:
					result += [e for e in merge_output]
					combined = True
				elif op == Selector._and:
					result = [e for e in result if (e in merge_output) != negated]
					combined = True
				elif op == Selector._not:
					negated = not negated
				else:
					break
				self.opc += 1
			if not combined:
				# assume or
				result += merge_output
		return result

	def test(self, entity, source):
		stack = []
		self.pc = self.opc # program counter
		while self.pc < len(self.program):
			op = self.program[self.pc]
			self.pc += 1
			if op == Selector.Merge or op == Selector.MergeFilter:
				break
			if callable(op):
				op(self, stack)
			else:
				val = type(op).test(op, entity, source)
				stack.append(val)
		return stack[-1]

	# boolean ops:
	def _and(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a and b)

	def _or(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a or b)

	def _not(self, stack):
		stack.append(not stack.pop())

class SelfSelector(Selector):
	"""
	Selects the source.
	"""
	class IsSelf:
		def test(self, entity, source):
			return entity is source

	def __init__(self):
		self.program = [self.IsSelf()]

	def eval(self, entities, source):
		return [source]

	def test(self, entity, source):
		return entity is source

SELF = SelfSelector()

class TargetSelector(Selector):
	"""
	Selects the source's target as target.
	"""
	class IsTarget:
		def test(self, entity, source):
			return entity is source.target

	def __init__(self):
		self.program = [self.IsTarget()]

	def eval(self, entities, source):
		return [source.target]

	def test(self, entity, source):
		return entity is source.target

TARGET = TargetSelector()

class AdjacentSelector(Selector):
	"""
	Selects the minions adjacent to the targets.
	"""
	class SelectAdjacent:
		def merge(self, selector, entities):
			result = []
			for e in entities:
				result.extend(e.adjacentMinions)
			return result

	def __init__(self, selector):
		self.program = [Selector.MergeFilter]
		self.program.extend(selector.program)
		self.program.append(Selector.Merge)
		self.program.append(self.SelectAdjacent())
		self.program.append(Selector.Unmerge)

SELF_ADJACENT = AdjacentSelector(SELF)
TARGET_ADJACENT = AdjacentSelector(TARGET)

class RandomSelector(Selector):
	"""
	Selects a 1-member random sample of the targets.
	This selector can be multiplied to select more than 1 target.
	"""
	class SelectRandom:
		def __init__(self, times):
			self.times = times

		def merge(self, selector, entities):
			return random.sample(entities, min(len(entities), self.times))

	def __init__(self, selector):
		self.random = self.SelectRandom(1)
		self.selector = selector
		self.program = [Selector.MergeFilter]
		self.program.extend(selector.program)
		self.program.append(Selector.Merge)
		self.program.append(self.random)
		self.program.append(Selector.Unmerge)

	def __mul__(self, other):
		result = RandomSelector(self.selector)
		result.random.times = self.random.times * other
		return result

RANDOM = RandomSelector

class TargetingRequirement(IntEnum):
	DAMAGED = 1
	HAS_DEATHRATTLE = 2

	def test(self, entity, *args):
		if self == TargetingRequirement.DAMAGED:
			return bool(getattr(entity, "damage", 0))
		elif self == TargetingRequirement.HAS_DEATHRATTLE:
			return getattr(entity, "hasDeathrattle", False)
		return False

DAMAGED = Selector(TargetingRequirement.DAMAGED)
DEATHRATTLE = Selector(TargetingRequirement.HAS_DEATHRATTLE)

IN_PLAY = Selector(Zone.PLAY)
IN_DECK = Selector(Zone.DECK)
IN_HAND = Selector(Zone.HAND)
HIDDEN = Selector(Zone.SECRET)

FRIENDLY = Selector(Affiliation.FRIENDLY)
ENEMY = Selector(Affiliation.HOSTILE)
CONTROLLED_BY_TARGET = Selector(Affiliation.TARGET)

ALL_PLAYERS = PLAYER = Selector(CardType.PLAYER)
CONTROLLER = ALL_PLAYERS + FRIENDLY
OPPONENT = ALL_PLAYERS + ENEMY

HERO = Selector(CardType.HERO)
MINION = Selector(CardType.MINION)
CHARACTER = MINION | HERO
WEAPON = Selector(CardType.WEAPON)
SPELL = Selector(CardType.SPELL)
SECRET = Selector(CardType.SECRET)
HERO_POWER = Selector(CardType.HERO_POWER)

DEMON = Selector(Race.DEMON)
MECH = Selector(Race.MECHANICAL)
MURLOC = Selector(Race.MURLOC)
PIRATE = Selector(Race.PIRATE)
TOTEM = Selector(Race.TOTEM)

CONTROLLER_HAND = IN_HAND + FRIENDLY
CONTROLLER_DECK = IN_DECK + FRIENDLY
OPPONENT_HAND = IN_HAND + ENEMY
OPPONENT_DECK = IN_DECK + OPPONENT

ALL_HEROES = IN_PLAY + HERO
ALL_MINIONS = IN_PLAY + MINION
ALL_CHARACTERS = IN_PLAY + CHARACTER
ALL_WEAPONS = IN_PLAY + WEAPON
ALL_SECRETS = HIDDEN + SECRET
ALL_HERO_POWERS = IN_PLAY + HERO_POWER

FRIENDLY_HERO = IN_PLAY + FRIENDLY + HERO
FRIENDLY_MINIONS = IN_PLAY + FRIENDLY + MINION
FRIENDLY_CHARACTERS = IN_PLAY + FRIENDLY + CHARACTER
FRIENDLY_WEAPON = IN_PLAY + FRIENDLY + WEAPON
FRIENDLY_SECRETS = HIDDEN + FRIENDLY + SECRET
FRIENDLY_HERO_POWER = IN_PLAY + FRIENDLY + HERO_POWER
ENEMY_HERO = IN_PLAY + ENEMY + HERO
ENEMY_MINIONS = IN_PLAY + ENEMY + MINION
ENEMY_CHARACTERS = IN_PLAY + ENEMY + CHARACTER
ENEMY_WEAPON = IN_PLAY + ENEMY + WEAPON
ENEMY_SECRETS = HIDDEN + ENEMY + SECRET
ENEMY_HERO_POWER = IN_PLAY + ENEMY + HERO_POWER

RANDOM_MINION = RANDOM(ALL_MINIONS)
RANDOM_CHARACTER = RANDOM(ALL_CHARACTERS)
RANDOM_FRIENDLY_MINION = RANDOM(FRIENDLY_MINIONS)
RANDOM_FRIENDLY_CHARACTER = RANDOM(FRIENDLY_CHARACTERS)
RANDOM_ENEMY_MINION = RANDOM(ENEMY_MINIONS)
RANDOM_ENEMY_CHARACTER = RANDOM(ENEMY_CHARACTERS)

DAMAGED_CHARACTERS = ALL_CHARACTERS + DAMAGED
<commit_msg>Add a BEAST selector<commit_after>"""
Targeting logic
"""

import random
from enum import IntEnum
from .enums import Affiliation, CardType, PlayReq, Race, Zone
from .utils import CardList

# Requirements-based targeting
def isValidTarget(self, target, requirements=None):
	if target.type == CardType.MINION:
		if target.dead:
			return False
		if target.stealthed and self.controller != target.controller:
			return False
		if target.immune and self.controller != target.controller:
			return False
		if self.type == CardType.SPELL and target.cantBeTargetedByAbilities:
			return False
		if self.type == CardType.HERO_POWER and target.cantBeTargetedByHeroPowers:
			return False

	if requirements is None:
		requirements = self.requirements

	for req, param in requirements.items():
		if req == PlayReq.REQ_MINION_TARGET:
			if target.type != CardType.MINION:
				return False
		elif req == PlayReq.REQ_FRIENDLY_TARGET:
			if target.controller != self.controller:
				return False
		elif req == PlayReq.REQ_ENEMY_TARGET:
			if target.controller == self.controller:
				return False
		elif req == PlayReq.REQ_DAMAGED_TARGET:
			if not target.damage:
				return False
		elif req == PlayReq.REQ_TARGET_MAX_ATTACK:
			if target.atk > param or 0:
				return False
		elif req == PlayReq.REQ_NONSELF_TARGET:
			if target is self:
				return False
		elif req == PlayReq.REQ_TARGET_WITH_RACE:
			if target.type != CardType.MINION or target.race != param:
				return False
		elif req == PlayReq.REQ_HERO_TARGET:
			if target.type != CardType.HERO:
				return False
		elif req == PlayReq.REQ_TARGET_MIN_ATTACK:
			if target.atk < param or 0:
				return False
		elif req == PlayReq.REQ_MUST_TARGET_TAUNTER:
			if not target.taunt:
				return False
		elif req == PlayReq.REQ_UNDAMAGED_TARGET:
			if target.damage:
				return False

		# fireplace reqs
		elif req == PlayReq.REQ_SPELL_TARGET:
			if target.type != CardType.SPELL:
				return False
		elif req == PlayReq.REQ_SECRET_TARGET:
			if target.type != CardType.SPELL or not target.secret:
				return False
		elif req == PlayReq.REQ_WEAPON_TARGET:
			if target.type != CardType.WEAPON:
				return False
		elif req == PlayReq.REQ_NO_MINIONS_PLAYED_THIS_TURN:
			if self.controller.minionsPlayedThisTurn:
				return False
		elif req == PlayReq.REQ_TARGET_HAS_BATTLECRY:
			if not target.hasBattlecry:
				return False
		elif req == PlayReq.REQ_SOURCE_IS_ENRAGED:
			if not self.enraged:
				return False
	return True

class Selector:
	"""
	A Forth-like program consisting of methods of Selector and members of
	IntEnum classes. The IntEnums must have appropriate test() methods
	    def test(self, entity)
	returning a boolean, true if entity matches the condition.
	"""
	class MergeFilter:
		"""
		Signals the start of a merge: the following commands define the filter
		to be passed after Merge
		"""
		pass

	class Merge:
		"""
		Ops between Merge and Unmerge are classes with merge() methods
		    def merge(self, selector, entities)
		that operate on the full collection specified by the ops between
		MergeFilter and Merge.
		"""
		pass

	class Unmerge:
		pass

	def __init__(self, *args):
		self.program = []
		first = True
		for arg in args:
			self.program.append(arg)
			if not first:
				self.program.append(Selector._or)
			first = False

	def __repr__(self):
		prog = []
		for op in self.program:
			name = ""
			if hasattr(op, "__name__"):
				name = op.__name__
			elif isinstance(op, IntEnum):
				name = op.name
			else:
				name = repr(op)
			prog.append(name.lstrip("_"))
		return "<{}: {}>".format(self.__class__.__name__, " ".join(prog))

	def __or__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._or)
		return result

	def __add__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program.append(Selector._and)
		return result

	def __sub__(self, other):
		result = Selector()
		result.program = self.program + other.program
		result.program += [Selector._not, Selector._and]
		return result

	def eval(self, entities, source):
		self.opc = 0 # outer program counter
		result = []
		while self.opc < len(self.program):
			if self.program[self.opc] != Selector.MergeFilter:
				result += [e for e in entities if self.test(e, source)]
				self.opc = self.pc
				if self.opc >= len(self.program):
					break
			else:
				self.opc += 1
			# handle merge step:
			merge_input = CardList([e for e in entities if self.test(e, source)])
			self.opc = self.pc
			merge_output = CardList()
			while self.opc < len(self.program):
				op = self.program[self.opc]
				self.opc += 1
				if op == Selector.Unmerge:
					break
				merge_output += op.merge(self, merge_input)
			negated = False
			combined = False
			while self.opc < len(self.program):
				# special handling for operators on merged collections:
				op = self.program[self.opc]
				if op == Selector._or:
					result += [e for e in merge_output]
					combined = True
				elif op == Selector._and:
					result = [e for e in result if (e in merge_output) != negated]
					combined = True
				elif op == Selector._not:
					negated = not negated
				else:
					break
				self.opc += 1
			if not combined:
				# assume or
				result += merge_output
		return result

	def test(self, entity, source):
		stack = []
		self.pc = self.opc # program counter
		while self.pc < len(self.program):
			op = self.program[self.pc]
			self.pc += 1
			if op == Selector.Merge or op == Selector.MergeFilter:
				break
			if callable(op):
				op(self, stack)
			else:
				val = type(op).test(op, entity, source)
				stack.append(val)
		return stack[-1]

	# boolean ops:
	def _and(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a and b)

	def _or(self, stack):
		a = stack.pop()
		b = stack.pop()
		stack.append(a or b)

	def _not(self, stack):
		stack.append(not stack.pop())

class SelfSelector(Selector):
	"""
	Selects the source.
	"""
	class IsSelf:
		def test(self, entity, source):
			return entity is source

	def __init__(self):
		self.program = [self.IsSelf()]

	def eval(self, entities, source):
		return [source]

	def test(self, entity, source):
		return entity is source

SELF = SelfSelector()

class TargetSelector(Selector):
	"""
	Selects the source's target as target.
	"""
	class IsTarget:
		def test(self, entity, source):
			return entity is source.target

	def __init__(self):
		self.program = [self.IsTarget()]

	def eval(self, entities, source):
		return [source.target]

	def test(self, entity, source):
		return entity is source.target

TARGET = TargetSelector()

class AdjacentSelector(Selector):
	"""
	Selects the minions adjacent to the targets.
	"""
	class SelectAdjacent:
		def merge(self, selector, entities):
			result = []
			for e in entities:
				result.extend(e.adjacentMinions)
			return result

	def __init__(self, selector):
		self.program = [Selector.MergeFilter]
		self.program.extend(selector.program)
		self.program.append(Selector.Merge)
		self.program.append(self.SelectAdjacent())
		self.program.append(Selector.Unmerge)

SELF_ADJACENT = AdjacentSelector(SELF)
TARGET_ADJACENT = AdjacentSelector(TARGET)

class RandomSelector(Selector):
	"""
	Selects a 1-member random sample of the targets.
	This selector can be multiplied to select more than 1 target.
	"""
	class SelectRandom:
		def __init__(self, times):
			self.times = times

		def merge(self, selector, entities):
			return random.sample(entities, min(len(entities), self.times))

	def __init__(self, selector):
		self.random = self.SelectRandom(1)
		self.selector = selector
		self.program = [Selector.MergeFilter]
		self.program.extend(selector.program)
		self.program.append(Selector.Merge)
		self.program.append(self.random)
		self.program.append(Selector.Unmerge)

	def __mul__(self, other):
		result = RandomSelector(self.selector)
		result.random.times = self.random.times * other
		return result

RANDOM = RandomSelector

class TargetingRequirement(IntEnum):
	DAMAGED = 1
	HAS_DEATHRATTLE = 2

	def test(self, entity, *args):
		if self == TargetingRequirement.DAMAGED:
			return bool(getattr(entity, "damage", 0))
		elif self == TargetingRequirement.HAS_DEATHRATTLE:
			return getattr(entity, "hasDeathrattle", False)
		return False

DAMAGED = Selector(TargetingRequirement.DAMAGED)
DEATHRATTLE = Selector(TargetingRequirement.HAS_DEATHRATTLE)

IN_PLAY = Selector(Zone.PLAY)
IN_DECK = Selector(Zone.DECK)
IN_HAND = Selector(Zone.HAND)
HIDDEN = Selector(Zone.SECRET)

FRIENDLY = Selector(Affiliation.FRIENDLY)
ENEMY = Selector(Affiliation.HOSTILE)
CONTROLLED_BY_TARGET = Selector(Affiliation.TARGET)

ALL_PLAYERS = PLAYER = Selector(CardType.PLAYER)
CONTROLLER = ALL_PLAYERS + FRIENDLY
OPPONENT = ALL_PLAYERS + ENEMY

HERO = Selector(CardType.HERO)
MINION = Selector(CardType.MINION)
CHARACTER = MINION | HERO
WEAPON = Selector(CardType.WEAPON)
SPELL = Selector(CardType.SPELL)
SECRET = Selector(CardType.SECRET)
HERO_POWER = Selector(CardType.HERO_POWER)

BEAST = Selector(Race.BEAST)
DEMON = Selector(Race.DEMON)
MECH = Selector(Race.MECHANICAL)
MURLOC = Selector(Race.MURLOC)
PIRATE = Selector(Race.PIRATE)
TOTEM = Selector(Race.TOTEM)

CONTROLLER_HAND = IN_HAND + FRIENDLY
CONTROLLER_DECK = IN_DECK + FRIENDLY
OPPONENT_HAND = IN_HAND + ENEMY
OPPONENT_DECK = IN_DECK + OPPONENT

ALL_HEROES = IN_PLAY + HERO
ALL_MINIONS = IN_PLAY + MINION
ALL_CHARACTERS = IN_PLAY + CHARACTER
ALL_WEAPONS = IN_PLAY + WEAPON
ALL_SECRETS = HIDDEN + SECRET
ALL_HERO_POWERS = IN_PLAY + HERO_POWER

FRIENDLY_HERO = IN_PLAY + FRIENDLY + HERO
FRIENDLY_MINIONS = IN_PLAY + FRIENDLY + MINION
FRIENDLY_CHARACTERS = IN_PLAY + FRIENDLY + CHARACTER
FRIENDLY_WEAPON = IN_PLAY + FRIENDLY + WEAPON
FRIENDLY_SECRETS = HIDDEN + FRIENDLY + SECRET
FRIENDLY_HERO_POWER = IN_PLAY + FRIENDLY + HERO_POWER
ENEMY_HERO = IN_PLAY + ENEMY + HERO
ENEMY_MINIONS = IN_PLAY + ENEMY + MINION
ENEMY_CHARACTERS = IN_PLAY + ENEMY + CHARACTER
ENEMY_WEAPON = IN_PLAY + ENEMY + WEAPON
ENEMY_SECRETS = HIDDEN + ENEMY + SECRET
ENEMY_HERO_POWER = IN_PLAY + ENEMY + HERO_POWER

RANDOM_MINION = RANDOM(ALL_MINIONS)
RANDOM_CHARACTER = RANDOM(ALL_CHARACTERS)
RANDOM_FRIENDLY_MINION = RANDOM(FRIENDLY_MINIONS)
RANDOM_FRIENDLY_CHARACTER = RANDOM(FRIENDLY_CHARACTERS)
RANDOM_ENEMY_MINION = RANDOM(ENEMY_MINIONS)
RANDOM_ENEMY_CHARACTER = RANDOM(ENEMY_CHARACTERS)

DAMAGED_CHARACTERS = ALL_CHARACTERS + DAMAGED
<|endoftext|>


<commit_before>"""
    Access to the decompiler (decompilation of files).

    :copyright: © 2015 by Petr Zemek <s3rvac@gmail.com> and contributors
    :license: MIT, see the ``LICENSE`` file for more details
"""

import contextlib
import shutil
import time

from retdec.file import File
from retdec.service import Service
from retdec.resource import Resource

class Decompiler(Service):
    """Access to the decompilation service."""

    def run_decompilation(self, **kwargs):
        """Starts a decompilation with the given arguments.

        :returns: Decompilation Started decompilation.
        """
        conn = self._create_new_api_connection('/decompiler/decompilations')
        id = self._start_decompilation(conn, **kwargs)
        return Decompilation(id, conn)

    def _start_decompilation(self, conn, **kwargs):
        """Starts a decompilation with the given arguments.

        :param retdec.conn.APIConnection conn: Connection to the API to be used
                                               for sending API requests.

        :returns: Unique identifier of the decompilation.
        """
        # The input file is always required.
        input_file = self._get_input_file(kwargs)

        params = {
            'mode': self._get_mode(input_file, kwargs)
        }
        files = {
            'input': input_file
        }
        response = conn.send_post_request('', params=params, files=files)
        return response['id']

    def _get_mode(self, input_file, kwargs):
        """Returns a mode from the given arguments (`dict`)."""
        if 'mode' in kwargs:
            return kwargs['mode'].lower()

        # Select the mode automatically based on the input file's name.
        if input_file.name.lower().endswith('.c'):
            return 'c'
        return 'bin'

    def _get_input_file(self, kwargs):
        """Returns an input file from the given arguments (`dict`)."""
        if 'input_file' in kwargs:
            return File(kwargs['input_file'])

class Decompilation(Resource):
    """A representation of a decompilation."""

    def wait_until_finished(self):
        """Waits until the decompilation finishes."""
        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        while True:
            response = self._conn.send_get_request('/{}/status'.format(self.id))
            if response['finished']:
                break
            # Sleep a bit to prevent abuse of the API.
            time.sleep(0.5)

    def save_output_hll(self):
        """Saves the decompiled output code to the current directory."""
        file_path = '/{}/outputs/hll'.format(self.id)
        with contextlib.closing(self._conn.get_file(file_path)) as src:
            with open(src.name, 'wb') as dst:
                shutil.copyfileobj(src, dst)
<commit_msg>Fix the description of Decompiler.run_decompilation().<commit_after>"""
    Access to the decompiler (decompilation of files).

    :copyright: © 2015 by Petr Zemek <s3rvac@gmail.com> and contributors
    :license: MIT, see the ``LICENSE`` file for more details
"""

import contextlib
import shutil
import time

from retdec.file import File
from retdec.service import Service
from retdec.resource import Resource

class Decompiler(Service):
    """Access to the decompilation service."""

    def run_decompilation(self, **kwargs):
        """Starts a decompilation with the given arguments.

        :returns: Started decompilation (:class:`Decompilation`).
        """
        conn = self._create_new_api_connection('/decompiler/decompilations')
        id = self._start_decompilation(conn, **kwargs)
        return Decompilation(id, conn)

    def _start_decompilation(self, conn, **kwargs):
        """Starts a decompilation with the given arguments.

        :param retdec.conn.APIConnection conn: Connection to the API to be used
                                               for sending API requests.

        :returns: Unique identifier of the decompilation.
        """
        # The input file is always required.
        input_file = self._get_input_file(kwargs)

        params = {
            'mode': self._get_mode(input_file, kwargs)
        }
        files = {
            'input': input_file
        }
        response = conn.send_post_request('', params=params, files=files)
        return response['id']

    def _get_mode(self, input_file, kwargs):
        """Returns a mode from the given arguments (`dict`)."""
        if 'mode' in kwargs:
            return kwargs['mode'].lower()

        # Select the mode automatically based on the input file's name.
        if input_file.name.lower().endswith('.c'):
            return 'c'
        return 'bin'

    def _get_input_file(self, kwargs):
        """Returns an input file from the given arguments (`dict`)."""
        if 'input_file' in kwargs:
            return File(kwargs['input_file'])

class Decompilation(Resource):
    """A representation of a decompilation."""

    def wait_until_finished(self):
        """Waits until the decompilation finishes."""
        # Currently, the retdec.com API does not support push notifications, so
        # we have to do polling.
        while True:
            response = self._conn.send_get_request('/{}/status'.format(self.id))
            if response['finished']:
                break
            # Sleep a bit to prevent abuse of the API.
            time.sleep(0.5)

    def save_output_hll(self):
        """Saves the decompiled output code to the current directory."""
        file_path = '/{}/outputs/hll'.format(self.id)
        with contextlib.closing(self._conn.get_file(file_path)) as src:
            with open(src.name, 'wb') as dst:
                shutil.copyfileobj(src, dst)
<|endoftext|>


<commit_before>from discord.ext import commands
import aiohttp
from bs4 import BeautifulSoup

#WIP-This cog will not work correctly as is.
class revimage:
    """Reverse image search commands"""
    def __init__(self, bot):
        self.bot = bot
        self.sauce_session = aiohttp.ClientSession()
        self.tineye_session = aiohttp.ClientSession()
        self.google_session = aiohttp.ClientSession()

    def __unload(self):
        self.sauce_session.close()
        self.tineye_session.close()
        self.google_session.close()

    def _tag_to_title(self, tag):
        return tag.replace(' ', ', ').replace('_', ' ').title()

    @commands.command(pass_context=True)
    async def tineye(self, ctx, link=None):
        """
        Reverse image search using tineye
        usage:  .tineye <image-link> or
                .tineye on image upload comment
        """
        file = ctx.message.attachments
        if link is None and not file:
            await self.bot.say('Message didn\'t contain Image')
        else:
            await self.bot.type()
            if file:
                url = file[0]['proxy_url']
            else:
                url = link
            async with self.tineye_session.get('https://tineye.com/search/?url={}'.format(url)) as response:
                soup = BeautifulSoup(await response.text(), 'html.parser')
                pages = []
                image_link = None
                hidden = soup.find(class_='match').select('.hidden-xs')[0]
                if hidden.contents[0].startswith('Page:'):
                    pages.append('<{}>'.format(hidden.next_sibling['href']))
                else:
                    image_link = hidden.a['href']
#            message = '\n**Pages:** '
#            message += '\n**Pages:** '.join(pages)
            if image_link is not None:
                message = '\n**Image Found:** \n<{}>'.format(image_link)
            else:
                message = '\n**No Matching Images Found'
            await self.bot.reply(message)

#    @commands.command(pass_context=True)
#    async def gimage(self, ctx, link=None):
#        """
#        Reverse image search using google
#        usage:  .gimage <image-link> or
#                .gimage on image upload comment
#        """
#        file = ctx.message.attachments
#        if link is None and not file:
#            await self.bot.say('Message didn\'t contain Image')
#        else:
#            await self.bot.type()
#            if file:
#                url = file[0]['proxy_url']
#            else:
#                url = link
#            async with self.google_session.get('https://www.google.com/searchbyimage?image_url={}'.format(url)) as response:
#                soup = BeautifulSoup(await response.text(), 'html.parser')
#                pages = []
#                image_link = None
#                hidden = soup.find(class_='match').select('.hidden-xs')[0]
#                if hidden.contents[0].startswith('Page:'):
#                    pages.append('<{}>'.format(hidden.next_sibling['href']))
#                else:
#                    image_link = hidden.a['href']
#            message = '\n**Pages:** '
#            message += '\n**Pages:** '.join(pages)
#            if image_link is not None:
#                message += '\n**direct image:** <{}>'.format(image_link)
#            await self.bot.reply(message)

def setup(bot):
    bot.add_cog(revimage(bot))
<commit_msg>update no match<commit_after>from discord.ext import commands
import aiohttp
from bs4 import BeautifulSoup

#WIP-This cog will not work correctly as is.
class revimage:
    """Reverse image search commands"""
    def __init__(self, bot):
        self.bot = bot
        self.sauce_session = aiohttp.ClientSession()
        self.tineye_session = aiohttp.ClientSession()
        self.google_session = aiohttp.ClientSession()

    def __unload(self):
        self.sauce_session.close()
        self.tineye_session.close()
        self.google_session.close()

    def _tag_to_title(self, tag):
        return tag.replace(' ', ', ').replace('_', ' ').title()

    @commands.command(pass_context=True)
    async def tineye(self, ctx, link=None):
        """
        Reverse image search using tineye
        usage:  .tineye <image-link> or
                .tineye on image upload comment
        """
        file = ctx.message.attachments
        if link is None and not file:
            await self.bot.say('Message didn\'t contain Image')
        else:
            await self.bot.type()
            if file:
                url = file[0]['proxy_url']
            else:
                url = link
            async with self.tineye_session.get('https://tineye.com/search/?url={}'.format(url)) as response:
                soup = BeautifulSoup(await response.text(), 'html.parser')
                pages = []
                image_link = None
                hidden = soup.find(class_='match').select('.hidden-xs')[0]
                if hidden.contents[0].startswith('Page:'):
                    pages.append('<{}>'.format(hidden.next_sibling['href']))
                else:
                    image_link = hidden.a['href']
                except IndexError:
                    message = '\n**No matches found**'
#            message = '\n**Pages:** '
#            message += '\n**Pages:** '.join(pages)
            if image_link is not None:
                message = '\n**Image Found:** \n<{}>'.format(image_link)
            await self.bot.reply(message)

#    @commands.command(pass_context=True)
#    async def gimage(self, ctx, link=None):
#        """
#        Reverse image search using google
#        usage:  .gimage <image-link> or
#                .gimage on image upload comment
#        """
#        file = ctx.message.attachments
#        if link is None and not file:
#            await self.bot.say('Message didn\'t contain Image')
#        else:
#            await self.bot.type()
#            if file:
#                url = file[0]['proxy_url']
#            else:
#                url = link
#            async with self.google_session.get('https://www.google.com/searchbyimage?image_url={}'.format(url)) as response:
#                soup = BeautifulSoup(await response.text(), 'html.parser')
#                pages = []
#                image_link = None
#                hidden = soup.find(class_='match').select('.hidden-xs')[0]
#                if hidden.contents[0].startswith('Page:'):
#                    pages.append('<{}>'.format(hidden.next_sibling['href']))
#                else:
#                    image_link = hidden.a['href']
#            message = '\n**Pages:** '
#            message += '\n**Pages:** '.join(pages)
#            if image_link is not None:
#                message += '\n**direct image:** <{}>'.format(image_link)
#            await self.bot.reply(message)

def setup(bot):
    bot.add_cog(revimage(bot))
<|endoftext|>


<commit_before>from selenium.webdriver.firefox.webdriver import WebDriver
from fixture.session import SessionHelper
from fixture.group import GroupHelper
from fixture.contact import ContactHelper

class Application:

    def __init__(self):
        self.wd = WebDriver()
        self.wd.implicitly_wait(60)
        self.session = SessionHelper(self)
        self.group = GroupHelper(self)
        self.contact = ContactHelper(self)

    def open_home_page(self):
        wd = self.wd
        wd.get("http://localhost/addressbook/")

    def destroy(self):
        self.wd.quit()

    def is_valid(self):
        try:
            self.wd.current_url
            return True
        except:
            return False<commit_msg>Change Wait time from 60 to 5 sec<commit_after>from selenium.webdriver.firefox.webdriver import WebDriver
from fixture.session import SessionHelper
from fixture.group import GroupHelper
from fixture.contact import ContactHelper

class Application:

    def __init__(self):
        self.wd = WebDriver()
        self.wd.implicitly_wait(5)
        self.session = SessionHelper(self)
        self.group = GroupHelper(self)
        self.contact = ContactHelper(self)

    def open_home_page(self):
        wd = self.wd
        wd.get("http://localhost/addressbook/")

    def destroy(self):
        self.wd.quit()

    def is_valid(self):
        try:
            self.wd.current_url
            return True
        except:
            return False<|endoftext|>


<commit_before>import json
import mimetypes

from flask import request
from os.path import join, getmtime, getsize
from werkzeug.datastructures import Headers
from .utils import cached

class ApiDoc(object):
    """
    ApiDoc hosts the apidoc files in a specified url.
    """

    def __init__(self, folder_path=None, url_path=None, dynamic_url=True, app=None):
        """
        Initializes a new instance of ApiDoc.

        :param folder_path: The folder with apidoc files. Defaults to the 'docs' folder in the flask static folder.
        :param url_path: The url path for the apidoc files. Defaults to the '/docs'.
        :param dynamic_url: Set `True` to replace all the urls in ApiDoc files by the current url.
        :param app: The flask application.
        """

        self.folder_path = folder_path
        self.url_path = url_path

        if self.folder_path is None:
            self.folder_path = 'docs'

        if self.url_path is None:
            self.url_path = '/docs'

        self.dynamic_url = dynamic_url

        self.app = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """
        Adds the flask url routes for the apidoc files.
        :param app: the flask application.
        """

        self.app = app

        url = self.url_path

        if not self.url_path.endswith('/'):
            url += '/'

        app.add_url_rule(url, 'docs', self.__send_static_file, strict_slashes=True)
        app.add_url_rule(url + '<path:path>', 'docs', self.__send_static_file, strict_slashes=True)

    def __send_static_file(self, path=None):
        """
        Sends apidoc files from the apidoc folder to the browser.
        :param path: the apidoc file
        """

        if not path:
            path = 'index.html'

        file_name = join(self.folder_path, path)

        # the api_project.js has the absolute url
        # hard coded so we replace them by the current url.
        if self.dynamic_url and path == 'api_project.js':
            return self.__send_api_file(file_name)

        # Any other apidoc file is treated as a normal static file
        return self.app.send_static_file(file_name)

    @cached
    def __send_api_file(self, file_name):
        """
        Sends apidoc files from the apidoc folder to the browser.
        This method replaces all absolute urls in the file by
        the current url.
        :param file_name: the apidoc file
        """

        file_name = join(self.app.static_folder, file_name)

        with open(file_name, 'rt') as file:
            data = file.read()

        # replaces the hard coded url by the
        # current url.
        api_project = self.__read_api_project()

        new_url = request.url_root.strip('/')
        old_url = api_project.get('url')
        data = data.replace(old_url, new_url)

        # creates a flask response to send
        # the file to the browser

        headers = Headers()
        headers['Content-Length'] = getsize(file_name)

        response = self.app.response_class(data,
                                           mimetype=mimetypes.guess_type(file_name)[0],
                                           headers=headers,
                                           direct_passthrough=True)

        response.last_modified = int(getmtime(file_name))

        return response

    @cached
    def __read_api_project(self):
        """
        Reads the api_project.json file from apidoc folder as a json string.
        :return: a json string
        """

        file_name = join(self.app.static_folder, self.folder_path, 'api_project.json')

        with open(file_name, 'rt') as file:
            data = file.read()

        return json.loads(data)
<commit_msg>Add option to allow absolute urls in @api<commit_after>import json
import mimetypes

from flask import request
from os.path import join, getmtime, getsize
from werkzeug.datastructures import Headers
from .utils import cached

class ApiDoc(object):
    """
    ApiDoc hosts the apidoc files in a specified url.
    """

    def __init__(self, folder_path=None, url_path=None, dynamic_url=True, app=None):
        """
        Initializes a new instance of ApiDoc.

        :param folder_path: The folder with apidoc files. Defaults to the 'docs' folder in the flask static folder.
        :param url_path: The url path for the apidoc files. Defaults to the '/docs'.
        :param dynamic_url: Set `True` to replace all the urls in ApiDoc files by the current url.
        :param app: The flask application.
        """

        self.folder_path = folder_path
        self.url_path = url_path

        if self.folder_path is None:
            self.folder_path = 'docs'

        if self.url_path is None:
            self.url_path = '/docs'

        self.dynamic_url = dynamic_url
        self.allow_absolute_url = True

        self.app = None

        if app:
            self.init_app(app)

    def init_app(self, app):
        """
        Adds the flask url routes for the apidoc files.
        :param app: the flask application.
        """

        self.app = app

        self.dynamic_url = self.app.config.get('APIDOC_DYNAMIC_URL', self.dynamic_url)
        self.allow_absolute_url = self.app.config.get('APIDOC_ALLOW_ABSOLUTE_URL', self.allow_absolute_url)

        url = self.url_path

        if not self.url_path.endswith('/'):
            url += '/'

        app.add_url_rule(url, 'docs', self.__send_static_file, strict_slashes=True)
        app.add_url_rule(url + '<path:path>', 'docs', self.__send_static_file, strict_slashes=True)

    def __send_static_file(self, path=None):
        """
        Send apidoc files from the apidoc folder to the browser.
        :param path: the apidoc file.
        """

        if not path:
            path = 'index.html'

        file_name = join(self.folder_path, path)

        # the api_project.js has the absolute url
        # hard coded so we replace them by the current url.
        if self.dynamic_url and path == 'api_project.js':
            return self.__send_api_file(file_name)

        if self.allow_absolute_url and path == 'main.js':
            return self.__send_main_file(file_name)

        # Any other apidoc file is treated as a normal static file
        return self.app.send_static_file(file_name)

    @cached
    def __send_api_file(self, file_name):
        """
        Send apidoc files from the apidoc folder to the browser.
        This method replaces all absolute urls in the file by
        the current url.
        :param file_name: the apidoc file.
        """

        file_name = join(self.app.static_folder, file_name)

        with open(file_name, 'rt') as file:
            data = file.read()

        # replaces the hard coded url by the
        # current url.
        api_project = self.__read_api_project()

        new_url = request.url_root.strip('/')
        old_url = api_project.get('url')
        data = data.replace(old_url, new_url)

        # creates a flask response to send
        # the file to the browser

        headers = Headers()
        headers['Content-Length'] = getsize(file_name)

        response = self.app.response_class(data,
                                           mimetype=mimetypes.guess_type(file_name)[0],
                                           headers=headers,
                                           direct_passthrough=True)

        response.last_modified = int(getmtime(file_name))

        return response

    @cached
    def __send_main_file(self, file_name):
        """
        Send apidoc files from the apidoc folder to the browser.
        This method replaces all absolute urls in the file by
        the current url.
        :param file_name: the apidoc file.
        """

        file_name = join(self.app.static_folder, file_name)

        with open(file_name, 'rt') as file:
            data = file.read()

        data = data.replace(
            'fields.article.url = apiProject.url + fields.article.url;',
            '''if (fields.article.url.substr(0, 4).toLowerCase() !== \'http\')
                        fields.article.url = apiProject.url + fields.article.url;''')

        headers = Headers()
        headers['Content-Length'] = getsize(file_name)

        response = self.app.response_class(data,
                                           mimetype=mimetypes.guess_type(file_name)[0],
                                           headers=headers,
                                           direct_passthrough=True)

        response.last_modified = int(getmtime(file_name))

        return response

    @cached
    def __read_api_project(self):
        """
        Reads the api_project.json file from apidoc folder as a json string.
        :return: a json string
        """

        file_name = join(self.app.static_folder, self.folder_path, 'api_project.json')

        with open(file_name, 'rt') as file:
            data = file.read()

        return json.loads(data)
<|endoftext|>