Exemple #1
0
 def set_home(self, home, memory=False):
     """Sets the home folder"""
     # self._settings['home'] = home
     self.home = home
     if not memory:
         self.storage = JSONStorage(self.get_home(), 'settings')
         self.reload()
Exemple #2
0
 def set_settings(self, params):
     """Loads the parameters overriding the defaults"""
     settings = self._default.copy()
     if params is not None:
         if not isinstance(params, dict):
             raise ValueError("Params must be a dict")
         for defined in self.param_definition.keys():
             if defined in params:
                 settings[defined] = params[defined]
                 logging.debug('Set configuration key ' + defined + ' to ' +
                               str(params[defined]))
     self._settings = settings
     self.storage = JSONStorage(self.get_home(), 'settings')
def scrape_locations(country_id):
    req = RequestHandler()
    with JSONStorage(f'lmigroup_{country_id}') as stor:
        st = [0]
        while st:
            n = st.pop()
            print(n)
            key = f'loc_{n}'
            if stor.has_item(key):
                data = stor.read_item(key)
            else:
                data = get_locations(req, n, country_id)
                stor.store_item(key, data)
            for i in data:
                st.append(i['id'])
def show_construction_types(country_id):
    d = []
    ii = {0: 'root'}
    with JSONStorage(f'lmigroup_{country_id}') as stor:
        for i in stor.items():
            if i.startswith('constr_'):
                data = stor.read_item(i)
                for v in data:
                    if v:
                        d.append((v['id'], v))
                        ii[v['id']] = v['name']
    for i, v in sorted(d):
        print(i, v['name'])
        print('parent: ', ii[v['parentId']])
        print()
def scrape_construction_types(country_id):
    req = RequestHandler()
    with JSONStorage(f'lmigroup_{country_id}') as stor:
        st = [(0, True), (0, False)]
        while st:
            n, p = st.pop()
            print(n, p)
            key = f'constr_{n}'
            if p:
                key += 'p'
            if stor.has_item(key):
                data = stor.read_item(key)
            else:
                data = get_construction_types(req, n, p, country_id)
                stor.store_item(key, data)
            for i in data:
                st.append((i['id'], p))
    def configure(self):
        """Configures the storage system"""
        # Read params
        if self.params is None:
            self.params = {}
        params = self.params
        self.memory = params.get('memory', False)
        data = params.get('data', None)
        if self.path is not None:
            self.data_storage = JSONStorage(
                self.path,
                self.subcollection,
                self.memory)
            self.items = self.data_storage.load()
            if self.items is None:
                self.items = []
        if data is not None:
            self.items = data

        self._calc_autoid()
def create_csv(country_id):
    con_n = {}
    loc_n = {}
    occ_used = set()
    loc_used = set()

    cost_array = defaultdict(lambda: defaultdict(list))

    with JSONStorage(f'lmigroup_{country_id}') as stor:
        stor.clear_errors()
        for i in stor.items():
            if i.startswith('loc_'):
                for l in stor.read_item(i):
                    loc_n[l['id']] = l['name'].strip()
            if i.startswith('constr_'):
                for c in stor.read_item(i):
                    con_n[c['id']] = c['name'].strip()
            if i.startswith('cost_'):
                cost_data = stor.read_item(i)
                occ_used.add(cost_data['construction']['id'])
                loc_used.add(cost_data['location']['id'])
                cost_array[cost_data['construction']['id']][
                    cost_data['location']['id']] = [
                        cost_data['lowerCost'], cost_data['upperCost']
                    ]

    occ_ids = sorted(occ_used)
    loc_ids = sorted(loc_used)

    with open(f'country_{country_id}.csv', 'w') as f:
        fr = ['']
        fr.extend(map(loc_n.get, loc_ids))
        f.write(','.join(fr) + '\n')
        for oid in occ_ids:
            r = [f'"{con_n[oid]}"']
            for lid in loc_ids:
                r.append('"' + '\n'.join(map(str, cost_array[oid][lid])) + '"')
            f.write(','.join(r) + '\n')
def scrape_costs(country_id):
    req = RequestHandler()
    with JSONStorage(f'lmigroup_{country_id}') as stor:
        stor.clear_errors()
        locations = []
        constructions = []
        for i in stor.items():
            if i.startswith('loc_'):
                locations.extend(stor.read_item(i))
            if i.startswith('constr_'):
                constructions.extend(stor.read_item(i))
        for location, construction in product(locations, constructions):
            print(location['id'], construction['id'])
            key = f'cost_{location["id"]}_{construction["id"]}'
            if not stor.has_item(key):
                data = calculate_cost(req, location['id'], construction['id'])
                data['location'] = location
                data['construction'] = construction
                if 'message' in data:
                    print(data['message'])
                    stor.mark_notfound(key, data['message'])
                else:
                    stor.store_item(key, data)
