<commit_before>#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Runs the WebDriver Java acceptance tests.

This script is called from chrome/test/chromedriver/run_all_tests.py and reports
results using the buildbot annotation scheme.

For ChromeDriver documentation, refer to http://code.google.com/p/chromedriver.
"""

import optparse
import os
import shutil
import sys
import xml.dom.minidom as minidom

_THIS_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))

import chrome_paths
import test_environment
import util

if util.IsLinux():
  sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
  from pylib import constants

class TestResult(object):
  """A result for an attempted single test case."""

  def __init__(self, name, time, failure):
    """Initializes a test result.

    Args:
      name: the full name of the test.
      time: the amount of time the test ran, in seconds.
      failure: the test error or failure message, or None if the test passed.
    """
    self._name = name
    self._time = time
    self._failure = failure

  def GetName(self):
    """Returns the test name."""
    return self._name

  def GetTime(self):
    """Returns the time it took to run the test."""
    return self._time

  def IsPass(self):
    """Returns whether the test passed."""
    return self._failure is None

  def GetFailureMessage(self):
    """Returns the test failure message, or None if the test passed."""
    return self._failure

def _Run(java_tests_src_dir, test_filter,
         chromedriver_path, chrome_path, log_path, android_package_key,
         verbose, debug):
  """Run the WebDriver Java tests and return the test results.

  Args:
    java_tests_src_dir: the java test source code directory.
    test_filter: the filter to use when choosing tests to run. Format is same
        as Google C++ Test format.
    chromedriver_path: path to ChromeDriver exe.
    chrome_path: path to Chrome exe.
    log_path: path to server log.
    android_package_key: name of Chrome's Android package.
    verbose: whether the output should be verbose.
    debug: whether the tests should wait until attached by a debugger.

  Returns:
    A list of |TestResult|s.
  """
  test_dir = util.MakeTempDir()
  keystore_path = ('java', 'client', 'test', 'keystore')
  required_dirs = [keystore_path[:-1],
                   ('javascript',),
                   ('third_party', 'closure', 'goog'),
                   ('third_party', 'js')]
  for required_dir in required_dirs:
    os.makedirs(os.path.join(test_dir, *required_dir))

  test_jar = 'test-standalone.jar'
  class_path = test_jar
  shutil.copyfile(os.path.join(java_tests_src_dir, 'keystore'),
                  os.path.join(test_dir, *keystore_path))
  util.Unzip(os.path.join(java_tests_src_dir, 'common.zip'), test_dir)
  shutil.copyfile(os.path.join(java_tests_src_dir, test_jar),
                  os.path.join(test_dir, test_jar))

  sys_props = ['selenium.browser=chrome',
               'webdriver.chrome.driver=' + os.path.abspath(chromedriver_path)]
  if chrome_path:
    sys_props += ['webdriver.chrome.binary=' + os.path.abspath(chrome_path)]
  if log_path:
    sys_props += ['webdriver.chrome.logfile=' + log_path]
  if android_package_key:
    android_package = constants.PACKAGE_INFO[android_package_key].package
    sys_props += ['webdriver.chrome.android_package=' + android_package]
    if android_package_key == 'chromedriver_webview_shell':
      android_activity = constants.PACKAGE_INFO[android_package_key].activity
      android_process = '%s:main' % android_package
      sys_props += ['webdriver.chrome.android_activity=' + android_activity]
      sys_props += ['webdriver.chrome.android_process=' + android_process]
  if test_filter:
    # Test jar actually takes a regex. Convert from glob.
    test_filter = test_filter.replace('*', '.*')
    sys_props += ['filter=' + test_filter]

  jvm_args = []
  if debug:
    transport = 'dt_socket'
    if util.IsWindows():
      transport = 'dt_shmem'
    jvm_args += ['-agentlib:jdwp=transport=%s,server=y,suspend=y,'
                 'address=33081' % transport]
    # Unpack the sources into the test directory and add to the class path
    # for ease of debugging, particularly with jdb.
    util.Unzip(os.path.join(java_tests_src_dir, 'test-nodeps-srcs.jar'),
               test_dir)
    class_path += ':' + test_dir

  return _RunAntTest(
      test_dir, 'org.openqa.selenium.chrome.ChromeDriverTests',
      class_path, sys_props, jvm_args, verbose)

def _RunAntTest(test_dir, test_class, class_path, sys_props, jvm_args, verbose):
  """Runs a single Ant JUnit test suite and returns the |TestResult|s.

  Args:
    test_dir: the directory to run the tests in.
    test_class: the name of the JUnit test suite class to run.
    class_path: the Java class path used when running the tests, colon delimited
    sys_props: Java system properties to set when running the tests.
    jvm_args: Java VM command line args to use.
    verbose: whether the output should be verbose.

  Returns:
    A list of |TestResult|s.
  """
  def _CreateBuildConfig(test_name, results_file, class_path, junit_props,
                         sys_props, jvm_args):
    def _SystemPropToXml(prop):
      key, value = prop.split('=')
      return '<sysproperty key="%s" value="%s"/>' % (key, value)
    def _JvmArgToXml(arg):
      return '<jvmarg value="%s"/>' % arg
    return '\n'.join([
        '<project>',
        '  <target name="test">',
        '    <junit %s>' % ' '.join(junit_props),
        '      <formatter type="xml"/>',
        '      <classpath>',
        '        <pathelement path="%s"/>' % class_path,
        '      </classpath>',
        '      ' + '\n      '.join(map(_SystemPropToXml, sys_props)),
        '      ' + '\n      '.join(map(_JvmArgToXml, jvm_args)),
        '      <test name="%s" outfile="%s"/>' % (test_name, results_file),
        '    </junit>',
        '  </target>',
        '</project>'])

  def _ProcessResults(results_path):
    doc = minidom.parse(results_path)
    tests = []
    for test in doc.getElementsByTagName('testcase'):
      name = test.getAttribute('classname') + '.' + test.getAttribute('name')
      time = test.getAttribute('time')
      failure = None
      error_nodes = test.getElementsByTagName('error')
      failure_nodes = test.getElementsByTagName('failure')
      if error_nodes:
        failure = error_nodes[0].childNodes[0].nodeValue
      elif failure_nodes:
        failure = failure_nodes[0].childNodes[0].nodeValue
      tests += [TestResult(name, time, failure)]
    return tests

  junit_props = ['printsummary="yes"',
                 'fork="yes"',
                 'haltonfailure="no"',
                 'haltonerror="no"']
  if verbose:
    junit_props += ['showoutput="yes"']

  ant_file = open(os.path.join(test_dir, 'build.xml'), 'w')
  ant_file.write(_CreateBuildConfig(
      test_class, 'results', class_path, junit_props, sys_props, jvm_args))
  ant_file.close()

  if util.IsWindows():
    ant_name = 'ant.bat'
  else:
    ant_name = 'ant'
  code = util.RunCommand([ant_name, 'test'], cwd=test_dir)
  if code != 0:
    print 'FAILED to run java tests of %s through ant' % test_class
    return
  return _ProcessResults(os.path.join(test_dir, 'results.xml'))

def PrintTestResults(results):
  """Prints the given results in a format recognized by the buildbot."""
  failures = []
  failure_names = []
  for result in results:
    if not result.IsPass():
      failures += [result]
      failure_names += ['.'.join(result.GetName().split('.')[-2:])]

  print 'Ran %s tests' % len(results)
  print 'Failed %s:' % len(failures)
  util.AddBuildStepText('failed %s/%s' % (len(failures), len(results)))
  for result in failures:
    print '=' * 80
    print '=' * 10, result.GetName(), '(%ss)' % result.GetTime()
    print result.GetFailureMessage()
    if len(failures) < 10:
      util.AddBuildStepText('.'.join(result.GetName().split('.')[-2:]))
  print 'Rerun failing tests with filter:', ':'.join(failure_names)
  return len(failures)

def main():
  parser = optparse.OptionParser()
  parser.add_option(
      '', '--verbose', action='store_true', default=False,
      help='Whether output should be verbose')
  parser.add_option(
      '', '--debug', action='store_true', default=False,
      help='Whether to wait to be attached by a debugger')
  parser.add_option(
      '', '--chromedriver', type='string', default=None,
      help='Path to a build of the chromedriver library(REQUIRED!)')
  parser.add_option(
      '', '--chrome', type='string', default=None,
      help='Path to a build of the chrome binary')
  parser.add_option(
      '', '--log-path',
      help='Output verbose server logs to this file')
  parser.add_option(
      '', '--chrome-version', default='HEAD',
      help='Version of chrome. Default is \'HEAD\'')
  parser.add_option(
      '', '--android-package', help='Android package key')
  parser.add_option(
      '', '--filter', type='string', default=None,
      help='Filter for specifying what tests to run, "*" will run all. E.g., '
           '*testShouldReturnTitleOfPageIfSet')
  parser.add_option(
      '', '--also-run-disabled-tests', action='store_true', default=False,
      help='Include disabled tests while running the tests')
  parser.add_option(
      '', '--isolate-tests', action='store_true', default=False,
      help='Relaunch the jar test harness after each test')
  options, _ = parser.parse_args()

  options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
  if options.chromedriver is None or not os.path.exists(options.chromedriver):
    parser.error('chromedriver is required or the given path is invalid.' +
                 'Please run "%s --help" for help' % __file__)

  if options.android_package:
    if options.android_package not in constants.PACKAGE_INFO:
      parser.error('Invalid --android-package')
    if options.chrome_version != 'HEAD':
      parser.error('Android does not support the --chrome-version argument.')
    environment = test_environment.AndroidTestEnvironment(
        options.android_package)
  else:
    environment = test_environment.DesktopTestEnvironment(
        options.chrome_version)

  try:
    environment.GlobalSetUp()
    # Run passed tests when filter is not provided.
    if options.isolate_tests:
      test_filters = environment.GetPassedJavaTests()
    else:
      if options.filter:
        test_filter = options.filter
      else:
        test_filter = '*'
      if not options.also_run_disabled_tests:
        if '-' in test_filter:
          test_filter += ':'
        else:
          test_filter += '-'
        test_filter += ':'.join(environment.GetDisabledJavaTestMatchers())
      test_filters = [test_filter]

    java_tests_src_dir = os.path.join(chrome_paths.GetSrc(), 'chrome', 'test',
                                      'chromedriver', 'third_party',
                                      'java_tests')
    if (not os.path.exists(java_tests_src_dir) or
        not os.listdir(java_tests_src_dir)):
      java_tests_url = ('http://src.chromium.org/svn/trunk/deps/third_party'
                        '/webdriver')
      print ('"%s" is empty or it doesn\'t exist. ' % java_tests_src_dir +
             'Need to map <chrome-svn>/trunk/deps/third_party/webdriver to '
             'chrome/test/chromedriver/third_party/java_tests in .gclient.\n'
             'Alternatively, do:\n'
             '  $ cd chrome/test/chromedriver/third_party\n'
             '  $ svn co %s java_tests' % java_tests_url)
      return 1

    results = []
    for filter in test_filters:
      results += _Run(
          java_tests_src_dir=java_tests_src_dir,
          test_filter=filter,
          chromedriver_path=options.chromedriver,
          chrome_path=util.GetAbsolutePathOfUserPath(options.chrome),
          log_path=options.log_path,
          android_package_key=options.android_package,
          verbose=options.verbose,
          debug=options.debug)
    return PrintTestResults(results)
  finally:
    environment.GlobalTearDown()

if __name__ == '__main__':
  sys.exit(main())
<commit_msg>[chromedriver] Run Java tests with --no-sandbox on Linux.<commit_after>#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Runs the WebDriver Java acceptance tests.

This script is called from chrome/test/chromedriver/run_all_tests.py and reports
results using the buildbot annotation scheme.

For ChromeDriver documentation, refer to http://code.google.com/p/chromedriver.
"""

