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

import argparse
import curses
import curses.ascii
import os
import sys
import text_unidecode

# constants

DESCRIPTION = "shakyo2d is a tool to learn about something just copying it " \
              "by hand."

TTY_DEVICE_FILE = "/dev/tty"

QUIT_CHARS = {chr(curses.ascii.ESC), curses.ascii.ctrl('[')}
DELETE_CHARS = {chr(curses.ascii.DEL), chr(curses.ascii.BS),
                chr(curses.KEY_BACKSPACE), chr(curses.KEY_DC)}
CLEAR_CHAR = curses.ascii.ctrl('u')
CHEAT_CHAR = curses.ascii.ctrl('n')

CAN_CHEAT = False
SPACES_PER_TAB = 2

ATTR_CORRECT = curses.A_NORMAL
ATTR_ERROR = curses.A_REVERSE

# the order of bugs

def error(*message):
  print("ERROR:", *message, file=sys.stderr)

def fail(*message):
  error(*message)
  exit(1)

# classes

class Console:
  def __init__(self, window):
    window.keypad(True)
    window.scrollok(True)
    self._window = window
    self._game = None

  @property
  def ui(self):
    class Ui:
      def __init__(self, console):
        assert isinstance(console, Console)
        self.__console = console

      def set_game(self, game):
        self.__console._game = game

      def play_game(self):
        assert self.__console._game != None
        self.__console._game.play()

    return Ui(self)

  @property
  def api(self):
    class Api:
      def __init__(self, console):
        assert isinstance(console, Console)
        self.__console = console

      @property
      def screen_height(self):
        return self.__console._window.getmaxyx()[0]

      @property
      def screen_width(self):
        return self.__console._window.getmaxyx()[1]

      def get_char(self) -> str:
        return chr(self.__console._window.getch())

      def add_char(self, char: str, attr=curses.A_NORMAL):
        assert len(char) == 1
        if not self.__console._window.getyx()[1] < self.screen_width: return
        self.__console._window.addch(ord(char), attr)

      def print_line(self, line_pos, text):
        assert len(text) <= self.screen_width
        self.__console._window.move(line_pos, 0)
        self.__console._window.clrtoeol()
        self.__console._window.addstr(line_pos, 0, text)

      def move(self, y, x):
        self.__console._window.move(y, x)

      def clear(self):
        self.__console._window.clear()

      def scroll(self):
        self.__console._window.scroll()

    return Api(self)

class TypingGame:
  def __init__(self, api, example_file):
    self.__api = api
    self.__example_text = FormattedText(example_file,
                                        line_length=(api.screen_width - 1))
    self.__geometry = Geometry(api.screen_height)
    self.__input_text = ""
    if self.__example_text[0] == None:
      raise Exception("No line can be read from stdin.")

  def play(self):
    self.__api.clear()
    self.__initialize_screen()

    game_over = False
    while not game_over:
      char = self.__api.get_char()
      assert curses.ascii.isascii(char)

      if char in QUIT_CHARS:
        return
      elif char == CLEAR_CHAR:
        self.__clear_input_text()
      elif char in DELETE_CHARS:
        self.__delete_char()
      elif char == CHEAT_CHAR and CAN_CHEAT:
        game_over = self.__cheat()
      elif curses.ascii.isprint(char) or curses.ascii.isspace(char):
        game_over = self.__add_char(char)

  def __add_char(self, char: str) -> bool:
    go_to_next_line = char == '\n' \
                      and self.__input_text == self.__example_text[0]
    if go_to_next_line and self.__example_text[1] == None:
      return True

    if go_to_next_line:
      self.__scroll()
    elif len(self.__input_text) == len(self.__example_text[0]):
      pass
    elif char == '\t':
      for _ in range(SPACES_PER_TAB):
        result = self.__add_char(' ')
        assert result == False
    elif curses.ascii.isprint(char):
      self.__input_text += char
      attr = ATTR_CORRECT \
             if char == self.__example_text[0][len(self.__input_text) - 1] \
             else ATTR_ERROR
      self.__api.add_char(char, attr=attr)
    return False

  def __delete_char(self):
    if len(self.__input_text) == 0: return
    current_cursor_position = len(self.__input_text)
    self.__api.move(self.__geometry.current_line, current_cursor_position - 1)
    self.__api.add_char(self.__example_text[0][len(self.__input_text) - 1])
    self.__api.move(self.__geometry.current_line, current_cursor_position - 1)
    self.__input_text = self.__input_text[:-1]

  def __cheat(self):
    if self.__example_text[1] == None:
      return True
    self.__scroll()
    return False

  def __initialize_screen(self):
    self.__print_all_example_text()
    self.__clear_input_text()

  def __scroll(self):
    self.__api.scroll()
    del self.__example_text[0]
    self.__print_bottom_example_text()
    self.__clear_input_text()

  def __clear_input_text(self):
    self.__input_text = ""
    self.__api.move(self.__geometry.current_line, 0)

  def __print_bottom_example_text(self):
    index = self.__geometry.bottom_line - self.__geometry.current_line
    if self.__example_text[index] != None:
      self.__api.print_line(self.__geometry.bottom_line,
                            self.__example_text[index])

  def __print_all_example_text(self):
    for index in range(self.__geometry.bottom_line
                       - self.__geometry.current_line):
      if self.__example_text[index] == None: break
      self.__api.print_line(self.__geometry.current_line + index,
                            self.__example_text[index])

class Geometry:
  def __init__(self, screen_height):
    self.current_line = (screen_height - 1) // 2
    self.bottom_line = screen_height - 1

class FormattedText:
  def __init__(self, text_file, line_length=79):
    self.__file = text_file
    self.__line_length = line_length
    self.__buffered_lines = []

  def __del__(self):
    self.__file.close()

  def __getitem__(self, index: int) -> str:
    self.__read_lines_from_file()

    if index < len(self.__buffered_lines):
      return self.__buffered_lines[index]
    return None

  def __delitem__(self, index: int):
    del self.__buffered_lines[index]

  def __read_lines_from_file(self):
    lines = self.__file.readlines()

    for line in lines:
      self.__buffer_line(self.__preprocess_text(line))

  def __buffer_line(self, line):
    line = line.rstrip()

    while len(line) > self.__line_length:
      buffered_line, line = self.__split_line(line)
      self.__buffered_lines.append(buffered_line)
    self.__buffered_lines.append(line)

  def __split_line(self, line):
    return line[self.__line_length:].rstrip(), \
           line[:self.__line_length].strip()

  @staticmethod
  def __preprocess_text(text):
    return text_unidecode.unidecode(text.replace('\t', ' ' * SPACES_PER_TAB))

# functions

def reset_stdin():
  TEMPORARY_FD = 3

  os.dup2(sys.stdin.fileno(), TEMPORARY_FD)
  os.close(sys.stdin.fileno())
  sys.stdin = open(TTY_DEVICE_FILE)
  original_stdin = os.fdopen(TEMPORARY_FD)
  return original_stdin

def initialize_curses():
  window = curses.initscr()
  curses.noecho()
  curses.cbreak()
  curses.start_color()
  curses.use_default_colors()
  return window

def finalize_curses():
  curses.nocbreak()
  curses.echo()
  curses.endwin() # should be in the very last line

# main routine

def main():
  if not sys.stdout.isatty(): fail("stdout is not a tty.")
  if sys.stdin.isatty(): fail("stdin is a tty.")

  example_file = reset_stdin()

  try:
    # CAUTION:
    # You need to raise some Exception() instead of calling exit() here
    # to prevent curses messing up your terminal.

    window = initialize_curses()

    console = Console(window)
    console.ui.set_game(TypingGame(console.api, example_file))
    console.ui.play_game()
  finally:
    finalize_curses()

def parse_args():
  arg_parser = argparse.ArgumentParser(description=DESCRIPTION)
  arg_parser.add_argument("-c", "--cheat",
                          dest="can_cheat",
                          action="store_true",
                          help="enable the cheat key, {}"
                               .format(curses.ascii.unctrl(CHEAT_CHAR)))
  arg_parser.add_argument("-t", "--spaces-per-tab",
                          type=int, dest="spaces_per_tab",
                          help="set number of spaces per tab")

  args = arg_parser.parse_args()
  if args.spaces_per_tab != None:
    global SPACES_PER_TAB
    SPACES_PER_TAB = args.spaces_per_tab
  if args.can_cheat == True:
    global CAN_CHEAT
    CAN_CHEAT = True

if __name__ == "__main__":
  parse_args()
  main()
<commit_msg>Change whole console API<commit_after>#!/usr/bin/env python3

import argparse
import curses
import curses.ascii
import os
import sys
import text_unidecode

# constants

DESCRIPTION = "shakyo2d is a tool to learn about something just copying it " \
              "by hand."

TTY_DEVICE_FILE = "/dev/tty"

QUIT_CHARS = {chr(curses.ascii.ESC), curses.ascii.ctrl('[')}
DELETE_CHARS = {chr(curses.ascii.DEL), chr(curses.ascii.BS),
                chr(curses.KEY_BACKSPACE), chr(curses.KEY_DC)}
CLEAR_CHAR = curses.ascii.ctrl('u')
CHEAT_CHAR = curses.ascii.ctrl('n')

CAN_CHEAT = False
SPACES_PER_TAB = 2

ATTR_CORRECT = curses.A_NORMAL
ATTR_ERROR = curses.A_REVERSE

# the order of bugs

def error(*message):
  print("ERROR:", *message, file=sys.stderr)

def fail(*message):
  error(*message)
  exit(1)

# classes

class Console:
  def __init__(self, window):
    window.keypad(True)
    window.scrollok(True)
    self._window = window
    self._game = None

  @property
  def ui(self):
    class Ui:
      def __init__(self, console):
        assert isinstance(console, Console)
        self.__console = console

      def set_game(self, game):
        self.__console._game = game

      def play_game(self):
        assert self.__console._game != None
        self.__console._game.play()

    return Ui(self)

  @property
  def api(self):
    class Api:
      class SavedPosition:
        def __init__(self, window):
          self.__window = window

        def __enter__(self):
          self.__saved_position = self.__window.getyx()

        def __exit__(self, *_):
          self.__window.move(*self.__saved_position)

      def __init__(self, console):
        assert isinstance(console, Console)
        self.__console = console

      @property
      def screen_height(self):
        return self.__console._window.getmaxyx()[0]

      @property
      def screen_width(self):
        return self.__console._window.getmaxyx()[1]

      def get_char(self) -> str:
        return chr(self.__console._window.getch())

      def put_char(self, char: str, attr=curses.A_NORMAL):
        assert len(char) == 1 # TODO: make it proper
        with self.SavedPosition(self.__console._window):
          self.__console._window.addch(ord(char), attr)

      def put_line(self, line_pos, text):
        assert len(text) <= self.screen_width
        with self.SavedPosition(self.__console._window):
          self.__console._window.move(line_pos, 0)
          self.__console._window.clrtoeol()
          self.__console._window.addstr(line_pos, 0, text)

      def move(self, y, x):
        self.__console._window.move(y, x)

      def move_right(self):
        y, x = self.__console._window.getyx()
        if x == self.screen_width - 1: return
        self.__console._window.move(y, x + 1)

      def move_left(self):
        y, x = self.__console._window.getyx()
        if x == 0: return
        self.__console._window.move(y, x - 1)

      def clear(self):
        with self.SavedPosition(self.__console._window):
          self.__console._window.clear()

      def scroll(self):
        with self.SavedPosition(self.__console._window):
          self.__console._window.scroll()

    return Api(self)