Exemple #9
0
class Config(object):
    """Config is the main class for this module; initialize the values with
     the default configuration, allows query/edit or save it's state."""

    _instance = None
    OSX = 1
    WINDOWS = 2
    OTHER = 3
    DIR_MODE = 0700

    # Settings description
    param_definition = {
        'build_user_dir': "Build the user data directory",
        'plugins_enabled': "List of plugins enabled",
        'lang': """The application language must be locale_COUNTRY
                    or ':system:'.
                    Examples:
                        en_UK for English (United Kingdom)
                        ca_ES for catalan
                        es_ES for spanish
                """,
        'copy': """Copy files to the collection folder policy:
                        never     never copy files
                        always    copy all the files
                        remote    only network files
                """,
    }

    # Default settings
    _default = {
        'build_user_dir': True,
        'plugins_enabled': [],
        'lang': ':system:',
        'copy': 'http',
    }

    def __init__(self, platform=None):
        """ Constructor for Config, initialize all the attributes"""
        if not Config._instance is None:
            raise Exception("Called more that once")
        Config.isntance = self
        self.__file__ = FILEPATH
        if platform is None:
            platform = Config.get_current_os()
        elif platform not in [Config.OSX, Config.WINDOWS, Config.OTHER]:
            raise Exception("Platform identifier %s not found" % platform)
        self.platform = platform
        self.resources = self.get_resources_path()
        self.home = ":auto:"
        # Parse all the parameters
        self._settings = []
        self.storage = None
        self.set_settings(None)

    def save(self):
        """Persistences call, stores all the data at disc"""
        if self.storage is not None:
            self.storage.save(self._settings)

    def set(self, key, value):
        """Overrides a value of the settings or creates a new one"""
        self._settings[key] = value

    def set_home(self, home, memory=False):
        """Sets the home folder"""
        # self._settings['home'] = home
        self.home = home
        if not memory:
            self.storage = JSONStorage(self.get_home(), 'settings')
            self.reload()

    def set_settings(self, params):
        """Loads the parameters overriding the defaults"""
        settings = self._default.copy()
        if params is not None:
            if not isinstance(params, dict):
                raise ValueError("Params must be a dict")
            for defined in self.param_definition.keys():
                if defined in params:
                    settings[defined] = params[defined]
                    logging.debug('Set configuration key ' + defined + ' to ' +
                                  str(params[defined]))
        self._settings = settings
        self.storage = JSONStorage(self.get_home(), 'settings')

    def get_settings(self):
        """Returns the settings"""
        return self._settings

    def reload(self):
        """Reloads the stored configuration (if exists)"""
        if self.storage is not None:
            self.set_settings(self.storage.load())

    @staticmethod
    def get_instance():
        """Returns the config instance"""
        if Config._instance is None:
            Config._instance = Config()
        return Config._instance

    def get_resources_path(self):
        """Returns the resources path, in MacOs is the folder Resources
         inside the bundle """
        # determine if application is a script file or frozen exe
        application_path = ''
        if getattr(sys, 'frozen', False):
            application_path = os.path.dirname(sys.executable)
            if self.platform == Config.OSX:
                application_path = application_path.replace(
                    'MacOS',
                    'Resources'
                )
        else:
            application_path = self.__file__.replace(
                os.path.join('collector', 'core'),
                '')
        return os.path.abspath(application_path)

    def get_appdata_path(self):
        """Returns the app data folder, this folder is inside the
         application"""
        return os.path.join(self.resources, 'data')

    def get_home(self):
        """Returns the user data path (home)"""
        value = self.home
        if value == ':auto:':
            value = Config.calculate_data_path(self.platform)
        elif value == ':resources:':
            value = self.get_appdata_path()
        return value

    get_data_path = get_home

    def get_plugin_path(self):
        """Returns the user plugin path"""
        return os.path.join(self.get_home(), 'plugins')

    @staticmethod
    def get_current_os(platform=None):
        """Try to discover the current OS"""
        if platform is None:
            platform = sys.platform
        platform = platform.lower()
        if platform in 'win32' or platform in 'win64':
            return Config.WINDOWS
        elif platform in 'darwin':
            return Config.OSX
        else:
            return Config.OTHER

    @staticmethod
    def calculate_data_path(platform=None):
        """ Calculates the user data directory,
         the exact location depends of the OS"""
        config_dir = None
        if platform is None:
            platform = Config.get_current_os()
        if platform == Config.WINDOWS:
            # TODO try to use distutils get_special_folder_path
            #config_dir = get_special_folder_path("CSIDL_APPDATA")
            config_dir = os.path.expanduser('~')
            config_dir = os.path.join(config_dir, 'Collector')
        elif platform == Config.OSX:
            config_dir = os.path.expanduser(
                '~/Library/Application Support/Collector')
        else:
            bdir = os.path.abspath(os.path.expanduser(
                os.environ.get('XDG_CONFIG_HOME', '~/.config')))
            config_dir = os.path.join(bdir, 'collector')
        return config_dir

    def build_data_directory(self):
        """Creates the content inside the user data directory"""
        subfolders = ['user_plugins', 'config', 'collections']
        import shutil
        base = self.get_home()
        if not os.path.exists(base):
            os.makedirs(base, mode=Config.DIR_MODE)
            appdata = self.get_appdata_path()
            # Do a full copy because no previus data exists
            for folder in subfolders:
                dst = os.path.join(base, folder)
                src = os.path.join(appdata, folder)
                shutil.copytree(src, dst)
        # TODO check if some data is missing?

    def conf(self, key):
        """Returns the setting value for the requested key"""
        if key != 'home':
            return self._settings[key]
        else:
            return self.get_home()

    get = conf