import optparse
import os
import shutil
import stat
import sys
import xml.dom.minidom as minidom

_THIS_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(1, os.path.join(_THIS_DIR, os.pardir))

import chrome_paths
import test_environment
import util

if util.IsLinux():
  sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'android'))
  from pylib import constants

class TestResult(object):
  """A result for an attempted single test case."""

  def __init__(self, name, time, failure):
    """Initializes a test result.

    Args:
      name: the full name of the test.
      time: the amount of time the test ran, in seconds.
      failure: the test error or failure message, or None if the test passed.
    """
    self._name = name
    self._time = time
    self._failure = failure

  def GetName(self):
    """Returns the test name."""
    return self._name

  def GetTime(self):
    """Returns the time it took to run the test."""
    return self._time

  def IsPass(self):
    """Returns whether the test passed."""
    return self._failure is None

  def GetFailureMessage(self):
    """Returns the test failure message, or None if the test passed."""
    return self._failure

def _Run(java_tests_src_dir, test_filter,
         chromedriver_path, chrome_path, log_path, android_package_key,
         verbose, debug):
  """Run the WebDriver Java tests and return the test results.

  Args:
    java_tests_src_dir: the java test source code directory.
    test_filter: the filter to use when choosing tests to run. Format is same
        as Google C++ Test format.
    chromedriver_path: path to ChromeDriver exe.
    chrome_path: path to Chrome exe.
    log_path: path to server log.
    android_package_key: name of Chrome's Android package.
    verbose: whether the output should be verbose.
    debug: whether the tests should wait until attached by a debugger.

  Returns:
    A list of |TestResult|s.
  """
  test_dir = util.MakeTempDir()
  keystore_path = ('java', 'client', 'test', 'keystore')
  required_dirs = [keystore_path[:-1],
                   ('javascript',),
                   ('third_party', 'closure', 'goog'),
                   ('third_party', 'js')]
  for required_dir in required_dirs:
    os.makedirs(os.path.join(test_dir, *required_dir))

  test_jar = 'test-standalone.jar'
  class_path = test_jar
  shutil.copyfile(os.path.join(java_tests_src_dir, 'keystore'),
                  os.path.join(test_dir, *keystore_path))
  util.Unzip(os.path.join(java_tests_src_dir, 'common.zip'), test_dir)
  shutil.copyfile(os.path.join(java_tests_src_dir, test_jar),
                  os.path.join(test_dir, test_jar))

  sys_props = ['selenium.browser=chrome',
               'webdriver.chrome.driver=' + os.path.abspath(chromedriver_path)]
  if chrome_path:
    sys_props += ['webdriver.chrome.binary=' + os.path.abspath(chrome_path)]
  if log_path:
    sys_props += ['webdriver.chrome.logfile=' + log_path]
  if android_package_key:
    android_package = constants.PACKAGE_INFO[android_package_key].package
    sys_props += ['webdriver.chrome.android_package=' + android_package]
    if android_package_key == 'chromedriver_webview_shell':
      android_activity = constants.PACKAGE_INFO[android_package_key].activity
      android_process = '%s:main' % android_package
      sys_props += ['webdriver.chrome.android_activity=' + android_activity]
      sys_props += ['webdriver.chrome.android_process=' + android_process]
  if test_filter:
    # Test jar actually takes a regex. Convert from glob.
    test_filter = test_filter.replace('*', '.*')
    sys_props += ['filter=' + test_filter]

  jvm_args = []
  if debug:
    transport = 'dt_socket'
    if util.IsWindows():
      transport = 'dt_shmem'
    jvm_args += ['-agentlib:jdwp=transport=%s,server=y,suspend=y,'
                 'address=33081' % transport]
    # Unpack the sources into the test directory and add to the class path
    # for ease of debugging, particularly with jdb.
    util.Unzip(os.path.join(java_tests_src_dir, 'test-nodeps-srcs.jar'),
               test_dir)
    class_path += ':' + test_dir

  return _RunAntTest(
      test_dir, 'org.openqa.selenium.chrome.ChromeDriverTests',
      class_path, sys_props, jvm_args, verbose)

def _RunAntTest(test_dir, test_class, class_path, sys_props, jvm_args, verbose):
  """Runs a single Ant JUnit test suite and returns the |TestResult|s.

  Args:
    test_dir: the directory to run the tests in.
    test_class: the name of the JUnit test suite class to run.
    class_path: the Java class path used when running the tests, colon delimited
    sys_props: Java system properties to set when running the tests.
    jvm_args: Java VM command line args to use.
    verbose: whether the output should be verbose.

  Returns:
    A list of |TestResult|s.
  """
  def _CreateBuildConfig(test_name, results_file, class_path, junit_props,
                         sys_props, jvm_args):
    def _SystemPropToXml(prop):
      key, value = prop.split('=')
      return '<sysproperty key="%s" value="%s"/>' % (key, value)
    def _JvmArgToXml(arg):
      return '<jvmarg value="%s"/>' % arg
    return '\n'.join([
        '<project>',
        '  <target name="test">',
        '    <junit %s>' % ' '.join(junit_props),
        '      <formatter type="xml"/>',
        '      <classpath>',
        '        <pathelement path="%s"/>' % class_path,
        '      </classpath>',
        '      ' + '\n      '.join(map(_SystemPropToXml, sys_props)),
        '      ' + '\n      '.join(map(_JvmArgToXml, jvm_args)),
        '      <test name="%s" outfile="%s"/>' % (test_name, results_file),
        '    </junit>',
        '  </target>',
        '</project>'])

  def _ProcessResults(results_path):
    doc = minidom.parse(results_path)
    tests = []
    for test in doc.getElementsByTagName('testcase'):
      name = test.getAttribute('classname') + '.' + test.getAttribute('name')
      time = test.getAttribute('time')
      failure = None
      error_nodes = test.getElementsByTagName('error')
      failure_nodes = test.getElementsByTagName('failure')
      if error_nodes:
        failure = error_nodes[0].childNodes[0].nodeValue
      elif failure_nodes:
        failure = failure_nodes[0].childNodes[0].nodeValue
      tests += [TestResult(name, time, failure)]
    return tests

  junit_props = ['printsummary="yes"',
                 'fork="yes"',
                 'haltonfailure="no"',
                 'haltonerror="no"']
  if verbose:
    junit_props += ['showoutput="yes"']

  ant_file = open(os.path.join(test_dir, 'build.xml'), 'w')
  ant_file.write(_CreateBuildConfig(
      test_class, 'results', class_path, junit_props, sys_props, jvm_args))
  ant_file.close()

  if util.IsWindows():
    ant_name = 'ant.bat'
  else:
    ant_name = 'ant'
  code = util.RunCommand([ant_name, 'test'], cwd=test_dir)
  if code != 0:
    print 'FAILED to run java tests of %s through ant' % test_class
    return
  return _ProcessResults(os.path.join(test_dir, 'results.xml'))

def PrintTestResults(results):
  """Prints the given results in a format recognized by the buildbot."""
  failures = []
  failure_names = []
  for result in results:
    if not result.IsPass():
      failures += [result]
      failure_names += ['.'.join(result.GetName().split('.')[-2:])]

  print 'Ran %s tests' % len(results)
  print 'Failed %s:' % len(failures)
  util.AddBuildStepText('failed %s/%s' % (len(failures), len(results)))
  for result in failures:
    print '=' * 80
    print '=' * 10, result.GetName(), '(%ss)' % result.GetTime()
    print result.GetFailureMessage()
    if len(failures) < 10:
      util.AddBuildStepText('.'.join(result.GetName().split('.')[-2:]))
  print 'Rerun failing tests with filter:', ':'.join(failure_names)
  return len(failures)