class TypingGame:
  def __init__(self, api, example_file):
    self.__api = api
    self.__example_text = FormattedText(example_file,
                                        line_length=(api.screen_width - 1))
    self.__geometry = Geometry(api.screen_height)
    self.__input_text = ""
    if self.__example_text[0] == None:
      raise Exception("No line can be read from stdin.")

  def play(self):
    self.__api.clear()
    self.__initialize_screen()

    game_over = False
    while not game_over:
      char = self.__api.get_char()
      assert curses.ascii.isascii(char)

      if char in QUIT_CHARS:
        return
      elif char == CLEAR_CHAR:
        self.__clear_input_text()
      elif char in DELETE_CHARS:
        self.__delete_char()
      elif char == CHEAT_CHAR and CAN_CHEAT:
        game_over = self.__cheat()
      elif curses.ascii.isprint(char) or curses.ascii.isspace(char):
        game_over = self.__add_char(char)

  def __add_char(self, char: str) -> bool:
    go_to_next_line = char == '\n' \
                      and self.__input_text == self.__example_text[0]
    if go_to_next_line and self.__example_text[1] == None:
      return True

    if go_to_next_line:
      self.__scroll()
    elif len(self.__input_text) == len(self.__example_text[0]):
      pass
    elif char == '\t':
      for _ in range(SPACES_PER_TAB):
        result = self.__add_char(' ')
        assert result == False
    elif curses.ascii.isprint(char):
      self.__input_text += char
      attr = ATTR_CORRECT \
             if char == self.__example_text[0][len(self.__input_text) - 1] \
             else ATTR_ERROR
      self.__api.put_char(char, attr=attr)
      self.__api.move_right()
    return False

  def __delete_char(self):
    if len(self.__input_text) == 0: return
    self.__input_text = self.__input_text[:-1]
    self.__api.move_left()
    self.__api.put_char(self.__example_text[0][len(self.__input_text)])

  def __cheat(self):
    if self.__example_text[1] == None:
      return True
    self.__scroll()
    return False

  def __initialize_screen(self):
    self.__print_all_example_text()
    self.__clear_input_text()

  def __scroll(self):
    self.__api.scroll()
    del self.__example_text[0]
    self.__print_bottom_example_text()
    self.__clear_input_text()

  def __clear_input_text(self):
    self.__input_text = ""
    self.__api.move(self.__geometry.current_line, 0)

  def __print_bottom_example_text(self):
    index = self.__geometry.bottom_line - self.__geometry.current_line
    if self.__example_text[index] != None:
      self.__api.put_line(self.__geometry.bottom_line,
                          self.__example_text[index])

  def __print_all_example_text(self):
    for index in range(self.__geometry.bottom_line
                       - self.__geometry.current_line):
      if self.__example_text[index] == None: break
      self.__api.put_line(self.__geometry.current_line + index,
                          self.__example_text[index])

class Geometry:
  def __init__(self, screen_height):
    self.current_line = (screen_height - 1) // 2
    self.bottom_line = screen_height - 1

class FormattedText:
  def __init__(self, text_file, line_length=79):
    self.__file = text_file
    self.__line_length = line_length
    self.__buffered_lines = []

  def __del__(self):
    self.__file.close()

  def __getitem__(self, index: int) -> str:
    self.__read_lines_from_file()

    if index < len(self.__buffered_lines):
      return self.__buffered_lines[index]
    return None

  def __delitem__(self, index: int):
    del self.__buffered_lines[index]

  def __read_lines_from_file(self):
    lines = self.__file.readlines()

    for line in lines:
      self.__buffer_line(self.__preprocess_text(line))

  def __buffer_line(self, line):
    line = line.rstrip()

    while len(line) > self.__line_length:
      buffered_line, line = self.__split_line(line)
      self.__buffered_lines.append(buffered_line)
    self.__buffered_lines.append(line)

  def __split_line(self, line):
    return line[self.__line_length:].rstrip(), \
           line[:self.__line_length].strip()

  @staticmethod
  def __preprocess_text(text):
    return text_unidecode.unidecode(text.replace('\t', ' ' * SPACES_PER_TAB))

# functions

def reset_stdin():
  TEMPORARY_FD = 3

  os.dup2(sys.stdin.fileno(), TEMPORARY_FD)
  os.close(sys.stdin.fileno())
  sys.stdin = open(TTY_DEVICE_FILE)
  original_stdin = os.fdopen(TEMPORARY_FD)
  return original_stdin

def initialize_curses():
  window = curses.initscr()
  curses.noecho()
  curses.cbreak()
  curses.start_color()
  curses.use_default_colors()
  return window

def finalize_curses():
  curses.nocbreak()
  curses.echo()
  curses.endwin() # should be in the very last line

# main routine

def main():
  if not sys.stdout.isatty(): fail("stdout is not a tty.")
  if sys.stdin.isatty(): fail("stdin is a tty.")

  example_file = reset_stdin()

  try:
    # CAUTION:
    # You need to raise some Exception() instead of calling exit() here
    # to prevent curses messing up your terminal.

    window = initialize_curses()

    console = Console(window)
    console.ui.set_game(TypingGame(console.api, example_file))
    console.ui.play_game()
  finally:
    finalize_curses()

def parse_args():
  arg_parser = argparse.ArgumentParser(description=DESCRIPTION)
  arg_parser.add_argument("-c", "--cheat",
                          dest="can_cheat",
                          action="store_true",
                          help="enable the cheat key, {}"
                               .format(curses.ascii.unctrl(CHEAT_CHAR)))
  arg_parser.add_argument("-t", "--spaces-per-tab",
                          type=int, dest="spaces_per_tab",
                          help="set number of spaces per tab")

  args = arg_parser.parse_args()
  if args.spaces_per_tab != None:
    global SPACES_PER_TAB
    SPACES_PER_TAB = args.spaces_per_tab
  if args.can_cheat == True:
    global CAN_CHEAT
    CAN_CHEAT = True

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


<commit_before>"""
Class for Hinode/EIS instrument. Holds information about spectral, temporal, and spatial resolution
and other instrument-specific information.
"""

import os
import glob
import sys
import logging

import numpy as np
from scipy.interpolate import splrep,splev
import sunpy.map
import astropy.units as u

from synthesizAR.instruments import InstrumentBase,Pair

class InstrumentHinodeEIS(InstrumentBase):
    """
    Class for Extreme-ultraviolet Imaging Spectrometer (EIS) instrument on the Hinode spacecraft.
    Converts emissivity calculations for each loop into detector units based on the spectral,
    spatial, and temporal resolution along with the instrument response functions.
    """

    name = 'Hinode_EIS'
    cadence = 10.0*u.s
    resolution = Pair(1.0*u.arcsec/u.pixel,2.0*u.arcsec/u.pixel)
    fits_template = sunpy.map.header.MapMeta()
    fits_template['telescop'] = 'Hinode'
    fits_template['instrume'] = 'EIS'
    fits_template['detector'] = 'EIS'
    fits_template['waveunit'] = 'angstrom'

    def __init__(self,detector_file_dir,observing_time,observing_area=None):
        super().__init__(observing_time,observing_area)
        self._setup_from_file(detector_file_dir)

    def _setup_from_file(self,detector_file_dir):
        """
        Read instrument properties from files. This is a temporary solution and requires that the
        detector files all be collected into the same directory and be formatted in a specific way.

        .. warning:: This method will be modified once EIS response functions become
                    available in a different format.
        """
        eis_instr_files = glob.glob(os.path.join(detector_file_dir,'EIS_*_*.*.ins'))
        self.channels = []
        for eif in eis_instr_files:
            #extract some metadata from the filename
            base = os.path.splitext(os.path.basename(eif))[0]
            wave = float(base.split('_')[-1])*u.angstrom
            name = '{}_{}_{}'.format(base.split('_')[1][:2],base.split('_')[1][2:],
                                    wave.value)
            #read the response function from the file
            with open(eif,'r') as f:
                lines = f.readlines()
            resp_x,resp_y = np.empty(int(lines[0])),np.empty(int(lines[0]))
            for i in range(1,int(lines[0])+1):
                resp_x[i-1],resp_y[i-1] = list(filter(None,lines[i].split(' ')))
            self.channels.append({'wavelength':wave,'name':name,
                    'response':{'x':resp_x*u.angstrom,
                                'y':resp_y*u.count/u.pixel/u.photon*u.steradian*u.cm**2}})

        self.channels = sorted(self.channels,key=lambda x:x['wavelength'])

    def detect(self,loop,channel):
        """
        Calculate response of Hinode/EIS detector for given loop object.
        """
        # only interpolate once
        if not all([w in channel['response']['x'] for w in loop.wavelengths /
                        if channel['response']['x'][0] <= wavelength <= channel['response']['x'][-1]]):
            nots = splrep(channel['response']['x'].value,channel['response']['y'].value)
            tmp_x = np.sort(np.hstack([channel['response']['x'].value,loop.wavelengths]))
            channel['response']['y'] = splev(tmp_x,nots)*channel['response']['y'].unit
            channel['response']['x'] = tmp_x*channel['response']['x'].unit

        counts = np.zeros(loop.density.shape)
        for wavelength in loop.wavelengths:
            if wavelength in channel['response']['x']:
                counts += channel['response']['y'][np.argwhere(channel['response']['x']==wavelength)[0][0]].value*loop.get_emission(wavelength).value

        return counts*loop.get_emission(wavelength).unit*channel['response']['y'].unit
<commit_msg>line break bug fix<commit_after>"""
Class for Hinode/EIS instrument. Holds information about spectral, temporal, and spatial resolution
and other instrument-specific information.
"""

import os
import glob
import sys
import logging

import numpy as np
from scipy.interpolate import splrep,splev
import sunpy.map
import astropy.units as u

from synthesizAR.instruments import InstrumentBase,Pair

