<commit_before># ------------------------------------- #
#        Python Package Importing       #
# ------------------------------------- #

# Importing Necessary System Packages
import sys, os, math
import numpy as np
import matplotlib as plt
import time as tp
import random as rp
from optparse import OptionParser
import glob

# Importing cPickle/Pickle
try:
   import cPickle as pickle
except:
   import pickle

# Import the Amuse Base Packages
from amuse import datamodel
from amuse.units import nbody_system
from amuse.units import units
from amuse.units import constants
from amuse.datamodel import particle_attributes
from amuse.io import *
from amuse.lab import *

# Import the Amuse Stellar Packages
from amuse.ic.kingmodel import new_king_model
from amuse.ic.kroupa import new_kroupa_mass_distribution

# Import the Amuse Gravity & Close-Encounter Packages
from amuse.community.ph4.interface import ph4
from amuse.community.smalln.interface import SmallN
from amuse.community.kepler.interface import Kepler
from amuse.community.sse.interface import SSE
from amuse.couple import multiples

# Import the Tycho Packages
from tycho import create, util, read, write

num_stars = 10
num_psys = 0
cluster_name = "workingAsIntendedTest"
restart_file = cluster_name+"_restart"
write_file = restart_file

def write_initial_state(master_set, ic_array, file_prefix):
    ''' Writes out an initial state for the Tycho Module.
        master_set: The Master Amuse Particle Set used in Tycho
        ic_array: Predefined Numpy Array that Stores Initial Conditions in SI Units
        file_prefix: String Value for a Prefix to the Saved File
    '''
# First, Define/Make the Directory for the Initial State to be Stored
    file_dir = os.getcwd()+"/InitialState"
    if not os.path.exists(file_dir):
        os.makedirs(file_dir)
    file_base = file_dir+"/"+file_prefix
# Second, Write the AMUSE Particle Set to a HDF5 File
    file_format = "hdf5"
    write_set_to_file(master_set, file_base+"_particles.hdf5", format=file_format, close_file=True)
# Third, Pickle the Initial Conditions Array
    ic_file = open(file_base+"_ic.pkl", "wb")
    pickle.dump(ic_array, ic_file)
    ic_file.close()

def write_time_step(master_set, converter, current_time, file_prefix):
    ''' Writes out necessary information for a time step.
        master_set: The Master AMUSE Particle Set used in Tycho
        multiples_code: The Multiples Instance for Tycho
        current_time: The Simulations Current Time
        file_prefix: String Value for a Prefix to the Saved File
    '''
# First, Define/Make the Directory for the Time Step to be Stored
    file_dir_MS = os.getcwd()+"/Run/MasterParticleSet"
    file_dir_CoM = os.getcwd()+"/Run/CoMSet"
    if not os.path.exists(file_dir_MS):
        os.makedirs(file_dir_MS)
    if not os.path.exists(file_dir_CoM):
        os.makedirs(file_dir_CoM)
    file_base_MS = file_dir_MS+"/"+file_prefix
    file_base_CoM = file_dir_CoM+"/"+file_prefix
# Second, Create the CoM Tree Particle Set from Multiples
# Third, Convert from NBody to SI Before Writing
    MS_SI = datamodel.ParticlesWithUnitsConverted(master_set, converter.as_converter_from_nbody_to_si())
#    CoM_SI = datamodel.ParticlesWithUnitsConverted(CoM_Set, converter.as_converter_from_nbody_to_si())
# Fourth, Write the Master AMUSE Particle Set to a HDF5 File
    file_format = "hdf5"
    write_set_to_file(MS_SI, file_base_MS+"_MS_t%.3f.hdf5" %(current_time.number), \
                      format=file_format, close_file=True)
# Fifth, Write the CoM Tree Particle Set to a HDF5 File
#    write_set_to_file(CoM_SI, file_base_CoM+"_CoM_t%.3f.hdf5" %(current_time.number), \
#                      format=file_format, close_file=True)

# ------------------------------------ #
#        WRITING  RESTART FILE         #
# ------------------------------------ #

