<commit_before># Copyright (c) 2011 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.

import re

from buildbot.process.properties import Properties
from buildbot.schedulers.trysched import TryBase
from buildbot.schedulers.trysched import BadJobfile
from twisted.internet import defer
from twisted.python import log
from twisted.web import client

class TryJobBase(TryBase):
  compare_attrs = TryBase.compare_attrs + (
      'pools', 'last_good-urls', 'code_review_sites')

  # Simplistic email matching regexp.
  _EMAIL_VALIDATOR = re.compile(
      r'[a-zA-Z][a-zA-Z0-9\.\+\-\_]*@[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,3}$')

  def __init__(self, name, pools, properties,
               last_good_urls, code_review_sites):
    TryBase.__init__(self, name, pools.ListBuilderNames(), properties or {})
    self.pools = pools
    pools.SetParent(self)
    self.last_good_urls = last_good_urls
    self.code_review_sites = code_review_sites
    self._last_lkgr = None

  def gotChange(self, change, important):  # pylint: disable=R0201
    log.msg('ERROR: gotChange was unexpectedly called.')

  def parse_options(self, options):
    """Converts try job settings into a dict."""
    # Flush None and '' keys.
    options = dict(
        (k, v) for k, v in options.iteritems() if v not in (None, ''))

    options.setdefault('name', 'Unnamed')
    options.setdefault('user', 'John Doe')
    options['email'] = [e for e in options.get('email', '').split(',') if e]
    for email in options['email']:
      if not TryJobBase._EMAIL_VALIDATOR.match(email):
        raise BadJobfile("'%s' is an invalid email address!" % email)

    options.setdefault('patch', None)
    options.setdefault('root', None)
    # -pN argument to patch.
    options['patchlevel'] = int(options.get('patchlevel', 0))
    options.setdefault('branch', None)
    options.setdefault('revision', None)
    options.setdefault('reason', '%s: %s' % (options['user'], options['name']))
    options['testfilter'] = [
        i for i in options.get('testfilter', '').split(',') if i
    ]
    options.setdefault('project', self.pools.default_pool_name)
    options.setdefault('repository', None)
    # Code review infos. Enforce numbers.
    def try_int(key):
      if options.setdefault(key, None) is None:
        return
      options[key] = int(options[key])
    try_int('patchset')
    try_int('issue')

    builder_names = []
    if 'bot' in options:
      builder_names = options.get('bot', '').split(',')
    options['bot'] = self.pools.Select(builder_names, options['project'])
    log.msg(
        'Choose %s for job %s' % (','.join(options['bot']), options['reason']))
    return options

  def get_props(self, options):
    """Current job extra properties that are not related to the source stamp.
    Initialize with the Scheduler's base properties.
    """
    keys = ('clobber', 'issue', 'patchset', 'rietveld', 'testfilter')
    # All these settings have no meaning when False or not set, so don't set
    # them in that case.
    properties = dict((i, options[i]) for i in keys if options.get(i))
    props = Properties()
    props.updateFromProperties(self.properties)
    props.update(properties, 'Try job')
    return props

  @staticmethod
  def parse_decoration(properties, decorations):
    """Returns properties extended by the meaning of decoration.
    """

    props = Properties()
    props.updateFromProperties(properties)
    for decoration in decorations.split(':'):
      if decoration == 'compile':
        testfilter = props.getProperty('testfilter') or 'None'
        props.setProperty('testfilter', testfilter, 'Decoration')

      #TODO(petermayo) Define a DSL of useful modifications to individual
      # bots of a test run.
    return props

  def SubmitJob(self, parsed_job, changeids):
    if not parsed_job['bot']:
      raise BadJobfile(
          'incoming Try job did not specify any allowed builder names')

    d = self.master.db.sourcestamps.addSourceStamp(
        branch=parsed_job['branch'],
        revision=parsed_job['revision'],
        patch_body=parsed_job['patch'],
        patch_level=parsed_job['patchlevel'],
        patch_subdir=parsed_job['root'],
        project=parsed_job['project'],
        repository=parsed_job['repository'] or '',
        changeids=changeids)

    def create_buildset(ssid):
      log.msg('Creating try job(s) %s' % ssid)
      result = None
      for build in parsed_job['bot']:
        bot = build.split(':', 1)[0]
        result = self.addBuildsetForSourceStamp(ssid=ssid,
            reason=parsed_job['name'],
            external_idstring=parsed_job['name'],
            builderNames=[bot],
            properties=self.parse_decoration(
                self.get_props(parsed_job), ''.join(build.split(':', 1)[1:])))
      return result

    d.addCallback(create_buildset)
    d.addErrback(log.err, "Failed to queue a try job!")
    return d

  def get_lkgr(self, options):
    """Grabs last known good revision number if necessary."""
    options['rietveld'] = (self.code_review_sites or {}).get(options['project'])
    last_good_url = (self.last_good_urls or {}).get(options['project'])
    if options['revision'] or not last_good_url:
      return defer.succeed(0)

    def Success(result):
      try:
        new_value = int(result.strip())
      except (TypeError, ValueError):
        new_value = None
      if new_value and (not self._last_lkgr or new_value > self._last_lkgr):
        self._last_lkgr = new_value
      options['revision'] = self._last_lkgr or 'HEAD'

    def Failure(result):
      options['revision'] = self._last_lkgr or 'HEAD'

    connection = client.getPage(last_good_url, agent='buildbot')
    connection.addCallbacks(Success, Failure)
    return connection
<commit_msg>Add exception handling to parse_options() and throw BadJobfile on failure.<commit_after># Copyright (c) 2011 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.

import re

from buildbot.process.properties import Properties
from buildbot.schedulers.trysched import TryBase
from buildbot.schedulers.trysched import BadJobfile
from twisted.internet import defer
from twisted.python import log
from twisted.web import client

class TryJobBase(TryBase):
  compare_attrs = TryBase.compare_attrs + (
      'pools', 'last_good-urls', 'code_review_sites')

  # Simplistic email matching regexp.
  _EMAIL_VALIDATOR = re.compile(
      r'[a-zA-Z][a-zA-Z0-9\.\+\-\_]*@[a-zA-Z0-9\.\-]+\.[a-zA-Z]{2,3}$')

  def __init__(self, name, pools, properties,
               last_good_urls, code_review_sites):
    TryBase.__init__(self, name, pools.ListBuilderNames(), properties or {})
    self.pools = pools
    pools.SetParent(self)
    self.last_good_urls = last_good_urls
    self.code_review_sites = code_review_sites
    self._last_lkgr = None

  def gotChange(self, change, important):  # pylint: disable=R0201
    log.msg('ERROR: gotChange was unexpectedly called.')

  def parse_options(self, options):
    """Converts try job settings into a dict."""
    try:
      # Flush None and '' keys.
      options = dict(
          (k, v) for k, v in options.iteritems() if v not in (None, ''))

      options.setdefault('name', 'Unnamed')
      options.setdefault('user', 'John Doe')
      options['email'] = [e for e in options.get('email', '').split(',') if e]
      for email in options['email']:
        if not TryJobBase._EMAIL_VALIDATOR.match(email):
          raise BadJobfile("'%s' is an invalid email address!" % email)

      options.setdefault('patch', None)
      options.setdefault('root', None)
      # -pN argument to patch.
      options['patchlevel'] = int(options.get('patchlevel', 0))
      options.setdefault('branch', None)
      options.setdefault('revision', None)
      options.setdefault(
          'reason', '%s: %s' % (options['user'], options['name']))
      options['testfilter'] = [
          i for i in options.get('testfilter', '').split(',') if i
      ]
      options.setdefault('project', self.pools.default_pool_name)
      options.setdefault('repository', None)
      # Code review infos. Enforce numbers.
      def try_int(key):
        if options.setdefault(key, None) is None:
          return
        options[key] = int(options[key])
      try_int('patchset')
      try_int('issue')

      builder_names = []
      if 'bot' in options:
        builder_names = options.get('bot', '').split(',')
      options['bot'] = self.pools.Select(builder_names, options['project'])
      log.msg(
          'Choose %s for job %s' %
          (','.join(options['bot']), options['reason']))
      return options
    except (TypeError, ValueError), e:
      raise BadJobfile('Failed to parse the metadata: %r' % options, e)

  def get_props(self, options):
    """Current job extra properties that are not related to the source stamp.
    Initialize with the Scheduler's base properties.
    """
    keys = ('clobber', 'issue', 'patchset', 'rietveld', 'testfilter')
    # All these settings have no meaning when False or not set, so don't set
    # them in that case.
    properties = dict((i, options[i]) for i in keys if options.get(i))
    props = Properties()
    props.updateFromProperties(self.properties)
    props.update(properties, 'Try job')
    return props

  @staticmethod
  def parse_decoration(properties, decorations):
    """Returns properties extended by the meaning of decoration.
    """

    props = Properties()
    props.updateFromProperties(properties)
    for decoration in decorations.split(':'):
      if decoration == 'compile':
        testfilter = props.getProperty('testfilter') or 'None'
        props.setProperty('testfilter', testfilter, 'Decoration')

      #TODO(petermayo) Define a DSL of useful modifications to individual
      # bots of a test run.
    return props

  def SubmitJob(self, parsed_job, changeids):
    if not parsed_job['bot']:
      raise BadJobfile(
          'incoming Try job did not specify any allowed builder names')

    d = self.master.db.sourcestamps.addSourceStamp(
        branch=parsed_job['branch'],
        revision=parsed_job['revision'],
        patch_body=parsed_job['patch'],
        patch_level=parsed_job['patchlevel'],
        patch_subdir=parsed_job['root'],
        project=parsed_job['project'],
        repository=parsed_job['repository'] or '',
        changeids=changeids)

    def create_buildset(ssid):
      log.msg('Creating try job(s) %s' % ssid)
      result = None
      for build in parsed_job['bot']:
        bot = build.split(':', 1)[0]
        result = self.addBuildsetForSourceStamp(ssid=ssid,
            reason=parsed_job['name'],
            external_idstring=parsed_job['name'],
            builderNames=[bot],
            properties=self.parse_decoration(
                self.get_props(parsed_job), ''.join(build.split(':', 1)[1:])))
      return result

    d.addCallback(create_buildset)
    d.addErrback(log.err, "Failed to queue a try job!")
    return d

  def get_lkgr(self, options):
    """Grabs last known good revision number if necessary."""
    options['rietveld'] = (self.code_review_sites or {}).get(options['project'])
    last_good_url = (self.last_good_urls or {}).get(options['project'])
    if options['revision'] or not last_good_url:
      return defer.succeed(0)

    def Success(result):
      try:
        new_value = int(result.strip())
      except (TypeError, ValueError):
        new_value = None
      if new_value and (not self._last_lkgr or new_value > self._last_lkgr):
        self._last_lkgr = new_value
      options['revision'] = self._last_lkgr or 'HEAD'

    def Failure(result):
      options['revision'] = self._last_lkgr or 'HEAD'

    connection = client.getPage(last_good_url, agent='buildbot')
    connection.addCallbacks(Success, Failure)
    return connection
