<commit_before>from tusk import __path__
import json, os

def interp_varname(varname):
	first = varname[0]
	second = varname[1]

	#T - RT in ATUS vars
	# TXAGE_EC

	if first == 't':
		return (varname[1:], 'ATUS-interview', 'summary-file')
	else:
		fl_types = {
			'G': 'CPS-geography',
			'H': 'CPS-household',
			'P': 'CPS-person',
			'T': 'ATUS-interview'
		}
		sl_types = {
			'U': 'unedited',
			'E': 'edited',
			'R': 'recoded',
			'T': 'topcoded'
		}
		return (varname[2:], fl_types[first], sl_types[second])

DICTIONARY = json.load(open(os.path.join(__path__[0], 'data-dictionary/data_dictionary.json'), 'rb'))
LEXICON = json.load(open(os.path.join(__path__[0], 'activity-lexicon/activity_lexicon.json'), 'rb'))

def interpret_code(variable, value):
	if variable not in DICTIONARY and variable in Variables:
		# use the first entry as the decoder
		variable = Variables[variable][0][0]
	try:
		metadata = DICTIONARY[variable]
		if metadata["validEntries"].has_key(str(value)):
			return str(metadata["validEntries"][str(value)])
		elif value == -1:
			return 'blank'
		elif value == -2:
			return 'don\'t know'
		elif value == -3:
			return 'refused'
	except KeyError:
		return str(value)

def interpret(d, k):
	return interpret_code(k, d[k])

# A SQLite UDF
def sql_decode(original_name, value):
	return interpret_code(original_name, value)

def sql_normalize_activity_code(acode):
	acode = str(acode)
	code_size = len(acode)
	return acode.rjust(code_size+1 if code_size%2 == 1 else code_size, '0')

def sql_decode_activity(activity_code):
	activity_code = sql_normalize_activity_code(activity_code)
	return LEXICON.get(activity_code, 'unknown activity code %s' % activity_code)

def sql_parsetime(tstring):
	'''19:51:00 => ATUS minute offset (starts at 4am). Does NOT account for overrun.'''
	hours, minutes, seconds = tstring.split(':')
	return (int(hours)-4)*60 + int(minutes)

def sql_time2minute(tstart, tstop, which):
	tstart = sql_parsetime(tstart)
	tstop = sql_parsetime(tstop)
	if tstop < tstart:
		tstop += 1440
	return [tstart, tstop][which]

# A SQLite aggregator
class SQL_collect:
    def __init__(self):
        self.collected = []
    def step(self, value):
        self.collected.append(value)
    def finalize(self):
        return json.dumps(self.collected)

def sql_family_income(hufaminc, hefaminc, year):
	if year > 2009:
		return hefaminc
	return hufaminc

# A map from alias to (variable, expression)
# If not a tuple, assumed that variable and expression are the same, for
# brevity (this is patched up below.)
Variables = {
	'age': 'TEAGE',
	'sex_code': 'TESEX',
	'race_code': 'PTDTRACE',
	'labor_status_code': 'TELFS',
	'region_code': 'GEREG',
	'housing_type_code': 'HEHOUSUT',
	'household_id': 'HRHHID',
	'fulldate': 'TUDIARYDATE',
	'month': 'TUMONTH',
	'year': 'TUYEAR',
	'cps_year': 'HRYEAR4',
	'cps_month': 'HRMONTH',
	'weekday_code': 'TUDIARYDAY',
	'household_members': 'HRNUMHOU',
	'weekly_earnings': (['TRERNWA'], '(TRERNWA/100.0)'),
	'weekly_overtime_earnings': (['TEERN'], '(TEERN/100.0)'),
	'friend_time': 'TRTFRIEND',
	'family_time': 'TRTFAMILY',
	'caseid': 'TUCASEID',
	'lineno': 'TULINENO',
	'relation_code': 'TERRP',
	'family_income_code': (
		['HUFAMINC', 'HEFAMINC', 'HRYEAR4'],
		'family_income(HUFAMINC, HEFAMINC, HRYEAR4)'),
	# note that HEFAMINC is interpreted like HUFAMINC because the
	# codes are the same and only listed in full for HUFAMINC
	'family_income': (
		['HUFAMINC', 'HEFAMINC', 'HRYEAR4'],
		"decode('HUFAMINC', family_income(HUFAMINC, HEFAMINC, HRYEAR4))"),
	'education_code': 'PEEDUCA',
	'activity_location_code': 'TEWHERE',
	'duration': 'TUACTDUR',
	'activity_number': 'TUACTIVITY_N',
	'start_time': 'TUSTARTTIM',
	'stop_time': 'TUSTOPTIME',
	'start_minute': (
		['TUSTARTTIM', 'TUSTOPTIME'],
		'time2minute(TUSTARTTIM, TUSTOPTIME, 0)'),
	'stop_minute': (
		['TUSTARTTIM', 'TUSTOPTIME'],
		'time2minute(TUSTARTTIM, TUSTOPTIME, 1)'),

	# Selected meta-summaries
	'minutes_working': 't050101+t050102',

	# Selected summary time variables
	'minutes_sleeping': 't010101',
	'minutes_eating': 't110101',
	'minutes_TV': 't120303',
	'minutes_washing_and_dressing': 't010201',
	'minutes_cooking': 't020201',
	'minutes_socializing': 't120101',
	'minutes_main_job': 't050101',
	'minutes_travel_for_shopping': 't180782',
	'minutes_commuting': 't180501',
	'minutes_cleaning': 't020101',
	'minutes_reading': 't120312',
	'minutes_travel_for_food': 't181101',
	'minutes_shopping': 't070104',
	'minutes_cleaning_kitchen': 't020203',
	'minutes_travel_for_socializing': 't181201',
	'minutes_relaxing': 't120301',
	'minutes_childcare': 't030101',
	'minutes_laundry': 't020102',
	'minutes_grocery_shopping': 't070101',
	'minutes_going_to_grocery_store': 't180701',
	'minutes_organizing': 't020902',
	'minutes_petcare': 't020681',
	'minutes_traveling_for_children': 't180381',
	'minutes_lawncare': 't020501',
	'minutes_computer_use': 't120308',
	'minutes_pickup_children': 't030112',

	# TODO: this is only the right name in the multi-year files
	'weight': 'TUFNWGTP',

	# activity codes are special cased
	'activity_code': (['TRCODEP'], 'normalize_activity_code(TRCODEP)'),
	'activity_tier1_code': (['TRTIER1P'], 'normalize_activity_code(TRTIER1P)'),
	'activity_tier2_code': (['TRTIER2P'], 'normalize_activity_code(TRTIER2P)'),
	'activity': (['TRCODEP'], 'decode_activity(TRCODEP)'),
	'activity_tier1': (['TRTIER1P'], 'decode_activity(TRTIER1P)'),
	'activity_tier2': (['TRTIER2P'], 'decode_activity(TRTIER2P)'),

	# occupation
}

# If aliases go to a single string, assume that it's the variable
# name and the expression.
for aliased in Variables:
	if not isinstance(Variables[aliased], tuple):
		Variables[aliased] = ([Variables[aliased]], Variables[aliased])

# Automatically add decoded versions of _code variables
for aliased, (inputs, expr) in Variables.items():
	if aliased.endswith('_code'):
		if aliased[:-len('_code')] in Variables:
			continue
		Variables[aliased[:-len('_code')]] = (inputs, "decode('%s', %s)" % (inputs[0], expr))

def rewrite(original_name):
	if original_name in Variables:
		return Variables[original_name][1]
	return original_name

# n.b. this will have to change from a 1-1 mapping to be robust to different
# data sources. Will have to look at what tables are available.
Tables = {
	'activities': 'atusact_0312',
	'summary': 'atussum_0312',
	'respondents': 'atusresp_0312',
	'roster': 'atusrost_0312',
	'cps': 'atuscps_0312'
}<commit_msg>realized a bug in stop-time wraparound<commit_after>from tusk import __path__
import json, os

def interp_varname(varname):
	first = varname[0]
	second = varname[1]

	#T - RT in ATUS vars
	# TXAGE_EC

	if first == 't':
		return (varname[1:], 'ATUS-interview', 'summary-file')
	else:
		fl_types = {
			'G': 'CPS-geography',
			'H': 'CPS-household',
			'P': 'CPS-person',
			'T': 'ATUS-interview'
		}
		sl_types = {
			'U': 'unedited',
			'E': 'edited',
			'R': 'recoded',
			'T': 'topcoded'
		}
		return (varname[2:], fl_types[first], sl_types[second])

DICTIONARY = json.load(open(os.path.join(__path__[0], 'data-dictionary/data_dictionary.json'), 'rb'))
LEXICON = json.load(open(os.path.join(__path__[0], 'activity-lexicon/activity_lexicon.json'), 'rb'))

def interpret_code(variable, value):
	if variable not in DICTIONARY and variable in Variables:
		# use the first entry as the decoder
		variable = Variables[variable][0][0]
	try:
		metadata = DICTIONARY[variable]
		if metadata["validEntries"].has_key(str(value)):
			return str(metadata["validEntries"][str(value)])
		elif value == -1:
			return 'blank'
		elif value == -2:
			return 'don\'t know'
		elif value == -3:
			return 'refused'
	except KeyError:
		return str(value)

def interpret(d, k):
	return interpret_code(k, d[k])

# A SQLite UDF
def sql_decode(original_name, value):
	return interpret_code(original_name, value)

def sql_normalize_activity_code(acode):
	acode = str(acode)
	code_size = len(acode)
	return acode.rjust(code_size+1 if code_size%2 == 1 else code_size, '0')

def sql_decode_activity(activity_code):
	activity_code = sql_normalize_activity_code(activity_code)
	return LEXICON.get(activity_code, 'unknown activity code %s' % activity_code)

def sql_parsetime(tstring):
	'''19:51:00 => ATUS minute offset (starts at 4am). Does NOT account for overrun.'''
	hours, minutes, seconds = tstring.split(':')
	return (int(hours)-4)*60 + int(minutes)

def sql_time2minute(tstart, tstop, which):
	tstart = sql_parsetime(tstart)
	tstop = sql_parsetime(tstop)
	if tstop < 0:
		tstop += 1440
	if tstart < 0:
		tstart += 1440
	return [tstart, tstop][which]

# A SQLite aggregator
class SQL_collect:
    def __init__(self):
        self.collected = []
    def step(self, value):
        self.collected.append(value)
    def finalize(self):
        return json.dumps(self.collected)

def sql_family_income(hufaminc, hefaminc, year):
	if year > 2009:
		return hefaminc
	return hufaminc

