class JsonOutput(object): def __init__(self, file, logLimit): self.jsonOutputFile = file self.jsonOutput = {} self.jsonOutputCoins = {} self.jsonOutput["raw_data"] = self.jsonOutputCoins self.jsonOutputLog = RingBuffer(logLimit); def status(self, status, time): self.jsonOutput["last_update"] = time self.jsonOutput["last_status"] = status def printline(self, line): self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write(unicode(json.dumps(self.jsonOutput, ensure_ascii=False, sort_keys=True))) f.close() def statusValue(self, coin, key, value): if(coin not in self.jsonOutputCoins): self.jsonOutputCoins[coin] = {} self.jsonOutputCoins[coin][key] = str(value) def clearStatusValues(self): self.jsonOutputCoins = {}
class DistanceData: def __init__(self, nodeid, buffersize=10): self.nodeid = nodeid self.buffersize = buffersize self.buffer = RingBuffer(buffersize) def add_observation(self, observation): self.buffer.append(observation) def get_filtered_value(self): #TODO implement filtering curr_vals = self.buffer.get() curr_vals.sort() return curr_vals[len(curr_vals)/2]
def run(self): rb = RingBuffer(56) while self.measure: rb.append(self.ser.read(1)[0]) if rb[0] == ord("B") and rb[1] == ord("E") and rb[54] == ord("E") and rb[55] == ord("N"): timestamp = int.from_bytes(bytes(rb[2:6]), byteorder="little") timestamp = timestamp & 0xffffffff data = np.fromstring(bytes(rb[6:54]), dtype="<f") if self.start_time is None: self.start_time = timestamp self.newData.emit([timestamp-self.start_time, data]) self.ser.close()
def run(self): rb = RingBuffer(56) while self.measure: rb.append(self.ser.read(1)[0]) if rb[0] == ord("B") and rb[1] == ord("E") and rb[54] == ord( "E") and rb[55] == ord("N"): timestamp = int.from_bytes(bytes(rb[2:6]), byteorder="little") timestamp = timestamp & 0xffffffff data = np.fromstring(bytes(rb[6:54]), dtype="<f") if self.start_time is None: self.start_time = timestamp self.newData.emit([timestamp - self.start_time, data]) self.ser.close()
class JsonOutput(object): def __init__(self, file, logLimit, exchange=''): self.jsonOutputFile = file self.jsonOutput = {} self.clearStatusValues() self.jsonOutputLog = RingBuffer(logLimit) self.jsonOutput['exchange'] = exchange self.jsonOutput['label'] = Config.get("BOT", "label", "Lending Bot") def status(self, status, time, days_remaining_msg): self.jsonOutput["last_update"] = time + days_remaining_msg self.jsonOutput["last_status"] = status def printline(self, line): line = line.replace("\n", ' | ') self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write( unicode(json.dumps(self.jsonOutput, ensure_ascii=True, sort_keys=True), errors='replace')) f.close() def addSectionLog(self, section, key, value): if section not in self.jsonOutput: self.jsonOutput[section] = {} if key not in self.jsonOutput[section]: self.jsonOutput[section][key] = {} self.jsonOutput[section][key] = value def statusValue(self, coin, key, value): if coin not in self.jsonOutputCoins: self.jsonOutputCoins[coin] = {} self.jsonOutputCoins[coin][key] = str(value) def clearStatusValues(self): self.jsonOutputCoins = {} self.jsonOutput["raw_data"] = self.jsonOutputCoins self.jsonOutputCurrency = {} self.jsonOutput["outputCurrency"] = self.jsonOutputCurrency def outputCurrency(self, key, value): self.jsonOutputCurrency[key] = str(value)
class JsonOutput(object): def __init__(self, file, logLimit): self.jsonOutputFile = file self.jsonOutput = {} self.jsonOutputLog = RingBuffer(logLimit); def status(self, status, time): self.jsonOutput["last_update"] = time self.jsonOutput["last_status"] = status self.writeJsonFile() def printline(self, line): self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write(unicode(json.dumps(self.jsonOutput, ensure_ascii=False, sort_keys=True))) f.close()
class JsonOutput(object): def __init__(self, file, logLimit, exchange=''): self.jsonOutputFile = file self.jsonOutput = {} self.clearStatusValues() self.jsonOutputLog = RingBuffer(logLimit) self.jsonOutput['exchange'] = exchange self.jsonOutput['label'] = Config.get("BOT", "label", "Lending Bot") def status(self, status, time, days_remaining_msg): self.jsonOutput["last_update"] = time + days_remaining_msg self.jsonOutput["last_status"] = status def printline(self, line): line = line.replace("\n", ' | ') self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write(unicode(json.dumps(self.jsonOutput, ensure_ascii=True, sort_keys=True), errors='replace')) f.close() def addSectionLog(self, section, key, value): if section not in self.jsonOutput: self.jsonOutput[section] = {} if key not in self.jsonOutput[section]: self.jsonOutput[section][key] = {} self.jsonOutput[section][key] = value def statusValue(self, coin, key, value): if coin not in self.jsonOutputCoins: self.jsonOutputCoins[coin] = {} self.jsonOutputCoins[coin][key] = str(value) def clearStatusValues(self): self.jsonOutputCoins = {} self.jsonOutput["raw_data"] = self.jsonOutputCoins self.jsonOutputCurrency = {} self.jsonOutput["outputCurrency"] = self.jsonOutputCurrency def outputCurrency(self, key, value): self.jsonOutputCurrency[key] = str(value)
class JsonOutput(object): def __init__(self, file, logLimit): self.jsonOutputFile = file self.jsonOutput = {} self.clearStatusValues() self.jsonOutputLog = RingBuffer(logLimit) def status(self, status, time, days_remaining_msg): self.jsonOutput["last_update"] = time + days_remaining_msg self.jsonOutput["last_status"] = status def printline(self, line): line = line.replace("\n", ' | ') self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write( unicode( json.dumps(self.jsonOutput, ensure_ascii=False, sort_keys=True))) f.close() def statusValue(self, coin, key, value): if coin not in self.jsonOutputCoins: self.jsonOutputCoins[coin] = {} self.jsonOutputCoins[coin][key] = str(value) def clearStatusValues(self): self.jsonOutputCoins = {} self.jsonOutput["raw_data"] = self.jsonOutputCoins self.jsonOutputCurrency = {} self.jsonOutput["outputCurrency"] = self.jsonOutputCurrency def outputCurrency(self, key, value): self.jsonOutputCurrency[key] = str(value)
class JsonOutput(object): def __init__(self, file, logLimit): self.jsonOutputFile = file self.jsonOutput = {} self.jsonOutputLog = RingBuffer(logLimit) def status(self, status, time): self.jsonOutput["last_update"] = time self.jsonOutput["last_status"] = status self.writeJsonFile() def printline(self, line): self.jsonOutputLog.append(line) def writeJsonFile(self): with io.open(self.jsonOutputFile, 'w', encoding='utf-8') as f: self.jsonOutput["log"] = self.jsonOutputLog.get() f.write( unicode( json.dumps(self.jsonOutput, ensure_ascii=False, sort_keys=True))) f.close()
def main(): # e0 = Element(0) # e1 = Element(1) # e2 = Element(2) # e3 = Element(3) rb = RingBuffer(4) rb.append(0) rb.append(1) rb.append(2) rb.append(3) rb.append(4) rb.append(5) print(rb.delete()) print(rb.delete()) print(rb.get_data())
def process_subtitles(self, srtpath): ''' Process ``scenario.txt``, translate «date-based» subtitles to time-bases SRT-subtitles. ''' lf = open(self.scenariopath, "r") subtitles = lf.read().decode("utf-8") lf.close() subtitles = re.sub(r"(?m)^#[^\n]*\n?", "", subtitles) scenario = [] for line in subtitles.splitlines(): if len(line.split(" ", 1))>1: datas, text = line.split(" ", 1) vcstime = None datas = datas.replace(u'\ufeff','') for format in ["%d.%m.%Y", "%Y-%m-%d"]: try: vcstime = time.strptime(datas.encode("latin-1"), format) break except ValueError: pass if not vcstime: print "Warning: can not understand date <%s>" % datas subtitletimestart = (time.mktime(vcstime) - time.mktime(self.startdate)) * self.movielength / self.historylength if -1 < subtitletimestart < 0: subtitletimestart = 0 if subtitletimestart < 0: print "Date <%s> before start of work history" % datas else: scenario.append( (subtitletimestart, text) ) if len(scenario) == 0: return scenario.sort() messages = RingBuffer(3) class SRTText: """ Subtitles in SRT format """ def __init__(self): self.srt = "" self.index = 0 self.stime = float(max([scenario[0][0]-1, 0])) self.etime = 0.0 def append(self, messages): """ Append subtitle from list of messages """ ml = messages.get() msg = " * ".join(ml) subtitletimestart_str = time.strftime("%H:%M:%S", time.gmtime(self.stime)) subtitletimeend_str = time.strftime("%H:%M:%S", time.gmtime(self.etime)) self.srt += """ %d %s,000 --> %s,000 %s """ % (self.index, subtitletimestart_str, subtitletimeend_str, msg) self.stime = self.etime self.index += 1 default_subtitle_time = 3 srt_text = SRTText() for s in scenario: newtime = float(s[0]) if newtime > srt_text.stime + default_subtitle_time: srt_text.etime = srt_text.stime + default_subtitle_time srt_text.append(messages) messages = RingBuffer(3) srt_text.stime = newtime else: srt_text.etime = newtime srt_text.append(messages) messages.append(s[1]) srt_text.etime = min(srt_text.etime + 3, self.movielength) srt_text.append(messages) lf = open(srtpath, "w") lf.write(srt_text.srt.encode("utf-8")) lf.close()
class Process: """ Represents a Process that can be launched, monitored and killed """ def __init__(self, process_config_obj=None): if process_config_obj != None and type(process_config_obj) == type( ProcessConfig()): self.name = process_config_obj.name self.startcmds = process_config_obj.startcmds self.wdir = process_config_obj.wdir self.outlines = process_config_obj.outlines self.outbuffer = RingBuffer(self.outlines) self.stdin_pipe = process_config_obj.stdin_pipe self.envdict = process_config_obj.envdict self.startuplvl = process_config_obj.startuplvl ### self.retcode = None self.subproc = None self.started = False self.tmpfpath = None self.stdout_queue = None self.stdout_thread = None def start(self): if self.started: return tmpfhandle, self.tmpfpath = tempfile.mkstemp() tmpf = os.fdopen(tmpfhandle, 'w') tmpf.write('#!{shellcmd}\n'.format(shellcmd=SHELL_CMD)) tmpf.write('trap "exit" INT TERM\n') tmpf.write('trap "kill 0" EXIT\n') tmpf.write('cd "{path}"\n'.format(path=self.wdir)) if type(self.startcmds) == type([]): for l in self.startcmds: if not l.endswith(' $'): l = l + ' $' tmpf.write(l + "\n") elif type(self.startcmds) == type(""): bgmode = ' $' if not self.startcmds.endswith(' $') else '' tmpf.write(self.startcmds + bgmode + "\n") tmpf.write('sleep infinity\n') tmpf.close() #tmpf = open(self.tmpfpath, "r") #for l in tmpf: # print("{l}".format(l=l)) #tmpf.close() stdin_arg = subprocess.PIPE if self.stdin_pipe else None env_arg = dict(os.environ) env_arg.update(self.envdict) try: self.subproc = subprocess.Popen([SHELL_CMD, self.tmpfpath], bufsize=0, preexec_fn=os.setpgrp, stdin=stdin_arg, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.wdir, env=env_arg) except OSError: print("Process.start(): subprocess.Popen(...) raised OSError") return self.stdout_queue = Queue() self.stdout_thread = Thread(target=self._enqueue_stdout, args=(self.subproc.stdout, self.stdout_queue)) self.stdout_thread.daemon = True self.stdout_thread.start() self.started = True def _update_out_buffer(self): if not self.started: return pollresult = self.subproc.poll() if pollresult != None: self.retcode = pollresult while True: try: line = self.stdout_queue.get_nowait() except Empty: break if (len(line) > 0 and line[-1] == '\n'): line = line[:-1] self.outbuffer.append(line) def terminate(self): if not self.started: return os.killpg(os.getpgid(self.subproc.pid), signal.SIGTERM) self.started = False def kill(self): if not self.started: return os.killpg(os.getpgid(self.subproc.pid), signal.SIGKILL) self.started = False def terminated(self): return self.retcode != None def running(self): return self.started and not self.terminated() def return_code(self): return self.retcode def get_output(self): if not self.started: return self._update_out_buffer() return self.outbuffer.get() def send(self, input_data): if not self.started: return stdoutdata, stderrdata = self.subproc.communicate(input_data) pollresult = self.subproc.poll() if pollresult != None: self.retcode = pollresult return lines = stdoutdata.split('\n') for l in lines: self.outbuffer.append(l) def _enqueue_stdout(self, out, queue): for line in iter(out.readline, b''): queue.put(line.decode("utf-8")) out.close()
class Poloniex: def __init__(self, api_key, secret): self.APIKey = api_key self.Secret = secret self.req_per_sec = 6 self.req_time_log = RingBuffer(self.req_per_sec) self.lock = threading.RLock() # socket.setdefaulttimeout(int(Config.get("BOT", "timeout", 30, 1, 180))) @synchronized def limit_request_rate(self): now = time.time() # start checking only when request time log is full if len(self.req_time_log) == self.req_per_sec: time_since_oldest_req = now - self.req_time_log[0] # check if oldest request is more than 1sec ago if time_since_oldest_req < 1: # print self.req_time_log.get() # uncomment to debug # print "Waiting %s sec to keep api request rate" % str(1 - time_since_oldest_req) # print "Req: %d 6th Req: %d Diff: %f sec" %(now, self.req_time_log[0], time_since_oldest_req) self.req_time_log.append(now + 1 - time_since_oldest_req) time.sleep(1 - time_since_oldest_req) return # uncomment to debug # else: # print self.req_time_log.get() # print "Req: %d 6th Req: %d Diff: %f sec" % (now, self.req_time_log[0], time_since_oldest_req) # append current request time to the log, pushing out the 6th request time before it self.req_time_log.append(now) @synchronized def api_query(self, command, req=None): # keep the 6 request per sec limit self.limit_request_rate() if req is None: req = {} def _read_response(resp): data = json.loads(resp.read()) if 'error' in data: raise PoloniexApiError(data['error']) return data try: if command == "returnTicker" or command == "return24hVolume": ret = urllib2.urlopen( urllib2.Request('https://poloniex.com/public?command=' + command)) return _read_response(ret) elif command == "returnOrderBook": ret = urllib2.urlopen( urllib2.Request('https://poloniex.com/public?command=' + command + '¤cyPair=' + str(req['currencyPair']))) return _read_response(ret) elif command == "returnMarketTradeHistory": ret = urllib2.urlopen( urllib2.Request('https://poloniex.com/public?command=' + "returnTradeHistory" + '¤cyPair=' + str(req['currencyPair']) + '&start=' + str(req['start']) + '&stop=' + str(req['stop']))) return _read_response(ret) elif command == "returnChartData": ret = urllib2.urlopen( urllib2.Request('https://poloniex.com/public?command=' + "returnChartData" + '¤cyPair=' + str(req['currencyPair']) + '&start=' + str(req['start']) + '&stop=' + str(req['stop']) + '&period=' + str(req['period']))) return _read_response(ret) elif command == "returnLoanOrders": req_url = 'https://poloniex.com/public?command=' + "returnLoanOrders" + '¤cy=' + str( req['currency']) if req['limit'] != '': req_url += '&limit=' + str(req['limit']) ret = urllib2.urlopen(urllib2.Request(req_url)) return _read_response(ret) else: req['command'] = command req['nonce'] = int(time.time() * 1000) post_data = urllib.urlencode(req) sign = hmac.new(self.Secret, post_data, hashlib.sha512).hexdigest() headers = {'Sign': sign, 'Key': self.APIKey} print(post_data) ret = urllib2.urlopen( urllib2.Request('https://poloniex.com/tradingApi', post_data, headers)) json_ret = _read_response(ret) return post_process(json_ret) except urllib2.HTTPError as ex: raw_polo_response = ex.read() try: data = json.loads(raw_polo_response) polo_error_msg = data['error'] except: if ex.code == 502: # 502 Bad Gateway so response is likely HTML from Cloudflare polo_error_msg = '' else: polo_error_msg = raw_polo_response ex.message = ex.message if ex.message else str(ex) ex.message = "{0} Requesting {1}. Poloniex reports: '{2}'".format( ex.message, command, polo_error_msg) raise ex except Exception as ex: ex.message = ex.message if ex.message else str(ex) ex.message = "{0} Requesting {1}".format(ex.message, command) raise def return_ticker(self): return self.api_query("returnTicker") def return24h_volume(self): return self.api_query("return24hVolume") def return_order_book(self, currency_pair): return self.api_query("returnOrderBook", {'currencyPair': currency_pair}) # def return_market_trade_history(self, currency_pair): # return self.api_query("returnMarketTradeHistory", {'currencyPair': currency_pair}) def return_chart_data(self, currency_pair, start, stop, period): return self.api_query( "returnChartData", { "currencyPair": currency_pair, 'start': start, 'stop': stop, 'period': period }) def return_market_trade_history(self, currency_pair, start, stop): return self.api_query("returnMarketTradeHistory", { "currencyPair": currency_pair, 'start': start, 'stop': stop }) def transfer_balance(self, currency, amount, from_account, to_account): return self.api_query( "transferBalance", { 'currency': currency, 'amount': amount, 'fromAccount': from_account, 'toAccount': to_account }) # Returns all of your balances. # Outputs: # {"BTC":"0.59098578","LTC":"3.31117268", ... } def return_balances(self): return self.api_query('returnBalances') def return_available_account_balances(self, account): balances = self.api_query('returnAvailableAccountBalances', {"account": account}) if isinstance( balances, list ): # silly api wrapper, empty dict returns a list, which breaks the code later. balances = {} return balances # Returns your open orders for a given market, specified by the "currencyPair" POST parameter, e.g. "BTC_XCP" # Inputs: # currencyPair The currency pair e.g. "BTC_XCP" # Outputs: # orderNumber The order number # type sell or buy # rate Price the order is selling or buying at # Amount Quantity of order # total Total value of order (price * quantity) def return_open_orders(self, currency_pair): return self.api_query('returnOpenOrders', {"currencyPair": currency_pair}) def return_open_loan_offers(self): loan_offers = self.api_query('returnOpenLoanOffers') if isinstance( loan_offers, list ): # silly api wrapper, empty dict returns a list, which breaks the code later. loan_offers = {} return loan_offers def return_active_loans(self): return self.api_query('returnActiveLoans') def return_lending_history(self, start, stop, limit=500): return self.api_query('returnLendingHistory', { 'start': start, 'end': stop, 'limit': limit }) # Returns your trade history for a given market, specified by the "currencyPair" POST parameter # Inputs: # currencyPair The currency pair e.g. "BTC_XCP" # Outputs: # date Date in the form: "2014-02-19 03:44:59" # rate Price the order is selling or buying at # amount Quantity of order # total Total value of order (price * quantity) # type sell or buy # def return_trade_history(self, currency_pair): # return self.api_query('returnTradeHistory', {"currencyPair": currency_pair}) def return_trade_history(self, currency_pair, start, stop): return self.api_query('returnTradeHistory', { "currencyPair": currency_pair, 'start': start, 'stop': stop }) # Places a buy order in a given market. Required POST parameters are "currencyPair", "rate", and "amount". # If successful, the method will return the order number. # Inputs: # currencyPair The curreny pair # rate price the order is buying at # amount Amount of coins to buy # Outputs: # orderNumber The order number def buy(self, currency_pair, rate, amount): return self.api_query('buy', { "currencyPair": currency_pair, "rate": rate, "amount": amount }) # Places a sell order in a given market. Required POST parameters are "currencyPair", "rate", and "amount". # If successful, the method will return the order number. # Inputs: # currencyPair The curreny pair # rate price the order is selling at # amount Amount of coins to sell # Outputs: # orderNumber The order number def sell(self, currency_pair, rate, amount): return self.api_query('sell', { "currencyPair": currency_pair, "rate": rate, "amount": amount }) def create_loan_offer(self, currency, amount, duration, auto_renew, lending_rate): return self.api_query( 'createLoanOffer', { "currency": currency, "amount": amount, "duration": duration, "autoRenew": auto_renew, "lendingRate": lending_rate, }) # Cancels an order you have placed in a given market. Required POST parameters are "currencyPair" and "orderNumber". # Inputs: # currencyPair The curreny pair # orderNumber The order number to cancel # Outputs: # succes 1 or 0 def cancel(self, currency_pair, order_number): return self.api_query('cancelOrder', { "currencyPair": currency_pair, "orderNumber": order_number }) def cancel_loan_offer(self, currency, order_number): return self.api_query('cancelLoanOffer', { "currency": currency, "orderNumber": order_number }) # Immediately places a withdrawal for a given currency, with no email confirmation. # In order to use this method, the withdrawal privilege must be enabled for your API key. # Required POST parameters are "currency", "amount", and "address". Sample output: {"response":"Withdrew 2398 NXT."} # Inputs: # currency The currency to withdraw # amount The amount of this coin to withdraw # address The withdrawal address # Outputs: # response Text containing message about the withdrawal def withdraw(self, currency, amount, address): return self.api_query('withdraw', { "currency": currency, "amount": amount, "address": address }) def return_loan_orders(self, currency, limit=''): return self.api_query('returnLoanOrders', { "currency": currency, "limit": limit }) # Toggles the auto renew setting for the specified orderNumber def toggle_auto_renew(self, order_number): return self.api_query('toggleAutoRenew', {"orderNumber": order_number})
def process_subtitles(self, srtpath): ''' Process ``scenario.txt``, translate «date-based» subtitles to time-bases SRT-subtitles. ''' lf = open(self.scenariopath, "r") subtitles = lf.read().decode("utf-8") lf.close() subtitles = re.sub(r"(?m)^#[^\n]*\n?", "", subtitles) scenario = [] for line in subtitles.splitlines(): if len(line.split(" ", 1)) > 1: datas, text = line.split(" ", 1) vcstime = None datas = datas.replace(u'\ufeff', '') for format in ["%d.%m.%Y", "%Y-%m-%d"]: try: vcstime = time.strptime(datas.encode("latin-1"), format) break except ValueError: pass if not vcstime: print "Warning: can not understand date <%s>" % datas subtitletimestart = (time.mktime(vcstime) - time.mktime( self.startdate)) * self.movielength / self.historylength if -1 < subtitletimestart < 0: subtitletimestart = 0 if subtitletimestart < 0: print "Date <%s> before start of work history" % datas else: scenario.append((subtitletimestart, text)) if len(scenario) == 0: return scenario.sort() messages = RingBuffer(3) class SRTText: """ Subtitles in SRT format """ def __init__(self): self.srt = "" self.index = 0 self.stime = float(max([scenario[0][0] - 1, 0])) self.etime = 0.0 def append(self, messages): """ Append subtitle from list of messages """ ml = messages.get() msg = " * ".join(ml) subtitletimestart_str = time.strftime("%H:%M:%S", time.gmtime(self.stime)) subtitletimeend_str = time.strftime("%H:%M:%S", time.gmtime(self.etime)) self.srt += """ %d %s,000 --> %s,000 %s """ % (self.index, subtitletimestart_str, subtitletimeend_str, msg) self.stime = self.etime self.index += 1 default_subtitle_time = 3 srt_text = SRTText() for s in scenario: newtime = float(s[0]) if newtime > srt_text.stime + default_subtitle_time: srt_text.etime = srt_text.stime + default_subtitle_time srt_text.append(messages) messages = RingBuffer(3) srt_text.stime = newtime else: srt_text.etime = newtime srt_text.append(messages) messages.append(s[1]) srt_text.etime = min(srt_text.etime + 3, self.movielength) srt_text.append(messages) lf = open(srtpath, "w") lf.write(srt_text.srt.encode("utf-8")) lf.close()