class InstrumentHinodeEIS(InstrumentBase):
    """
    Class for Extreme-ultraviolet Imaging Spectrometer (EIS) instrument on the Hinode spacecraft.
    Converts emissivity calculations for each loop into detector units based on the spectral,
    spatial, and temporal resolution along with the instrument response functions.
    """

    name = 'Hinode_EIS'
    cadence = 10.0*u.s
    resolution = Pair(1.0*u.arcsec/u.pixel,2.0*u.arcsec/u.pixel)
    fits_template = sunpy.map.header.MapMeta()
    fits_template['telescop'] = 'Hinode'
    fits_template['instrume'] = 'EIS'
    fits_template['detector'] = 'EIS'
    fits_template['waveunit'] = 'angstrom'

    def __init__(self,detector_file_dir,observing_time,observing_area=None):
        super().__init__(observing_time,observing_area)
        self._setup_from_file(detector_file_dir)

    def _setup_from_file(self,detector_file_dir):
        """
        Read instrument properties from files. This is a temporary solution and requires that the
        detector files all be collected into the same directory and be formatted in a specific way.

        .. warning:: This method will be modified once EIS response functions become
                    available in a different format.
        """
        eis_instr_files = glob.glob(os.path.join(detector_file_dir,'EIS_*_*.*.ins'))
        self.channels = []
        for eif in eis_instr_files:
            #extract some metadata from the filename
            base = os.path.splitext(os.path.basename(eif))[0]
            wave = float(base.split('_')[-1])*u.angstrom
            name = '{}_{}_{}'.format(base.split('_')[1][:2],base.split('_')[1][2:],
                                    wave.value)
            #read the response function from the file
            with open(eif,'r') as f:
                lines = f.readlines()
            resp_x,resp_y = np.empty(int(lines[0])),np.empty(int(lines[0]))
            for i in range(1,int(lines[0])+1):
                resp_x[i-1],resp_y[i-1] = list(filter(None,lines[i].split(' ')))
            self.channels.append({'wavelength':wave,'name':name,
                    'response':{'x':resp_x*u.angstrom,
                                'y':resp_y*u.count/u.pixel/u.photon*u.steradian*u.cm**2}})

        self.channels = sorted(self.channels,key=lambda x:x['wavelength'])

    def detect(self,loop,channel):
        """
        Calculate response of Hinode/EIS detector for given loop object.
        """
        # only interpolate once
        if not all([w in channel['response']['x'] for w in loop.wavelengths \
                    if channel['response']['x'][0] <= wavelength <= channel['response']['x'][-1]]):
            nots = splrep(channel['response']['x'].value,channel['response']['y'].value)
            tmp_x = np.sort(np.hstack([channel['response']['x'].value,loop.wavelengths]))
            channel['response']['y'] = splev(tmp_x,nots)*channel['response']['y'].unit
            channel['response']['x'] = tmp_x*channel['response']['x'].unit

        counts = np.zeros(loop.density.shape)
        for wavelength in loop.wavelengths:
            if wavelength in channel['response']['x']:
                counts += channel['response']['y'][np.argwhere(channel['response']['x']==wavelength)[0][0]].value*loop.get_emission(wavelength).value

        return counts*loop.get_emission(wavelength).unit*channel['response']['y'].unit
<|endoftext|>


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

class Shooter:
    def __init__(self, offset, xpos, dpi, comms, n, field = [22.3125, 45]):
        self.offsetpx = offset
        self.xpospx = xpos

        self.leftdeg = 0
        self.centerdeg = 45
        self.rightdeg = 90

        self.theta = 45
        self.aimval = 128
        self.shot = 0
        self.comms = comms
        self.number = n
        self.fieldpx = [field[0] * dpi, field[1] * dpi]

    def can_hit(self, target):
        return True

    def target2angle(self, target):
        opp = target[0] - self.xpospx
        adj = target[1] + self.offsetpx
        self.theta = self.centerdeg + math.degrees(math.atan(opp/adj))
        if self.theta <= self.leftdeg:
            self.theta = self.leftdeg
            self.aimval = 1
        elif self.theta >= self.rightdeg:
            self.theta = self.rightdeg
            self.aimval = 128
        else:
            self.aimval = int((17.0/6) * self.theta)
        print "shooter " + self.number + " aimed at theta " + str(self.theta)
        return self.aimval

    def get_aim_line(self, line_length = 300):
        angle = self.centerdeg - self.theta # + for cw of straight; - for ccw
        print self.number + " in get_aim_line angle is " + str(angle)
        y1 = self.fieldpx[1]
        # triangle not visible in img. adj is offset and opposite is where
        # barrel intersects line, since point where angle measured is pivot
        x1add = int(round(math.tan(math.radians(angle)))) * self.offsetpx
        print "adding " + str(x1add) + " to x1"
        x1 = self.xpospx + x1add
        # aim is hypotenuse of triangle on board, where near angle is 90 - angle
        # y is opposite from that and x is x1 + adjacent
        y2sub = int(round(math.sin(math.radians(90 - angle)))) * line_length
        print "subtracting " + str(y2sub) + " from y2"
        y2 = self.fieldpx[1] - y2sub
        x2add = int(round(math.cos(math.radians(90 - angle)))) * line_length
        print "adding " + str(x2add) + " to x2"
        x2 = x1 + x2add
        return ((x1, y1), (x2, y2))

    def aim(self, target):
        if self.can_hit(target):
            self.aimval = self.target2angle(target)
            self.comms.aim(self.number, bin(self.aimval))

    def fire(self):
        self.comms.fire(self.number)

    def shoot(self, target):
        self.aim(target)
        self.fire()
<commit_msg>cast to float fixes jerky shooter movement. also draw line 100 not 300px<commit_after>#! /usr/bin/env python
import math

class Shooter:
    def __init__(self, offset, xpos, dpi, comms, n, field = [22.3125, 45]):
        self.offsetpx = offset
        self.xpospx = xpos

        self.leftdeg = 0
        self.centerdeg = 45
        self.rightdeg = 90

        self.theta = 45
        self.aimval = 128
        self.shot = 0
        self.comms = comms
        self.number = n
        self.fieldpx = [field[0] * dpi, field[1] * dpi]

    def can_hit(self, target):
        return True

    def target2angle(self, target):
        print self.number + " in TARGET2ANGLE"
        opp = float(target[0] - self.xpospx)
        adj = float(target[1] + self.offsetpx)
        self.theta = self.centerdeg + math.degrees(math.atan(opp/adj))
        if self.theta <= self.leftdeg:
            self.theta = self.leftdeg
            self.aimval = 1
        elif self.theta >= self.rightdeg:
            self.theta = self.rightdeg
            self.aimval = 128
        else:
            self.aimval = int((17.0/6) * self.theta)
        print "shooter " + self.number + " aimed at theta " + str(self.theta)
        return self.aimval

    def get_aim_line(self, line_length = 100):
        angle = self.centerdeg - self.theta # + for cw of straight; - for ccw
        #print self.number + " in get_aim_line angle is " + str(angle)
        y1 = self.fieldpx[1]
        # triangle not visible in img. adj is offset and opposite is where
        # barrel intersects line, since point where angle measured is pivot
        x1add = int((math.tan(math.radians(angle))) * self.offsetpx)
        #print "adding " + str(x1add) + " to x1"
        x1 = self.xpospx + x1add
        # aim is hypotenuse of triangle on board, where near angle is 90 - angle
        # y is opposite from that and x is x1 + adjacent
        y2sub = int((math.sin(math.radians(90 - angle)) + .01) * line_length)
        #print "subtracting " + str(y2sub) + " from y2"
        y2 = self.fieldpx[1] - y2sub
        x2add = int((math.cos(math.radians(90 - angle)) + .01) * line_length)
        #print "adding " + str(x2add) + " to x2"
        x2 = x1 + x2add
        return ((x1, y1), (x2, y2))

    def aim(self, target):
        self.aimval = self.target2angle(target)
        self.comms.aim(self.number, bin(self.aimval))

    def fire(self):
        self.comms.fire(self.number)

    def shoot(self, target):
        self.aim(target)
        self.fire()
<|endoftext|>


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

import os
import logging
from threading import Lock
from flask import Flask, Response, jsonify, request, make_response, json, url_for

# Create Flask application
app = Flask(__name__)
app.config['LOGGING_LEVEL'] = logging.INFO

# Status Codes
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_204_NO_CONTENT = 204
HTTP_400_BAD_REQUEST = 400
HTTP_404_NOT_FOUND = 404
HTTP_409_CONFLICT = 409

# Lock for thread-safe counter increment
lock = Lock()

######################################################################
# Data Store, pre-populated with sample data
######################################################################
shopping_carts = [
    {
        'uid':1,
        'sid':  1,
        'products': [
            {
                'sku': 123456780,
                'quantity': 2,
                'name': "Settlers of Catan",
                'unitprice': 27.99
            },
            {
                'sku': 876543210,
                'quantity': 1,
                'name': "Risk",
                'unitprice': 27.99
            }
        ]
    },
    {
        'uid':2,
        'sid':  2,
        'products': []
    },
    {
        'uid': 3,
        'sid': 3,
        'products': [
            {
                'sku': 114672050,
                'quantity': 1,
                'name': "Game of Life",
                'unitprice': 13.99
            }
        ]
    },
]

current_shopping_cart_id = 4

######################################################################
# GET INDEX
######################################################################
@app.route('/')
def index():
    shopcarts_url = request.base_url + "shopcarts"
    return make_response(jsonify(name='Shopcart Demo REST API Service v1.0',
                   version='1.0',
                   url=shopcarts_url
                   ), HTTP_200_OK)

######################################################################
# LIST ALL SHOPCARTS FOR ALL USERS
######################################################################
#USAGE: /shopcarts or /shopcarts?sid=1 for quering for a user
@app.route('/shopcarts', methods=['GET'])
def list_shopcarts():
    results=[]
    sid=request.args.get('sid')
    if sid:
        #Extra check for query input
        try:
            sid = int(sid)
        except ValueError:
            return make_response(jsonify(shopping_carts), HTTP_200_OK)

        results=[cart for cart in shopping_carts if cart['sid']==int(sid)]
        if len(results)==0:
            results=shopping_carts
        else:

            if len(results[0]['products'])==0:
                results='The cart contains no products'
            else:
                results=results[0]['products']
    else:
        results=shopping_carts

    return make_response(jsonify(results), HTTP_200_OK)

######################################################################
# RETRIEVE A USER'S CART
######################################################################
#USAGE: /shopcarts/3
@app.route('/shopcarts/<int:sid>', methods=['GET'])
def get_shopcart(sid):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    if len(carts) > 0:
        message = carts[0]['products']
        if not message:
            message='The cart contains no products'
        rc = HTTP_200_OK
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND

    return make_response(jsonify(message), rc)