# A map from alias to (variable, expression)
# If not a tuple, assumed that variable and expression are the same, for
# brevity (this is patched up below.)
Variables = {
	'age': 'TEAGE',
	'sex_code': 'TESEX',
	'race_code': 'PTDTRACE',
	'labor_status_code': 'TELFS',
	'region_code': 'GEREG',
	'housing_type_code': 'HEHOUSUT',
	'household_id': 'HRHHID',
	'fulldate': 'TUDIARYDATE',
	'month': 'TUMONTH',
	'year': 'TUYEAR',
	'cps_year': 'HRYEAR4',
	'cps_month': 'HRMONTH',
	'weekday_code': 'TUDIARYDAY',
	'household_members': 'HRNUMHOU',
	'weekly_earnings': (['TRERNWA'], '(TRERNWA/100.0)'),
	'weekly_overtime_earnings': (['TEERN'], '(TEERN/100.0)'),
	'friend_time': 'TRTFRIEND',
	'family_time': 'TRTFAMILY',
	'caseid': 'TUCASEID',
	'lineno': 'TULINENO',
	'relation_code': 'TERRP',
	'family_income_code': (
		['HUFAMINC', 'HEFAMINC', 'HRYEAR4'],
		'family_income(HUFAMINC, HEFAMINC, HRYEAR4)'),
	# note that HEFAMINC is interpreted like HUFAMINC because the
	# codes are the same and only listed in full for HUFAMINC
	'family_income': (
		['HUFAMINC', 'HEFAMINC', 'HRYEAR4'],
		"decode('HUFAMINC', family_income(HUFAMINC, HEFAMINC, HRYEAR4))"),
	'education_code': 'PEEDUCA',
	'activity_location_code': 'TEWHERE',
	'duration': 'TUACTDUR',
	'activity_number': 'TUACTIVITY_N',
	'start_time': 'TUSTARTTIM',
	'stop_time': 'TUSTOPTIME',
	'start_minute': (
		['TUSTARTTIM', 'TUSTOPTIME'],
		'time2minute(TUSTARTTIM, TUSTOPTIME, 0)'),
	'stop_minute': (
		['TUSTARTTIM', 'TUSTOPTIME'],
		'time2minute(TUSTARTTIM, TUSTOPTIME, 1)'),

	# Selected meta-summaries
	'minutes_working': 't050101+t050102',

	# Selected summary time variables
	'minutes_sleeping': 't010101',
	'minutes_eating': 't110101',
	'minutes_TV': 't120303',
	'minutes_washing_and_dressing': 't010201',
	'minutes_cooking': 't020201',
	'minutes_socializing': 't120101',
	'minutes_main_job': 't050101',
	'minutes_travel_for_shopping': 't180782',
	'minutes_commuting': 't180501',
	'minutes_cleaning': 't020101',
	'minutes_reading': 't120312',
	'minutes_travel_for_food': 't181101',
	'minutes_shopping': 't070104',
	'minutes_cleaning_kitchen': 't020203',
	'minutes_travel_for_socializing': 't181201',
	'minutes_relaxing': 't120301',
	'minutes_childcare': 't030101',
	'minutes_laundry': 't020102',
	'minutes_grocery_shopping': 't070101',
	'minutes_going_to_grocery_store': 't180701',
	'minutes_organizing': 't020902',
	'minutes_petcare': 't020681',
	'minutes_traveling_for_children': 't180381',
	'minutes_lawncare': 't020501',
	'minutes_computer_use': 't120308',
	'minutes_pickup_children': 't030112',

	# TODO: this is only the right name in the multi-year files
	'weight': 'TUFNWGTP',

	# activity codes are special cased
	'activity_code': (['TRCODEP'], 'normalize_activity_code(TRCODEP)'),
	'activity_tier1_code': (['TRTIER1P'], 'normalize_activity_code(TRTIER1P)'),
	'activity_tier2_code': (['TRTIER2P'], 'normalize_activity_code(TRTIER2P)'),
	'activity': (['TRCODEP'], 'decode_activity(TRCODEP)'),
	'activity_tier1': (['TRTIER1P'], 'decode_activity(TRTIER1P)'),
	'activity_tier2': (['TRTIER2P'], 'decode_activity(TRTIER2P)'),

	# occupation
}

# If aliases go to a single string, assume that it's the variable
# name and the expression.
for aliased in Variables:
	if not isinstance(Variables[aliased], tuple):
		Variables[aliased] = ([Variables[aliased]], Variables[aliased])

# Automatically add decoded versions of _code variables
for aliased, (inputs, expr) in Variables.items():
	if aliased.endswith('_code'):
		if aliased[:-len('_code')] in Variables:
			continue
		Variables[aliased[:-len('_code')]] = (inputs, "decode('%s', %s)" % (inputs[0], expr))

def rewrite(original_name):
	if original_name in Variables:
		return Variables[original_name][1]
	return original_name

# n.b. this will have to change from a 1-1 mapping to be robust to different
# data sources. Will have to look at what tables are available.
Tables = {
	'activities': 'atusact_0312',
	'summary': 'atussum_0312',
	'respondents': 'atusresp_0312',
	'roster': 'atusrost_0312',
	'cps': 'atuscps_0312'
}<|endoftext|>


<commit_before>"""RingCube class definition"""
import logging
import os
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
from astropy import units as u
from skimage import exposure

from pysis import CubeFile

from ._utils import which_epi_janus_resonance
from .io import PathManager
from .meta import get_all_resonances, get_meta_df
from .opusapi import MetaData

try:
    # prettier plots with seaborn
    import seaborn as sns
    _SEABORN_INSTALLED = True
except ImportError:
    _SEABORN_INSTALLED = False
else:
    sns.set_context('notebook')
    sns.set_style('white')

logger = logging.getLogger(__name__)

resonances = get_all_resonances()
meta_df = get_meta_df()

def calc_4_3(width):
    """Calculate 4:3 ratio for figures.

    so that they import nicely in prezzies.

    Parameters
    ----------
    width : int, float
        Width of plotting window
    """
    return (width, 3 * width / 4)

class RingCube(CubeFile):

    def __init__(self, fname, plot_limits=(1, 99), **kwargs):
        p = Path(fname)
        self.pm = PathManager(fname)
        if not p.is_absolute():
            # assuming it's an image_id and user wants default action:
            if self.pm.cubepath.exists():
                fname = str(self.pm.cubepath)
            else:
                fname = str(self.pm.undestriped)
        # if fname is absolute path, open exactly that one:
        super().__init__(str(fname), **kwargs)
        try:
            self.meta = meta_df.loc[self.pm.img_id]
        except KeyError:
            self.meta = None
        self.resonance_axis = None
        self.pmin = plot_limits[0]
        self.pmax = plot_limits[1]

    def get_opus_meta_data(self):
        print("Getting metadata from the online OPUS database.")
        self.opusmeta = MetaData(self.pm._id)
        print("Done.")
        return self.opusmeta

    @property
    def meta_pixres(self):
        if self.meta is not None:
            return int(self.meta.mean_radial_res * 1000)
        else:
            return np.nan

    @property
    def meta_litstatus(self):
        if self.meta is not None:
            return self.meta.is_lit
        else:
            return np.nan

    @property
    def mapping_label(self):
        return self.label['IsisCube']['Mapping']

    @property
    def minrad(self):
        "float: MinimumRingRadius in Mm."
        return self.mapping_label['MinimumRingRadius'] / 1e6 * u.Mm

    @property
    def minrad_km(self):
        return self.minrad.to(u.km)

    @property
    def midrad(self):
        return (self.minrad + self.maxrad) / 2

    @property
    def maxrad(self):
        "float: MaxiumRingRadius in Mm."
        return self.mapping_label['MaximumRingRadius'] / 1e6 * u.Mm

    @property
    def maxrad_km(self):
        return self.maxrad.to(u.km)

    @property
    def minlon(self):
        return self.mapping_label['MinimumRingLongitude'] * u.degree

    @property
    def maxlon(self):
        return self.mapping_label['MaximumRingLongitude'] * u.degree

    @property
    def img(self):
        "apply_numpy_special is inherited from CubeFile."
        return self.apply_numpy_specials()[0]

    @property
    def extent(self):
        return [i.value for i in [self.minlon, self.maxlon, self.minrad, self.maxrad]]

    @property
    def resolution_val(self):
        return self.mapping_label['PixelResolution'].value * u.m / u.pixel

    @property
    def plottitle(self):
        return Path(self.filename).stem.split('.')[0]

    @property
    def plotfname(self):
        return self.filename.split('.')[0] + '.png'

    @property
    def plot_limits(self):
        data = self.img
        return np.percentile(data[~np.isnan(data)], (self.pmin, self.pmax))

    def imshow(self, data=None, plow=1, phigh=99, save=False, ax=None,
               interpolation='none', extra_title=None, show_resonances='some',
               set_extent=True, equalized=False, rmin=None, rmax=None, **kwargs):
        """Powerful default display.

        show_resonances can be True, a list, 'all', or 'some'
        """
        if data is None:
            data = self.img
        if self.resonance_axis is not None:
            logger.debug('removing resonance_axis')
            self.resonance_axis.remove()
        if equalized:
            data = exposure.equalize_hist(np.nan_to_num(data))
        extent_val = self.extent if set_extent else None
        min_, max_ = np.percentile(data[~np.isnan(data)], (plow, phigh))
        self.min_ = min_
        self.max_ = max_
        if ax is None:
            if not _SEABORN_INSTALLED:
                fig, ax = plt.subplots(figsize=calc_4_3(8))
            else:
                fig, ax = plt.subplots()
        else:
            fig = ax.get_figure()
        im = ax.imshow(data, extent=extent_val, cmap='gray', vmin=min_,
                       vmax=max_, interpolation=interpolation, origin='lower',
                       aspect='auto', **kwargs)
        if any([rmin is not None, rmax is not None]):
            ax.set_ylim(rmin, rmax)
        self.mpl_im = im
        ax.set_xlabel('Longitude [deg]')
        ax.set_ylabel('Radius [Mm]')
        ax.ticklabel_format(useOffset=False)
        # ax.grid('on')
        title = self.plot_title
        if extra_title:
            title += ', ' + extra_title
        ax.set_title(title, fontsize=12)
        if show_resonances:
            self.set_resonance_axis(ax, show_resonances, rmin, rmax)
        fig.tight_layout()
        if save:
            savename = self.plotfname
            if extra_title:
                savename = savename[:-4] + '_' + extra_title + '.png'
            fig.savefig(savename, dpi=150)

    @property
    def plot_title(self):
        title = ("{}, Res: {} m/pix, {}, LIT: {}".format(
            self.plottitle,
            self.meta_pixres,
            self.imagetime.date().isoformat(),
            self.meta_litstatus))
        return title

    @property
    def inside_resonances(self):
        lower_filter = (resonances['radius'] > (self.minrad_km))
        higher_filter = (resonances['radius'] < (self.maxrad_km))
        return resonances[lower_filter & higher_filter]

    @property
    def janus_swap_phase(self):
        return which_epi_janus_resonance('janus', self.imagetime)

    def set_resonance_axis(self, ax, show_resonances, rmin=None, rmax=None):
        if show_resonances == 'some':
            show_resonances = ['janus', 'prometheus', 'epimetheus', 'atlas']
        elif show_resonances == 'all':
            show_resonances = self.inside_resonances.moon.unique()
            show_resonances = [
                i for i in show_resonances if i[:-1] not in ['janus', 'epimetheus']]
            show_resonances.extend(['janus', 'epimetheus'])
        # check for janus/epimetheus year and copy over items
        # into final moons list
        moons = []
        for moon in show_resonances:
            if moon in ['janus', 'epimetheus']:
                moons.append(which_epi_janus_resonance(moon,
                                                       self.imagetime))
            else:
                moons.append(moon)
        try:
            moonfilter = (self.inside_resonances.moon.isin(moons))
        except TypeError:
            # if show_resonances not a list, do nothing, == 'all'
            moonfilter = True
        newticks = self.inside_resonances[moonfilter]
        ax2 = ax.twinx()
        ax2.set_ybound(self.minrad.value, self.maxrad.value)
        ax2.ticklabel_format(useOffset=False)
        # i plot in Mm, hence the division by 1000 here.
        ax2.set_yticks(newticks.radius / 1000)
        ax2.set_yticklabels(newticks.name)
        if any([rmin is not None, rmax is not None]):
            ax2.set_ylim(rmin, rmax)
        self.resonance_axis = ax2

    @property
    def mean_profile(self):
        return np.nanmean(self.img, axis=1)

    @property
    def median_profile(self):
        return np.nanmedian(self.img, axis=1)

    @property
    def density_wave_subtracted(self):
        subtracted = self.img - self.mean_profile[:, np.newaxis]
        return subtracted

    @property
    def density_wave_median_subtracted(self):
        subtracted = self.img - self.median_profile[:, np.newaxis]
        return subtracted

    def imshow_subtracted(self, median=False, **kwargs):
        if median:
            self.imshow(data=self.density_wave_median_subtracted, **kwargs)
        else:
            self.imshow(data=self.density_wave_subtracted, **kwargs)

    @property
    def imgmin(self):
        return np.nanmin(self.img)

    @property
    def imgmax(self):
        return np.nanmax(self.img)

    @property
    def imgminmax(self):
        return self.imgmin, self.imgmax

    @property
    def inner_zoom(self, data=None):
        if data is None:
            data = self.img
        shape = self.img.shape
        x1 = shape[0] // 4
        x2 = 3 * shape[0] // 4
        y1 = shape[1] // 4
        y2 = 3 * shape[1] // 4
        return data[x1:x2, y1:y2]

    @property
    def imagetime(self):
        return self.label['IsisCube']['Instrument']['ImageTime']