<|endoftext|>


<commit_before># coding: utf-8

""" TriAnd RR Lyrae """

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
from datetime import datetime, timedelta

# Third-party
import astropy.coordinates as coord
import astropy.units as u
from astropy.io import ascii
from astropy.time import Time
from astropy.table import Table, Column, join
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Project
from streams.coordinates import sex_to_dec
from streams.observation.time import gmst_to_utc, lmst_to_gmst
from streams.observation.rrlyrae import time_to_phase, phase_to_time
from streams.observation.triand import all_stars, triand_stars, standards
from streams.util import project_root

matplotlib.rc('xtick', labelsize=12, direction='in')
matplotlib.rc('ytick', labelsize=12, direction='in')

# CHANGE THIS
observing_path = "/Users/adrian/Documents/GraduateSchool/Observing"
output_path = os.path.join(observing_path, "2013-10_MDM")
kitt_peak_longitude = (111. + 35/60. + 40.9/3600)*u.deg

def tcs_list(decimal=False):
    """ Given the table of stars, ouput a list to be fed in to the TCS """

    names = []
    ras = []
    decs = []
    epoch = []
    for ii,star in enumerate(triand_stars):
        names.append("TriAndRRL{0}".format(ii+1))

        ra = coord.RA(star['ra']*u.deg)
        dec = coord.Dec(star['dec']*u.deg)

        if decimal:
            ras.append(ra.degree)
            decs.append(dec.degree)
        else:
            ras.append(ra.to_string(unit=u.hour, sep=' ', pad=True, precision=1))
            decs.append(dec.to_string(unit=u.deg, sep=' ', alwayssign=True, precision=1))
        epoch.append(2000.0)

    for ii,star in enumerate(standards):
        names.append(star['name'].replace(' ', '_'))
        ra = coord.RA(star['ra']*u.deg)
        dec = coord.Dec(star['dec']*u.deg)

        if decimal:
            ras.append(ra.degree)
            decs.append(dec.degree)
        else:
            ras.append(ra.to_string(unit=u.hour, sep=' ', pad=True, precision=1))
            decs.append(dec.to_string(unit=u.deg, sep=' ', alwayssign=True, precision=1))
        epoch.append(2000.0)

    t = Table()
    t.add_column(Column(names, name='name'))
    t.add_column(Column(ras, name='ra'))
    t.add_column(Column(decs, name='dec'))
    if not decimal:
        t.add_column(Column(epoch, name='epoch'))

    return t

def source_meridian_window(ra, utc_day, buffer_time=2.*u.hour):
    """ Compute the minimum and maximum time (UTC) for the window
        of observability for the given source.

        Parameters
        ----------
        ra : astropy.units.Quantity
            The right ascension of the object.
        utc_day : astropy.time.Time
            The day to compute the window on.
    """

    hour_angles = [-buffer_time.hour,buffer_time.hour]*u.hourangle

    jds = []
    for ha in hour_angles:
        lst = day.datetime + timedelta(hours=(ha + ra).hourangle)
        gmst = lmst_to_gmst(lst.time(), kitt_peak_longitude)
        utc = gmst_to_utc(gmst, utc_day)
        jds.append(utc.jd)

    return Time(jds, scale='utc', format='jd')

def open_finder_charts():
    for ii,star in enumerate(triand_stars):
        url = "http://ptf.caltech.edu/cgi-bin/ptf/variable/fc.cgi?name=TriAndRRL{0}&ra={ra}&dec={dec}&bigwidth=300.000000&bigspan=19.000000&zoomwidth=150.000000&zoomspan=8.000000"
        print(url.format(ii+1, ra=star['ra'], dec=star['dec']))
        os.system("open '{0}'".format(url.format(ii+1, ra=star['ra'], dec=star['dec'])))

# output list of all targets to be added to the TCS
tcs = tcs_list(False)
fn = os.path.join(output_path, "tcs_list.txt")
ascii.write(tcs, fn, Writer=ascii.Basic)
with open(fn, 'r') as f:
    d = "".join(f.readlines()[1:]).replace('"', '')

with open(fn, 'w') as f:
    f.write(d)

tcs = tcs_list(True)
fn = "iobserve_list.txt"
ascii.write(tcs, os.path.join(output_path, fn), Writer=ascii.Basic)

# read the stars that are done
done_stars = ascii.read(os.path.join(observing_path, "done_rrlyrae.txt"))

# Create a queue for the given day
queue = []

_date = map(int, sys.argv[1].split("-"))
day = Time(datetime(*_date), scale='utc')

phase_plot_path = os.path.join(output_path, str(day.datetime.date()))
if not os.path.exists(phase_plot_path):
    os.mkdir(phase_plot_path)

for star in all_stars:

    if star["name"] in done_stars["name"]:
        print("Star {0} already done!".format(star["name"]))
        continue

    # For each star, figure out its observability window, e.g., the times
    #   that it is at -2 hr from meridian and +2 hr from meridian
    t1,t2 = source_meridian_window(star['ra']*u.deg, day)
    if t1.jd > day.jd+1.:
        jd1 = t1.jd-1
        jd2 = t2.jd-1
    else:
        jd1 = t1.jd
        jd2 = t2.jd

    if jd1 > jd2:
        jd2 += 1.

    obs_window = Time([jd1, jd2], format='jd', scale='utc')
    period = star['period']*u.day
    t0 = Time(star['rhjd0'], scale='utc', format='mjd')

    # Now we want to see if at what time the phase of the pulsation is around
    #   0.4 and 0.7
    #optimal_phases = np.array([0.4, 0.7])
    #optimal_phase_times = phase_to_time(optimal_phases, day=day, t0=t0, period=period)
    #print(optimal_phase_times.datetime, obs_window.datetime)
    #continue

    # Here instead we'll look at the possible times we can observe
    step = 1.*u.minute
    jds = Time(np.arange(jd1, jd2, step.day), format='jd', scale='utc')

    ut_hours = np.array([sex_to_dec((jd.datetime.hour,jd.datetime.minute,jd.datetime.second)) for jd in jds])
    phases = time_to_phase(jds, period=period, t0=t0)

    fig,ax = plt.subplots(1,1,figsize=(4,4))
    ax.plot(ut_hours, phases, marker='o', linestyle='none')
    ax.set_xlim(1.5, 13.)
    ax.set_ylim(0., 1.)
    ax.set_xlabel("UT time")
    ax.text(5., 0.9, star['name'])
    fig.savefig(os.path.join(phase_plot_path, "{0}.png".format(star['name'])))

    idx1 = (phases > 0.1) & (phases < 0.5) & \
           (ut_hours < 13.) & (ut_hours > 2.)

    idx2 = (phases >= 0.5) & (phases < 0.8) & \
           (ut_hours < 13.) & (ut_hours > 2.)

    if not np.any(idx1) and not np.any(idx2):
        print("Skipping {0}, no suitable observing time."\
                .format(star['name']))
        continue

    if np.any(idx1):
        first_obs_time = jds[idx1][0]
        phase_at_first = phases[idx1][0]
        queue.append({'name' : str(star['name']),
                      'time' : first_obs_time.datetime.time().strftime("'%H:%M:%S'"),
                      'phase' : phase_at_first,
                      'info' : "pre-mean",
                      'vmag' : star['magAvg']})

    if np.any(idx2):
        first_obs_time = jds[idx2][0]
        phase_at_first = phases[idx2][0]
        queue.append({'name' : str(star['name']),
                      'time' : first_obs_time.datetime.time().strftime("'%H:%M:%S'"),
                      'phase' : phase_at_first,
                      'info' : "post-mean",
                      'vmag' : star['magAvg']})

queue = Table(queue)
queue = queue['name','time','vmag','phase','info']
queue.sort('time')

fn = "queue_{0}.csv".format(day.datetime.date())
ascii.write(queue, os.path.join(output_path, fn), Writer=ascii.Basic, delimiter=',')<commit_msg>updated for allyson<commit_after># coding: utf-8

""" TriAnd RR Lyrae """

from __future__ import division, print_function

__author__ = "adrn <adrn@astro.columbia.edu>"

# Standard library
import os, sys
from datetime import datetime, timedelta

# Third-party
import astropy.coordinates as coord
import astropy.units as u
from astropy.io import ascii
from astropy.time import Time
from astropy.table import Table, Column, join
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Project
from streamteam.observation import sex_to_dec, gmst_to_utc, lmst_to_gmst
from streamteam.observation.rrlyrae import time_to_phase, phase_to_time

#########################################################################
# Set these

# - the target list must contain, at least, columns 'name' for the star name,
#       'ra' and 'dec' for sky coordinates, 'period' for the period in days,
#       'hjd0' for the HJD (MJD) of the peak of the pulsation, and
#       'Vmag' for the V-band magnitude
target_list_filename = "/Users/adrian/projects/streams/data/observing/triand.txt"

# path to write files and plots to
output_path = ""

#
#########################################################################

kitt_peak_longitude = (111. + 35/60. + 40.9/3600)*u.deg
def tcs_list(stars):
    """ Given a table of stars, ouput a list to be fed in to the TCS """

    names = []
    ras = []
    decs = []
    epoch = []
    for ii,star in enumerate(stars):
        names.append(star['name'])
        ra = coord.Longitude(star['ra']*u.deg)
        dec = coord.Latitude(star['dec']*u.deg)

        ras.append(ra.to_string(unit=u.hour, sep=' ', pad=True, precision=1))
        decs.append(dec.to_string(unit=u.deg, sep=' ', alwayssign=True, precision=1))
        epoch.append(2000.0)

    t = Table()
    t.add_column(Column(names, name='name'))
    t.add_column(Column(ras, name='ra'))
    t.add_column(Column(decs, name='dec'))
    t.add_column(Column(epoch, name='epoch'))

    return t

def source_meridian_window(ra, utc_day, buffer_time=2.*u.hour):
    """ Compute the minimum and maximum time (UTC) for the window
        of observability for the given source.

        Parameters
        ----------
        ra : astropy.units.Quantity
            The right ascension of the object.
        utc_day : astropy.time.Time
            The day to compute the window on.
    """

    hour_angles = [-buffer_time.to(u.hour).value,buffer_time.to(u.hour).value]*u.hourangle

    jds = []
    for ha in hour_angles:
        lst = day.datetime + timedelta(hours=(ha + ra).to(u.hourangle).value)
        gmst = lmst_to_gmst(lst.time(), kitt_peak_longitude)
        utc = gmst_to_utc(gmst, utc_day)
        jds.append(utc.jd)

    return Time(jds, scale='utc', format='jd')

# def open_finder_charts(stars):
#     for ii,star in enumerate(stars):
#         url = "http://ptf.caltech.edu/cgi-bin/ptf/variable/fc.cgi?name={1}{0}&ra={ra}&dec={dec}&bigwidth=300.000000&bigspan=19.000000&zoomwidth=150.000000&zoomspan=8.000000"
#         print(url.format(ii+1, star_name_prefix, ra=star['ra'], dec=star['dec']))
#         os.system("open '{0}'".format(url.format(ii+1, ra=star['ra'], dec=star['dec'])))

