<commit_before># coding=utf-8
__author__ = "AstroPrint Product Team <<EMAIL>>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2016 3DaGoGo, Inc - Released under terms of the AGPLv3 License"

import threading
import logging
import time
import os
import struct
import makerbot_driver.errors

from serial import SerialException

from makerbot_driver import MachineFactory

from octoprint.settings import settings
from octoprint.events import eventManager, Events
from octoprint.util import getExceptionString

from astroprint.printer import Printer
from astroprint.printer.s3g.printjob import PrintJobS3G
from astroprint.printfiles.x3g import PrintFileManagerX3g
from astroprint.printfiles import FileDestinations
from astroprint.printer.manager import printerManager

class PrinterS3g(Printer):
	driverName = 's3g'
	allowTerminal = False

	_fileManagerClass = PrintFileManagerX3g

	CONNECT_MAX_RETRIES = 10
	UPDATE_INTERVAL = 3 #secs

	def __init__(self):
		self._comm = None
		self._profile = None
		self._gcodeParser = None
		self._port = None
		self._baudrate = None
		self._errorValue = ''
		self._botThread = None
		self._printJob = None
		self._heatingUp = False
		self._firmwareVersion = None
		self._selectedTool = 0
		self._printingSpeed = 100
		self._printingFlow = 100
		self._previousSelectedTool = 0
		self._logger = logging.getLogger(__name__)
		self._state_condition = threading.Condition()
		super(PrinterS3g, self).__init__()

	def rampdown(self):
		super(PrinterS3g, self).rampdown()

		if self._comm:
			if self._comm.is_open():
				self._comm.close()

			del self._comm

	def isReady(self):
		return self.isOperational() #and not self._comm.isStreaming()

	def isHeatingUp(self):
		return self._heatingUp

	def getStateString(self):
		if self._state == self.STATE_NONE:
			return "Offline"
		#if self._state == self.STATE_OPEN_SERIAL:
		#	return "Opening serial port"
		#if self._state == self.STATE_DETECT_SERIAL:
		#	return "Detecting serial port"
		#if self._state == self.STATE_DETECT_BAUDRATE:
		#	return "Detecting baudrate"
		if self._state == self.STATE_CONNECTING:
			return "Connecting"
		if self._state == self.STATE_OPERATIONAL:
			return "Operational"
		if self._state == self.STATE_PRINTING:
			#if self.isSdFileSelected():
			#	return "Printing from SD"
			#elif self.isStreaming():
			#	return "Sending file to SD"
			#else:
			return "Printing"
		if self._state == self.STATE_PAUSED:
			return "Paused"
		if self._state == self.STATE_CLOSED:
			return "Closed"
		if self._state == self.STATE_ERROR:
			return "Error: %s" % (self.getShortErrorString())
		if self._state == self.STATE_CLOSED_WITH_ERROR:
			return "Closed with Error: %s" % (self.getShortErrorString())
		if self._state == self.STATE_TRANSFERING_FILE:
			return "Transfering file to SD"
		return "?%d?" % (self._state)

	def getCurrentConnection(self):
		return self.getStateString(), self._port, self._baudrate

	def getShortErrorString(self):
		if len(self._errorValue) < 50:
			return self._errorValue
		return self._errorValue[:50] + "..."

	def getErrorString(self):
		return self._errorValue

	def _changeState(self, newState):
		if self._state == newState:
			return

		oldState = self.getStateString()
		self._state = newState
		self._logger.info('Changing printer state from [%s] to [%s]' % (oldState, self.getStateString()))

		# forward relevant state changes to gcode manager
		if oldState == self.STATE_PRINTING:
			#if self._currentFile is not None:
			#	if state == self.STATE_OPERATIONAL:
			#		self._fileManager.printSucceeded(self._currentFile["filename"], self._comm.getPrintTime())
			#	elif state == self.STATE_CLOSED or state == self.STATE_ERROR or state == self.STATE_CLOSED_WITH_ERROR:
			#		self._fileManager.printFailed(self._currentFile["filename"], self._comm.getPrintTime())
			self._fileManager.resumeAnalysis() # printing done, put those cpu cycles to good use

		if newState == self.STATE_PRINTING:
			self._fileManager.pauseAnalysis() # do not analyse gcode while printing
		elif newState == self.STATE_CLOSED:
			eventManager().fire(Events.DISCONNECTED)
		elif newState == self.STATE_CONNECTING:
			eventManager().fire(Events.CONNECTING)

		self.refreshStateData()

	def _work(self):
		import makerbot_driver.MachineFactory

		s = settings()

		retries = self.CONNECT_MAX_RETRIES

		try:
			while True:
				if self.isConnected():
					self._comm.close()

				if retries < 0:
					self._changeState(self.STATE_ERROR)
					self._errorValue = "Error Connecting"
					self._logger.error('Error connecting to printer.')
					self._comm = None
					break

				else:
					try:
						result = makerbot_driver.MachineFactory().build_from_port(self._port, condition= self._state_condition)
<commit_msg>raise disconnect event when there's an error in the line<commit_after># coding=utf-8
__author__ = "AstroPrint Product Team <<EMAIL>>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2016 3DaGoGo, Inc - Released under terms of the AGPLv3 License"