<commit_msg>filter warnings and clean-up clim calculations<commit_after>"""RingCube class definition"""
import logging
import os
import warnings
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
from astropy import units as u
from skimage import exposure

from pysis import CubeFile

from ._utils import which_epi_janus_resonance
from .io import PathManager
from .meta import get_all_resonances, get_meta_df
from .opusapi import MetaData

try:
    # prettier plots with seaborn
    import seaborn as sns
    _SEABORN_INSTALLED = True
except ImportError:
    _SEABORN_INSTALLED = False
else:
    sns.set_context('notebook')
    sns.set_style('white')

logger = logging.getLogger(__name__)

resonances = get_all_resonances()
meta_df = get_meta_df()

def calc_4_3(width):
    """Calculate 4:3 ratio for figures.

    so that they import nicely in prezzies.

    Parameters
    ----------
    width : int, float
        Width of plotting window
    """
    return (width, 3 * width / 4)

class RingCube(CubeFile):

    def __init__(self, fname, plot_limits=(1, 99), destriped=True, **kwargs):
        p = Path(fname)
        self.pm = PathManager(fname)
        if not p.is_absolute():
            # assuming it's an image_id and user wants default action:
            if self.pm.cubepath.exists() and destriped is True:
                fname = str(self.pm.cubepath)
            else:
                fname = str(self.pm.undestriped)
        # if fname is absolute path, open exactly that one:
        super().__init__(str(fname), **kwargs)
        try:
            self.meta = meta_df.loc[self.pm.img_id]
        except KeyError:
            self.meta = None
        self.resonance_axis = None
        self.pmin = plot_limits[0]
        self.pmax = plot_limits[1]
        self._plot_limits = self.calc_clim(self.img)

    def get_opus_meta_data(self):
        print("Getting metadata from the online OPUS database.")
        self.opusmeta = MetaData(self.pm._id)
        print("Done.")
        return self.opusmeta

    @property
    def meta_pixres(self):
        if self.meta is not None:
            return int(self.meta.mean_radial_res * 1000)
        else:
            return np.nan

    @property
    def meta_litstatus(self):
        if self.meta is not None:
            return self.meta.is_lit
        else:
            return np.nan

    @property
    def mapping_label(self):
        return self.label['IsisCube']['Mapping']

    @property
    def minrad(self):
        "float: MinimumRingRadius in Mm."
        return self.mapping_label['MinimumRingRadius'] / 1e6 * u.Mm

    @property
    def minrad_km(self):
        return self.minrad.to(u.km)

    @property
    def midrad(self):
        return (self.minrad + self.maxrad) / 2

    @property
    def maxrad(self):
        "float: MaxiumRingRadius in Mm."
        return self.mapping_label['MaximumRingRadius'] / 1e6 * u.Mm

    @property
    def maxrad_km(self):
        return self.maxrad.to(u.km)

    @property
    def minlon(self):
        return self.mapping_label['MinimumRingLongitude'] * u.degree

    @property
    def maxlon(self):
        return self.mapping_label['MaximumRingLongitude'] * u.degree

    @property
    def img(self):
        "apply_numpy_special is inherited from CubeFile."
        return self.apply_numpy_specials()[0]

    @property
    def extent(self):
        return [i.value for i in [self.minlon, self.maxlon, self.minrad, self.maxrad]]

    @property
    def resolution_val(self):
        return self.mapping_label['PixelResolution'].value * u.m / u.pixel

    @property
    def plottitle(self):
        return Path(self.filename).stem.split('.')[0]

    @property
    def plotfname(self):
        return self.filename.split('.')[0] + '.png'

    def calc_clim(self, data):
        return np.percentile(data[~np.isnan(data)], (self.pmin, self.pmax))

    @property
    def plot_limits(self):
        return self.calc_clim(self.plotted_data)

    def imshow(self, data=None, save=False, ax=None,
               interpolation='none', extra_title=None, show_resonances='some',
               set_extent=True, equalized=False, rmin=None, rmax=None, **kwargs):
        """Powerful default display.

        show_resonances can be True, a list, 'all', or 'some'
        """
        if data is None:
            data = self.img
        self.plotted_data = data
        if self.resonance_axis is not None:
            logger.debug('removing resonance_axis')
            self.resonance_axis.remove()
        if equalized:
            data = exposure.equalize_hist(np.nan_to_num(data))
        extent_val = self.extent if set_extent else None
        min_, max_ = self.plot_limits
        self.min_ = min_
        self.max_ = max_
        if ax is None:
            if not _SEABORN_INSTALLED:
                fig, ax = plt.subplots(figsize=calc_4_3(8))
            else:
                fig, ax = plt.subplots()
        else:
            fig = ax.get_figure()
        im = ax.imshow(data, extent=extent_val, cmap='gray', vmin=min_,
                       vmax=max_, interpolation=interpolation, origin='lower',
                       aspect='auto', **kwargs)
        if any([rmin is not None, rmax is not None]):
            ax.set_ylim(rmin, rmax)
        self.mpl_im = im
        ax.set_xlabel('Longitude [deg]')
        ax.set_ylabel('Radius [Mm]')
        ax.ticklabel_format(useOffset=False)
        # ax.grid('on')
        title = self.plot_title
        if extra_title:
            title += ', ' + extra_title
        ax.set_title(title, fontsize=12)
        if show_resonances:
            self.set_resonance_axis(ax, show_resonances, rmin, rmax)
        fig.tight_layout()
        if save:
            savename = self.plotfname
            if extra_title:
                savename = savename[:-4] + '_' + extra_title + '.png'
            fig.savefig(savename, dpi=150)
        self.im = im
        return im

    @property
    def plot_title(self):
        title = ("{}, Res: {} m/pix, {}, LIT: {}".format(
            self.plottitle,
            self.meta_pixres,
            self.imagetime.date().isoformat(),
            self.meta_litstatus))
        return title

    @property
    def inside_resonances(self):
        lower_filter = (resonances['radius'] > (self.minrad_km))
        higher_filter = (resonances['radius'] < (self.maxrad_km))
        return resonances[lower_filter & higher_filter]

    @property
    def janus_swap_phase(self):
        return which_epi_janus_resonance('janus', self.imagetime)

    def set_resonance_axis(self, ax, show_resonances, rmin=None, rmax=None):
        if show_resonances == 'some':
            show_resonances = ['janus', 'prometheus', 'epimetheus', 'atlas']
        elif show_resonances == 'all':
            show_resonances = self.inside_resonances.moon.unique()
            show_resonances = [
                i for i in show_resonances if i[:-1] not in ['janus', 'epimetheus']]
            show_resonances.extend(['janus', 'epimetheus'])
        # check for janus/epimetheus year and copy over items
        # into final moons list
        moons = []
        for moon in show_resonances:
            if moon in ['janus', 'epimetheus']:
                moons.append(which_epi_janus_resonance(moon,
                                                       self.imagetime))
            else:
                moons.append(moon)
        try:
            moonfilter = (self.inside_resonances.moon.isin(moons))
        except TypeError:
            # if show_resonances not a list, do nothing, == 'all'
            moonfilter = True
        newticks = self.inside_resonances[moonfilter]
        ax2 = ax.twinx()
        ax2.set_ybound(self.minrad.value, self.maxrad.value)
        ax2.ticklabel_format(useOffset=False)
        # i plot in Mm, hence the division by 1000 here.
        ax2.set_yticks(newticks.radius / 1000)
        ax2.set_yticklabels(newticks.name)
        if any([rmin is not None, rmax is not None]):
            ax2.set_ylim(rmin, rmax)
        self.resonance_axis = ax2

    @property
    def mean_profile(self):
        return np.nanmean(self.img, axis=1)

    @property
    def median_profile(self):
        return np.nanmedian(self.img, axis=1)

    @property
    def density_wave_subtracted(self):
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', r'All-NaN slice encountered')
            subtracted = self.img - self.mean_profile[:, np.newaxis]
        return subtracted

    @property
    def density_wave_median_subtracted(self):
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', r'All-NaN slice encountered')
            subtracted = self.img - self.median_profile[:, np.newaxis]
        return subtracted

    def imshow_subtracted(self, median=False, **kwargs):
        if median:
            self.imshow(data=self.density_wave_median_subtracted, **kwargs)
        else:
            self.imshow(data=self.density_wave_subtracted, **kwargs)

    @property
    def imgmin(self):
        return np.nanmin(self.img)

    @property
    def imgmax(self):
        return np.nanmax(self.img)

    @property
    def imgminmax(self):
        return self.imgmin, self.imgmax

    @property
    def inner_zoom(self, data=None):
        if data is None:
            data = self.img
        shape = self.img.shape
        x1 = shape[0] // 4
        x2 = 3 * shape[0] // 4
        y1 = shape[1] // 4
        y2 = 3 * shape[1] // 4
        return data[x1:x2, y1:y2]

    @property
    def imagetime(self):
        return self.label['IsisCube']['Instrument']['ImageTime']
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import re
from irc import events
import irc.client
import time
import hashlib
import logging
import os
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

_rfc_1459_command_regexp = re.compile("^(:(?P<prefix>[^ ]+) +)?" +
    "(?P<command>[^ ]+)( *(?P<argument> .+))?")

engine = create_engine("sqlite:///db/cobot.db")
Base = declarative_base()

from .tables import User, UserPriv

Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