# read the target list
stars = ascii.read(target_list_filename)

# output list of all targets to be added to the TCS
tcs = tcs_list(stars)
fn = os.path.join(output_path, "tcs_list.txt")
ascii.write(tcs, fn, Writer=ascii.Basic)
with open(fn, 'r') as f:
    d = "".join(f.readlines()[1:]).replace('"', '')

with open(fn, 'w') as f:
    f.write(d)

# Create a queue for the given day
queue = []

_date = map(int, sys.argv[1].split("-"))
day = Time(datetime(*_date), scale='utc')

phase_plot_path = os.path.join(output_path, str(day.datetime.date()))
if not os.path.exists(phase_plot_path):
    os.mkdir(phase_plot_path)

for star in stars:

    # For each star, figure out its observability window, e.g., the times
    #   that it is at -2 hr from meridian and +2 hr from meridian
    t1,t2 = source_meridian_window(star['ra']*u.deg, day)
    if t1.jd > day.jd+1.:
        jd1 = t1.jd-1
        jd2 = t2.jd-1
    else:
        jd1 = t1.jd
        jd2 = t2.jd

    if jd1 > jd2:
        jd2 += 1.

    obs_window = Time([jd1, jd2], format='jd', scale='utc')
    period = star['period']*u.day
    t0 = Time(star['hjd0'], scale='utc', format='mjd')

    # Now we want to see if at what time the phase of the pulsation is around
    #   0.4 and 0.7
    #optimal_phases = np.array([0.4, 0.7])
    #optimal_phase_times = phase_to_time(optimal_phases, day=day, t0=t0, period=period)
    #print(optimal_phase_times.datetime, obs_window.datetime)
    #continue

    # Here instead we'll look at the possible times we can observe
    step = 1.*u.minute
    jds = Time(np.arange(jd1, jd2, step.to(u.day).value), format='jd', scale='utc')

    ut_hours = np.array([sex_to_dec((jd.datetime.hour,jd.datetime.minute,jd.datetime.second)) for jd in jds])
    phases = time_to_phase(jds, period=period, t0=t0)

    fig,ax = plt.subplots(1,1,figsize=(4,4))
    ax.plot(ut_hours, phases, marker='o', linestyle='none')
    ax.set_xlim(1.5, 13.)
    ax.set_ylim(0., 1.)
    ax.set_xlabel("UT time")
    ax.text(5., 0.9, star['name'])
    fig.savefig(os.path.join(phase_plot_path, "{0}.png".format(star['name'])))

    idx1 = (phases > 0.1) & (phases < 0.5) & \
           (ut_hours < 13.) & (ut_hours > 2.)

    idx2 = (phases >= 0.5) & (phases < 0.8) & \
           (ut_hours < 13.) & (ut_hours > 2.)

    if not np.any(idx1) and not np.any(idx2):
        print("Skipping {0}, no suitable observing time."\
                .format(star['name']))
        continue

    if np.any(idx1):
        first_obs_time = jds[idx1][0]
        phase_at_first = phases[idx1][0]
        queue.append({'name' : str(star['name']),
                      'time' : first_obs_time.datetime.time().strftime("'%H:%M:%S'"),
                      'phase' : phase_at_first,
                      'info' : "pre-mean",
                      'vmag' : star['Vmag']})

    if np.any(idx2):
        first_obs_time = jds[idx2][0]
        phase_at_first = phases[idx2][0]
        queue.append({'name' : str(star['name']),
                      'time' : first_obs_time.datetime.time().strftime("'%H:%M:%S'"),
                      'phase' : phase_at_first,
                      'info' : "post-mean",
                      'vmag' : star['Vmag']})

queue = Table(queue)
queue = queue['name','time','vmag','phase','info']
queue.sort('time')

fn = "queue_{0}.csv".format(day.datetime.date())
ascii.write(queue, os.path.join(output_path, fn), Writer=ascii.Basic, delimiter=',')<|endoftext|>


<commit_before>import json
r = json.load(open("results.json"))

def printCSVRecord(r, fields, out):
    ''' Print out one result record in CSV delimited form. Just the one entry'''
    s = ','
    out.write(s.join([str(r[x]) for x in fields])+'\n')

def ensureFields(r, fields):
    ''' Make sure all the fields exist in M. Insert 0 if not '''
    r.update((missing, 0) for missing in set(fields).difference(r.keys()))

fields = ['count', 'min', 'max', 'mean', 'popStdDev']
out = open("test.out", "w")
s=','
out.write(s.join(fields)+ '\n')
for rec in r :
    ensureFields(rec['main']['insert2'],  fields)
    printCSVRecord(rec['main']['insert2'], fields, out)

out.close()
<commit_msg>More flexibility<commit_after>import json
r = json.load(open("results.json"))

def printCSVRecord(r, fields, out):
    ''' Print out one result record in CSV delimited form. Just the one entry'''
    s = ','
    out.write(s.join([str(r[x]) for x in fields])+'\n')

def ensureFields(r, fields):
    ''' Make sure all the fields exist in M. Insert 0 if not '''
    r.update((missing, 0) for missing in set(fields).difference(r.keys()))

def lookup(dic, keys):
    if len(keys) > 1:
        return lookup(dic.get(keys[0], {}), keys[1:])
    return dic.get(keys[0])

def CSVForField(r, key, fields, out) :
    ''' Create CSV File for the given key. Key is the list of keys to get to the right place '''
    s=','
    out.write(s.join(fields)+ '\n')
    for rec in r:
        cur = lookup(rec, key)
        ensureFields(cur, fields)
        printCSVRecord(cur, fields, out)

fields = ['count', 'min', 'max', 'mean', 'popStdDev']

out = open("test.out", "w")
CSVForField(r, ["main", "insert2"], fields, out)

out.close()
<|endoftext|>


<commit_before>from django.conf.urls import url
from locations import views

UUID = r"\w{8}-\w{4}-\w{4}-\w{4}-\w{12}"

urlpatterns = [
    # Sorted by alphabetized categories

    # Locations
    url(r'^locations/$', views.location_list,
        name='location_list'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/$', views.location_detail,
        name='location_detail'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/delete/$', views.location_delete,
        name='location_delete'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/switch_enabled/$', views.location_switch_enabled,
        name='location_switch_enabled'),

    # Packages
    url(r'^packages/$', views.package_list,
        name='package_list'),
    url(r'^packages/aip_delete_request/$', views.aip_delete_request,
        name='aip_delete_request'),
    url(r'^packages/(?P<uuid>'+UUID+')/update_status/$', views.package_update_status,
        name='package_update_status'),
    url(r'^packages/aip_recover_request$', views.aip_recover_request,
        name='aip_recover_request'),
    url(r'^packages/(?P<package_uuid>' + UUID + ')/reingest/$', 'aip_reingest',
        name='aip_reingest'),

    # Pipelines
    url(r'^pipelines/$', views.pipeline_list,
        name='pipeline_list'),
    url(r'^pipelines/create/$', views.pipeline_edit,
        name='pipeline_create'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/edit/$', views.pipeline_edit,
        name='pipeline_edit'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/detail/$', views.pipeline_detail,
        name='pipeline_detail'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/delete/$', views.pipeline_delete,
        name='pipeline_delete'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/switch_enabled/$', views.pipeline_switch_enabled,
        name='pipeline_switch_enabled'),

    # Spaces
    url(r'^spaces/$', views.space_list,
        name='space_list'),
    url(r'^spaces/(?P<uuid>'+UUID+')/$', views.space_detail,
        name='space_detail'),
    url(r'^spaces/(?P<uuid>'+UUID+')/edit/$', views.space_edit,
        name='space_edit'),
    url(r'^spaces/(?P<uuid>'+UUID+')/delete/$', views.space_delete,
        name='space_delete'),
    url(r'^spaces/(?P<space_uuid>'+UUID+')/location_create/$', views.location_edit,
        name='location_create'),
    url(r'^spaces/(?P<space_uuid>'+UUID+')/location/(?P<location_uuid>'+UUID+')/edit/$', views.location_edit,
        name='location_edit'),
    url(r'^spaces/create/$', views.space_create,
        name='space_create'),
    # Spaces AJAX
    url(r'^spaces/get_form_type/$', views.ajax_space_create_protocol_form,
        name='ajax_space_create_protocol_form'),

    # Callbacks
    url(r'^callbacks/$', views.callback_list,
        name='callback_list'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/$', views.callback_detail,
        name='callback_detail'),
    url(r'^callbacks/create/$', views.callback_edit,
        name='callback_create'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/edit/$', views.callback_edit,
        name='callback_edit'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/delete/$', views.callback_delete,
        name='callback_delete'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/switch_enabled/$', views.callback_switch_enabled,
        name='callback_switch_enabled'),
]
<commit_msg>Fix "Re-ingest" button<commit_after>from django.conf.urls import url
from locations import views

UUID = r"\w{8}-\w{4}-\w{4}-\w{4}-\w{12}"

urlpatterns = [
    # Sorted by alphabetized categories

    # Locations
    url(r'^locations/$', views.location_list,
        name='location_list'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/$', views.location_detail,
        name='location_detail'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/delete/$', views.location_delete,
        name='location_delete'),
    url(r'^locations/(?P<location_uuid>'+UUID+')/switch_enabled/$', views.location_switch_enabled,
        name='location_switch_enabled'),

    # Packages
    url(r'^packages/$', views.package_list,
        name='package_list'),
    url(r'^packages/aip_delete_request/$', views.aip_delete_request,
        name='aip_delete_request'),
    url(r'^packages/(?P<uuid>'+UUID+')/update_status/$', views.package_update_status,
        name='package_update_status'),
    url(r'^packages/aip_recover_request$', views.aip_recover_request,
        name='aip_recover_request'),
    url(r'^packages/(?P<package_uuid>' + UUID + ')/reingest/$', views.aip_reingest,
        name='aip_reingest'),

    # Pipelines
    url(r'^pipelines/$', views.pipeline_list,
        name='pipeline_list'),
    url(r'^pipelines/create/$', views.pipeline_edit,
        name='pipeline_create'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/edit/$', views.pipeline_edit,
        name='pipeline_edit'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/detail/$', views.pipeline_detail,
        name='pipeline_detail'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/delete/$', views.pipeline_delete,
        name='pipeline_delete'),
    url(r'^pipeline/(?P<uuid>'+UUID+')/switch_enabled/$', views.pipeline_switch_enabled,
        name='pipeline_switch_enabled'),

    # Spaces
    url(r'^spaces/$', views.space_list,
        name='space_list'),
    url(r'^spaces/(?P<uuid>'+UUID+')/$', views.space_detail,
        name='space_detail'),
    url(r'^spaces/(?P<uuid>'+UUID+')/edit/$', views.space_edit,
        name='space_edit'),
    url(r'^spaces/(?P<uuid>'+UUID+')/delete/$', views.space_delete,
        name='space_delete'),
    url(r'^spaces/(?P<space_uuid>'+UUID+')/location_create/$', views.location_edit,
        name='location_create'),
    url(r'^spaces/(?P<space_uuid>'+UUID+')/location/(?P<location_uuid>'+UUID+')/edit/$', views.location_edit,
        name='location_edit'),
    url(r'^spaces/create/$', views.space_create,
        name='space_create'),
    # Spaces AJAX
    url(r'^spaces/get_form_type/$', views.ajax_space_create_protocol_form,
        name='ajax_space_create_protocol_form'),

    # Callbacks
    url(r'^callbacks/$', views.callback_list,
        name='callback_list'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/$', views.callback_detail,
        name='callback_detail'),
    url(r'^callbacks/create/$', views.callback_edit,
        name='callback_create'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/edit/$', views.callback_edit,
        name='callback_edit'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/delete/$', views.callback_delete,
        name='callback_delete'),
    url(r'^callbacks/(?P<uuid>'+UUID+')/switch_enabled/$', views.callback_switch_enabled,
        name='callback_switch_enabled'),
]
<|endoftext|>