######################################################################
# RETRIEVE USER'S PRODUCTS LIST IN THE CART
######################################################################
#USAGE: /shopcarts/3/products or /shopcarts/3/products?sku=114672050 for querying for a product
@app.route('/shopcarts/<int:sid>/products', methods=['GET'])
def get_products(sid):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    sku = request.args.get('sku')
    if len(carts) > 0:
        products = carts[0]['products']
        if(len(products)==0):
            message='The cart contains no products'
        else:
            if sku:
                #Extra check for query input
                try:
                    sku = int(sku)
                except ValueError:
                    return make_response(jsonify(products), HTTP_200_OK)

                message=[product for product in products if product['sku']==int(sku)]
                if len(message)==0:
                    message=products
                else:
                    message=message[0]
            else:
                message=products
        rc = HTTP_200_OK
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND

    return make_response(jsonify(message), rc)

######################################################################
# RETRIEVE A PRODUCT FROM USER'S SHOPCART
######################################################################
#USAGE: /shopcarts/3/products/114672050
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['GET'])
def get_product(sid,sku):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    if(len(carts)==0):
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        return make_response(jsonify(message),HTTP_404_NOT_FOUND)
    else:
        products=[product for product in carts[0]['products'] if product['sku']==sku]
        if(len(products)==0):
            message = { 'error' : 'Product with sku: %s was not found in the cart for user %s' % (str(sku), str(sid))}
            return make_response(jsonify(message),HTTP_404_NOT_FOUND)
        else:
            return make_response(jsonify(products[0]), HTTP_200_OK)

######################################################################
# ADD A NEW SHOPPING CART
######################################################################
@app.route('/shopcarts', methods=['POST'])
def create_shopcarts():
    payload = request.get_json()
    if is_validShoppingCart(payload):
        id = next_sid()
        if 'products' not in payload:
            payload['products'] = []
        shopcart = {'uid': payload['uid'],'sid': id, 'products': payload['products']}
        shopping_carts.append(shopcart)
        message = shopcart
        rc = HTTP_201_CREATED
    else:
        message = { 'error' : 'Data is not valid' }
        rc = HTTP_400_BAD_REQUEST

    response = make_response(jsonify(message), rc)
    if rc == HTTP_201_CREATED:
        response.headers['Location'] = url_for('get_shopcart', sid=id)
    return response

######################################################################
# ADD A NEW PRODUCT IN A SHOPPING CART
######################################################################
@app.route('/shopcarts/<int:sid>/products', methods=['POST'])
def create_products(sid):
    cart = [cart for cart in shopping_carts if cart['sid']==sid]
    if len(cart) > 0:
        payload = request.get_json()
        if is_validProduct(payload):
            for i in range(0,len(payload['products'])):
                product = {'sku': payload['products'][i]['sku'],'quantity': payload['products'][i]['quantity'], 'name': payload['products'][i]['name'], 'unitprice' : payload['products'][i]['unitprice']}
                cart[0]['products'].append(product)
            message = cart[0]
            rc = HTTP_201_CREATED
        else:
            message = { 'error' : 'Data is not valid' }
            rc = HTTP_400_BAD_REQUEST

        response = make_response(jsonify(message), rc)
        if rc == HTTP_201_CREATED:
            response.headers['Location'] = url_for('get_product', sku = payload['sku'], sid=shopping_carts[cart[0].sid])
        return response
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND
        return make_response(jsonify(message), rc)

######################################################################
# UPDATE product in a shopping cart
######################################################################
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['PUT'])
def put_product(sid, sku):
    cart = [cart for cart in shopping_carts if cart['sid'] == sid]
    if len(cart) > 0:
        payload = request.get_json()
        products = payload['products']

        if is_validProduct(payload) and len(products) == 1:
            updated_product = {'sku': products[0]['sku'], 'quantity': products[0]['quantity'], 'name': products[0]['name'], 'unitprice': products[0]['unitprice']}
            print(updated_product)

            found_product = False
            for i in range(len(cart[0]['products'])):
                product = cart[0]['products'][i]
                if product['sku'] == sku:
                    cart[0]['products'][i] = updated_product
                    found_product = True
                    break

            if found_product:
                message = cart[0]
                rc = HTTP_200_OK
            else:
                message = { 'error' : 'Product %s was not found in shopping cart %s' % (str(sku), str(sid)) }
                rc = HTTP_404_NOT_FOUND
        else:
            message = { 'error' : 'Product data is not valid' }
            rc = HTTP_400_BAD_REQUEST

        response = make_response(jsonify(message), rc)

        if rc == HTTP_201_CREATED:
            response.headers['Location'] = url_for('put_product', sku = payload['sku'], sid=shopping_carts[cart[0].sid])
        return response

    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND
        return make_response(jsonify(message), rc)

######################################################################
# DELETE A PRODUCT FROM A SHOPPING CART
######################################################################
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['DELETE'])
def delete_products(sid,sku):
    for i in range(len(shopping_carts)):
    	if shopping_carts[i]['sid'] == sid:
    	    del shopping_carts[i]
    	    break
    return '', HTTP_204_NO_CONTENT

######################################################################
# DELETE A PRODUCT FROM A SHOPPING CART
######################################################################
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['DELETE'])
def delete_products(sid,sku):
    for i in range(len(shopping_carts)):
    	if shopping_carts[i]['sid'] == sid:
    	    for j in range(len(shopping_carts[i]['products'])):
    	    	if shopping_carts[i]['products'][j]['sku'] == sku:
    	    		del shopping_carts[i]['products'][j]
    	    		break
    return '', HTTP_204_NO_CONTENT

######################################################################
#  U T I L I T Y   F U N C T I O N S
######################################################################
def next_sid():
    global current_shopping_cart_id
    with lock:
        current_shopping_cart_id += 1
    return current_shopping_cart_id

def is_validProduct(data):
    valid = False
    try:
        for i in range(0,len(data['products'])):
            sku = data['products'][i]['sku']
            quantity = data['products'][i]['quantity']
            name = data['products'][i]['name']
            unitprice = data['products'][i]['unitprice']
        valid = True
    except KeyError as err:
        app.logger.warn('Missing parameter error: %s', err)
    except TypeError as err:
        app.logger.warn('Invalid Content Type error: %s', err)

    return valid

def is_validShoppingCart(data):
    valid = False
    try:
        user_id = data['uid']
        valid = True
    except KeyError as err:
        app.logger.warn('Missing parameter error: %s', err)
    except TypeError as err:
        app.logger.warn('Invalid Content Type error: %s', err)

    return valid

@app.before_first_request
def setup_logging():
    if not app.debug:
        # In production mode, add log handler to sys.stderr.
        handler = logging.StreamHandler()
        handler.setLevel(app.config['LOGGING_LEVEL'])
        # formatter = logging.Formatter(app.config['LOGGING_FORMAT'])
        #'%Y-%m-%d %H:%M:%S'
        formatter = logging.Formatter('[%(asctime)s] - %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')
        handler.setFormatter(formatter)
        app.logger.addHandler(handler)

######################################################################
#   M A I N
######################################################################
if __name__ == "__main__":
    # Pull options from environment
    debug = (os.getenv('DEBUG', 'False') == 'True')
    port = os.getenv('PORT', '8888')
    app.run(host='0.0.0.0', port=int(port), debug=debug)
<commit_msg>Resolving conflicts<commit_after># Copyright 2016, 2017 Echo Squad. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import logging
from threading import Lock
from flask import Flask, Response, jsonify, request, make_response, json, url_for

# Create Flask application
app = Flask(__name__)
app.config['LOGGING_LEVEL'] = logging.INFO

# Status Codes
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_204_NO_CONTENT = 204
HTTP_400_BAD_REQUEST = 400
HTTP_404_NOT_FOUND = 404
HTTP_409_CONFLICT = 409

# Lock for thread-safe counter increment
lock = Lock()

######################################################################
# Data Store, pre-populated with sample data
######################################################################
shopping_carts = [
    {
        'uid':1,
        'sid':  1,
        'products': [
            {
                'sku': 123456780,
                'quantity': 2,
                'name': "Settlers of Catan",
                'unitprice': 27.99
            },
            {
                'sku': 876543210,
                'quantity': 1,
                'name': "Risk",
                'unitprice': 27.99
            }
        ]
    },
    {
        'uid':2,
        'sid':  2,
        'products': []
    },
    {
        'uid': 3,
        'sid': 3,
        'products': [
            {
                'sku': 114672050,
                'quantity': 1,
                'name': "Game of Life",
                'unitprice': 13.99
            }
        ]
    },
]

current_shopping_cart_id = 4

######################################################################
# GET INDEX
######################################################################
@app.route('/')
def index():
    shopcarts_url = request.base_url + "shopcarts"
    return make_response(jsonify(name='Shopcart Demo REST API Service v1.0',
                   version='1.0',
                   url=shopcarts_url
                   ), HTTP_200_OK)

######################################################################
# LIST ALL SHOPCARTS FOR ALL USERS
######################################################################
#USAGE: /shopcarts or /shopcarts?sid=1 for quering for a user
@app.route('/shopcarts', methods=['GET'])
def list_shopcarts():
    results=[]
    sid=request.args.get('sid')
    if sid:
        #Extra check for query input
        try:
            sid = int(sid)
        except ValueError:
            return make_response(jsonify(shopping_carts), HTTP_200_OK)

        results=[cart for cart in shopping_carts if cart['sid']==int(sid)]
        if len(results)==0:
            results=shopping_carts
        else:

            if len(results[0]['products'])==0:
                results='The cart contains no products'
            else:
                results=results[0]['products']
    else:
        results=shopping_carts

    return make_response(jsonify(results), HTTP_200_OK)

######################################################################
# RETRIEVE A USER'S CART
######################################################################
#USAGE: /shopcarts/3
@app.route('/shopcarts/<int:sid>', methods=['GET'])
def get_shopcart(sid):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    if len(carts) > 0:
        message = carts[0]['products']
        if not message:
            message='The cart contains no products'
        rc = HTTP_200_OK
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND

    return make_response(jsonify(message), rc)

######################################################################
# RETRIEVE USER'S PRODUCTS LIST IN THE CART
######################################################################
#USAGE: /shopcarts/3/products or /shopcarts/3/products?sku=114672050 for querying for a product
@app.route('/shopcarts/<int:sid>/products', methods=['GET'])
def get_products(sid):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    sku = request.args.get('sku')
    if len(carts) > 0:
        products = carts[0]['products']
        if(len(products)==0):
            message='The cart contains no products'
        else:
            if sku:
                #Extra check for query input
                try:
                    sku = int(sku)
                except ValueError:
                    return make_response(jsonify(products), HTTP_200_OK)

                message=[product for product in products if product['sku']==int(sku)]
                if len(message)==0:
                    message=products
                else:
                    message=message[0]
            else:
                message=products
        rc = HTTP_200_OK
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND

    return make_response(jsonify(message), rc)