class pyCoBot:
    def __init__(self, server, client, conf):
        self.session = Session
        self.handlers = []
        self.server = client.server()
        self.server.connect(server, conf['port'], conf['nick'],
            username=conf['nick'], ircname="pyCoBot")
        self.server.add_global_handler("all_raw_messages", self.allraw)

        self.modules = {}
        self.modinfo = {}
        self.commandhandlers = {}
        self.conf = conf
        self.authd = {}  # Usuarios autenticados..
        for i, val in enumerate(conf['modules']):
            self.loadmod(conf['modules'][i], conf['server'])

    def allraw(self, con, event):
        ev = self.processline(event.arguments[0], con)
        # OPTIMIZE: hacer esto es feo, cambiarlo por algo mejor!
        for i, val in enumerate(self.handlers):
            if ev.type == self.handlers[i]['numeric']:
                m = getattr(self.handlers[i]['mod'], self.handlers[i]['func'])
                m(self.server)

        if ev.type == "privmsg" or ev.type == "pubmsg":
            #p = re.compile("(?:" + re.escape(self.conf['prefix']) + "|" +
            #    re.escape(self.conf['nick']) + "[:, ]? )(.*)(?!\w+)")
            # Buscamos por el prefijo..
            p1 = re.compile(re.escape(self.conf['prefix']) +
                "(\S{1,52})[ ]?(.*)")
            m1 = p1.search(ev.arguments[0])

            # Buscamos por el nick como prefijo..
            p2 = re.compile(re.escape(self.conf['nick']) +
                "[:, ]? (\S{1,52})[ ]?(.*)")
            m2 = p2.search(ev.arguments[0])
            if not m1 is None:
                del ev.splitd[0]
                com = m1.group(1)
            elif not m2 is None:
                del ev.splitd[0]
                del ev.splitd[0]
                com = m2.group(1)

            if not m1 is None or not m2 is None:
                if com == "help" or com == "ayuda":
                    r = False
                    if not len(ev.splitd) > 0:
                        comlist = "help auth "
                        for i in list(self.commandhandlers.keys()):
                            comlist = comlist + i + " "

                        con.privmsg(ev.target, "\2pyCoBot alpha\2. Comandos " +
                        "empezar con \2" + self.conf["prefix"] + "\2. " +
                        "Escriba " + self.conf["prefix"] + "help \2<comando>" +
                        "\2 para mas información sobre un comando")

                        con.privmsg(ev.target, "Comandos: " + comlist)
                    else:
                        if ev.splitd[0] == "help":  # Harcoded help :P
                            r = "Muestra la ayuda de un comando, o, si no " + \
                             " tiene parametros, la lista de comandos." + \
                             " Sintaxis: help [comando]"
                        elif ev.splitd[0] == "auth":
                            r = "Identifica a un usuario registrado con el " + \
                             " Bot. Sintaxis" + \
                             " Sintaxis: help [comando]"
                        else:
                            try:
                                r = self.commandhandlers[ev.splitd[0]]['chelp']
                            except KeyError:
                                pass
                        if not r:
                            con.privmsg(ev.target, "No se ha encontrado el " +
                             "comando")
                        else:
                            con.privmsg(ev.target, "Ayuda de \2" + ev.splitd[0]
                             + "\2: " + r)
                elif com == "auth" and ev.type == "privmsg":
                    self.auth(ev)
                elif com == "update":
                    pass  # TODO: actualizador!!
                else:
                    try:
                        self.commandhandlers[com]
                    except KeyError:
                        return 0
                    # Verificación de autenticación
                    if not self.commandhandlers[com]['cpriv'] == -1:
                        try:
                            uid = self.authd[ev.source]
                            continua = False
                            session = self.session()
                            for row in session.query(UserPriv) \
                            .filter(UserPriv.uid == uid):
                                # priv >= cpriv && privsec == "*"
                                if row.sec == "*" and row.priv >= self \
                                 .commandhandlers[com]['cpriv']:
                                    continua = True
                                # priv >= cpriv && privsec == cprivsec
                                elif row.sec == self.\
                                 commandhandlers[com]['cprivsect'] \
                                 and row.priv >= self \
                                 .commandhandlers[com]['cpriv']:
                                    continua = True
                        except KeyError:
                            self.server.privmsg(ev.target,
                            "\00304Error\003: No autorizado")
                            return 1
                        if not continua is True:
                            self.server.privmsg(ev.target,
                            "\00304Error\003: No autorizado")
                            return 1
                    getattr(self.commandhandlers[com]['mod'],
                      self.commandhandlers[com]['func'])(self, self.server, ev)

        if ev.type == "welcome":
            for i, val in enumerate(self.conf['autojoin']):
                con.join(self.conf['autojoin'][i])

    # Procesa una linea y retorna un Event
    def processline(self, line, c):
        prefix = None
        command = None
        arguments = None

        m = _rfc_1459_command_regexp.match(line)
        if m.group("prefix"):
            prefix = m.group("prefix")

        if m.group("command"):
            command = m.group("command").lower()

        if m.group("argument"):
            a = m.group("argument").split(" :", 1)
            arguments = a[0].split()
            if len(a) == 2:
                arguments.append(a[1])

        # Translate numerics into more readable strings.
        command = events.numeric.get(command, command)

        if command in ["privmsg", "notice"]:
            target, message = arguments[0], arguments[1]
            messages = irc.client._ctcp_dequote(message)

            if command == "privmsg":
                if irc.client.is_channel(target):
                    command = "pubmsg"
            else:
                if irc.client.is_channel(target):
                    command = "pubnotice"
                else:
                    command = "privnotice"

            for m in messages:
                if isinstance(m, tuple):
                    if command in ["privmsg", "pubmsg"]:
                        command = "ctcp"
                    else:
                        command = "ctcpreply"

                    if command == "ctcp" and m[0] == "ACTION":
                        return irc.client.Event("action", prefix, target, m[1:])
                    else:
                        return irc.client.Event(command,
                             irc.client.NickMask(prefix), target, m)
                else:
                    return irc.client.Event(command,
                         irc.client.NickMask(prefix), target, [m])

        else:
            target = None

            if command == "quit":
                arguments = [arguments[0]]
            elif command == "ping":
                target = arguments[0]
            else:
                target = arguments[0]
                arguments = arguments[1:]

            if command == "mode":
                if not irc.client.is_channel(target):
                    command = "umode"

            return irc.client.Event(command, prefix, target, arguments)

    def auth(self, event):
        session = self.session()
        passw = hashlib.sha1(event.splitd[1].encode('utf-8')).hexdigest()

        try:
            row = session.query(User).filter(User.name == event.splitd[0]) \
             .filter(User.password == passw).one()
            self.authd[event.source] = row.uid
            self.server.privmsg(event.target, "Autenticado exitosamente como" +
             row.name)
        except:
            self.server.privmsg(event.target, "\00304Error\003: Usuario o " +
            "contraseña incorrectos")

    def addHandler(self, numeric, modulo, func):
        """ Registra un handler con el bot.
        Parametros:
            - server: Nombre (dirección) del servidor en el que se registra el
             handler (la misma que aparece en la configuración)
            - numeric: Nombre del comando IRC que accionara el handler
              (lista: irc/events.py)
            - modulo: 'self' del módulo en el que se registra el handler
            - func: la función que se llamará en el módulo en cuestión
        """
        h = {}
        h['numeric'] = numeric
        h['mod'] = modulo
        h['func'] = func

        self.handlers.append(h)

        logging.debug("Registrado handler en '%s' ('%s')"
           % (self.conf['server'], numeric))

    def addCommandHandler(self, command, module, func, chelp="", cpriv=-1,
         cprivsect="*", privmsgonly=False):
        """ Registra un commandHandler con el bot (un comando, bah)
        Parametros:
            - server: Nombre (dirección) del servidor en el que se registra el
             handler (la misma que aparece en la configuración)
            - command: Nombre del comando que se va a registrar
            - módulo: 'self' del módulo donde se registra el handler
            - fund; la función que se llamara en el módulo en cuestión.
            - chelp: La ayuda del comando
            - cpriv y cprivsect: Privilegios requeridos para usar el comando
            - privmsgonly: si el comando solo debe ser ejecutado por privmsg
        Los comandos se accionan al escribir <prefijo>comando;
         <nickdelbot>, comando; <nickdelbot>: comando y <nickdelbot> comando """
        h = {}
        h['mod'] = module
        h['func'] = func
        h['cpriv'] = cpriv
        h['cprivsect'] = cprivsect
        h['privmsgonly'] = privmsgonly
        self.commandhandlers[command] = h

        logging.debug("Registrado commandHandler en '%s' ('%s')"
         % (self.conf['server'], command))

    # carga de modulos
    def loadmod(self, module, cli):
        logging.info('Cargando modulo "%s" en %s'
         % (module, self.conf['server']))
        try:
            # D:
            modulef = open('modules/%s/%s.py' % (module, module)).read()
            nclassname = "m" + str(int(time.time())) + "x" + module
            mod = re.sub(r".*class (.*):", "class " + nclassname + ":", modulef)
            open('tmp/%s/%s.py' % (self.conf['pserver'], nclassname),
                 'w').write(mod)

            self.modules[module] = my_import("tmp." + self.conf['pserver'] +
            "." + nclassname + "." + nclassname)(self, cli)
            self.modinfo[module] = nclassname
        except IOError:
            logging.error("No se pudo cargar el modulo '%s'. No se ha" +
            " encontrado el archivo." % module)

    def unloadmod(self, module):
        logging.info('Des-cargando modulo "%s" en %s'
         % (module, self.conf['server']))
        try:
            self.modules[module]
        except NameError:
            logging.error("El modulo %s no existe o no esta cargado" % module)
            return 1
        os.remove("tmp/%s/%s.py" % (self.conf['pserver'], self.modinfo[module]))
        # Eliminamos los handlers..
        for i, val in enumerate(self.handlers):
            if self.modules[module] == self.handlers[i]['mod']:
                logging.debug('Eliminando handler "%s" del modulo %s en %s'
                 % (self.handlers[i]['numeric'], module, self.conf['server']))
                del self.handlers[i]

        l = []
        # Eliminamos los commandhandlers
        for i in list(self.commandhandlers.keys()):
            if self.modules[module] == self.commandhandlers[i]['mod']:
                l.append(i)
        for q in enumerate(l):
                logging.debug('Eliminando commandhandler "%s" del modulo %s'
                 % (q[1], module))
                del self.commandhandlers[q[1]]

def my_import(cl):
        d = cl.rfind(".")
        classname = cl[d + 1:len(cl)]
        m = __import__(cl[0:d], globals(), locals(), [classname])
        return getattr(m, classname)<commit_msg>Arreglando los privilegios y preparandolo todo para poner privilegios por canal<commit_after># -*- coding: utf-8 -*-
import re
from irc import events
import irc.client
import time
import hashlib
import logging
import os
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

_rfc_1459_command_regexp = re.compile("^(:(?P<prefix>[^ ]+) +)?" +
    "(?P<command>[^ ]+)( *(?P<argument> .+))?")

engine = create_engine("sqlite:///db/cobot.db")
Base = declarative_base()

from .tables import User, UserPriv

Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

