"""The local thread, based on the local Python interpreter thread.

The local thread is the thread that every rsyscall program has available from the
start. From this thread, we create all the others.

"""
from __future__ import annotations
from rsyscall.thread import Thread
from rsyscall.tasks.util import log_syscall, raise_if_error
from rsyscall._raw import ffi, lib # type: ignore
import trio
import rsyscall.far as far
from rsyscall.near.sysif import SyscallInterface, SyscallResponse
import rsyscall.near.types as near
import rsyscall.handle as handle
import rsyscall.loader as loader
import logging
import os
import typing as t
from dataclasses import dataclass
import rsyscall.memory.allocator as memory
from rsyscall.memory.ram import RAM
from rsyscall.memory.transport import MemoryTransport
from rsyscall.handle import Pointer, Task, MemoryMapping
from rsyscall.signal import SIG, Sigaction, Sighandler
from rsyscall.sys.socket import AF, SOCK
from rsyscall.network.connection import FDPassConnection
from rsyscall.environ import Environment
from rsyscall.loader import NativeLoader
from rsyscall.monitor import ChildProcessMonitor

from rsyscall.sys.epoll import EpollFlag
from rsyscall.epoller import Epoller

logger = logging.getLogger(__name__)

__all__ = [
    "thread",
]

async def _direct_syscall(number, arg1=0, arg2=0, arg3=0, arg4=0, arg5=0, arg6=0):
    "Make a syscall directly in the current thread."
    return lib.rsyscall_raw_syscall(arg1, arg2, arg3, arg4, arg5, arg6, number)

class LocalSyscallResponse(SyscallResponse):
    "Dummy SyscallResponse for local syscalls."
    def __init__(self, result_func: t.Callable[[], int]) -> None:
        self.result_func = result_func

    async def receive(self) -> int:
        return self.result_func()

class LocalSyscall(SyscallInterface):
    "Makes syscalls in the local, Python interpreter thread."
    def __init__(self) -> None:
        self.logger = logger

    def get_activity_fd(self) -> None:
        return None

    async def close_interface(self) -> None:
        pass

    async def submit_syscall(self, number, arg1=0, arg2=0, arg3=0, arg4=0, arg5=0, arg6=0) -> LocalSyscallResponse:
        """Make a syscall in the local thread; return SyscallResponse already containing the result.

        We can't actually implement the submit_syscall API for local syscalls, so we just
        immediately make the syscall and pack the response into a dummy SyscallResponse.

        Linux returns errors as just another kind of syscall return value. A certain range
        of possible syscall return values (-4095 to 0, not inclusive) indicates an error;
        we call raise_if_error to check and throw if we're in that range.

        """
        log_syscall(self.logger, number, arg1, arg2, arg3, arg4, arg5, arg6)
        result = await _direct_syscall(
            number,
            arg1=int(arg1), arg2=int(arg2), arg3=int(arg3),
            arg4=int(arg4), arg5=int(arg5), arg6=int(arg6))
        def f(result=result) -> int:
            raise_if_error(result)
            return result
        return LocalSyscallResponse(f)

class LocalMemoryTransport(MemoryTransport):
    "This is a memory transport that only works on local pointers."
    def __init__(self, local_task: Task) -> None:
        self.local_task = local_task

    def inherit(self, task: Task) -> LocalMemoryTransport:
        return self

    async def batch_write(self, ops: t.List[t.Tuple[Pointer, bytes]]) -> None:
        for dest, data in ops:
            if dest.mapping.task.address_space != self.local_task.address_space:
                raise Exception("trying to write to pointer", dest, "not in local address space")
            ffi.memmove(ffi.cast('void*', int(dest.near)), data, len(data))

    async def batch_read(self, ops: t.List[Pointer]) -> t.List[bytes]:
        ret: t.List[bytes] = []
        for src in ops:
            if src.mapping.task.address_space != self.local_task.address_space:
                raise Exception("trying to read from pointer", src, "not in local address space")
            buf = ffi.buffer(ffi.cast('void*', int(src.near)), src.size())
            ret.append(bytes(buf))
        return ret

async def _make_local_thread() -> Thread:
    """Create the local thread, allocating various resources locally.

    For the most part, the local thread is like any other thread; it just bootstraps
    differently, and uses syscall and memory interfaces which are specialized to the local
    thread.

    """
    process = near.Process(os.getpid())
    task = Task(
        LocalSyscall(), process, far.FDTable(process.id),
        far.AddressSpace(process.id),
        far.PidNamespace(process.id),
    )
    ram = RAM(task, LocalMemoryTransport(task), memory.AllocatorClient.make_allocator(task))
    epfd = await task.epoll_create()
    async def wait_readable():
        logger.debug("wait_readable(%s)", epfd.near.number)
        await trio.hazmat.wait_readable(epfd.near.number)
    epoller = Epoller.make_subsidiary(ram, epfd, wait_readable)
    thread = Thread(
        task, ram,
        await FDPassConnection.make(task, ram, epoller),
        NativeLoader.make_from_symbols(task, lib),
        epoller,
        await ChildProcessMonitor.make(ram, task, epoller),
        Environment(task, ram, {key.encode(): value.encode() for key, value in os.environ.items()}),
        stdin=task.make_fd_handle(near.FileDescriptor(0)),
        stdout=task.make_fd_handle(near.FileDescriptor(1)),
        stderr=task.make_fd_handle(near.FileDescriptor(2)),
    )
    return thread

async def _initialize() -> Thread:
    thr = await _make_local_thread()
    # Wipe out the SIGWINCH handler that the readline module installs.
    # We do this because otherwise this handler will be inherited down to our
    # children, where it will segfault on run due to the environment being
    # totally different (lacking TLS for one). I'm not sure if there's any
    # alternative; wiping out the signal handlers from within the children after
    # they've been created still leaves a window for the signal handler to run.
    import readline
    await thr.task.sigaction(SIG.WINCH, await thr.ram.ptr(Sigaction(Sighandler.DFL)), None)
    return thr

thread: Thread = trio.run(_initialize)
"The local thread, fully initialized at import time"


from mpl_toolkits.basemap import Basemap, cm, shiftgrid,interp
from netCDF4 import Dataset as NetCDFFile
import numpy as N
import math
import matplotlib.pyplot as plt
import glob
import numpy.ma as ma
from scipy.interpolate import griddata
import scipy.stats
from matplotlib.dates import DateFormatter
import datetime
from statsmodels.stats.weightstats import DescrStatsW
import matplotlib.colors as colors

nclu=NetCDFFile('/scratch2/scratchdirs/tslin2/plot/globalcrop/data/m3yield_isam.nc','r')
ncvar_maize = nclu.variables['maizey'][0,:,:]
lonab = nclu.variables["lon"][:]

region1=NetCDFFile('/scratch2/scratchdirs/tslin2/plot/globalcrop/data/clm/RCP45_crop_150901.nc','r')
maitrop = region1.variables['maize_trop'][4,:,:]
maitemp = region1.variables['maize_temp'][4,:,:]
maitropi = region1.variables['maize_trop_irrig'][4,:,:]
maitempi = region1.variables['maize_temp_irrig'][4,:,:]
maitrop= ma.masked_where(maitrop<=0,maitrop)
maitropi= ma.masked_where(maitropi<=0,maitropi)
maitemp= ma.masked_where(maitemp<=0,maitemp)
maitempi= ma.masked_where(maitempi<=0,maitempi)
maitrop=ma.filled(maitrop, fill_value=0.)
maitropi=ma.filled(maitropi,fill_value=0.)
maitemp=ma.filled(maitemp, fill_value=0.)
maitempi=ma.filled(maitempi, fill_value=0.)
maizeto = maitrop+maitemp
maizetoi = maitropi+maitempi
maitoatemp=maitemp+maitempi
maitoatrop=maitrop+maitropi
maizetotal = maizeto+maizetoi

isam=NetCDFFile('/scratch2/scratchdirs/tslin2/isam/cheyenne/plot/finalyield/clm/clm45his_maiscaleifyield.nc','r')
isamyield = N.average(isam.variables['yield'][95:105,:,:],axis=0)
lona1 = isam.variables["lon"][:]
lata1 = isam.variables["lat"][:]
lon2,lat2 = N.meshgrid(lona1,lata1)

isamyield[N.isnan(isamyield)] = -9999
isamyield = ma.masked_where(isamyield<=0,isamyield)
isamyield = ma.masked_where(maizetotal<=0,isamyield)
#isamyield=ma.filled(isamyield, fill_value=0.)

yieldfa= N.zeros((10, 360, 720))
yieldf2a= N.zeros((10, 360, 720))
yieldf= N.zeros((10, 360, 720))
yieldf2= N.zeros((10, 360, 720))
years2 = range(2090,2100)

clmtropfin= N.zeros((10, 360, 720))
clmtempfin= N.zeros((10, 360, 720))

for j in range(0,10):

        clm2n=NetCDFFile('/scratch2/scratchdirs/tslin2/plot/globalcrop/data/clm/clm45rcp45/maizetrop_rcp45_co2_rf_fert_0.5x0.5.nc','r')
        cc = N.flipud(clm2n.variables['yield'][84+j,:,:])
        clmtropfin[j,:,:] = cc

        clm3n=NetCDFFile('/scratch2/scratchdirs/tslin2/plot/globalcrop/data/clm/clm45rcp45/maizetemp_rcp45_co2_rf_fert_0.5x0.5.nc','r')
        dd = N.flipud(clm3n.variables['yield'][84+j,:,:])
        clmtempfin[j,:,:] = dd

yield_new2a=N.average(clmtropfin,axis=0)
yield_new2=N.average(clmtempfin,axis=0)

yield_new2= ma.masked_where(yield_new2<=0.,yield_new2)
yield_new2a= ma.masked_where(yield_new2a<=0.,yield_new2a)
yield_new2=ma.masked_where( maitoatemp<=0,yield_new2)
yield_new2=ma.filled(yield_new2, fill_value=0.)

yield_new2a=ma.masked_where( maitoatrop<=0,yield_new2a)
yield_new2a=ma.filled(yield_new2a, fill_value=0.)

yield_new2=yield_new2+yield_new2a

yield_new2=ma.masked_where(isamyield<=0.,yield_new2)
yieldisam=yield_new2-isamyield
yieldisam= ma.masked_where(yieldisam==0.,yieldisam)

ncvar_maize,lona11 = shiftgrid(180.5,ncvar_maize,lonab,start=False)
yieldisam= ma.masked_where(ncvar_maize<=0.,yieldisam)

fig = plt.figure(figsize=(12,6))

ax1 = fig.add_subplot(211)
ax1.set_title("isam mai yield 1996-2005 (t/ha)",fontsize=18)

