<commit_before># coding=utf-8
"""
This module defines the interface for communicating with a connected printer.

The communication is in fact divided in two components, the :class:`PrinterInterface` and a deeper lying
communcation layer. However, plugins should only ever need to use the :class:`PrinterInterface` as the
abstracted version of the actual printer communiciation.

.. autofunction:: get_connection_options

.. autoclass:: PrinterInterface
   :members:

.. autoclass:: PrinterCallback
   :members:
"""

from __future__ import absolute_import

__author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms of the AGPLv3 License"

import re

import octoprint.util.comm as comm
from octoprint.settings import settings

def get_connection_options():
	"""
	Retrieves the available ports, baudrates, prefered port and baudrate for connecting to the printer.

	Returned ``dict`` has the following structure::

	    ports: <list of available serial ports>
	    baudrates: <list of available baudrates>
	    portPreference: <configured default serial port>
	    baudratePreference: <configured default baudrate>
	    autoconnect: <whether autoconnect upon server startup is enabled or not>

	Returns:
	    (dict): A dictionary holding the connection options in the structure specified above
	"""
	return {
		"ports": comm.serialList(),
		"baudrates": comm.baudrateList(),
		"portPreference": settings().get(["serial", "port"]),
		"baudratePreference": settings().getInt(["serial", "baudrate"]),
		"autoconnect": settings().getBoolean(["serial", "autoconnect"])
	}