class pyCoBot:
    def __init__(self, server, client, conf):
        self.session = Session
        self.handlers = []
        self.server = client.server()
        self.server.connect(server, conf['port'], conf['nick'],
            username=conf['nick'], ircname="pyCoBot")
        self.server.add_global_handler("all_raw_messages", self.allraw)

        self.modules = {}
        self.modinfo = {}
        self.commandhandlers = {}
        self.conf = conf
        self.authd = {}  # Usuarios autenticados..
        for i, val in enumerate(conf['modules']):
            self.loadmod(conf['modules'][i], conf['server'])

    def allraw(self, con, event):
        ev = self.processline(event.arguments[0], con)
        # OPTIMIZE: hacer esto es feo, cambiarlo por algo mejor!
        for i, val in enumerate(self.handlers):
            if ev.type == self.handlers[i]['numeric']:
                m = getattr(self.handlers[i]['mod'], self.handlers[i]['func'])
                m(self.server)

        if ev.type == "privmsg" or ev.type == "pubmsg":
            #p = re.compile("(?:" + re.escape(self.conf['prefix']) + "|" +
            #    re.escape(self.conf['nick']) + "[:, ]? )(.*)(?!\w+)")
            # Buscamos por el prefijo..
            p1 = re.compile(re.escape(self.conf['prefix']) +
                "(\S{1,52})[ ]?(.*)")
            m1 = p1.search(ev.arguments[0])

            # Buscamos por el nick como prefijo..
            p2 = re.compile(re.escape(self.conf['nick']) +
                "[:, ]? (\S{1,52})[ ]?(.*)")
            m2 = p2.search(ev.arguments[0])
            if not m1 is None:
                del ev.splitd[0]
                com = m1.group(1)
            elif not m2 is None:
                del ev.splitd[0]
                del ev.splitd[0]
                com = m2.group(1)

            if not m1 is None or not m2 is None:
                if com == "help" or com == "ayuda":
                    r = False
                    if not len(ev.splitd) > 0:
                        comlist = "help auth "
                        for i in list(self.commandhandlers.keys()):
                            comlist = comlist + i + " "

                        con.privmsg(ev.target, "\2pyCoBot alpha\2. Comandos " +
                        "empezar con \2" + self.conf["prefix"] + "\2. " +
                        "Escriba " + self.conf["prefix"] + "help \2<comando>" +
                        "\2 para mas información sobre un comando")

                        con.privmsg(ev.target, "Comandos: " + comlist)
                    else:
                        if ev.splitd[0] == "help":  # Harcoded help :P
                            r = "Muestra la ayuda de un comando, o, si no " + \
                             " tiene parametros, la lista de comandos." + \
                             " Sintaxis: help [comando]"
                        elif ev.splitd[0] == "auth":
                            r = "Identifica a un usuario registrado con el " + \
                             " Bot. Sintaxis" + \
                             " Sintaxis: help [comando]"
                        else:
                            try:
                                r = self.commandhandlers[ev.splitd[0]]['chelp']
                            except KeyError:
                                pass
                        if not r:
                            con.privmsg(ev.target, "No se ha encontrado el " +
                             "comando")
                        else:
                            con.privmsg(ev.target, "Ayuda de \2" + ev.splitd[0]
                             + "\2: " + r)
                elif com == "auth" and ev.type == "privmsg":
                    self.auth(ev)
                elif com == "update":
                    pass  # TODO: actualizador!!
                else:
                    try:
                        self.commandhandlers[com]
                    except KeyError:
                        return 0
                    # Verificación de autenticación
                    if not self.commandhandlers[com]['cpriv'] == -1:
                        try:
                            uid = self.authd[ev.source]
                            continua = False
                            session = self.session()
                            for row in session.query(UserPriv) \
                            .filter(UserPriv.uid == uid):
                                if (row.priv >= self.commandhandlers[com]
                                 ['cpriv']) and (row.secmod == "*" or row.secmod
                                 == self.commandhandlers[com]['mod'].__class__
                                 .__name__):
                                    continua = True
                                    # TODO: Implementar privilegios por canal.
                        except KeyError:
                            self.server.privmsg(ev.target,
                            "\00304Error\003: No autorizado")
                            return 1
                        if not continua is True:
                            self.server.privmsg(ev.target,
                            "\00304Error\003: No autorizado")
                            return 1
                    getattr(self.commandhandlers[com]['mod'],
                      self.commandhandlers[com]['func'])(self, self.server, ev)

        if ev.type == "welcome":
            for i, val in enumerate(self.conf['autojoin']):
                con.join(self.conf['autojoin'][i])

    # Procesa una linea y retorna un Event
    def processline(self, line, c):
        prefix = None
        command = None
        arguments = None

        m = _rfc_1459_command_regexp.match(line)
        if m.group("prefix"):
            prefix = m.group("prefix")

        if m.group("command"):
            command = m.group("command").lower()

        if m.group("argument"):
            a = m.group("argument").split(" :", 1)
            arguments = a[0].split()
            if len(a) == 2:
                arguments.append(a[1])

        # Translate numerics into more readable strings.
        command = events.numeric.get(command, command)

        if command in ["privmsg", "notice"]:
            target, message = arguments[0], arguments[1]
            messages = irc.client._ctcp_dequote(message)

            if command == "privmsg":
                if irc.client.is_channel(target):
                    command = "pubmsg"
            else:
                if irc.client.is_channel(target):
                    command = "pubnotice"
                else:
                    command = "privnotice"

            for m in messages:
                if isinstance(m, tuple):
                    if command in ["privmsg", "pubmsg"]:
                        command = "ctcp"
                    else:
                        command = "ctcpreply"

                    if command == "ctcp" and m[0] == "ACTION":
                        return irc.client.Event("action", prefix, target, m[1:])
                    else:
                        return irc.client.Event(command,
                             irc.client.NickMask(prefix), target, m)
                else:
                    return irc.client.Event(command,
                         irc.client.NickMask(prefix), target, [m])

        else:
            target = None

            if command == "quit":
                arguments = [arguments[0]]
            elif command == "ping":
                target = arguments[0]
            else:
                target = arguments[0]
                arguments = arguments[1:]

            if command == "mode":
                if not irc.client.is_channel(target):
                    command = "umode"

            return irc.client.Event(command, prefix, target, arguments)

    def auth(self, event):
        session = self.session()
        passw = hashlib.sha1(event.splitd[1].encode('utf-8')).hexdigest()

        try:
            row = session.query(User).filter(User.name == event.splitd[0]) \
             .filter(User.password == passw).one()
            self.authd[event.source] = row.uid
            self.server.privmsg(event.target, "Autenticado exitosamente como" +
             row.name)
        except:
            self.server.privmsg(event.target, "\00304Error\003: Usuario o " +
            "contraseña incorrectos")

    def addHandler(self, numeric, modulo, func):
        """ Registra un handler con el bot.
        Parametros:
            - server: Nombre (dirección) del servidor en el que se registra el
             handler (la misma que aparece en la configuración)
            - numeric: Nombre del comando IRC que accionara el handler
              (lista: irc/events.py)
            - modulo: 'self' del módulo en el que se registra el handler
            - func: la función que se llamará en el módulo en cuestión
        """
        h = {}
        h['numeric'] = numeric
        h['mod'] = modulo
        h['func'] = func

        self.handlers.append(h)

        logging.debug("Registrado handler en '%s' ('%s')"
           % (self.conf['server'], numeric))

    def addCommandHandler(self, command, module, func, chelp="", cpriv=-1,
         cprivchan=False, privmsgonly=False):
        """ Registra un commandHandler con el bot (un comando, bah)
        Parametros:
            - server: Nombre (dirección) del servidor en el que se registra el
             handler (la misma que aparece en la configuración)
            - command: Nombre del comando que se va a registrar
            - módulo: 'self' del módulo donde se registra el handler
            - fund; la función que se llamara en el módulo en cuestión.
            - chelp: La ayuda del comando
            - cpriv y cprivsect: Privilegios requeridos para usar el comando
            - privmsgonly: si el comando solo debe ser ejecutado por privmsg
        Los comandos se accionan al escribir <prefijo>comando;
         <nickdelbot>, comando; <nickdelbot>: comando y <nickdelbot> comando """
        h = {}
        h['mod'] = module
        h['func'] = func
        h['cpriv'] = cpriv
        h['cprivchan'] = cprivchan
        h['privmsgonly'] = privmsgonly
        h['chelp'] = chelp
        self.commandhandlers[command] = h

        logging.debug("Registrado commandHandler en '%s' ('%s')"
         % (self.conf['server'], command))

    # carga de modulos
    def loadmod(self, module, cli):
        logging.info('Cargando modulo "%s" en %s'
         % (module, self.conf['server']))
        try:
            # D:
            modulef = open('modules/%s/%s.py' % (module, module)).read()
            nclassname = "m" + str(int(time.time())) + "x" + module
            mod = re.sub(r".*class (.*):", "class " + nclassname + ":", modulef)
            open('tmp/%s/%s.py' % (self.conf['pserver'], nclassname),
                 'w').write(mod)

            self.modules[module] = my_import("tmp." + self.conf['pserver'] +
            "." + nclassname + "." + nclassname)(self, cli)
            self.modinfo[module] = nclassname
        except IOError:
            logging.error("No se pudo cargar el modulo '%s'. No se ha" +
            " encontrado el archivo." % module)

    def unloadmod(self, module):
        logging.info('Des-cargando modulo "%s" en %s'
         % (module, self.conf['server']))
        try:
            self.modules[module]
        except NameError:
            logging.error("El modulo %s no existe o no esta cargado" % module)
            return 1
        os.remove("tmp/%s/%s.py" % (self.conf['pserver'], self.modinfo[module]))
        # Eliminamos los handlers..
        for i, val in enumerate(self.handlers):
            if self.modules[module] == self.handlers[i]['mod']:
                logging.debug('Eliminando handler "%s" del modulo %s en %s'
                 % (self.handlers[i]['numeric'], module, self.conf['server']))
                del self.handlers[i]

        l = []
        # Eliminamos los commandhandlers
        for i in list(self.commandhandlers.keys()):
            if self.modules[module] == self.commandhandlers[i]['mod']:
                l.append(i)
        for q in enumerate(l):
                logging.debug('Eliminando commandhandler "%s" del modulo %s'
                 % (q[1], module))
                del self.commandhandlers[q[1]]

def my_import(cl):
        d = cl.rfind(".")
        classname = cl[d + 1:len(cl)]
        m = __import__(cl[0:d], globals(), locals(), [classname])
        return getattr(m, classname)<|endoftext|>


<commit_before>from collections import namedtuple

from .serialize import h2b

NetworkValues = namedtuple('NetworkValues',
                           ('network_name', 'subnet_name', 'code', 'wif', 'address',
                            'pay_to_script', 'prv32', 'pub32'))