map = Basemap(projection ='cyl', llcrnrlat=-65, urcrnrlat=90,llcrnrlon=-180, urcrnrlon=180, resolution='c')
#map = Basemap(llcrnrlon=-119,llcrnrlat=23,urcrnrlon=-63,urcrnrlat=51,projection='lcc',lat_1=33,lat_2=45,lon_0=-95)
map.drawcoastlines()
#map.drawstates()
#map.drawcountries(color='b')

x,y = map(lon2,lat2)

map.drawcoastlines()
map.drawcountries()
map.drawmapboundary()
cs = map.pcolormesh(x,y,isamyield,cmap=plt.cm.jet,norm=colors.PowerNorm(gamma=1./2.),vmin=0,vmax=16)
cbar = map.colorbar(cs,location='bottom',size="4%",pad="2%")
cbar.ax.tick_params(labelsize=12)
plt.axis('off')

ax2 = fig.add_subplot(212)
ax2.set_title("Maize RCP4.5",fontsize=18)
map = Basemap(projection ='cyl', llcrnrlat=-65, urcrnrlat=90,llcrnrlon=-180, urcrnrlon=180, resolution='c')
#map = Basemap(llcrnrlon=-119,llcrnrlat=23,urcrnrlon=-63,urcrnrlat=51,projection='lcc',lat_1=33,lat_2=45,lon_0=-95)
map.drawcoastlines(color='gray')
#map.drawstates()
#map.drawcountries(color='b')

#map.drawcoastlines()
#map.drawcountries()
#map.drawmapboundary(color='gray')
cs = map.pcolormesh(x,y,yieldisam/isamyield*100,cmap=plt.cm.bwr,vmin=-100.,vmax=100.)
cbar = map.colorbar(cs,location='bottom',size="4%",pad="2%")
cbar.ax.tick_params(labelsize=12)
plt.axis('off')
plt.tight_layout()

plt.savefig('mai2006_2015_rcp45_clmc.jpg',dpi=300,bbox_inches='tight')
plt.show()


import tweepy
import config
import time
import datetime
import numpy as np
import os
import json
import pandas as pd

def rehydrate(directory_path):
    '''
    rehydrates the tweet ids in all txt files in the current directory
    tweets are saved into a separate file with the same name into jsonl format
    '''
    #Stores the current path so we can change back to it later
    cwd = os.getcwd()

    #Changes the path to the folder containing the files we wish to rehydrate
    os.chdir(directory_path)

    #Lists the files so we can iterate through them
    folder = os.listdir()

    for file in range(len(folder)):

        #Checks to make sure the jsonl file doesn't already exist for the politician
        politician_check = folder[file][:-4] + '.jsonl'
        if politician_check in folder:
            print("The data for " + folder[file][:-4] + " already exists.")
            continue

        #Checks to make sure file ends in a txt extension
        if folder[file][-4:] == '.txt':
            #Rehydrates the tweet ids using twarc
            os.system('twarc hydrate ' + folder[file] + ' > ' + folder[file][:-4] + '.jsonl')
            print("Data for " + folder[file][:-4] + " has been obtained.")
        else:
            continue

    #Changes the directory to the original path
    os.chdir(cwd)

def get_data(scientific_path, misinformation_path):
    '''
    setup for rehyrating tweets for both our scientific and misinformation groups
    '''
    rehydrate(scientific_path)
    rehydrate(misinformation_path)

def get_metrics(politician_file, filepath):
    '''
    obtains the engagement metrics for all the tweet ids in our txt files
    engagement metrics are saved into a separate file with the same name in csv format
    '''

    working_path = os.getcwd()
    os.chdir(filepath)

    check = politician_file + '.csv'

    #Checks to make sure the csv file does not already exist before calling on the API
    if check in os.listdir():
        print("The csv for " + politician_list + " already exists.")
        os.chdir(working_path)
        return

    #Opens the text file of tweet ids found in the filepath
    text_file = open(politician_file + ".txt", "r")
    lines = text_file.read().splitlines()
    text_file.close()

    #List containing dataframes consisting of 100 rows
    metrics_list = []

    for i in range(0, len(lines), 100):
        #Gets 100 tweet ids at a time and passes it to the call to the API
        #The API can only look up metrics for 100 tweets at a time
        partition = lines[i:i+100]
        partition_string = ','.join(partition)

        request = os.popen("curl 'https://api.twitter.com/2/tweets?ids=" + partition_string + "&tweet.fields=public_metrics' --header 'Authorization: Bearer " + config.bearer_token + "'").read()

        #Check for rate limit, if exceeded we sleep for 15 minutes to reset the limit
        #Then continues where it left off for the tweet ids
        if 'exceeded' in request:
            print("Rate Limit Exceeded. Sleeping for 15 Minutes.")
            time.sleep(60*15)
            request = os.popen("curl 'https://api.twitter.com/2/tweets?ids=" + partition_string + "&tweet.fields=public_metrics' --header 'Authorization: Bearer " + config.bearer_token + "'").read()

        #A string with json is returned from the API call, this converts it to Json
        to_json = json.loads(request)

        #Takes the data portion of the output and turns it into a dataframe
        #Appends the dataframe of 100 rows to a list containing the smaller dataframes
        metrics_data = pd.DataFrame.from_dict(to_json['data'])
        metrics_list.append(metrics_data)

    #Appends the small dataframes of 100 into a larger dataframe
    metrics = pd.concat(metrics_list, ignore_index=True)

    #Saves the metrics dataframe to a csv file so we can reduce the number of API calls we make
    metrics.to_csv(politician_file + '.csv', index=True)
    print("The csv for " + politician_file + " has been completed.")

    os.chdir(working_path)

    return metrics

def get_csvs(scientific_path, misinformation_path, scientific_list, misinformation_list):
    '''
    setup for obtaining engagement metrics for both our scientific and misinformation groups
    '''

    for i in range(len(scientific_list)):
        get_metrics(scientific_list[i], scientific_path)

    for i in range(len(misinformation_list)):
        get_metrics(misinformation_list[i], misinformation_path)


# python imports
import datetime
import itertools
import os

# django imports
from django.conf import settings

# third-party imports
from whoosh import qparser
from whoosh.analysis import CharsetFilter, StandardAnalyzer
from whoosh.fields import Schema, ID, TEXT
from whoosh.index import create_in, open_dir, EmptyIndexError
from whoosh.support.charset import default_charset, charset_table_to_dict

# The last time an indexing process was run
LAST_INDEXING = None

def get_schema():
    # Analyzer to ignore accents-related differences
    # ( https://pythonhosted.org/Whoosh/stemming.html#character-folding )
    charmap = charset_table_to_dict(default_charset)
    name_analyzer = StandardAnalyzer() | CharsetFilter(charmap)

    return Schema(
        id=ID(stored=True, unique=True),
        name=TEXT(stored=True, analyzer=name_analyzer)
    )

def get_search_index():
    """
        Return the search index and a boolean value indicating if it had to be
            created now.
    """
    if not os.path.exists(settings.SEARCH_INDEX_DIR):
        os.mkdir(settings.SEARCH_INDEX_DIR)

    try:
        index = open_dir(settings.SEARCH_INDEX_DIR)
        index_created_now = False
    except EmptyIndexError:
        index = create_in(settings.SEARCH_INDEX_DIR, get_schema())
        index_created_now = True

    return index, index_created_now

def update_index():
    """
        Update the search index.
    """
    from .models import Spot
    global LAST_INDEXING

    index, index_created_now = get_search_index()

    spots_to_index = Spot.objects.only('name').available()

    if not index_created_now:
        if LAST_INDEXING:
            spots_to_index = spots_to_index.filter(
                last_modified__gt=LAST_INDEXING
            )

    writer = index.writer()

    for spot in spots_to_index:
        writer.update_document(
            id=unicode(spot.id),
            name=unicode(spot.name)
        )

    writer.commit()

    LAST_INDEXING = datetime.datetime.now()

def delete_spot_from_index(spot):
    from .models import Spot
    assert isinstance(spot, Spot)
    index, index_created_now = get_search_index()
    if not index_created_now:
        writer = index.writer()
        writer.delete_by_term('id', unicode(spot.id))
        writer.commit()

def search_spots(search_term, limit=250):
    from .models import Spot
    assert isinstance(limit, int) and limit > 0
    index = get_search_index()[0]
    parser = qparser.QueryParser(
        'name',
        get_schema(),
        group=qparser.OrGroup.factory(0.9)
    )
    words = search_term.split()
    query_string = ' '.join(['*%s*' % w for w in words])
    query = parser.parse(query_string)
    with index.searcher() as searcher:
        spots = [
            Spot(id=result['id'], name=result['name'])
            for result in searcher.search(query, limit=limit)
        ]
        corrector = searcher.corrector('name')
        suggestions = [corrector.suggest(w, maxdist=4) for w in words]
    suggestions = itertools.chain(*suggestions)
    suggestions = list(set(suggestions))  # Remove duplicates
    suggestions = [w for w in suggestions if len(w) >= 3]  # Min length
    suggestions.sort(key=len, reverse=True)  # Biggest words first
    return {'spots': spots, 'suggestions': suggestions}


"""This is for finding words in a given string, ignoring spaces
(if you want it to look for spots with spaces then add a space before
and one after the word you are looking before giving it to the function"""
def wordSearcher(wordToFind, stringToSearch, output="firstChar", multipleLocs=True):
    '''(str, str [, str, bool]) -> list of int
    search for wordToFind in stringToSearch
    soon to be deprecated'''
    wordLocations = []
    if wordToFind in stringToSearch: #no point going through the whole string if there isn't a possible match to start with
        for charNum in range(len(stringToSearch)): #search through the string sequentially from char 0 to end
            if stringToSearch[charNum:(charNum+len(wordToFind))]== wordToFind: #play the matching game, if you win append the result to the wordLocations list
                if output.lower()=="firstchar": #make sure that only if the program wants the first char you give them the first char
                    wordLocations.append(charNum)

                elif output.lower()=="lastchar": #if they want the last char, make it so!
                    wordLocations.append(charNum+len(wordToFind))

                elif output.lower()=="uptoword": #if they want the searched string up to the word, give them that
                    wordLocations.append(stringToSearch[:charNum])

                elif output.lower()=="uptoandword": #if they want the searched string up to the end of the word, engage!
                    wordLocations.append(stringToSearch[:charNum+len(wordToFind)])

                if not multipleLocs: #in case they just want the first case end the function here
                        return wordLocations
    return wordLocations


"""""
====================================================================
datasynth.py - nipype wrapper for camino diffusion model simulations
====================================================================

"""
from nipype.interfaces.base import (traits, TraitedSpec, File, StdOutCommandLine,
                                    StdOutCommandLineInputSpec, isdefined)
# from nipype.utils.filemanip import split_filename
import os