def main():
  parser = optparse.OptionParser()
  parser.add_option(
      '', '--verbose', action='store_true', default=False,
      help='Whether output should be verbose')
  parser.add_option(
      '', '--debug', action='store_true', default=False,
      help='Whether to wait to be attached by a debugger')
  parser.add_option(
      '', '--chromedriver', type='string', default=None,
      help='Path to a build of the chromedriver library(REQUIRED!)')
  parser.add_option(
      '', '--chrome', type='string', default=None,
      help='Path to a build of the chrome binary')
  parser.add_option(
      '', '--log-path',
      help='Output verbose server logs to this file')
  parser.add_option(
      '', '--chrome-version', default='HEAD',
      help='Version of chrome. Default is \'HEAD\'')
  parser.add_option(
      '', '--android-package', help='Android package key')
  parser.add_option(
      '', '--filter', type='string', default=None,
      help='Filter for specifying what tests to run, "*" will run all. E.g., '
           '*testShouldReturnTitleOfPageIfSet')
  parser.add_option(
      '', '--also-run-disabled-tests', action='store_true', default=False,
      help='Include disabled tests while running the tests')
  parser.add_option(
      '', '--isolate-tests', action='store_true', default=False,
      help='Relaunch the jar test harness after each test')
  options, _ = parser.parse_args()

  if util.IsLinux():
    wrapper_dir = util.MakeTempDir()
    wrapper_script = os.path.join(wrapper_dir, 'chrome')
    with open(wrapper_script, 'w') as f:
      f.write('#!/bin/sh\nexec "%s" --no-sandbox "$@"' % options.chrome)
    st = os.stat(wrapper_script)
    os.chmod(wrapper_script, st.st_mode | stat.S_IEXEC)
    options.chrome = wrapper_script

  options.chromedriver = util.GetAbsolutePathOfUserPath(options.chromedriver)
  if options.chromedriver is None or not os.path.exists(options.chromedriver):
    parser.error('chromedriver is required or the given path is invalid.' +
                 'Please run "%s --help" for help' % __file__)

  if options.android_package:
    if options.android_package not in constants.PACKAGE_INFO:
      parser.error('Invalid --android-package')
    if options.chrome_version != 'HEAD':
      parser.error('Android does not support the --chrome-version argument.')
    environment = test_environment.AndroidTestEnvironment(
        options.android_package)
  else:
    environment = test_environment.DesktopTestEnvironment(
        options.chrome_version)

  try:
    environment.GlobalSetUp()
    # Run passed tests when filter is not provided.
    if options.isolate_tests:
      test_filters = environment.GetPassedJavaTests()
    else:
      if options.filter:
        test_filter = options.filter
      else:
        test_filter = '*'
      if not options.also_run_disabled_tests:
        if '-' in test_filter:
          test_filter += ':'
        else:
          test_filter += '-'
        test_filter += ':'.join(environment.GetDisabledJavaTestMatchers())
      test_filters = [test_filter]

    java_tests_src_dir = os.path.join(chrome_paths.GetSrc(), 'chrome', 'test',
                                      'chromedriver', 'third_party',
                                      'java_tests')
    if (not os.path.exists(java_tests_src_dir) or
        not os.listdir(java_tests_src_dir)):
      java_tests_url = ('http://src.chromium.org/svn/trunk/deps/third_party'
                        '/webdriver')
      print ('"%s" is empty or it doesn\'t exist. ' % java_tests_src_dir +
             'Need to map <chrome-svn>/trunk/deps/third_party/webdriver to '
             'chrome/test/chromedriver/third_party/java_tests in .gclient.\n'
             'Alternatively, do:\n'
             '  $ cd chrome/test/chromedriver/third_party\n'
             '  $ svn co %s java_tests' % java_tests_url)
      return 1

    results = []
    for filter in test_filters:
      results += _Run(
          java_tests_src_dir=java_tests_src_dir,
          test_filter=filter,
          chromedriver_path=options.chromedriver,
          chrome_path=util.GetAbsolutePathOfUserPath(options.chrome),
          log_path=options.log_path,
          android_package_key=options.android_package,
          verbose=options.verbose,
          debug=options.debug)
    return PrintTestResults(results)
  finally:
    environment.GlobalTearDown()

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


<commit_before>#!/usr/bin/env python3
"""
Pong in Pygame (written against Python 3.5)
"""

import argparse
import math
import random
import sys
from collections import namedtuple

import pygame
from pygame import locals as consts

DEBUG = False
DEBUG_PATH = None
DEBUG_PATH_COLOR = (128, 0, 0,)

# Ye olde window constants
FRAMES_PER_SECOND = 40
BACKGROUND_COLOR = (0, 0, 0,)
SCREEN_HEIGHT = 1000
SCREEN_WIDTH = 1600

# Ball constants
BALL_START_ANGLE = 45
BALL_MIN_SPEED = 10
BALL_MAX_SPEED = 30
BALL_HEIGHT = 20
BALL_WIDTH = 20
BALL_COLOR = (127, 216, 127,)

# Paddle constants
PADDLE_MIN_SPEED = 10
PADDLE_MAX_SPEED = 20
PADDLE_HEIGHT = 150
PADDLE_WIDTH = 30
PADDLE_COLOR = (127, 216, 127,)
PADDLE_DOWN_DIR = 1
PADDLE_UP_DIR = -1

# Ye olde data structures
Sides = namedtuple('Sides', ['top', 'right', 'bottom', 'left'])
Cartesian = namedtuple('Cartesian', ['x', 'y'])

class Path:

    def __init__(self):
        self.points = []

    def __repr__(self):
        return '<Path ({})>'.format(','.join(self.points))

    def add(self, point):
        self.points.append(point)

    def clear(self):
        self.points = []

class Vector:

    def __init__(self, angle, magnitude):
        self.angle = angle
        self.magnitude = magnitude

    def __repr__(self):
        return '<Vector (a: {}, m: {} x: {}, y: {})>'.format(
            self.angle,
            self.magnitude,
            *self.cartesian)

    @classmethod
    def from_cartesian(x, y):
        self.magnitude = math.sqrt(x**2 + y**2)
        if x != 0:
            self.angle = math.degrees(math.atan(y / x))
        else:
            self.angle = 90 if y >= 0 else 270

    @property
    def cartesian(self):
        magnitude = self.magnitude
        angle = self.angle
        return Cartesian(
            x = magnitude * math.cos(math.radians(angle)),
            y = -magnitude * math.sin(math.radians(angle)),
        )

    def reflect(self, horizontally=False, vertically=False):
        normed_angle = self.angle % 360
        if horizontally:
            normed_angle = (360 - (normed_angle - 180)) % 360
        if vertically:
            normed_angle = 360 - normed_angle
        return self.__class__(normed_angle, self.magnitude)

class Ball:

    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((BALL_WIDTH, BALL_HEIGHT))
        self.image.fill(BALL_COLOR)
        center_vert = SCREEN_HEIGHT // 2 - (BALL_HEIGHT // 2)
        center_horiz = SCREEN_WIDTH // 2 - (BALL_WIDTH // 2)
        self.rect = self.image.get_rect().move(center_horiz, center_vert)
        angle = BALL_START_ANGLE or random.randint(0, 360)
        self.vector = Vector(angle, BALL_MAX_SPEED)
        self.touching_paddle = False

    def calc_sides_touched(self):
        return Sides(
            top = self.rect.top <= 0,
            right = self.rect.right >= SCREEN_WIDTH,
            bottom = self.rect.bottom >= SCREEN_HEIGHT,
            left = self.rect.left <= 0,
        )

    def check_paddle_collision(self, paddle):
        if pygame.sprite.collide_rect(self, paddle):
            self.touching_paddle = True

    def should_change_direction(self):
        screen_area = pygame.display.get_surface().get_rect()
        return not screen_area.contains(self.rect) or self.touching_paddle

    def update(self):
        if self.should_change_direction():
            sides_touched = self.calc_sides_touched()
            if any(sides_touched):
                reflect_h = sides_touched.left or sides_touched.right
                reflect_v = sides_touched.top or sides_touched.bottom
            else:
                reflect_h = True
                reflect_v = False
            self.vector = self.vector.reflect(reflect_h, reflect_v)
        self.rect.move_ip(*self.vector.cartesian)
        self.touching_paddle = False