######################################################################
# RETRIEVE A PRODUCT FROM USER'S SHOPCART
######################################################################
#USAGE: /shopcarts/3/products/114672050
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['GET'])
def get_product(sid,sku):
    carts = [cart for cart in shopping_carts if cart['sid']==sid]
    if(len(carts)==0):
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        return make_response(jsonify(message),HTTP_404_NOT_FOUND)
    else:
        products=[product for product in carts[0]['products'] if product['sku']==sku]
        if(len(products)==0):
            message = { 'error' : 'Product with sku: %s was not found in the cart for user %s' % (str(sku), str(sid))}
            return make_response(jsonify(message),HTTP_404_NOT_FOUND)
        else:
            return make_response(jsonify(products[0]), HTTP_200_OK)

######################################################################
# ADD A NEW SHOPPING CART
######################################################################
@app.route('/shopcarts', methods=['POST'])
def create_shopcarts():
    payload = request.get_json()
    if is_validShoppingCart(payload):
        id = next_sid()
        if 'products' not in payload:
            payload['products'] = []
        shopcart = {'uid': payload['uid'],'sid': id, 'products': payload['products']}
        shopping_carts.append(shopcart)
        message = shopcart
        rc = HTTP_201_CREATED
    else:
        message = { 'error' : 'Data is not valid' }
        rc = HTTP_400_BAD_REQUEST

    response = make_response(jsonify(message), rc)
    if rc == HTTP_201_CREATED:
        response.headers['Location'] = url_for('get_shopcart', sid=id)
    return response

######################################################################
# ADD A NEW PRODUCT IN A SHOPPING CART
######################################################################
@app.route('/shopcarts/<int:sid>/products', methods=['POST'])
def create_products(sid):
    cart = [cart for cart in shopping_carts if cart['sid']==sid]
    if len(cart) > 0:
        payload = request.get_json()
        if is_validProduct(payload):
            for i in range(0,len(payload['products'])):
                product = {'sku': payload['products'][i]['sku'],'quantity': payload['products'][i]['quantity'], 'name': payload['products'][i]['name'], 'unitprice' : payload['products'][i]['unitprice']}
                cart[0]['products'].append(product)
            message = cart[0]
            rc = HTTP_201_CREATED
        else:
            message = { 'error' : 'Data is not valid' }
            rc = HTTP_400_BAD_REQUEST

        response = make_response(jsonify(message), rc)
        if rc == HTTP_201_CREATED:
            response.headers['Location'] = url_for('get_product', sku = payload['sku'], sid=shopping_carts[cart[0].sid])
        return response
    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND
        return make_response(jsonify(message), rc)

######################################################################
# UPDATE product in a shopping cart
######################################################################
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['PUT'])
def put_product(sid, sku):
    cart = [cart for cart in shopping_carts if cart['sid'] == sid]
    if len(cart) > 0:
        payload = request.get_json()
        products = payload['products']

        if is_validProduct(payload) and len(products) == 1:
            updated_product = {'sku': products[0]['sku'], 'quantity': products[0]['quantity'], 'name': products[0]['name'], 'unitprice': products[0]['unitprice']}
            print(updated_product)

            found_product = False
            for i in range(len(cart[0]['products'])):
                product = cart[0]['products'][i]
                if product['sku'] == sku:
                    cart[0]['products'][i] = updated_product
                    found_product = True
                    break

            if found_product:
                message = cart[0]
                rc = HTTP_200_OK
            else:
                message = { 'error' : 'Product %s was not found in shopping cart %s' % (str(sku), str(sid)) }
                rc = HTTP_404_NOT_FOUND
        else:
            message = { 'error' : 'Product data is not valid' }
            rc = HTTP_400_BAD_REQUEST

        response = make_response(jsonify(message), rc)

        if rc == HTTP_201_CREATED:
            response.headers['Location'] = url_for('put_product', sku = payload['sku'], sid=shopping_carts[cart[0].sid])
        return response

    else:
        message = { 'error' : 'Shopping Cart with id: %s was not found' % str(sid) }
        rc = HTTP_404_NOT_FOUND
        return make_response(jsonify(message), rc)

######################################################################
# DELETE A PRODUCT FROM A SHOPPING CART
######################################################################
@app.route('/shopcarts/<int:sid>/products/<int:sku>', methods=['DELETE'])
def delete_products(sid,sku):
    for i in range(len(shopping_carts)):
    	if shopping_carts[i]['sid'] == sid:
    	    for j in range(len(shopping_carts[i]['products'])):
    	    	if shopping_carts[i]['products'][j]['sku'] == sku:
    	    		del shopping_carts[i]['products'][j]
    	    		break
    return '', HTTP_204_NO_CONTENT

######################################################################
#  U T I L I T Y   F U N C T I O N S
######################################################################
def next_sid():
    global current_shopping_cart_id
    with lock:
        current_shopping_cart_id += 1
    return current_shopping_cart_id

def is_validProduct(data):
    valid = False
    try:
        for i in range(0,len(data['products'])):
            sku = data['products'][i]['sku']
            quantity = data['products'][i]['quantity']
            name = data['products'][i]['name']
            unitprice = data['products'][i]['unitprice']
        valid = True
    except KeyError as err:
        app.logger.warn('Missing parameter error: %s', err)
    except TypeError as err:
        app.logger.warn('Invalid Content Type error: %s', err)

    return valid

def is_validShoppingCart(data):
    valid = False
    try:
        user_id = data['uid']
        valid = True
    except KeyError as err:
        app.logger.warn('Missing parameter error: %s', err)
    except TypeError as err:
        app.logger.warn('Invalid Content Type error: %s', err)

    return valid

@app.before_first_request
def setup_logging():
    if not app.debug:
        # In production mode, add log handler to sys.stderr.
        handler = logging.StreamHandler()
        handler.setLevel(app.config['LOGGING_LEVEL'])
        # formatter = logging.Formatter(app.config['LOGGING_FORMAT'])
        #'%Y-%m-%d %H:%M:%S'
        formatter = logging.Formatter('[%(asctime)s] - %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')
        handler.setFormatter(formatter)
        app.logger.addHandler(handler)

######################################################################
#   M A I N
######################################################################
if __name__ == "__main__":
    # Pull options from environment
    debug = (os.getenv('DEBUG', 'False') == 'True')
    port = os.getenv('PORT', '8888')
    app.run(host='0.0.0.0', port=int(port), debug=debug)
<|endoftext|>


<commit_before>from django.utils.translation import ugettext_lazy as _

from oscar.apps.basket import signals
from oscar.core.loading import get_model, get_class

from rest_framework import status, generics, exceptions
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView

from oscarapi import serializers, permissions
from oscarapi.basket.operations import (
    apply_offers,
    get_basket
)
from oscarapi.views.mixin import PutIsPatchMixin
from oscarapi.views.utils import BasketPermissionMixin

__all__ = ('BasketView', 'LineList', 'LineDetail', 'AddProductView',
           'add_voucher', 'shipping_methods')

Basket = get_model('basket', 'Basket')
Line = get_model('basket', 'Line')
Repository = get_class('shipping.repository', 'Repository')

class BasketView(APIView):
    """
    Api for retrieving a user's basket.

    GET:
    Retrieve your basket.
    """
    def get(self, request, format=None):
        basket = get_basket(request)
        ser = serializers.BasketSerializer(basket,
                                           context={'request': request})
        return Response(ser.data)

class AddProductView(APIView):
    """
    Add a certain quantity of a product to the basket.

    POST(url, quantity)
    {
        "url": "http://testserver.org/oscarapi/products/209/",
        "quantity": 6
    }

    If you've got some options to configure for the product to add to the
    basket, you should pass the optional ``options`` property:
    {
        "url": "http://testserver.org/oscarapi/products/209/",
        "quantity": 6,
        "options": [{
            "option": "http://testserver.org/oscarapi/options/1/",
            "value": "some value"
        }]
    }
    """
    def validate(self, basket, product, quantity):
        availability = basket.strategy.fetch_for_product(
            product).availability

        # check if product is available at all
        if not availability.is_available_to_buy:
            return False, availability.message

        # check if we can buy this quantity
        allowed, message = availability.is_purchase_permitted(quantity)
        if not allowed:
            return False, message

        # check if there is a limit on amount
        allowed, message = basket.is_quantity_allowed(quantity)
        if not allowed:
            return False, quantity
        return True, None

    def post(self, request, format=None):
        p_ser = serializers.AddProductSerializer(
            data=request.DATA, context={'request': request})
        if p_ser.is_valid():
            basket = get_basket(request)
            product = p_ser.object['url']
            quantity = p_ser.object['quantity']
            options = p_ser.object.get('options', [])

            basket_valid, message = self.validate(basket, product, quantity)
            if not basket_valid:
                return Response(
                    {'reason': message},
                    status=status.HTTP_406_NOT_ACCEPTABLE)

            basket.add_product(product, quantity=quantity, options=options)
            apply_offers(request, basket)
            ser = serializers.BasketSerializer(
                basket, context={'request': request})
            return Response(ser.data)

        return Response(
            {'reason': p_ser.errors}, status=status.HTTP_406_NOT_ACCEPTABLE)

@api_view(('POST',))
def add_voucher(request, format=None):
    """
    Add a voucher to the basket.

    POST(vouchercode)
    {
        "vouchercode": "kjadjhgadjgh7667"
    }

    Will return 200 and the voucher as json if succesful.
    If unsuccessful, will return 406 with the error.
    """
    v_ser = serializers.VoucherAddSerializer(data=request.DATA,
                                             context={'request': request})
    if v_ser.is_valid():
        basket = get_basket(request)
        voucher = v_ser.object
        basket.vouchers.add(voucher)

        signals.voucher_addition.send(
            sender=None, basket=basket, voucher=voucher)

        # Recalculate discounts to see if the voucher gives any
        apply_offers(request, basket)
        discounts_after = basket.offer_applications

        # Look for discounts from this new voucher
        for discount in discounts_after:
            if discount['voucher'] and discount['voucher'] == voucher:
                break
        else:
            basket.vouchers.remove(voucher)
            return Response(
                {'reason': _(
                    "Your basket does not qualify for a voucher discount")},
                status=status.HTTP_406_NOT_ACCEPTABLE)

        ser = serializers.VoucherSerializer(
            voucher, context={'request': request})
        return Response(ser.data)

    return Response(v_ser.errors, status=status.HTTP_406_NOT_ACCEPTABLE)

@api_view(('GET',))
def shipping_methods(request, format=None):
    """
    Get the available shipping methods and their cost for this order.

    GET:
    A list of shipping method details and the prices.
    """
    basket = get_basket(request)
    shiping_methods = Repository().get_shipping_methods(
        basket=request.basket, user=request.user,
        request=request)
    ser = serializers.ShippingMethodSerializer(
        shiping_methods, many=True, context={'basket': basket})
    return Response(ser.data)