<commit_before># util.py
import numpy as np
import sys

def kernel2distanceMatrix(simMat,method):
    # https://rdrr.io/cran/mmpp/man/k2d.html
    m,n = simMat.shape
    disMat = np.ones((m,n),dtype=float)

    if method=='naive':
        for i in range(m):
            for j in range(n):
                # d_n(x,y) = 1 - k(x,y)/sqrt{ k(x,x)k(y,y)},
                disMat[i][j] = (1.0 - simMat[i][j])/np.sqrt(simMat[i][i]*simMat[j][j])
    else:
        assert False, 'FATAL: unkown method'

    return disMat

def getType(idStr):
    prefix1 = idStr[0:1]
    prefix1 = prefix1.upper()

    prefix3 = idStr[0:3]
    prefix3 = prefix3.upper()

    name = None
    if prefix3=='COM' or prefix1=='D':
        name = 'compound'
    elif prefix3=='PRO' or prefix3=='HSA':
        name = 'protein'
    else:
        assert False, 'Unknown idStr'

    return name

def randData(pairList,limit):
############# Generate random ID #############
    # sys.stderr.write ("Generating additional random data...\n")
    temp1 = None
    tempC = None
    tempP = None
    idP = None
    idC = None

    nPair = len(pairList)
    while nPair < 1000:
        temp1 = np.random.randint(1,3334*17277)
        if temp1%3334 == 0:
            idP = 3334
            idC = temp1/3334
        else:
            idP = temp1%3334
            idC = (temp1/3334)+1
        tempC = "COM"+str(idC).zfill(8)

        tempP = "PRO"+str(idP).zfill(8)
        pairList.append([tempC, tempP])
        nPair += 1
    return pairList
<commit_msg>add makeKernelMat<commit_after># util.py
import numpy as np
import sys

def kernel2distanceMatrix(method,simMat):
    # https://rdrr.io/cran/mmpp/man/k2d.html
    m,n = simMat.shape
    disMat = np.ones((m,n),dtype=float)

    if method=='naive':
        for i in range(m):
            for j in range(n):
                # d_n(x,y) = 1 - k(x,y)/sqrt{ k(x,x)k(y,y)},
                disMat[i][j] = (1.0 - simMat[i][j])/np.sqrt(simMat[i][i]*simMat[j][j])
    else:
        assert False, 'FATAL: unkown method'

    return disMat

def makeKernelMatrix(kernelDict,comList,proList):
    nCom = len(comList); nPro = len(proList)

    comSimMat = np.zeros((nCom,nCom),dtype=float)
    proSimMat = np.zeros((nPro,nPro),dtype=float)

    for row,i in enumerate(comList):
        for col,j in enumerate(comList):
            comSimMat[row][col] = kernelDict[(i,j)]

    for row,i in enumerate(proList):
        for col,j in enumerate(proList):
            proSimMat[row][col] = kernelDict[(i,j)]

    return (comSimMat,proSimMat)

def getType(idStr):
    prefix1 = idStr[0:1]
    prefix1 = prefix1.upper()

    prefix3 = idStr[0:3]
    prefix3 = prefix3.upper()

    name = None
    if prefix3=='COM' or prefix1=='D':
        name = 'compound'
    elif prefix3=='PRO' or prefix3=='HSA':
        name = 'protein'
    else:
        assert False, 'Unknown idStr'

    return name

def randData(pairList,limit):
############# Generate random ID #############
    # sys.stderr.write ("Generating additional random data...\n")
    temp1 = None
    tempC = None
    tempP = None
    idP = None
    idC = None

    nPair = len(pairList)
    while nPair < 1000:
        temp1 = np.random.randint(1,3334*17277)
        if temp1%3334 == 0:
            idP = 3334
            idC = temp1/3334
        else:
            idP = temp1%3334
            idC = (temp1/3334)+1
        tempC = "COM"+str(idC).zfill(8)

        tempP = "PRO"+str(idP).zfill(8)
        pairList.append([tempC, tempP])
        nPair += 1
    return pairList
<|endoftext|>


<commit_before># Copyright (C) 2010  Wil Mahan <wmahan+fatics@gmail.com>
#
# This file is part of FatICS.
#
# FatICS is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FatICS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with FatICS.  If not, see <http://www.gnu.org/licenses/>.
#

# Implementation of botless tournaments on FatICS ~ilknight
# Tournament commands here in this file

import tourney
import user

from command import *

@ics_command('listtourneys', '', admin.Level.user)
class Listtourneys(Command):
    def run(self, args, conn):
        if conn.user.is_guest:
            conn.write("Only registered players may use tourney commands.")
            return
        conn.write(' -----------------------------------------------------------------------\n')
        conn.write('| Current Tournaments                                                   |\n')
        conn.write('|-----------------------------------------------------------------------|\n')
        conn.write('| ID  | Tourney Name                | T.Ctrl. | Pair. | Manager         |\n')
        conn.write('|-----------------------------------------------------------------------|\n')
        for t in tourney.tourneys:
            conn.write('| %-4d| %-28s| %-8s| %-6s| %-16s|\n' %
                (t.number, t.name, t.time_control, t.pairing_method, t.manager))
        conn.write(' -----------------------------------------------------------------------\n')
        conn.write(ngettext('\n\nFound %d tournament.\n',
            '\n\nFound %d tournaments.\n', len(tourney.tourneys)) % len(tourney.tourneys))

@ics_command('createtourney', '', admin.Level.user)
class Createtourney(Command):
    def run(self, args, conn):
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        tourney.new_tournament(tourney.Tournament())
        tournament = tourney.tourneys[-1]
        number = tourney.tourneys.index(tournament)
        tournament.manager = conn.user.name
        conn.write("New tournament created with ID %d.\n" % number)

@ics_command('jointourney', 'd', admin.Level.user)
class Jointourney(Command):
    def run(self, args, conn):
        number = int(args[0])
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        tourney.tourneys[number].players.append(conn.user.name)
        tourney.tourneys[number].player_scores[conn.user.name] = 0
        time_control = tourney.tourneys[number].time_control.split(" ")
        time_minute = int(time_control[0])
        time_second = int(time_control[1])
        # no variants yet
        if time_minute > 10:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating('standard')
        elif time_minute > 2:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating('blitz')
        elif time_minute <= 2:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating('lightning')
        tourney.tourneys[number].players_in.append(conn.user.name)
        conn.write("You have successfully joined tournament number %d!\n" % number)
        tourney.tourneys[number].announce("%s(%d) has joined tournament #%d" %
            (conn.user.name, tourney.tourneys[number].player_ratings[conn.user.name], number))
        return

@ics_command('setpairingmethod', 'dw', admin.Level.user)
class Setpairingmethod(Command):
    def run(self, args, conn):
        number = args[0]
        method = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        if not method in ('ss', 'rr', 'ko'):
            conn.write('"%s" is not a valid pairing method\n' % method)
            return
        tourney.tourneys[number].pairing_method = method

@ics_command('settimecontrol', 'dS', admin.Level.user)
class Settimecontrol(Command):
    def run(self, args, conn):
        number = args[0]
        time_control = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        if not len(time_control.split(" ")) == 2:
            conn.write('That is not a valid time control.')
        tourney.tourneys[number].time_control = time_control
        conn.write('Time control of tourney number %d changed to "%s".\n' % (number, time_control))

@ics_command('settourneyname', 'dS', admin.Level.user)
class Settourneyname(Command):
    def run(self, args, conn):
        number = args[0]
        name = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        tourney.tourneys[number].name = name
        conn.write('Name of tourney number %d changed to "%s".\n' % (number, name))

<commit_msg>Fixed bugs with announce. Added listplayers command.<commit_after># Copyright (C) 2010  Wil Mahan <wmahan+fatics@gmail.com>
#
# This file is part of FatICS.
#
# FatICS is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FatICS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with FatICS.  If not, see <http://www.gnu.org/licenses/>.
#

# Implementation of botless tournaments on FatICS ~ilknight
# Tournament commands here in this file

import speed_variant
import tourney
import user

from command import *

@ics_command('listtourneys', '', admin.Level.user)
class Listtourneys(Command):
    def run(self, args, conn):
        if conn.user.is_guest:
            conn.write("Only registered players may use tourney commands.")
            return
        conn.write('+-----------------------------------------------------------------------+\n')
        conn.write('| Current Tournaments                                                   |\n')
        conn.write('+-----------------------------------------------------------------------+\n')
        conn.write('| ID  | Tourney Name                | T.Ctrl. | Pair. | Manager         |\n')
        conn.write('+-----------------------------------------------------------------------+\n')
        for t in tourney.tourneys:
            conn.write('| %-4d| %-28s| %-8s| %-6s| %-16s|\n' %
                (t.number, t.name, t.time_control, t.pairing_method, t.manager))
        conn.write('+-----------------------------------------------------------------------+\n')
        conn.write(ngettext('\nFound %d tournament.\n',
            '\nFound %d tournaments.\n', len(tourney.tourneys)) % len(tourney.tourneys))

@ics_command('createtourney', '', admin.Level.user)
class Createtourney(Command):
    def run(self, args, conn):
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        tourney.new_tournament(tourney.Tournament())
        tournament = tourney.tourneys[-1]
        number = tourney.tourneys.index(tournament)
        tournament.manager = conn.user.name
        conn.write("New tournament created with ID %d.\n" % number)