class AnalyticModelInputSpec(StdOutCommandLineInputSpec):

    n_compartments = traits.Int(argstr='compartment %d', units='NA', position=1,
                                desc="Number of compartments " )

    compartment1_name = traits.Enum('stick', 'CylinderGPD', 'Gammadistribradiicylinders',
                                    'Ball', 'Zeppelin', 'Tensor', 'Astrosticks',
                                    'Astrocylinders', 'SphereGPD', 'Dot', argstr='%s',
                                    position=2,desc = 'compartment1_name' )

    compartment1_vf = traits.Float(argstr='%1.3f',position=3,desc='compartment1_volume_fraction')

    compartment1_params = traits.List(traits.Float,position=4,minlen=0, maxlen=5,argstr='%s',
                                      desc='compartment1_parameters')

    compartment2_name = traits.Enum('stick', 'CylinderGPD', 'Gammadistribradiicylinders',
                                    'Ball', 'Zeppelin', 'Tensor', 'Astrosticks',
                                    'Astrocylinders', 'SphereGPD', 'Dot', argstr='%s',
                                    position=5,desc = 'compartment2_name' )

    compartment2_vf = traits.Float(argstr='%1.3f',position=6,desc='compartment2_volume_fraction')

    compartment2_params = traits.List(traits.Float,position=7,minlen=0, maxlen=5,argstr='%s',
                                      desc='compartment2_parameters')

    compartment3_name = traits.Enum('stick', 'CylinderGPD', 'Gammadistribradiicylinders',
                                    'Ball', 'Zeppelin', 'Tensor', 'Astrosticks',
                                    'Astrocylinders', 'SphereGPD', 'Dot', argstr='%s',
                                    position=8,desc = 'compartment3_name' )

    compartment3_params = traits.List(traits.Float,position=9,minlen=0, maxlen=5,argstr='%s',
                                      desc='compartment3_parameters')

    n_voxels = traits.Int(argstr='-voxels %d', units='NA', desc="Number of voxels to simulate")
    # Check: 'separateruns' option for running a separate simulation in each voxel

    schemefile = traits.File(exists=True, argstr='-schemefile %s',desc = 'scheme file')

    out_file = traits.File(desc = 'name of output file (.Bfloat format)')

class AnalyticModelOutputSpec(TraitedSpec):

    synth_data = File(exists=True, desc='simulated_data')

class AnalyticModel(StdOutCommandLine):
    """
    Example: 'ZeppelinCylinderDot model from camino analytic models tutorial

    -------
    >>> from nipype.interfaces.camino import datasynth
    >>> zcd = datasynth.AnalyticModel()
    >>> zcd.inputs.n_compartments = 3
    >>> zcd.inputs.compartment1_name = 'CylinderGPD'
    >>> zcd.inputs.compartment1_vf = 0.6
    >>> zcd.inputs.compartment1_params = [1.7E-9, 0.0,0.0,4E-6]
    >>> zcd.inputs.compartment2_name = 'Zeppelin'
    >>> zcd.inputs.compartment2_vf = 0.1
    >>> zcd.inputs.compartment2_params = [1.7E-9,0.0,0.0,2E-10]
    >>> zcd.inputs.compartment3_name = 'Dot'
    >>> zcd.inputs.schemefile = '59.scheme'
    >>> zcd.inputs.n_voxels = 1
    >>> zcd.inputs.out_file = 'sim_data.Bfloat'
    >>> zcd.run()                  # doctest: +SKIP
    """

    _cmd = 'datasynth -synthmodel'
    input_spec=AnalyticModelInputSpec
    output_spec=AnalyticModelOutputSpec

    def _list_outputs(self):
        outputs = self.output_spec().get()
        outputs['synth_data'] = os.path.abspath(self._gen_outfilename())
        return outputs

    def _gen_outfilename(self):
        outfilename = self.inputs.out_file
        return outfilename

class MonteCarloInputSpec(StdOutCommandLineInputSpec):

    walkers = traits.Int(argstr='-walkers %d', position=1,units='NA', desc="Number of " \
                         "spins to use in simulation. Simple simulations require " \
                         "around 10000 spins, but simulations on more complex " \
                         "substrates require more spins to capture the additional " \
                         "complexity, particularly at higher b-values." \
                         "For the simulations covered in this tutorial we recommend" \
                         "AT LEAST 100000 spins, but more may well be required.")

    tmax = traits.Int(argstr='-tmax %d', position=2,units='NA', desc="Number of timesteps into " \
                      "which the simulation is divided. This can be thought of as " \
                      "defining the temporal resolution of the simulation, since the total" \
                      "duration of a simulation's dynamics (i.e. the period of time that is " \
                      "simulated, and not how long it takes to run!) is defined by its schemefile." \
                      "This duration will be split into a number of updates of equal length" \
                      "dt. This is an important number, since together with the diffusivity" \
                      "it defines the length of steps in each spin's' random walk."\
                      "It also defines how long a simulation will take to run." \
                      "More timesteps equates to a longer execution. Investigations"  \
                      "have shown that simple substrates require about 1000 updates"\
                      "although very complex substrates and very high b-values "\
                      "may need more (5000 or more).")

    voxels = traits.Int(argstr='-voxels %d', units='NA', position=3,desc="Specifies the number of voxels of "\
                         "data to synthesise. It is important to specify this to be at least 1. By "\
                         "default, a simulation will run once and then fill remaining voxels with "\
                         "different noise-realisations of the synthesised data. To run a separate "\
                         "simulation in each voxel, use the -separateruns option.")

    barrier_permeability = traits.Float(argstr='-p %s', units='NA',position=4, desc="Specifies the probability"\
                                     "that a spin will step through a barrier unaffected instead of"\
                                     "interacting with it. This is usually set to 0, making barriers impermeable.")

    schemefile = traits.File(argstr='-schemefile %s', units='NA', position=5,desc="Specifies the scheme file "\
                            "to use for data synthesis. The scheme file describes the pulse sequence "\
                            "used to generate diffusion-weighted data. These specify gradients, "\
                            "pulse durations, orientations, separations, etc. and are no different "\
                            "to those used by other parts of Camino.Specifies the seed for the random number ")

    initial = traits.Enum('uniform', 'intra', 'extra', 'square', 'hex', argstr='-initial %s',position=6,desc="Specificies "\
                          "initial conditions of spins by a keyword. uniform distributes spins uniformly "\
                          "(but randomly) across the substrate. delta locates them all at the same "\
                          "point in the centre of the substrate, intra distributes them uniformly in "\
                          "the intracellular space and extra does the same but in the extracellular "\
                          "space. Note that some substrates do not have a reliable definition of "\
                          "intracellular and extracellular, and in this case the use of intra and "\
                          "extra will lead to unexpected results and is deprecated.")

    substrate = traits.Enum('empty', 'cylinder', 'crossing', 'inflammation', 'ply', argstr='-substrate %s',position=7,desc=" write somethign here")

    substratesize = traits.Float(argstr='-substratesize %s',desc="something to write here")

    ply_file = traits.File(argstr='-plyfile %s', desc='plyfile...')

    increments = traits.Int(argstr='-increments %s',desc="something to write here")

    diffusivity = traits.Float(argstr='-diffusivity %d', units='NA', desc="Specifies the free"\
                              "diffusivity for spins in the simulation in SI units. The default" \
                              " value is 2.0E-9m^s/s but this can be changed as needed. All physical" \
                              " quantities in Camino (including b-value) use SI units (seconds, " \
                              "meters, teslas) so it may be necessary to convert to SI before " \
                              "specifying them.")

    separateruns = traits.Bool(argstr='-separateruns', desc="Runs a separate simulation in each voxel")

    seed = traits.Int(argstr='-seed %d', units='NA', desc="Specifies the seed for the random number "\
                       "generators to use. Since it is a Monte-Carlo simulation, it makes extensive "\
                       "use of random numbers when running. Specifying different seeds will cause "\
                       "different sequences of random numbers to be generated and hence different "\
                       "trajectories of spins to be developed as (slightly) different synthetic "\
                       "measurements to be synthesised. A seed can be any integer, although it is "\
                       "better to use large numbers (8 or 9 digits) as more complex seeds give lower "\
                       "correlations in random number sequences.")

    duration = traits.Float(argstr='-duration %s', units='NA', desc="Specifies the duration "\
                                       "of the dynamics (in seconds) if no scheme file is used. "\
                                       "You can find out what this should be by using the longest "\
                                       "acquisition in your scheme file. The simulation should be long enough"\
                                       "to run at least from the onset of the first gradient block to the end "\
                                       "of the last.")

    trajectories_file = traits.Either(traits.Bool, traits.File(),hash_files=False, argstr='-trajfile %s', units='NA', desc="Specifies the name of the trajfile "\
                                   "generated. A trajfile contains the complete trajectories of all spins in a "\
                                   "given simulation and may be parsed into a set of measurements at a later date.")

    scan = traits.Int(argstr='-scan %d', units='NA', desc="This command reads the trajectories file specified "\
                      "and synthesise diffusion weighted data using myscheme.scheme. Due to the size of the files "\
                      "involved this will take at least several seconds and may take several minutes for larger files.")

    packing = traits.Enum('square', 'hex', argstr='-packing %s',desc="The simulation supports both of these configurations,"\
                          "Cylinders in the simulation do not necessarily have to be abutting (i.e. close-packed, so that "\
                          "their edges touch), although this is certainly possible. The size and spacing of cylinders is "\
                          "controlled by the -cylinderrad and -cylindersep options respectively. -cylinderrad specifies "\
                          "the RADIUS of all cylinders and -cylindersep the separation between cylinders. "\
                          "The cylindersep variable is defined as the distance between the central axes of the cylinders "\
                          "and hence must be at least twice the cylinder radius. Separations closer than this will cause "\
                          "cylinders to overlap and intersect and may cause unexpected results. Both distances must be "\
                          "specified in meters (NOT in microns.")

    numcylinders = traits.Int(argstr='-numcylinders %s',desc="something to write here")

    voxelsizefrac = traits.Float(argstr='-voxelsizefrac %s',desc="something to write here")

    stats_file = File(argstr='-statsfile %s', desc="generate a stats file, just specify its name "\
                      "from the command line using -statsfile myStatsFile.dat along with the rest of your simulation command")

    cylinder_radius = traits.Float(argstr='-cylinderrad %s',desc="cylinder radius")

    cylinder_separation = traits.Float(argstr='-cylindersep %s',desc="The cylindersep variable is "\
                                       "defined as the distance between the central axes of the cylinders "\
                                       "and hence must be at least twice the cylinder radius. "\
                                       "Separations closer than this will cause cylinders to overlap and "\
                                       "intersect and may cause unexpected results. Both distances must be "\
                                       "specified in meters (NOT in microns).")

    crossangle = traits.Float(argstr='-crossangle %s',desc="The crossing angle is specified in radians "\
                                      "(NOT degrees) using the -crossangle 0.7854. This is approximately pi/4,"\
                                      " or 45 degrees. The crossing angle can take on any value, just make sure"\
                                      " you use radians!")

    gamma = traits.List(traits.Float,minlen=2,maxlen=2,argstr='-gamma %s',desc="Gamma distribution parameters")

    #out_file = traits.File(desc = 'name of output file')