class PrinterInterface(object):
	"""
	The :class:`PrinterInterface` represents the developer interface to the :class:`~octoprint.printer.standard.Printer`
	instance.
	"""

	valid_axes = ("x", "y", "z", "e")
	"""Valid axes identifiers."""

	valid_tool_regex = re.compile("^(tool\d+)$")
	"""Regex for valid tool identifiers."""

	valid_heater_regex = re.compile("^(tool\d+|bed)$")
	"""Regex for valid heater identifiers."""

	def connect(self, port=None, baudrate=None, profile=None):
		"""
		Connects to the printer, using the specified serial ``port``, ``baudrate`` and printer ``profile``. If a
		connection is already established, that connection will be closed prior to connecting anew with the provided
		parameters.

		Arguments:
		    port (str): Name of the serial port to connect to. If not provided, an auto detection will be attempted.
		    baudrate (int): Baudrate to connect with. If not provided, an auto detection will be attempted.
		    profile (str): Name of the printer profile to use for this connection. If not provided, the default
		        will be retrieved from the :class:`PrinterProfileManager`.
		"""
		pass

	def disconnect(self):
		"""
		Disconnects from the printer. Does nothing if no connection is currently established.
		"""
		raise NotImplementedError()

	def get_transport(self):
		"""
		Returns the communication layer's transport object, if a connection is currently established.

		Note that this doesn't have to necessarily be a :class:`serial.Serial` instance, it might also be something
		different, so take care to do instance checks before attempting to access any properties or methods.

		Returns:
		    object: The communication layer's transport object
		"""
		raise NotImplementedError()

	def fake_ack(self):
		"""
		Fakes an acknowledgement for the communication layer. If the communication between OctoPrint and the printer
		gets stuck due to lost "ok" responses from the server due to communication issues, this can be used to get
		things going again.
		"""
		raise NotImplementedError()

	def commands(self, commands):
		"""
		Sends the provided ``commands`` to the printer.

		Arguments:
		    commands (str, list): The commands to send. Might be a single command provided just as a string or a list
		        of multiple commands to send in order.
		"""
		raise NotImplementedError()

	def script(self, name, context=None):
		"""
		Sends the GCODE script ``name`` to the printer.

		The script will be run through the template engine, the rendering context can be extended by providing a
		``context`` with additional template variables to use.

		If the script is unknown, an :class:`UnknownScriptException` will be raised.

		Arguments:
		    name (str): The name of the GCODE script to render.
		    context (dict): An optional context of additional template variables to provide to the renderer.

		Raises:
		    UnknownScriptException: There is no GCODE script with name ``name``
		"""
		raise NotImplementedError()

	def jog(self, axis, amount):
		"""
		Jogs the specified printer ``axis`` by the specified ``amount`` in mm.

		Arguments:
		    axis (str): The axis to jog, will be converted to lower case, one of "x", "y", "z" or "e"
		    amount (int, float): The amount by which to jog in mm
		"""
		raise NotImplementedError()

	def home(self, axes):
		"""
		Homes the specified printer ``axes``.

		Arguments:
		    axes (str, list): The axis or axes to home, each of which must converted to lower case must match one of
		        "x", "y", "z" and "e"
		"""
		raise NotImplementedError()

	def extrude(self, amount):
		"""
		Extrude ``amount`` milimeters of material from the tool.

		Arguments:
		    amount (int, float): The amount of material to extrude in mm
		"""
		raise NotImplementedError()

	def change_tool(self, tool):
		"""
		Switch the currently active ``tool`` (for which extrude commands will apply).

		Arguments:
		    tool (str): The tool to switch to, matching the regex "tool[0-9]+" (e.g. "tool0", "tool1", ...)
		"""
		raise NotImplementedError()

	def set_temperature(self, heater, value):
		"""
		Sets the target temperature on the specified ``heater`` to the given ``value`` in celsius.

		Arguments:
		    heater (str): The heater for which to set the target temperature. Either "bed" for setting the bed
		        temperature or something matching the regular expression "tool[0-9]+" (e.g. "tool0", "tool1", ...) for
		        the hotends of the printer
		    value (int, float): The temperature in celsius to set the target temperature to.
		"""
		raise NotImplementedError()

	def set_temperature_offset(self, offsets=None):
		"""
		Sets the temperature ``offsets`` to apply to target temperatures red from a GCODE file while printing.

		Arguments:
		    offsets (dict): A dictionary specifying the offsets to apply. Keys must match the format for the ``heater``
		        parameter to :func:`set_temperature`, so "bed" for the offset for the bed target temperature and
		        "tool[0-9]+" for the offsets to the hotend target temperatures.
		"""
		raise NotImplementedError()

	def feed_rate(self, factor):
		"""
		Sets the ``factor`` for the printer's feed rate.

		Arguments:
		    factor (int, float): The factor for the feed rate to send to the firmware. Percentage expressed as either an
		    int between 0 and 100 or a float between 0 and 1.
		"""
		raise NotImplementedError()

	def flow_rate(self, factor):
		"""
		Sets the ``factor`` for the printer's flow rate.

		Arguments:
		    factor (int, float): The factor for the flow rate to send to the firmware. Percentage expressed as either an
		    int between 0 and 100 or a float between 0 and 1.
		"""
		raise NotImplementedError()

	def select_file(self, path, sd, printAfterSelect=False):
		"""
		Selects the specified ``path`` for printing, specifying if the file is to be found on the ``sd`` or not.
		Optionally can also directly start the print after selecting the file.

		Arguments:
		    path (str): The path to select for printing. Either an absolute path (local file) or a
		"""
		raise NotImplementedError()

	def unselect_file(self):
		"""
		Unselects and currently selected file.
		"""
		raise NotImplementedError()

	def start_print(self):
		"""
		Starts printing the currently selected file. If no file is currently selected, does nothing.
		"""
		raise NotImplementedError()

	def toggle_pause_print(self):
		"""
		Pauses the current print job if it is currently running or resumes it if it is currently paused.
		"""
		raise NotImplementedError()

	def cancel_print(self):
		"""
		Cancels the current print job.
		"""
		raise NotImplementedError()

	def get_state_string(self):
		"""
		Returns:
		     (str) A human readable string corresponding to the current communication state.
		"""
		raise NotImplementedError()

	def get_current_data(self):
		"""
		Returns:
		    (dict) The current state data.
		"""
		raise NotImplementedError()

	def get_current_job(self):
		"""
		Returns:
		    (dict) The data of the current job.
		"""
		raise NotImplementedError()

	def get_current_temperatures(self):
		"""
		Returns:
		    (dict) The current temperatures.
		"""
		raise NotImplementedError()

	def get_temperature_history(self):
		"""
		Returns:
		    (list) The temperature history.
		"""
		raise NotImplementedError()

	def get_current_connection(self):
		"""
		Returns:
		    (tuple) The current connection information as a 4-tuple ``(connection_string, port, baudrate, printer_profile)``.
		        If the printer is currently not connected, the tuple will be ``("Closed", None, None, None)``.
		"""
		raise NotImplementedError()

	def is_closed_or_error(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently disconnected and/or in an error state.
		"""
		raise NotImplementedError()

	def is_operational(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently connected and available.
		"""
		raise NotImplementedError()

	def is_printing(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently printing.
		"""
		raise NotImplementedError()

	def is_paused(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently paused.
		"""
		raise NotImplementedError()

	def is_error(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently in an error state.
		"""
		raise NotImplementedError()

	def is_ready(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently operational and ready for new print jobs (not printing).
		"""
		raise NotImplementedError()

	def register_callback(self, callback):
		"""
		Registers a :class:`PrinterCallback` with the instance.

		Arguments:
		    callback (PrinterCallback): The callback object to register.
		"""
		raise NotImplementedError()

	def unregister_callback(self, callback):
		"""
		Unregisters a :class:`PrinterCallback` from the instance.

		Arguments:
		    callback (PrinterCallback): The callback object to unregister.
		"""
		raise NotImplementedError()

class PrinterCallback(object):
	def on_printer_add_log(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new communication log entry from the communication layer.

		Arguments:
		    data (str): The received log line.
		"""
		pass

	def on_printer_add_message(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new message from the communication layer.

		Arguments:
		    data (str): The received message.
		"""
		pass

	def on_printer_add_temperature(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new temperature data set from the communication layer.

		``data`` is a ``dict`` of the following structure::

		    tool0:
		        actual: <temperature of the first hotend, in degC>
		        target: <target temperature of the first hotend, in degC>
		    ...
		    bed:
		        actual: <temperature of the bed, in degC>
		        target: <target temperature of the bed, in degC>

		Arguments:
		    data (dict): A dict of all current temperatures in the format as specified above
		"""
		pass

	def on_printer_received_registered_message(self, name, output):
		"""
		Called when the :class:`PrinterInterface` received a registered message, e.g. from a feedback command.

		Arguments:
		    name (str): Name of the registered message (e.g. the feedback command)
		    output (str): Output for the registered message
		"""
		pass

	def on_printer_send_initial_data(self, data):
		"""
		Called when registering as a callback with the :class:`PrinterInterface` to receive the initial data (state,
		log and temperature history etc) from the printer.

		``data`` is a ``dict`` of the following structure::

		    temps:
		      - time: <timestamp of the temperature data point>
		        tool0:
		            actual: <temperature of the first hotend, in degC>
		            target: <target temperature of the first hotend, in degC>
		        ...
		        bed:
		            actual: <temperature of the bed, in degC>
		            target: <target temperature of the bed, in degC>
		      - ...
		    logs: <list of current communication log lines>
		    messages: <list of current messages from the firmware>

		Arguments:
		    data (dict): The initial data in the format as specified above.
		"""
		pass

	def on_printer_send_current_data(self, data):
		"""
		Called when the internal state of the :class:`PrinterInterface` changes, due to changes in the printer state,
		temperatures, log lines, job progress etc. Updates via this method are guaranteed to be throttled to a maximum
		of 2 calles per second.

		``data`` is a ``dict`` of the following structure::

		    state:
		        text: <current state string>
		        flags:
		            operational: <whether the printer is currently connected and responding>
		            printing: <whether the printer is currently printing>
		            closedOrError: <whether the printer is currently disconnected and/or in an error state>
		            error: <whether the printer is currently in an error state>
		            paused: <whether the printer is currently paused>
		            ready: <whether the printer is operational and ready for jobs>
		            sdReady: <whether an SD card is present>
		    job:
		        file:
		            name: <name of the file>,
		            size: <size of the file in bytes>,
		            origin: <origin of the file, "local" or "sdcard">,
		            date: <last modification date of the file>
		        estimatedPrintTime: <estimated print time of the file in seconds>
		        lastPrintTime: <last print time of the file in seconds>
		        filament:
		            length: <estimated length of filament needed for this file, in mm>
		            volume: <estimated volume of filament needed for this file, in ccm>
		    progress:
		        completion: <progress of the print job in percent (0-100)>
		        filepos: <current position in the file in bytes>
		        printTime: <current time elapsed for printing, in seconds>
		        printTimeLeft: <estimated time left to finish printing, in seconds>
		    currentZ: <current position of the z axis, in mm>
		    offsets: <current configured temperature offsets, keys are "bed" or "tool[0-9]+", values the offset in degC>

		Arguments:
		    data (dict): The current data in the format as specified above.
		"""
		pass

class UnknownScript(Exception):
	def __init__(self, name, *args, **kwargs):
		self.name = name
<commit_msg>Lengthen doc on PrinterInterface.select_file<commit_after># coding=utf-8
"""
This module defines the interface for communicating with a connected printer.

The communication is in fact divided in two components, the :class:`PrinterInterface` and a deeper lying
communcation layer. However, plugins should only ever need to use the :class:`PrinterInterface` as the
abstracted version of the actual printer communiciation.

.. autofunction:: get_connection_options

.. autoclass:: PrinterInterface
   :members:

.. autoclass:: PrinterCallback
   :members:
"""

from __future__ import absolute_import

__author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms of the AGPLv3 License"

import re

import octoprint.util.comm as comm
from octoprint.settings import settings

def get_connection_options():
	"""
	Retrieves the available ports, baudrates, prefered port and baudrate for connecting to the printer.

	Returned ``dict`` has the following structure::

	    ports: <list of available serial ports>
	    baudrates: <list of available baudrates>
	    portPreference: <configured default serial port>
	    baudratePreference: <configured default baudrate>
	    autoconnect: <whether autoconnect upon server startup is enabled or not>

	Returns:
	    (dict): A dictionary holding the connection options in the structure specified above
	"""
	return {
		"ports": comm.serialList(),
		"baudrates": comm.baudrateList(),
		"portPreference": settings().get(["serial", "port"]),
		"baudratePreference": settings().getInt(["serial", "baudrate"]),
		"autoconnect": settings().getBoolean(["serial", "autoconnect"])
	}

class PrinterInterface(object):
	"""
	The :class:`PrinterInterface` represents the developer interface to the :class:`~octoprint.printer.standard.Printer`
	instance.
	"""

	valid_axes = ("x", "y", "z", "e")
	"""Valid axes identifiers."""

	valid_tool_regex = re.compile("^(tool\d+)$")
	"""Regex for valid tool identifiers."""

	valid_heater_regex = re.compile("^(tool\d+|bed)$")
	"""Regex for valid heater identifiers."""

	def connect(self, port=None, baudrate=None, profile=None):
		"""
		Connects to the printer, using the specified serial ``port``, ``baudrate`` and printer ``profile``. If a
		connection is already established, that connection will be closed prior to connecting anew with the provided
		parameters.

		Arguments:
		    port (str): Name of the serial port to connect to. If not provided, an auto detection will be attempted.
		    baudrate (int): Baudrate to connect with. If not provided, an auto detection will be attempted.
		    profile (str): Name of the printer profile to use for this connection. If not provided, the default
		        will be retrieved from the :class:`PrinterProfileManager`.
		"""
		pass

	def disconnect(self):
		"""
		Disconnects from the printer. Does nothing if no connection is currently established.
		"""
		raise NotImplementedError()

	def get_transport(self):
		"""
		Returns the communication layer's transport object, if a connection is currently established.

		Note that this doesn't have to necessarily be a :class:`serial.Serial` instance, it might also be something
		different, so take care to do instance checks before attempting to access any properties or methods.

		Returns:
		    object: The communication layer's transport object
		"""
		raise NotImplementedError()

	def fake_ack(self):
		"""
		Fakes an acknowledgement for the communication layer. If the communication between OctoPrint and the printer
		gets stuck due to lost "ok" responses from the server due to communication issues, this can be used to get
		things going again.
		"""
		raise NotImplementedError()

	def commands(self, commands):
		"""
		Sends the provided ``commands`` to the printer.

		Arguments:
		    commands (str, list): The commands to send. Might be a single command provided just as a string or a list
		        of multiple commands to send in order.
		"""
		raise NotImplementedError()

	def script(self, name, context=None):
		"""
		Sends the GCODE script ``name`` to the printer.

		The script will be run through the template engine, the rendering context can be extended by providing a
		``context`` with additional template variables to use.

		If the script is unknown, an :class:`UnknownScriptException` will be raised.

		Arguments:
		    name (str): The name of the GCODE script to render.
		    context (dict): An optional context of additional template variables to provide to the renderer.

		Raises:
		    UnknownScriptException: There is no GCODE script with name ``name``
		"""
		raise NotImplementedError()

	def jog(self, axis, amount):
		"""
		Jogs the specified printer ``axis`` by the specified ``amount`` in mm.

		Arguments:
		    axis (str): The axis to jog, will be converted to lower case, one of "x", "y", "z" or "e"
		    amount (int, float): The amount by which to jog in mm
		"""
		raise NotImplementedError()

	def home(self, axes):
		"""
		Homes the specified printer ``axes``.

		Arguments:
		    axes (str, list): The axis or axes to home, each of which must converted to lower case must match one of
		        "x", "y", "z" and "e"
		"""
		raise NotImplementedError()

	def extrude(self, amount):
		"""
		Extrude ``amount`` milimeters of material from the tool.

		Arguments:
		    amount (int, float): The amount of material to extrude in mm
		"""
		raise NotImplementedError()

	def change_tool(self, tool):
		"""
		Switch the currently active ``tool`` (for which extrude commands will apply).

		Arguments:
		    tool (str): The tool to switch to, matching the regex "tool[0-9]+" (e.g. "tool0", "tool1", ...)
		"""
		raise NotImplementedError()

	def set_temperature(self, heater, value):
		"""
		Sets the target temperature on the specified ``heater`` to the given ``value`` in celsius.

		Arguments:
		    heater (str): The heater for which to set the target temperature. Either "bed" for setting the bed
		        temperature or something matching the regular expression "tool[0-9]+" (e.g. "tool0", "tool1", ...) for
		        the hotends of the printer
		    value (int, float): The temperature in celsius to set the target temperature to.
		"""
		raise NotImplementedError()

	def set_temperature_offset(self, offsets=None):
		"""
		Sets the temperature ``offsets`` to apply to target temperatures red from a GCODE file while printing.

		Arguments:
		    offsets (dict): A dictionary specifying the offsets to apply. Keys must match the format for the ``heater``
		        parameter to :func:`set_temperature`, so "bed" for the offset for the bed target temperature and
		        "tool[0-9]+" for the offsets to the hotend target temperatures.
		"""
		raise NotImplementedError()

	def feed_rate(self, factor):
		"""
		Sets the ``factor`` for the printer's feed rate.

		Arguments:
		    factor (int, float): The factor for the feed rate to send to the firmware. Percentage expressed as either an
		    int between 0 and 100 or a float between 0 and 1.
		"""
		raise NotImplementedError()

	def flow_rate(self, factor):
		"""
		Sets the ``factor`` for the printer's flow rate.

		Arguments:
		    factor (int, float): The factor for the flow rate to send to the firmware. Percentage expressed as either an
		    int between 0 and 100 or a float between 0 and 1.
		"""
		raise NotImplementedError()

	def select_file(self, path, sd, printAfterSelect=False):
		"""
		Selects the specified ``path`` for printing, specifying if the file is to be found on the ``sd`` or not.
		Optionally can also directly start the print after selecting the file.

		Arguments:
		    path (str): The path to select for printing. Either an absolute path (local file) or a
		        filename (SD card).
		    sd (boolean): Indicates whether the file is on the SD card or not.
		    printAfterSelect (boolean): Indicates whether a print should be started
		        after the file is selected.
		"""
		raise NotImplementedError()

	def unselect_file(self):
		"""
		Unselects and currently selected file.
		"""
		raise NotImplementedError()

	def start_print(self):
		"""
		Starts printing the currently selected file. If no file is currently selected, does nothing.
		"""
		raise NotImplementedError()

	def toggle_pause_print(self):
		"""
		Pauses the current print job if it is currently running or resumes it if it is currently paused.
		"""
		raise NotImplementedError()

	def cancel_print(self):
		"""
		Cancels the current print job.
		"""
		raise NotImplementedError()

	def get_state_string(self):
		"""
		Returns:
		     (str) A human readable string corresponding to the current communication state.
		"""
		raise NotImplementedError()

	def get_current_data(self):
		"""
		Returns:
		    (dict) The current state data.
		"""
		raise NotImplementedError()

	def get_current_job(self):
		"""
		Returns:
		    (dict) The data of the current job.
		"""
		raise NotImplementedError()

	def get_current_temperatures(self):
		"""
		Returns:
		    (dict) The current temperatures.
		"""
		raise NotImplementedError()

	def get_temperature_history(self):
		"""
		Returns:
		    (list) The temperature history.
		"""
		raise NotImplementedError()

	def get_current_connection(self):
		"""
		Returns:
		    (tuple) The current connection information as a 4-tuple ``(connection_string, port, baudrate, printer_profile)``.
		        If the printer is currently not connected, the tuple will be ``("Closed", None, None, None)``.
		"""
		raise NotImplementedError()

	def is_closed_or_error(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently disconnected and/or in an error state.
		"""
		raise NotImplementedError()

	def is_operational(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently connected and available.
		"""
		raise NotImplementedError()

	def is_printing(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently printing.
		"""
		raise NotImplementedError()

	def is_paused(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently paused.
		"""
		raise NotImplementedError()

	def is_error(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently in an error state.
		"""
		raise NotImplementedError()

	def is_ready(self):
		"""
		Returns:
		    (boolean) Whether the printer is currently operational and ready for new print jobs (not printing).
		"""
		raise NotImplementedError()

	def register_callback(self, callback):
		"""
		Registers a :class:`PrinterCallback` with the instance.

		Arguments:
		    callback (PrinterCallback): The callback object to register.
		"""
		raise NotImplementedError()

	def unregister_callback(self, callback):
		"""
		Unregisters a :class:`PrinterCallback` from the instance.

		Arguments:
		    callback (PrinterCallback): The callback object to unregister.
		"""
		raise NotImplementedError()

class PrinterCallback(object):
	def on_printer_add_log(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new communication log entry from the communication layer.

		Arguments:
		    data (str): The received log line.
		"""
		pass

	def on_printer_add_message(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new message from the communication layer.

		Arguments:
		    data (str): The received message.
		"""
		pass

	def on_printer_add_temperature(self, data):
		"""
		Called when the :class:`PrinterInterface` receives a new temperature data set from the communication layer.

		``data`` is a ``dict`` of the following structure::

		    tool0:
		        actual: <temperature of the first hotend, in degC>
		        target: <target temperature of the first hotend, in degC>
		    ...
		    bed:
		        actual: <temperature of the bed, in degC>
		        target: <target temperature of the bed, in degC>

		Arguments:
		    data (dict): A dict of all current temperatures in the format as specified above
		"""
		pass

	def on_printer_received_registered_message(self, name, output):
		"""
		Called when the :class:`PrinterInterface` received a registered message, e.g. from a feedback command.

		Arguments:
		    name (str): Name of the registered message (e.g. the feedback command)
		    output (str): Output for the registered message
		"""
		pass

	def on_printer_send_initial_data(self, data):
		"""
		Called when registering as a callback with the :class:`PrinterInterface` to receive the initial data (state,
		log and temperature history etc) from the printer.

		``data`` is a ``dict`` of the following structure::

		    temps:
		      - time: <timestamp of the temperature data point>
		        tool0:
		            actual: <temperature of the first hotend, in degC>
		            target: <target temperature of the first hotend, in degC>
		        ...
		        bed:
		            actual: <temperature of the bed, in degC>
		            target: <target temperature of the bed, in degC>
		      - ...
		    logs: <list of current communication log lines>
		    messages: <list of current messages from the firmware>

		Arguments:
		    data (dict): The initial data in the format as specified above.
		"""
		pass

	def on_printer_send_current_data(self, data):
		"""
		Called when the internal state of the :class:`PrinterInterface` changes, due to changes in the printer state,
		temperatures, log lines, job progress etc. Updates via this method are guaranteed to be throttled to a maximum
		of 2 calles per second.

		``data`` is a ``dict`` of the following structure::

		    state:
		        text: <current state string>
		        flags:
		            operational: <whether the printer is currently connected and responding>
		            printing: <whether the printer is currently printing>
		            closedOrError: <whether the printer is currently disconnected and/or in an error state>
		            error: <whether the printer is currently in an error state>
		            paused: <whether the printer is currently paused>
		            ready: <whether the printer is operational and ready for jobs>
		            sdReady: <whether an SD card is present>
		    job:
		        file:
		            name: <name of the file>,
		            size: <size of the file in bytes>,
		            origin: <origin of the file, "local" or "sdcard">,
		            date: <last modification date of the file>
		        estimatedPrintTime: <estimated print time of the file in seconds>
		        lastPrintTime: <last print time of the file in seconds>
		        filament:
		            length: <estimated length of filament needed for this file, in mm>
		            volume: <estimated volume of filament needed for this file, in ccm>
		    progress:
		        completion: <progress of the print job in percent (0-100)>
		        filepos: <current position in the file in bytes>
		        printTime: <current time elapsed for printing, in seconds>
		        printTimeLeft: <estimated time left to finish printing, in seconds>
		    currentZ: <current position of the z axis, in mm>
		    offsets: <current configured temperature offsets, keys are "bed" or "tool[0-9]+", values the offset in degC>

		Arguments:
		    data (dict): The current data in the format as specified above.
		"""
		pass

class UnknownScript(Exception):
	def __init__(self, name, *args, **kwargs):
		self.name = name
<|endoftext|>


<commit_before><commit_msg>Goals: prevent division by zero<commit_after><|endoftext|>


<commit_before>"""
X-Forwarded-For Proxy Fix
=========================

This module provides a middleware that adjusts the WSGI environ based on
``X-Forwarded-`` headers that proxies in front of an application may
set.

When an application is running behind a proxy server, WSGI may see the
request as coming from that server rather than the real client. Proxies
set various headers to track where the request actually came from.

This middleware should only be applied if the application is actually
behind such a proxy, and should be configured with the number of proxies
that are chained in front of it. Not all proxies set all the headers.
Since incoming headers can be faked, you must set how many proxies are
setting each header so the middleware knows what to trust.

.. autoclass:: ProxyFix

:copyright: 2007 Pallets
:license: BSD-3-Clause
"""

class ProxyFix(object):
    """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in
    front of the application may set.

    -   ``X-Forwarded-For`` sets ``REMOTE_ADDR``.
    -   ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``.
    -   ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and
        ``SERVER_PORT``.
    -   ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``.
    -   ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``.

    You must tell the middleware how many proxies set each header so it
    knows what values to trust. It is a security issue to trust values
    that came from the client rather than a proxy.

    The original values of the headers are stored in the WSGI
    environ as ``werkzeug.proxy_fix.orig``, a dict.

    :param app: The WSGI application to wrap.
    :param x_for: Number of values to trust for ``X-Forwarded-For``.
    :param x_proto: Number of values to trust for ``X-Forwarded-Proto``.
    :param x_host: Number of values to trust for ``X-Forwarded-Host``.
    :param x_port: Number of values to trust for ``X-Forwarded-Port``.
    :param x_prefix: Number of values to trust for
        ``X-Forwarded-Prefix``.

    .. code-block:: python

        from werkzeug.middleware.proxy_fix import ProxyFix
        # App is behind one proxy that sets the -For and -Host headers.
        app = ProxyFix(app, x_for=1, x_host=1)

    .. versionchanged:: 1.0
        Deprecated code has been removed:

        *   The ``num_proxies`` argument and attribute.
        *   The ``get_remote_addr`` method.
        *   The environ keys ``orig_remote_addr``,
            ``orig_wsgi_url_scheme``, and ``orig_http_host``.

    .. versionchanged:: 0.15
        All headers support multiple values. The ``num_proxies``
        argument is deprecated. Each header is configured with a
        separate number of trusted proxies.

    .. versionchanged:: 0.15
        Original WSGI environ values are stored in the
        ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``,
        ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated
        and will be removed in 1.0.

    .. versionchanged:: 0.15
        Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``.

    .. versionchanged:: 0.15
        ``X-Forwarded-Host`` and ``X-Forwarded-Port`` modify
        ``SERVER_NAME`` and ``SERVER_PORT``.
    """

    def __init__(self, app, x_for=1, x_proto=1, x_host=0, x_port=0, x_prefix=0):
        self.app = app
        self.x_for = x_for
        self.x_proto = x_proto
        self.x_host = x_host
        self.x_port = x_port
        self.x_prefix = x_prefix

    def _get_trusted_comma(self, trusted, value):
        """Get the real value from a comma-separated header based on the
        configured number of trusted proxies.

        :param trusted: Number of values to trust in the header.
        :param value: Header value to parse.
        :return: The real value, or ``None`` if there are fewer values
            than the number of trusted proxies.

        .. versionadded:: 0.15
        """
        if not (trusted and value):
            return
        values = [x.strip() for x in value.split(",")]
        if len(values) >= trusted:
            return values[-trusted]

    def __call__(self, environ, start_response):
        """Modify the WSGI environ based on the various ``Forwarded``
        headers before calling the wrapped application. Store the
        original environ values in ``werkzeug.proxy_fix.orig_{key}``.
        """
        environ_get = environ.get
        orig_remote_addr = environ_get("REMOTE_ADDR")
        orig_wsgi_url_scheme = environ_get("wsgi.url_scheme")
        orig_http_host = environ_get("HTTP_HOST")
        environ.update(
            {
                "werkzeug.proxy_fix.orig": {
                    "REMOTE_ADDR": orig_remote_addr,
                    "wsgi.url_scheme": orig_wsgi_url_scheme,
                    "HTTP_HOST": orig_http_host,
                    "SERVER_NAME": environ_get("SERVER_NAME"),
                    "SERVER_PORT": environ_get("SERVER_PORT"),
                    "SCRIPT_NAME": environ_get("SCRIPT_NAME"),
                }
            }
        )

        x_for = self._get_trusted_comma(self.x_for, environ_get("HTTP_X_FORWARDED_FOR"))
        if x_for:
            environ["REMOTE_ADDR"] = x_for

        x_proto = self._get_trusted_comma(
            self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO")
        )
        if x_proto:
            environ["wsgi.url_scheme"] = x_proto

        x_host = self._get_trusted_comma(
            self.x_host, environ_get("HTTP_X_FORWARDED_HOST")
        )
        if x_host:
            environ["HTTP_HOST"] = x_host
            parts = x_host.split(":", 1)
            environ["SERVER_NAME"] = parts[0]
            if len(parts) == 2:
                environ["SERVER_PORT"] = parts[1]

        x_port = self._get_trusted_comma(
            self.x_port, environ_get("HTTP_X_FORWARDED_PORT")
        )
        if x_port:
            host = environ.get("HTTP_HOST")
            if host:
                parts = host.split(":", 1)
                host = parts[0] if len(parts) == 2 else host
                environ["HTTP_HOST"] = "%s:%s" % (host, x_port)
            environ["SERVER_PORT"] = x_port

        x_prefix = self._get_trusted_comma(
            self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX")
        )
        if x_prefix:
            environ["SCRIPT_NAME"] = x_prefix

        return self.app(environ, start_response)
<commit_msg>use parse_list_header in ProxyFix<commit_after>"""
X-Forwarded-For Proxy Fix
=========================

This module provides a middleware that adjusts the WSGI environ based on
``X-Forwarded-`` headers that proxies in front of an application may
set.

When an application is running behind a proxy server, WSGI may see the
request as coming from that server rather than the real client. Proxies
set various headers to track where the request actually came from.

This middleware should only be applied if the application is actually
behind such a proxy, and should be configured with the number of proxies
that are chained in front of it. Not all proxies set all the headers.
Since incoming headers can be faked, you must set how many proxies are
setting each header so the middleware knows what to trust.

.. autoclass:: ProxyFix

:copyright: 2007 Pallets
:license: BSD-3-Clause
"""
from werkzeug.http import parse_list_header

class ProxyFix(object):
    """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in
    front of the application may set.

    -   ``X-Forwarded-For`` sets ``REMOTE_ADDR``.
    -   ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``.
    -   ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and
        ``SERVER_PORT``.
    -   ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``.
    -   ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``.

    You must tell the middleware how many proxies set each header so it
    knows what values to trust. It is a security issue to trust values
    that came from the client rather than a proxy.

    The original values of the headers are stored in the WSGI
    environ as ``werkzeug.proxy_fix.orig``, a dict.

    :param app: The WSGI application to wrap.
    :param x_for: Number of values to trust for ``X-Forwarded-For``.
    :param x_proto: Number of values to trust for ``X-Forwarded-Proto``.
    :param x_host: Number of values to trust for ``X-Forwarded-Host``.
    :param x_port: Number of values to trust for ``X-Forwarded-Port``.
    :param x_prefix: Number of values to trust for
        ``X-Forwarded-Prefix``.

    .. code-block:: python

        from werkzeug.middleware.proxy_fix import ProxyFix
        # App is behind one proxy that sets the -For and -Host headers.
        app = ProxyFix(app, x_for=1, x_host=1)

    .. versionchanged:: 1.0
        Deprecated code has been removed:

        *   The ``num_proxies`` argument and attribute.
        *   The ``get_remote_addr`` method.
        *   The environ keys ``orig_remote_addr``,
            ``orig_wsgi_url_scheme``, and ``orig_http_host``.

    .. versionchanged:: 0.15
        All headers support multiple values. The ``num_proxies``
        argument is deprecated. Each header is configured with a
        separate number of trusted proxies.

    .. versionchanged:: 0.15
        Original WSGI environ values are stored in the
        ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``,
        ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated
        and will be removed in 1.0.

    .. versionchanged:: 0.15
        Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``.

    .. versionchanged:: 0.15
        ``X-Forwarded-Host`` and ``X-Forwarded-Port`` modify
        ``SERVER_NAME`` and ``SERVER_PORT``.
    """

    def __init__(self, app, x_for=1, x_proto=1, x_host=0, x_port=0, x_prefix=0):
        self.app = app
        self.x_for = x_for
        self.x_proto = x_proto
        self.x_host = x_host
        self.x_port = x_port
        self.x_prefix = x_prefix

    def _get_real_value(self, trusted, value):
        """Get the real value from a list header based on the configured
        number of trusted proxies.

        :param trusted: Number of values to trust in the header.
        :param value: Comma separated list header value to parse.
        :return: The real value, or ``None`` if there are fewer values
            than the number of trusted proxies.

        .. versionchanged:: 1.0
            Renamed from ``_get_trusted_comma``.

        .. versionadded:: 0.15
        """
        if not (trusted and value):
            return
        values = parse_list_header(value)
        if len(values) >= trusted:
            return values[-trusted]

    def __call__(self, environ, start_response):
        """Modify the WSGI environ based on the various ``Forwarded``
        headers before calling the wrapped application. Store the
        original environ values in ``werkzeug.proxy_fix.orig_{key}``.
        """
        environ_get = environ.get
        orig_remote_addr = environ_get("REMOTE_ADDR")
        orig_wsgi_url_scheme = environ_get("wsgi.url_scheme")
        orig_http_host = environ_get("HTTP_HOST")
        environ.update(
            {
                "werkzeug.proxy_fix.orig": {
                    "REMOTE_ADDR": orig_remote_addr,
                    "wsgi.url_scheme": orig_wsgi_url_scheme,
                    "HTTP_HOST": orig_http_host,
                    "SERVER_NAME": environ_get("SERVER_NAME"),
                    "SERVER_PORT": environ_get("SERVER_PORT"),
                    "SCRIPT_NAME": environ_get("SCRIPT_NAME"),
                }
            }
        )

        x_for = self._get_real_value(self.x_for, environ_get("HTTP_X_FORWARDED_FOR"))
        if x_for:
            environ["REMOTE_ADDR"] = x_for

        x_proto = self._get_real_value(
            self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO")
        )
        if x_proto:
            environ["wsgi.url_scheme"] = x_proto

        x_host = self._get_real_value(self.x_host, environ_get("HTTP_X_FORWARDED_HOST"))
        if x_host:
            environ["HTTP_HOST"] = x_host
            parts = x_host.split(":", 1)
            environ["SERVER_NAME"] = parts[0]
            if len(parts) == 2:
                environ["SERVER_PORT"] = parts[1]

        x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT"))
        if x_port:
            host = environ.get("HTTP_HOST")
            if host:
                parts = host.split(":", 1)
                host = parts[0] if len(parts) == 2 else host
                environ["HTTP_HOST"] = "%s:%s" % (host, x_port)
            environ["SERVER_PORT"] = x_port

        x_prefix = self._get_real_value(
            self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX")
        )
        if x_prefix:
            environ["SCRIPT_NAME"] = x_prefix

        return self.app(environ, start_response)
<|endoftext|>


<commit_before>"""
Flow Manager

NOTE: this class should be created by singleton factory in factory.py

this class is responsible for
    1. register a user's flow
    2. loop up flow by user id

Author: Ming Fang <mingf@cs.cmu.edu>
"""

import logging
from weiss.flows.flow import Flow

logger = logging.getLogger(__name__)

class FlowManager:
    def __init__(self):
        self._flowTable = {}
        self.next_userid = 2147483647

    def register(self, uid, flow):
        """Register a user's flow object

        :param uid: the user id
        :param flow: the flow obj associated with the user
        :return: void
        """
        self._flowTable[uid] = flow
        return

    def lookUp(self, uid):
        """Look up a flow given a user id, a int

        :param uid: the user id to be looked up, get it by request.user
        :return: the flow obj associated with the given user, or None if not found
        """
        return self._flowTable.get(uid, None)

    def new(self, request=None):
        if request is None:
            flow = Flow(self.next_userid)
            self.next_userid -= 1
        else:
            flow = Flow(request.user.id, request.user, request)
        self.register(request.user_id, flow)
        return flow

    def delete(self, user):
        if user in self._flowTable:
            del self._flowTable[user]
<commit_msg>minor fix<commit_after>"""
Flow Manager

NOTE: this class should be created by singleton factory in factory.py

this class is responsible for
    1. register a user's flow
    2. loop up flow by user id

Author: Ming Fang <mingf@cs.cmu.edu>
"""

import logging
from weiss.flows.flow import Flow

logger = logging.getLogger(__name__)

class FlowManager:
    def __init__(self):
        self._flowTable = {}
        self.next_userid = 2147483647

    def register(self, uid, flow):
        """Register a user's flow object

        :param uid: the user id
        :param flow: the flow obj associated with the user
        :return: void
        """
        self._flowTable[uid] = flow
        return

    def lookUp(self, uid):
        """Look up a flow given a user id, a int

        :param uid: the user id to be looked up, get it by request.user
        :return: the flow obj associated with the given user, or None if not found
        """
        return self._flowTable.get(uid, None)

    def new(self, request=None):
        if request is None:
            flow = Flow(self.next_userid)
            self.next_userid -= 1
        else:
            flow = Flow(request.user.id, request.user, request)
        self.register(flow.user_id, flow)
        return flow

    def delete(self, user):
        if user in self._flowTable:
            del self._flowTable[user]
<|endoftext|>


<commit_before>import argparse
import numpy as np
import os.path as osp

import chainer
from chainer import training
from chainer.training import extensions

from chainercv.datasets import TransformDataset
from chainercv.datasets import VOCSemanticSegmentationDataset
from chainercv.extensions import SemanticSegmentationVisReport
from chainercv import transforms

from fcn32s import FCN32s

class TestModeEvaluator(extensions.Evaluator):

    def evaluate(self):
        model = self.get_target('main')
        model.train = False
        ret = super(TestModeEvaluator, self).evaluate()
        model.train = True
        return ret

def main():
    parser = argparse.ArgumentParser(
        description='ChainerCV Semantic Segmentation example with FCN')
    parser.add_argument('--batch_size', '-b', type=int, default=1,
                        help='Number of images in each mini-batch')
    parser.add_argument('--iteration', '-i', type=int, default=50000,
                        help='Number of iteration to carry out')
    parser.add_argument('--gpu', '-g', type=int, default=-1,
                        help='GPU ID (negative value indicates CPU)')
    parser.add_argument('--lr', '-l', type=float, default=1e-10,
                        help='Learning rate of the optimizer')
    parser.add_argument('--out', '-o', default='result',
                        help='Directory to output the result')
    parser.add_argument('--resume', '-r', default='',
                        help='Resume the training from snapshot')
    args = parser.parse_args()

    print('GPU: {}'.format(args.gpu))
    print('# Minibatch-size: {}'.format(args.batch_size))
    print('# iteration: {}'.format(args.iteration))
    print('')
    batch_size = args.batch_size
    iteration = args.iteration
    gpu = args.gpu
    lr = args.lr
    out = args.out
    resume = args.resume

    # prepare datasets
    def transform(in_data):
        img, label = in_data
        vgg_subtract_bgr = np.array(
            [103.939, 116.779, 123.68], np.float32)[:, None, None]
        img -= vgg_subtract_bgr
        img = transforms.pad(img, size=(512, 512), bg_value=0)
        label = transforms.pad(label, size=(512, 512), bg_value=-1)
        return img, label

    train_data = VOCSemanticSegmentationDataset(mode='train')
    test_data = VOCSemanticSegmentationDataset(mode='val')
    train_data = TransformDataset(train_data, transform)
    test_data = TransformDataset(test_data, transform)

    # set up FCN32s
    n_class = 21
    model = FCN32s(n_class=n_class)
    if gpu != -1:
        model.to_gpu(gpu)
        chainer.cuda.get_device(gpu).use()

    # prepare an optimizer
    optimizer = chainer.optimizers.MomentumSGD(lr=lr, momentum=0.99)
    optimizer.setup(model)
    optimizer.add_hook(chainer.optimizer.WeightDecay(rate=0.0005))

    # prepare iterators
    train_iter = chainer.iterators.SerialIterator(
        train_data, batch_size=batch_size)
    test_iter = chainer.iterators.SerialIterator(
        test_data, batch_size=1, repeat=False, shuffle=False)

    updater = training.StandardUpdater(train_iter, optimizer, device=gpu)
    trainer = training.Trainer(updater, (iteration, 'iteration'), out=out)

    val_interval = 3000, 'iteration'
    log_interval = 100, 'iteration'

    trainer.extend(
        TestModeEvaluator(test_iter, model, device=gpu), trigger=val_interval)

    # reporter related
    trainer.extend(extensions.LogReport(trigger=log_interval))
    trainer.extend(extensions.PrintReport(
        ['iteration', 'main/time',
         'main/loss', 'validation/main/loss',
         'main/accuracy', 'validation/main/accuracy',
         'main/accuracy_cls', 'validation/main/accuracy_cls',
         'main/iu', 'validation/main/iu',
         'main/fwavacc', 'validation/main/fwavacc']),
        trigger=log_interval)
    trainer.extend(extensions.ProgressBar(update_interval=10))

    # visualize training
    trainer.extend(
        extensions.PlotReport(
            ['main/loss', 'validation/main/loss'],
            trigger=log_interval, file_name='loss.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/accuracy', 'validation/main/accuracy'],
            trigger=log_interval, file_name='accuracy.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/accuracy_cls', 'validation/main/accuracy_cls'],
            trigger=log_interval, file_name='accuracy_cls.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/iu', 'validation/main/iu'],
            trigger=log_interval, file_name='iu.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/fwavacc', 'validation/main/fwavacc'],
            trigger=log_interval, file_name='fwavacc.png')
    )

    def vis_transform(in_data):
        vgg_subtract_bgr = np.array(
            [103.939, 116.779, 123.68], np.float32)[:, None, None]
        img, label = in_data
        img += vgg_subtract_bgr
        img, label = transforms.chw_to_pil_image((img, label))
        return img, label

    trainer.extend(
        SemanticSegmentationVisReport(
            range(10),  # visualize outputs for the first 10 data of test_data
            test_data,
            model,
            n_class=n_class,
            predict_func=model.predict,  # a function to predict output
            vis_transform=vis_transform
        ),
        trigger=val_interval, invoke_before_training=True)

    trainer.extend(extensions.dump_graph('main/loss'))

    if resume:
        chainer.serializers.load_npz(osp.expanduser(resume), trainer)

    trainer.run()

if __name__ == '__main__':
    main()
<commit_msg>fix usage of pad in an example<commit_after>import argparse
import numpy as np
import os.path as osp

import chainer
from chainer import training
from chainer.training import extensions

from chainercv.datasets import TransformDataset
from chainercv.datasets import VOCSemanticSegmentationDataset
from chainercv.extensions import SemanticSegmentationVisReport
from chainercv import transforms

from fcn32s import FCN32s

class TestModeEvaluator(extensions.Evaluator):

    def evaluate(self):
        model = self.get_target('main')
        model.train = False
        ret = super(TestModeEvaluator, self).evaluate()
        model.train = True
        return ret

def main():
    parser = argparse.ArgumentParser(
        description='ChainerCV Semantic Segmentation example with FCN')
    parser.add_argument('--batch_size', '-b', type=int, default=1,
                        help='Number of images in each mini-batch')
    parser.add_argument('--iteration', '-i', type=int, default=50000,
                        help='Number of iteration to carry out')
    parser.add_argument('--gpu', '-g', type=int, default=-1,
                        help='GPU ID (negative value indicates CPU)')
    parser.add_argument('--lr', '-l', type=float, default=1e-10,
                        help='Learning rate of the optimizer')
    parser.add_argument('--out', '-o', default='result',
                        help='Directory to output the result')
    parser.add_argument('--resume', '-r', default='',
                        help='Resume the training from snapshot')
    args = parser.parse_args()

    print('GPU: {}'.format(args.gpu))
    print('# Minibatch-size: {}'.format(args.batch_size))
    print('# iteration: {}'.format(args.iteration))
    print('')
    batch_size = args.batch_size
    iteration = args.iteration
    gpu = args.gpu
    lr = args.lr
    out = args.out
    resume = args.resume

    # prepare datasets
    def transform(in_data):
        img, label = in_data
        vgg_subtract_bgr = np.array(
            [103.939, 116.779, 123.68], np.float32)[:, None, None]
        img -= vgg_subtract_bgr
        img = transforms.resize_contain(img, size=(512, 512), bg_value=0)
        label = transforms.resize_contain(label, size=(512, 512), bg_value=-1)
        return img, label

    train_data = VOCSemanticSegmentationDataset(mode='train')
    test_data = VOCSemanticSegmentationDataset(mode='val')
    train_data = TransformDataset(train_data, transform)
    test_data = TransformDataset(test_data, transform)

    # set up FCN32s
    n_class = 21
    model = FCN32s(n_class=n_class)
    if gpu != -1:
        model.to_gpu(gpu)
        chainer.cuda.get_device(gpu).use()

    # prepare an optimizer
    optimizer = chainer.optimizers.MomentumSGD(lr=lr, momentum=0.99)
    optimizer.setup(model)
    optimizer.add_hook(chainer.optimizer.WeightDecay(rate=0.0005))

    # prepare iterators
    train_iter = chainer.iterators.SerialIterator(
        train_data, batch_size=batch_size)
    test_iter = chainer.iterators.SerialIterator(
        test_data, batch_size=1, repeat=False, shuffle=False)

    updater = training.StandardUpdater(train_iter, optimizer, device=gpu)
    trainer = training.Trainer(updater, (iteration, 'iteration'), out=out)

    val_interval = 3000, 'iteration'
    log_interval = 100, 'iteration'

    trainer.extend(
        TestModeEvaluator(test_iter, model, device=gpu), trigger=val_interval)

    # reporter related
    trainer.extend(extensions.LogReport(trigger=log_interval))
    trainer.extend(extensions.PrintReport(
        ['iteration', 'main/time',
         'main/loss', 'validation/main/loss',
         'main/accuracy', 'validation/main/accuracy',
         'main/accuracy_cls', 'validation/main/accuracy_cls',
         'main/iu', 'validation/main/iu',
         'main/fwavacc', 'validation/main/fwavacc']),
        trigger=log_interval)
    trainer.extend(extensions.ProgressBar(update_interval=10))

    # visualize training
    trainer.extend(
        extensions.PlotReport(
            ['main/loss', 'validation/main/loss'],
            trigger=log_interval, file_name='loss.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/accuracy', 'validation/main/accuracy'],
            trigger=log_interval, file_name='accuracy.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/accuracy_cls', 'validation/main/accuracy_cls'],
            trigger=log_interval, file_name='accuracy_cls.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/iu', 'validation/main/iu'],
            trigger=log_interval, file_name='iu.png')
    )
    trainer.extend(
        extensions.PlotReport(
            ['main/fwavacc', 'validation/main/fwavacc'],
            trigger=log_interval, file_name='fwavacc.png')
    )

    def vis_transform(in_data):
        vgg_subtract_bgr = np.array(
            [103.939, 116.779, 123.68], np.float32)[:, None, None]
        img, label = in_data
        img += vgg_subtract_bgr
        img, label = transforms.chw_to_pil_image((img, label))
        return img, label

    trainer.extend(
        SemanticSegmentationVisReport(
            range(10),  # visualize outputs for the first 10 data of test_data
            test_data,
            model,
            n_class=n_class,
            predict_func=model.predict,  # a function to predict output
            vis_transform=vis_transform
        ),
        trigger=val_interval, invoke_before_training=True)

    trainer.extend(extensions.dump_graph('main/loss'))

    if resume:
        chainer.serializers.load_npz(osp.expanduser(resume), trainer)

    trainer.run()

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


<commit_before>import json
import urllib
import codecs
import requests

DATA_URL = 'http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz'
CONFIG_URL = 'http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/wczytaj-konfiguracje'

HEADERS = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Host': 'monitoring.krakow.pios.gov.pl',
    'Origin': 'http://monitoring.krakow.pios.gov.pl',
    'Referer': 'http://monitoring.krakow.pios.gov.pl',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest'
}