class LineList(BasketPermissionMixin, generics.ListCreateAPIView):
    """
    Api for adding lines to a basket.

    Permission will be checked,
    Regular users may only access their own basket,
    staff users may access any basket.

    GET:
    A list of basket lines.

    POST(basket, line_reference, product, stockrecord,
         quantity, price_currency, price_excl_tax, price_incl_tax):
    Add a line to the basket, example::

        {
            "basket": "http://127.0.0.1:8000/oscarapi/baskets/100/",
            "line_reference": "234_345",
            "product": "http://127.0.0.1:8000/oscarapi/products/209/",
            "stockrecord":
                "http://127.0.0.1:8000/oscarapi/stockrecords/100/",
            "quantity": 3,
            "price_currency": "EUR",
            "price_excl_tax": "100.0",
            "price_incl_tax": "121.0"
        }
    """
    queryset = Line.objects.all()
    serializer_class = serializers.LineSerializer

    def get(self, request, pk=None, format=None):
        if pk is not None:
            self.check_basket_permission(request, pk)
            self.queryset = self.queryset.filter(basket__id=pk)
        elif not request.user.is_staff:
            self.permission_denied(request)

        return super(LineList, self).get(request, format)

    def post(self, request, pk=None, format=None):
        data_basket = self.get_data_basket(request.DATA, format)
        self.check_basket_permission(request, basket=data_basket)

        if pk is not None:
            url_basket = self.check_basket_permission(request, basket_pk=pk)
            if url_basket != data_basket:
                raise exceptions.NotAcceptable(
                    _('Target basket inconsistent %s != %s') % (
                        url_basket.pk, data_basket.pk
                    )
                )
        elif not request.user.is_staff:
            self.permission_denied(request)

        return super(LineList, self).post(request, format=format)

class LineDetail(PutIsPatchMixin, generics.RetrieveUpdateDestroyAPIView):
    queryset = Line.objects.all()
    serializer_class = serializers.LineSerializer
    permission_classes = (permissions.IsAdminUserOrRequestContainsLine,)
<commit_msg>.object is now deprecated and replaced with .validated_data<commit_after>from django.utils.translation import ugettext_lazy as _

from oscar.apps.basket import signals
from oscar.core.loading import get_model, get_class

from rest_framework import status, generics, exceptions
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView

from oscarapi import serializers, permissions
from oscarapi.basket.operations import (
    apply_offers,
    get_basket
)
from oscarapi.views.mixin import PutIsPatchMixin
from oscarapi.views.utils import BasketPermissionMixin

__all__ = ('BasketView', 'LineList', 'LineDetail', 'AddProductView',
           'add_voucher', 'shipping_methods')

Basket = get_model('basket', 'Basket')
Line = get_model('basket', 'Line')
Repository = get_class('shipping.repository', 'Repository')

class BasketView(APIView):
    """
    Api for retrieving a user's basket.

    GET:
    Retrieve your basket.
    """
    def get(self, request, format=None):
        basket = get_basket(request)
        ser = serializers.BasketSerializer(basket,
                                           context={'request': request})
        return Response(ser.data)

class AddProductView(APIView):
    """
    Add a certain quantity of a product to the basket.

    POST(url, quantity)
    {
        "url": "http://testserver.org/oscarapi/products/209/",
        "quantity": 6
    }

    If you've got some options to configure for the product to add to the
    basket, you should pass the optional ``options`` property:
    {
        "url": "http://testserver.org/oscarapi/products/209/",
        "quantity": 6,
        "options": [{
            "option": "http://testserver.org/oscarapi/options/1/",
            "value": "some value"
        }]
    }
    """
    def validate(self, basket, product, quantity):
        availability = basket.strategy.fetch_for_product(
            product).availability

        # check if product is available at all
        if not availability.is_available_to_buy:
            return False, availability.message

        # check if we can buy this quantity
        allowed, message = availability.is_purchase_permitted(quantity)
        if not allowed:
            return False, message

        # check if there is a limit on amount
        allowed, message = basket.is_quantity_allowed(quantity)
        if not allowed:
            return False, quantity
        return True, None

    def post(self, request, format=None):
        p_ser = serializers.AddProductSerializer(
            data=request.DATA, context={'request': request})
        if p_ser.is_valid():
            basket = get_basket(request)
            product = p_ser.validated_data['url']
            quantity = p_ser.validated_data['quantity']
            options = p_ser.validated_data.get('options', [])

            basket_valid, message = self.validate(basket, product, quantity)
            if not basket_valid:
                return Response(
                    {'reason': message},
                    status=status.HTTP_406_NOT_ACCEPTABLE)

            basket.add_product(product, quantity=quantity, options=options)
            apply_offers(request, basket)
            ser = serializers.BasketSerializer(
                basket, context={'request': request})
            return Response(ser.data)

        return Response(
            {'reason': p_ser.errors}, status=status.HTTP_406_NOT_ACCEPTABLE)

@api_view(('POST',))
def add_voucher(request, format=None):
    """
    Add a voucher to the basket.

    POST(vouchercode)
    {
        "vouchercode": "kjadjhgadjgh7667"
    }

    Will return 200 and the voucher as json if succesful.
    If unsuccessful, will return 406 with the error.
    """
    v_ser = serializers.VoucherAddSerializer(data=request.DATA,
                                             context={'request': request})
    if v_ser.is_valid():
        basket = get_basket(request)
        voucher = v_ser.object
        basket.vouchers.add(voucher)

        signals.voucher_addition.send(
            sender=None, basket=basket, voucher=voucher)

        # Recalculate discounts to see if the voucher gives any
        apply_offers(request, basket)
        discounts_after = basket.offer_applications

        # Look for discounts from this new voucher
        for discount in discounts_after:
            if discount['voucher'] and discount['voucher'] == voucher:
                break
        else:
            basket.vouchers.remove(voucher)
            return Response(
                {'reason': _(
                    "Your basket does not qualify for a voucher discount")},
                status=status.HTTP_406_NOT_ACCEPTABLE)

        ser = serializers.VoucherSerializer(
            voucher, context={'request': request})
        return Response(ser.data)

    return Response(v_ser.errors, status=status.HTTP_406_NOT_ACCEPTABLE)

@api_view(('GET',))
def shipping_methods(request, format=None):
    """
    Get the available shipping methods and their cost for this order.

    GET:
    A list of shipping method details and the prices.
    """
    basket = get_basket(request)
    shiping_methods = Repository().get_shipping_methods(
        basket=request.basket, user=request.user,
        request=request)
    ser = serializers.ShippingMethodSerializer(
        shiping_methods, many=True, context={'basket': basket})
    return Response(ser.data)

class LineList(BasketPermissionMixin, generics.ListCreateAPIView):
    """
    Api for adding lines to a basket.

    Permission will be checked,
    Regular users may only access their own basket,
    staff users may access any basket.

    GET:
    A list of basket lines.

    POST(basket, line_reference, product, stockrecord,
         quantity, price_currency, price_excl_tax, price_incl_tax):
    Add a line to the basket, example::

        {
            "basket": "http://127.0.0.1:8000/oscarapi/baskets/100/",
            "line_reference": "234_345",
            "product": "http://127.0.0.1:8000/oscarapi/products/209/",
            "stockrecord":
                "http://127.0.0.1:8000/oscarapi/stockrecords/100/",
            "quantity": 3,
            "price_currency": "EUR",
            "price_excl_tax": "100.0",
            "price_incl_tax": "121.0"
        }
    """
    queryset = Line.objects.all()
    serializer_class = serializers.LineSerializer

    def get(self, request, pk=None, format=None):
        if pk is not None:
            self.check_basket_permission(request, pk)
            self.queryset = self.queryset.filter(basket__id=pk)
        elif not request.user.is_staff:
            self.permission_denied(request)

        return super(LineList, self).get(request, format)

    def post(self, request, pk=None, format=None):
        data_basket = self.get_data_basket(request.DATA, format)
        self.check_basket_permission(request, basket=data_basket)

        if pk is not None:
            url_basket = self.check_basket_permission(request, basket_pk=pk)
            if url_basket != data_basket:
                raise exceptions.NotAcceptable(
                    _('Target basket inconsistent %s != %s') % (
                        url_basket.pk, data_basket.pk
                    )
                )
        elif not request.user.is_staff:
            self.permission_denied(request)

        return super(LineList, self).post(request, format=format)

class LineDetail(PutIsPatchMixin, generics.RetrieveUpdateDestroyAPIView):
    queryset = Line.objects.all()
    serializer_class = serializers.LineSerializer
    permission_classes = (permissions.IsAdminUserOrRequestContainsLine,)
<|endoftext|>


<commit_before># MIT License
# Copyright (c) 2017 MassChallenge, Inc.