class Paddle:

    def __init__(self, top, left):
        super().__init__()
        self.height = PADDLE_HEIGHT
        self.width = PADDLE_WIDTH
        self.image = pygame.Surface((self.width, self.height))
        self.image.fill(PADDLE_COLOR)
        self.rect = self.image.get_rect().move(left, top)
        self.speed = 0
        self.direction = 0
        self.is_moving = False

    def up(self):
        self.is_moving = True
        self.direction = PADDLE_UP_DIR
        self.speed = PADDLE_MAX_SPEED

    def down(self):
        self.is_moving = True
        self.direction = PADDLE_DOWN_DIR
        self.speed = PADDLE_MAX_SPEED

    def recenter(self):
        self.is_moving = True
        d_center = self.rect.centery - (SCREEN_HEIGHT // 2)
        self.direction = PADDLE_DOWN_DIR if d_center < 0 else PADDLE_UP_DIR
        self.speed = min(PADDLE_MAX_SPEED, abs(d_center))

    def update(self):
        if self.is_moving:
            self.rect.move_ip(0, self.speed * self.direction)
            self.is_moving = False

class MercilessAutomaton:

    def __init__(self, paddle):
        self.paddle = paddle
        self.sweet_spot_radius = self.paddle.rect.height // 4

    # TODO: don't assume we are on the right side
    def predict_intercept(self, start, vector, intercept_x, max_reflections=5):
        """
        Predict where the ball will intercept our paddle

        max_reflections specifies the maximum number of bounces off
        the top or bottom of the screen we are willing to calculate
        ahead of time. This estimate will be a little inaccurate if
        start and vector are calculated from the center of the ball
        because the bounce is calculated from the edges
        """
        DEBUG_PATH.add(start)
        x, y = start
        diff_x = intercept_x - x
        angle = vector.angle
        magnitude = diff_x / math.cos(math.radians(angle))
        projected = Vector(angle, magnitude)
        proj_y = y + projected.cartesian.y
        intercept = Cartesian(intercept_x, proj_y)

        if 0 <= proj_y <= SCREEN_HEIGHT:
            DEBUG_PATH.add(intercept)
            return intercept
        elif max_reflections == 0:
            return None

        if proj_y < 0:
            next_y = 0
        else:
            next_y = SCREEN_HEIGHT

        new_diff_y = abs(next_y - y)
        # kind of wonky looking math. here's what is intended:
        # 90 - (angle % 180) yields angle compared to y-axis
        #                    when we are moving to the right
        # Then SohCahToa...TAN is opposite over adjacent. we've defined
        #             angle such that length of adjacent leg is
        #             distance from starting coord to the top/bottom
        #             edge of the screen we are moving toward
        # this allows the computer player to predict what will happen
        # when the ball bounces off the top/bottom edge of the screen.
        new_diff_x = math.tan(math.radians(abs(90 - (angle % 180)))) * new_diff_y

        new_start = Cartesian(x + new_diff_x, next_y)
        new_vector = vector.reflect(vertically=True)
        return self.predict_intercept(new_start, new_vector, intercept_x,
                                      max_reflections-1)

    # TODO: don't assume we are on the right side
    def play(self, ball):
        """
        Implement a basic strategy

        Basic strategy:
        ===============
        1) Use geometry
        2) Never get tired, never get hungry. Never feel pity. Never
           be moved by a great symphony.
        3) Crush hoomuns.
        """
        DEBUG_PATH.clear()
        angle = ball.vector.angle
        its_coming_right_for_us = not (90 <= angle <= 270)
        is_in_play = (its_coming_right_for_us and
                      ball.rect.left <= self.paddle.rect.left)
        if is_in_play:
            ball_location = Cartesian(*ball.rect.center)
            intercept = self.predict_intercept(
                ball_location, ball.vector, self.paddle.rect.left)
            sweet_spot = Sides(
                top=self.paddle.rect.centery - self.sweet_spot_radius,
                bottom=self.paddle.rect.centery + self.sweet_spot_radius,
                left=None,
                right=None,
            )
            if intercept and intercept.y < sweet_spot.top:
                self.paddle.up()
            if intercept and intercept.y > sweet_spot.bottom:
                self.paddle.down()
        else:
            self.paddle.recenter()

def is_quit_event(e):
    return (
        e.type == consts.QUIT or
        (e.type == consts.KEYDOWN and e.key == consts.K_ESCAPE)
    )

def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('pong')
    pygame.mouse.set_visible(False)

    background = pygame.Surface(screen.get_size())
    background.fill(BACKGROUND_COLOR)
    screen.blit(background, (0, 0))

    paddle1 = Paddle(50, 100)
    paddle2 = Paddle(50, screen.get_rect().width - 110)
    computer = MercilessAutomaton(paddle2)
    ball = Ball()
    all_sprites = (paddle1, paddle2, ball,)
    clock = pygame.time.Clock()

    if DEBUG:
        import pdb

    while True:
        pygame.event.pump()
        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
            if is_quit_event(event):
                pygame.quit()
                sys.exit()

        if DEBUG and keys[ord('d')]:
            pdb.set_trace()

        if keys[consts.K_UP]:
            paddle1.up()
        elif keys[consts.K_DOWN]:
            paddle1.down()

        computer.play(ball)
        ball.check_paddle_collision(paddle1)
        ball.check_paddle_collision(paddle2)

        screen.blit(background, (0, 0))
        for sprite in all_sprites:
            sprite.update()
            screen.blit(sprite.image, sprite.rect)

        if DEBUG and len(DEBUG_PATH.points) > 1:
            pygame.draw.lines(screen, DEBUG_PATH_COLOR, False, DEBUG_PATH.points)
        pygame.display.flip()
        clock.tick(FRAMES_PER_SECOND)

    pygame.quit()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--debug', action='store_true')
    args = parser.parse_args()
    global DEBUG
    global DEBUG_PATH
    DEBUG = args.debug
    DEBUG_PATH = Path()
    main()
<commit_msg>take abs out here for trig clarity<commit_after>#!/usr/bin/env python3
"""
Pong in Pygame (written against Python 3.5)
"""

import argparse
import math
import random
import sys
from collections import namedtuple

import pygame
from pygame import locals as consts

DEBUG = False
DEBUG_PATH = None
DEBUG_PATH_COLOR = (128, 0, 0,)

# Ye olde window constants
FRAMES_PER_SECOND = 40
BACKGROUND_COLOR = (0, 0, 0,)
SCREEN_HEIGHT = 1000
SCREEN_WIDTH = 1600

# Ball constants
BALL_START_ANGLE = 62
BALL_MIN_SPEED = 10
BALL_MAX_SPEED = 30
BALL_HEIGHT = 20
BALL_WIDTH = 20
BALL_COLOR = (127, 216, 127,)

# Paddle constants
PADDLE_MIN_SPEED = 10
PADDLE_MAX_SPEED = 20
PADDLE_HEIGHT = 150
PADDLE_WIDTH = 30
PADDLE_COLOR = (127, 216, 127,)
PADDLE_DOWN_DIR = 1
PADDLE_UP_DIR = -1

# Ye olde data structures
Sides = namedtuple('Sides', ['top', 'right', 'bottom', 'left'])
Cartesian = namedtuple('Cartesian', ['x', 'y'])

class Path:

    def __init__(self):
        self.points = []

    def __repr__(self):
        return '<Path ({})>'.format(','.join(self.points))

    def add(self, point):
        self.points.append(point)

    def clear(self):
        self.points = []

class Vector:

    def __init__(self, angle, magnitude):
        self.angle = angle
        self.magnitude = magnitude

    def __repr__(self):
        return '<Vector (a: {}, m: {} x: {}, y: {})>'.format(
            self.angle,
            self.magnitude,
            *self.cartesian)

    @classmethod
    def from_cartesian(x, y):
        self.magnitude = math.sqrt(x**2 + y**2)
        if x != 0:
            self.angle = math.degrees(math.atan(y / x))
        else:
            self.angle = 90 if y >= 0 else 270

    @property
    def cartesian(self):
        magnitude = self.magnitude
        angle = self.angle
        return Cartesian(
            x = magnitude * math.cos(math.radians(angle)),
            y = -magnitude * math.sin(math.radians(angle)),
        )

    def reflect(self, horizontally=False, vertically=False):
        normed_angle = self.angle % 360
        if horizontally:
            normed_angle = (360 - (normed_angle - 180)) % 360
        if vertically:
            normed_angle = 360 - normed_angle
        return self.__class__(normed_angle, self.magnitude)

class Ball:

    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((BALL_WIDTH, BALL_HEIGHT))
        self.image.fill(BALL_COLOR)
        center_vert = SCREEN_HEIGHT // 2 - (BALL_HEIGHT // 2)
        center_horiz = SCREEN_WIDTH // 2 - (BALL_WIDTH // 2)
        self.rect = self.image.get_rect().move(center_horiz, center_vert)
        angle = BALL_START_ANGLE or random.randint(0, 360)
        self.vector = Vector(angle, BALL_MAX_SPEED)
        self.touching_paddle = False

    def calc_sides_touched(self):
        return Sides(
            top = self.rect.top <= 0,
            right = self.rect.right >= SCREEN_WIDTH,
            bottom = self.rect.bottom >= SCREEN_HEIGHT,
            left = self.rect.left <= 0,
        )

    def check_paddle_collision(self, paddle):
        if pygame.sprite.collide_rect(self, paddle):
            self.touching_paddle = True

    def should_change_direction(self):
        screen_area = pygame.display.get_surface().get_rect()
        return not screen_area.contains(self.rect) or self.touching_paddle

    def update(self):
        if self.should_change_direction():
            sides_touched = self.calc_sides_touched()
            if any(sides_touched):
                reflect_h = sides_touched.left or sides_touched.right
                reflect_v = sides_touched.top or sides_touched.bottom
            else:
                reflect_h = True
                reflect_v = False
            self.vector = self.vector.reflect(reflect_h, reflect_v)
        self.rect.move_ip(*self.vector.cartesian)
        self.touching_paddle = False

class Paddle:

    def __init__(self, top, left):
        super().__init__()
        self.height = PADDLE_HEIGHT
        self.width = PADDLE_WIDTH
        self.image = pygame.Surface((self.width, self.height))
        self.image.fill(PADDLE_COLOR)
        self.rect = self.image.get_rect().move(left, top)
        self.speed = 0
        self.direction = 0
        self.is_moving = False

    def up(self):
        self.is_moving = True
        self.direction = PADDLE_UP_DIR
        self.speed = PADDLE_MAX_SPEED

    def down(self):
        self.is_moving = True
        self.direction = PADDLE_DOWN_DIR
        self.speed = PADDLE_MAX_SPEED

    def recenter(self):
        self.is_moving = True
        d_center = self.rect.centery - (SCREEN_HEIGHT // 2)
        self.direction = PADDLE_DOWN_DIR if d_center < 0 else PADDLE_UP_DIR
        self.speed = min(PADDLE_MAX_SPEED, abs(d_center))

    def update(self):
        if self.is_moving:
            self.rect.move_ip(0, self.speed * self.direction)
            self.is_moving = False

class MercilessAutomaton:

    def __init__(self, paddle):
        self.paddle = paddle
        self.sweet_spot_radius = self.paddle.rect.height // 4

    # TODO: don't assume we are on the right side
    def predict_intercept(self, start, vector, intercept_x, max_reflections=5):
        """
        Predict where the ball will intercept our paddle

        max_reflections specifies the maximum number of bounces off
        the top or bottom of the screen we are willing to calculate
        ahead of time. This estimate will be a little inaccurate if
        start and vector are calculated from the center of the ball
        because the bounce is calculated from the edges
        """
        DEBUG_PATH.add(start)
        x, y = start
        diff_x = intercept_x - x
        angle = vector.angle
        magnitude = diff_x / math.cos(math.radians(angle))
        projected = Vector(angle, magnitude)
        proj_y = y + projected.cartesian.y
        intercept = Cartesian(intercept_x, proj_y)

        if 0 <= proj_y <= SCREEN_HEIGHT:
            DEBUG_PATH.add(intercept)
            return intercept
        elif max_reflections == 0:
            return None

        if proj_y < 0:
            next_y = 0
        else:
            next_y = SCREEN_HEIGHT

        new_diff_y = abs(next_y - y)
        # kind of wonky looking math. here's what is intended:
        # 90 - (angle % 180) yields angle compared to y-axis
        #                    when we are moving to the right
        # Then SohCahToa...TAN is opposite over adjacent. we've defined
        #             angle such that length of adjacent leg is
        #             distance from starting coord to the top/bottom
        #             edge of the screen we are moving toward
        # this allows the computer player to predict what will happen
        # when the ball bounces off the top/bottom edge of the screen.
        new_diff_x = abs(
            math.tan(math.radians(90 - (angle % 180))) * new_diff_y)

        new_start = Cartesian(x + new_diff_x, next_y)
        new_vector = vector.reflect(vertically=True)
        return self.predict_intercept(new_start, new_vector, intercept_x,
                                      max_reflections-1)

    # TODO: don't assume we are on the right side
    def play(self, ball):
        """
        Implement a basic strategy

        Basic strategy:
        ===============
        1) Use geometry
        2) Never get tired, never get hungry. Never feel pity. Never
           be moved by a great symphony.
        3) Crush hoomuns.
        """
        DEBUG_PATH.clear()
        angle = ball.vector.angle
        its_coming_right_for_us = not (90 <= angle <= 270)
        is_in_play = (its_coming_right_for_us and
                      ball.rect.left <= self.paddle.rect.left)
        if is_in_play:
            ball_location = Cartesian(*ball.rect.center)
            intercept = self.predict_intercept(
                ball_location, ball.vector, self.paddle.rect.left)
            sweet_spot = Sides(
                top=self.paddle.rect.centery - self.sweet_spot_radius,
                bottom=self.paddle.rect.centery + self.sweet_spot_radius,
                left=None,
                right=None,
            )
            if intercept and intercept.y < sweet_spot.top:
                self.paddle.up()
            if intercept and intercept.y > sweet_spot.bottom:
                self.paddle.down()
        else:
            self.paddle.recenter()

def is_quit_event(e):
    return (
        e.type == consts.QUIT or
        (e.type == consts.KEYDOWN and e.key == consts.K_ESCAPE)
    )

def main():
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('pong')
    pygame.mouse.set_visible(False)

    background = pygame.Surface(screen.get_size())
    background.fill(BACKGROUND_COLOR)
    screen.blit(background, (0, 0))

    paddle1 = Paddle(50, 100)
    paddle2 = Paddle(50, screen.get_rect().width - 110)
    computer = MercilessAutomaton(paddle2)
    ball = Ball()
    all_sprites = (paddle1, paddle2, ball,)
    clock = pygame.time.Clock()

    if DEBUG:
        import pdb

    while True:
        pygame.event.pump()
        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
            if is_quit_event(event):
                pygame.quit()
                sys.exit()

        if DEBUG and keys[ord('d')]:
            pdb.set_trace()

        if keys[consts.K_UP]:
            paddle1.up()
        elif keys[consts.K_DOWN]:
            paddle1.down()

        computer.play(ball)
        ball.check_paddle_collision(paddle1)
        ball.check_paddle_collision(paddle2)

        screen.blit(background, (0, 0))
        for sprite in all_sprites:
            sprite.update()
            screen.blit(sprite.image, sprite.rect)

        if DEBUG and len(DEBUG_PATH.points) > 1:
            pygame.draw.lines(screen, DEBUG_PATH_COLOR, False, DEBUG_PATH.points)
        pygame.display.flip()
        clock.tick(FRAMES_PER_SECOND)

    pygame.quit()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--debug', action='store_true')
    args = parser.parse_args()
    global DEBUG
    global DEBUG_PATH
    DEBUG = args.debug
    DEBUG_PATH = Path()
    main()
<|endoftext|>


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

# author: pharesim@nhzcrypto.org

import json
import urllib
import urllib2
import sqlite3
import math
import ConfigParser
import time

config = ConfigParser.RawConfigParser()
config.read('config.ini')

conn = sqlite3.connect(config.get("pool", "database"))
c = conn.cursor()

def main():
    while True:
        startForging()
        getleased()
        getNew(json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccountBlockIds&account="+config.get("pool", "poolaccount")+"&timestamp="+getTimestamp()).read()))
        time.sleep(100)
        payout()
        time.sleep(100)

def startForging():
    payload = {
        'requestType': 'getForging',
        'secretPhrase': config.get("pool", "poolphrase")
    }
    opener = urllib2.build_opener(urllib2.HTTPHandler())
    data = urllib.urlencode(payload)
    forging = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
    if 'errorCode' in forging.keys():
        if forging['errorCode'] == 5:
            payload['requestType'] = 'startForging'
            data = urllib.urlencode(payload)
            forging = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
            print "Started forging"

    return True

def getleased():
    leasedaccounts = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+config.get("pool", "poolaccount")).read())
    for lessor in leasedaccounts['lessors']:
        lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+lessor).read())
        balance = lessorAccount['guaranteedBalanceNQT']
        accountadd = lessorAccount['account']
        heightfrom = lessorAccount['currentLeasingHeightFrom']
        heightto = lessorAccount['currentLeasingHeightTo']
        rs = lessorAccount['accountRS']
        c.execute("INSERT OR REPLACE INTO leased (account, heightfrom, heightto, amount, ars) VALUES (?,?,?,?,?);",(accountadd, heightfrom, heightto, balance, rs))

    conn.commit()
    return True