stations = {
    4: 'Tarnow',
    5: 'Skawina',
    6: 'Aleja Krasinskiego',
    7: 'Nowa Huta',
    8: 'Nowy Sacz',
    9: 'Zakopane',
    10: 'Olkusz',
    11: 'Trzebinia',
    12: 'Szymbark',
    15: 'Szarow',
    16: 'Krakow-Kurdwanow',
    19: 'Limanowa P',
    20: 'Szczawnica P',
    21: 'Kety P',
    23: 'Slomniki P',
    24: 'Myslenice P',
    25: 'Bukowno P',
    29: 'Sucha Beskidzka II',
    148: 'Szarow Spokojna'
}

channels = {'pl_PL': {
        47: 'Tlenki Azotu',
        49: 'Benzen',
        50: 'Tlenek Wegla',
        53: 'Tlenek Azotu',
        54: 'Dwutlenek Azotu',
        57: 'PM10',
        61: 'Dwutlenek Siarki',
        146: 'Ozon',
        211: 'PM25'},
    'en_US': {
        47: 'Nitrogen Monoxides',
        49: 'Benzene',
        50: 'Carbon Monoxide',
        53: 'Nitrogen Monoxide',
        54: 'Nitrogen Dioxide',
        57: 'PM10',
        61: 'Sulfur Dioxide',
        146: 'Ozone',
        211: 'PM25'
    }
}