from .allocator_factory import AllocatorFactory
from .application_answer_factory import ApplicationAnswerFactory
from .application_factory import ApplicationFactory
from .application_panel_assignment_factory import (
    ApplicationPanelAssignmentFactory,
)
from .application_question_factory import ApplicationQuestionFactory
from .application_type_factory import ApplicationTypeFactory
from .base_profile_factory import BaseProfileFactory
from .bucket_state_factory import BucketStateFactory
from .clearance_factory import ClearanceFactory
from .content_type_factory import ContentTypeFactory
from .core_profile_factory import CoreProfileFactory
from .criterion_factory import CriterionFactory
from .criterion_option_spec_factory import CriterionOptionSpecFactory
from .currency_factory import CurrencyFactory
from .entrepreneur_factory import EntrepreneurFactory
from .entrepreneur_profile_factory import EntrepreneurProfileFactory
from .expert_category_factory import ExpertCategoryFactory
from .expert_factory import ExpertFactory
# Late Loading Factories
# These fail if put in alphabetical order in the above list
# presumably due to their SubFactories.
from .expert_interest_factory import ExpertInterestFactory
from .expert_interest_type_factory import ExpertInterestTypeFactory
from .expert_profile_factory import ExpertProfileFactory
# Other utility methods
from .factory_utils import expert_data
from .functional_expertise_factory import FunctionalExpertiseFactory
from .group_factory import GroupFactory
from .industry_factory import IndustryFactory
from .interest_category_factory import InterestCategoryFactory
from .job_posting_factory import JobPostingFactory
from .judge_application_feedback_factory import JudgeApplicationFeedbackFactory
from .judge_availability_factory import JudgeAvailabilityFactory
from .judge_feedback_component_factory import JudgeFeedbackComponentFactory
from .judge_panel_assignment_factory import JudgePanelAssignmentFactory
from .judge_round_commitment_factory import JudgeRoundCommitmentFactory
from .judging_form_element_factory import JudgingFormElementFactory
from .judging_form_factory import JudgingFormFactory
from .judging_round_factory import JudgingRoundFactory
from .location_factory import LocationFactory
from .member_factory import MemberFactory
from .member_profile_factory import MemberProfileFactory
from .mentor_program_office_hour_factory import (
    MentorProgramOfficeHourFactory,
)
from .mentoring_specialties_factory import MentoringSpecialtiesFactory
from .model_change_factory import ModelChangeFactory
from .named_group_factory import NamedGroupFactory
from .newsletter_factory import NewsletterFactory
from .newsletter_receipt_factory import NewsletterReceiptFactory
from .node_published_for_factory import NodePublishedForFactory
from .observer_factory import ObserverFactory
from .organization_factory import OrganizationFactory
from .panel_factory import PanelFactory
from .panel_location_factory import PanelLocationFactory
from .panel_time_factory import PanelTimeFactory
from .panel_type_factory import PanelTypeFactory
from .partner_factory import PartnerFactory
from .partner_team_member_factory import PartnerTeamMemberFactory
from .paypal_payment_factory import PayPalPaymentFactory
from .permission_factory import PermissionFactory
from .program_cycle_factory import ProgramCycleFactory
from .program_factory import ProgramFactory
from .program_family_factory import ProgramFamilyFactory
from .program_override_factory import ProgramOverrideFactory
from .program_partner_factory import ProgramPartnerFactory
from .program_partner_type_factory import ProgramPartnerTypeFactory
from .program_role_factory import ProgramRoleFactory
from .program_role_grant_factory import ProgramRoleGrantFactory
from .program_startup_attribute_factory import ProgramStartupAttributeFactory
from .program_startup_status_factory import ProgramStartupStatusFactory
from .question_factory import QuestionFactory
from .reference_factory import ReferenceFactory
from .refund_code_factory import RefundCodeFactory
from .refund_code_redemption_factory import RefundCodeRedemptionFactory
from .scenario_application_factory import ScenarioApplicationFactory
from .scenario_factory import ScenarioFactory
from .scenario_judge_factory import ScenarioJudgeFactory
from .scenario_preference_factory import ScenarioPreferenceFactory
from .section_factory import SectionFactory
from .site_factory import SiteFactory
from .site_program_authorization_factory import SiteProgramAuthorizationFactory
from .startup_attribute_factory import StartupAttributeFactory
from .startup_cycle_interest_factory import StartupCycleInterestFactory
from .startup_factory import StartupFactory
from .startup_label_factory import StartupLabelFactory
from .startup_mentor_relationship_factory import (
    StartupMentorRelationshipFactory,
)
from .startup_mentor_tracking_record_factory import (
    StartupMentorTrackingRecordFactory,
)
from .startup_override_grant_factory import StartupOverrideGrantFactory
from .startup_program_interest_factory import StartupProgramInterestFactory
from .startup_role_factory import StartupRoleFactory
from .startup_status_factory import StartupStatusFactory
from .startup_team_member_factory import StartupTeamMemberFactory
from .url_node_factory import UrlNodeFactory
from .user_label_factory import UserLabelFactory
from .user_role_factory import UserRoleFactory
from .legal_check_factory import LegalCheckFactory
from .user_legal_check_factory import UserLegalCheckFactory
from simpleuser.tests.factories import UserFactory
from .nav_tree_factory import NavTreeFactory
from .nav_tree_item_factory import NavTreeItemFactory
from .subnav_association_factory import NodeSubNavAssociationFactory
from .program_family_location_factory import ProgramFamilyLocationFactory
from .gender_choices_factory import GenderChoicesFactory
from .ethno_racial_identity_factory import EthnoRacialIdentityFactory
from .deferrable_modal_factory import DeferrableModalFactory
from .user_deferrable_modal_factory import UserDeferrableModalFactory
from .user_note_factory import UserNoteFactory
from .organization_note_factory import OrganizationNoteFactory
from .partner_judging_instructions_factory import PartnerJudgingInstructionsFactory
<commit_msg>[AC-9102] resolve lint issues<commit_after># MIT License
# Copyright (c) 2017 MassChallenge, Inc.

from .allocator_factory import AllocatorFactory
from .application_answer_factory import ApplicationAnswerFactory
from .application_factory import ApplicationFactory
from .application_panel_assignment_factory import (
    ApplicationPanelAssignmentFactory,
)
from .application_question_factory import ApplicationQuestionFactory
from .application_type_factory import ApplicationTypeFactory
from .base_profile_factory import BaseProfileFactory
from .bucket_state_factory import BucketStateFactory
from .clearance_factory import ClearanceFactory
from .content_type_factory import ContentTypeFactory
from .core_profile_factory import CoreProfileFactory
from .criterion_factory import CriterionFactory
from .criterion_option_spec_factory import CriterionOptionSpecFactory
from .currency_factory import CurrencyFactory
from .entrepreneur_factory import EntrepreneurFactory
from .entrepreneur_profile_factory import EntrepreneurProfileFactory
from .expert_category_factory import ExpertCategoryFactory
from .expert_factory import ExpertFactory
# Late Loading Factories
# These fail if put in alphabetical order in the above list
# presumably due to their SubFactories.
from .expert_interest_factory import ExpertInterestFactory
from .expert_interest_type_factory import ExpertInterestTypeFactory
from .expert_profile_factory import ExpertProfileFactory
# Other utility methods
from .factory_utils import expert_data
from .functional_expertise_factory import FunctionalExpertiseFactory
from .group_factory import GroupFactory
from .industry_factory import IndustryFactory
from .interest_category_factory import InterestCategoryFactory
from .job_posting_factory import JobPostingFactory
from .judge_application_feedback_factory import JudgeApplicationFeedbackFactory
from .judge_availability_factory import JudgeAvailabilityFactory
from .judge_feedback_component_factory import JudgeFeedbackComponentFactory
from .judge_panel_assignment_factory import JudgePanelAssignmentFactory
from .judge_round_commitment_factory import JudgeRoundCommitmentFactory
from .judging_form_element_factory import JudgingFormElementFactory
from .judging_form_factory import JudgingFormFactory
from .judging_round_factory import JudgingRoundFactory
from .location_factory import LocationFactory
from .member_factory import MemberFactory
from .member_profile_factory import MemberProfileFactory
from .mentor_program_office_hour_factory import (
    MentorProgramOfficeHourFactory,
)
from .mentoring_specialties_factory import MentoringSpecialtiesFactory
from .model_change_factory import ModelChangeFactory
from .named_group_factory import NamedGroupFactory
from .newsletter_factory import NewsletterFactory
from .newsletter_receipt_factory import NewsletterReceiptFactory
from .node_published_for_factory import NodePublishedForFactory
from .observer_factory import ObserverFactory
from .organization_factory import OrganizationFactory
from .panel_factory import PanelFactory
from .panel_location_factory import PanelLocationFactory
from .panel_time_factory import PanelTimeFactory
from .panel_type_factory import PanelTypeFactory
from .partner_factory import PartnerFactory
from .partner_team_member_factory import PartnerTeamMemberFactory
from .paypal_payment_factory import PayPalPaymentFactory
from .permission_factory import PermissionFactory
from .program_cycle_factory import ProgramCycleFactory
from .program_factory import ProgramFactory
from .program_family_factory import ProgramFamilyFactory
from .program_override_factory import ProgramOverrideFactory
from .program_partner_factory import ProgramPartnerFactory
from .program_partner_type_factory import ProgramPartnerTypeFactory
from .program_role_factory import ProgramRoleFactory
from .program_role_grant_factory import ProgramRoleGrantFactory
from .program_startup_attribute_factory import ProgramStartupAttributeFactory
from .program_startup_status_factory import ProgramStartupStatusFactory
from .question_factory import QuestionFactory
from .reference_factory import ReferenceFactory
from .refund_code_factory import RefundCodeFactory
from .refund_code_redemption_factory import RefundCodeRedemptionFactory
from .scenario_application_factory import ScenarioApplicationFactory
from .scenario_factory import ScenarioFactory
from .scenario_judge_factory import ScenarioJudgeFactory
from .scenario_preference_factory import ScenarioPreferenceFactory
from .section_factory import SectionFactory
from .site_factory import SiteFactory
from .site_program_authorization_factory import SiteProgramAuthorizationFactory
from .startup_attribute_factory import StartupAttributeFactory
from .startup_cycle_interest_factory import StartupCycleInterestFactory
from .startup_factory import StartupFactory
from .startup_label_factory import StartupLabelFactory
from .startup_mentor_relationship_factory import (
    StartupMentorRelationshipFactory,
)
from .startup_mentor_tracking_record_factory import (
    StartupMentorTrackingRecordFactory,
)
from .startup_override_grant_factory import StartupOverrideGrantFactory
from .startup_program_interest_factory import StartupProgramInterestFactory
from .startup_role_factory import StartupRoleFactory
from .startup_status_factory import StartupStatusFactory
from .startup_team_member_factory import StartupTeamMemberFactory
from .url_node_factory import UrlNodeFactory
from .user_label_factory import UserLabelFactory
from .user_role_factory import UserRoleFactory
from .legal_check_factory import LegalCheckFactory
from .user_legal_check_factory import UserLegalCheckFactory
from simpleuser.tests.factories import UserFactory
from .nav_tree_factory import NavTreeFactory
from .nav_tree_item_factory import NavTreeItemFactory
from .subnav_association_factory import NodeSubNavAssociationFactory
from .program_family_location_factory import ProgramFamilyLocationFactory
from .gender_choices_factory import GenderChoicesFactory
from .ethno_racial_identity_factory import EthnoRacialIdentityFactory
from .deferrable_modal_factory import DeferrableModalFactory
from .user_deferrable_modal_factory import UserDeferrableModalFactory
from .user_note_factory import UserNoteFactory
from .organization_note_factory import OrganizationNoteFactory
from .partner_judging_instructions_factory import (
    PartnerJudgingInstructionsFactory,
)
<|endoftext|>