@ics_command('jointourney', 'd', admin.Level.user)
class Jointourney(Command):
    def run(self, args, conn):
        number = int(args[0])
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        tourney.tourneys[number].players.append(conn.user.name)
        tourney.tourneys[number].player_scores[conn.user.name] = 0
        time_control = tourney.tourneys[number].time_control.split(" ")
        time_minute = int(time_control[0])
        time_second = int(time_control[1])
        # no variants yet
        if time_minute > 10:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating(
                speed_variant.from_names('standard','chess'))
        elif time_minute > 2:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating(
                speed_variant.from_names('blitz','chess'))
        elif time_minute <= 2:
            tourney.tourneys[number].player_ratings[conn.user.name] = conn.user.get_rating(
                speed_variant.from_names('lightning','chess'))
        tourney.tourneys[number].players_in.append(conn.user.name)
        conn.write("You have successfully joined tournament number %d!\n" % number)
        tourney.tourneys[number].announce("%s(%d) has joined tournament #%d" %
            (conn.user.name, tourney.tourneys[number].player_ratings[conn.user.name], number))
        return

@ics_command('listplayers', 'd', admin.Level.user)
class Listplayers(Command):
    def run(self, args, conn):
        number = args[0]
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        conn.write('+----------------------------------------------------------+\n')
        conn.write('| Player Handle             | Rating | Score | Status      |\n')
        conn.write('+---------------------------+--------+-------+-------------+\n')
        for u in tourney.tourneys[number].players
            rating = tourney.tourneys[number].player_ratings[u]
            score = tourney.tourneys[number].player_scores[u]
            # get status of player
            if not user.find_by_name_exact(u).is_online:
                status = "Offline"
            elif u in tourney.tourneys[number].player_byes:
                status = "Ready (BYE)"
            elif user.find_by_name_exact(u).is_online.session.game:
                status = "Playing"
            else:
                status = "Ready"
            conn.write('| %-26s| %-7s| %-6s| %-12s|\n' % (u, rating, score, status))
        conn.write('+----------------------------------------------------------+\n')

@ics_command('setpairingmethod', 'dw', admin.Level.user)
class Setpairingmethod(Command):
    def run(self, args, conn):
        number = args[0]
        method = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        if not method in ('ss', 'rr', 'ko'):
            conn.write('"%s" is not a valid pairing method\n' % method)
            return
        tourney.tourneys[number].pairing_method = method

@ics_command('settimecontrol', 'dS', admin.Level.user)
class Settimecontrol(Command):
    def run(self, args, conn):
        number = args[0]
        time_control = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        if not len(time_control.split(" ")) == 2:
            conn.write('That is not a valid time control.')
        tourney.tourneys[number].time_control = time_control
        conn.write('Time control of tourney number %d changed to "%s".\n' % (number, time_control))

@ics_command('settourneyname', 'dS', admin.Level.user)
class Settourneyname(Command):
    def run(self, args, conn):
        number = args[0]
        name = args[1]
        if not conn.user.has_title('TM'):
            conn.write("You are not a tournament manager (TM).\n")
            return
        if number >= len(tourney.tourneys):
            conn.write('Tourney number %d not found.\n' % number)
            return
        tourney.tourneys[number].name = name
        conn.write('Name of tourney number %d changed to "%s".\n' % (number, name))

<|endoftext|>


<commit_before>import discord

from discord import app_commands
from discord.ext import commands
from utils.configuration import StaffRank
from typing import Union, TYPE_CHECKING

if TYPE_CHECKING:
    from kurisu import Kurisu

class InsufficientStaffRank(commands.CheckFailure):
    message: str

def is_staff(role: str):
    async def predicate(ctx: commands.Context):
        if check_staff(ctx.bot, role, ctx.author.id) or (ctx.guild and ctx.author == ctx.guild.owner):
            return True
        raise InsufficientStaffRank(f"You must be at least {role} to use this command.")
    return commands.check(predicate)

def is_staff_app(role: str):
    async def predicate(interaction: discord.Interaction) -> bool:
        if (interaction.guild and interaction.user == interaction.guild.owner) or check_staff(interaction.client, role, interaction.user.id):  # type: ignore
            return True
        raise InsufficientStaffRank(f"You must be at least {role} to use this command.")
    return app_commands.check(predicate)

def check_staff(bot: 'Kurisu', role: str, user_id: int) -> bool:
    position = bot.configuration.staff.get(user_id)
    if position is None:
        return False
    return position <= StaffRank[role]

async def check_bot_or_staff(ctx: Union[commands.Context, discord.Interaction], target: Union[discord.Member, discord.User], action: str):
    bot = ctx.bot if isinstance(ctx, commands.Context) else ctx.client
    if target.bot:
        who = "a bot"
    elif check_staff(bot, "Helper", target.id):
        who = "another staffer"
    else:
        return False
    if isinstance(ctx, commands.Context):
        await ctx.send(f"You can't {action} {who} with this command!")
    else:
        await ctx.response.send_message(f"You can't {action} {who} with this command!", ephemeral=True)
    return True

def check_if_user_can_sr():
    async def predicate(ctx):
        author = ctx.author
        if not check_staff(ctx.bot, 'Helper', author.id) and (ctx.bot.roles['Verified'] not in author.roles) and (
                ctx.bot.roles['Trusted'] not in author.roles) and (ctx.bot.roles['Retired Staff'] not in author.roles):
            return False
        return True

    return commands.check(predicate)

def check_if_user_can_ready():
    async def predicate(ctx):
        channel = ctx.channel
        if channel != ctx.bot.channels['newcomers']:
            return False
        return True

    return commands.check(predicate)
<commit_msg>checks.py: Fix check for helpers<commit_after>import discord

from discord import app_commands
from discord.ext import commands
from utils.configuration import StaffRank
from typing import Union, TYPE_CHECKING

if TYPE_CHECKING:
    from kurisu import Kurisu

class InsufficientStaffRank(commands.CheckFailure):
    message: str

def is_staff(role: str):
    async def predicate(ctx: commands.Context):
        if check_staff(ctx.bot, role, ctx.author.id) or (ctx.guild and ctx.author == ctx.guild.owner):
            return True
        raise InsufficientStaffRank(f"You must be at least {role} to use this command.")
    return commands.check(predicate)

def is_staff_app(role: str):
    async def predicate(interaction: discord.Interaction) -> bool:
        if (interaction.guild and interaction.user == interaction.guild.owner) or check_staff(interaction.client, role, interaction.user.id):  # type: ignore
            return True
        raise InsufficientStaffRank(f"You must be at least {role} to use this command.")
    return app_commands.check(predicate)

def check_staff(bot: 'Kurisu', role: str, user_id: int) -> bool:
    if bot.configuration.helpers.get(user_id):
        position = StaffRank.Helper
    else:
        position = bot.configuration.staff.get(user_id)

    if position is None:
        return False
    return position <= StaffRank[role]

async def check_bot_or_staff(ctx: Union[commands.Context, discord.Interaction], target: Union[discord.Member, discord.User], action: str):
    bot = ctx.bot if isinstance(ctx, commands.Context) else ctx.client
    if target.bot:
        who = "a bot"
    elif check_staff(bot, "Helper", target.id):
        who = "another staffer"
    else:
        return False
    if isinstance(ctx, commands.Context):
        await ctx.send(f"You can't {action} {who} with this command!")
    else:
        await ctx.response.send_message(f"You can't {action} {who} with this command!", ephemeral=True)
    return True

def check_if_user_can_sr():
    async def predicate(ctx):
        author = ctx.author
        if not check_staff(ctx.bot, 'Helper', author.id) and (ctx.bot.roles['Verified'] not in author.roles) and (
                ctx.bot.roles['Trusted'] not in author.roles) and (ctx.bot.roles['Retired Staff'] not in author.roles):
            return False
        return True

    return commands.check(predicate)

def check_if_user_can_ready():
    async def predicate(ctx):
        channel = ctx.channel
        if channel != ctx.bot.channels['newcomers']:
            return False
        return True

    return commands.check(predicate)
<|endoftext|>


<commit_before>
import sys
import os
import re

import argparse

from mtm.log.LogStreamFile import LogStreamFile
from mtm.log.LogStreamConsole import LogStreamConsole

from mtm.util.ZipHelper import ZipHelper

from mtm.util.ScriptRunner import ScriptRunner

from mtm.util.ProcessRunner import ProcessRunner
from mtm.util.SystemHelper import SystemHelper
from mtm.util.VarManager import VarManager
from mtm.config.Config import Config
from mtm.log.Logger import Logger
from mtm.util.VisualStudioHelper import VisualStudioHelper
from mtm.util.UnityHelper import UnityHelper

from mtm.util.Assert import *

import mtm.ioc.Container as Container
from mtm.ioc.Inject import Inject

ScriptDir = os.path.dirname(os.path.realpath(__file__))
RootDir = os.path.realpath(os.path.join(ScriptDir, '../../../..'))
BuildDir = os.path.realpath(os.path.join(RootDir, 'Build'))