class MeasPeriod:
    DAY = 'day'
    MONTH = 'month'
    YEAR = 'year'

class ViewType:
    STATION = 'station'
    PARAM = 'parameter'

skip = ('avg', 'data', 'thresholds', 'thresholdsForAvg')
labels = (
    'timestamp', 'value', 'aggType', 'chartTooltipContent', 'count', 'coverageRate', 'decimals', 'extStartTime',
    'interval',
    'isAvgValid', 'label', 'ord', 'paramCode', 'paramId', 'paramLabel', 'paramPostfix', 'retroCount',
    'scaleMax', 'scaleMin', 'startTime', 'unit', 'unitLabel')

def flatten(data, separator='.', prefix=''):
    """
    Flattens multilevel dicts into single level dicts combining keys for subsequent levels using specified separator.

    If dictionary contains element with empty dictionary as a value, it will be removed from the result

    Args:
        data: dictionary to flatten
        separator: used when creating flattened key identifiers
        prefix: optional prefix for all key identifiers

    Returns:
        flattened dict if 'data' parameter was dict or empty dict otherwise
    """
    storage = {}

    if isinstance(data, dict):
        for key, value in data.items():
            new_prefix = key if prefix == '' else prefix + separator + key
            if isinstance(value, dict):
                storage.update(flatten(value, separator=separator, prefix=new_prefix))
            else:
                storage[new_prefix] = value

    return storage