def write_state_to_file(time, stars_python,gravity_code, multiples_code, write_file, cp_hist=False, backup = 0 ):
    print "Writing state to write file: ", write_file,"\n\n"
    if write_file is not None:
        particles = gravity_code.particles.copy()
        write_channel = gravity_code.particles.new_channel_to(particles)
        write_channel.copy_attribute("index_in_code", "id")
        bookkeeping = {'neighbor_veto': multiples_code.neighbor_veto,
            'neighbor_distance_factor': multiples_code.neighbor_distance_factor,
                'multiples_external_tidal_correction': multiples_code.multiples_external_tidal_correction,
                    'multiples_integration_energy_error': multiples_code.multiples_integration_energy_error,
                        'multiples_internal_tidal_correction': multiples_code.multiples_internal_tidal_correction,
                        'model_time': multiples_code.model_time,
                        'root_index': multiples.root_index
        }

        '''
            bookkeeping.neighbor_veto =
            bookkeeping.multiples_external_tidal_correction = multiples_code.multiples_external_tidal_correction
            bookkeeping.multiples_integration_energy_error = multiples_code.multiples_integration_energy_error
            bookkeeping.multiples_internal_tidal_correction = multiples_code.multiples_internal_tidal_correction
            bookkeeping.model_time = multiples_code.model_time
            '''
        for root, tree in multiples_code.root_to_tree.iteritems():
            #multiples.print_multiple_simple(tree,kep)
            root_in_particles = root.as_particle_in_set(particles)
            subset = tree.get_tree_subset().copy()
            if root_in_particles is not None:
                root_in_particles.components = subset
        io.write_set_to_file(particles,write_file+".stars.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist)
        io.write_set_to_file(stars_python,write_file+".stars_python.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist)
        config = {'time' : time,
            'py_seed': pickle.dumps(random.getstate()),
                'numpy_seed': pickle.dumps(numpy.random.get_state()),
#                    'options': pickle.dumps(options)
        }
        with open(write_file + ".conf", "wb") as f:
            pickle.dump(config, f)
        with open(write_file + ".bookkeeping", "wb") as f:
            pickle.dump(bookkeeping, f)
        print "\nState successfully written to:  ", write_file
        print time
        if backup > 0:
            io.write_set_to_file(particles,write_file+".backup.stars.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist, close_file=True)
            io.write_set_to_file(stars_python,write_file+".backup.stars_python.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist, close_file=True)
            config2 = {'time' : time,
                'py_seed': pickle.dumps(random.getstate()),
                    'numpy_seed': pickle.dumps(numpy.random.get_state()),
#                        'options': pickle.dumps(options)
            }
            with open(write_file + ".backup.conf", "wb") as f:
                pickle.dump(config2, f)
                f.close()
            with open(write_file + ".backup.bookkeeping", "wb") as f:
                pickle.dump(bookkeeping, f)
                f.close()
            print "\nBackup write completed.\n"

        if backup > 2:
            io.write_set_to_file(particles,write_file+"."+str(int(time.number))+".stars.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist, close_file=True)
            io.write_set_to_file(stars_python,write_file+"."+str(int(time.number))+".stars_python.hdf5",'hdf5',version='2.0', append_to_file=False, copy_history=cp_hist, close_file=True)
            config2 = {'time' : time,
                'py_seed': pickle.dumps(random.getstate()),
                    'numpy_seed': pickle.dumps(numpy.random.get_state()),
#                        'options': pickle.dumps(options)
            }
            with open(write_file + "." +str(int(time.number))+".conf", "wb") as f:
                pickle.dump(config2, f)
                f.close()
            with open(write_file + "."+str(int(time.number))+".bookkeeping", "wb") as f:
                pickle.dump(bookkeeping, f)
                f.close()
            print "\nBackup write completed.\n"

def read_state_from_file(restart_file, gravity_code, kep, SMALLN):

    stars = read_set_from_file(restart_file+".stars.hdf5",'hdf5',version='2.0', close_file=True).copy()
#    single_stars = read_set_from_file(restart_file+".singles.hdf5",'hdf5',version='2.0')
#    multiple_stars = read_set_from_file(restart_file+".coms.hdf5",'hdf5',version='2.0')
    stars_python = read_set_from_file(restart_file+".stars_python.hdf5",'hdf5',version='2.0', close_file=True).copy()
    with open(restart_file + ".bookkeeping", "rb") as f:
        bookkeeping = pickle.load(f)
        f.close()
    print bookkeeping
    root_to_tree = {}
    for root in stars:
        if hasattr(root, 'components') and not root.components is None:
            root_to_tree[root] = datamodel.trees.BinaryTreeOnParticle(root.components[0])
    gravity_code.particles.add_particles(stars)
#    print bookkeeping['model_time']
#    gravity_code.set_begin_time = bookkeeping['model_time']

    multiples_code = multiples.Multiples(gravity_code, SMALLN, kep)
#    multiples_code.neighbor_distance_factor = 1.0
#    multiples_code.neighbor_veto = False
#    multiples_code.neighbor_distance_factor = 2.0
#    multiples_code.neighbor_veto = True
    multiples_code.neighbor_distance_factor = bookkeeping['neighbor_distance_factor']
    multiples_code.neighbor_veto = bookkeeping['neighbor_veto']
    multiples_code.multiples_external_tidal_correction = bookkeeping['multiples_external_tidal_correction']
    multiples_code.multiples_integration_energy_error = bookkeeping['multiples_integration_energy_error']
    multiples_code.multiples_internal_tidal_correction = bookkeeping['multiples_internal_tidal_correction']
    multiples.root_index = bookkeeping['root_index']
    multiples_code.root_to_tree = root_to_tree
#    multiples_code.set_model_time = bookkeeping['model_time']

    return stars_python, multiples_code

def king_cluster(num_stars, filename_cluster, w0=2.5, IBF=0.5, rand_seed=0):
    ''' Creates an open cluster according to the King Model & Kroupa IMF
        num_stars: The total number of stellar systems.
        seed: The random seed used for cluster generation.
        filename_cluster: The filename used when saving the cluster.
        w0: The King density parameter.
        IBF: The Initial Binary Fraction.
    '''
# TODO: Have rand_seed actually do something ...

# Creates a List of Masses (in SI Units) Drawn from the Kroupa IMF
    masses_SI = new_kroupa_mass_distribution(num_stars)
# Creates the SI-NBody Converter
    converter = nbody_system.nbody_to_si(masses_SI.sum(), 1 | units.parsec)
# Creates a AMUS Particle Set Consisting of Positions (King) and Masses (Kroupa)
    stars_SI = new_king_model(num_stars, w0, convert_nbody=converter)
    stars_SI.mass = masses_SI
    print stars_SI.mass.as_quantity_in(units.MSun)
# Assigning IDs to the Stars
    stars_SI.id = np.arange(num_stars) + 1
    stars_SI.type = "star"
# Moving Stars to Virial Equilibrium
    stars_SI.move_to_center()
    if num_stars == 1:
        pass
    else:
        stars_SI.scale_to_standard(convert_nbody=converter)
    if int(IBF) != 0:
# Creating a Temporary Particle Set to Store Binaries
        binaries=Particles()
# Selects the Indices of Stars that will be converted to Binaries
        num_binaries = int(IBF*num_stars)
        select_stars_indices_for_binaries = rp.sample(xrange(0, num_stars), num_binaries)
        select_stars_indices_for_binaries.sort()
        delete_star_indices = []
# Creates a decending list of Star Indicies to make deletion easier.
        for y in xrange(0, num_binaries):
            delete_star_indices.append(select_stars_indices_for_binaries[(num_binaries-1)-y])
# Creates the Binaries and assigns IDs
        for j in xrange(0, num_binaries):
            q = select_stars_indices_for_binaries[j]
            binaries.add_particles(binary_system(stars_SI[q], converter))
        binaries.id = np.arange(num_binaries*2) + 2000000
# Deletes the Stars that were converted to Binaries
        for k in xrange(0, num_binaries):
            b = delete_star_indices[k]
            stars_SI.remove_particle(stars_SI[b])
# Merges the Binaries into to the Master Particle set
        stars_SI.add_particle(binaries)
# Assigning SOI Estimate for Interaction Radius
    if num_stars == 1:
        stars_SI.radius = 1000 | units.AU
    else:
        stars_SI.radius = util.calc_SOI(stars_SI.mass, np.var(stars_SI.velocity), G=units.constants.G)
# Returns the Cluster & Converter
    return stars_SI, converter

def binary_system(old_star, converter):
    ''' Creates a Binary System from an Original Star, given an NBody-to-SI converter.
        old_star: The original star that is being replaced.
        converter: The AMUSE unit converter to keep scaling correct.
    '''
# Define Original Star's Information
    rcm = old_star.position
# Define Binary System Elements
# TO DO: Make this fit observations!
    r = 500 | units.AU
    r1 = 0.5*r
    r2 = -0.5*r
# Create a Temporary
    binary = Particles(2)
    star1 = binary[0]
    star2 = binary[1]
    star1.type = 'star'
    star2.type = 'star'
    star1.mass = 0.5*old_star.mass
    star2.mass = 0.5*old_star.mass
    star1.radius = old_star.radius/2.0
    star2.radius = old_star.radius/2.0
    star1.position = [r1.number,0.0,0.0] | units.AU #nbody_system.length
    star2.position = [r2.number,0.0,0.0] | units.AU
# Calculate the Orbit Velocities for the Pair
    vel1 = np.sqrt(units.constants.G*star2.mass*r1/r**2)
    vel2 =-1*np.sqrt(units.constants.G*star1.mass*(np.absolute(r2))/r**2)
# Define New Velocities
    star1.vx = old_star.vx
    star1.vy = vel1 + old_star.vy
    star1.vz = old_star.vz
    star2.vx = old_star.vx
    star2.vy = vel2 + old_star.vy
    star2.vz = old_star.vz
# Preform the Euler Rotation and Replace the Binary
    util.preform_EulerRotation(binary)
    star1.position = star1.position+rcm
    star2.position = star2.position+rcm
    return binary

def planetary_systems(stars, converter, num_systems, filename_planets, Earth=False, Jupiter=False, Neptune=False):
    ''' Creates several mock planetary systems around random stars in the provided set.
        stars: The AMUSE Particle Set containing stellar information.
        num_systems: The number of planetary systems requested.
        filename_planets: Filename for the Initial Planetary System HDF5 Archive.
        Earth, Jupiter, Neptune: Booleans asking if they should be included.
    '''
# Sets Initial Parameters
    num_stars = len(stars)
    select_stars_indices = rp.sample(xrange(0, num_stars), num_systems)
    i = 0
    ID_Earth = 3000000
    ID_Jupiter = 5000000
    ID_Neptune = 8000000
    systems = datamodel.Particles()
# Begins to Build Planetary Systems According to Provided Information
    for system in xrange(num_systems):
        planets = datamodel.Particles()
        j = select_stars_indices[system]
        if Earth:
            init_a = 1.000 | units.AU
            init_e = 0.016
            mass_E = 0.003 | units.MJupiter
            planets.add_particle(planet(ID_Earth+system, stars[j], mass_E, init_a, init_e))
        if Jupiter:
            init_a = 5.454 | units.AU
            init_e = 0.048
            mass_J = 1 | units.MJupiter
            planets.add_particle(planet(ID_Jupiter+system, stars[j], mass_J, init_a, init_e))
        if Neptune:
            init_a = 30.110 | units.AU
            init_e = 0.009
            mass_N = 0.054 | units.MJupiter
            planets.add_particle(planet(ID_Neptune+system, stars[j], mass_N, init_a, init_e))
    # Moves Planetary System to the Origin and Applies a Random Euler Rotation
        for p in planets:
            p.position = p.position - stars[j].position
            p.velocity = p.velocity - stars[j].velocity
        util.preform_EulerRotation(planets)
        for p in planets:
            p.position = p.position + stars[j].position
            p.velocity = p.velocity + stars[j].velocity
    # Adds the System to the Provided AMUSE Particle Set
        systems.add_particles(planets)
    return systems

def planet(ID, host_star, planet_mass, init_a, init_e, random_orientation=False):
    ''' Creates a planet as an AMUSE Particle with provided characteristics.
        ID: Identifying number unique to this planet.
        host_star: The AMUSE Particle that is the host star for the planet.
        planet_mass: The mass of the planet (in the nbody units).
        init_a: Initial semi-major axis (in nbody units).
        init_e: Initial eccentricity (in nbody units).
        random_orientation: Boolean to incline the planet in a random fashion.
    '''
# Sets Planet Values to Provided Conditions
    p = datamodel.Particle()
    p.id = ID
    p.type = "planet"
    p.host_star = host_star.id
    p.mass = planet_mass
# Calculates a Random Position in the Orbit & Gets the Orbital Speed
    cosTheta = math.cos(np.random.random()*math.pi*2)
    init_x = init_a*(1-init_e**2)/(1+init_e*cosTheta) # Need to Double Check ... Thornton 302
    init_vy = np.sqrt(units.constants.G*host_star.mass*(2/init_x-1/init_a))
# Sets the Dynamical Radius to the Hill Sphere Approx.
    p.radius = util.calc_HillRadius(init_a, init_e, p.mass, host_star.mass)
# Sets the Particle in "Orbit" Around the Origin
# May Need to Correct This Later to Accurately Depict Position in Orbit
    p.position = [init_x.number, 0.0 , 0.0] | init_x.unit
    p.velocity = [0.0 , init_vy.number, 0.0] | init_vy.unit
# Preforms a Euler Rotation on the Planet if Requested
# Not Working Properly due to Data Structure, Need to Fix
    if random_orientation:
        temp = datamodel.Particles().add_particle(p)
        util.preform_EulerRotation(temp)
        p = temp[0]
# Moves the Planet to Orbit the Host Star
    p.position = p.position + host_star.position
    p.velocity = p.velocity + host_star.velocity
# Returns the Created AMUSE Particle
    return p

MasterSet = datamodel.Particles()
# Create the Stellar Cluster, Shift from SI to NBody, Add the Particles to MS, & Open a Channel to the MS
stars_SI, converter = king_cluster(num_stars, 'test_stars', rand_seed=0, IBF=0.5)
stars_NB = datamodel.ParticlesWithUnitsConverted(stars_SI, converter.as_converter_from_nbody_to_si())
MasterSet.add_particles(stars_NB)
#channel_stars_master = stars_NB.new_channel_to(MasterSet)
# Create Planetary Systems, Shift from SI to NBody, Add the Particles to MS, & Open a Channel to the MS
systems_SI = planetary_systems(stars_SI, converter, num_psys, 'test_planets', Jupiter=True)
systems_NB = datamodel.ParticlesWithUnitsConverted(systems_SI, converter.as_converter_from_nbody_to_si())
MasterSet.add_particles(systems_NB)

print MasterSet

time = 0.0 | nbody_system.time
delta_t = 0.05 | nbody_system.time
number_of_steps = 10
end_time = number_of_steps*delta_t
num_workers = 1
eps2 = 0.0 | nbody_system.length**2
use_gpu = 1
gpu_ID = -1

    # Setting PH4 as the Top-Level Gravity Code
if use_gpu == 1:
    gravity = ph4(number_of_workers = num_workers, redirection = "none", mode = "gpu")
#try:
    #gravity = ph4(number_of_workers = num_workers, redirection = "none", mode = "gp$
#except Exception as ex:
#    gravity = ph4(number_of_workers = num_workers, redirection = "none")
#    print "*** GPU worker code not found. Reverting to non-GPU code. ***"
else:
    gravity = grav(number_of_workers = num_workers, redirection = "none")

# Initializing PH4 with Initial Conditions
gravity.initialize_code()
gravity.parameters.set_defaults()
gravity.parameters.begin_time = time
gravity.parameters.epsilon_squared = eps2
gravity.parameters.timestep_parameter = delta_t.number

# Setting up the Code to Run with GPUs Provided by Command Line
gravity.parameters.use_gpu = use_gpu
gravity.parameters.gpu_id = gpu_ID

# Setting Up the Stopping Conditions in PH4
stopping_condition = gravity.stopping_conditions.collision_detection
stopping_condition.enable()
sys.stdout.flush()

# Adding and Committing Particles to PH4
gravity.particles.add_particles(MasterSet)
gravity.commit_particles()

# Starting the AMUSE Channel for PH4
grav_channel = gravity.particles.new_channel_to(MasterSet)

# Initializing Kepler and SmallN
kep = Kepler(None, redirection = "none")
kep.initialize_code()
util.init_smalln()

# Initializing MULTIPLES
multiples_code = multiples.Multiples(gravity, util.new_smalln, kep)
multiples_code.neighbor_distance_factor = 1.0
multiples_code.neighbor_veto = True

multiples_code.evolve_model(time)
gravity.synchronize_model()
# Copy values from the module to the set in memory.
grav_channel.copy()

# Copy the index (ID) as used in the module to the id field in
# memory.  The index is not copied by default, as different
# codes may have different indices for the same particle and
# we don't want to overwrite silently.
grav_channel.copy_attribute("index_in_code", "id")

write.write_state_to_file(time, MasterSet, gravity, multiples_code, write_file)

gravity.stop()
kep.stop()
util.stop_smalln()

# Setting PH4 as the Top-Level Gravity Code
if use_gpu == 1:
    gravity = ph4(number_of_workers = num_workers, redirection = "none", mode = "gpu")
else:
    gravity = grav(number_of_workers = num_workers, redirection = "none")

# Initializing PH4 with Initial Conditions
gravity.initialize_code()
gravity.parameters.set_defaults()
gravity.parameters.begin_time = time
gravity.parameters.epsilon_squared = eps2
gravity.parameters.timestep_parameter = delta_t.number

# Setting up the Code to Run with GPUs Provided by Command Line
gravity.parameters.use_gpu = use_gpu
gravity.parameters.gpu_id = gpu_ID

# Initializing Kepler and SmallN
kep = Kepler(None, redirection = "none")
kep.initialize_code()
util.init_smalln()

MasterSet2 = []
MasterSet2, multiples_code = read.read_state_from_file(restart_file, gravity, kep, util.new_smalln)

if np.array_equal(MasterSet, MasterSet2):
    print "It worked!"
print "Finished!"

print MasterSet
print MasterSet2
<commit_msg>Delete restart_test.py<commit_after><|endoftext|>


<commit_before># Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.

from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QUrl

from UM.Application import Application
from UM.PluginRegistry import PluginRegistry

from . import ContainerProxy

import os.path

class ActiveToolProxy(QObject):
    def __init__(self, parent = None):
        super().__init__(parent)

        self._active_tool = None
        Application.getInstance().getController().activeToolChanged.connect(self._onActiveToolChanged)
        self._onActiveToolChanged()

        self._properties = { }
        self._properties_proxy = ContainerProxy.ContainerProxy(self._properties)

    activeToolChanged = pyqtSignal()
    #propertyChanged = pyqtSignal()

    @pyqtProperty(bool, notify = activeToolChanged)
    def valid(self):
        return self._active_tool != None

    @pyqtProperty(QUrl, notify = activeToolChanged)
    def activeToolPanel(self):
        if not self._active_tool:
            return QUrl()

        try:
            panel_file = PluginRegistry.getInstance().getMetaData(self._active_tool.getPluginId())["tool"]["tool_panel"]
        except KeyError:
            return QUrl()

        return QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self._active_tool.getPluginId()), panel_file))

    @pyqtSlot(str)
    def triggerAction(self, action):
        if not self._active_tool:
            return

        action = getattr(self._active_tool, action)
        if action:
            action()

    propertiesChanged = pyqtSignal()
    @pyqtProperty(QObject, notify = propertiesChanged)
    def properties(self):
        return self._properties_proxy;

    @pyqtSlot(str, "QVariant")
    def setProperty(self, property, value):
        if not self._active_tool:
            return
        if hasattr(self._active_tool, "set" + property):
            option_setter = getattr(self._active_tool, "set" + property)
            if option_setter:
                option_setter(value)

        if hasattr(self._active_tool, property):
            setattr(self._active_tool, property, value)

    def _onPropertyChanged(self):
        self._updateProperties()

    def _onActiveToolChanged(self):
        if self._active_tool:
            self._active_tool.propertyChanged.disconnect(self._onPropertyChanged)

        self._active_tool = Application.getInstance().getController().getActiveTool()
        if self._active_tool is not None:
            self._active_tool.propertyChanged.connect(self._onPropertyChanged)
            self._updateProperties()

        self.activeToolChanged.emit()

    def _updateProperties(self):
        self._properties.clear()

        for name in self._active_tool.getExposedProperties():
            property_getter = getattr(self._active_tool, "get" + name)
            if property_getter:
                self._properties[name] = property_getter()

            if hasattr(self._active_tool, name):
                self._properties[name] = getattr(self._active_tool, name)

        self.propertiesChanged.emit()

def createActiveToolProxy(engine, script_engine):
    return ActiveToolProxy()
<commit_msg>Removed commented signal<commit_after># Copyright (c) 2015 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher.

from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject, QUrl

from UM.Application import Application
from UM.PluginRegistry import PluginRegistry

from . import ContainerProxy

import os.path

class ActiveToolProxy(QObject):
    def __init__(self, parent = None):
        super().__init__(parent)

        self._active_tool = None
        Application.getInstance().getController().activeToolChanged.connect(self._onActiveToolChanged)
        self._onActiveToolChanged()

        self._properties = { }
        self._properties_proxy = ContainerProxy.ContainerProxy(self._properties)

    activeToolChanged = pyqtSignal()

    @pyqtProperty(bool, notify = activeToolChanged)
    def valid(self):
        return self._active_tool != None

    @pyqtProperty(QUrl, notify = activeToolChanged)
    def activeToolPanel(self):
        if not self._active_tool:
            return QUrl()

        try:
            panel_file = PluginRegistry.getInstance().getMetaData(self._active_tool.getPluginId())["tool"]["tool_panel"]
        except KeyError:
            return QUrl()

        return QUrl.fromLocalFile(os.path.join(PluginRegistry.getInstance().getPluginPath(self._active_tool.getPluginId()), panel_file))

    @pyqtSlot(str)
    def triggerAction(self, action):
        if not self._active_tool:
            return

        action = getattr(self._active_tool, action)
        if action:
            action()

    propertiesChanged = pyqtSignal()
    @pyqtProperty(QObject, notify = propertiesChanged)
    def properties(self):
        return self._properties_proxy;

    @pyqtSlot(str, "QVariant")
    def setProperty(self, property, value):
        if not self._active_tool:
            return
        if hasattr(self._active_tool, "set" + property):
            option_setter = getattr(self._active_tool, "set" + property)
            if option_setter:
                option_setter(value)

        if hasattr(self._active_tool, property):
            setattr(self._active_tool, property, value)

    def _onPropertyChanged(self):
        self._updateProperties()

    def _onActiveToolChanged(self):
        if self._active_tool:
            self._active_tool.propertyChanged.disconnect(self._onPropertyChanged)

        self._active_tool = Application.getInstance().getController().getActiveTool()
        if self._active_tool is not None:
            self._active_tool.propertyChanged.connect(self._onPropertyChanged)
            self._updateProperties()

        self.activeToolChanged.emit()

    def _updateProperties(self):
        self._properties.clear()

        for name in self._active_tool.getExposedProperties():
            property_getter = getattr(self._active_tool, "get" + name)
            if property_getter:
                self._properties[name] = property_getter()

            if hasattr(self._active_tool, name):
                self._properties[name] = getattr(self._active_tool, name)

        self.propertiesChanged.emit()

def createActiveToolProxy(engine, script_engine):
    return ActiveToolProxy()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""Core functionality."""

#-------------------------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------------------------

from collections import defaultdict
import glob
import inspect
import logging
import os.path as op

from .utils import Bunch, load_text, dump_text, _create_dir_if_not_exists
from .plugin import get_plugins

logger = logging.getLogger(__name__)

#-------------------------------------------------------------------------------------------------
# Graph routines
#-------------------------------------------------------------------------------------------------

def _graph_from_edges(edges):
    """Return the adjacency list of a graph defined by a list of edges."""
    g = defaultdict(set)
    for a, b in edges:
        g[a].add(b)
    return g

def _bfs_paths(graph, start, target):
    """Generate paths from start to target."""
    # http://eddmann.com/posts/depth-first-search-and-breadth-first-search-in-python/  # noqa
    queue = [(start, [start])]
    while queue:
        (vertex, path) = queue.pop(0)
        for next in graph[vertex] - set(path):
            if next == target:
                yield path + [next]
            else:
                queue.append((next, path + [next]))

def _bfs_component(graph, start):
    visited, queue = set(), [start]
    while queue:
        vertex = queue.pop(0)
        if vertex not in visited:
            visited.add(vertex)
            queue.extend(graph[vertex] - visited)
    return visited

def _find_path(edges, start, target):
    """Return a shortest path in a graph defined by a list of edges."""
    graph = _graph_from_edges(edges)
    try:
        return next(_bfs_paths(graph, start, target))
    except StopIteration:
        return None

def _connected_component(edges, start):
    graph = _graph_from_edges(edges)
    # We remove the start from the component.
    return sorted(_bfs_component(graph, start) - set([start]))

#-------------------------------------------------------------------------------------------------
# Main class
#-------------------------------------------------------------------------------------------------

def _get_annotation(func, name):
    return getattr(func, '__annotations__', {}).get(name, None)

class Podoc(object):
    """Conversion pipeline for markup documents.

    This class implements the core conversion functionality of podoc.

    Parameters
    ----------

    plugins : list of str (None)
        List of plugins to load. By default, load all plugins found.
    with_pandoc : bool (True)
        Whether to load all pandoc conversion paths.

    """

    def __init__(self, plugins=None, with_pandoc=True):
        self._funcs = {}  # mapping `(lang0, lang1) => func`
        self._langs = {}  # mapping `lang: Bunch()`
        self._load_plugins(plugins, with_pandoc)

    def _load_plugins(self, plugins=None, with_pandoc=True):
        """Load plugins. By default (None), all plugins found are loaded."""
        # Load plugins.
        plugins = plugins if plugins is not None else get_plugins()
        for p in plugins:
            # Skip pandoc plugin.
            if not with_pandoc and p.__name__ == 'PandocPlugin':
                continue
            p().attach(self)

    # Main methods
    # --------------------------------------------------------------------------------------------

    def register_func(self, func=None, source=None, target=None,
                      pre_filter=None, post_filter=None,
                      ):
        """Register a conversion function between two languages."""
        if func is None:
            return lambda _: self.register_func(_, source=source,
                                                target=target)
        assert func
        assert 'context' in inspect.getargspec(func).args
        source = source or _get_annotation(func, 'source')
        target = target or _get_annotation(func, 'target')
        assert source
        assert target
        if (source, target) in self._funcs:
            logger.debug("Conversion `%s -> %s` already registered, skipping.",
                         source, target)
            return
        logger.log(5, "Register conversion `%s -> %s`.", source, target)
        self._funcs[(source, target)] = Bunch(func=func,
                                              pre_filter=pre_filter,
                                              post_filter=post_filter,
                                              )

    def register_lang(self, name, file_ext=None,
                      load_func=None, dump_func=None,
                      loads_func=None, dumps_func=None,
                      eq_filter=None,
                      **kwargs):
        """Register a language with a file extension and load/dump
        functions."""
        if file_ext:
            assert file_ext.startswith('.')
        if name in self._langs:
            logger.log(5, "Language `%s` already registered, skipping.", name)
            return
        logger.log(5, "Register language `%s`.", name)
        # Default parameters.
        load_func = load_func or load_text
        dump_func = dump_func or dump_text
        loads_func = loads_func or (lambda _: _)
        dumps_func = dumps_func or (lambda _: _)
        self._langs[name] = Bunch(file_ext=file_ext,
                                  load_func=load_func,
                                  dump_func=dump_func,
                                  loads_func=loads_func,
                                  dumps_func=dumps_func,
                                  eq_filter=eq_filter,
                                  **kwargs)

    def _create_context(self, path=None, source=None, target=None, lang_chain=None,
                        output=None, output_dir=None,
                        ):

        # Infer source and target from lang_chain.
        if lang_chain is not None:
            assert len(lang_chain) >= 2
            source = lang_chain[0]
            target = lang_chain[-1]

        # Use real paths.
        if path is not None:
            path = op.realpath(path)
        if output is not None:
            output = op.realpath(output)
        if output_dir is not None:
            output_dir = op.realpath(output_dir)

        # NOTE: 'json' is an alias for 'ast', to match with pandoc's terminology.
        source = source if source != 'json' else 'ast'
        target = target if target != 'json' else 'ast'

        # If the output is specified and not the target, infer the target
        # from the file extension.
        if target is None and output is not None:
            target = self.get_lang_for_file_ext(op.splitext(output)[1])
        assert target

        # NOTE: decide whether the object is a path or contents string.
        if path is not None:
            if not op.exists(path):
                raise ValueError("File %s does not exist.", path)
            # Get the source from the file extension
            if source is None and lang_chain is None:
                source = self.get_lang_for_file_ext(op.splitext(path)[1])
        assert source

        # At this point, we should have a non-empty object.
        if lang_chain is None:
            # Find the shortest path from source to target in the conversion graph.
            assert source and target
            lang_chain = _find_path(self.conversion_pairs,
                                    source, target)
            if not lang_chain:
                raise ValueError("No path found from `{}` to `{}`.".format(
                                 source, target))
        assert isinstance(lang_chain, (tuple, list))

        # Process output_dir.
        if path and output_dir:
            _create_dir_if_not_exists(output_dir)
            extension = self.get_file_ext(target)
            # Construct the output filename.
            output = op.join(output_dir, op.splitext(op.basename(path))[0] + extension)

        return Bunch(path=path, source=source, target=target,
                     lang_chain=lang_chain, output=output)

    def _make_conversion(self, obj, context):
        # Iterate over all successive pairs.
        for t0, t1 in zip(context.lang_chain, context.lang_chain[1:]):
            # Get the function registered for t0, t1.
            fd = self._funcs.get((t0, t1), None)
            if not fd:
                raise ValueError("No function registered for `{}` => `{}`.".
                                 format(t0, t1))
            f = fd.func
            # Pre-filter.
            obj = fd.pre_filter(obj, context=context) if fd.pre_filter else obj
            # Perform the conversion.
            obj = f(obj, context=context)
            # Post-filter.
            obj = fd.post_filter(obj, context=context) if fd.post_filter else obj
        return obj

    def _convert_from_context(self, obj_or_path, context, is_path=None, do_append=None):
        # Load the object from disk if necessary.
        obj = self.load(obj_or_path, context.source, context=context) if is_path else obj_or_path
        # Make the conversion in memory.
        obj = self._make_conversion(obj, context)
        # Save the file, unless the conversion function did it (output_file_required).
        if context.output and not context.get('output_file_required', None):
            output_dir = op.dirname(context.output)
            _create_dir_if_not_exists(output_dir)
            self.dump(obj, context.output, lang=context.target,
                      context=context, do_append=do_append)
        return obj

    def convert_text(self, text, source=None, target=None, lang_chain=None,
                     output=None, output_dir=None,
                     return_context=False):
        # Create the context object.
        context = self._create_context(source=source, target=target, lang_chain=lang_chain,
                                       output=output, output_dir=output_dir,)
        obj = self._convert_from_context(text, context, is_path=False)
        if return_context:
            return obj, context
        return obj

    def convert_files(self, paths, source=None, target=None, lang_chain=None,
                      output=None, output_dir=None):
        """Convert a file by passing it through a chain of conversion functions."""
        contexts = []
        for i, path in enumerate(paths):
            # Create the context object.
            context = self._create_context(path=path, source=source, target=target,
                                           lang_chain=lang_chain,
                                           output=output, output_dir=output_dir,
                                           )
            logger.debug("Converting `%s` from %s to %s.", op.basename(context.path),
                         context.source, context.target)
            self._convert_from_context(context.path, context, is_path=True, do_append=i >= 1)
            contexts.append(context)
        return contexts

    def convert_file(self, path, source=None, target=None, lang_chain=None,
                     output=None, output_dir=None, return_context=False):
        # Create the context object.
        context = self._create_context(path=path, source=source, target=target,
                                       lang_chain=lang_chain,
                                       output=output, output_dir=output_dir,
                                       )
        logger.debug("Converting `%s` from %s to %s.", op.basename(context.path),
                     context.source, context.target)
        obj = self._convert_from_context(context.path, context, is_path=True)
        if return_context:
            return obj, context
        return obj

    def pre_filter(self, obj, source, target):
        fd = self._funcs.get((source, target), None)
        if fd and fd.pre_filter:
            return fd.pre_filter(obj)
        else:
            return obj

    # Properties
    # --------------------------------------------------------------------------------------------

    @property
    def languages(self):
        """List of all registered languages."""
        return sorted(self._langs)

    @property
    def file_extensions(self):
        """List of all registered file extensions."""
        return sorted(set(lang.file_ext for lang in self._langs.values()
                          if lang.file_ext))

    @property
    def conversion_pairs(self):
        """List of registered conversion pairs."""
        return sorted(self._funcs.keys())

    # File-related methods
    # --------------------------------------------------------------------------------------------

    def get_target_languages(self, lang):
        """List of languages to which a given language can be converted to."""
        return _connected_component(self.conversion_pairs, lang)

    def get_files_in_dir(self, path, lang=None):
        """Return the list of files of a given language in a directory."""
        assert path
        path = op.realpath(op.expanduser(path))
        assert op.exists(path)
        assert op.isdir(path)
        # Find the file extension for the given language.
        file_ext = (self._langs[lang].file_ext or '') if lang else ''
        filenames = glob.glob(op.join(path, '*' + file_ext))
        return [op.join(path, fn) for fn in filenames]

    def get_lang_for_file_ext(self, file_ext):
        """Get the language registered with a given file extension."""
        for name, b in self._langs.items():
            if b.file_ext == file_ext:
                return name
        raise ValueError(("The file extension `{}` hasn't been "
                          "registered.").format(file_ext))

    def get_file_ext(self, lang):
        """Return the file extension registered for a given language."""
        return self._langs[lang].file_ext

    def load(self, path, lang=None, context=None):
        """Load a file which has a registered file extension."""
        # Find the language corresponding to the file's extension.
        file_ext = op.splitext(path)[1]
        lang = lang or self.get_lang_for_file_ext(file_ext)
        func = self._langs[lang].load_func
        kwargs = {'context': context} if 'context' in inspect.getargspec(func).args else {}
        # Load the file using the function registered for the language.
        return func(path, **kwargs)

    def dump(self, contents, path, lang=None, context=None, do_append=None):
        """Dump an object to a file."""
        # Find the language corresponding to the file's extension.
        file_ext = op.splitext(path)[1]
        lang = lang or self.get_lang_for_file_ext(file_ext)
        func = self._langs[lang].dump_func
        kwargs = {'context': context} if 'context' in inspect.getargspec(func).args else {}
        if 'do_append' in inspect.getargspec(func).args:
            kwargs.update({'do_append': do_append})
        # Dump the file using the function registered for the language.
        return func(contents, path, **kwargs)

    def loads(self, s, lang=None):
        """Load an object from its string representation."""
        assert lang
        # Load the string using the function registered for the language.
        return self._langs[lang].loads_func(s)

    def dumps(self, contents, lang=None):
        """Dump an object to a string."""
        assert lang
        # Dump the string using the function registered for the language.
        return self._langs[lang].dumps_func(contents)

    def assert_equal(self, obj0, obj1, lang=None):
        """Assert that two objects are equal."""
        assert lang
        f = self._langs[lang].eq_filter
        if not f:
            assert obj0 == obj1
            return
        assert f(obj0) == f(obj1)
<commit_msg>Fix convert_files() return result<commit_after># -*- coding: utf-8 -*-

"""Core functionality."""

#-------------------------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------------------------

from collections import defaultdict
import glob
import inspect
import logging
import os.path as op

from .utils import Bunch, load_text, dump_text, _create_dir_if_not_exists
from .plugin import get_plugins

logger = logging.getLogger(__name__)

#-------------------------------------------------------------------------------------------------
# Graph routines
#-------------------------------------------------------------------------------------------------

def _graph_from_edges(edges):
    """Return the adjacency list of a graph defined by a list of edges."""
    g = defaultdict(set)
    for a, b in edges:
        g[a].add(b)
    return g

def _bfs_paths(graph, start, target):
    """Generate paths from start to target."""
    # http://eddmann.com/posts/depth-first-search-and-breadth-first-search-in-python/  # noqa
    queue = [(start, [start])]
    while queue:
        (vertex, path) = queue.pop(0)
        for next in graph[vertex] - set(path):
            if next == target:
                yield path + [next]
            else:
                queue.append((next, path + [next]))

def _bfs_component(graph, start):
    visited, queue = set(), [start]
    while queue:
        vertex = queue.pop(0)
        if vertex not in visited:
            visited.add(vertex)
            queue.extend(graph[vertex] - visited)
    return visited

def _find_path(edges, start, target):
    """Return a shortest path in a graph defined by a list of edges."""
    graph = _graph_from_edges(edges)
    try:
        return next(_bfs_paths(graph, start, target))
    except StopIteration:
        return None

def _connected_component(edges, start):
    graph = _graph_from_edges(edges)
    # We remove the start from the component.
    return sorted(_bfs_component(graph, start) - set([start]))

#-------------------------------------------------------------------------------------------------
# Main class
#-------------------------------------------------------------------------------------------------

def _get_annotation(func, name):
    return getattr(func, '__annotations__', {}).get(name, None)

class Podoc(object):
    """Conversion pipeline for markup documents.

    This class implements the core conversion functionality of podoc.

    Parameters
    ----------

    plugins : list of str (None)
        List of plugins to load. By default, load all plugins found.
    with_pandoc : bool (True)
        Whether to load all pandoc conversion paths.

    """

    def __init__(self, plugins=None, with_pandoc=True):
        self._funcs = {}  # mapping `(lang0, lang1) => func`
        self._langs = {}  # mapping `lang: Bunch()`
        self._load_plugins(plugins, with_pandoc)

    def _load_plugins(self, plugins=None, with_pandoc=True):
        """Load plugins. By default (None), all plugins found are loaded."""
        # Load plugins.
        plugins = plugins if plugins is not None else get_plugins()
        for p in plugins:
            # Skip pandoc plugin.
            if not with_pandoc and p.__name__ == 'PandocPlugin':
                continue
            p().attach(self)

    # Main methods
    # --------------------------------------------------------------------------------------------

    def register_func(self, func=None, source=None, target=None,
                      pre_filter=None, post_filter=None,
                      ):
        """Register a conversion function between two languages."""
        if func is None:
            return lambda _: self.register_func(_, source=source,
                                                target=target)
        assert func
        assert 'context' in inspect.getargspec(func).args
        source = source or _get_annotation(func, 'source')
        target = target or _get_annotation(func, 'target')
        assert source
        assert target
        if (source, target) in self._funcs:
            logger.debug("Conversion `%s -> %s` already registered, skipping.",
                         source, target)
            return
        logger.log(5, "Register conversion `%s -> %s`.", source, target)
        self._funcs[(source, target)] = Bunch(func=func,
                                              pre_filter=pre_filter,
                                              post_filter=post_filter,
                                              )

    def register_lang(self, name, file_ext=None,
                      load_func=None, dump_func=None,
                      loads_func=None, dumps_func=None,
                      eq_filter=None,
                      **kwargs):
        """Register a language with a file extension and load/dump
        functions."""
        if file_ext:
            assert file_ext.startswith('.')
        if name in self._langs:
            logger.log(5, "Language `%s` already registered, skipping.", name)
            return
        logger.log(5, "Register language `%s`.", name)
        # Default parameters.
        load_func = load_func or load_text
        dump_func = dump_func or dump_text
        loads_func = loads_func or (lambda _: _)
        dumps_func = dumps_func or (lambda _: _)
        self._langs[name] = Bunch(file_ext=file_ext,
                                  load_func=load_func,
                                  dump_func=dump_func,
                                  loads_func=loads_func,
                                  dumps_func=dumps_func,
                                  eq_filter=eq_filter,
                                  **kwargs)

    def _create_context(self, path=None, source=None, target=None, lang_chain=None,
                        output=None, output_dir=None,
                        ):

        # Infer source and target from lang_chain.
        if lang_chain is not None:
            assert len(lang_chain) >= 2
            source = lang_chain[0]
            target = lang_chain[-1]

        # Use real paths.
        if path is not None:
            path = op.realpath(path)
        if output is not None:
            output = op.realpath(output)
        if output_dir is not None:
            output_dir = op.realpath(output_dir)

        # NOTE: 'json' is an alias for 'ast', to match with pandoc's terminology.
        source = source if source != 'json' else 'ast'
        target = target if target != 'json' else 'ast'

        # If the output is specified and not the target, infer the target
        # from the file extension.
        if target is None and output is not None:
            target = self.get_lang_for_file_ext(op.splitext(output)[1])
        assert target

        # NOTE: decide whether the object is a path or contents string.
        if path is not None:
            if not op.exists(path):
                raise ValueError("File %s does not exist.", path)
            # Get the source from the file extension
            if source is None and lang_chain is None:
                source = self.get_lang_for_file_ext(op.splitext(path)[1])
        assert source

        # At this point, we should have a non-empty object.
        if lang_chain is None:
            # Find the shortest path from source to target in the conversion graph.
            assert source and target
            lang_chain = _find_path(self.conversion_pairs,
                                    source, target)
            if not lang_chain:
                raise ValueError("No path found from `{}` to `{}`.".format(
                                 source, target))
        assert isinstance(lang_chain, (tuple, list))

        # Process output_dir.
        if path and output_dir:
            _create_dir_if_not_exists(output_dir)
            extension = self.get_file_ext(target)
            # Construct the output filename.
            output = op.join(output_dir, op.splitext(op.basename(path))[0] + extension)

        return Bunch(path=path, source=source, target=target,
                     lang_chain=lang_chain, output=output)

    def _make_conversion(self, obj, context):
        # Iterate over all successive pairs.
        for t0, t1 in zip(context.lang_chain, context.lang_chain[1:]):
            # Get the function registered for t0, t1.
            fd = self._funcs.get((t0, t1), None)
            if not fd:
                raise ValueError("No function registered for `{}` => `{}`.".
                                 format(t0, t1))
            f = fd.func
            # Pre-filter.
            obj = fd.pre_filter(obj, context=context) if fd.pre_filter else obj
            # Perform the conversion.
            obj = f(obj, context=context)
            # Post-filter.
            obj = fd.post_filter(obj, context=context) if fd.post_filter else obj
        return obj

    def _convert_from_context(self, obj_or_path, context, is_path=None, do_append=None):
        # Load the object from disk if necessary.
        obj = self.load(obj_or_path, context.source, context=context) if is_path else obj_or_path
        # Make the conversion in memory.
        obj = self._make_conversion(obj, context)
        # Save the file, unless the conversion function did it (output_file_required).
        if context.output and not context.get('output_file_required', None):
            output_dir = op.dirname(context.output)
            _create_dir_if_not_exists(output_dir)
            self.dump(obj, context.output, lang=context.target,
                      context=context, do_append=do_append)
        return obj

    def convert_text(self, text, source=None, target=None, lang_chain=None,
                     output=None, output_dir=None,
                     return_context=False):
        # Create the context object.
        context = self._create_context(source=source, target=target, lang_chain=lang_chain,
                                       output=output, output_dir=output_dir,)
        obj = self._convert_from_context(text, context, is_path=False)
        if return_context:
            return obj, context
        return obj

    def convert_files(self, paths, source=None, target=None, lang_chain=None,
                      output=None, output_dir=None):
        """Convert a file by passing it through a chain of conversion functions."""
        objs = []
        for i, path in enumerate(paths):
            # Create the context object.
            context = self._create_context(path=path, source=source, target=target,
                                           lang_chain=lang_chain,
                                           output=output, output_dir=output_dir,
                                           )
            logger.debug("Converting `%s` from %s to %s.", op.basename(context.path),
                         context.source, context.target)
            obj = self._convert_from_context(context.path, context,
                                             is_path=True, do_append=i >= 1)
            objs.append(obj)
        return objs[0] if objs and len(objs) else objs

    def convert_file(self, path, source=None, target=None, lang_chain=None,
                     output=None, output_dir=None, return_context=False):
        # Create the context object.
        context = self._create_context(path=path, source=source, target=target,
                                       lang_chain=lang_chain,
                                       output=output, output_dir=output_dir,
                                       )
        logger.debug("Converting `%s` from %s to %s.", op.basename(context.path),
                     context.source, context.target)
        obj = self._convert_from_context(context.path, context, is_path=True)
        if return_context:
            return obj, context
        return obj

    def pre_filter(self, obj, source, target):
        fd = self._funcs.get((source, target), None)
        if fd and fd.pre_filter:
            return fd.pre_filter(obj)
        else:
            return obj

    # Properties
    # --------------------------------------------------------------------------------------------

    @property
    def languages(self):
        """List of all registered languages."""
        return sorted(self._langs)

    @property
    def file_extensions(self):
        """List of all registered file extensions."""
        return sorted(set(lang.file_ext for lang in self._langs.values()
                          if lang.file_ext))

    @property
    def conversion_pairs(self):
        """List of registered conversion pairs."""
        return sorted(self._funcs.keys())

    # File-related methods
    # --------------------------------------------------------------------------------------------

    def get_target_languages(self, lang):
        """List of languages to which a given language can be converted to."""
        return _connected_component(self.conversion_pairs, lang)

    def get_files_in_dir(self, path, lang=None):
        """Return the list of files of a given language in a directory."""
        assert path
        path = op.realpath(op.expanduser(path))
        assert op.exists(path)
        assert op.isdir(path)
        # Find the file extension for the given language.
        file_ext = (self._langs[lang].file_ext or '') if lang else ''
        filenames = glob.glob(op.join(path, '*' + file_ext))
        return [op.join(path, fn) for fn in filenames]

    def get_lang_for_file_ext(self, file_ext):
        """Get the language registered with a given file extension."""
        for name, b in self._langs.items():
            if b.file_ext == file_ext:
                return name
        raise ValueError(("The file extension `{}` hasn't been "
                          "registered.").format(file_ext))

    def get_file_ext(self, lang):
        """Return the file extension registered for a given language."""
        return self._langs[lang].file_ext

    def load(self, path, lang=None, context=None):
        """Load a file which has a registered file extension."""
        # Find the language corresponding to the file's extension.
        file_ext = op.splitext(path)[1]
        lang = lang or self.get_lang_for_file_ext(file_ext)
        func = self._langs[lang].load_func
        kwargs = {'context': context} if 'context' in inspect.getargspec(func).args else {}
        # Load the file using the function registered for the language.
        return func(path, **kwargs)

    def dump(self, contents, path, lang=None, context=None, do_append=None):
        """Dump an object to a file."""
        # Find the language corresponding to the file's extension.
        file_ext = op.splitext(path)[1]
        lang = lang or self.get_lang_for_file_ext(file_ext)
        func = self._langs[lang].dump_func
        kwargs = {'context': context} if 'context' in inspect.getargspec(func).args else {}
        if 'do_append' in inspect.getargspec(func).args:
            kwargs.update({'do_append': do_append})
        # Dump the file using the function registered for the language.
        return func(contents, path, **kwargs)

    def loads(self, s, lang=None):
        """Load an object from its string representation."""
        assert lang
        # Load the string using the function registered for the language.
        return self._langs[lang].loads_func(s)

    def dumps(self, contents, lang=None):
        """Dump an object to a string."""
        assert lang
        # Dump the string using the function registered for the language.
        return self._langs[lang].dumps_func(contents)

    def assert_equal(self, obj0, obj1, lang=None):
        """Assert that two objects are equal."""
        assert lang
        f = self._langs[lang].eq_filter
        if not f:
            assert obj0 == obj1
            return
        assert f(obj0) == f(obj1)
<|endoftext|>


<commit_before>#!/usr/bin/env python
import os
import re
import sys
import json
import time
import struct
import pprint
import logging
import requests
import argparse
import getpass
import csv
import time
import tkinter as tk

from collections import OrderedDict
from pokemondata import PokemonData
from pokeivwindow import PokeIVWindow

# add directory of this file to PATH, so that the package will be found
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

# import Pokemon Go API lib
from pgoapi import pgoapi
from pgoapi import utilities as util

# other stuff
from google.protobuf.internal import encoder
from geopy.geocoders import GoogleV3
from s2sphere import Cell, CellId, LatLng

log = logging.getLogger(__name__)
def setupLogger():
    # log settings
    # log format
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s')
    # log level for http request class
    logging.getLogger("requests").setLevel(logging.WARNING)
    # log level for main pgoapi class
    logging.getLogger("pgoapi").setLevel(logging.INFO)
    # log level for internal pgoapi class
    logging.getLogger("rpc_api").setLevel(logging.INFO)

def init_config():
    parser = argparse.ArgumentParser()
    config_file = "config.json"

    # If config file exists, load variables from json
    load   = {}
    if os.path.isfile(config_file):
        with open(config_file) as data:
            load.update(json.load(data))

    # Read passed in Arguments
    required = lambda x: not x in load
    parser.add_argument("-a", "--auth_service", help="Auth Service ('ptc' or 'google')",required=required("auth_service"))
    parser.add_argument("-u", "--username", help="Username", required=required("username"))
    parser.add_argument("-p", "--password", help="Password")
    parser.add_argument("-m", "--minimumIV", help="All pokemon equal to or above this IV value are kept regardless of duplicates")
    parser.add_argument("-me", "--max_evolutions", help="Maximum number of evolutions in one pass")
    parser.add_argument("-ed", "--evolution_delay", help="delay between evolutions in seconds")
    parser.add_argument("-td", "--transfer_delay", help="delay between transfers in seconds")
    parser.add_argument("-hm", "--hard_minimum", help="transfer candidates will be selected if they are below minimumIV (will transfer unique pokemon)", action="store_true")
    parser.add_argument("-cp", "--cp_override", help="will keep pokemon that have CP equal to or above the given limit, regardless of IV")
    parser.add_argument("-v", "--verbose", help="displays additional information about each pokemon", action="store_true")
    parser.add_argument("-el", "--evolve_list", help="Evolve lsit has been deprecated. Please use white list instead (-wl).", action="append")
    parser.add_argument("-wl", "--white_list", help="list of the only pokemon to transfer and evolve by ID or name (ex: -wl 1 = -wl bulbasaur)", action="append")
    parser.add_argument("-bl", "--black_list", help="list of the pokemon not to transfer and evolve by ID or name (ex: -bl 1 = -bl bulbasaur)", action="append")
    parser.add_argument("-f", "--force", help="forces all pokemon not passing the IV threshold to be transfer candidates regardless of evolution", action="store_true")
    config = parser.parse_args()

    # Passed in arguments shoud trump
    for key in config.__dict__:
        if key in load and config.__dict__[key] is None and load[key]:
            if key == "black_list" or key == "white_list":
                config.__dict__[key] = str(load[key]).split(',')
            else:
                config.__dict__[key] = str(load[key])
        elif key in load and (type(config.__dict__[key]) == type(True)) and not config.__dict__[key] and load[key]: #if it's boolean and false
            if str(load[key]) == "True":
                config.__dict__[key] = True

    if config.__dict__["password"] is None:
        logging.info("Secure Password Input (if there is no password prompt, use --password <pw>):")
        config.__dict__["password"] = getpass.getpass()

    if config.auth_service not in ['ptc', 'google']:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    if config.__dict__["minimumIV"] is None:
        config.__dict__["minimumIV"] = "101"
    if config.__dict__["max_evolutions"] is None:
        config.__dict__["max_evolutions"] = "71"
    if config.__dict__["evolution_delay"] is None:
        config.__dict__["evolution_delay"] = "25"
    if config.__dict__["transfer_delay"] is None:
        config.__dict__["transfer_delay"] = "10"

    if config.white_list is not None and config.black_list is not None:
        logging.error("Black list and white list can not be used together.")
        return

    if config.evolve_list is not None:
        logging.error("Evolve lsit has been deprecated. Please use white list instead (-wl).")
        return

    if config.white_list is not None:
        config.white_list = [x.lower() for x in config.white_list]
    if config.black_list is not None:
        config.black_list = [x.lower() for x in config.black_list]

    return OrderedDict(sorted(vars(config).items())) #namespaces are annoying => sorted dict

def main():
    setupLogger()
    log.debug('Logger set up')

    config = init_config()
    if not config:
        return

    # instantiate pgoapi
    api = pgoapi.PGoApi()

    # -- dictionaries for pokedex, families, and evolution prices
    with open('names.tsv') as f:
        f.readline()
        pokedex = dict(csv.reader(f, delimiter='\t'))

    with open('families.tsv') as f:
        f.readline()
        family = dict(csv.reader(f, delimiter='\t'))

    with open('evolves.tsv') as f:
        f.readline()
        cost = dict(csv.reader(f, delimiter='\t'))

    data = PokemonData(pokedex, family, cost, config, api)

    main_window = tk.Tk()
    app = PokeIVWindow(config,data,api,master=main_window)
    app.mainloop()

if __name__ == '__main__':
    main()<commit_msg>using a new theme because I just realised it looked kind of bad on windows--changed button sizing too<commit_after>#!/usr/bin/env python
import os
import re
import sys
import json
import time
import struct
import pprint
import logging
import requests
import argparse
import getpass
import csv
import time

from tkinter import ttk
import tkinter as tk

from collections import OrderedDict
from pokemondata import PokemonData
from pokeivwindow import PokeIVWindow

# add directory of this file to PATH, so that the package will be found
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

# import Pokemon Go API lib
from pgoapi import pgoapi
from pgoapi import utilities as util

# other stuff
from google.protobuf.internal import encoder
from geopy.geocoders import GoogleV3
from s2sphere import Cell, CellId, LatLng

log = logging.getLogger(__name__)
def setupLogger():
    # log settings
    # log format
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(module)10s] [%(levelname)5s] %(message)s')
    # log level for http request class
    logging.getLogger("requests").setLevel(logging.WARNING)
    # log level for main pgoapi class
    logging.getLogger("pgoapi").setLevel(logging.INFO)
    # log level for internal pgoapi class
    logging.getLogger("rpc_api").setLevel(logging.INFO)

def init_config():
    parser = argparse.ArgumentParser()
    config_file = "config.json"

    # If config file exists, load variables from json
    load   = {}
    if os.path.isfile(config_file):
        with open(config_file) as data:
            load.update(json.load(data))

    # Read passed in Arguments
    required = lambda x: not x in load
    parser.add_argument("-a", "--auth_service", help="Auth Service ('ptc' or 'google')",required=required("auth_service"))
    parser.add_argument("-u", "--username", help="Username", required=required("username"))
    parser.add_argument("-p", "--password", help="Password")
    parser.add_argument("-m", "--minimumIV", help="All pokemon equal to or above this IV value are kept regardless of duplicates")
    parser.add_argument("-me", "--max_evolutions", help="Maximum number of evolutions in one pass")
    parser.add_argument("-ed", "--evolution_delay", help="delay between evolutions in seconds")
    parser.add_argument("-td", "--transfer_delay", help="delay between transfers in seconds")
    parser.add_argument("-hm", "--hard_minimum", help="transfer candidates will be selected if they are below minimumIV (will transfer unique pokemon)", action="store_true")
    parser.add_argument("-cp", "--cp_override", help="will keep pokemon that have CP equal to or above the given limit, regardless of IV")
    parser.add_argument("-v", "--verbose", help="displays additional information about each pokemon", action="store_true")
    parser.add_argument("-el", "--evolve_list", help="Evolve lsit has been deprecated. Please use white list instead (-wl).", action="append")
    parser.add_argument("-wl", "--white_list", help="list of the only pokemon to transfer and evolve by ID or name (ex: -wl 1 = -wl bulbasaur)", action="append")
    parser.add_argument("-bl", "--black_list", help="list of the pokemon not to transfer and evolve by ID or name (ex: -bl 1 = -bl bulbasaur)", action="append")
    parser.add_argument("-f", "--force", help="forces all pokemon not passing the IV threshold to be transfer candidates regardless of evolution", action="store_true")
    config = parser.parse_args()

    # Passed in arguments shoud trump
    for key in config.__dict__:
        if key in load and config.__dict__[key] is None and load[key]:
            if key == "black_list" or key == "white_list":
                config.__dict__[key] = str(load[key]).split(',')
            else:
                config.__dict__[key] = str(load[key])
        elif key in load and (type(config.__dict__[key]) == type(True)) and not config.__dict__[key] and load[key]: #if it's boolean and false
            if str(load[key]) == "True":
                config.__dict__[key] = True

    if config.__dict__["password"] is None:
        logging.info("Secure Password Input (if there is no password prompt, use --password <pw>):")
        config.__dict__["password"] = getpass.getpass()

    if config.auth_service not in ['ptc', 'google']:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    if config.__dict__["minimumIV"] is None:
        config.__dict__["minimumIV"] = "101"
    if config.__dict__["max_evolutions"] is None:
        config.__dict__["max_evolutions"] = "71"
    if config.__dict__["evolution_delay"] is None:
        config.__dict__["evolution_delay"] = "25"
    if config.__dict__["transfer_delay"] is None:
        config.__dict__["transfer_delay"] = "10"

    if config.white_list is not None and config.black_list is not None:
        logging.error("Black list and white list can not be used together.")
        return

    if config.evolve_list is not None:
        logging.error("Evolve lsit has been deprecated. Please use white list instead (-wl).")
        return

    if config.white_list is not None:
        config.white_list = [x.lower() for x in config.white_list]
    if config.black_list is not None:
        config.black_list = [x.lower() for x in config.black_list]

    return OrderedDict(sorted(vars(config).items())) #namespaces are annoying => sorted dict

def main():
    setupLogger()
    log.debug('Logger set up')

    config = init_config()
    if not config:
        return

    # instantiate pgoapi
    api = pgoapi.PGoApi()

    # -- dictionaries for pokedex, families, and evolution prices
    with open('names.tsv') as f:
        f.readline()
        pokedex = dict(csv.reader(f, delimiter='\t'))

    with open('families.tsv') as f:
        f.readline()
        family = dict(csv.reader(f, delimiter='\t'))

    with open('evolves.tsv') as f:
        f.readline()
        cost = dict(csv.reader(f, delimiter='\t'))

    data = PokemonData(pokedex, family, cost, config, api)

    main_window = tk.Tk()

    main_window.style = ttk.Style()
    main_window.style.theme_use("classic")

    app = PokeIVWindow(config,data,api,master=main_window)
    app.mainloop()

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


<commit_before># -*- coding: utf-8 -*-

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import gzip
import math
import os
import platform
import re

import six

_INFO_HELP = """Memory subsystem
===============================================================================
`hwk.memory.Info` attributes:

total_physical_bytes (int)

  Number of bytes of physical RAM available to the system

total_usable_bytes (int)

  Number of bytes usable by the system (physical bytes minus a few bits
  reserved for system and the resident kernel size)

supported_page_sizes (set of int)

  A set of ints indicating memory page sizes the system can utilize, in bytes
"""

class Info(object):
    """Object describing the memory information about a system."""

    def __init__(self):
        self.total_physical_bytes = None
        self.total_usable_bytes = None
        self.supported_page_sizes = None

    def __repr__(self):
        tpb = 'unknown'
        if self.total_physical_bytes is not None:
            tpb = math.floor(self.total_physical_bytes / (1024 * 1024))
            tpb = six.text_type(tpb) + ' MB'
        tub = 'unknown'
        if self.total_usable_bytes is not None:
            tub = math.floor(self.total_usable_bytes / (1024 * 1024))
            tub = six.text_type(tub) + ' MB'
        return "memory (%s physical, %s usable)" % (tpb, tub)

    def describe(self):
        return _INFO_HELP

def supported_page_sizes():
    """Returns a set() containing the memory page sizes, in KB, supported by
    the host, or None if the page sizes could not be determined.
    """
    try:
        return {
            "Linux": _linux_supported_page_sizes,
        }[platform.system()]()
    except KeyError:
        return None

def _linux_supported_page_sizes():
    # In Linux, /sys/kernel/mm/hugepages contains a directory per page size
    # supported by the kernel. The directory name corresponds to the pattern
    # 'hugepages-{pagesize}kb'
    hp_dir = '/sys/kernel/mm/hugepages'
    return set([int(parts.split('-')[1][0:-2]) for parts in os.listdir(hp_dir)
                if os.path.isdir(os.path.join(hp_dir, parts))])

def total_physical_bytes():
    """Returns the total physical memory in bytes or None if the information
    could not be determined.
    """
    try:
        return {
            "Linux": _linux_total_physical_bytes,
        }[platform.system()]()
    except KeyError:
        return None

# System log lines will look similar to the following:
# ... kernel: [0.000000] Memory: 24633272K/25155024K ...
_SYSLOG_MEM_LINE_RE = re.compile(r'Memory:\s+\d+K\/(\d+)K')

def _linux_total_physical_bytes():
    # In Linux, the total physical memory can be determined by looking at the
    # output of dmidecode, however dmidecode requires root privileges to run,
    # so instead we examine the system logs for startup information containing
    # total physical memory and cache the results of this.
    def _find_physical_kb(line):
        matched = _SYSLOG_MEM_LINE_RE.search(six.text_type(line))
        if matched:
            return int(matched.group(1)) * 1024
        return None

    log_dir = '/var/log'
    log_files = sorted([
        filename for filename in os.listdir(log_dir)
        # /var/log will contain a file called syslog and 0 or more files called
        # syslog.$NUMBER or syslog.$NUMBER.gz containing system log records. We
        # search each, stopping when we match a system log record line that
        # contains physical memory information.
        if filename.startswith('syslog')
    ])

    for filename in log_files:
        unzip = filename.endswith('.gz')
        if unzip:
            opener = gzip.open
        else:
            opener = open

        try:
            path = os.path.join(log_dir, filename)
            with opener(path, 'rb') as f:
                for line in f.readlines():
                    size = _find_physical_kb(line)
                    if size is not None:
                        return size
        except IOError:
            return None
    return None

def info():
    """Returns a `hwk.memory.Info` object containing information on the memory
    available to the system, or None if the information could not be
    determined.
    """
    return {
        "Linux": _linux_info,
    }[platform.system()]()

def _linux_info():
    # In Linux, /proc/meminfo contains a set of memory-related amounts, with
    # lines looking like the following:
    #
    # $ cat /proc/meminfo
    # MemTotal:       24677596 kB
    # MemFree:        21244356 kB
    # MemAvailable:   22085432 kB
    # ...
    # HugePages_Total:       0
    # HugePages_Free:        0
    # HugePages_Rsvd:        0
    # HugePages_Surp:        0
    # ...
    #
    # It's worth noting that /proc/meminfo returns exact information, not
    # "theoretical" information. For instance, on the above system, I have 24GB
    # of RAM but MemTotal is indicating only around 23GB. This is because
    # MemTotal contains the exact amount of *usable* memory after accounting
    # for the kernel's resident memory size and a few reserved bits. For more
    # information, see:
    #
    #  https://www.kernel.org/doc/Documentation/filesystems/proc.txt
    mem_filepath = '/proc/meminfo'
    meminfo_lines = open(mem_filepath, 'rb').readlines()
    values = {}
    for line in meminfo_lines:
        parts = line.split()
        key = parts[0].strip(six.b(': '))
        value = int(parts[1].strip())
        in_kb = (len(parts) == 3 and parts[2].strip() == 'kB')
        if in_kb:
            value = value * 1024
        values[key] = value

    res = Info()
    res.supported_page_sizes = _linux_supported_page_sizes()
    tub = values[six.b('MemTotal')]
    tpb = _linux_total_physical_bytes()
    if tpb is None:
        msg = """
WARNING: Could not determine total physical bytes of memory. This may be due to
the host being a virtual machine or container with no /var/log/syslog file, or
the current user may not have necessary privileges to read the syslog. We are
falling back to setting the total physical amount of memory to the total usable
amount of memory
"""

        print(os.stderr, msg)
        tpb = tub
    res.total_physical_bytes = tpb
    res.total_usable_bytes = tub
    return res
<commit_msg>os.stderr does not exist. use sys<commit_after># -*- coding: utf-8 -*-

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import gzip
import math
import os
import platform
import re
import sys

import six

_INFO_HELP = """Memory subsystem
===============================================================================
`hwk.memory.Info` attributes:

total_physical_bytes (int)

  Number of bytes of physical RAM available to the system

total_usable_bytes (int)

  Number of bytes usable by the system (physical bytes minus a few bits
  reserved for system and the resident kernel size)

supported_page_sizes (set of int)

  A set of ints indicating memory page sizes the system can utilize, in bytes
"""

class Info(object):
    """Object describing the memory information about a system."""

    def __init__(self):
        self.total_physical_bytes = None
        self.total_usable_bytes = None
        self.supported_page_sizes = None

    def __repr__(self):
        tpb = 'unknown'
        if self.total_physical_bytes is not None:
            tpb = math.floor(self.total_physical_bytes / (1024 * 1024))
            tpb = six.text_type(tpb) + ' MB'
        tub = 'unknown'
        if self.total_usable_bytes is not None:
            tub = math.floor(self.total_usable_bytes / (1024 * 1024))
            tub = six.text_type(tub) + ' MB'
        return "memory (%s physical, %s usable)" % (tpb, tub)

    def describe(self):
        return _INFO_HELP

def supported_page_sizes():
    """Returns a set() containing the memory page sizes, in KB, supported by
    the host, or None if the page sizes could not be determined.
    """
    try:
        return {
            "Linux": _linux_supported_page_sizes,
        }[platform.system()]()
    except KeyError:
        return None

def _linux_supported_page_sizes():
    # In Linux, /sys/kernel/mm/hugepages contains a directory per page size
    # supported by the kernel. The directory name corresponds to the pattern
    # 'hugepages-{pagesize}kb'
    hp_dir = '/sys/kernel/mm/hugepages'
    return set([int(parts.split('-')[1][0:-2]) for parts in os.listdir(hp_dir)
                if os.path.isdir(os.path.join(hp_dir, parts))])

def total_physical_bytes():
    """Returns the total physical memory in bytes or None if the information
    could not be determined.
    """
    try:
        return {
            "Linux": _linux_total_physical_bytes,
        }[platform.system()]()
    except KeyError:
        return None

# System log lines will look similar to the following:
# ... kernel: [0.000000] Memory: 24633272K/25155024K ...
_SYSLOG_MEM_LINE_RE = re.compile(r'Memory:\s+\d+K\/(\d+)K')

def _linux_total_physical_bytes():
    # In Linux, the total physical memory can be determined by looking at the
    # output of dmidecode, however dmidecode requires root privileges to run,
    # so instead we examine the system logs for startup information containing
    # total physical memory and cache the results of this.
    def _find_physical_kb(line):
        matched = _SYSLOG_MEM_LINE_RE.search(six.text_type(line))
        if matched:
            return int(matched.group(1)) * 1024
        return None

    log_dir = '/var/log'
    log_files = sorted([
        filename for filename in os.listdir(log_dir)
        # /var/log will contain a file called syslog and 0 or more files called
        # syslog.$NUMBER or syslog.$NUMBER.gz containing system log records. We
        # search each, stopping when we match a system log record line that
        # contains physical memory information.
        if filename.startswith('syslog')
    ])

    for filename in log_files:
        unzip = filename.endswith('.gz')
        if unzip:
            opener = gzip.open
        else:
            opener = open

        try:
            path = os.path.join(log_dir, filename)
            with opener(path, 'rb') as f:
                for line in f.readlines():
                    size = _find_physical_kb(line)
                    if size is not None:
                        return size
        except IOError:
            return None
    return None

def info():
    """Returns a `hwk.memory.Info` object containing information on the memory
    available to the system, or None if the information could not be
    determined.
    """
    return {
        "Linux": _linux_info,
    }[platform.system()]()

def _linux_info():
    # In Linux, /proc/meminfo contains a set of memory-related amounts, with
    # lines looking like the following:
    #
    # $ cat /proc/meminfo
    # MemTotal:       24677596 kB
    # MemFree:        21244356 kB
    # MemAvailable:   22085432 kB
    # ...
    # HugePages_Total:       0
    # HugePages_Free:        0
    # HugePages_Rsvd:        0
    # HugePages_Surp:        0
    # ...
    #
    # It's worth noting that /proc/meminfo returns exact information, not
    # "theoretical" information. For instance, on the above system, I have 24GB
    # of RAM but MemTotal is indicating only around 23GB. This is because
    # MemTotal contains the exact amount of *usable* memory after accounting
    # for the kernel's resident memory size and a few reserved bits. For more
    # information, see:
    #
    #  https://www.kernel.org/doc/Documentation/filesystems/proc.txt
    mem_filepath = '/proc/meminfo'
    meminfo_lines = open(mem_filepath, 'rb').readlines()
    values = {}
    for line in meminfo_lines:
        parts = line.split()
        key = parts[0].strip(six.b(': '))
        value = int(parts[1].strip())
        in_kb = (len(parts) == 3 and parts[2].strip() == 'kB')
        if in_kb:
            value = value * 1024
        values[key] = value

    res = Info()
    res.supported_page_sizes = _linux_supported_page_sizes()
    tub = values[six.b('MemTotal')]
    tpb = _linux_total_physical_bytes()
    if tpb is None:
        msg = """
WARNING: Could not determine total physical bytes of memory. This may be due to
the host being a virtual machine or container with no /var/log/syslog file, or
the current user may not have necessary privileges to read the syslog. We are
falling back to setting the total physical amount of memory to the total usable
amount of memory
"""

        print(sys.stderr, msg)
        tpb = tub
    res.total_physical_bytes = tpb
    res.total_usable_bytes = tub
    return res
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from company.models import Company

def serialize_product(product):
    json = {'plScore':None,
            'verified':False,
            'id':product.id}

    company = product.company

    if company:

        json['company'] = {}
        json['company']['name'] = company.common_name \
            if company.common_name \
            else company.official_name if company.official_name \
            else company.name
        json['company']['plRnD'] = company.plRnD
        json['company']['plRnD_notes'] = company.plRnD_notes
        json['company']['plWorkers'] = company.plWorkers
        json['company']['plWorkers_notes'] = company.plWorkers_notes
        json['company']['plCapital'] = company.plCapital
        json['company']['plCapital_notes'] = company.plCapital_notes
        json['company']['plTaxes'] = company.plTaxes
        json['company']['plTaxes_notes'] = company.plTaxes_notes
        json['company']['plBrand'] = company.plBrand
        json['company']['plBrand_notes'] = company.plBrand_notes

        if company.plRnD and company.plWorkers and company.plCapital and\
            company.plTaxes and company.plBrand:
            plScore = .2 * company.plRnD / 100 + \
                    .2 * company.plWorkers / 100 + \
                    .3 * company.plCapital / 100 + \
                    .2 * company.plTaxes / 100 + \
                    .1 * company.plBrand / 100
            json['plScore'] =  int(100 * plScore)
            json['verified'] = company.verified
    else:
        for prefix in CODE_PREFIX_TO_COUNTRY.keys():
            if product.code.startswith(prefix):
                json['plScore'] = 0
                json['verified'] = False
                json['company'] = {}
                json['company']['name'] = 'Miejsce produkcji: {}'\
                    .format(CODE_PREFIX_TO_COUNTRY[prefix])

    return json

CODE_PREFIX_TO_COUNTRY = {
            "30" : "Francja",
            "31" : "Francja",
            "32" : "Francja",
            "33" : "Francja",
            "34" : "Francja",
            "35" : "Francja",
            "36" : "Francja",
            "37" : "Francja",
            "380" : "Bułgaria",
            "383" : "Słowenia",
            "385" : "Chorwacja",
            "387" : "Bośnia-Hercegowina",
            "40" : "Niemcy",
            "41" : "Niemcy",
            "42" : "Niemcy",
            "43" : "Niemcy",
            "44" : "Niemcy",
            "45" : "Japonia",
            "46" : "Federacja Rosyjska",
            "470" : "Kirgistan",
            "471" : "Taiwan",
            "474" : "Estonia",
            "475" : "Łotwa",
            "476" : "Azerbejdżan",
            "477" : "Litwa",
            "478" : "Uzbekistan",
            "479" : "Sri Lanka",
            "480" : "Filipiny",
            "481" : "Białoruś",
            "482" : "Ukraina",
            "484" : "Mołdova",
            "485" : "Armenia",
            "486" : "Gruzja",
            "487" : "Kazachstan",
            "489" : "Hong Kong",
            "49" : "Japonia",
            "50" : "Wielka Brytania",
            "520" : "Grecja",
            "528" : "Liban",
            "529" : "Cypr",
            "531" : "Macedonia",
            "535" : "Malta",
            "539" : "Irlandia",
            "54" : "Belgia & Luksemburg",
            "560" : "Portugalia",
            "569" : "Islandia",
            "57" : "Dania",
#            "590" : "Polska",
            "594" : "Rumunia",
            "599" : "Węgry",
            "600" : "Południowa Afryka",
            "601" : "Południowa Afryka",
            "608" : "Bahrain",
            "609" : "Mauritius",
            "611" : "Maroko",
            "613" : "Algeria",
            "619" : "Tunezja",
            "621" : "Syria",
            "622" : "Egipt",
            "624" : "Libia",
            "625" : "Jordania",
            "626" : "Iran",
            "627" : "Kuwejt",
            "628" : "Arabia Saudyjska",
            "64" : "Finlandia",
            "690" : "Chiny",
            "691" : "Chiny",
            "692" : "Chiny",
            "70" : "Norwegia",
            "729" : "Izrael",
            "73" : "Szwecja",
            "740" : "Gwatemala",
            "741" : "Salwador",
            "742" : "Honduras",
            "743" : "Nikaragua",
            "744" : "Kostaryka",
            "745" : "Panama",
            "746" : "Dominikana",
            "750" : "Meksyk",
            "759" : "Wenezuela",
            "76" : "Szwajcaria",
            "770" : "Kolumbia",
            "773" : "Urugwaj",
            "775" : "Peru",
            "777" : "Boliwia",
            "779" : "Argentyna",
            "780" : "Chile",
            "784" : "Paragwaj",
            "786" : "Ekwador",
            "789" : "Brazylia",
            "790" : "Brazylia",
            "80" : "Włochy",
            "81" : "Włochy",
            "82" : "Włochy",
            "83" : "Włochy",
            "84" : "Hiszpania",
            "850" : "Kuba",
            "858" : "Słowacja",
            "859" : "Czechy",
            "860" : "Jugosławia",
            "867" : "Korea Północna",
            "869" : "Turcja",
            "87" : "Holandia",
            "880" : "Korea Południowa",
            "885" : "Tajlandia",
            "888" : "Singapur",
            "890" : "Indie",
            "893" : "Wietnam",
            "899" : "Indonezja",
            "90" : "Austria",
            "91" : "Austria",
            "93" : "Australia",
            "94" : "Nowa Zelandia",
            "950" : "EAN - IDA",
            "955" : "Malezja",
            "958" : "Makao",
}

<commit_msg>Python tips & tricks by @mik-laj<commit_after># -*- coding: utf-8 -*-

from company.models import Company

def serialize_product(product):
    json = {'plScore':None,
            'verified':False,
            'id':product.id}

    company = product.company

    if company:

        json['company'] = {}
        json['company']['name'] = company.common_name or company.official_name \
                                  or company.name
        json['company']['plRnD'] = company.plRnD
        json['company']['plRnD_notes'] = company.plRnD_notes
        json['company']['plWorkers'] = company.plWorkers
        json['company']['plWorkers_notes'] = company.plWorkers_notes
        json['company']['plCapital'] = company.plCapital
        json['company']['plCapital_notes'] = company.plCapital_notes
        json['company']['plTaxes'] = company.plTaxes
        json['company']['plTaxes_notes'] = company.plTaxes_notes
        json['company']['plBrand'] = company.plBrand
        json['company']['plBrand_notes'] = company.plBrand_notes

        if company.plRnD and company.plWorkers and company.plCapital and\
            company.plTaxes and company.plBrand:
            plScore = .2 * company.plRnD / 100 + \
                    .2 * company.plWorkers / 100 + \
                    .3 * company.plCapital / 100 + \
                    .2 * company.plTaxes / 100 + \
                    .1 * company.plBrand / 100
            json['plScore'] =  int(100 * plScore)
            json['verified'] = company.verified
    else:
        for prefix in CODE_PREFIX_TO_COUNTRY.keys():
            if product.code.startswith(prefix):
                json['plScore'] = 0
                json['verified'] = False
                json['company'] = {}
                json['company']['name'] = 'Miejsce produkcji: {}'\
                    .format(CODE_PREFIX_TO_COUNTRY[prefix])

    return json

CODE_PREFIX_TO_COUNTRY = {
            "30" : "Francja",
            "31" : "Francja",
            "32" : "Francja",
            "33" : "Francja",
            "34" : "Francja",
            "35" : "Francja",
            "36" : "Francja",
            "37" : "Francja",
            "380" : "Bułgaria",
            "383" : "Słowenia",
            "385" : "Chorwacja",
            "387" : "Bośnia-Hercegowina",
            "40" : "Niemcy",
            "41" : "Niemcy",
            "42" : "Niemcy",
            "43" : "Niemcy",
            "44" : "Niemcy",
            "45" : "Japonia",
            "46" : "Federacja Rosyjska",
            "470" : "Kirgistan",
            "471" : "Taiwan",
            "474" : "Estonia",
            "475" : "Łotwa",
            "476" : "Azerbejdżan",
            "477" : "Litwa",
            "478" : "Uzbekistan",
            "479" : "Sri Lanka",
            "480" : "Filipiny",
            "481" : "Białoruś",
            "482" : "Ukraina",
            "484" : "Mołdova",
            "485" : "Armenia",
            "486" : "Gruzja",
            "487" : "Kazachstan",
            "489" : "Hong Kong",
            "49" : "Japonia",
            "50" : "Wielka Brytania",
            "520" : "Grecja",
            "528" : "Liban",
            "529" : "Cypr",
            "531" : "Macedonia",
            "535" : "Malta",
            "539" : "Irlandia",
            "54" : "Belgia & Luksemburg",
            "560" : "Portugalia",
            "569" : "Islandia",
            "57" : "Dania",
#            "590" : "Polska",
            "594" : "Rumunia",
            "599" : "Węgry",
            "600" : "Południowa Afryka",
            "601" : "Południowa Afryka",
            "608" : "Bahrain",
            "609" : "Mauritius",
            "611" : "Maroko",
            "613" : "Algeria",
            "619" : "Tunezja",
            "621" : "Syria",
            "622" : "Egipt",
            "624" : "Libia",
            "625" : "Jordania",
            "626" : "Iran",
            "627" : "Kuwejt",
            "628" : "Arabia Saudyjska",
            "64" : "Finlandia",
            "690" : "Chiny",
            "691" : "Chiny",
            "692" : "Chiny",
            "70" : "Norwegia",
            "729" : "Izrael",
            "73" : "Szwecja",
            "740" : "Gwatemala",
            "741" : "Salwador",
            "742" : "Honduras",
            "743" : "Nikaragua",
            "744" : "Kostaryka",
            "745" : "Panama",
            "746" : "Dominikana",
            "750" : "Meksyk",
            "759" : "Wenezuela",
            "76" : "Szwajcaria",
            "770" : "Kolumbia",
            "773" : "Urugwaj",
            "775" : "Peru",
            "777" : "Boliwia",
            "779" : "Argentyna",
            "780" : "Chile",
            "784" : "Paragwaj",
            "786" : "Ekwador",
            "789" : "Brazylia",
            "790" : "Brazylia",
            "80" : "Włochy",
            "81" : "Włochy",
            "82" : "Włochy",
            "83" : "Włochy",
            "84" : "Hiszpania",
            "850" : "Kuba",
            "858" : "Słowacja",
            "859" : "Czechy",
            "860" : "Jugosławia",
            "867" : "Korea Północna",
            "869" : "Turcja",
            "87" : "Holandia",
            "880" : "Korea Południowa",
            "885" : "Tajlandia",
            "888" : "Singapur",
            "890" : "Indie",
            "893" : "Wietnam",
            "899" : "Indonezja",
            "90" : "Austria",
            "91" : "Austria",
            "93" : "Australia",
            "94" : "Nowa Zelandia",
            "950" : "EAN - IDA",
            "955" : "Malezja",
            "958" : "Makao",
}

<|endoftext|>