class MonteCarloOutputSpec(TraitedSpec):

    synth_data = File(exists=True, desc='simulated_data')
    trajectories_file = File(exists=True)

class MonteCarlo(StdOutCommandLine):
    """
    Example
    -------

    >>> import nipype.interfaces.camino.datasynth
    >>> mc = datasynth.MonteCarlo()

    >>> mc = datasynth.MonteCarlo()
    >>> mc.inputs.walkers = 100000
    >>> mc.inputs.tmax = 1000
    >>> mc.inputs.barrier_permeability = 0.0
    >>> mc.inputs.voxels = 1
    >>> mc.inputs.initial = 'uniform'
    >>> mc.inputs.schemefile = '59.scheme'
    >>> mc.inputs.substrate = 'inflammation'
    >>> mc.inputs.increments = 1
    >>> mc.inputs.gamma = [1.84037, 7.8E-7]
    >>> mc.inputs.substratesize = 3.5E-5 #0.0000355m = 0.0355mm = 35.5um
    >>> mc.inputs.numcylinders = 100
    >>> mc.inputs.out_file = 'gammacyls_n100_tester_fixed_code.bfloat'
    >>> mc.cmdline
    """

    _cmd = 'datasynth'
    input_spec=MonteCarloInputSpec
    output_spec=MonteCarloOutputSpec

    def _gen_outfilename(self):
        return "synth_data.Bfloat"

    def _gen_filename(self, name):
        if name is 'trajectories_file':
            return 'MC.traj'
        else:
            return super(MonteCarlo, self)._gen_filename(name)

    def _format_arg(self, name, spec, value):
        if name == 'trajectories_file':
            if isinstance(value, bool):
                if value == True:
                    value = self._gen_filename(name)
                else:
                    return ""
        elif name == 'out_file':
            if isdefined(self.inputs.trajectories_file) and self.inputs.trajectories_file:
                return ""
            else:
                return super(MonteCarlo, self)._format_arg(name, spec, value)
        return super(MonteCarlo, self)._format_arg(name, spec, value)

    def _list_outputs(self):
        outputs = self.output_spec().get()
        if isdefined(self.inputs.trajectories_file) and self.inputs.trajectories_file:
            if isinstance(self.inputs.trajectories_file, bool):
                outputs['trajectories_file'] = os.path.abspath(self._gen_filename("trajectories_file"))
            else:
                outputs['trajectories_file'] = os.path.abspath(self.inputs.trajectories_file)
        elif isdefined(self.inputs.out_file) and self.inputs.out_file:
            outputs['synth_data'] = os.path.abspath(self.inputs.out_file)
        else:
            outputs['synth_data'] = os.path.abspath(self._gen_filename("out_file"))
        return outputs #self._outputs_from_inputs(outputs)

class ScanTrajfileInputSpec(StdOutCommandLineInputSpec):

    trajfile = traits.File(exists=True, argstr='-trajfile %s',desc = 'trajectories file')

    schemefile = traits.File(exists=True, argstr='-schemefile %s',desc = 'scheme file')

    out_file = traits.File(desc = 'name of output file (.Bfloat format)')

class ScanTrajfileOutputSpec(TraitedSpec):

    synth_data = File(exists=True, desc='simulated_data')

class ScanTrajfile(StdOutCommandLine):
    """
    Example:
    -------
    >>> from nipype.interfaces.camino import datasynth
    >>> st = datasynth.ScanTrajfile()
    >>> st.inputs.trajfile = <trajectories filename>
    >>> st.inputs.schemefile = < scheme file >
    >>> st.inputs.out_file = < output file >
    >>> st.run()                  # doctest: +SKIP
    """

    _cmd = 'scan '
    input_spec=ScanTrajfileInputSpec
    output_spec=ScanTrajfileOutputSpec

    def _list_outputs(self):
        outputs = self.output_spec().get()
        outputs['synth_data'] = os.path.abspath(self._gen_outfilename())
        return outputs

    def _gen_outfilename(self):
        outfilename = self.inputs.out_file
        return outfilename


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Sep  5 12:32:28 2020