class ResponseError(Exception):
    """
    Thrown when problems with server response occur.
    """
    pass

def xml_http_request(url, headers, data):
    """
    Sends XMLHttpRequest to given address with header and data

    Args:
        url: to send request to
        headers: JSON formatted header, HTTP encoded
        data: JSON formatted data, HTTP encoded

    Returns:
        dict of JSON response from page

    Raises:
        ResponseError if couldn't retrieve valid data

    """
    raw_result = requests.post(url=url, headers=headers, data=data)
    if raw_result.status_code != 200:
        raise ResponseError('Server returned error {}: {}'.format(raw_result.status_code, raw_result.text))

    result = json.loads(raw_result.content)

    if not result['success']:
        raise ResponseError('Server returned error \'{}\''.format(result['error']))

    return result

class Config:
    def __init__(self, url):

        self.config = None
        self.url = url
        self.update()

    def update(self):
        """
        Sends request to WIOS server and updates instance with new data (they are originally
        used to configure web page)

        Returns:
            dict with retrieved raw config

        Raises:
            ResponseError if couldn't retrieve valid data
        """
        self.config = xml_http_request(CONFIG_URL, headers=HEADERS, data={'measType': 'auto'})['config']
        return self.config

    def get_raw_config(self):
        """
        Returns internally stored (with update() method) config from WIOS server

        Returns:
            dict with raw config

        Raises:
            ResponseError if couldn't retrieve valid data
        """
        return self.config

    def get_raw_channels(self):
        return self.config['channels']

    def get_raw_stations(self):
        return self.config['stations']

    def get_raw_params(self):
        return self.config['params']

    def get_raw_thresholds(self):
        return self.config['thresholds']