class Runner:
    _scriptRunner = Inject('ScriptRunner')
    _log = Inject('Logger')
    _sys = Inject('SystemHelper')
    _varMgr = Inject('VarManager')
    _zipHelper = Inject('ZipHelper')
    _vsSolutionHelper = Inject('VisualStudioHelper')
    _unityHelper = Inject('UnityHelper')

    def run(self, args):
        self._args = args
        success = self._scriptRunner.runWrapper(self._runInternal)

        if not success:
            sys.exit(1)

    def _runInternal(self):
        self._varMgr.set('RootDir', RootDir)
        self._varMgr.set('BuildDir', BuildDir)
        self._varMgr.set('PythonDir', '[BuildDir]/python')
        self._varMgr.set('TempDir', '[BuildDir]/Temp')
        self._varMgr.set('AssetsDir', '[RootDir]/UnityProject/Assets')
        self._varMgr.set('ZenjectDir', '[AssetsDir]/Plugins/Zenject')
        self._varMgr.set('DistDir', '[BuildDir]/Dist')
        self._varMgr.set('BinDir', '[RootDir]/NonUnityBuild/Bin')

        versionStr = self._sys.readFileAsText('[ZenjectDir]/Version.txt').strip()

        self._log.info("Found version {0}", versionStr)

        self._populateDistDir(versionStr)

        if self._args.addTag:
            self._sys.executeAndReturnOutput("git tag -a v{0} -m 'Version {0}'".format(versionStr))
            self._log.info("Incremented version to {0}! New tag was created as well", versionStr)
        else:
            self._log.info("Incremented version to {0}!  Dist directory contains the releases.  NOTE: No tags were created however", versionStr)

    def _populateDistDir(self, versionStr):

        self._sys.deleteDirectoryIfExists('[DistDir]')
        self._sys.createDirectory('[DistDir]')

        self._sys.deleteDirectoryIfExists('[TempDir]')
        self._sys.createDirectory('[TempDir]')

        try:
            self._buildUsageDll()
            # Do this first because it is the thing that usually breaks
            self._createNonUnityZip('[DistDir]/Zenject-NonUnity@v{0}.zip'.format(versionStr))
            self._createCSharpPackage(True, '[DistDir]/Zenject-WithSampleGames@v{0}.unitypackage'.format(versionStr))
            self._createCSharpPackage(False, '[DistDir]/Zenject@v{0}.unitypackage'.format(versionStr))
        finally:
            self._sys.deleteDirectory('[TempDir]')

    def _buildUsageDll(self):
        self._log.heading('Building Zenject-usage.dll')
        self._vsSolutionHelper.buildVisualStudioProject('[RootDir]/AssemblyBuild/Zenject-usage/Zenject-usage.sln', 'Release')

    def _createNonUnityZip(self, zipPath):

        self._log.heading('Creating non unity zip')

        tempDir = '[TempDir]/Debug'
        self._sys.createDirectory(tempDir)
        self._sys.clearDirectoryContents(tempDir)

        binDir = '[BinDir]/Release'
        self._sys.deleteDirectoryIfExists(binDir)
        self._sys.createDirectory(binDir)
        self._log.info('Building non unity Zenject solution')
        self._vsSolutionHelper.buildVisualStudioProject('[RootDir]/NonUnityBuild/Zenject.sln', 'Release')

        self._log.info('Copying Zenject dlls')
        self._sys.copyFile('{0}/Zenject.dll'.format(binDir), '{0}/Zenject.dll'.format(tempDir))
        self._sys.copyFile('{0}/Zenject-Signals.dll'.format(binDir), '{0}/Zenject-Signals.dll'.format(tempDir))
        self._sys.copyFile('[ZenjectDir]/Source/Usage/Zenject-usage.dll', '{0}/Zenject-usage.dll'.format(tempDir))

        self._zipHelper.createZipFile(tempDir, zipPath)

    def _createCSharpPackage(self, includeSample, outputPath):

        self._log.heading('Creating {0}'.format(os.path.basename(outputPath)))

        self._varMgr.set('PackageTempDir', '[TempDir]/Packager')
        self._varMgr.set('ZenTempDir', '[PackageTempDir]/Assets/Plugins/Zenject')

        self._sys.createDirectory('[PackageTempDir]')
        self._sys.createDirectory('[PackageTempDir]/ProjectSettings')

        try:
            self._log.info('Copying Zenject to temporary directory')
            self._sys.copyDirectory('[ZenjectDir]', '[ZenTempDir]')

            self._log.info('Cleaning up Zenject directory')
            self._zipHelper.createZipFile('[ZenTempDir]/OptionalExtras/UnitTests', '[ZenTempDir]/OptionalExtras/UnitTests.zip')
            self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/UnitTests')
            self._sys.removeFile('[ZenTempDir]/OptionalExtras/UnitTests.meta')

            self._zipHelper.createZipFile('[ZenTempDir]/OptionalExtras/TestFramework', '[ZenTempDir]/OptionalExtras/TestFramework.zip')
            self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/TestFramework')
            self._sys.removeFile('[ZenTempDir]/OptionalExtras/TestFramework.meta')

            self._zipHelper.createZipFile('[ZenTempDir]/OptionalExtras/IntegrationTests', '[ZenTempDir]/OptionalExtras/IntegrationTests.zip')
            self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/IntegrationTests')
            self._sys.removeFile('[ZenTempDir]/OptionalExtras/IntegrationTests.meta')

            self._sys.removeFile('[ZenTempDir]/Source/Zenject.csproj')

            if not includeSample:
                self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame1 (Beginner)')
                self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame2 (Advanced)')

            self._createUnityPackage('[PackageTempDir]', outputPath)
        finally:
            self._sys.deleteDirectory('[PackageTempDir]')

    def _createUnityPackage(self, projectPath, outputPath):
        self._sys.copyFile('[BuildDir]/UnityPackager/UnityPackageUtil.cs', '{0}/Assets/Editor/UnityPackageUtil.cs'.format(projectPath))

        self._log.info('Running unity to create unity package')

        self._unityHelper.runEditorFunction('[PackageTempDir]', 'Zenject.UnityPackageUtil.CreateUnityPackage')
        self._sys.move('{0}/Zenject.unitypackage'.format(projectPath), outputPath)

def installBindings():

    config = {
        'PathVars': {
            'UnityExePath': 'D:/Utils/Unity/Installs/2018.2.0f2/Editor/Unity.exe',
            'LogPath': os.path.join(BuildDir, 'Log.txt'),
            'MsBuildExePath': 'C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe'
        },
        'Compilation': {
            'UseDevenv': False
        },
    }
    Container.bind('Config').toSingle(Config, [config])

    Container.bind('LogStream').toSingle(LogStreamFile)
    Container.bind('LogStream').toSingle(LogStreamConsole, True, False)

    Container.bind('ScriptRunner').toSingle(ScriptRunner)
    Container.bind('VarManager').toSingle(VarManager)
    Container.bind('SystemHelper').toSingle(SystemHelper)
    Container.bind('Logger').toSingle(Logger)
    Container.bind('ProcessRunner').toSingle(ProcessRunner)
    Container.bind('ZipHelper').toSingle(ZipHelper)
    Container.bind('VisualStudioHelper').toSingle(VisualStudioHelper)
    Container.bind('UnityHelper').toSingle(UnityHelper)

if __name__ == '__main__':

    if (sys.version_info < (3, 0)):
        print('Wrong version of python!  Install python 3 and try again')
        sys.exit(2)

    parser = argparse.ArgumentParser(description='Zenject Releaser')
    parser.add_argument('-t', '--addTag', action='store_true', help='')
    args = parser.parse_args(sys.argv[1:])

    installBindings()

    Runner().run(args)

<commit_msg>Changed to not zip up the test framework<commit_after>
import sys
import os
import re

import argparse

from mtm.log.LogStreamFile import LogStreamFile
from mtm.log.LogStreamConsole import LogStreamConsole

from mtm.util.ZipHelper import ZipHelper

from mtm.util.ScriptRunner import ScriptRunner

from mtm.util.ProcessRunner import ProcessRunner
from mtm.util.SystemHelper import SystemHelper
from mtm.util.VarManager import VarManager
from mtm.config.Config import Config
from mtm.log.Logger import Logger
from mtm.util.VisualStudioHelper import VisualStudioHelper
from mtm.util.UnityHelper import UnityHelper

from mtm.util.Assert import *

import mtm.ioc.Container as Container
from mtm.ioc.Inject import Inject

ScriptDir = os.path.dirname(os.path.realpath(__file__))
RootDir = os.path.realpath(os.path.join(ScriptDir, '../../../..'))
BuildDir = os.path.realpath(os.path.join(RootDir, 'Build'))

class Runner:
    _scriptRunner = Inject('ScriptRunner')
    _log = Inject('Logger')
    _sys = Inject('SystemHelper')
    _varMgr = Inject('VarManager')
    _zipHelper = Inject('ZipHelper')
    _vsSolutionHelper = Inject('VisualStudioHelper')
    _unityHelper = Inject('UnityHelper')

    def run(self, args):
        self._args = args
        success = self._scriptRunner.runWrapper(self._runInternal)

        if not success:
            sys.exit(1)

    def _runInternal(self):
        self._varMgr.set('RootDir', RootDir)
        self._varMgr.set('BuildDir', BuildDir)
        self._varMgr.set('PythonDir', '[BuildDir]/python')
        self._varMgr.set('TempDir', '[BuildDir]/Temp')
        self._varMgr.set('AssetsDir', '[RootDir]/UnityProject/Assets')
        self._varMgr.set('ZenjectDir', '[AssetsDir]/Plugins/Zenject')
        self._varMgr.set('DistDir', '[BuildDir]/Dist')
        self._varMgr.set('BinDir', '[RootDir]/NonUnityBuild/Bin')

        versionStr = self._sys.readFileAsText('[ZenjectDir]/Version.txt').strip()

        self._log.info("Found version {0}", versionStr)

        self._populateDistDir(versionStr)

        if self._args.addTag:
            self._sys.executeAndReturnOutput("git tag -a v{0} -m 'Version {0}'".format(versionStr))
            self._log.info("Incremented version to {0}! New tag was created as well", versionStr)
        else:
            self._log.info("Incremented version to {0}!  Dist directory contains the releases.  NOTE: No tags were created however", versionStr)

    def _populateDistDir(self, versionStr):

        self._sys.deleteDirectoryIfExists('[DistDir]')
        self._sys.createDirectory('[DistDir]')

        self._sys.deleteDirectoryIfExists('[TempDir]')
        self._sys.createDirectory('[TempDir]')

        try:
            self._buildUsageDll()
            # Do this first because it is the thing that usually breaks
            self._createNonUnityZip('[DistDir]/Zenject-NonUnity@v{0}.zip'.format(versionStr))
            self._createCSharpPackage(True, '[DistDir]/Zenject-WithSampleGames@v{0}.unitypackage'.format(versionStr))
            self._createCSharpPackage(False, '[DistDir]/Zenject@v{0}.unitypackage'.format(versionStr))
        finally:
            self._sys.deleteDirectory('[TempDir]')

    def _buildUsageDll(self):
        self._log.heading('Building Zenject-usage.dll')
        self._vsSolutionHelper.buildVisualStudioProject('[RootDir]/AssemblyBuild/Zenject-usage/Zenject-usage.sln', 'Release')

    def _createNonUnityZip(self, zipPath):

        self._log.heading('Creating non unity zip')

        tempDir = '[TempDir]/Debug'
        self._sys.createDirectory(tempDir)
        self._sys.clearDirectoryContents(tempDir)

        binDir = '[BinDir]/Release'
        self._sys.deleteDirectoryIfExists(binDir)
        self._sys.createDirectory(binDir)
        self._log.info('Building non unity Zenject solution')
        self._vsSolutionHelper.buildVisualStudioProject('[RootDir]/NonUnityBuild/Zenject.sln', 'Release')

        self._log.info('Copying Zenject dlls')
        self._sys.copyFile('{0}/Zenject.dll'.format(binDir), '{0}/Zenject.dll'.format(tempDir))
        self._sys.copyFile('{0}/Zenject-Signals.dll'.format(binDir), '{0}/Zenject-Signals.dll'.format(tempDir))
        self._sys.copyFile('[ZenjectDir]/Source/Usage/Zenject-usage.dll', '{0}/Zenject-usage.dll'.format(tempDir))

        self._zipHelper.createZipFile(tempDir, zipPath)

    def _createCSharpPackage(self, includeSample, outputPath):

        self._log.heading('Creating {0}'.format(os.path.basename(outputPath)))

        self._varMgr.set('PackageTempDir', '[TempDir]/Packager')
        self._varMgr.set('ZenTempDir', '[PackageTempDir]/Assets/Plugins/Zenject')

        self._sys.createDirectory('[PackageTempDir]')
        self._sys.createDirectory('[PackageTempDir]/ProjectSettings')

        try:
            self._log.info('Copying Zenject to temporary directory')
            self._sys.copyDirectory('[ZenjectDir]', '[ZenTempDir]')

            self._log.info('Cleaning up Zenject directory')
            self._zipHelper.createZipFile('[ZenTempDir]/OptionalExtras/UnitTests', '[ZenTempDir]/OptionalExtras/UnitTests.zip')
            self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/UnitTests')
            self._sys.removeFile('[ZenTempDir]/OptionalExtras/UnitTests.meta')

            self._zipHelper.createZipFile('[ZenTempDir]/OptionalExtras/IntegrationTests', '[ZenTempDir]/OptionalExtras/IntegrationTests.zip')
            self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/IntegrationTests')
            self._sys.removeFile('[ZenTempDir]/OptionalExtras/IntegrationTests.meta')

            self._sys.removeFile('[ZenTempDir]/Source/Zenject.csproj')

            if not includeSample:
                self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame1 (Beginner)')
                self._sys.deleteDirectory('[ZenTempDir]/OptionalExtras/SampleGame2 (Advanced)')

            self._createUnityPackage('[PackageTempDir]', outputPath)
        finally:
            self._sys.deleteDirectory('[PackageTempDir]')

    def _createUnityPackage(self, projectPath, outputPath):
        self._sys.copyFile('[BuildDir]/UnityPackager/UnityPackageUtil.cs', '{0}/Assets/Editor/UnityPackageUtil.cs'.format(projectPath))

        self._log.info('Running unity to create unity package')

        self._unityHelper.runEditorFunction('[PackageTempDir]', 'Zenject.UnityPackageUtil.CreateUnityPackage')
        self._sys.move('{0}/Zenject.unitypackage'.format(projectPath), outputPath)