NETWORKS = (

    # BTC bitcoin mainnet : xprv/xpub
    NetworkValues("Bitcoin", "mainnet", "BTC", b'\x80', b'\0', b'\5', h2b("0488ADE4"), h2b("0488B21E")),
    # BTC bitcoin testnet : tprv/tpub
    NetworkValues("Bitcoin", "testnet3", "XTN", b'\xef', b'\x6f', b'\xc4',
                  h2b("04358394"), h2b("043587CF")),

    # LTC litecoin mainnet : Ltpv/Ltub
    NetworkValues("Litecoin", "mainnet", "LTC", b'\xb0', b'\x30', b'\5', h2b('019d9cfe'), h2b('019da462')),
    # LTC litecoin testnet : ttpv/ttub
    NetworkValues("Litecoin", "testnet", "XLT", b'\xef', b'\x6f', b'\xc4',
                  h2b('0436ef7d'), h2b('0436f6e1')),

    # VIA viacoin mainnet : xprv/xpub
    NetworkValues("Viacoin", "mainnet", "VIA", b'\xc7', b'\x47', b'\x21', h2b('0488ADE4'), h2b('0488B21E')),
    # VIA viacoin testnet : tprv/tpub
    NetworkValues("Viacoin", "testnet", "TVI", b'\xff', b'\x7f', b'\xc4', h2b('04358394'), h2b('043587CF')),

    # FTC feathercoin mainnet : xprv/xpub
    NetworkValues("Feathercoin", "mainnet", "FTC", b'\x8e', b'\x0e', b'\x60', h2b('0488ADE4'), h2b('0488B21E')),
    # FTC feathercoin testnet : tprv/tpub
    NetworkValues("Feathercoin", "testnet", "FTX", b'\xC1', b'\x41', b'\xc4', h2b('04358394'), h2b('043587CF')),

    # DOGE Dogecoin mainnet : dogv/dogp
    NetworkValues(
        "Dogecoin", "mainnet", "DOGE", b'\x9e', b'\x1e', b'\x16', h2b("02FD3955"), h2b("02FD3929")),
    # DOGE Dogecoin testnet : tgpv/tgub
    NetworkValues(
        "Dogecoin", "testnet", "XDT", b'\xf1', b'\x71', b'\xc4', h2b("0432a9a8"), h2b("0432a243")),

    # BC BlackCoin mainnet : bcpv/bcpb
    NetworkValues("Blackcoin", "mainnet", "BC", b'\x99', b'\x19', None, h2b("02cfbf60"), h2b("02cfbede")),

    # DRK Dash mainnet : drkv/drkp
    NetworkValues(
        "Dash", "mainnet", "DASH", b'\xcc', b'\x4c', b'\x10', h2b("02fe52f8"), h2b("02fe52cc")),

    # DRK Dash testnet : DRKV/DRKP
    NetworkValues(
        "Dash", "testnet", "tDASH", b'\xef', b'\x8b', b'\x13', h2b("3a8061a0"), h2b("3a805837")),

    # MEC Megacoin mainnet : mecv/mecp
    NetworkValues("Megacoin", "mainnet", "MEC", b'\xb2', b'\x32', None, h2b("03a04db7"), h2b("03a04d8b")),

    NetworkValues(
        "Myriadcoin", "mainnet", "MYR", b'\xb2', b'\x32', b'\x09', h2b('0488ADE4'), h2b('0488B21E')),

    NetworkValues(
        "Unobtanium", "mainnet", "UNO", b'\xe0', b'\x82', b'\x1e', h2b('0488ADE4'), h2b('0488B21E')),

    # JBS Jumbucks mainnet : jprv/jpub
    NetworkValues("Jumbucks", "mainnet", "JBS", b'\xab', b'\x2b', None, h2b('037a6460'), h2b('037a689a')),

    # MZC Mazacoin mainnet: xprv/xpub
    NetworkValues("Mazacoin", "mainnet", "MZC", b'\xe0', b'\x32', b'\9', h2b("0488ADE4"), h2b("0488B21E")),

    NetworkValues(
        "Riecoin", "mainnet", "RIC", b'\x80', b'\x3c', b'\x05', h2b('0488ADE4'), h2b('0488B21E')),

)

# Map from short code to details about that network.
NETWORK_NAME_LOOKUP = dict((i.code, i) for i in NETWORKS)

# All network names, return in same order as list above: for UI purposes.
NETWORK_NAMES = [i.code for i in NETWORKS]

DEFAULT_NETCODES = NETWORK_NAMES

def _lookup(netcode, property):
    # Lookup a specific value needed for a specific network
    network = NETWORK_NAME_LOOKUP.get(netcode)
    if network:
        return getattr(network, property)
    return None

def network_name_for_netcode(netcode):
    return _lookup(netcode, "network_name")

def subnet_name_for_netcode(netcode):
    return _lookup(netcode, "subnet_name")

def full_network_name_for_netcode(netcode):
    network = NETWORK_NAME_LOOKUP[netcode]
    if network:
        return "%s %s" % (network.network_name, network.subnet_name)

def wif_prefix_for_netcode(netcode):
    return _lookup(netcode, "wif")

def address_prefix_for_netcode(netcode):
    return _lookup(netcode, "address")

def pay_to_script_prefix_for_netcode(netcode):
    return _lookup(netcode, "pay_to_script")

def prv32_prefix_for_netcode(netcode):
    return _lookup(netcode, "prv32")

def pub32_prefix_for_netcode(netcode):
    return _lookup(netcode, "pub32")
<commit_msg>Added DEFCOIN (DFC) support to networks.py<commit_after>from collections import namedtuple

from .serialize import h2b

NetworkValues = namedtuple('NetworkValues',
                           ('network_name', 'subnet_name', 'code', 'wif', 'address',
                            'pay_to_script', 'prv32', 'pub32'))

NETWORKS = (

    # BTC bitcoin mainnet : xprv/xpub
    NetworkValues("Bitcoin", "mainnet", "BTC", b'\x80', b'\0', b'\5', h2b("0488ADE4"), h2b("0488B21E")),
    # BTC bitcoin testnet : tprv/tpub
    NetworkValues("Bitcoin", "testnet3", "XTN", b'\xef', b'\x6f', b'\xc4',
                  h2b("04358394"), h2b("043587CF")),

    # LTC litecoin mainnet : Ltpv/Ltub
    NetworkValues("Litecoin", "mainnet", "LTC", b'\xb0', b'\x30', b'\5', h2b('019d9cfe'), h2b('019da462')),
    # LTC litecoin testnet : ttpv/ttub
    NetworkValues("Litecoin", "testnet", "XLT", b'\xef', b'\x6f', b'\xc4',
                  h2b('0436ef7d'), h2b('0436f6e1')),

    # VIA viacoin mainnet : xprv/xpub
    NetworkValues("Viacoin", "mainnet", "VIA", b'\xc7', b'\x47', b'\x21', h2b('0488ADE4'), h2b('0488B21E')),
    # VIA viacoin testnet : tprv/tpub
    NetworkValues("Viacoin", "testnet", "TVI", b'\xff', b'\x7f', b'\xc4', h2b('04358394'), h2b('043587CF')),

    # FTC feathercoin mainnet : xprv/xpub
    NetworkValues("Feathercoin", "mainnet", "FTC", b'\x8e', b'\x0e', b'\x60', h2b('0488ADE4'), h2b('0488B21E')),
    # FTC feathercoin testnet : tprv/tpub
    NetworkValues("Feathercoin", "testnet", "FTX", b'\xC1', b'\x41', b'\xc4', h2b('04358394'), h2b('043587CF')),

    # DOGE Dogecoin mainnet : dogv/dogp
    NetworkValues(
        "Dogecoin", "mainnet", "DOGE", b'\x9e', b'\x1e', b'\x16', h2b("02FD3955"), h2b("02FD3929")),
    # DOGE Dogecoin testnet : tgpv/tgub
    NetworkValues(
        "Dogecoin", "testnet", "XDT", b'\xf1', b'\x71', b'\xc4', h2b("0432a9a8"), h2b("0432a243")),

    # BC BlackCoin mainnet : bcpv/bcpb
    NetworkValues("Blackcoin", "mainnet", "BC", b'\x99', b'\x19', None, h2b("02cfbf60"), h2b("02cfbede")),

    # DRK Dash mainnet : drkv/drkp
    NetworkValues(
        "Dash", "mainnet", "DASH", b'\xcc', b'\x4c', b'\x10', h2b("02fe52f8"), h2b("02fe52cc")),

    # DRK Dash testnet : DRKV/DRKP
    NetworkValues(
        "Dash", "testnet", "tDASH", b'\xef', b'\x8b', b'\x13', h2b("3a8061a0"), h2b("3a805837")),

    # MEC Megacoin mainnet : mecv/mecp
    NetworkValues("Megacoin", "mainnet", "MEC", b'\xb2', b'\x32', None, h2b("03a04db7"), h2b("03a04d8b")),

    NetworkValues(
        "Myriadcoin", "mainnet", "MYR", b'\xb2', b'\x32', b'\x09', h2b('0488ADE4'), h2b('0488B21E')),

    NetworkValues(
        "Unobtanium", "mainnet", "UNO", b'\xe0', b'\x82', b'\x1e', h2b('0488ADE4'), h2b('0488B21E')),

    # JBS Jumbucks mainnet : jprv/jpub
    NetworkValues("Jumbucks", "mainnet", "JBS", b'\xab', b'\x2b', None, h2b('037a6460'), h2b('037a689a')),

    # MZC Mazacoin mainnet: xprv/xpub
    NetworkValues("Mazacoin", "mainnet", "MZC", b'\xe0', b'\x32', b'\9', h2b("0488ADE4"), h2b("0488B21E")),

    NetworkValues(
        "Riecoin", "mainnet", "RIC", b'\x80', b'\x3c', b'\x05', h2b('0488ADE4'), h2b('0488B21E')),

    # DFC Defcoin mainnet: dfcv/dfcp
    NetworkValues(
        "DEFCOIN", "mainnet", "DFC", b'\x9e', b'\x1e', b'\x16', h2b("02FA54D7"), h2b("02FA54AD")),

)

# Map from short code to details about that network.
NETWORK_NAME_LOOKUP = dict((i.code, i) for i in NETWORKS)

# All network names, return in same order as list above: for UI purposes.
NETWORK_NAMES = [i.code for i in NETWORKS]

DEFAULT_NETCODES = NETWORK_NAMES

def _lookup(netcode, property):
    # Lookup a specific value needed for a specific network
    network = NETWORK_NAME_LOOKUP.get(netcode)
    if network:
        return getattr(network, property)
    return None

def network_name_for_netcode(netcode):
    return _lookup(netcode, "network_name")

def subnet_name_for_netcode(netcode):
    return _lookup(netcode, "subnet_name")

def full_network_name_for_netcode(netcode):
    network = NETWORK_NAME_LOOKUP[netcode]
    if network:
        return "%s %s" % (network.network_name, network.subnet_name)

def wif_prefix_for_netcode(netcode):
    return _lookup(netcode, "wif")

def address_prefix_for_netcode(netcode):
    return _lookup(netcode, "address")

def pay_to_script_prefix_for_netcode(netcode):
    return _lookup(netcode, "pay_to_script")

def prv32_prefix_for_netcode(netcode):
    return _lookup(netcode, "prv32")

def pub32_prefix_for_netcode(netcode):
    return _lookup(netcode, "pub32")
<|endoftext|>


<commit_before>try:
    import StringIO
except:
    import io as StringIO
import traceback
from os.path import basename

try:
    __setFalse = False
except:
    import __builtin__
    setattr(__builtin__, 'True', 1)
    setattr(__builtin__, 'False', 0)

import pydevd_constants
from pydevd_constants import DictIterItems

MAX_ITEMS_TO_HANDLE = 500
TOO_LARGE_MSG = 'Too large to show contents. Max items to show: ' + str(MAX_ITEMS_TO_HANDLE)
TOO_LARGE_ATTR = 'Unable to handle:'