def get_raw_data(encoded_query):
    """
    Sends request to WIOS server and retrieves data

    Args:
        encoded_query: of query parameters

    Returns:
        dict of JSON response from page

    Raises:
        ResponseError if couldn't retrieve valid data
    """
    raw_result = requests.post(DATA_URL, headers=HEADERS, data=encoded_query)
    if raw_result.status_code != 200:
        raise ResponseError('Server returned error {}: {}'.format(raw_result.status_code, raw_result.text))

    result = json.loads(raw_result.content)

    if not result['success']:
        raise ResponseError('Server returned error \'{}\''.format(result['error']))

    return result

def prepare_query(year, month, day, station, channels, meas_type='Auto', view_type=ViewType.STATION, meas_period=MeasPeriod.DAY):
    """
    Prepares encoded JSON query to retrieve data

    Args:
        year: integer year
        month: integer month
        day: integer day
        station: integer
        channels: list of integers representing pollution types
        meas_type: type of measurement TODO: check other types of measurement
        view_type: whether server has to return data by pollution parameter for all of the stations or for one station
            with all parameters. Available defines are in class ViewType
        meas_period: can be one of defined in class MeasPeriod and defines period of measurements which can be daily,
            monthly and yearly

    Returns:
        string of encoded JSON query
    """
    header = {
        "measType": meas_type,
        "viewType": view_type,
        "dateRange": meas_period,
        "date": "{}.{}.{}".format(day, month, year),
        "viewTypeEntityId": station,
        "channels": channels
    }

    return "query=" + urllib.quote(json.dumps(header, separators=(",", ":")))