def getNew(newBlocks):
    shares = getShares()
    if 'blockIds' in newBlocks:
        for block in newBlocks['blockIds']:
            blockData = json.loads(urllib2.urlopen(config.get("pool", "nhzhost2")+"/nhz?requestType=getBlock&block="+block).read())
            if 'errorCode' in blockData.keys():
                if blockData['errorCode'] == 5:
                    time.sleep(120)
                    return True
                else:
                    c.execute("INSERT OR IGNORE INTO blocks (timestamp, block, totalfee, height) VALUES (?,?,?,?);", (blockData['timestamp'],block,blockData['totalFeeNQT'],blockData['height']))

            blockFee = float(blockData['totalFeeNQT'])
            blockheight = float(blockData['height'])
            if blockFee > 0:
                for (account, amount) in shares.items():
                    if account is not config.get("pool", "poolaccount"):
                        lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+account).read())
                        heightfrom = lessorAccount['currentLeasingHeightFrom']
                        if heightfrom < blockheight:
                            payout = math.floor(blockFee * (amount['percentage']/100))

                            c.execute(
                                    "INSERT OR IGNORE INTO accounts (blocktime, account, percentage, amount, paid) VALUES (?,?,?,?,?);",
                            (blockData['timestamp'],account,amount['percentage'],payout,False)
                        )

    conn.commit()
    return True

def getTimestamp():
    timestamp = config.get("pool", "poolstart")

    c.execute("SELECT timestamp FROM blocks ORDER BY timestamp DESC LIMIT 1;")
    blocks = c.fetchall()

    if len(blocks) > 0 and blocks[0][0] > config.get("pool", "poolstart"):
        timestamp = blocks[0][0]

    return str(int(timestamp)+1)

def getShares():
    poolAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+config.get("pool", "poolaccount")).read())
    totalAmount = 0
    if 'guaranteedBalanceNQT' in poolAccount:
        totalAmount  = float(poolAccount['guaranteedBalanceNQT'])

    leasedAmount = { config.get("pool", "poolaccount"): { 'amount': totalAmount } }

    if 'lessors' in poolAccount:
        for lessor in poolAccount['lessors']:
            lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+lessor).read())
            leasedAmount[lessor] = { 'amount': float(lessorAccount['guaranteedBalanceNQT']) }
            totalAmount += float(lessorAccount['guaranteedBalanceNQT'])

    if totalAmount > 0:
        for (account, amount) in leasedAmount.items():
            leasedAmount[account]['percentage'] = amount['amount'] / (totalAmount/100)

    return leasedAmount

def payout():
    c.execute("SELECT account, amount FROM accounts WHERE paid=0 AND amount>0;")
    unpaid = c.fetchall()
    c.execute("SELECT * FROM blocks WHERE totalfee>0;")
    blocks = c.fetchall()

    pending = {}
    for share in unpaid:
        if share[0] in pending:
            pending[share[0]] += share[1]
        else:
            pending[share[0]] = share[1]

    for (account, amount) in pending.items():
        if amount > getLimit():
            time.sleep(100)
            fee     = int(math.floor(((amount*float(config.get("pool", "feePercent")))/100)))
            payment = str((amount-fee)-100000000)
            account = str(account)
            fee     = str(fee)
            print "Pay out "+payment+" to "+account+" (keep fee: "+fee+")"
            payload = {
                'requestType': 'sendMoney',
                'secretPhrase': config.get("pool", "poolphrase"),
                'recipient': account,
                'amountNQT': payment,
                'feeNQT': 100000000,
                'deadline': 60
            }
            opener = urllib2.build_opener(urllib2.HTTPHandler())
            data = urllib.urlencode(payload)
            content = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
            if 'transaction' in content.keys():
                c.execute("UPDATE accounts SET paid=? WHERE account=?;",(content['transaction'],str(account)))
                c.execute("INSERT INTO payouts (account, fee, payment) VALUES (?,?,?);",(account, fee, payment))

    conn.commit()
    return True

def getLimit():
    return float(config.get("pool", "payoutlimit"))*100000000;

if __name__ == "__main__":
    main()
<commit_msg>fork check<commit_after>#!/usr/bin/env python

# author: pharesim@nhzcrypto.org

import json
import urllib
import urllib2
import sqlite3
import math
import ConfigParser
import time

config = ConfigParser.RawConfigParser()
config.read('config.ini')

conn = sqlite3.connect(config.get("pool", "database"))
c = conn.cursor()

def main():
    while True:
        startForging()
        getleased()
        getNew(json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccountBlockIds&account="+config.get("pool", "poolaccount")+"&timestamp="+getTimestamp()).read()))
        time.sleep(100)
        payout()
        time.sleep(100)

def startForging():
    payload = {
        'requestType': 'getForging',
        'secretPhrase': config.get("pool", "poolphrase")
    }
    opener = urllib2.build_opener(urllib2.HTTPHandler())
    data = urllib.urlencode(payload)
    forging = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
    if 'errorCode' in forging.keys():
        if forging['errorCode'] == 5:
            payload['requestType'] = 'startForging'
            data = urllib.urlencode(payload)
            forging = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
            print "Started forging"

    return True

def getleased():
    leasedaccounts = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+config.get("pool", "poolaccount")).read())
    for lessor in leasedaccounts['lessors']:
        lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+lessor).read())
        balance = lessorAccount['guaranteedBalanceNQT']
        accountadd = lessorAccount['account']
        heightfrom = lessorAccount['currentLeasingHeightFrom']
        heightto = lessorAccount['currentLeasingHeightTo']
        rs = lessorAccount['accountRS']
        c.execute("INSERT OR REPLACE INTO leased (account, heightfrom, heightto, amount, ars) VALUES (?,?,?,?,?);",(accountadd, heightfrom, heightto, balance, rs))

    conn.commit()
    return True

def getNew(newBlocks):
    shares = getShares()
    if 'blockIds' in newBlocks:
        for block in newBlocks['blockIds']:
	    print block
            blockData = json.loads(urllib2.urlopen(config.get("pool", "nhzhost2")+"/nhz?requestType=getBlock&block="+block).read())
            print blockData
            c.execute("INSERT OR IGNORE INTO blocks (timestamp, block, totalfee, height) VALUES (?,?,?,?);", (blockData['timestamp'],block,blockData['totalFeeNQT'],blockData['height']))

            blockFee = float(blockData['totalFeeNQT'])
            blockheight = float(blockData['height'])
            if blockFee > 0:
                for (account, amount) in shares.items():
                    if account is not config.get("pool", "poolaccount"):
                        lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+account).read())
                        heightfrom = lessorAccount['currentLeasingHeightFrom']
                        if heightfrom < blockheight:
                            payout = math.floor(blockFee * (amount['percentage']/100))

                            c.execute(
                                    "INSERT OR IGNORE INTO accounts (blocktime, account, percentage, amount, paid) VALUES (?,?,?,?,?);",
                            (blockData['timestamp'],account,amount['percentage'],payout,False)
                        )

    conn.commit()
    return True