#=======================================================================================================================
# UnableToResolveVariableException
#=======================================================================================================================
class UnableToResolveVariableException(Exception):
    pass

#=======================================================================================================================
# InspectStub
#=======================================================================================================================
class InspectStub:
    def isbuiltin(self, _args):
        return False
    def isroutine(self, object):
        return False

try:
    import inspect
except:
    inspect = InspectStub()

try:
    import java.lang #@UnresolvedImport
except:
    pass

#types does not include a MethodWrapperType
try:
    MethodWrapperType = type([].__str__)
except:
    MethodWrapperType = None

#=======================================================================================================================
# AbstractResolver
#=======================================================================================================================
class AbstractResolver:
    '''
        This class exists only for documentation purposes to explain how to create a resolver.

        Some examples on how to resolve things:
        - list: getDictionary could return a dict with index->item and use the index to resolve it later
        - set: getDictionary could return a dict with id(object)->object and reiterate in that array to resolve it later
        - arbitrary instance: getDictionary could return dict with attr_name->attr and use getattr to resolve it later
    '''

    def resolve(self, var, attribute):
        '''
            In this method, we'll resolve some child item given the string representation of the item in the key
            representing the previously asked dictionary.

            @param var: this is the actual variable to be resolved.
            @param attribute: this is the string representation of a key previously returned in getDictionary.
        '''
        raise NotImplementedError

    def getDictionary(self, var):
        '''
            @param var: this is the variable that should have its children gotten.

            @return: a dictionary where each pair key, value should be shown to the user as children items
            in the variables view for the given var.
        '''
        raise NotImplementedError

#=======================================================================================================================
# DefaultResolver
#=======================================================================================================================
class DefaultResolver:
    '''
        DefaultResolver is the class that'll actually resolve how to show some variable.
    '''

    def resolve(self, var, attribute):
        return getattr(var, attribute)

    def getDictionary(self, var):
        if MethodWrapperType:
            return self._getPyDictionary(var)
        else:
            return self._getJyDictionary(var)

    def _getJyDictionary(self, obj):
        ret = {}
        found = java.util.HashMap()

        original = obj
        if hasattr(obj, '__class__') and obj.__class__ == java.lang.Class:

            #get info about superclasses
            classes = []
            classes.append(obj)
            c = obj.getSuperclass()
            while c != None:
                classes.append(c)
                c = c.getSuperclass()

            #get info about interfaces
            interfs = []
            for obj in classes:
                interfs.extend(obj.getInterfaces())
            classes.extend(interfs)

            #now is the time when we actually get info on the declared methods and fields
            for obj in classes:

                declaredMethods = obj.getDeclaredMethods()
                declaredFields = obj.getDeclaredFields()
                for i in range(len(declaredMethods)):
                    name = declaredMethods[i].getName()
                    ret[name] = declaredMethods[i].toString()
                    found.put(name, 1)

                for i in range(len(declaredFields)):
                    name = declaredFields[i].getName()
                    found.put(name, 1)
                    #if declaredFields[i].isAccessible():
                    declaredFields[i].setAccessible(True)
                    #ret[name] = declaredFields[i].get( declaredFields[i] )
                    try:
                        ret[name] = declaredFields[i].get(original)
                    except:
                        ret[name] = declaredFields[i].toString()

        #this simple dir does not always get all the info, that's why we have the part before
        #(e.g.: if we do a dir on String, some methods that are from other interfaces such as
        #charAt don't appear)
        try:
            d = dir(original)
            for name in d:
                if found.get(name) is not 1:
                    ret[name] = getattr(original, name)
        except:
            #sometimes we're unable to do a dir
            pass

        return ret

    def _getPyDictionary(self, var):
        filterPrivate = False
        filterSpecial = True
        filterFunction = True
        filterBuiltIn = True

        names = dir(var)
        if not names and hasattr(var, '__members__'):
            names = var.__members__
        d = {}

        #Be aware that the order in which the filters are applied attempts to
        #optimize the operation by removing as many items as possible in the
        #first filters, leaving fewer items for later filters

        if filterBuiltIn or filterFunction:
            for n in names:
                if filterSpecial:
                    if n.startswith('__') and n.endswith('__'):
                        continue

                if filterPrivate:
                    if n.startswith('_') or n.endswith('__'):
                        continue

                try:
                    attr = getattr(var, n)

                    #filter builtins?
                    if filterBuiltIn:
                        if inspect.isbuiltin(attr):
                            continue

                    #filter functions?
                    if filterFunction:
                        if inspect.isroutine(attr) or isinstance(attr, MethodWrapperType):
                            continue
                except:
                    #if some error occurs getting it, let's put it to the user.
                    strIO = StringIO.StringIO()
                    traceback.print_exc(file=strIO)
                    attr = strIO.getvalue()

                d[ n ] = attr

        return d

#=======================================================================================================================
# DictResolver
#=======================================================================================================================
class DictResolver:

    def resolve(self, dict, key):
        if key == '__len__':
            return None

        if '(' not in key:
            #we have to treat that because the dict resolver is also used to directly resolve the global and local
            #scopes (which already have the items directly)
            return dict[key]

        #ok, we have to iterate over the items to find the one that matches the id, because that's the only way
        #to actually find the reference from the string we have before.
        expected_id = int(key.split('(')[-1][:-1])
        for key, val in DictIterItems(dict):
            if id(key) == expected_id:
                return val

        raise UnableToResolveVariableException()

    def keyStr(self, key):
        if isinstance(key, str):
            return "'%s'"%key
        else:
            if not pydevd_constants.IS_PY3K:
                if isinstance(key, unicode):
                    return "u'%s'"%key
            return key

    def getDictionary(self, dict):
        ret = {}

        for key, val in DictIterItems(dict):
            #we need to add the id because otherwise we cannot find the real object to get its contents later on.
            key = '%s (%s)' % (self.keyStr(key), id(key))
            ret[key] = val

        ret['__len__'] = len(dict)
        return ret

#=======================================================================================================================
# TupleResolver
#=======================================================================================================================
class TupleResolver: #to enumerate tuples and lists

    def resolve(self, var, attribute):
        '''
            @param var: that's the original attribute
            @param attribute: that's the key passed in the dict (as a string)
        '''
        if attribute == '__len__' or attribute == TOO_LARGE_ATTR:
            return None
        return var[int(attribute)]

    def getDictionary(self, var):
        #return dict( [ (i, x) for i, x in enumerate(var) ] )
        # modified 'cause jython does not have enumerate support
        l = len(var)
        d = {}

        if l < MAX_ITEMS_TO_HANDLE:
            format = '%0' + str(int(len(str(l)))) + 'd'

            for i, item in zip(range(l), var):
                d[ format % i ] = item
        else:
            d[TOO_LARGE_ATTR] = TOO_LARGE_MSG
        d['__len__'] = len(var)
        return d

#=======================================================================================================================
# SetResolver
#=======================================================================================================================
class SetResolver:
    '''
        Resolves a set as dict id(object)->object
    '''

    def resolve(self, var, attribute):
        if attribute == '__len__':
            return None

        attribute = int(attribute)
        for v in var:
            if id(v) == attribute:
                return v

        raise UnableToResolveVariableException('Unable to resolve %s in %s' % (attribute, var))

    def getDictionary(self, var):
        d = {}
        for item in var:
            d[ id(item) ] = item
        d['__len__'] = len(var)
        return d

#=======================================================================================================================
# InstanceResolver
#=======================================================================================================================
class InstanceResolver:

    def resolve(self, var, attribute):
        field = var.__class__.getDeclaredField(attribute)
        field.setAccessible(True)
        return field.get(var)

    def getDictionary(self, obj):
        ret = {}

        declaredFields = obj.__class__.getDeclaredFields()
        for i in range(len(declaredFields)):
            name = declaredFields[i].getName()
            try:
                declaredFields[i].setAccessible(True)
                ret[name] = declaredFields[i].get(obj)
            except:
                traceback.print_exc()

        return ret

#=======================================================================================================================
# JyArrayResolver
#=======================================================================================================================
class JyArrayResolver:
    '''
        This resolves a regular Object[] array from java
    '''

    def resolve(self, var, attribute):
        if attribute == '__len__':
            return None
        return var[int(attribute)]

    def getDictionary(self, obj):
        ret = {}

        for i in range(len(obj)):
            ret[ i ] = obj[i]

        ret['__len__'] = len(obj)
        return ret

#=======================================================================================================================
# NdArrayResolver
#=======================================================================================================================
class NdArrayResolver:
    '''
        This resolves a numpy ndarray returning some metadata about the NDArray
    '''

    def resolve(self, obj, attribute):
        if attribute == '__internals__':
            return defaultResolver.getDictionary(obj)
        if attribute == 'min':
            return obj.min()
        if attribute == 'max':
            return obj.max()
        if attribute == 'shape':
            return obj.shape
        if attribute == 'dtype':
            return obj.dtype
        if attribute == 'size':
            return obj.size
        return None

    def getDictionary(self, obj):
        ret = dict()
        ret['__internals__'] = defaultResolver.getDictionary(obj)
        if obj.size > 1024 * 1024:
            ret['min'] = 'ndarray too big, calculating min would slow down debugging'
            ret['max'] = 'ndarray too big, calculating max would slow down debugging'
        else:
            ret['min'] = obj.min()
            ret['max'] = obj.max()
        ret['shape'] = obj.shape
        ret['dtype'] = obj.dtype
        ret['size'] = obj.size
        return ret

#=======================================================================================================================
# FrameResolver
#=======================================================================================================================
class FrameResolver:
    '''
    This resolves a frame.
    '''

    def resolve(self, obj, attribute):
        if attribute == '__internals__':
            return defaultResolver.getDictionary(obj)

        if attribute == 'stack':
            return self.getFrameStack(obj)

        if attribute == 'f_locals':
            return obj.f_locals

        return None

    def getDictionary(self, obj):
        ret = dict()
        ret['__internals__'] = defaultResolver.getDictionary(obj)
        ret['stack'] = self.getFrameStack(obj)
        ret['f_locals'] = obj.f_locals
        return ret

    def getFrameStack(self, frame):
        ret = []
        if frame is not None:
            ret.append(self.getFrameName(frame))

            while frame.f_back:
                frame = frame.f_back
                ret.append(self.getFrameName(frame))

        return ret

    def getFrameName(self, frame):
        if frame is None:
            return 'None'
        try:
            name = basename(frame.f_code.co_filename)
            return 'frame: %s [%s:%s]  id:%s' % (frame.f_code.co_name, name, frame.f_lineno, id(frame))
        except:
            return 'frame object'

defaultResolver = DefaultResolver()
dictResolver = DictResolver()
tupleResolver = TupleResolver()
instanceResolver = InstanceResolver()
jyArrayResolver = JyArrayResolver()
setResolver = SetResolver()
ndarrayResolver = NdArrayResolver()
frameResolver = FrameResolver()
<commit_msg>If dictionary is too big, only show partial contents.<commit_after>try:
    import StringIO
except:
    import io as StringIO
import traceback
from os.path import basename

try:
    __setFalse = False
except:
    import __builtin__
    setattr(__builtin__, 'True', 1)
    setattr(__builtin__, 'False', 0)

import pydevd_constants
from pydevd_constants import DictIterItems