if __name__ == '__main__':
    from pprint import pprint
    #from samples import SAMPLE_RESPONSE

    # storage = flatten(SAMPLE_RESPONSE['data'])
    # pprint(storage)
    # if SAMPLE_RESPONSE['success']:
    #    print "\n".join([str(x) for x in flatten(SAMPLE_RESPONSE['data'])])
    # else:
    #    print "Data retrieval failed"

    #prepared_query = prepare_query(2015, 5, 17, 5, [31, 36, 34, 30, 32])
    #pprint(prepared_query)
    #result = get_raw_data(prepared_query)
    config = Config(CONFIG_URL)
    result = config.get_raw_stations()
    pprint(result)
<commit_msg>add validation of date in header<commit_after>import json
import urllib
import codecs
import requests

DATA_URL = 'http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/pobierz'
CONFIG_URL = 'http://monitoring.krakow.pios.gov.pl/dane-pomiarowe/wczytaj-konfiguracje'

HEADERS = {
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Host': 'monitoring.krakow.pios.gov.pl',
    'Origin': 'http://monitoring.krakow.pios.gov.pl',
    'Referer': 'http://monitoring.krakow.pios.gov.pl',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest'
}

stations = {
    4: 'Tarnow',
    5: 'Skawina',
    6: 'Aleja Krasinskiego',
    7: 'Nowa Huta',
    8: 'Nowy Sacz',
    9: 'Zakopane',
    10: 'Olkusz',
    11: 'Trzebinia',
    12: 'Szymbark',
    15: 'Szarow',
    16: 'Krakow-Kurdwanow',
    19: 'Limanowa P',
    20: 'Szczawnica P',
    21: 'Kety P',
    23: 'Slomniki P',
    24: 'Myslenice P',
    25: 'Bukowno P',
    29: 'Sucha Beskidzka II',
    148: 'Szarow Spokojna'
}

channels = {'pl_PL': {
        47: 'Tlenki Azotu',
        49: 'Benzen',
        50: 'Tlenek Wegla',
        53: 'Tlenek Azotu',
        54: 'Dwutlenek Azotu',
        57: 'PM10',
        61: 'Dwutlenek Siarki',
        146: 'Ozon',
        211: 'PM25'},
    'en_US': {
        47: 'Nitrogen Monoxides',
        49: 'Benzene',
        50: 'Carbon Monoxide',
        53: 'Nitrogen Monoxide',
        54: 'Nitrogen Dioxide',
        57: 'PM10',
        61: 'Sulfur Dioxide',
        146: 'Ozone',
        211: 'PM25'
    }
}

class MeasPeriod:
    DAY = 'day'
    MONTH = 'month'
    YEAR = 'year'

class ViewType:
    STATION = 'station'
    PARAM = 'parameter'

skip = ('avg', 'data', 'thresholds', 'thresholdsForAvg')
labels = (
    'timestamp', 'value', 'aggType', 'chartTooltipContent', 'count', 'coverageRate', 'decimals', 'extStartTime',
    'interval',
    'isAvgValid', 'label', 'ord', 'paramCode', 'paramId', 'paramLabel', 'paramPostfix', 'retroCount',
    'scaleMax', 'scaleMin', 'startTime', 'unit', 'unitLabel')

def flatten(data, separator='.', prefix=''):
    """
    Flattens multilevel dicts into single level dicts combining keys for subsequent levels using specified separator.

    If dictionary contains element with empty dictionary as a value, it will be removed from the result

    Args:
        data: dictionary to flatten
        separator: used when creating flattened key identifiers
        prefix: optional prefix for all key identifiers

    Returns:
        flattened dict if 'data' parameter was dict or empty dict otherwise
    """
    storage = {}

    if isinstance(data, dict):
        for key, value in data.items():
            new_prefix = key if prefix == '' else prefix + separator + key
            if isinstance(value, dict):
                storage.update(flatten(value, separator=separator, prefix=new_prefix))
            else:
                storage[new_prefix] = value

    return storage