<commit_before># -*- encoding: utf-8 -*-
###########################################################################
#    Copyright (C) OpenERP Venezuela (<http://openerp.com.ve>).
#    All Rights Reserved
# Credits######################################################
#    Coded by:   Humberto Arocha humberto@openerp.com.ve
#                Angelica Barrios angelicaisabelb@gmail.com
#               Jordi Esteve <jesteve@zikzakmedia.com>
#    Planified by: Humberto Arocha
#    Finance by: LUBCAN COL S.A.S http://www.lubcancol.com
#    Audited by: Humberto Arocha humberto@openerp.com.ve
#############################################################################
#    This program 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.
#
#    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
##############################################################################
{
    "name": "Common financial reports",
    "version": "2.0",
    "author": "Vauxoo",
    "website": "http://www.vauxoo.com",
    "depends": ["base", "account"],
    "category": "Localisation/Accounting",
    "description": """
Multiporpuse Accounting report generator.
=========================================

From the wizard you will be asked to provide information needed to create your
report.

Not only you can set the option within the wizard you can create your own
Customized Account Financial Reports, in here, you will be able to create
Templates for generating Two types of Reports: Balance Sheets and Income
Statements, incluiding Analytic Ledgers. Besides, you can select within a set
of choices to get better detailed report, be it that you ask it by one or
several periods, by months (12 Months + YTD), or by quarters (4QRT's + YTD).
Even you can get your reports in currencies other than the one set on your
company.

In the [ Account's Sign on Reports ] Section in the Company will be able to
set the sign conventions for the Accounts, so that you will be able to see in
positives Values in your reports for those accounts with Accreditable nature
where appropriate""",
    "data": [
        "security/security.xml",
        "security/ir.model.access.csv",
        "view/report.xml",
        "view/wizard.xml",
        "view/company_view.xml",
        "view/account_financial_report_view.xml",
    ],
    "active": False,
    "installable": True
}
<commit_msg>[FIX] Module Category should be accounting, not localization it is a generic module.<commit_after># -*- encoding: utf-8 -*-
###########################################################################
#    Copyright (C) OpenERP Venezuela (<http://openerp.com.ve>).
#    All Rights Reserved
# Credits######################################################
#    Coded by:   Humberto Arocha humberto@openerp.com.ve
#                Angelica Barrios angelicaisabelb@gmail.com
#               Jordi Esteve <jesteve@zikzakmedia.com>
#    Planified by: Humberto Arocha
#    Finance by: LUBCAN COL S.A.S http://www.lubcancol.com
#    Audited by: Humberto Arocha humberto@openerp.com.ve
#############################################################################
#    This program 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.
#
#    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
##############################################################################
{
    "name": "Common financial reports",
    "version": "2.0",
    "author": "Vauxoo",
    "website": "http://www.vauxoo.com",
    "depends": ["base",
                "account"
                ],
    "category": "Accounting",
    "description": """
Multiporpuse Accounting report generator.
=========================================

From the wizard you will be asked to provide information needed to create your
report.

Not only you can set the option within the wizard you can create your own
Customized Account Financial Reports, in here, you will be able to create
Templates for generating Two types of Reports: Balance Sheets and Income
Statements, incluiding Analytic Ledgers. Besides, you can select within a set
of choices to get better detailed report, be it that you ask it by one or
several periods, by months (12 Months + YTD), or by quarters (4QRT's + YTD).
Even you can get your reports in currencies other than the one set on your
company.

In the [ Account's Sign on Reports ] Section in the Company will be able to
set the sign conventions for the Accounts, so that you will be able to see in
positives Values in your reports for those accounts with Accreditable nature
where appropriate""",
    "data": [
        "security/security.xml",
        "security/ir.model.access.csv",
        "view/report.xml",
        "view/wizard.xml",
        "view/company_view.xml",
        "view/account_financial_report_view.xml",
    ],
    "active": False,
    "installable": True
}
<|endoftext|>


<commit_before># import sys
import re
import datetime
from pprint import pprint

from django.core.management.base import BaseCommand, CommandError
from django.db import connections

# from fo2.models import rows_to_dict_list_lower
# import lotes.models as models

from insumo.views import MapaPorInsumo_dados

class Command(BaseCommand):
    help = 'Monta tabela de sugestão de compras por insumo.'
    # __MAX_TASKS = 100

    def my_println(self, text=''):
        self.my_print(text, ending='\n')

    def my_print(self, text='', ending=''):
        self.stdout.write(text, ending=ending)
        self.stdout.flush()

    # def iter_cursor(self, cursor):
    #     columns = [i[0].lower() for i in cursor.description]
    #     for row in cursor:
    #         dict_row = dict(zip(columns, row))
    #         yield dict_row
    #
    # def get_someting(self):
    #     cursor_s = connections['so'].cursor()
    #     sql = '''
    #         SELECT
    #           1
    #         FROM DUAL
    #     '''
    #     cursor_s.execute(sql)
    #     return self.iter_cursor(cursor_s)

    def valid_1A(self, s, tam, descr):
        pat = re.compile(r"^[0-9A-Z]{%s}$" % (tam))
        if not pat.match(s):
            msg = "Valor de '{}' inválido: '{}'.".format(descr, s)
            raise Exception(msg)

    def conta_nao_None(self, name):
        if self.kwargs[name] is None:
            return 0
        else:
            return 1

    def add_arguments(self, parser):
        parser.add_argument(
            'nivel', help='nivel', choices=['2', '9'], nargs='?')
        parser.add_argument('referencia', help='5 caracteres', nargs='?')
        parser.add_argument('cor', help='6 caracteres', nargs='?')
        parser.add_argument('tamanho', help='1 a 3 caracteres', nargs='?')

    def handle(self, *args, **kwargs):
        self.my_println('---')
        self.my_println('{}'.format(datetime.datetime.now()))
        self.kwargs = kwargs

        try:
            conta_parm = \
                self.conta_nao_None('nivel') + \
                self.conta_nao_None('referencia') + \
                self.conta_nao_None('cor') + \
                self.conta_nao_None('tamanho')
            if conta_parm % 4 != 0:
                msg = "Informe as 4 partes do código do item ou nada"
                raise Exception(msg)

            if conta_parm == 4:
                nivel = kwargs['nivel']
                ref = kwargs['referencia']
                cor = kwargs['cor']
                tam = kwargs['tamanho']
                self.valid_1A(ref, 5, 'Referencia')
                self.valid_1A(cor, 6, 'Cor')
                self.valid_1A(tam, '1,3', 'Tamanho')

                cursor = connections['so'].cursor()
                datas = MapaPorInsumo_dados(cursor, nivel, ref, cor, tam)
                pprint(datas['data_sug'])

            # pega xyz
            # ixyz = self.get_someting()
            #
            count_task = 0
            # while count_task < self.__MAX_TASKS:
            #
            #     try:
            #         row_xyz = next(ixyz)
            #         field = row_xyz['field']
            #     except StopIteration:
            #         pass
            #
        except Exception as e:
            raise CommandError(
                'Error montando sugestão de compras "{}"'.format(e))

        self.my_println(format(datetime.datetime.now(), '%H:%M:%S.%f'))
<commit_msg>evoluindo command, já insere sugestão de insumo específico<commit_after># import sys
import re
from datetime import datetime
from pprint import pprint
import pytz

from django.utils import timezone
from django.core.management.base import BaseCommand, CommandError
from django.db import connections

import insumo.models as models
from insumo.views import MapaPorInsumo_dados

class Command(BaseCommand):
    help = 'Monta tabela de sugestão de compras por insumo.'
    # __MAX_TASKS = 100

    def my_println(self, text=''):
        self.my_print(text, ending='\n')

    def my_print(self, text='', ending=''):
        self.stdout.write(text, ending=ending)
        self.stdout.flush()

    def valid_1A(self, s, tam, descr):
        pat = re.compile(r"^[0-9A-Z]{%s}$" % (tam))
        if not pat.match(s):
            msg = "Valor de '{}' inválido: '{}'.".format(descr, s)
            raise Exception(msg)

    def countNone(self, *values):
        count = 0
        for value in values:
            if value is None:
                count += 1
        return count

    def add_arguments(self, parser):
        parser.add_argument(
            'nivel_ou_tipo', help='nivel ou tipo',
            choices=['2', '9', 'e', 't'], nargs='?')
        parser.add_argument('referencia', help='5 caracteres', nargs='?')
        parser.add_argument('cor', help='6 caracteres', nargs='?')
        parser.add_argument('tamanho', help='1 a 3 caracteres', nargs='?')

    def handle(self, *args, **kwargs):
        self.my_println('---')
        self.my_println('{}'.format(datetime.now()))

        nivel = kwargs['nivel_ou_tipo']
        ref = kwargs['referencia']
        cor = kwargs['cor']
        tam = kwargs['tamanho']
        try:
            conta_none = self.countNone(nivel, ref, cor, tam)
            if conta_none % 3 != 0:
                raise Exception(
                    "Informe as 4 partes do código do item "
                    "ou o tipo de execução")

            if conta_none == 3:
                if nivel == 'e':
                    print('só utilizados em estrutura')
                elif nivel == 't':
                    print('todos')
            elif conta_none == 0:
                self.valid_1A(ref, 5, 'Referencia')
                self.valid_1A(cor, 6, 'Cor')
                self.valid_1A(tam, '1,3', 'Tamanho')

                cursor = connections['so'].cursor()
                datas = MapaPorInsumo_dados(cursor, nivel, ref, cor, tam)
                data_sug = datas['data_sug']
                pprint(data_sug)

                sc = models.SugestaoCompra.objects.filter(
                    nivel=nivel,
                    referencia=ref,
                    tamanho=tam,
                    cor=cor,
                ).order_by('-data').first()

                ultima_sug = []
                if sc:
                    print(sc.id)
                    scd = models.SugestaoCompraDatas.objects.filter(
                        sugestao=sc).order_by('data_compra').values()
                    for data in scd:
                        pprint(data)
                        ultima_sug.append({
                            'QUANT': data['qtd'],
                            'SEMANA_COMPRA': data['data_compra'],
                            'SEMANA_RECEPCAO': data['data_recepcao'],
                        })
                    pprint(ultima_sug)
                    print(ultima_sug == data_sug)

                if ultima_sug == data_sug:
                    print('Sugestão inalterada')
                else:
                    print('Gravando nova sugestão')
                    sc = models.SugestaoCompra()
                    sc.nivel = nivel
                    sc.referencia = ref
                    sc.tamanho = tam
                    sc.ordem_tamanho = 0
                    sc.cor = cor
                    sc.data = timezone.now()
                    sc.save()
                    print(sc.id)

                    for sugestao in data_sug:
                        pprint(sugestao)
                        scd = models.SugestaoCompraDatas()
                        scd.sugestao = sc
                        scd.data_compra = sugestao['SEMANA_COMPRA']
                        scd.data_recepcao = sugestao['SEMANA_RECEPCAO']
                        scd.qtd = sugestao['QUANT']
                        scd.save()
                        print(scd.id)

            # pega xyz
            # ixyz = self.get_someting()
            #
            count_task = 0
            # while count_task < self.__MAX_TASKS:
            #
            #     try:
            #         row_xyz = next(ixyz)
            #         field = row_xyz['field']
            #     except StopIteration:
            #         pass
            #
        except Exception as e:
            raise CommandError(
                'Error montando sugestão de compras "{}"'.format(e))

        self.my_println(format(datetime.now(), '%H:%M:%S.%f'))
<|endoftext|>