@author: gac
"""

from multiprocessing import Process, Value, RawArray
from threading import Thread
import subprocess, time, os
# os.popen('sh /home/gac/nginx.sh')
import cv2
import numpy as np
import json
import paho.mqtt.client as mqtt

class playVideoOnDemand:
    def __init__(self, image_raw, cam_IP, flag):
        self.pushVideo_dict = dict()

        def on_connect(client, userdata, flags, rc):
            print("Connected with result code " + str(rc))

        def on_message(client, userdata, msg):
            self.pushVideo_dict = dict(json.loads(msg.payload.decode()))
            # print(msg.topic + " " + str(msg.payload))

        self.flag_dict = {}
        self.openVideo = []
        self.cam_IP = cam_IP
        self.client = mqtt.Client()
        self.client.on_connect = on_connect
        self.client.on_message = on_message
        self.client.connect("127.0.0.1", 1883, 60)
        self.client.subscribe('/Caeri/Push_Stream', qos=0)
        self.client.loop_start()
        while flag.value == 1:
            # print(self.pushVideo_dict)
            try:
                for cameraIp, para in list(self.pushVideo_dict.items()):
                    print(para.get('set'))
                    if para.get('set') == 1:
                        if cameraIp in self.openVideo or cameraIp != self.cam_IP:
                            time.sleep(0.5)
                            break
                        self.flag_dict[cameraIp] = 1
                        self.openVideo.append(cameraIp)
                        pushType = para.get('pushType')
                        pushUri = para.get('pushUri')
                        try:
                            pushTimeMin = int(para.get('pushTimeMin'))
                        except:
                            pushTimeMin = 10
                        if cameraIp and pushUri:
                            Thread(target=lambda: self.push_stream(cameraIp, image_raw, pushType, pushUri,
                                                                   pushTimeMin)).start()
                    else:
                        self.flag_dict[cameraIp] = 0
                        del self.pushVideo_dict[cameraIp]
            except:
                pass
            time.sleep(0.5)

    def push_stream(self, cameraIp, push_img_raw, pushType, pushUri, pushTimeMin):
        command = ['ffmpeg',
                   '-y',
                   '-f', 'rawvideo',
                   '-vcodec', 'rawvideo',
                   '-pix_fmt', 'bgr24',
                   '-s', "{}x{}".format(960, 540),
                   '-r', '25',
                   '-i', '-',
                   '-c:v', 'libx264',
                   '-pix_fmt', 'yuv420p',
                   '-preset', 'ultrafast',
                   '-f', 'flv',
                   pushUri]
        # 管道配置
        p = subprocess.Popen(command, stdin=subprocess.PIPE)
        del self.pushVideo_dict[cameraIp]
        t0 = time.time()
        while self.flag_dict[cameraIp]:
            t = time.time()
            if t - t0 < int(pushTimeMin) * 60:
                data = np.copy(np.ctypeslib.as_array(push_img_raw))
                height = data[0] + data[1] * 256
                if height == 0:
                    continue
                width = data[2] + data[3] * 256
                image = data[4:height * width * 3 + 4].reshape(height, width, 3)
                try:
                    image = cv2.resize(image, (960, 540))
                    p.stdin.write(image.tobytes())
                except:
                    continue
            else:
                self.openVideo.remove(cameraIp)
                break
            if time.time() - t < 1/25:
                time.sleep(1/25 - (time.time() - t))
        self.openVideo.remove(cameraIp)

def push_rtmp(filename, IP='127.0.0.1', shape=(640, 360)):
    rtmp = 'rtmp://116.63.160.171:31935/live/' + filename
    print(rtmp)
    command = ['ffmpeg',
               '-y',
               '-f', 'rawvideo',
               '-vcodec', 'rawvideo',
               '-pix_fmt', 'bgr24',
               '-s', "{}x{}".format(shape[0], shape[1]),
               # '-r', str(fps),
               '-i', '-',
               '-c:v', 'libx264',
               '-pix_fmt', 'yuv420p',
               '-preset', 'ultrafast',
               '-f', 'flv',
               rtmp]
    return subprocess.Popen(command, stdin=subprocess.PIPE)

def camera_push_screen(file_name, img_arr, flag, img_size=(640, 360)):
    tick = time.time()
    while flag:
        t1 = time.time()
        if 'push_img' not in vars():
            push_img = push_rtmp(filename=file_name)
        if subprocess.Popen.poll(push_img) != None:
            push_img.kill()
            del push_img
            continue
        if time.time() - tick > 10:
            print('push status:', subprocess.Popen.poll(push_img))
            tick = time.time()
        data = np.copy(np.ctypeslib.as_array(img_arr))
        height = data[0] + data[1] * 256
        width = data[2] + data[3] * 256
        img = data[4:height * width * 3 + 4].reshape(height, width, 3)
        if height == width == 0:
            # print('image error')
            continue
        else:
            show_image = cv2.resize(img, img_size)
        try:
            # cv2.imshow('a', show_image)
            # cv2.waitKey(1)
            push_img.stdin.write(show_image.tobytes())
            # print('push stream success')
        except:
            print('Push stream failed!')
        # print(time.time() - t1)
        while time.time() - t1 <= 1 / 25:
            continue

if __name__ == '__main__':
    img = cv2.imread("D:/Desktop/000001.jpg")
    flag = Value('i', 1)
    Image_Raw = RawArray("B", 1920 * 1080 * 3 + 4)  # np.uint8
    i_height, i_width = img.shape[0], img.shape[1]
    i_packet_head = [i_height % 256, i_height // 256, i_width % 256, i_width // 256]
    i_packet_body = img.ravel()
    i_packet = np.insert(i_packet_body, 0, i_packet_head)
    memoryview(Image_Raw).cast('B')[:img.size + 4] = i_packet
    # a = Process(target=camera_push_screen, args=('172_16_11_130', Image_Raw, flag))
    # a.start()
    cam_IP = '10.130.210.30'
    b = Process(target=playVideoOnDemand, args=(Image_Raw, cam_IP, flag))
    b.start()
    while True:
        t1 = time.time()
        # print(aa.value)
        while time.time() - t1 <= 1 / 2:
            continue


from docker import Client
import pytest
from faker import Faker
from utils import retry
from factories import ContainerFactory, MasterFactory, MinionFactory

@pytest.fixture(scope="session")
def docker_client():
    client = Client(base_url='unix://var/run/docker.sock')
    return client

@pytest.fixture(scope="session")
def salt_root(tmpdir_factory):
    return tmpdir_factory.mktemp("salt")

@pytest.fixture(scope="session")
def pillar_root(salt_root):
    salt_root.mkdir('pillar')
    return '/etc/salt/pillar'

@pytest.fixture(scope="session")
def file_root(salt_root):
    salt_root.mkdir('topfiles')
    return '/etc/salt/topfiles'

@pytest.fixture(scope="module")
def salt_master_config(file_root, pillar_root):
    return {
        'base_config': {
            'hash_type': 'sha384',
            'pillar_roots': {
                'base': [pillar_root]
            },
            'file_roots': {
                'base': [file_root]
            }
        }
    }

@pytest.fixture(scope="module")
def salt_minion_config(master_container, salt_root, docker_client):
    return {
        'master': master_container['ip'],
        'hash_type': 'sha384',
    }

@pytest.fixture(scope="module")
def master_container_extras():
    return dict()

@pytest.fixture(scope="module")
def master_container(request, salt_root, master_container_extras, salt_master_config, docker_client):
    fake = Faker()
    obj = ContainerFactory(
        config__name='master_{0}_{1}'.format(fake.word(), fake.word()),
        config__salt_config__tmpdir=salt_root,
        docker_client=docker_client,
        config__salt_config__conf_type='master',
        config__salt_config__config=salt_master_config,
        config__salt_config__post__id='{0}_{1}'.format(fake.word(), fake.word()),
        **master_container_extras
    )
    request.addfinalizer(
        lambda: obj['docker_client'].remove_container(
            obj['config']['name'], force=True)
    )
    return obj

@pytest.fixture(scope="module")
def minion_container_extras():
    return dict()

@pytest.fixture(scope="module")
def minion_container(request, salt_root, minion_container_extras, salt_minion_config, docker_client):
    fake = Faker()
    obj = ContainerFactory(
        config__name='minion_{0}_{1}'.format(fake.word(), fake.word()),
        config__salt_config__tmpdir=salt_root,
        docker_client=docker_client,
        config__salt_config__conf_type='minion',
        config__salt_config__config={
            'base_config': salt_minion_config
        },
        **minion_container_extras
    )
    request.addfinalizer(
        lambda: obj['docker_client'].remove_container(
            obj['config']['name'], force=True))
    return obj

@pytest.fixture(scope="module")
def master(request, master_container):
    return MasterFactory(container=master_container)

@pytest.fixture(scope="module")
def minion(request, minion_container):
    out = MinionFactory(container=minion_container)
    return out

@pytest.fixture(scope='module')
def minion_key_cached(master, minion):

    def cache():
        return minion['id'] in master.salt_key(minion['id'])['minions_pre']

    assert retry(cache) is True

@pytest.fixture(scope='module')
def minion_key_accepted(master, minion, minion_key_cached):
    master.salt_key_accept(minion['id'])

    def accept():
        return minion['id'] in master.salt_key()['minions']

    assert retry(accept) is True


#!/usr/bin/env python

# BSD 3-Clause License; see https://github.com/scikit-hep/uproot/blob/master/LICENSE

import struct
from copy import copy

import numpy

import uproot
import uproot.const
import uproot.write.compress
import uproot.write.sink.cursor

class newbranch(object):

    def __init__(self, type, flushsize=30000, title="", compression=None):
        self.name = ""
        self.type = type
        self.flushsize = flushsize
        self.title = title
        self.compression = compression

class newtree(object):

    def __init__(self, branches={}, flushsize=30000, title="", compression=None):
        self.branches = branches
        self.flushsize = flushsize
        self.title = title
        self.compression = compression

class TTree(object):

    def __init__(self, newtree):
        self.name = ""
        self.fClassName = b"TTree"
        self.fName = self.fixstring(self.name)
        self.fTitle = self.fixstring(newtree.title)

        self.branches = []
        for name, branch in newtree.branches.items():
            self.branches.append(TBranch(branch.type, name, branch.title, defaultBasketSize=32000, compression=branch.compression))

        self.fields = {"_fLineColor": 602,
                       "_fLineStyle": 1,
                       "_fLineWidth": 1,
                       "_fFillColor": 0,
                       "_fFillStyle": 1001,
                       "_fMarkerColor": 1,
                       "_fMarkerStyle": 1,
                       "_fMarkerSize": 1.0,
                       "_fEntries": 0,
                       "_fTotBytes": 0,
                       "_fZipBytes": 0,
                       "_fSavedBytes": 0,
                       "_fFlushedBytes": 0,
                       "_fWeight": 1.0,
                       "_fTimerInterval": 0,
                       "_fScanField": 25,
                       "_fUpdate": 0,
                       "_fDefaultEntryOffsetLen": 1000, #TODO: WHAT IS THIS?
                       "_fNClusterRange": 0,
                       "_fMaxEntries": 1000000000000, #TODO: HOW DOES THIS WORK?
                       "_fMaxEntryLoop": 1000000000000, #Same as fMaxEntries?
                       "_fMaxVirtualSize": 0,
                       "_fAutoSave": -300000000,
                       "_fAutoFlush": -30000000,
                       "_fEstimate": 1000000,
                       "_fClusterRangeEnd": [],
                       "_fClusterSize": [],
                       "_fBranches": [],
                       "_fFriends": None,
                       "_fTreeIndex": None,
                       "_fIndex": [],
                       "_fIndexValues": [],
                       "_fAliases": None,
                       "_fLeaves": [],
                       "_fUserInfo": None,
                       "_fBranchRef": None}

    @staticmethod
    def fixstring(string):
        if isinstance(string, bytes):
            return string
        else:
            return string.encode("utf-8")

    _format_cntvers = struct.Struct(">IH")

    _format_tobject1 = struct.Struct(">HII")
    def put_tobject(self, cursor, hexbytes):
        return cursor.put_fields(self._format_tobject1, 1, 0, hexbytes)

    def put_tnamed(self, cursor, name, title, hexbytes=numpy.uint32(0x03000000)):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        buff = (self.put_tobject(cursor, hexbytes) +
                cursor.put_string(name) + cursor.put_string(title))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tattline = struct.Struct(">hhh")
    def put_tattline(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 2
        buff = (cursor.put_fields(self._format_tattline,
                                  self.fields["_fLineColor"],
                                  self.fields["_fLineStyle"],
                                  self.fields["_fLineWidth"]))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tattfill = struct.Struct(">hh")
    def put_tattfill(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 2
        buff = (cursor.put_fields(self._format_tattfill,
                                  self.fields["_fFillColor"],
                                  self.fields["_fFillStyle"]))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tattmarker = struct.Struct(">hhf")
    def put_tattmarker(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 2
        buff = (cursor.put_fields(self._format_tattmarker,
                                  self.fields["_fMarkerColor"],
                                  self.fields["_fMarkerStyle"],
                                  self.fields["_fMarkerSize"]))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_rootiofeatures = struct.Struct(">B")
    def put_rootiofeatures(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 0
        fIOBits = 0
        cursor.skip(4)
        buff = b"\x1a\xa1/\x10" + cursor.put_fields(self._format_rootiofeatures, fIOBits)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tobjarray1 = struct.Struct(">ii")
    def put_tobjarray(self, cursor, values, classname, fBits=50331648):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        buff = self._skiptobj(cursor, fBits)
        vers = 3
        try:
            size = len(values)
        except TypeError:
            size = 1
            values = [values]
        low = 0
        buff += cursor.put_string(b"") + cursor.put_fields(self._format_tobjarray1, size, low)
        for value in values:
            buff += self.util.put_objany(cursor, (value, classname), self.keycursor)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_skiptobj1 = struct.Struct(">h")
    _format_skiptobj2 = struct.Struct(">II")
    def _skiptobj(self, cursor, fBits):
        version = 1
        buff = cursor.put_fields(self._format_skiptobj1, version)
        fUniqueID = 0
        buff += cursor.put_fields(self._format_skiptobj2, fUniqueID, fBits)
        return buff

    _format_tarray = struct.Struct(">i")
    def put_tarray(self, cursor, values):
        return cursor.put_fields(self._format_tarray, values.size) + cursor.put_array(values)

    _format_ttree = struct.Struct(">qqqqqdiiiiIqqqqqq")
    def _write(self, context, cursor, name, compression, key, keycursor, util):
        self.util = util
        self.util.set_obj(self)
        copy_cursor = copy(cursor)
        write_cursor = copy(cursor)
        self.keycursor = keycursor
        cursor.skip(self._format_cntvers.size)
        vers = 20

        self.fields["_fClusterRangeEnd"] = numpy.array(self.fields["_fClusterRangeEnd"], dtype="int64", copy=False)
        self.fields["_fClusterSize"] = numpy.array(self.fields["_fClusterSize"], dtype="int64", copy=False)
        self.fields["_fIndexValues"] = numpy.array(self.fields["_fIndexValues"], dtype=">f8", copy=False)
        self.fields["_fIndex"] = numpy.array(self.fields["_fIndex"], dtype=">i8", copy=False)

        for branch in self.branches:
            self.fields["_fEntries"] += branch.fields["_fEntries"]
            self.fields["_fTotBytes"] += branch.fields["_fTotBytes"]
            self.fields["_fZipBytes"] += branch.fields["_fZipBytes"]
            self.fields["_fLeaves"].append(branch.fields["_fLeaves"])
            #TODO: HAVE TO WRITE BRANCH!
            branch.util = self.util
            branch.keycursor = self.keycursor
            self.fields["_fBranches"].append(branch)

        buff = (self.put_tnamed(cursor, name, self.fTitle, hexbytes=numpy.uint32(0x03000008)) +
                self.put_tattline(cursor) +
                self.put_tattfill(cursor) +
                self.put_tattmarker(cursor) +
                cursor.put_fields(self._format_ttree, self.fields["_fEntries"],
                                  self.fields["_fTotBytes"],
                                  self.fields["_fZipBytes"],
                                  self.fields["_fSavedBytes"],
                                  self.fields["_fFlushedBytes"],
                                  self.fields["_fWeight"],
                                  self.fields["_fTimerInterval"],
                                  self.fields["_fScanField"],
                                  self.fields["_fUpdate"],
                                  self.fields["_fDefaultEntryOffsetLen"],
                                  self.fields["_fNClusterRange"],
                                  self.fields["_fMaxEntries"],
                                  self.fields["_fMaxEntryLoop"],
                                  self.fields["_fMaxVirtualSize"],
                                  self.fields["_fAutoSave"],
                                  self.fields["_fAutoFlush"],
                                  self.fields["_fEstimate"]) +
                cursor.put_array(self.fields["_fClusterRangeEnd"]) +
                b"\x00")
        cursor.skip(len(b"\x00"))
        buff += (cursor.put_array(self.fields["_fClusterSize"]) +
                b"\x00")
        cursor.skip(len(b"\x00"))
        buff += (self.put_rootiofeatures(cursor) +
                self.put_tobjarray(cursor, self.fields["_fBranches"], "TBranch", fBits=50348032))
        if self.fields["_fBranches"] == []:
            buff += self.put_tobjarray(cursor, self.fields["_fLeaves"], "TLeaf")
        else:
            buff += self.put_tobjarray(cursor, self.fields["_fLeaves"][0][0], classname=self.fields["_fLeaves"][0][1])
        buff += (self.util.put_objany(cursor, (self.fields["_fAliases"], "TList"), self.keycursor) +
                 self.put_tarray(cursor, self.fields["_fIndexValues"]) +
                 self.put_tarray(cursor, self.fields["_fIndex"]) +
                 self.util.put_objany(cursor, (self.fields["_fTreeIndex"], "TVirtualIndex"), self.keycursor) +
                 self.util.put_objany(cursor, (self.fields["_fFriends"], "TList"), self.keycursor) +
                 self.util.put_objany(cursor, (self.fields["_fUserInfo"], "TList"), self.keycursor) +
                 self.util.put_objany(cursor, (self.fields["_fBranchRef"], "TBranchRef"), self.keycursor))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        givenbytes = copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff
        uproot.write.compress.write(context, write_cursor, givenbytes, compression, key, keycursor)

class TBranch(object):

    # Need to think about appropriate defaultBasketSize
    # Need to look at ROOT's default branch compression
    def __init__(self, type, name, title, defaultBasketSize=32000, compression=None):

        self.type = numpy.dtype(type).newbyteorder(">")
        self.name = self.fixstring(name)
        if title == "":
            self.title = self.fixstring(name)
            self.nametitle = self.title + b"/I"
        else:
            self.title = self.fixstring(title)
            self.nametitle = self.title
        self.defaultBasketSize = defaultBasketSize
        self.compression = compression
        self.util = None
        self.keycursor = None

        self.fields = {"_fCompress" : 100,
                       "_fBasketSize" : self.defaultBasketSize,
                       "_fEntryOffsetLen": 0,
                       "_fWriteBasket": 0, #Number of baskets
                       "_fOffset": 0,
                       "_fMaxBaskets": 10, #TODO: WHAT DOES THIS MEAN?!!! (IMPORTANT!!!)
                       "_fSplitLevel": 0,
                       "_fEntries": 0, #Number of values in the branch = fEntryNumber in our case
                       "_fFirstEntry": 0, #First value in the branch
                       "_fTotBytes": 0, #Number of bytes of the branch?
                       "_fZipBytes": 0, #Same as fTotBytes when no compression
                       "_fBasketBytes": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       "_fBasketEntry": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #TODO: WHAT DOES THIS MEAN?!!! (IMPORTANT!!!)
                       "_fBasketSeek": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #Number of entries = fMaxBaskets. Empty baskets = 0.
                       "_fFileName": b"",
                       "_fBranches": [],
                       "_fLeaves": [],
                       "_fFillColor": 0,
                       "_fFillStyle": 1001,
                       "_fEntryNumber": 0}

        if self.type == "int8":
            self.fields["_fLeaves"] = [self, "TLeafB"]
        elif self.type == ">U":
            self.fields["_fLeaves"] = [self, "TLeafC"]
        elif self.type == ">f8":
            self.fields["_fLeaves"] = [self, "TLeafD"]
        elif self.type == ">f4":
            self.fields["_fLeaves"] = [self, "TLeafF"]
        elif self.type == ">i4":
            self.fields["_fLeaves"] = [self, "TLeafI"]
        elif self.type == ">i8":
            self.fields["_fLeaves"] = [self, "TleafL"]
        elif self.type == ">?":
            self.fields["_fLeaves"] = [self, "TLeafO"]
        elif self.type == ">i2":
            self.fields["_fLeaves"] = [self, "TLeafS"]
        else:
            raise NotImplementedError

        self.fields["_fBasketBytes"] = numpy.array(self.fields["_fBasketBytes"], dtype=">i4", copy=False)
        self.fields["_fBasketEntry"] = numpy.array(self.fields["_fBasketEntry"], dtype=">i8", copy=False)
        self.fields["_fBasketSeek"] = numpy.array(self.fields["_fBasketSeek"], dtype=">i8", copy=False)

    def append(self, item):
        self.extend(item)

    def extend(self, items):
        raise NotImplementedError

    def basket(self, items):
        raise NotImplementedError

    @staticmethod
    def fixstring(string):
        if isinstance(string, bytes):
            return string
        else:
            return string.encode("utf-8")

    _format_cntvers = struct.Struct(">IH")

    _format_tobject1 = struct.Struct(">HII")
    def put_tobject(self, cursor, hexbytes):
        return cursor.put_fields(self._format_tobject1, 1, 0, hexbytes)

    def put_tnamed(self, cursor, name, title, hexbytes=numpy.uint32(0x03000000)):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        buff = (self.put_tobject(cursor, hexbytes) +
                cursor.put_string(name) + cursor.put_string(title))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tattfill = struct.Struct(">hh")
    def put_tattfill(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 2
        buff = (cursor.put_fields(self._format_tattfill,
                                  self.fields["_fFillColor"],
                                  self.fields["_fFillStyle"]))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_rootiofeatures = struct.Struct(">B")
    def put_rootiofeatures(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 0
        fIOBits = 0
        cursor.skip(4)
        buff = b"\x1a\xa1/\x10"
        buff += cursor.put_fields(self._format_rootiofeatures, fIOBits)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleaf1 = struct.Struct('>iii??')
    def put_tleaf(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 2
        fLen = 1
        fLenType = 4
        fOffset = 0
        fIsRange = False
        fIsUnsigned = False
        fLeafCount = None
        buff = (self.put_tnamed(cursor, self.name, self.title) +
                cursor.put_fields(self._format_tleaf1, fLen, fLenType, fOffset, fIsRange, fIsUnsigned) +
                self.util.put_objany(cursor, (fLeafCount, "TLeaf"), self.keycursor))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafI1 = struct.Struct('>ii')
    def put_tleafI(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafI1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafB1 = struct.Struct('>bb')
    def put_tleafB(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafB1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafD1 = struct.Struct('>dd')
    def put_tleafD(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafD1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafF1 = struct.Struct('>ff')
    def put_tleafF(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafF1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafL1 = struct.Struct('>qq')
    def put_tleafL(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafL1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafO1 = struct.Struct('>??')
    def put_tleafO(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafO1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tleafS1 = struct.Struct('>hh')
    def put_tleafS(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 1
        fMinimum = 0
        fMaximum = 0
        buff = self.put_tleaf(cursor) + cursor.put_fields(self._format_tleafS1, fMinimum, fMaximum)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_tobjarray1 = struct.Struct(">ii")
    def put_tobjarray(self, cursor, values, classname, fBits=50331648):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        buff = self._skiptobj(cursor, fBits)
        vers = 3
        try:
            size = len(values)
        except TypeError:
            size = 1
            values = [values]
        low = 0
        buff += cursor.put_string(b"") + cursor.put_fields(self._format_tobjarray1, size, low)
        for value in values:
            buff += self.util.put_objany(cursor, (value, classname), self.keycursor)
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff

    _format_skiptobj1 = struct.Struct(">h")
    _format_skiptobj2 = struct.Struct(">II")
    def _skiptobj(self, cursor, fBits):
        version = 1
        buff = cursor.put_fields(self._format_skiptobj1, version)
        fUniqueID = 0
        buff += cursor.put_fields(self._format_skiptobj2, fUniqueID, fBits)
        return buff

    _format_tbranch1 = struct.Struct('>iiiiq')
    _format_tbranch2 = struct.Struct('>iIiqqqq')
    def write(self, cursor):
        copy_cursor = copy(cursor)
        cursor.skip(self._format_cntvers.size)
        vers = 13
        buff = (self.put_tnamed(cursor, self.name, self.nametitle, hexbytes=numpy.uint32(0x03400000)) +
                self.put_tattfill(cursor) +
                cursor.put_fields(self._format_tbranch1,
                                  self.fields["_fCompress"],
                                  self.fields["_fBasketSize"],
                                  self.fields["_fEntryOffsetLen"],
                                  self.fields["_fWriteBasket"],
                                  self.fields["_fEntryNumber"]) +
                self.put_rootiofeatures(cursor) +
                cursor.put_fields(self._format_tbranch2,
                                  self.fields["_fOffset"],
                                  self.fields["_fMaxBaskets"],
                                  self.fields["_fSplitLevel"],
                                  self.fields["_fEntries"],
                                  self.fields["_fFirstEntry"],
                                  self.fields["_fTotBytes"],
                                  self.fields["_fZipBytes"]) +
                self.put_tobjarray(cursor, self.fields["_fBranches"], classname="TBranch") +
                self.put_tobjarray(cursor, self.fields["_fLeaves"][0], classname=self.fields["_fLeaves"][1]) +
                #self.put_tobjarray(cursor, self.fields["fBaskets"]) +
                b"@\x00\x00\x15\x00\x03\x00\x01\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
        cursor.skip(len(b"@\x00\x00\x15\x00\x03\x00\x01\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"))
        buff += (b"\x01")
        cursor.skip(len(b"\x01"))
        buff += (cursor.put_array(self.fields["_fBasketBytes"]) +
                b"\x01")
        cursor.skip(len(b"\x01"))
        buff += (cursor.put_array(self.fields["_fBasketEntry"]) + b"\x01")
        cursor.skip(len(b"\x01"))
        buff += (cursor.put_array(self.fields["_fBasketSeek"]) +
                cursor.put_string(self.fields["_fFileName"]))
        length = len(buff) + self._format_cntvers.size
        cnt = numpy.int64(length - 4) | uproot.const.kByteCountMask
        return copy_cursor.put_fields(self._format_cntvers, cnt, vers) + buff


import chainer
import chainer.functions as F
import chainer.links.caffe as C
import numpy as np
from PIL import Image

from model import ImageCaptionNN

TEST_IMAGES = ('test-{}.jpg'.format(i) for i in range(1, 6))

index2word = {0: '', 1:''}
with open('words.txt', 'r') as f:
    for line in f:
        line = line.strip().split(',')
        index2word[int(line[0])] = line[1]

cnn = C.CaffeFunction('bvlc_alexnet.caffemodel')
model = ImageCaptionNN(max(index2word.keys()) + 1, 512)
chainer.serializers.load_hdf5('chap09.hdf5', model)

words_max = 15
beam_w = 5

def tree_traverse():
    global max_score
    cur_word = cur_sentence[-1]
    score = np.prod(cur_score)
    depth = len(cur_sentence)
    if depth > 5 and score < max_score * 0.6:
        return
    if cur_word == 1 or depth > words_max:
        data = np.array(cur_sentence)
        sentences.append((score, data))
        if score > max_score:
            max_score = score
        return
    cur_model = model_history[-1].copy()
    x = np.array([cur_word], dtype=np.int32)
    y = cur_model.decode(x)
    z = F.softmax(y)
    result = z.data[0]
    argsort = np.argsort(result)[::-1]
    model_history.append(cur_model)
    for i in range(beam_w):
        cur_sentence.append(argsort[i])
        cur_score.append(result[argsort[i]])
        tree_traverse()
        cur_sentence.pop()
        cur_score.pop()
    model_history.pop()

for image_filename in TEST_IMAGES:
    with open(image_filename, 'r') as f:
        print(image_filename)
        image = Image.open(image_filename).resize((400, 400)).convert('RGB')

        vectors = []

        for s in ((0, 0, 227, 227),
                  (173, 0, 400, 227),
                  (0, 173, 227, 400),
                  (173, 173, 400, 400),
                  (86, 86, 313, 313)):
            crop_image = image.crop(s)
            pix = np.array(crop_image, dtype=np.float32)
            pix = pix[::-1].transpose(2, 0, 1)
            pix = np.array([pix], dtype=np.float32)
            x, = cnn(inputs={'data': pix}, outputs=['fc6'], disable=['drop6'])
            model.encode(x)

        c, h = model.get_state()
        model.set_state(c, h)

        sentences = []
        model_history = [model]
        cur_sentence = [0]
        cur_score = []
        max_score = 0

        tree_traverse()

        sentences = sorted(sentences, key=lambda x: x[0])[::-1]

        for i in range(min([5, len(sentences)])):
            score, description = sentences[i]
            print('{}  {}'.format(score, ''.join(map(index2word.get, description))))


__all__ = ('ROSConsole', )

import os
import re
import shlex
import subprocess
import sys
from functools import partial

#from designer.utils.utils import get_fs_encoding
from kivy.app import runTouchApp
from kivy.clock import Clock
from kivy.compat import PY2
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.logger import Logger
from kivy.properties import (
    BooleanProperty,
    DictProperty,
    ListProperty,
    NumericProperty,
    ObjectProperty,
)
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.utils import platform
from pygments.lexers.shell import BashSessionLexer
import paramiko
from ROSClientSSH import ROSClientSSH
from ROSClientSSH1 import ROSClientSSH1

try:
    import thread
except ImportError:
    import _thread as thread

Builder.load_string('''
<ROSConsole>:
    cols:1
    txtinput_history_box: history_box.__self__
    txtinput_command_line: command_line.__self__
    ScrollView:
        bar_width: 10
        scroll_type: ['bars', 'content']
        CodeInput:
            id: history_box
            size_hint: (1, None)
            height: 801
            font_size: root.font_size_history
            readonly: False
            foreground_color: root.foreground_color
            background_color: root.background_color
    TextInput:
        id: command_line
        multiline: False
        size_hint: (1, None)
        font_size: root.font_size
        readonly: root.readonly
        foreground_color: root.foreground_color
        background_color: root.background_color_input
        height: 36
        on_text_validate: root.on_enter(*args)
        on_touch_up:
            self.collide_point(*args[1].pos)\\
            and root._move_cursor_to_end(self)
''')

class ROSConsole(GridLayout):
    '''This is a Console widget used for debugging and running external
    commands
    '''

    readonly = BooleanProperty(False)
    foreground_color = ListProperty((1, 1, 1, 1))
    background_color = ListProperty((0, 0, 0, 1))
    background_color_input = ListProperty((0.1, .1, .1, 1))

    cached_history = NumericProperty(200)
    cached_commands = NumericProperty(90)
    environment = DictProperty(os.environ.copy())
    font_size = NumericProperty(14)
    font_size_history = NumericProperty(14)
    textcache = ListProperty(['', ])

    txtinput_command_line = ObjectProperty(None)

    def __init__(self, **kwargs):
        self.register_event_type('on_subprocess_done')
        self.register_event_type('on_command_list_done')
        super(ROSConsole, self).__init__(**kwargs)
        # initialisations
        self.txtinput_command_line_refocus = False
        self.txtinput_run_command_refocus = False
        self.win = None
        self.scheduled = False
        self.command_history = []
        self.command_history_pos = 0
        self.command_status = 'closed'
        if sys.version_info >= (3, 0):
            self.cur_dir = os.getcwd()
        else:
            self.cur_dir = os.getcwdu()
        self.command_list = []  # list of cmds to be executed
        #self.stdout = std_in_out(self, 'stdout')
        #self.stdin = std_in_out(self, 'stdin')
        self.popen_obj = None
        # self.stderror = stderror(self)
        # delayed initialisation
        Clock.schedule_once(self._initialize)
        _trig = Clock.create_trigger(self._change_txtcache)
        Clock.schedule_once(_trig)
        self.bind(textcache=_trig)

        self.rosSSH = ROSClientSSH1("berry")

        self._hostname = 'unknown'
        try:
            if hasattr(os, 'uname'):
                self._hostname = os.uname()[1]
            else:
                self._hostname = os.environ.get('COMPUTERNAME', 'unknown')
        except Exception:
            pass
        self._username = os.environ.get('USER', '')
        if not self._username:
            self._username = os.environ.get('USERNAME', 'unknown')

    def clear(self, *args):
        '''Clear the Kivy Console area
        '''
        self.txtinput_history_box.text = ''
        self.textcache = ['']

    def _initialize(self, dt):
        '''Set console default variable values
        '''

        self.txtinput_history_box.lexer = BashSessionLexer()
        self.txtinput_history_box.text = ''.join(self.textcache)

        self.rosSSH.open(self.add_to_cache)

        self.txtinput_command_line.text = self.rosSSH.prompt()
        self.txtinput_command_line.bind(focus=self.on_focus)
        self.txtinput_command_line.bind(selection_text=self.on_txtinput_selection)
        self._focus(self.txtinput_command_line)

    def on_txtinput_selection(self, *args):
        '''Callback to command input text selection.
        Cannot select the PS1 variable, so it'll handle to select only
        input text.
        '''
        ticl = self.txtinput_command_line
        col = len(self.rosSSH.prompt())
        ticl.select_text(col, len(ticl.text))

    def _move_cursor_to_end(self, instance):
        '''Moves the command input cursor to the end
        '''
        def mte(*l):
            instance.cursor = instance.get_cursor_from_index(len_prompt)
        len_prompt = len(self.rosSSH.prompt())
        if instance.cursor[0] < len_prompt:
            Clock.schedule_once(mte, -1)

    def _focus(self, widg, t_f=True):
        Clock.schedule_once(partial(self._deffered_focus, widg, t_f))

    def _deffered_focus(self, widg, t_f, dt):
        if widg.get_root_window():
            widg.focus = t_f

    def _change_txtcache(self, *args):
        '''Update the Kivy Console output area
        '''
        try:
            # if passing the text cache limit, omit it
            self.textcache = self.textcache[-self.cached_history:]
        except IndexError:
            pass
        for i in range(len(self.textcache)):
            pass
            #if PY2 and isinstance(self.textcache[i], unicode):
            #    self.textcache[i] = self.textcache[i].encode('utf-8')
        tihb = self.txtinput_history_box
        tihb.text = ''.join(self.textcache)
        if not self.get_root_window():
            return
        tihb.height = max(tihb.minimum_height, tihb.parent.height)
        tihb.parent.scroll_y = 0

    def on_key_down(self, *l):
        '''Handle the on_key_down from keyboard
        '''
        ticl = self.txtinput_command_line

        print (l)

        def move_cursor_to(col):
            '''Update the cursor position
            '''
            ticl.cursor =\
                col, ticl.cursor[1]

        def search_history(up_dn):
            if up_dn == 'up':
                plus_minus = -1
            else:
                plus_minus = 1
            l_curdir = len(self.rosSSH.prompt())
            col = ticl.cursor_col
            command = ticl.text[l_curdir: col]
            max_len = len(self.command_history) - 1
            chp = self.command_history_pos

            while max_len >= 0:
                if plus_minus == 1:
                    if self.command_history_pos > max_len - 1:
                        self.command_history_pos = max_len
                        return
                else:
                    if self.command_history_pos <= 0:
                        self.command_history_pos = max_len
                        return
                self.command_history_pos = self.command_history_pos\
                    + plus_minus
                cmd = self.command_history[self.command_history_pos]
                if cmd[:len(command)] == command:
                    ticl.text = ''.join((
                        self.rosSSH.prompt(), cmd))
                    move_cursor_to(col)
                    return
            self.command_history_pos = max_len + 1

        if ticl.focus:
            if len(l[4]) > 0 and l[4][0] == 'ctrl' and l[1] != 305:
                if (l[1]):
                    #ticl.text="^"+l[3]
                    self.rosSSH.sendSpecial(l[3])
                    #self.rosSSH.run(l[1], self.add_to_cache)

                return
            # if l[1] == 99 : #CTRL-C
            #     if len(l[4]) > 0 and l[4][0] == 'ctrl':
            #         print ("CC")
            #
            # if l[1] == 118:  # CTRL-V
            #     if len(l[4]) > 0 and l[4][0] == 'ctrl':
            #         print("CV")

            if l[1] == 273:
                # up arrow: display previous command
                if self.command_history_pos > 0:
                    self.command_history_pos -= 1
                    ticl.text = ''.join(
                        (self.rosSSH.prompt(),
                         self.command_history[self.command_history_pos]))
                return
            if l[1] == 274:
                # dn arrow: display next command
                if self.command_history_pos < len(self.command_history) - 1:
                    self.command_history_pos += 1
                    ticl.text = ''.join(
                        (self.rosSSH.prompt(),
                         self.command_history[self.command_history_pos]))
                else:
                    self.command_history_pos = len(self.command_history)
                    ticl.text = self.rosSSH.prompt()
                col = len(ticl.text)
                move_cursor_to(col)
                return
            if l[1] == 9:
                # tab: autocomplete
                def display_dir(cur_dir, starts_with=None):
                    # display contents of dir from cur_dir variable
                    try:
                        dir_list = os.listdir(cur_dir)
                    except OSError as err:
                        self.add_to_cache(''.join((err.strerror, '\n')))
                        return
                    if starts_with is not None:
                        len_starts_with = len(starts_with)
                    self.add_to_cache(
                            'contents of directory: ' + cur_dir + '\n')
                    txt = ''
                    no_of_matches = 0
                    for _file in dir_list:
                        if starts_with is not None:
                            if _file[:len_starts_with] == starts_with:
                                # if file matches starts with
                                txt = ''.join((txt, _file, '\t'))
                                no_of_matches += 1
                        else:
                            self.add_to_cache(''.join((_file, '\t')))
                    if no_of_matches == 1:
                        len_txt = len(txt) - 1
                        cmdl_text = ticl.text
                        len_cmdl = len(cmdl_text)
                        os_sep = os.sep \
                            if col == len_cmdl or (col < len_cmdl and
                                                   cmdl_text[col] !=
                                                   os.sep) else ''
                        ticl.text = ''.join(
                            (self.rosSSH.prompt(), text_before_cursor,
                             txt[len_starts_with:len_txt], os_sep,
                             cmdl_text[col:]))
                        move_cursor_to(col + (len_txt - len_starts_with) + 1)
                    elif no_of_matches > 1:
                        self.add_to_cache(txt)
                    self.add_to_cache('\n')

                # send back space to command line -remove the tab
                Clock.schedule_once(ticl.do_backspace, 0)
                l_curdir = len(self.rosSSH.prompt())
                move_cursor_to(l_curdir + len(ticl.text))
                ntext = os.path.expandvars(ticl.text)
                # store text before cursor for comparison
                col = ticl.cursor_col
                if ntext != ticl.text:
                    ticl.text = ntext
                    col = len(ntext)
                text_before_cursor = ticl.text[l_curdir: col]

                # if empty or space before: list cur dir
                if text_before_cursor == ''\
                   or ticl.text[col - 1] == ' ':
                    display_dir(self.cur_dir)
                # if in mid command:
                else:
                    # list commands in PATH starting with text before cursor
                    # split command into path till the seperator
                    cmd_start = text_before_cursor.rfind(' ')
                    cmd_start += 1
                    cur_dir = self.cur_dir\
                        if text_before_cursor[cmd_start] != os.sep\
                        else os.sep
                    os_sep = os.sep if cur_dir != os.sep else ''
                    cmd_end = text_before_cursor.rfind(os.sep)
                    len_txt_bef_cur = len(text_before_cursor) - 1
                    if cmd_end == len_txt_bef_cur:
                        # display files in path
                        if text_before_cursor[cmd_start] == os.sep:
                            cmd_start += 1
                        display_dir(''.join((cur_dir, os_sep,
                                    text_before_cursor[cmd_start:cmd_end])))
                    elif text_before_cursor[len_txt_bef_cur] == '.':
                        # if / already there return
                        if len(ticl.text) > col\
                           and ticl.text[col] == os.sep:
                            return
                        if text_before_cursor[len_txt_bef_cur - 1] == '.':
                            len_txt_bef_cur -= 1
                        if text_before_cursor[len_txt_bef_cur - 1]\
                           not in (' ', os.sep):
                            return
                        # insert at cursor os.sep: / or \
                        ticl.text = ''.join(
                                (self.rosSSH.prompt(),
                                 text_before_cursor, os_sep,
                                 ticl.text[col:]))
                    else:
                        if cmd_end < 0:
                            cmd_end = cmd_start
                        else:
                            cmd_end += 1
                        display_dir(''.join((
                                    cur_dir,
                                    os_sep,
                                    text_before_cursor[cmd_start:cmd_end])),
                                    text_before_cursor[cmd_end:])
                return
            if l[1] == 280:
                # pgup: search last command starting with...
                search_history('up')
                return
            if l[1] == 281:
                # pgdn: search next command starting with...
                search_history('dn')
                return
            if l[1] == 278:
                # Home: cursor should not go to the left of cur_dir
                col = len(self.rosSSH.prompt())
                move_cursor_to(col)
                if len(l[4]) > 0 and l[4][0] == 'shift':
                    ticl.selection_to = col
                return
            if l[1] == 276 or l[1] == 8:
                # left arrow/bkspc: cursor should not go left of cur_dir
                col = len(self.rosSSH.prompt())
                if ticl.cursor_col < col:
                    if l[1] == 8:
                        ticl.text = self.rosSSH.prompt()
                    move_cursor_to(col)
                return

    def on_focus(self, instance, value):
        '''Handle the focus on the command input
        '''
        if value:
            # focused
            if instance is self.txtinput_command_line:
                Window.unbind(on_key_down=self.on_key_down)
                Window.bind(on_key_down=self.on_key_down)
        else:
            # defocused
            Window.unbind(on_key_down=self.on_key_down)
            if self.txtinput_command_line_refocus:
                self.txtinput_command_line_refocus = False
                if self.txtinput_command_line.get_root_window():
                    self.txtinput_command_line.focus = True
                self.txtinput_command_line.scroll_x = 0
            if self.txtinput_run_command_refocus:
                self.txtinput_run_command_refocus = False
                instance.focus = True
                instance.scroll_x = 0
                instance.text = ''

    def add_to_cache(self, _string):
        if (_string!=None):
            self.textcache.append(_string)

    def kill_process(self, *args):
        '''Kill the current process
        '''
        if self.popen_obj:
            self.popen_obj.kill()

    def on_enter(self, *args):
        '''When the user press enter and wants to run a command
        '''
        self.unbind(on_subprocess_done=self.on_enter)
        # if there is a command running, it's necessary to stop it first
        if self.command_status == 'started':
            self.kill_process()
            # restart this call after killing the running process
            self.bind(on_subprocess_done=self.on_enter)
            return

        txtinput_command_line = self.txtinput_command_line
        add_to_cache = self.add_to_cache
        command_history = self.command_history

        def run_cmd(*args):
            '''Run the command
            '''
            if len(command) > 0:

                try:
                    # execute command
                    self.rosSSH.run(command)

                except (OSError, ValueError) as err:
                    add_to_cache(''.join(
                            (str(err),
                             ' < ', command, ' >\n')))
            self.command_status = 'closed'
            self.dispatch('on_subprocess_done')

            self.popen_obj = None
            txtinput_command_line.focus = True
            txtinput_command_line.text = self.rosSSH.prompt()
            #Clock.schedule_once(remove_command_interaction_widgets, 0)

        # append text to textcache
        #add_to_cache(self.txtinput_command_line.text + '\n')
        command = txtinput_command_line.text[len(self.rosSSH.prompt()):]

        if command == '':
            self.txtinput_command_line_refocus = True
            return

        # store command in command_history
        if self.command_history_pos > 0:
            self.command_history_pos = len(command_history)
            if command_history[self.command_history_pos - 1] != command:
                command_history.append(command)
        else:
            command_history.append(command)

        len_command_history = len(command_history)
        self.command_history_pos = len(command_history)

        # on reaching limit(cached_lines) pop first command
        if len_command_history >= self.cached_commands:
            self.command_history = command_history[1:]

        # replace $PATH with
        #command = os.path.expandvars(command)

        txtinput_command_line.text = self.rosSSH.prompt()

        # esecuzione in altro thread
        self.command_status = 'started'
        thread.start_new_thread(run_cmd, ())

    def on_subprocess_done(self, *args):
        '''Event handler for when a process was killed
        or just finished the execution.
        '''
        pass

    def on_command_list_done(self, *args):
        '''Event handler for when the whole command list was executed or killed
        '''
        pass

if __name__ == '__main__':
    runTouchApp(ROSConsole())


from .command_base import Command
from .pull_command import pull_url
from shrdluv import data

class AggregatorCommand(Command):
    def command_word(self):
        return "aggregator"

    def help_short(self):
        return "Manage aggregators"

    def arg_parser(self):
        parser = super().arg_parser()
        subparsers = parser.add_subparsers(required=True, dest="action")

        list_parser = subparsers.add_parser("list")

        add_parser = subparsers.add_parser("add")
        add_parser.add_argument("url")

        run_parser = subparsers.add_parser("run")
        return parser

    def run(self, args):
        try:
            parsed = self.arg_parser().parse_args(args[1:])
            if parsed.action == "list":
                list_aggregators()
            elif parsed.action == "add":
                add_aggregator(url=parsed.url)
            elif parsed.action == "run":
                run_aggregators()
            else:
                return {"status": "fail", "data": {"unknown action": parsed.action}}
            return {"status": "success", "data": {}}
        except Exception as e:
            print("error:", e)
            return {"status": "error", "data": {"error", e}}

def list_aggregators():
    try:
        for line in data.enumerate_aggregators():
            print(line)
    except FileNotFoundError:
        print("No aggregators found")

def add_aggregator(url):
    data.add_aggregator(url)

def run_aggregators():
    aggs = []
    try:
        for line in data.enumerate_aggregators():
            aggs.append(line)
    except FileNotFoundError:
        pass
    if len(aggs) == 0:
        print("No aggregators to run")
    else:
        for a in aggs:
            print("Pulling aggregator", a)
            result = pull_url(a)
            print(result)
            print()


"""
- Bu modül kameradan görüntü almak için kullanılır.
- Alınan görüntüyü gösterebilir veya göstermeyebilir.
- Görüntüler tekrar boyutlandırılabilir.
"""

import cv2

# Jetson Nano için gstreamer pipeline'ının oluşturulması
def gstreamer_pipeline(
        capture_width=1280,
        capture_height=720,
        display_width=1280,
        display_height=720,
        framerate=60,
        flip_method=0,
):
    return (
            "nvarguscamerasrc ! "
            "video/x-raw(memory:NVMM), "
            "width=(int)%d, height=(int)%d, "
            "format=(string)NV12, framerate=(fraction)%d/1 ! "
            "nvvidconv flip-method=%d ! "
            "video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
            "videoconvert ! "
            "video/x-raw, format=(string)BGR ! appsink"
            % (
                capture_width,
                capture_height,
                framerate,
                flip_method,
                display_width,
                display_height,
            )
    )

# Kameranın tanımlanması
cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0))

# Görüntü almak için metot
def getImg(display=False, size=[480, 240]):
    _, img = cap.read()
    img = cv2.resize(img, (size[0], size[1]))
    # display değişkeni 1 ise görüntüleri göster
    if display:
        cv2.imshow('IMG', img)
    return img

# Kod yalnız çalıştırılırsa görüntü al
if __name__ == '__main__':
    while True:
        img = getImg(True)


"""
usbProtocol.py

The following module has been created to manage the bluetooth interface between the control system and the connected devices

Michael Xynidis
Fluvio L Lobo Fenoglietto
09/01/2016

"""

# Import Libraries and/or Modules
import  os, serial, time
#from    timeStamp           import  *

"""
FUNCTIONS
"""

def createUSBPort( deviceName, portPrefix, portNumber, baudrate):
    """
    CREATE USB PORT
        input;
            deviceName (string) --name of the input device (for reference)
            portPrefix (string) --prefix based on the operating system of the control system/computer
                                = /dev/ttyACM --Linux
                                = COM --Windows
            portNumber (num)    --communication port number
            baudrate   (num)    --communication baudrate (bps)

        output;
            usbObject  (object) --serial object
    """
    #print fullStamp() + " createUSBPort()"
    usbObject = serial.Serial(
        port = portPrefix + str(portNumber),
        baudrate = baudrate)
    time.sleep(1)
    #usbConnectionCheck(usbObject,deviceName,portNumber,baudrate,attempts)
    usbObject.close()
    return usbObject