class ResponseError(Exception):
    """
    Thrown when problems with server response occur.
    """
    pass

def xml_http_request(url, headers, data):
    """
    Sends XMLHttpRequest to given address with header and data

    Args:
        url: to send request to
        headers: JSON formatted header, HTTP encoded
        data: JSON formatted data, HTTP encoded

    Returns:
        dict of JSON response from page

    Raises:
        ResponseError if couldn't retrieve valid data

    """
    raw_result = requests.post(url=url, headers=headers, data=data)
    if raw_result.status_code != 200:
        raise ResponseError('Server returned error {}: {}'.format(raw_result.status_code, raw_result.text))

    result = json.loads(raw_result.content)

    if not result['success']:
        raise ResponseError('Server returned error \'{}\''.format(result['error']))

    return result

class Config:
    def __init__(self, url):

        self.config = None
        self.url = url
        self.update()

    def update(self):
        """
        Sends request to WIOS server and updates instance with new data (they are originally
        used to configure web page)

        Returns:
            dict with retrieved raw config

        Raises:
            ResponseError if couldn't retrieve valid data
        """
        self.config = xml_http_request(CONFIG_URL, headers=HEADERS, data={'measType': 'auto'})['config']
        return self.config

    def get_raw_config(self):
        """
        Returns internally stored (with update() method) config from WIOS server

        Returns:
            dict with raw config

        Raises:
            ResponseError if couldn't retrieve valid data
        """
        return self.config

    def get_raw_channels(self):
        return self.config['channels']

    def get_raw_stations(self):
        return self.config['stations']

    def get_raw_params(self):
        return self.config['params']

    def get_raw_thresholds(self):
        return self.config['thresholds']

def get_raw_data(encoded_query):
    """
    Sends request to WIOS server and retrieves data

    Args:
        encoded_query: of query parameters

    Returns:
        dict of JSON response from page

    Raises:
        ResponseError if couldn't retrieve valid data
    """
    raw_result = xml_http_request(DATA_URL, headers=HEADERS, data=encoded_query)

    return raw_result

def prepare_query(station, channels, year, month=None, day=None,
                  meas_type='Auto', view_type=ViewType.STATION, meas_period=MeasPeriod.DAY):
    """
    Prepares encoded JSON query to retrieve data

    Args:
        station: integer
        channels: list of integers representing pollution types
        year: integer year
        month: integer month
        day: integer day
        meas_type: type of measurement TODO: check other types of measurement
        view_type: whether server has to return data by pollution parameter for all of the stations or for one station
            with all parameters. Available defines are in class ViewType
        meas_period: can be one of defined in class MeasPeriod and defines period of measurements which can be daily,
            monthly and yearly

    Returns:
        string of encoded JSON query
    """

    if meas_period == MeasPeriod.YEAR:
        date = str(year)
    elif meas_period == MeasPeriod.MONTH and month is not None:
        date = str(month) + '.' + str(year)
    elif month is not None and day is not None:
        date = "{}.{}.{}".format(day, month, year)
    else:
        raise ValueError('Not enough parameters to create date for period of type \'{}\''.format(meas_period))

    header = {
        "measType": meas_type,
        "viewType": view_type,
        "dateRange": meas_period,
        "date": date,
        "viewTypeEntityId": station,
        "channels": channels
    }

    return "query=" + urllib.quote(json.dumps(header, separators=(",", ":")))

if __name__ == '__main__':
    from pprint import pprint
    #from samples import SAMPLE_RESPONSE

    # storage = flatten(SAMPLE_RESPONSE['data'])
    # pprint(storage)
    # if SAMPLE_RESPONSE['success']:
    #    print "\n".join([str(x) for x in flatten(SAMPLE_RESPONSE['data'])])
    # else:
    #    print "Data retrieval failed"

    prepared_query = prepare_query(station=5, channels=[31, 36, 34, 30, 32],
                                   year=2015, month=5, day=17, meas_period=MeasPeriod.MONTH)
    #pprint(prepared_query)
    result = get_raw_data(prepared_query)
    #config = Config(CONFIG_URL)
    #result = config.get_raw_stations()
    pprint(result)
<|endoftext|>


<commit_before># encoding: utf-8

import sys
from workflow import Workflow, ICON_WEB, ICON_ERROR, web

def format_strings_from_quote(ticker, quote_data):
    usd_query = 'USDT_' + ticker.upper()
    last = '%.2f' % float(quote_data[usd_query]['last'])
    high = '%.2f' % float(quote_data[usd_query]['high24hr'])
    low = '%.2f' % float(quote_data[usd_query]['low24hr'])
    formatted = {}
    formatted['title'] = ticker.upper() + ': $' + last
    formatted['subtitle'] = '24hr High: ' + high + ' 24hr low ' + low
    return formatted

def main(wf):
    # Get query from Alfred
    if len(wf.args):
        query = wf.args[0]
    else:
        query = None

    url = 'https://poloniex.com/public?command=returnTicker'
    r = web.get(url)

    # throw an error if request failed
    # Workflow will catch this and show it to the user
    r.raise_for_status()

    # Parse the JSON returned by pinboard and extract the posts
    result = r.json()
    if query:
        usd_query = 'USDT_' + query.upper()
        usd_link = 'https://poloniex.com/exchange#' + usd_query
        if usd_query in result:
            formatted = format_strings_from_quote(query, result)
            wf.add_item(title=formatted['title'],
                        subtitle=formatted['subtitle'],
                        arg=usd_link,
                        valid=True,
                        icon=ICON_WEB)
        else:
            wf.add_item(title='Couldn\'t find a quote for that symbol.',
                        subtitle='Please try again.',
                        icon=ICON_ERROR)
    else:
        formatted = format_strings_from_quote('BTC', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_btc',
                    valid=True,
                    icon='icon/btc.png')

        formatted = format_strings_from_quote('ETH', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_eth',
                    valid=True,
                    icon='icon/eth.png')

        formatted = format_strings_from_quote('LTC', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_ltc',
                    valid=True,
                    icon='icon/ltc.png')

    # Send the results to Alfred as XML
    wf.send_feedback()

if __name__ == u"__main__":
    wf = Workflow()
    sys.exit(wf.run(main))<commit_msg>Remove comment.<commit_after># encoding: utf-8

import sys
from workflow import Workflow, ICON_WEB, ICON_ERROR, web

def format_strings_from_quote(ticker, quote_data):
    usd_query = 'USDT_' + ticker.upper()
    last = '%.2f' % float(quote_data[usd_query]['last'])
    high = '%.2f' % float(quote_data[usd_query]['high24hr'])
    low = '%.2f' % float(quote_data[usd_query]['low24hr'])
    formatted = {}
    formatted['title'] = ticker.upper() + ': $' + last
    formatted['subtitle'] = '24hr High: ' + high + ' 24hr low ' + low
    return formatted

def main(wf):
    # Get query from Alfred
    if len(wf.args):
        query = wf.args[0]
    else:
        query = None

    url = 'https://poloniex.com/public?command=returnTicker'
    r = web.get(url)

    # throw an error if request failed
    # Workflow will catch this and show it to the user
    r.raise_for_status()

    result = r.json()
    if query:
        usd_query = 'USDT_' + query.upper()
        usd_link = 'https://poloniex.com/exchange#' + usd_query
        if usd_query in result:
            formatted = format_strings_from_quote(query, result)
            wf.add_item(title=formatted['title'],
                        subtitle=formatted['subtitle'],
                        arg=usd_link,
                        valid=True,
                        icon=ICON_WEB)
        else:
            wf.add_item(title='Couldn\'t find a quote for that symbol.',
                        subtitle='Please try again.',
                        icon=ICON_ERROR)
    else:
        formatted = format_strings_from_quote('BTC', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_btc',
                    valid=True,
                    icon='icon/btc.png')

        formatted = format_strings_from_quote('ETH', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_eth',
                    valid=True,
                    icon='icon/eth.png')

        formatted = format_strings_from_quote('LTC', result)
        wf.add_item(title=formatted['title'],
                    subtitle=formatted['subtitle'],
                    arg='https://poloniex.com/exchange#usdt_ltc',
                    valid=True,
                    icon='icon/ltc.png')

    # Send the results to Alfred as XML
    wf.send_feedback()

if __name__ == u"__main__":
    wf = Workflow()
    sys.exit(wf.run(main))<|endoftext|>