def installBindings():

    config = {
        'PathVars': {
            'UnityExePath': 'D:/Utils/Unity/Installs/2018.2.0f2/Editor/Unity.exe',
            'LogPath': os.path.join(BuildDir, 'Log.txt'),
            'MsBuildExePath': 'C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe'
        },
        'Compilation': {
            'UseDevenv': False
        },
    }
    Container.bind('Config').toSingle(Config, [config])

    Container.bind('LogStream').toSingle(LogStreamFile)
    Container.bind('LogStream').toSingle(LogStreamConsole, True, False)

    Container.bind('ScriptRunner').toSingle(ScriptRunner)
    Container.bind('VarManager').toSingle(VarManager)
    Container.bind('SystemHelper').toSingle(SystemHelper)
    Container.bind('Logger').toSingle(Logger)
    Container.bind('ProcessRunner').toSingle(ProcessRunner)
    Container.bind('ZipHelper').toSingle(ZipHelper)
    Container.bind('VisualStudioHelper').toSingle(VisualStudioHelper)
    Container.bind('UnityHelper').toSingle(UnityHelper)

if __name__ == '__main__':

    if (sys.version_info < (3, 0)):
        print('Wrong version of python!  Install python 3 and try again')
        sys.exit(2)

    parser = argparse.ArgumentParser(description='Zenject Releaser')
    parser.add_argument('-t', '--addTag', action='store_true', help='')
    args = parser.parse_args(sys.argv[1:])

    installBindings()

    Runner().run(args)

<|endoftext|>


<commit_before>#!/usr/bin/python
# Copyright 2013 Google Inc.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

DOCUMENTATION = '''
---
module: gce_net
version_added: "1.5"
short_description: create/destroy GCE networks and firewall rules
description:
    - This module can create and destroy Google Compue Engine networks and
      firewall rules U(https://developers.google.com/compute/docs/networking).
      The I(name) parameter is reserved for referencing a network while the
      I(fwname) parameter is used to reference firewall rules.
      IPv4 Address ranges must be specified using the CIDR
      U(http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) format.
      Full install/configuration instructions for the gce* modules can
      be found in the comments of ansible/test/gce_tests.py.
options:
  allowed:
    description:
      - the protocol:ports to allow ('tcp:80' or 'tcp:80,443' or 'tcp:80-800;udp:1-25')
        this parameter is mandatory when creating or updating a firewall rule
    required: false
    default: null
    aliases: []
  ipv4_range:
    description:
      - the IPv4 address range in CIDR notation for the network
        this parameter is not mandatory when you specified existing network in name parameter, but when you create new network, this parameter is mandatory
    required: false
    aliases: ['cidr']
  fwname:
    description:
      - name of the firewall rule
    required: false
    default: null
    aliases: ['fwrule']
  name:
    description:
      - name of the network
    required: false
    default: null
    aliases: []
  src_range:
    description:
      - the source IPv4 address range in CIDR notation
    required: false
    default: null
    aliases: ['src_cidr']
  src_tags:
    description:
      - the source instance tags for creating a firewall rule
    required: false
    default: null
    aliases: []
  target_tags:
    version_added: "1.9"
    description:
      - the target instance tags for creating a firewall rule
    required: false
    default: null
    aliases: []
  state:
    description:
      - desired state of the network or firewall
    required: false
    default: "present"
    choices: ["active", "present", "absent", "deleted"]
    aliases: []
  service_account_email:
    version_added: "1.6"
    description:
      - service account email
    required: false
    default: null
    aliases: []
  pem_file:
    version_added: "1.6"
    description:
      - path to the pem file associated with the service account email
        This option is deprecated. Use 'credentials_file'.
    required: false
    default: null
    aliases: []
  credentials_file:
    version_added: "2.1.0"
    description:
      - path to the JSON file associated with the service account email
    required: false
    default: null
    aliases: []
  project_id:
    version_added: "1.6"
    description:
      - your GCE project ID
    required: false
    default: null
    aliases: []

requirements:
    - "python >= 2.6"
    - "apache-libcloud >= 0.13.3, >= 0.17.0 if using JSON credentials"
author: "Eric Johnson (@erjohnso) <erjohnso@google.com>"
'''

EXAMPLES = '''
# Simple example of creating a new network
- local_action:
    module: gce_net
    name: privatenet
    ipv4_range: '10.240.16.0/24'

# Simple example of creating a new firewall rule
- local_action:
    module: gce_net
    name: privatenet
    fwname: all-web-webproxy
    allowed: tcp:80,8080
    src_tags: ["web", "proxy"]

'''

try:
    from libcloud.compute.types import Provider
    from libcloud.compute.providers import get_driver
    from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
            ResourceExistsError, ResourceNotFoundError
    _ = Provider.GCE
    HAS_LIBCLOUD = True
except ImportError:
    HAS_LIBCLOUD = False

def format_allowed_section(allowed):
    """Format each section of the allowed list"""
    if allowed.count(":") == 0:
        protocol = allowed
        ports = []
    elif allowed.count(":") == 1:
        protocol, ports = allowed.split(":")
    else:
        return []
    if ports.count(","):
        ports = ports.split(",")
    else:
        ports = [ports]
    return_val = {"IPProtocol": protocol}
    if ports:
        return_val["ports"] = ports
    return return_val

def format_allowed(allowed):
    """Format the 'allowed' value so that it is GCE compatible."""
    return_value = []
    if allowed.count(";") == 0:
        return [format_allowed_section(allowed)]
    else:
        sections = allowed.split(";")
        for section in sections:
            return_value.append(format_allowed_section(section))
    return return_value

def main():
    module = AnsibleModule(
        argument_spec = dict(
            allowed = dict(),
            ipv4_range = dict(),
            fwname = dict(),
            name = dict(),
            src_range = dict(type='list'),
            src_tags = dict(type='list'),
            target_tags = dict(type='list'),
            state = dict(default='present'),
            service_account_email = dict(),
            pem_file = dict(),
            credentials_file = dict(),
            project_id = dict(),
        )
    )

    if not HAS_LIBCLOUD:
        module.exit_json(msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    allowed = module.params.get('allowed')
    ipv4_range = module.params.get('ipv4_range')
    fwname = module.params.get('fwname')
    name = module.params.get('name')
    src_range = module.params.get('src_range')
    src_tags = module.params.get('src_tags')
    target_tags = module.params.get('target_tags')
    state = module.params.get('state')

    changed = False
    json_output = {'state': state}

    if state in ['active', 'present']:
        network = None
        try:
            network = gce.ex_get_network(name)
            json_output['name'] = name
            json_output['ipv4_range'] = network.cidr
        except ResourceNotFoundError:
            pass
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # user wants to create a new network that doesn't yet exist
        if name and not network:
            if not ipv4_range:
                module.fail_json(msg="Network '" + name + "' is not found. To create network, 'ipv4_range' parameter is required",
                    changed=False)

            try:
                network = gce.ex_create_network(name, ipv4_range)
                json_output['name'] = name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        if fwname:
            # user creating a firewall rule
            if not allowed and not src_range and not src_tags:
                if changed and network:
                    module.fail_json(
                        msg="Network created, but missing required " + \
                        "firewall rule parameter(s)", changed=True)
                module.fail_json(
                    msg="Missing required firewall rule parameter(s)",
                    changed=False)

            allowed_list = format_allowed(allowed)

            # Fetch existing rule and if it exists, compare attributes
            # update if attributes changed.  Create if doesn't exist.
            try:
                fw_changed = False
                fw = gce.ex_get_firewall(fwname)

                # If old and new attributes are different, we update the firewall rule.
                # This implicitly let's us clear out attributes as well.
                # allowed_list is required and must not be None for firewall rules.
                if allowed_list and (allowed_list != fw.allowed):
                    fw.allowed = allowed_list
                    fw_changed = True

                if src_range != fw.source_ranges:
                    fw.source_ranges = src_range
                    fw_changed = True

                if src_tags != fw.source_tags:
                    fw.source_tags = src_tags
                    fw_changed = True

                if src_tags != fw.target_tags:
                    fw.target_tags = target_tags
                    fw_changed = True

                if fw_changed is True:
                    try:
                        gce.ex_update_firewall(fw)
                        changed = True
                    except Exception as e:
                        module.fail_json(msg=unexpected_error_msg(e), changed=False)

            # Firewall rule not found so we try to create it.
            except ResourceNotFoundError:
                try:
                    gce.ex_create_firewall(fwname, allowed_list, network=name,
                        source_ranges=src_range, source_tags=src_tags, target_tags=target_tags)
                    changed = True

                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e), changed=False)

            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            json_output['fwname'] = fwname
            json_output['allowed'] = allowed
            json_output['src_range'] = src_range
            json_output['src_tags'] = src_tags
            json_output['target_tags'] = target_tags

    if state in ['absent', 'deleted']:
        if fwname:
            json_output['fwname'] = fwname
            fw = None
            try:
                fw = gce.ex_get_firewall(fwname)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if fw:
                gce.ex_destroy_firewall(fw)
                changed = True
        elif name:
            json_output['name'] = name
            network = None
            try:
                network = gce.ex_get_network(name)

            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if network:
                gce.ex_destroy_network(network)
                changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)

# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.gce import *

if __name__ == '__main__':
    main()
<commit_msg>Added helper function and logic to sort attributes before comparing.<commit_after>#!/usr/bin/python
# Copyright 2013 Google Inc.
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