import threading
import logging
import time
import os
import struct
import makerbot_driver.errors

from serial import SerialException

from makerbot_driver import MachineFactory

from octoprint.settings import settings
from octoprint.events import eventManager, Events
from octoprint.util import getExceptionString

from astroprint.printer import Printer
from astroprint.printer.s3g.printjob import PrintJobS3G
from astroprint.printfiles.x3g import PrintFileManagerX3g
from astroprint.printfiles import FileDestinations
from astroprint.printer.manager import printerManager

class PrinterS3g(Printer):
	driverName = 's3g'
	allowTerminal = False

	_fileManagerClass = PrintFileManagerX3g

	CONNECT_MAX_RETRIES = 10
	UPDATE_INTERVAL = 3 #secs

	def __init__(self):
		self._comm = None
		self._profile = None
		self._gcodeParser = None
		self._port = None
		self._baudrate = None
		self._errorValue = ''
		self._botThread = None
		self._printJob = None
		self._heatingUp = False
		self._firmwareVersion = None
		self._selectedTool = 0
		self._printingSpeed = 100
		self._printingFlow = 100
		self._previousSelectedTool = 0
		self._logger = logging.getLogger(__name__)
		self._state_condition = threading.Condition()
		super(PrinterS3g, self).__init__()

	def rampdown(self):
		super(PrinterS3g, self).rampdown()

		if self._comm:
			if self._comm.is_open():
				self._comm.close()

			del self._comm

	def isReady(self):
		return self.isOperational() #and not self._comm.isStreaming()

	def isHeatingUp(self):
		return self._heatingUp

	def getStateString(self):
		if self._state == self.STATE_NONE:
			return "Offline"
		#if self._state == self.STATE_OPEN_SERIAL:
		#	return "Opening serial port"
		#if self._state == self.STATE_DETECT_SERIAL:
		#	return "Detecting serial port"
		#if self._state == self.STATE_DETECT_BAUDRATE:
		#	return "Detecting baudrate"
		if self._state == self.STATE_CONNECTING:
			return "Connecting"
		if self._state == self.STATE_OPERATIONAL:
			return "Operational"
		if self._state == self.STATE_PRINTING:
			#if self.isSdFileSelected():
			#	return "Printing from SD"
			#elif self.isStreaming():
			#	return "Sending file to SD"
			#else:
			return "Printing"
		if self._state == self.STATE_PAUSED:
			return "Paused"
		if self._state == self.STATE_CLOSED:
			return "Closed"
		if self._state == self.STATE_ERROR:
			return "Error: %s" % (self.getShortErrorString())
		if self._state == self.STATE_CLOSED_WITH_ERROR:
			return "Closed with Error: %s" % (self.getShortErrorString())
		if self._state == self.STATE_TRANSFERING_FILE:
			return "Transfering file to SD"
		return "?%d?" % (self._state)

	def getCurrentConnection(self):
		return self.getStateString(), self._port, self._baudrate

	def getShortErrorString(self):
		if len(self._errorValue) < 50:
			return self._errorValue
		return self._errorValue[:50] + "..."

	def getErrorString(self):
		return self._errorValue

	def _changeState(self, newState):
		if self._state == newState:
			return

		oldState = self.getStateString()
		self._state = newState
		self._logger.info('Changing printer state from [%s] to [%s]' % (oldState, self.getStateString()))

		# forward relevant state changes to gcode manager
		if oldState == self.STATE_PRINTING:
			#if self._currentFile is not None:
			#	if state == self.STATE_OPERATIONAL:
			#		self._fileManager.printSucceeded(self._currentFile["filename"], self._comm.getPrintTime())
			#	elif state == self.STATE_CLOSED or state == self.STATE_ERROR or state == self.STATE_CLOSED_WITH_ERROR:
			#		self._fileManager.printFailed(self._currentFile["filename"], self._comm.getPrintTime())
			self._fileManager.resumeAnalysis() # printing done, put those cpu cycles to good use

		if newState == self.STATE_PRINTING:
			self._fileManager.pauseAnalysis() # do not analyse gcode while printing
		elif newState == self.STATE_CLOSED:
			eventManager().fire(Events.DISCONNECTED)
		elif newState == self.STATE_ERROR:
			eventManager().fire(Events.DISCONNECTED)
		elif newState == self.STATE_CONNECTING:
			eventManager().fire(Events.CONNECTING)

		self.refreshStateData()

	def _work(self):
		import makerbot_driver.MachineFactory

		s = settings()

		retries = self.CONNECT_MAX_RETRIES

		try:
			while True:
				if self.isConnected():
					self._comm.close()

				if retries < 0:
					self._changeState(self.STATE_ERROR)
					self._errorValue = "Error Connecting"
					self._logger.error('Error connecting to printer.')
					self._comm = None
					break

				else:
					try:
						result = makerbot_driver.MachineFactory().build_from_port(self._port, condition= self._state_condition)

{'fraction_non_alphanumeric': 0.10115250051450916, 'fraction_numerical': 0.0065857172257666186, 'mean_word_length': 4.402445803224014, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5922206', 'n_tokens_mistral': 3535, 'n_tokens_neox': 3124, 'n_words': 765}