def getTimestamp():
    timestamp = config.get("pool", "poolstart")

    c.execute("SELECT timestamp FROM blocks ORDER BY timestamp DESC LIMIT 1;")
    blocks = c.fetchall()

    if len(blocks) > 0 and blocks[0][0] > config.get("pool", "poolstart"):
        timestamp = blocks[0][0]

    return str(int(timestamp)+1)

def getShares():
    poolAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+config.get("pool", "poolaccount")).read())
    totalAmount = 0
    if 'guaranteedBalanceNQT' in poolAccount:
        totalAmount  = float(poolAccount['guaranteedBalanceNQT'])

    leasedAmount = { config.get("pool", "poolaccount"): { 'amount': totalAmount } }

    if 'lessors' in poolAccount:
        for lessor in poolAccount['lessors']:
            lessorAccount = json.loads(urllib2.urlopen(config.get("pool", "nhzhost")+"/nhz?requestType=getAccount&account="+lessor).read())
            leasedAmount[lessor] = { 'amount': float(lessorAccount['guaranteedBalanceNQT']) }
            totalAmount += float(lessorAccount['guaranteedBalanceNQT'])

    if totalAmount > 0:
        for (account, amount) in leasedAmount.items():
            leasedAmount[account]['percentage'] = amount['amount'] / (totalAmount/100)

    return leasedAmount

def payout():
    c.execute("SELECT account, amount FROM accounts WHERE paid=0 AND amount>0;")
    unpaid = c.fetchall()
    c.execute("SELECT * FROM blocks WHERE totalfee>0;")
    blocks = c.fetchall()

    pending = {}
    for share in unpaid:
        if share[0] in pending:
            pending[share[0]] += share[1]
        else:
            pending[share[0]] = share[1]

    for (account, amount) in pending.items():
        if amount > getLimit():
            time.sleep(100)
            fee     = int(math.floor(((amount*float(config.get("pool", "feePercent")))/100)))
            payment = str((amount-fee)-100000000)
            account = str(account)
            fee     = str(fee)
            print "Pay out "+payment+" to "+account+" (keep fee: "+fee+")"
            payload = {
                'requestType': 'sendMoney',
                'secretPhrase': config.get("pool", "poolphrase"),
                'recipient': account,
                'amountNQT': payment,
                'feeNQT': 100000000,
                'deadline': 60
            }
            opener = urllib2.build_opener(urllib2.HTTPHandler())
            data = urllib.urlencode(payload)
            content = json.loads(opener.open(config.get("pool", "nhzhost")+'/nhz', data=data).read())
            if 'transaction' in content.keys():
                c.execute("UPDATE accounts SET paid=? WHERE account=?;",(content['transaction'],str(account)))
                c.execute("INSERT INTO payouts (account, fee, payment) VALUES (?,?,?);",(account, fee, payment))

    conn.commit()
    return True

def getLimit():
    return float(config.get("pool", "payoutlimit"))*100000000;

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


<commit_before>#!/bin/env python
#License#
#bitHopper by Colin Rice is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
#Based on a work at github.com.

import json
import work
import sys
import exceptions
import optparse
import time

from twisted.web import server, resource
from client import Agent
from _newclient import Request
from twisted.internet import reactor, defer
from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall
from twisted.python import log, failure

import urllib2

from password import *

def get_difficulty():
    req = urllib2.Request('http://blockexplorer.com/q/getdifficulty')
    response = urllib2.urlopen(req)
    diff_string = response.read()
    return float(diff_string)

difficulty = get_difficulty()

default_shares = difficulty

servers = {
        'bclc':{'shares':default_shares, 'name':'bitcoins.lc',
            'mine_address':'bitcoins.lc:8080', 'user':bclc_user, 'pass':bclc_pass,
            'lag':False, 'LP':None,
            'api_address':'https://www.bitcoins.lc/stats.json' },
        'mtred':{'shares':default_shares, 'name':'mtred',
            'mine_address':'mtred.com:8337', 'user':mtred_user, 'pass':mtred_pass,
            'lag':False, 'LP':None,
            'api_address':'https://mtred.com/api/user/key/d91c52cfe1609f161f28a1268a2915b8'},
        'btcg':{'shares':default_shares, 'name':'BTC Guild',
            'mine_address':'us.btcguild.com:8332', 'user':btcguild_user,
            'pass':btcguild_pass, 'lag':False, 'LP':None,
            'api_address':'https://www.btcguild.com/pool_stats.php'},
        'eligius':{'shares':difficulty*.41, 'name':'eligius',
            'mine_address':'su.mining.eligius.st:8337', 'user':eligius_address,
            'pass':'x', 'lag':False, 'LP':None},
        'mineco':{'shares': default_shares, 'name': 'mineco.in',
            'mine_address': 'mineco.in:3000', 'user': mineco_user,
            'pass': mineco_pass, 'lag': False, 'LP': None,
            'api_address':'https://mineco.in/stats.json', 'info':''},
        'bitclockers':{'shares': 0, 'name': 'bitclockers.com',
            'mine_address': 'pool.bitclockers.com:8332', 'user': bitclockers_user,
            'pass': bitclockers_pass, 'lag': False, 'LP': None,
            'api_address':'https://bitclockers.com/api'},
       'eclipsemc':{'shares': 0, 'name': 'eclipsemc.com',
            'mine_address': 'pacrim.eclipsemc.com:8337', 'user': eclipsemc_user,
            'pass': eclipsemc_pass, 'lag': False, 'LP': None,
            'api_address':'https://eclipsemc.com/api.php?key='+ eclipsemc_apikey
             +'&action=poolstats'},
   'miningmainframe':{'shares': 0, 'name': 'mining.mainframe.nl',
           'mine_address': 'mining.mainframe.nl:8343', 'user': miningmainframe_user,
           'pass': miningmainframe_pass, 'lag': False, 'LP': None,
            'api_address':'http://mining.mainframe.nl/api'}
        }

current_server = 'btcg'
json_agent = Agent(reactor)
lp_agent = Agent(reactor, persistent=True)
new_server = Deferred()

lp_set = False
options = None

def log_msg(msg):
    if options == None:
        print time.strftime("[%H:%M:%S] ") +str(msg)
        return
    if options.debug == True:
        log.msg(msg)
        return
    print time.strftime("[%H:%M:%S] ") +str(msg)

def log_dbg(msg):
    if options == None:
        return
    if options.debug == True:
        log.err(msg)
        return
    return

@defer.inlineCallbacks
def update_lp(response):
    global current_server
    log_msg("LP triggered from server " + str(current_server))
    global lp_set
    global new_server

    finish = Deferred()
    response.deliverBody(work.WorkProtocol(finish))
    try:
        body = yield finish
    except ResponseFailed:
        log_dbg('Reading LP Response failed')
        lp_set = True
        return

    try:
        message = json.loads(body)
        value =  message['result']
        #defer.returnValue(value)
    except exceptions.ValueError, e:
        log_dbg("Error in json decoding, Probably not a real LP response")
        lp_set = True
        log_dbg(body)
        defer.returnValue(None)

    update_servers()
    current = current_server
    select_best_server()
    if current == current_server:
        lp_set = False
        log_msg("LP triggering clients manually")
        new_server.callback(None)
        new_server = Deferred()

    defer.returnValue(None)

def set_lp(url, check = False):
    global lp_set
    if check:
        return not lp_set

    if lp_set:
        return

    global json_agent
    global servers
    global current_server
    server = servers[current_server]
    if url[0] == '/':
        lp_address = str(server['mine_address']) + str(url)
    else:
        lp_address = str(url)
    log_msg("LP Call " + lp_address)
    lp_set = True
    work.jsonrpc_lpcall(json_agent,server, lp_address, update_lp)

def select_best_server():
    """selects the best server for pool hopping. If there is not good server it returns eligious"""
    global servers
    global access
    global current_server
    global difficulty
    server_name = None

    min_shares = difficulty*.40

    for server in servers:
        info = servers[server]
        if 'info' in info:
            continue
        if info['shares']< min_shares and info['lag'] == False:
            min_shares = servers[server]['shares']
            server_name = server

    if server_name == None  and servers['eligius']['lag'] == False:
        server_name = 'eligius'

    elif server_name == None:
        min_shares = 10**10
        for server in servers:
            info = servers[server]
            if 'info' in info:
                continue
            if info['shares']< min_shares and info['lag'] == False:
                min_shares = servers[server]['shares']
                server_name = server

    if server_name == None:
        server_name = 'eligius'

    global new_server
    global lp_set

    if current_server != server_name:
        current_server = server_name
        lp_set = False
        log_msg("Server change to " + str(current_server) + ", telling client with LP")
        new_server.callback(None)
        new_server = Deferred()

    return

def get_new_server(server):
    global servers
    global current_server
    servers[current_server]['lag'] = True
    select_best_server()
    return servers[current_server]

def server_update():
    global servers
    min_shares = 10**10
    if servers[current_server]['shares'] > difficulty * .10:
        for server in servers:
            if servers[server]['shares'] < min_shares:
                min_shares = servers[server]['shares']

        if min_shares < servers[current_server]['shares']/2:
            select_best_server()
            return

    if servers[current_server]['shares'] > difficulty * .40:
        select_best_server()
        return

def mmf_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['shares_this_round'])
    servers['miningmainframe']['shares'] = round_shares
    log_msg( 'mining.mainframe.nl :' + str(round_shares))

def eclipsemc_sharesResponse(response):
    global servers
    info = json.loads(response[:response.find('}')+1])
    round_shares = int(info['round_shares'])
    servers['eclipsemc']['roundshares'] = round_shares
    log_msg( 'eclipsemc :' + str(round_shares))

def btcguild_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['round_shares'])
    servers['btcg']['shares'] = round_shares
    log_msg( 'btcguild :' + str(round_shares))

def bclc_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['round_shares'])
    servers['bclc']['shares'] = round_shares
    log_msg( 'bitcoin.lc :' + str(round_shares))

def mtred_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['server']['roundshares'])
    servers['mtred']['shares'] = round_shares
    log_msg('mtred :' + str(round_shares))

def mineco_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['shares_this_round'])
    servers['mineco']['shares'] = round_shares
    log_msg( 'mineco :' + str(round_shares))

def bitclockers_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['roundshares'])
    servers['bitclockers']['shares'] = round_shares
    log_msg( 'bitclockers :' + str(round_shares))

def errsharesResponse(error, args):
    log_msg('Error in pool api for ' + str(args))
    log_msg(str(error))
    pool = args
    global servers
    servers[pool]['shares'] = 10**10