def archive_data(country_id):
    with JSONStorage(f'lmigroup_{country_id}') as stor:
        stor.archive()
Exemple #11
0
class PersistenceDict(Persistence):
    """Implementation of persistence using a python dictionary"""

    _autoid = 1

    def __init__(self, schema, path, params=None):
        super(PersistenceDict, self).__init__(schema, path, params)
        self.items = []
        self.data_storage = None
        self.memory = False
        self.class_ = type(str(schema.collection + "_" + schema.id),
                           (FileDict,), {"schema": schema.id})
        # configure
        self.configure()

    def configure(self):
        """Configures the storage system"""
        # Read params
        if self.params is None:
            self.params = {}
        params = self.params
        self.memory = params.get('memory', False)
        data = params.get('data', None)
        if self.path is not None:
            self.data_storage = JSONStorage(
                self.path,
                self.subcollection,
                self.memory)
            self.items = self.data_storage.load()
            if self.items is None:
                self.items = []
        if data is not None:
            self.items = data

        self._calc_autoid()

    def _calc_autoid(self):
        """Searchs the max id used and set's the new autoid value"""
        maxid = 0
        for i in self.items:
            maxid = max(maxid, i['id'])
        self._autoid = maxid + 1

    def filter(self, fitlers):
        # TODO
        raise Exception("Not Implemented")

    def get_filters(self):
        #TODO
        return []

    def get_last(self, count):
        """Returns the last items created, the number of items are defined
         with the count parameter, the items are orderded by last inserted"""
        result = self.items[-count:]
        # Reverse the count
        objects = []
        result.reverse()
        for item in result:
            objects.append(FileDict(item))
        return objects

    def get(self, _id):
        if isinstance(_id, str):
            _id = int(_id)
        for item in self.items:
            if _id == item['id']:
                return FileDict(item)
        return None

    def get_all(self, start_at, limit, order=None):
        """Returns all the items starting at *start_at*, the results could
         be limited whit *limit*"""
        result = []
        objects = []
        if limit == 0:
            objects = self.items[start_at:]
        else:
            objects = self.items[start_at:(start_at + limit)]
        for item in objects:
            result.append(FileDict(item))
        return result

    def search(self, term):
        results = []
        term = term.lower()
        for item in self.items:
            if item['title'].lower().find(term) != -1:
                results.append(FileDict(item))
        return results

    def save(self, values):
        if 'id' in values:
            for item in self.items:
                if values['id'] == item['id']:
                    item.update(values)
        else:
            values['id'] = self._autoid
            self._autoid += 1
            self.items.append(values)
        self.commit()

    def delete(self, _id):
        for item in self.items:
            if item['id'] == _id:
                self.items.remove(item)
        self.commit()

    def commit(self):
        """Stores the changes"""
        if self.data_storage is not None:
            self.data_storage.save(self.items)

    def load_references(self, collections, item):
        if 'refLoaded' in item:
            return
        item = item.copy()
        item['refLoaded'] = True
        return item