DOCUMENTATION = '''
---
module: gce_net
version_added: "1.5"
short_description: create/destroy GCE networks and firewall rules
description:
    - This module can create and destroy Google Compue Engine networks and
      firewall rules U(https://developers.google.com/compute/docs/networking).
      The I(name) parameter is reserved for referencing a network while the
      I(fwname) parameter is used to reference firewall rules.
      IPv4 Address ranges must be specified using the CIDR
      U(http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) format.
      Full install/configuration instructions for the gce* modules can
      be found in the comments of ansible/test/gce_tests.py.
options:
  allowed:
    description:
      - the protocol:ports to allow ('tcp:80' or 'tcp:80,443' or 'tcp:80-800;udp:1-25')
        this parameter is mandatory when creating or updating a firewall rule
    required: false
    default: null
    aliases: []
  ipv4_range:
    description:
      - the IPv4 address range in CIDR notation for the network
        this parameter is not mandatory when you specified existing network in name parameter, but when you create new network, this parameter is mandatory
    required: false
    aliases: ['cidr']
  fwname:
    description:
      - name of the firewall rule
    required: false
    default: null
    aliases: ['fwrule']
  name:
    description:
      - name of the network
    required: false
    default: null
    aliases: []
  src_range:
    description:
      - the source IPv4 address range in CIDR notation
    required: false
    default: null
    aliases: ['src_cidr']
  src_tags:
    description:
      - the source instance tags for creating a firewall rule
    required: false
    default: null
    aliases: []
  target_tags:
    version_added: "1.9"
    description:
      - the target instance tags for creating a firewall rule
    required: false
    default: null
    aliases: []
  state:
    description:
      - desired state of the network or firewall
    required: false
    default: "present"
    choices: ["active", "present", "absent", "deleted"]
    aliases: []
  service_account_email:
    version_added: "1.6"
    description:
      - service account email
    required: false
    default: null
    aliases: []
  pem_file:
    version_added: "1.6"
    description:
      - path to the pem file associated with the service account email
        This option is deprecated. Use 'credentials_file'.
    required: false
    default: null
    aliases: []
  credentials_file:
    version_added: "2.1.0"
    description:
      - path to the JSON file associated with the service account email
    required: false
    default: null
    aliases: []
  project_id:
    version_added: "1.6"
    description:
      - your GCE project ID
    required: false
    default: null
    aliases: []

requirements:
    - "python >= 2.6"
    - "apache-libcloud >= 0.13.3, >= 0.17.0 if using JSON credentials"
author: "Eric Johnson (@erjohnso) <erjohnso@google.com>"
'''

EXAMPLES = '''
# Simple example of creating a new network
- local_action:
    module: gce_net
    name: privatenet
    ipv4_range: '10.240.16.0/24'

# Simple example of creating a new firewall rule
- local_action:
    module: gce_net
    name: privatenet
    fwname: all-web-webproxy
    allowed: tcp:80,8080
    src_tags: ["web", "proxy"]

'''

try:
    from libcloud.compute.types import Provider
    from libcloud.compute.providers import get_driver
    from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
            ResourceExistsError, ResourceNotFoundError
    _ = Provider.GCE
    HAS_LIBCLOUD = True
except ImportError:
    HAS_LIBCLOUD = False

def format_allowed_section(allowed):
    """Format each section of the allowed list"""
    if allowed.count(":") == 0:
        protocol = allowed
        ports = []
    elif allowed.count(":") == 1:
        protocol, ports = allowed.split(":")
    else:
        return []
    if ports.count(","):
        ports = ports.split(",")
    else:
        ports = [ports]
    return_val = {"IPProtocol": protocol}
    if ports:
        return_val["ports"] = ports
    return return_val

def format_allowed(allowed):
    """Format the 'allowed' value so that it is GCE compatible."""
    return_value = []
    if allowed.count(";") == 0:
        return [format_allowed_section(allowed)]
    else:
        sections = allowed.split(";")
        for section in sections:
            return_value.append(format_allowed_section(section))
    return return_value

def sorted_allowed_list(allowed_list):
    """Sort allowed_list (output of format_allowed) by protocol and port."""
    # sort by protocol
    allowed_by_protocol = sorted(allowed_list,key=lambda x: x['IPProtocol'])
    # sort the ports list
    return sorted(allowed_by_protocol, key=lambda y: y['ports'].sort())

def main():
    module = AnsibleModule(
        argument_spec = dict(
            allowed = dict(),
            ipv4_range = dict(),
            fwname = dict(),
            name = dict(),
            src_range = dict(type='list'),
            src_tags = dict(type='list'),
            target_tags = dict(type='list'),
            state = dict(default='present'),
            service_account_email = dict(),
            pem_file = dict(),
            credentials_file = dict(),
            project_id = dict(),
        )
    )

    if not HAS_LIBCLOUD:
        module.exit_json(msg='libcloud with GCE support (0.17.0+) required for this module')

    gce = gce_connect(module)

    allowed = module.params.get('allowed')
    ipv4_range = module.params.get('ipv4_range')
    fwname = module.params.get('fwname')
    name = module.params.get('name')
    src_range = module.params.get('src_range')
    src_tags = module.params.get('src_tags')
    target_tags = module.params.get('target_tags')
    state = module.params.get('state')

    changed = False
    json_output = {'state': state}

    if state in ['active', 'present']:
        network = None
        try:
            network = gce.ex_get_network(name)
            json_output['name'] = name
            json_output['ipv4_range'] = network.cidr
        except ResourceNotFoundError:
            pass
        except Exception as e:
            module.fail_json(msg=unexpected_error_msg(e), changed=False)

        # user wants to create a new network that doesn't yet exist
        if name and not network:
            if not ipv4_range:
                module.fail_json(msg="Network '" + name + "' is not found. To create network, 'ipv4_range' parameter is required",
                    changed=False)

            try:
                network = gce.ex_create_network(name, ipv4_range)
                json_output['name'] = name
                json_output['ipv4_range'] = ipv4_range
                changed = True
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

        if fwname:
            # user creating a firewall rule
            if not allowed and not src_range and not src_tags:
                if changed and network:
                    module.fail_json(
                        msg="Network created, but missing required " + \
                        "firewall rule parameter(s)", changed=True)
                module.fail_json(
                    msg="Missing required firewall rule parameter(s)",
                    changed=False)

            allowed_list = format_allowed(allowed)

            # Fetch existing rule and if it exists, compare attributes
            # update if attributes changed.  Create if doesn't exist.
            try:
                fw_changed = False
                fw = gce.ex_get_firewall(fwname)

                # If old and new attributes are different, we update the firewall rule.
                # This implicitly let's us clear out attributes as well.
                # allowed_list is required and must not be None for firewall rules.
                if allowed_list and (sorted_allowed_list(allowed_list) != sorted_allowed_list(fw.allowed)):
                    fw.allowed = allowed_list
                    fw_changed = True

                # If these attributes are lists, we sort them first, then compare.
                # Otherwise, we update if they differ.
                if fw.source_ranges != src_range:
                    if isinstance(src_range, list):
                        if sorted(fw.source_ranges) != sorted(src_range):
                            fw.source_ranges = src_range
                            fw_changed = True
                    else:
                        fw.source_ranges = src_range
                        fw_changed = True

                if fw.source_tags != src_tags:
                    if isinstance(src_range, list):
                        if sorted(fw.source_tags) != sorted(src_tags):
                            fw.source_tags = src_tags
                            fw_changed = True
                    else:
                        fw.source_tags = src_tags
                        fw_changed = True

                if fw.target_tags != target_tags:
                    if isinstance(target_tags, list):
                        if sorted(fw.target_tags) != sorted(target_tags):
                            fw.target_tags = target_tags
                            fw_changed = True
                    else:
                        fw.target_tags = target_tags
                        fw_changed = True

                if fw_changed is True:
                    try:
                        gce.ex_update_firewall(fw)
                        changed = True
                    except Exception as e:
                        module.fail_json(msg=unexpected_error_msg(e), changed=False)

            # Firewall rule not found so we try to create it.
            except ResourceNotFoundError:
                try:
                    gce.ex_create_firewall(fwname, allowed_list, network=name,
                        source_ranges=src_range, source_tags=src_tags, target_tags=target_tags)
                    changed = True

                except Exception as e:
                    module.fail_json(msg=unexpected_error_msg(e), changed=False)

            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)

            json_output['fwname'] = fwname
            json_output['allowed'] = allowed
            json_output['src_range'] = src_range
            json_output['src_tags'] = src_tags
            json_output['target_tags'] = target_tags

    if state in ['absent', 'deleted']:
        if fwname:
            json_output['fwname'] = fwname
            fw = None
            try:
                fw = gce.ex_get_firewall(fwname)
            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if fw:
                gce.ex_destroy_firewall(fw)
                changed = True
        elif name:
            json_output['name'] = name
            network = None
            try:
                network = gce.ex_get_network(name)

            except ResourceNotFoundError:
                pass
            except Exception as e:
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
            if network:
                gce.ex_destroy_network(network)
                changed = True

    json_output['changed'] = changed
    module.exit_json(**json_output)

# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.gce import *

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


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2015, Ansible, inc
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
#

DOCUMENTATION = '''
---
module: package
version_added: 2.0
author:
    - Ansible Inc
maintainers:
    - Ansible Core Team
short_description: Generic OS package manager
description:
     - Installs, upgrade and removes packages using the underlying OS package manager.
options:
  name:
    description:
      - "Package name, or package specifier with version, like C(name-1.0)."
      - "Be aware that packages are not always named the same and this module will not 'translate' them per distro."
    required: true
  state:
    description:
      - Whether to install (C(present), C(latest)), or remove (C(absent)) a package.
    required: true
  use:
    description:
      - The required package manager module to use (yum, apt, etc). The default 'auto' will use existing facts or try to autodetect it.
      - You should only use this field if the automatic selection is not working for some reason.
    required: false
    default: auto
requirements:
    - Whatever is required for the package plugins specific for each system.
notes:
    - This module actually calls the pertinent package modules for each system (apt, yum, etc).
'''
EXAMPLES = '''
- name: install the latest version of ntpdate
  package: name=ntpdate state=latest

# This uses a variable as this changes per distribution.
- name: remove the apache package
  package : name={{apache}} state=absent
'''
<commit_msg>removed extra space<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2015, Ansible, inc
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
#

DOCUMENTATION = '''
---
module: package
version_added: 2.0
author:
    - Ansible Inc
maintainers:
    - Ansible Core Team
short_description: Generic OS package manager
description:
     - Installs, upgrade and removes packages using the underlying OS package manager.
options:
  name:
    description:
      - "Package name, or package specifier with version, like C(name-1.0)."
      - "Be aware that packages are not always named the same and this module will not 'translate' them per distro."
    required: true
  state:
    description:
      - Whether to install (C(present), C(latest)), or remove (C(absent)) a package.
    required: true
  use:
    description:
      - The required package manager module to use (yum, apt, etc). The default 'auto' will use existing facts or try to autodetect it.
      - You should only use this field if the automatic selection is not working for some reason.
    required: false
    default: auto
requirements:
    - Whatever is required for the package plugins specific for each system.
notes:
    - This module actually calls the pertinent package modules for each system (apt, yum, etc).
'''
EXAMPLES = '''
- name: install the latest version of ntpdate
  package: name=ntpdate state=latest

# This uses a variable as this changes per distribution.
- name: remove the apache package
  package: name={{apache}} state=absent
'''
<|endoftext|>