def selectsharesResponse(response, args):
    #log_dbg('Calling sharesResponse for '+ args)
    func_map= {'bitclockers':bitclockers_sharesResponse,
        'mineco':mineco_sharesResponse,
        'mtred':mtred_sharesResponse,
        'bclc':bclc_sharesResponse,
        'btcg':btcguild_sharesResponse,
        'eclipsemc':eclipsemc_sharesResponse,
        'miningmainframe':mmf_sharesResponse}
    func_map[args](response)
    server_update()

def update_servers():
    global servers
    for server in servers:
        global json_agent
        if server is not 'eligius':
            info = servers[server]
            d = work.get(json_agent,info['api_address'])
            d.addCallback(selectsharesResponse, (server))
            d.addErrback(errsharesResponse, (server))
            d.addErrback(log_msg)

@defer.inlineCallbacks
def delag_server():
    log_dbg('Running Delager')
    global servers
    global json_agent
    for index in servers:
        server = servers[index]
        if server['lag'] == True:
            data = yield work.jsonrpc_call(json_agent, server,[], set_lp)
            if data != None:
                server['lag'] = False

def bitHopper_Post(request):

    global options
    if not options.noLP:
        request.setHeader('X-Long-Polling', '/LP')
    rpc_request = json.loads(request.content.read())
    #check if they are sending a valid message
    if rpc_request['method'] != "getwork":
        return json.dumps({'result':None, 'error':'Not supported', 'id':rpc_request['id']})

    #Check for data to be validated
    global servers
    global current_server
    global json_agent
    pool_server=servers[current_server]

    data = rpc_request['params']
    j_id = rpc_request['id']

    log_msg('RPC request ' + str(data) + " submitted to " + str(pool_server['name']))
    work.jsonrpc_getwork(json_agent, pool_server, data, j_id, request, get_new_server, set_lp)

    return server.NOT_DONE_YET

def bitHopperLP(value, *methodArgs):
    try:
        log_msg('LP triggered serving miner')
        request = methodArgs[0]
        #Duplicated from above because its a little less of a hack
        #But apparently people expect well formed json-rpc back but won't actually make the call
        try:
            json_request = request.content.read()
        except Exception,e:
            log_dbg( 'reading request content failed')
            json_request = None
        try:
            rpc_request = json.loads(json_request)
        except Exception, e:
            log_dbg('Loading the request failed')
            rpc_request = {'params':[],'id':1}
        #Check for data to be validated
        global servers
        global current_server
        global json_agent
        pool_server=servers[current_server]

        data = rpc_request['params']
        j_id = rpc_request['id']

        work.jsonrpc_getwork(json_agent, pool_server, data, j_id, request, get_new_server, set_lp)

    except Exception, e:
        log_msg('Error Caught in bitHopperLP')
        log_dbg(str(e))
        try:
            request.finish()
        except Exception, e:
            log_dbg( "Client already disconnected Urgh.")

    return None

class lpSite(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def render_POST(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def getChild(self,name,request):
        return self

class bitSite(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def render_POST(self, request):
        return bitHopper_Post(request)

    def getChild(self,name,request):
        if name == 'LP':
            return lpSite()
        return self

def main():
    global options
    parser = optparse.OptionParser(description='bitHopper')
    parser.add_option('--noLP', action = 'store_true' ,default=False, help='turns off client side longpolling')
    parser.add_option('--debug', action= 'store_true', default = False, help='Use twisted output')
    args, rest = parser.parse_args()
    options = args

    if options.debug: log.startLogging(sys.stdout)
    site = server.Site(bitSite())
    reactor.listenTCP(8337, site)
    update_call = LoopingCall(update_servers)
    update_call.start(117)
    delag_call = LoopingCall(delag_server)
    delag_call.start(30)
    reactor.run()

if __name__ == "__main__":
    main()

<commit_msg>Fixed eclipse shares function<commit_after>#!/bin/env python
#License#
#bitHopper by Colin Rice is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
#Based on a work at github.com.

import json
import work
import sys
import exceptions
import optparse
import time

from twisted.web import server, resource
from client import Agent
from _newclient import Request
from twisted.internet import reactor, defer
from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall
from twisted.python import log, failure

import urllib2

from password import *

def get_difficulty():
    req = urllib2.Request('http://blockexplorer.com/q/getdifficulty')
    response = urllib2.urlopen(req)
    diff_string = response.read()
    return float(diff_string)

difficulty = get_difficulty()

default_shares = difficulty

servers = {
        'bclc':{'shares':default_shares, 'name':'bitcoins.lc',
            'mine_address':'bitcoins.lc:8080', 'user':bclc_user, 'pass':bclc_pass,
            'lag':False, 'LP':None,
            'api_address':'https://www.bitcoins.lc/stats.json' },
        'mtred':{'shares':default_shares, 'name':'mtred',
            'mine_address':'mtred.com:8337', 'user':mtred_user, 'pass':mtred_pass,
            'lag':False, 'LP':None,
            'api_address':'https://mtred.com/api/user/key/d91c52cfe1609f161f28a1268a2915b8'},
        'btcg':{'shares':default_shares, 'name':'BTC Guild',
            'mine_address':'us.btcguild.com:8332', 'user':btcguild_user,
            'pass':btcguild_pass, 'lag':False, 'LP':None,
            'api_address':'https://www.btcguild.com/pool_stats.php'},
        'eligius':{'shares':difficulty*.41, 'name':'eligius',
            'mine_address':'su.mining.eligius.st:8337', 'user':eligius_address,
            'pass':'x', 'lag':False, 'LP':None},
        'mineco':{'shares': default_shares, 'name': 'mineco.in',
            'mine_address': 'mineco.in:3000', 'user': mineco_user,
            'pass': mineco_pass, 'lag': False, 'LP': None,
            'api_address':'https://mineco.in/stats.json', 'info':''},
        'bitclockers':{'shares': 0, 'name': 'bitclockers.com',
            'mine_address': 'pool.bitclockers.com:8332', 'user': bitclockers_user,
            'pass': bitclockers_pass, 'lag': False, 'LP': None,
            'api_address':'https://bitclockers.com/api'},
       'eclipsemc':{'shares': 0, 'name': 'eclipsemc.com',
            'mine_address': 'pacrim.eclipsemc.com:8337', 'user': eclipsemc_user,
            'pass': eclipsemc_pass, 'lag': False, 'LP': None,
            'api_address':'https://eclipsemc.com/api.php?key='+ eclipsemc_apikey
             +'&action=poolstats'},
   'miningmainframe':{'shares': 0, 'name': 'mining.mainframe.nl',
           'mine_address': 'mining.mainframe.nl:8343', 'user': miningmainframe_user,
           'pass': miningmainframe_pass, 'lag': False, 'LP': None,
            'api_address':'http://mining.mainframe.nl/api'}
        }

current_server = 'btcg'
json_agent = Agent(reactor)
lp_agent = Agent(reactor, persistent=True)
new_server = Deferred()

lp_set = False
options = None

def log_msg(msg):
    if options == None:
        print time.strftime("[%H:%M:%S] ") +str(msg)
        return
    if options.debug == True:
        log.msg(msg)
        return
    print time.strftime("[%H:%M:%S] ") +str(msg)

def log_dbg(msg):
    if options == None:
        return
    if options.debug == True:
        log.err(msg)
        return
    return

@defer.inlineCallbacks
def update_lp(response):
    global current_server
    log_msg("LP triggered from server " + str(current_server))
    global lp_set
    global new_server

    finish = Deferred()
    response.deliverBody(work.WorkProtocol(finish))
    try:
        body = yield finish
    except ResponseFailed:
        log_dbg('Reading LP Response failed')
        lp_set = True
        return

    try:
        message = json.loads(body)
        value =  message['result']
        #defer.returnValue(value)
    except exceptions.ValueError, e:
        log_dbg("Error in json decoding, Probably not a real LP response")
        lp_set = True
        log_dbg(body)
        defer.returnValue(None)

    update_servers()
    current = current_server
    select_best_server()
    if current == current_server:
        lp_set = False
        log_msg("LP triggering clients manually")
        new_server.callback(None)
        new_server = Deferred()

    defer.returnValue(None)

def set_lp(url, check = False):
    global lp_set
    if check:
        return not lp_set

    if lp_set:
        return

    global json_agent
    global servers
    global current_server
    server = servers[current_server]
    if url[0] == '/':
        lp_address = str(server['mine_address']) + str(url)
    else:
        lp_address = str(url)
    log_msg("LP Call " + lp_address)
    lp_set = True
    work.jsonrpc_lpcall(json_agent,server, lp_address, update_lp)

def select_best_server():
    """selects the best server for pool hopping. If there is not good server it returns eligious"""
    global servers
    global access
    global current_server
    global difficulty
    server_name = None

    min_shares = difficulty*.40

    for server in servers:
        info = servers[server]
        if 'info' in info:
            continue
        if info['shares']< min_shares and info['lag'] == False:
            min_shares = servers[server]['shares']
            server_name = server

    if server_name == None  and servers['eligius']['lag'] == False:
        server_name = 'eligius'

    elif server_name == None:
        min_shares = 10**10
        for server in servers:
            info = servers[server]
            if 'info' in info:
                continue
            if info['shares']< min_shares and info['lag'] == False:
                min_shares = servers[server]['shares']
                server_name = server

    if server_name == None:
        server_name = 'eligius'

    global new_server
    global lp_set

    if current_server != server_name:
        current_server = server_name
        lp_set = False
        log_msg("Server change to " + str(current_server) + ", telling client with LP")
        new_server.callback(None)
        new_server = Deferred()

    return

def get_new_server(server):
    global servers
    global current_server
    servers[current_server]['lag'] = True
    select_best_server()
    return servers[current_server]

def server_update():
    global servers
    min_shares = 10**10
    if servers[current_server]['shares'] > difficulty * .10:
        for server in servers:
            if servers[server]['shares'] < min_shares:
                min_shares = servers[server]['shares']

        if min_shares < servers[current_server]['shares']/2:
            select_best_server()
            return

    if servers[current_server]['shares'] > difficulty * .40:
        select_best_server()
        return

def mmf_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['shares_this_round'])
    servers['miningmainframe']['shares'] = round_shares
    log_msg( 'mining.mainframe.nl :' + str(round_shares))

def eclipsemc_sharesResponse(response):
    global servers
    info = json.loads(response[:response.find('}')+1])
    round_shares = int(info['round_shares'])
    servers['eclipsemc']['shares'] = round_shares
    log_msg( 'eclipsemc :' + str(round_shares))

def btcguild_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['round_shares'])
    servers['btcg']['shares'] = round_shares
    log_msg( 'btcguild :' + str(round_shares))

def bclc_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['round_shares'])
    servers['bclc']['shares'] = round_shares
    log_msg( 'bitcoin.lc :' + str(round_shares))