MAX_ITEMS_TO_HANDLE = 500
TOO_LARGE_MSG = 'Too large to show contents. Max items to show: ' + str(MAX_ITEMS_TO_HANDLE)
TOO_LARGE_ATTR = 'Unable to handle:'

#=======================================================================================================================
# UnableToResolveVariableException
#=======================================================================================================================
class UnableToResolveVariableException(Exception):
    pass

#=======================================================================================================================
# InspectStub
#=======================================================================================================================
class InspectStub:
    def isbuiltin(self, _args):
        return False
    def isroutine(self, object):
        return False

try:
    import inspect
except:
    inspect = InspectStub()

try:
    import java.lang #@UnresolvedImport
except:
    pass

#types does not include a MethodWrapperType
try:
    MethodWrapperType = type([].__str__)
except:
    MethodWrapperType = None

#=======================================================================================================================
# AbstractResolver
#=======================================================================================================================
class AbstractResolver:
    '''
        This class exists only for documentation purposes to explain how to create a resolver.

        Some examples on how to resolve things:
        - list: getDictionary could return a dict with index->item and use the index to resolve it later
        - set: getDictionary could return a dict with id(object)->object and reiterate in that array to resolve it later
        - arbitrary instance: getDictionary could return dict with attr_name->attr and use getattr to resolve it later
    '''

    def resolve(self, var, attribute):
        '''
            In this method, we'll resolve some child item given the string representation of the item in the key
            representing the previously asked dictionary.

            @param var: this is the actual variable to be resolved.
            @param attribute: this is the string representation of a key previously returned in getDictionary.
        '''
        raise NotImplementedError

    def getDictionary(self, var):
        '''
            @param var: this is the variable that should have its children gotten.

            @return: a dictionary where each pair key, value should be shown to the user as children items
            in the variables view for the given var.
        '''
        raise NotImplementedError

#=======================================================================================================================
# DefaultResolver
#=======================================================================================================================
class DefaultResolver:
    '''
        DefaultResolver is the class that'll actually resolve how to show some variable.
    '''

    def resolve(self, var, attribute):
        return getattr(var, attribute)

    def getDictionary(self, var):
        if MethodWrapperType:
            return self._getPyDictionary(var)
        else:
            return self._getJyDictionary(var)

    def _getJyDictionary(self, obj):
        ret = {}
        found = java.util.HashMap()

        original = obj
        if hasattr(obj, '__class__') and obj.__class__ == java.lang.Class:

            #get info about superclasses
            classes = []
            classes.append(obj)
            c = obj.getSuperclass()
            while c != None:
                classes.append(c)
                c = c.getSuperclass()

            #get info about interfaces
            interfs = []
            for obj in classes:
                interfs.extend(obj.getInterfaces())
            classes.extend(interfs)

            #now is the time when we actually get info on the declared methods and fields
            for obj in classes:

                declaredMethods = obj.getDeclaredMethods()
                declaredFields = obj.getDeclaredFields()
                for i in range(len(declaredMethods)):
                    name = declaredMethods[i].getName()
                    ret[name] = declaredMethods[i].toString()
                    found.put(name, 1)

                for i in range(len(declaredFields)):
                    name = declaredFields[i].getName()
                    found.put(name, 1)
                    #if declaredFields[i].isAccessible():
                    declaredFields[i].setAccessible(True)
                    #ret[name] = declaredFields[i].get( declaredFields[i] )
                    try:
                        ret[name] = declaredFields[i].get(original)
                    except:
                        ret[name] = declaredFields[i].toString()

        #this simple dir does not always get all the info, that's why we have the part before
        #(e.g.: if we do a dir on String, some methods that are from other interfaces such as
        #charAt don't appear)
        try:
            d = dir(original)
            for name in d:
                if found.get(name) is not 1:
                    ret[name] = getattr(original, name)
        except:
            #sometimes we're unable to do a dir
            pass

        return ret

    def _getPyDictionary(self, var):
        filterPrivate = False
        filterSpecial = True
        filterFunction = True
        filterBuiltIn = True

        names = dir(var)
        if not names and hasattr(var, '__members__'):
            names = var.__members__
        d = {}

        #Be aware that the order in which the filters are applied attempts to
        #optimize the operation by removing as many items as possible in the
        #first filters, leaving fewer items for later filters

        if filterBuiltIn or filterFunction:
            for n in names:
                if filterSpecial:
                    if n.startswith('__') and n.endswith('__'):
                        continue

                if filterPrivate:
                    if n.startswith('_') or n.endswith('__'):
                        continue

                try:
                    attr = getattr(var, n)

                    #filter builtins?
                    if filterBuiltIn:
                        if inspect.isbuiltin(attr):
                            continue

                    #filter functions?
                    if filterFunction:
                        if inspect.isroutine(attr) or isinstance(attr, MethodWrapperType):
                            continue
                except:
                    #if some error occurs getting it, let's put it to the user.
                    strIO = StringIO.StringIO()
                    traceback.print_exc(file=strIO)
                    attr = strIO.getvalue()

                d[ n ] = attr

        return d

#=======================================================================================================================
# DictResolver
#=======================================================================================================================
class DictResolver:

    def resolve(self, dict, key):
        if key == '__len__':
            return None

        if key == TOO_LARGE_ATTR:
            return None

        if '(' not in key:
            #we have to treat that because the dict resolver is also used to directly resolve the global and local
            #scopes (which already have the items directly)
            return dict[key]

        #ok, we have to iterate over the items to find the one that matches the id, because that's the only way
        #to actually find the reference from the string we have before.
        expected_id = int(key.split('(')[-1][:-1])
        for key, val in DictIterItems(dict):
            if id(key) == expected_id:
                return val

        raise UnableToResolveVariableException()

    def keyStr(self, key):
        if isinstance(key, str):
            return "'%s'"%key
        else:
            if not pydevd_constants.IS_PY3K:
                if isinstance(key, unicode):
                    return "u'%s'"%key
            return key

    def getDictionary(self, dict):
        ret = {}

        i = 0
        for key, val in DictIterItems(dict):
            i += 1
            #we need to add the id because otherwise we cannot find the real object to get its contents later on.
            key = '%s (%s)' % (self.keyStr(key), id(key))
            ret[key] = val
            if i > MAX_ITEMS_TO_HANDLE:
                ret[TOO_LARGE_ATTR] = TOO_LARGE_MSG
                break

        ret['__len__'] = len(dict)
        return ret

#=======================================================================================================================
# TupleResolver
#=======================================================================================================================
class TupleResolver: #to enumerate tuples and lists

    def resolve(self, var, attribute):
        '''
            @param var: that's the original attribute
            @param attribute: that's the key passed in the dict (as a string)
        '''
        if attribute == '__len__' or attribute == TOO_LARGE_ATTR:
            return None
        return var[int(attribute)]

    def getDictionary(self, var):
        #return dict( [ (i, x) for i, x in enumerate(var) ] )
        # modified 'cause jython does not have enumerate support
        l = len(var)
        d = {}

        if l < MAX_ITEMS_TO_HANDLE:
            format = '%0' + str(int(len(str(l)))) + 'd'

            for i, item in zip(range(l), var):
                d[ format % i ] = item
        else:
            d[TOO_LARGE_ATTR] = TOO_LARGE_MSG
        d['__len__'] = len(var)
        return d

#=======================================================================================================================
# SetResolver
#=======================================================================================================================
class SetResolver:
    '''
        Resolves a set as dict id(object)->object
    '''

    def resolve(self, var, attribute):
        if attribute == '__len__':
            return None

        attribute = int(attribute)
        for v in var:
            if id(v) == attribute:
                return v

        raise UnableToResolveVariableException('Unable to resolve %s in %s' % (attribute, var))

    def getDictionary(self, var):
        d = {}
        for item in var:
            d[ id(item) ] = item
        d['__len__'] = len(var)
        return d

#=======================================================================================================================
# InstanceResolver
#=======================================================================================================================
class InstanceResolver:

    def resolve(self, var, attribute):
        field = var.__class__.getDeclaredField(attribute)
        field.setAccessible(True)
        return field.get(var)

    def getDictionary(self, obj):
        ret = {}

        declaredFields = obj.__class__.getDeclaredFields()
        for i in range(len(declaredFields)):
            name = declaredFields[i].getName()
            try:
                declaredFields[i].setAccessible(True)
                ret[name] = declaredFields[i].get(obj)
            except:
                traceback.print_exc()

        return ret

#=======================================================================================================================
# JyArrayResolver
#=======================================================================================================================
class JyArrayResolver:
    '''
        This resolves a regular Object[] array from java
    '''

    def resolve(self, var, attribute):
        if attribute == '__len__':
            return None
        return var[int(attribute)]

    def getDictionary(self, obj):
        ret = {}

        for i in range(len(obj)):
            ret[ i ] = obj[i]

        ret['__len__'] = len(obj)
        return ret

#=======================================================================================================================
# NdArrayResolver
#=======================================================================================================================
class NdArrayResolver:
    '''
        This resolves a numpy ndarray returning some metadata about the NDArray
    '''

    def resolve(self, obj, attribute):
        if attribute == '__internals__':
            return defaultResolver.getDictionary(obj)
        if attribute == 'min':
            return obj.min()
        if attribute == 'max':
            return obj.max()
        if attribute == 'shape':
            return obj.shape
        if attribute == 'dtype':
            return obj.dtype
        if attribute == 'size':
            return obj.size
        return None

    def getDictionary(self, obj):
        ret = dict()
        ret['__internals__'] = defaultResolver.getDictionary(obj)
        if obj.size > 1024 * 1024:
            ret['min'] = 'ndarray too big, calculating min would slow down debugging'
            ret['max'] = 'ndarray too big, calculating max would slow down debugging'
        else:
            ret['min'] = obj.min()
            ret['max'] = obj.max()
        ret['shape'] = obj.shape
        ret['dtype'] = obj.dtype
        ret['size'] = obj.size
        return ret

#=======================================================================================================================
# FrameResolver
#=======================================================================================================================
class FrameResolver:
    '''
    This resolves a frame.
    '''

    def resolve(self, obj, attribute):
        if attribute == '__internals__':
            return defaultResolver.getDictionary(obj)

        if attribute == 'stack':
            return self.getFrameStack(obj)

        if attribute == 'f_locals':
            return obj.f_locals

        return None

    def getDictionary(self, obj):
        ret = dict()
        ret['__internals__'] = defaultResolver.getDictionary(obj)
        ret['stack'] = self.getFrameStack(obj)
        ret['f_locals'] = obj.f_locals
        return ret

    def getFrameStack(self, frame):
        ret = []
        if frame is not None:
            ret.append(self.getFrameName(frame))

            while frame.f_back:
                frame = frame.f_back
                ret.append(self.getFrameName(frame))

        return ret

    def getFrameName(self, frame):
        if frame is None:
            return 'None'
        try:
            name = basename(frame.f_code.co_filename)
            return 'frame: %s [%s:%s]  id:%s' % (frame.f_code.co_name, name, frame.f_lineno, id(frame))
        except:
            return 'frame object'

defaultResolver = DefaultResolver()
dictResolver = DictResolver()
tupleResolver = TupleResolver()
instanceResolver = InstanceResolver()
jyArrayResolver = JyArrayResolver()
setResolver = SetResolver()
ndarrayResolver = NdArrayResolver()
frameResolver = FrameResolver()
<|endoftext|>