def mtred_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['server']['roundshares'])
    servers['mtred']['shares'] = round_shares
    log_msg('mtred :' + str(round_shares))

def mineco_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['shares_this_round'])
    servers['mineco']['shares'] = round_shares
    log_msg( 'mineco :' + str(round_shares))

def bitclockers_sharesResponse(response):
    global servers
    info = json.loads(response)
    round_shares = int(info['roundshares'])
    servers['bitclockers']['shares'] = round_shares
    log_msg( 'bitclockers :' + str(round_shares))

def errsharesResponse(error, args):
    log_msg('Error in pool api for ' + str(args))
    log_msg(str(error))
    pool = args
    global servers
    servers[pool]['shares'] = 10**10

def selectsharesResponse(response, args):
    #log_dbg('Calling sharesResponse for '+ args)
    func_map= {'bitclockers':bitclockers_sharesResponse,
        'mineco':mineco_sharesResponse,
        'mtred':mtred_sharesResponse,
        'bclc':bclc_sharesResponse,
        'btcg':btcguild_sharesResponse,
        'eclipsemc':eclipsemc_sharesResponse,
        'miningmainframe':mmf_sharesResponse}
    func_map[args](response)
    server_update()

def update_servers():
    global servers
    for server in servers:
        global json_agent
        if server is not 'eligius':
            info = servers[server]
            d = work.get(json_agent,info['api_address'])
            d.addCallback(selectsharesResponse, (server))
            d.addErrback(errsharesResponse, (server))
            d.addErrback(log_msg)

@defer.inlineCallbacks
def delag_server():
    log_dbg('Running Delager')
    global servers
    global json_agent
    for index in servers:
        server = servers[index]
        if server['lag'] == True:
            data = yield work.jsonrpc_call(json_agent, server,[], set_lp)
            if data != None:
                server['lag'] = False

def bitHopper_Post(request):

    global options
    if not options.noLP:
        request.setHeader('X-Long-Polling', '/LP')
    rpc_request = json.loads(request.content.read())
    #check if they are sending a valid message
    if rpc_request['method'] != "getwork":
        return json.dumps({'result':None, 'error':'Not supported', 'id':rpc_request['id']})

    #Check for data to be validated
    global servers
    global current_server
    global json_agent
    pool_server=servers[current_server]

    data = rpc_request['params']
    j_id = rpc_request['id']

    log_msg('RPC request ' + str(data) + " submitted to " + str(pool_server['name']))
    work.jsonrpc_getwork(json_agent, pool_server, data, j_id, request, get_new_server, set_lp)

    return server.NOT_DONE_YET

def bitHopperLP(value, *methodArgs):
    try:
        log_msg('LP triggered serving miner')
        request = methodArgs[0]
        #Duplicated from above because its a little less of a hack
        #But apparently people expect well formed json-rpc back but won't actually make the call
        try:
            json_request = request.content.read()
        except Exception,e:
            log_dbg( 'reading request content failed')
            json_request = None
        try:
            rpc_request = json.loads(json_request)
        except Exception, e:
            log_dbg('Loading the request failed')
            rpc_request = {'params':[],'id':1}
        #Check for data to be validated
        global servers
        global current_server
        global json_agent
        pool_server=servers[current_server]

        data = rpc_request['params']
        j_id = rpc_request['id']

        work.jsonrpc_getwork(json_agent, pool_server, data, j_id, request, get_new_server, set_lp)

    except Exception, e:
        log_msg('Error Caught in bitHopperLP')
        log_dbg(str(e))
        try:
            request.finish()
        except Exception, e:
            log_dbg( "Client already disconnected Urgh.")

    return None

class lpSite(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def render_POST(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def getChild(self,name,request):
        return self

class bitSite(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        global new_server
        new_server.addCallback(bitHopperLP, (request))
        return server.NOT_DONE_YET

    def render_POST(self, request):
        return bitHopper_Post(request)

    def getChild(self,name,request):
        if name == 'LP':
            return lpSite()
        return self

def main():
    global options
    parser = optparse.OptionParser(description='bitHopper')
    parser.add_option('--noLP', action = 'store_true' ,default=False, help='turns off client side longpolling')
    parser.add_option('--debug', action= 'store_true', default = False, help='Use twisted output')
    args, rest = parser.parse_args()
    options = args

    if options.debug: log.startLogging(sys.stdout)
    site = server.Site(bitSite())
    reactor.listenTCP(8337, site)
    update_call = LoopingCall(update_servers)
    update_call.start(117)
    delag_call = LoopingCall(delag_server)
    delag_call.start(30)
    reactor.run()

if __name__ == "__main__":
    main()

<|endoftext|>


<commit_before># Copyright 2016 Red Hat, Inc.
#
# 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.

"""
    Version information.

    .. moduleauthor::  mulhern  <amulhern@redhat.com>
"""

__version_info__ = (0, 0, 4)
__version__ = '.'.join(str(x) for x in __version_info__)
<commit_msg>Version 0.0.5<commit_after># Copyright 2016 Red Hat, Inc.
#
# 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.

"""
    Version information.

    .. moduleauthor::  mulhern  <amulhern@redhat.com>
"""

__version_info__ = (0, 0, 5)
__version__ = '.'.join(str(x) for x in __version_info__)
<|endoftext|>


<commit_before># Copyright 2019 The TensorFlow Authors. 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.
# ==============================================================================
"""Tests for continuous runs using cross-worker collective ops."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import json
import os
from absl.testing import parameterized
import numpy as np

from tensorflow.python.distribute import collective_all_reduce_strategy
from tensorflow.python.distribute import combinations
from tensorflow.python.distribute import multi_process_runner
from tensorflow.python.distribute import multi_worker_test_base as test_base
from tensorflow.python.distribute import reduce_util
from tensorflow.python.eager import context
from tensorflow.python.eager import def_function
from tensorflow.python.eager import test
from tensorflow.python.framework import config
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops

# TODO(b/143286947): expand the test to cover fault tolerance and elasticity
class MultiWorkerContinuousRunTest(test.TestCase, parameterized.TestCase):

  @combinations.generate(combinations.combine(mode=['eager']))
  def testAllReduceContinuousRun(self, mode):
    num_workers = 5
    tensor_shape = [2, 2]
    local_device = '/device:CPU:0'
    if config.list_physical_devices('GPU'):
      local_device = '/device:GPU:0'

    def worker_step_fn():
      strategy = collective_all_reduce_strategy.CollectiveAllReduceStrategy()
      tf_config = json.loads(os.environ['TF_CONFIG'])
      worker_id = tf_config['task']['index']

      @def_function.function
      def run_reduce():
        with ops.device(local_device):
          t_in = array_ops.ones(tensor_shape) * worker_id
          return strategy.reduce(reduce_util.ReduceOp.MEAN, t_in, axis=None)

      t_out = run_reduce()
      # Element values from the workers are
      #     0, 1, ..., (num_workers - 1)
      expected_mean = (num_workers - 1) / 2
      expected_out = np.ones(tensor_shape) * expected_mean
      self.assertAllClose(t_out, expected_out)

    def worker_fn():
      gpus = config.list_physical_devices('GPU')
      if gpus:
        # Set virtual GPU with memory limit of 64MB so that multiple worker
        # processes can share the physical GPU
        config.set_logical_device_configuration(
            gpus[0], [context.LogicalDeviceConfiguration(64)])
      for _ in range(100):
        worker_step_fn()

    multi_process_runner.MultiProcessRunner().run(
        worker_fn,
        cluster_spec=test_base.create_cluster_spec(num_workers=num_workers))

if __name__ == '__main__':
  multi_process_runner.test_main()
<commit_msg>Use try_run_and_except_connection_error on multi_worker_continuous_run_test to avoid flakiness.<commit_after># Copyright 2019 The TensorFlow Authors. 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.
# ==============================================================================
"""Tests for continuous runs using cross-worker collective ops."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import json
import os
from absl.testing import parameterized
import numpy as np

from tensorflow.python.distribute import collective_all_reduce_strategy
from tensorflow.python.distribute import combinations
from tensorflow.python.distribute import multi_process_runner
from tensorflow.python.distribute import multi_process_runner_util
from tensorflow.python.distribute import multi_worker_test_base as test_base
from tensorflow.python.distribute import reduce_util
from tensorflow.python.eager import context
from tensorflow.python.eager import def_function
from tensorflow.python.eager import test
from tensorflow.python.framework import config
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops

# TODO(b/143286947): expand the test to cover fault tolerance and elasticity
class MultiWorkerContinuousRunTest(test.TestCase, parameterized.TestCase):

  @combinations.generate(combinations.combine(mode=['eager']))
  def testAllReduceContinuousRun(self, mode):
    num_workers = 5
    tensor_shape = [2, 2]
    local_device = '/device:CPU:0'
    if config.list_physical_devices('GPU'):
      local_device = '/device:GPU:0'

    def worker_step_fn():
      strategy = collective_all_reduce_strategy.CollectiveAllReduceStrategy()
      tf_config = json.loads(os.environ['TF_CONFIG'])
      worker_id = tf_config['task']['index']

      @def_function.function
      def run_reduce():
        with ops.device(local_device):
          t_in = array_ops.ones(tensor_shape) * worker_id
          return strategy.reduce(reduce_util.ReduceOp.MEAN, t_in, axis=None)

      t_out = run_reduce()
      # Element values from the workers are
      #     0, 1, ..., (num_workers - 1)
      expected_mean = (num_workers - 1) / 2
      expected_out = np.ones(tensor_shape) * expected_mean
      self.assertAllClose(t_out, expected_out)

    def worker_fn():
      gpus = config.list_physical_devices('GPU')
      if gpus:
        # Set virtual GPU with memory limit of 64MB so that multiple worker
        # processes can share the physical GPU
        config.set_logical_device_configuration(
            gpus[0], [context.LogicalDeviceConfiguration(64)])
      for _ in range(100):
        worker_step_fn()

    # TODO(b/141948186): Remove this `with` block once b/141948186 is resolved.
    with multi_process_runner_util.try_run_and_except_connection_error(self):
      multi_process_runner.MultiProcessRunner().run(
          worker_fn,
          cluster_spec=test_base.create_cluster_spec(num_workers=num_workers))

if __name__ == '__main__':
  multi_process_runner.test_main()
<|endoftext|>