<commit_before>import json
import math
import os
from statistics import mean

import numpy
from trefoil.geometry.bbox import BBox
from trefoil.netcdf.variable import SpatialCoordinateVariables
from django.conf import settings
from django.contrib.gis.geos import Polygon
from django.core.management import BaseCommand
from django.db import transaction
from ncdjango.models import Service
from netCDF4 import Dataset
from pyproj import Proj
from rasterio.features import rasterize

from seedsource_core.django.seedsource.models import SeedZone, TransferLimit, Region

VARIABLES = (
    'MAT', 'MWMT', 'MCMT', 'TD', 'MAP', 'MSP', 'AHM', 'SHM', 'DD_0', 'DD5', 'FFP', 'PAS', 'EMT', 'EXT', 'Eref', 'CMD'
)

def get_bands_fn(bands_fn):
    def _every(low, high, increment, start=0):
        """ Returns a generator for zones within low-high based on the increment """

        if high < low:
            return (x for x in [])

        low -= start
        high -= start

        low -= low % increment
        high += increment - high % increment

        return ((x + start, x + increment + start) for x in range(low, high, increment))

    def every_500(zone_id, low, high):
        return _every(low, high, 500)

    def every_1000(zone_id, low, high):
        return _every(low, high, 1000)

    def historical(zone_id, low, high):
        return _every(low, high, 500)

    def wa_psme(zone_id, low, high):
        if zone_id < 13:
            return _every(low, high, 1000)
        elif zone_id < 17:
            return [(0, 1400)] + list(_every(1400, high, 700, 1400))
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_psme(zone_id, low, high):
        if zone_id < 4:
            return [(0, 2000), (2000, 2750)] + list(_every(2750, high, 500, 2750))
        elif zone_id == 5:
            return _every(low, high, 500)
        elif zone_id == 4 or zone_id < 17:
            return [(0, 1000)] + list(_every(1000, high, 500, 1000))
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pico(zone_id, low, high):
        if zone_id < 14:
            return _every(low, high, 1000)
        elif zone_id < 18:
            return _every(low, high, 700)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_pico(zone_id, low, high):
        return _every(low, high, 1000)

    def or_pipo(zone_id, low, high):
        if zone_id == 10:
            return list(_every(low, min(4999, high), 1000)) + list(_every(5000, high, 700, 5000))
        elif zone_id < 16:
            return _every(low, high, 1000)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pipo(zone_id, low, high):
        if zone_id < 4:
            return [(0, high + 1)]
        elif zone_id < 12:
            return _every(low, high, 1000)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_thpl(zone_id, low, high):
        if zone_id < 5:
            return _every(low, high, 2000)
        elif zone_id < 8:
            return _every(low, high, 1500)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_thpl(zone_id, low, high):
        if zone_id < 3:
            return [(0, 999999)]
        elif zone_id < 5:
            return [(0, 3500), (3500, high + 1)]
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pimo(zone_id, low, high):
        return [(low, high + 1)]

    def or_pimo(zone_id, low, high):
        return [(low, high + 1)]

    def no_bands(zone_id, low, high):
        return [(low, high + 1)]

    return locals()[bands_fn]

class Command(BaseCommand):
    help = 'Calculates default variable transfer limits for each available seed zone'

    def __init__(self, *args, **kwargs):
        self.transfers_by_source = {}

        super().__init__(*args, **kwargs)

    def add_arguments(self, parser):
        parser.add_argument('zone_name', nargs='?', type=str, default='all', help='Accepts zone name or all')

    def _get_subsets(self, elevation, data, coords: SpatialCoordinateVariables, bbox):
        """ Returns subsets of elevation, data, and coords, clipped to the given bounds """

        x_slice = slice(*coords.x.indices_for_range(bbox.xmin, bbox.xmax))
        y_slice = slice(*coords.y.indices_for_range(bbox.ymin, bbox.ymax))

        return elevation[y_slice, x_slice], data[y_slice, x_slice], coords.slice_by_bbox(bbox)

    def _write_limit(self, variable, time_period, zone, masked_data, low=None, high=None):
        min_value = numpy.nanmin(masked_data)
        max_value = numpy.nanmax(masked_data)
        transfer = (max_value - min_value) / 2.0
        center = max_value - transfer

        if numpy.isnan(transfer) or hasattr(transfer, 'mask'):
            print('WARNING: Transfer limit is NaN for {}, zone {}, band {}-{}'.format(
                zone.source, zone.zone_id, low, high
            ))
            return

        TransferLimit.objects.create(
            variable=variable, time_period=time_period, zone=zone, transfer=transfer, center=center, low=low, high=high
        )

        transfers_by_variable = self.transfers_by_source.get(zone.source, {})
        transfers_by_variable[variable] = transfers_by_variable.get(variable, []) + [transfer]
        self.transfers_by_source[zone.source] = transfers_by_variable

    def handle(self, zone_name, *args, **options):
        query_zone_name = '' if zone_name == 'all' else zone_name

        zones = SeedZone.objects.filter(source__istartswith=query_zone_name).order_by('source')
        if not zones:
            seed_zone_choices = SeedZone.objects.values_list('source', flat=True).order_by('source').distinct()
            print('Error: {} zone does not exists'.format(zone_name))
            print('Choices are:\n\t- {}'.format('\n\t- '.join(seed_zone_choices)))
            return

        message = 'WARNING: This will replace "{}" transfer limits. Do you want to continue? [y/n]'.format(zone_name)
        if input(message).lower() not in {'y', 'yes'}:
            return

        self.transfers_by_source = {}

        with transaction.atomic():
            TransferLimit.objects.filter(zone__source__istartswith=query_zone_name).delete()

            last_zone_set = None
            last_region = None

            for time_period in ('1961_1990', '1981_2010'):
                for variable in VARIABLES:
                    print('Processing {} for {}...'.format(variable, time_period))

                    for zone in zones:
                        print(zone.name)
                        if zone.source != last_zone_set:
                            last_zone_set = zone.source
                            region = Region.objects.filter(
                                polygons__intersects=Polygon.from_bbox(zone.polygon.extent)
                            ).first()

                            if region != last_region:
                                last_region = region

                                print('Loading region {}'.format(region.name))

                                elevation_service = Service.objects.get(name='{}_dem'.format(region.name))
                                dataset_path = os.path.join(settings.NC_SERVICE_DATA_ROOT, elevation_service.data_path)

                                with Dataset(dataset_path) as ds:
                                    coords = SpatialCoordinateVariables.from_dataset(
                                        ds, x_name='lon', y_name='lat', projection=Proj(elevation_service.projection)
                                    )
                                    elevation = ds.variables['elevation'][:]

                                variable_service = Service.objects.get(
                                    name='{}_{}Y_{}'.format(region.name, time_period, variable)
                                )
                                dataset_path = os.path.join(settings.NC_SERVICE_DATA_ROOT, variable_service.data_path)
                                with Dataset(dataset_path) as ds:
                                    data = ds.variables[variable][:]

                        clipped_elevation, clipped_data, clipped_coords = self._get_subsets(
                            elevation, data, coords, BBox(zone.polygon.extent)
                        )

                        zone_mask = rasterize(
                            ((json.loads(zone.polygon.geojson), 1),), out_shape=clipped_elevation.shape,
                            transform=clipped_coords.affine, fill=0, dtype=numpy.dtype('uint8')
                        )

                        masked_dem = numpy.ma.masked_where(zone_mask == 0, clipped_elevation)
                        min_elevation = max(math.floor(numpy.nanmin(masked_dem) / 0.3048), 0)
                        max_elevation = math.ceil(numpy.nanmax(masked_dem) / 0.3048)
                        bands = list(get_bands_fn(zone.bands_fn)(zone.zone_id, min_elevation, max_elevation))

                        if not bands:
                            print('WARNING: No elevation bands found for {}, zone {}'.format(
                                zone.source, zone.zone_id
                            ))
                            continue

                        for band in bands:
                            low, high = band

                            # Bands are exclusive of the low number, so the first band is a special case, since we
                            # want to include 0. So we work around it by making the actual low -1
                            if low == 0:
                                low = -1

                            # Elevation bands are represented in feet
                            masked_data = numpy.ma.masked_where(
                                (zone_mask == 0) | (clipped_elevation <= low * 0.3048) |
                                (clipped_elevation > high * 0.3048),
                                clipped_data
                            )

                            self._write_limit(variable, time_period, zone, masked_data, low, high)

            for source, transfers_by_variable in self.transfers_by_source.items():
                for variable, transfers in transfers_by_variable.items():
                    TransferLimit.objects.filter(
                        variable=variable, zone__source=source
                    ).update(
                        avg_transfer=mean(transfers)
                    )
<commit_msg>Support zone sources spanning multiple regions, fix bug with small zones<commit_after>import json
import math
import os
from statistics import mean

import numpy
from django.conf import settings
from django.contrib.gis.geos import Polygon
from django.core.management import BaseCommand
from django.db import transaction
from ncdjango.models import Service
from netCDF4 import Dataset
from pyproj import Proj
from rasterio.features import rasterize
from seedsource_core.django.seedsource.models import SeedZone, TransferLimit, Region
from trefoil.geometry.bbox import BBox
from trefoil.netcdf.variable import SpatialCoordinateVariables

VARIABLES = (
    'MAT', 'MWMT', 'MCMT', 'TD', 'MAP', 'MSP', 'AHM', 'SHM', 'DD_0', 'DD5', 'FFP', 'PAS', 'EMT', 'EXT', 'Eref', 'CMD'
)

def get_bands_fn(bands_fn):
    def _every(low, high, increment, start=0):
        """ Returns a generator for zones within low-high based on the increment """

        if high < low:
            return (x for x in [])

        low -= start
        high -= start

        low -= low % increment
        high += increment - high % increment

        return ((x + start, x + increment + start) for x in range(low, high, increment))

    def every_500(zone_id, low, high):
        return _every(low, high, 500)

    def every_1000(zone_id, low, high):
        return _every(low, high, 1000)

    def historical(zone_id, low, high):
        return _every(low, high, 500)

    def wa_psme(zone_id, low, high):
        if zone_id < 13:
            return _every(low, high, 1000)
        elif zone_id < 17:
            return [(0, 1400)] + list(_every(1400, high, 700, 1400))
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_psme(zone_id, low, high):
        if zone_id < 4:
            return [(0, 2000), (2000, 2750)] + list(_every(2750, high, 500, 2750))
        elif zone_id == 5:
            return _every(low, high, 500)
        elif zone_id == 4 or zone_id < 17:
            return [(0, 1000)] + list(_every(1000, high, 500, 1000))
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pico(zone_id, low, high):
        if zone_id < 14:
            return _every(low, high, 1000)
        elif zone_id < 18:
            return _every(low, high, 700)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_pico(zone_id, low, high):
        return _every(low, high, 1000)

    def or_pipo(zone_id, low, high):
        if zone_id == 10:
            return list(_every(low, min(4999, high), 1000)) + list(_every(5000, high, 700, 5000))
        elif zone_id < 16:
            return _every(low, high, 1000)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pipo(zone_id, low, high):
        if zone_id < 4:
            return [(0, high + 1)]
        elif zone_id < 12:
            return _every(low, high, 1000)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_thpl(zone_id, low, high):
        if zone_id < 5:
            return _every(low, high, 2000)
        elif zone_id < 8:
            return _every(low, high, 1500)
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def or_thpl(zone_id, low, high):
        if zone_id < 3:
            return [(0, 999999)]
        elif zone_id < 5:
            return [(0, 3500), (3500, high + 1)]
        else:
            raise ValueError('Unrecognized zone: {}'.format(zone_id))

    def wa_pimo(zone_id, low, high):
        return [(low, high + 1)]

    def or_pimo(zone_id, low, high):
        return [(low, high + 1)]

    def no_bands(zone_id, low, high):
        return [(low, high + 1)]

    return locals()[bands_fn]

class Command(BaseCommand):
    help = 'Calculates default variable transfer limits for each available seed zone'

    def __init__(self, *args, **kwargs):
        self.transfers_by_source = {}

        super().__init__(*args, **kwargs)

    def add_arguments(self, parser):
        parser.add_argument('zone_name', nargs='?', type=str, default='all', help='Accepts zone name or all')

    def _get_subsets(self, elevation, data, coords: SpatialCoordinateVariables, bbox):
        """ Returns subsets of elevation, data, and coords, clipped to the given bounds """

        x_slice = slice(*coords.x.indices_for_range(bbox.xmin, bbox.xmax))
        y_slice = slice(*coords.y.indices_for_range(bbox.ymin, bbox.ymax))

        return elevation[y_slice, x_slice], data[y_slice, x_slice], coords.slice_by_bbox(bbox)

    def _write_limit(self, variable, time_period, zone, masked_data, low=None, high=None):
        min_value = numpy.nanmin(masked_data)
        max_value = numpy.nanmax(masked_data)
        transfer = (max_value - min_value) / 2.0
        center = max_value - transfer

        if numpy.isnan(transfer) or hasattr(transfer, 'mask'):
            print('WARNING: Transfer limit is NaN for {}, zone {}, band {}-{}'.format(
                zone.source, zone.zone_id, low, high
            ))
            return

        TransferLimit.objects.create(
            variable=variable, time_period=time_period, zone=zone, transfer=transfer, center=center, low=low, high=high
        )

        transfers_by_variable = self.transfers_by_source.get(zone.source, {})
        transfers_by_variable[variable] = transfers_by_variable.get(variable, []) + [transfer]
        self.transfers_by_source[zone.source] = transfers_by_variable

    def handle(self, zone_name, *args, **options):
        query_zone_name = '' if zone_name == 'all' else zone_name

        zones = SeedZone.objects.filter(source__istartswith=query_zone_name).order_by('source')
        if not zones:
            seed_zone_choices = SeedZone.objects.values_list('source', flat=True).order_by('source').distinct()
            print('Error: {} zone does not exists'.format(zone_name))
            print('Choices are:\n\t- {}'.format('\n\t- '.join(seed_zone_choices)))
            return

        message = 'WARNING: This will replace "{}" transfer limits. Do you want to continue? [y/n]'.format(zone_name)
        if input(message).lower() not in {'y', 'yes'}:
            return

        self.transfers_by_source = {}

        with transaction.atomic():
            TransferLimit.objects.filter(zone__source__istartswith=query_zone_name).delete()

            last_region = None

            for time_period in ('1961_1990', '1981_2010'):
                for variable in VARIABLES:
                    print('Processing {} for {}...'.format(variable, time_period))

                    for zone in zones:
                        print(zone.name)
                        region = Region.objects.filter(
                            polygons__intersects=Polygon.from_bbox(zone.polygon.extent)
                        ).first()

                        if region is None:
                            raise Exception('Could not find region for seed zone ' + zone.name)

                        if region != last_region:
                            last_region = region

                            print('Loading region {}'.format(region.name))

                            elevation_service = Service.objects.get(name='{}_dem'.format(region.name))
                            elevation_variable = elevation_service.variable_set.first()
                            dataset_path = os.path.join(settings.NC_SERVICE_DATA_ROOT, elevation_service.data_path)

                            with Dataset(dataset_path) as ds:
                                coords = SpatialCoordinateVariables.from_dataset(
                                    ds, x_name=elevation_variable.x_dimension,
                                    y_name=elevation_variable.y_dimension,
                                    projection=Proj(elevation_service.projection)
                                )
                                elevation = ds.variables[elevation_variable.variable][:]

                            variable_service = Service.objects.get(
                                name='{}_{}Y_{}'.format(region.name, time_period, variable)
                            )
                            dataset_path = os.path.join(settings.NC_SERVICE_DATA_ROOT, variable_service.data_path)
                            with Dataset(dataset_path) as ds:
                                data = ds.variables[variable][:]

                        bbox = BBox(zone.polygon.extent)
                        try:
                            clipped_elevation, clipped_data, clipped_coords = self._get_subsets(
                                elevation, data, coords, bbox
                            )

                            zone_mask = rasterize(
                                ((json.loads(zone.polygon.geojson), 1),), out_shape=clipped_elevation.shape,
                                transform=clipped_coords.affine, fill=0, dtype=numpy.dtype('uint8')
                            )

                            # If all data are masked out, re-rasterize with `all-touched=True`
                            if (zone_mask == 0).all():
                                zone_mask = rasterize(
                                    ((json.loads(zone.polygon.geojson), 1),), out_shape=clipped_elevation.shape,
                                    transform=clipped_coords.affine, fill=0, dtype=numpy.dtype('uint8'),
                                    all_touched=True
                                )
                        except (AssertionError, IndexError):  # trefoil throws exceptions for 1-cell slices
                            x_start, x_end = coords.x.indices_for_range(bbox.xmin, bbox.xmax)
                            if x_start == x_end:
                                x_end += 1

                            y_start, y_end = coords.y.indices_for_range(bbox.ymin, bbox.ymax)
                            if y_start == y_end:
                                y_end += 1

                            clipped_elevation = elevation[y_start:y_end, x_start:x_end]
                            clipped_data = elevation[y_start:y_end, x_start:x_end]

                            zone_mask = numpy.ones(clipped_elevation.shape)

                        masked_dem = numpy.ma.masked_where(zone_mask == 0, clipped_elevation)

                        # If all data are masked out at this point, skip this zone (it's probably in the ocean)
                        if masked_dem.mask.all():
                            continue

                        min_elevation = max(math.floor(numpy.nanmin(masked_dem) / 0.3048), 0)
                        max_elevation = math.ceil(numpy.nanmax(masked_dem) / 0.3048)
                        bands = list(get_bands_fn(zone.bands_fn)(zone.zone_id, min_elevation, max_elevation))

                        if not bands:
                            print('WARNING: No elevation bands found for {}, zone {}'.format(
                                zone.source, zone.zone_id
                            ))
                            continue

                        for band in bands:
                            low, high = band

                            # Bands are exclusive of the low number, so the first band is a special case, since we
                            # want to include 0. So we work around it by making the actual low -1
                            if low == 0:
                                low = -1

                            # Elevation bands are represented in feet
                            masked_data = numpy.ma.masked_where(
                                (zone_mask == 0) | (clipped_elevation <= low * 0.3048) |
                                (clipped_elevation > high * 0.3048),
                                clipped_data
                            )

                            self._write_limit(variable, time_period, zone, masked_data, low, high)

            for source, transfers_by_variable in self.transfers_by_source.items():
                for variable, transfers in transfers_by_variable.items():
                    TransferLimit.objects.filter(
                        variable=variable, zone__source=source
                    ).update(
                        avg_transfer=mean(transfers)
                    )
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

############################
# Basic Details

AUTHOR = u'Saevon'
SITENAME = u'Saevon.ca'
SITEURL = ''
TIMEZONE = 'Canada/Eastern'
DEFAULT_LANG = u'en'
THEME = 'theme'

############################
# Content

# Location of blog content
PATH = 'content'
ARTICLE_DIR = 'articles'

# Articles per page
DEFAULT_PAGINATION = 2

# Which direct templates should be paginated
PAGINATED_DIRECT_TEMPLATES = ()

# If the article is in a folder and doesn't have a category use the folder name as its category
USE_FOLDER_AS_CATEGORY = True
DEFAULT_CATEGORY = 'personal'

# Disable the authors list page (as there is only one author)
AUTHORS_SAVE_AS = False

# Feed generation is usually not desired when developing
# FEED_ATOM = ('atom.xml')
FEED_ATOM = None
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
CATEGORY_FEED_RSS = None
TAG_FEED_ATOM = None
TAG_FEED_RSS = None

FEED_DOMAIN = SITEURL
TRANSLATION_FEED = None

############################
# Coding
MD_EXTENSIONS = [
	'meta',
	'sane_lists',
	'smarty(smart_quotes=False)',
	'codehilite(css_class=highlight)',
	'extra',
	'del_ins',
	'alerts',
]

# Fix the import path
import sys
sys.path.append('.')

JINJA_EXTENSIONS  = []
from plugins.debug_dump import dump, dump_all
from plugins.category import find_category, category_preview_articles
from plugins.summary import summary
from plugins.tags import update_tags_count
JINJA_FILTERS = {
	'find_category': find_category,
	'category_preview_articles': category_preview_articles,
	'update_tags_count': update_tags_count,
	'summary': summary,

	# DEBUG
	'dump': dump,
	'dump_all': dump_all,
}

############################
# Links

ARTICLE_URL = '{category}/{slug}/'
ARTICLE_SAVE_AS = '{category}/{slug}/index.html'

AUTHOR_SAVE_AS = 'about.html'
AUTHOR_URL = 'about.html'

# Blog Links
LINKS =  (

)

# My Account Links
ACCOUNTS = (
    # (icon, url)
    ('github-square', 'https://github.com/Saevon'),
    ('linkedin-square', 'https://ca.linkedin.com/in/saevon'),
)

# Social widget
SOCIAL = (
    ('You can add links in your config file', '#'),
    ('Another social link', '#'),
)

<commit_msg>More configuration changes<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

############################
# Basic Details

AUTHOR = u'Saevon'
SITENAME = u'Saevon.ca'
SITEURL = ''
TIMEZONE = 'Canada/Eastern'
DEFAULT_LANG = u'en'
THEME = 'theme'

############################
# Content

# Location of blog content
PATH = 'content'
ARTICLE_DIR = 'articles'

# Articles per page
DEFAULT_PAGINATION = 2

# Which direct templates should be paginated
PAGINATED_DIRECT_TEMPLATES = []

# If the article is in a folder and doesn't have a category use the folder name as its category
USE_FOLDER_AS_CATEGORY = True
DEFAULT_CATEGORY = 'personal'

# Disable the authors list page (as there is only one author)
AUTHORS_SAVE_AS = False

# Feed generation is usually not desired when developing
# FEED_ATOM = ('atom.xml')
FEED_ATOM = None
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
CATEGORY_FEED_RSS = None
TAG_FEED_ATOM = None
TAG_FEED_RSS = None

FEED_DOMAIN = SITEURL
TRANSLATION_FEED = None

############################
# Coding
MD_EXTENSIONS = [
	'meta',
	'sane_lists',
	'smarty(smart_quotes=False)',
	'codehilite(css_class=highlight)',
	'extra',
	'del_ins',
	'alerts',
]

# Fix the import path
import sys
sys.path.append('.')

JINJA_EXTENSIONS  = []
from plugins.debug_dump import dump, dump_all
from plugins.category import find_category, category_preview_articles
from plugins.summary import summary
from plugins.tags import update_tags_count
JINJA_FILTERS = {
	'find_category': find_category,
	'category_preview_articles': category_preview_articles,
	'update_tags_count': update_tags_count,
	'summary': summary,

	# DEBUG
	'dump': dump,
	'dump_all': dump_all,
}

DELETE_OUTPUT_DIRECTORY = True

############################
# Links

ARTICLE_URL = '{category}/{slug}/'
ARTICLE_SAVE_AS = '{category}/{slug}/index.html'

AUTHOR_SAVE_AS = ''

# Disable tags, and have them go the tags page
TAG_SAVE_AS = ''
TAG_URL = 'tags.html#{slug}'

# Blog Links
LINKS =  (

)

# My Account Links
ACCOUNTS = (
    # (icon, url)
    ('github-square', 'https://github.com/Saevon'),
    ('linkedin-square', 'https://ca.linkedin.com/in/saevon'),
)

# Social widget
SOCIAL = (
    ('You can add links in your config file', '#'),
    ('Another social link', '#'),
)

<|endoftext|>


<commit_before>import argparse
import logging

from . import exc
from . import lsb
from .cliutil import priority
from .sudo_pushy import get_transport

LOG = logging.getLogger(__name__)

def install_suse(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    if codename == 'Mantis':
        distro='opensuse12'
    else:
        distro='sles-11sp2'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/{distro}/'.format(
        version=version,
        distro=distro,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/{distro}'.format(distro=distro)
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-{distro}{release}-{machine}-basic/ref/{version}/'.format(
            distro=distro,
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.noarch.rpm'.format(
                url=url,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'zypper',
            '--non-interactive',
            '--quiet',
            'install',
            'ceph',
            ],
        )

def uninstall_suse(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'libcephfs1',
        'librados2',
        'librbd1',
        ]
    args = [
        'zypper',
        '--non-interactive',
        '--quiet',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def uninstall_debian(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'ceph-mds',
        'ceph-common',
        'ceph-fs-common',
        ]
    args = [
        'apt-get',
        '-q',
        'remove',
        '-f',
        '-y',
        '--force-yes',
        ]
    if arg_purge:
        args.append('--purge')
    args.append('--')
    args.extend(packages)
    subprocess.check_call(args=args)

def install_fedora(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/fc{release}/'.format(
        version=version,
        release=release,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/fc{release}'.format(
        release=release,
        )
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-fc{release}-{machine}-basic/ref/{version}/'.format(
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.fc{release}.noarch.rpm'.format(
                url=url,
                release=release,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'yum',
            '-y',
            '-q',
            'install',
            'ceph',
            ],
        )

def uninstall_fedora(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        ]
    args = [
        'yum',
        '-q',
        '-y',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def install_centos(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/el6/'.format(
        version=version,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/'
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-centos{release}-{machine}-basic/ref/{version}/'.format(
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.el6.noarch.rpm'.format(
                url=url,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'yum',
            '-y',
            '-q',
            'install',
            'ceph',
            ],
        )

def uninstall_centos(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        ]
    args = [
        'yum',
        '-q',
        '-y',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def uninstall_debian(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'ceph-mds',
        'ceph-common',
        'ceph-fs-common',
        ]
    args = [
        'apt-get',
        '-q',
        'remove',
        '-f',
        '-y',
        '--force-yes',
        ]
    if arg_purge:
        args.append('--purge')
    args.append('--')
    args.extend(packages)
    subprocess.check_call(args=args)

def install_debian(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='wget -q -O- \'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc\' | apt-key add -'.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/debian-{version}/'.format(
            version=version,
            )
    elif version_kind == 'testing':
        url = 'http://ceph.com/debian-testing/'
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-deb-{codename}-{machine}-basic/ref/{version}'.format(
            codename=codename,
            machine=platform.machine(),
            version=version,
            )
    else:
        raise RuntimeError('Unknown version kind: %r' % version_kind)

    with file('/etc/apt/sources.list.d/ceph.list', 'w') as f:
        f.write('deb {url} {codename} main\n'.format(
                url=url,
                codename=codename,
                ))

    subprocess.check_call(
        args=[
            'apt-get',
            '-q',
            'update',
            ],
        )

    # TODO this does not downgrade -- should it?
    subprocess.check_call(
        args=[
            'env',
            'DEBIAN_FRONTEND=noninteractive',
            'DEBIAN_PRIORITY=critical',
            'apt-get',
            '-q',
            '-o', 'Dpkg::Options::=--force-confnew',
            'install',
            '--no-install-recommends',
            '--assume-yes',
            '--',
            'ceph',
            'ceph-mds',
            'ceph-common',
            'ceph-fs-common',
            # ceph only recommends gdisk, make sure we actually have
            # it; only really needed for osds, but minimal collateral
            'gdisk',
            ],
        )

def purge_data_any():
    import subprocess
    import os.path

    subprocess.call(args=[
            'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
            ])
    if os.path.exists('/var/lib/ceph'):
        subprocess.check_call(args=[
                'find', '/var/lib/ceph',
                '-mindepth', '1',
                '-maxdepth', '2',
                '-type', 'd',
                '-exec', 'umount', '{}', ';',
                ])
        subprocess.check_call(args=[
                'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
                ])
    subprocess.check_call(args=[
            'rm', '-rf', '--one-file-system', '--', '/etc/ceph',
            ])

def install(args):
    version = getattr(args, args.version_kind)
    version_str = args.version_kind
    if version:
        version_str += ' version {version}'.format(version=version)
    LOG.debug(
        'Installing %s on cluster %s hosts %s',
        version_str,
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s release %s codename %s', distro, release, codename)

        if (distro == 'Debian' or distro == 'Ubuntu'):
            install_r = sudo.compile(install_debian)
        elif (distro == 'CentOS' or distro == 'Scientific') or distro.startswith('RedHat'):
            install_r = sudo.compile(install_centos)
        elif distro == 'Fedora':
            install_r = sudo.compile(install_fedora)
        elif (distro == 'SUSE LINUX'):
            install_r = sudo.compile(install_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Installing on host %s ...', hostname)
        install_r(
            release=release,
            codename=codename,
            version_kind=args.version_kind,
            version=version,
            )

        sudo.close()

def uninstall(args):
    LOG.debug(
        'Uninstalling on cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s codename %s', distro, codename)

        if (distro == 'Debian' or distro == 'Ubuntu'):
            uninstall_r = sudo.compile(uninstall_debian)
        elif distro == 'CentOS' or distro == 'Scientific' or distro.startswith('RedHat'):
            uninstall_r = sudo.compile(uninstall_centos)
        elif distro == 'Fedora':
            uninstall_r = sudo.compile(uninstall_fedora)
        elif (distro == 'SUSE LINUX'):
            uninstall_r = sudo.compile(uninstall_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Uninstalling on host %s ...', hostname)
        uninstall_r()
        sudo.close()

def purge(args):
    LOG.debug(
        'Purging from cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s codename %s', distro, codename)

        if distro == 'Debian' or distro == 'Ubuntu':
            purge_r = sudo.compile(uninstall_debian)
        elif distro == 'CentOS' or distro == 'Scientific' or distro.startswith('RedHat'):
            purge_r = sudo.compile(uninstall_centos)
        elif distro == 'Fedora':
            purge_r = sudo.compile(uninstall_fedora)
        elif (distro == 'SUSE LINUX'):
            purge_r = sudo.compile(uninstall_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Purging host %s ...', hostname)
        purge_r(arg_purge=True)
        sudo.close()

def purge_data(args):
    LOG.debug(
        'Purging data from cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        # TODO username
        sudo = args.pushy(get_transport(hostname))

        LOG.debug('Purging data from host %s ...', hostname)
        purge_data_any_r = sudo.compile(purge_data_any)
        purge_data_any_r()
        sudo.close()

class StoreVersion(argparse.Action):
    """
    Like ``"store"`` but also remember which one of the exclusive
    options was set.

    There are three kinds of versions: stable, testing and dev.
    This sets ``version_kind`` to be the right one of the above.

    This kludge essentially lets us differentiate explicitly set
    values from defaults.
    """
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values)
        namespace.version_kind = self.dest

@priority(20)
def make(parser):
    """
    Install Ceph packages on remote hosts.
    """

    version = parser.add_mutually_exclusive_group()

    version.add_argument(
        '--stable',
        nargs='?',
        action=StoreVersion,
        choices=[
            'bobtail',
            'cuttlefish',
            ],
        metavar='CODENAME',
        help='install a release known as CODENAME (done by default) (default: %(default)s)',
        )

    version.add_argument(
        '--testing',
        nargs=0,
        action=StoreVersion,
        help='install the latest development release',
        )

    version.add_argument(
        '--dev',
        nargs='?',
        action=StoreVersion,
        const='master',
        metavar='BRANCH_OR_TAG',
        help='install a bleeding edge build from Git branch or tag (default: %(default)s)',
        )

    version.set_defaults(
        func=install,
        stable='cuttlefish',
        dev='master',
        version_kind='stable',
        )

    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to install on',
        )
    parser.set_defaults(
        func=install,
        )

@priority(80)
def make_uninstall(parser):
    """
    Remove Ceph packages from remote hosts.
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to uninstall Ceph from',
        )
    parser.set_defaults(
        func=uninstall,
        )

@priority(80)
def make_purge(parser):
    """
    Remove Ceph packages from remote hosts and purge all data.
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to purge Ceph from',
        )
    parser.set_defaults(
        func=purge,
        )

@priority(80)
def make_purge_data(parser):
    """
    Purge (delete, destroy, discard, shred) any Ceph data from /var/lib/ceph
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to purge Ceph data from',
        )
    parser.set_defaults(
        func=purge_data,
        )
<commit_msg>remove whitespace<commit_after>import argparse
import logging

from . import exc
from . import lsb
from .cliutil import priority
from .sudo_pushy import get_transport

LOG = logging.getLogger(__name__)

def install_suse(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    if codename == 'Mantis':
        distro='opensuse12'
    else:
        distro='sles-11sp2'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/{distro}/'.format(
        version=version,
        distro=distro,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/{distro}'.format(distro=distro)
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-{distro}{release}-{machine}-basic/ref/{version}/'.format(
            distro=distro,
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.noarch.rpm'.format(
                url=url,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'zypper',
            '--non-interactive',
            '--quiet',
            'install',
            'ceph',
            ],
        )

def uninstall_suse(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'libcephfs1',
        'librados2',
        'librbd1',
        ]
    args = [
        'zypper',
        '--non-interactive',
        '--quiet',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def uninstall_debian(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'ceph-mds',
        'ceph-common',
        'ceph-fs-common',
        ]
    args = [
        'apt-get',
        '-q',
        'remove',
        '-f',
        '-y',
        '--force-yes',
        ]
    if arg_purge:
        args.append('--purge')
    args.append('--')
    args.extend(packages)
    subprocess.check_call(args=args)

def install_fedora(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/fc{release}/'.format(
        version=version,
        release=release,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/fc{release}'.format(
        release=release,
        )
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-fc{release}-{machine}-basic/ref/{version}/'.format(
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.fc{release}.noarch.rpm'.format(
                url=url,
                release=release,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'yum',
            '-y',
            '-q',
            'install',
            'ceph',
            ],
        )

def uninstall_fedora(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        ]
    args = [
        'yum',
        '-q',
        '-y',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def install_centos(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='su -c \'rpm --import "https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc"\''.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/rpm-{version}/el6/'.format(
        version=version,
        )
    elif version_kind == 'testing':
        url = 'http://ceph.com/rpm-testing/'
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-rpm-centos{release}-{machine}-basic/ref/{version}/'.format(
            release=release.split(".",1)[0],
            machine=platform.machine(),
            version=version,
            )

    subprocess.check_call(
        args=[
            'rpm',
            '-Uvh',
            '--replacepkgs',
            '--force',
            '--quiet',
            '{url}noarch/ceph-release-1-0.el6.noarch.rpm'.format(
                url=url,
                ),
            ]
        )

    subprocess.check_call(
        args=[
            'yum',
            '-y',
            '-q',
            'install',
            'ceph',
            ],
        )

def uninstall_centos(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        ]
    args = [
        'yum',
        '-q',
        '-y',
        'remove',
        ]

    args.extend(packages)
    subprocess.check_call(args=args)

def uninstall_debian(arg_purge=False):
    import subprocess

    packages = [
        'ceph',
        'ceph-mds',
        'ceph-common',
        'ceph-fs-common',
        ]
    args = [
        'apt-get',
        '-q',
        'remove',
        '-f',
        '-y',
        '--force-yes',
        ]
    if arg_purge:
        args.append('--purge')
    args.append('--')
    args.extend(packages)
    subprocess.check_call(args=args)

def install_debian(release, codename, version_kind, version):
    import platform
    import subprocess

    if version_kind in ['stable', 'testing']:
        key = 'release'
    else:
        key = 'autobuild'

    subprocess.check_call(
        args='wget -q -O- \'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/{key}.asc\' | apt-key add -'.format(key=key),
        shell=True,
        )

    if version_kind == 'stable':
        url = 'http://ceph.com/debian-{version}/'.format(
            version=version,
            )
    elif version_kind == 'testing':
        url = 'http://ceph.com/debian-testing/'
    elif version_kind == 'dev':
        url = 'http://gitbuilder.ceph.com/ceph-deb-{codename}-{machine}-basic/ref/{version}'.format(
            codename=codename,
            machine=platform.machine(),
            version=version,
            )
    else:
        raise RuntimeError('Unknown version kind: %r' % version_kind)

    with file('/etc/apt/sources.list.d/ceph.list', 'w') as f:
        f.write('deb {url} {codename} main\n'.format(
                url=url,
                codename=codename,
                ))

    subprocess.check_call(
        args=[
            'apt-get',
            '-q',
            'update',
            ],
        )

    # TODO this does not downgrade -- should it?
    subprocess.check_call(
        args=[
            'env',
            'DEBIAN_FRONTEND=noninteractive',
            'DEBIAN_PRIORITY=critical',
            'apt-get',
            '-q',
            '-o', 'Dpkg::Options::=--force-confnew',
            'install',
            '--no-install-recommends',
            '--assume-yes',
            '--',
            'ceph',
            'ceph-mds',
            'ceph-common',
            'ceph-fs-common',
            # ceph only recommends gdisk, make sure we actually have
            # it; only really needed for osds, but minimal collateral
            'gdisk',
            ],
        )

def purge_data_any():
    import subprocess
    import os.path

    subprocess.call(args=[
            'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
            ])
    if os.path.exists('/var/lib/ceph'):
        subprocess.check_call(args=[
                'find', '/var/lib/ceph',
                '-mindepth', '1',
                '-maxdepth', '2',
                '-type', 'd',
                '-exec', 'umount', '{}', ';',
                ])
        subprocess.check_call(args=[
                'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
                ])
    subprocess.check_call(args=[
            'rm', '-rf', '--one-file-system', '--', '/etc/ceph',
            ])

def install(args):
    version = getattr(args, args.version_kind)
    version_str = args.version_kind
    if version:
        version_str += ' version {version}'.format(version=version)
    LOG.debug(
        'Installing %s on cluster %s hosts %s',
        version_str,
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s release %s codename %s', distro, release, codename)

        if (distro == 'Debian' or distro == 'Ubuntu'):
            install_r = sudo.compile(install_debian)
        elif (distro == 'CentOS' or distro == 'Scientific') or distro.startswith('RedHat'):
            install_r = sudo.compile(install_centos)
        elif distro == 'Fedora':
            install_r = sudo.compile(install_fedora)
        elif (distro == 'SUSE LINUX'):
            install_r = sudo.compile(install_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Installing on host %s ...', hostname)
        install_r(
            release=release,
            codename=codename,
            version_kind=args.version_kind,
            version=version,
            )

        sudo.close()

def uninstall(args):
    LOG.debug(
        'Uninstalling on cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s codename %s', distro, codename)

        if (distro == 'Debian' or distro == 'Ubuntu'):
            uninstall_r = sudo.compile(uninstall_debian)
        elif distro == 'CentOS' or distro == 'Scientific' or distro.startswith('RedHat'):
            uninstall_r = sudo.compile(uninstall_centos)
        elif distro == 'Fedora':
            uninstall_r = sudo.compile(uninstall_fedora)
        elif (distro == 'SUSE LINUX'):
            uninstall_r = sudo.compile(uninstall_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Uninstalling on host %s ...', hostname)
        uninstall_r()
        sudo.close()

def purge(args):
    LOG.debug(
        'Purging from cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        LOG.debug('Detecting platform for host %s ...', hostname)

        # TODO username
        sudo = args.pushy(get_transport(hostname))
        (distro, release, codename) = lsb.get_lsb_release(sudo)
        LOG.debug('Distro %s codename %s', distro, codename)

        if distro == 'Debian' or distro == 'Ubuntu':
            purge_r = sudo.compile(uninstall_debian)
        elif distro == 'CentOS' or distro == 'Scientific' or distro.startswith('RedHat'):
            purge_r = sudo.compile(uninstall_centos)
        elif distro == 'Fedora':
            purge_r = sudo.compile(uninstall_fedora)
        elif (distro == 'SUSE LINUX'):
            purge_r = sudo.compile(uninstall_suse)
        else:
            raise exc.UnsupportedPlatform(distro=distro, codename=codename)

        LOG.debug('Purging host %s ...', hostname)
        purge_r(arg_purge=True)
        sudo.close()

def purge_data(args):
    LOG.debug(
        'Purging data from cluster %s hosts %s',
        args.cluster,
        ' '.join(args.host),
        )

    for hostname in args.host:
        # TODO username
        sudo = args.pushy(get_transport(hostname))

        LOG.debug('Purging data from host %s ...', hostname)
        purge_data_any_r = sudo.compile(purge_data_any)
        purge_data_any_r()
        sudo.close()

class StoreVersion(argparse.Action):
    """
    Like ``"store"`` but also remember which one of the exclusive
    options was set.

    There are three kinds of versions: stable, testing and dev.
    This sets ``version_kind`` to be the right one of the above.

    This kludge essentially lets us differentiate explicitly set
    values from defaults.
    """
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values)
        namespace.version_kind = self.dest

@priority(20)
def make(parser):
    """
    Install Ceph packages on remote hosts.
    """

    version = parser.add_mutually_exclusive_group()

    version.add_argument(
        '--stable',
        nargs='?',
        action=StoreVersion,
        choices=[
            'bobtail',
            'cuttlefish',
            ],
        metavar='CODENAME',
        help='install a release known as CODENAME (done by default) (default: %(default)s)',
        )

    version.add_argument(
        '--testing',
        nargs=0,
        action=StoreVersion,
        help='install the latest development release',
        )

    version.add_argument(
        '--dev',
        nargs='?',
        action=StoreVersion,
        const='master',
        metavar='BRANCH_OR_TAG',
        help='install a bleeding edge build from Git branch or tag (default: %(default)s)',
        )

    version.set_defaults(
        func=install,
        stable='cuttlefish',
        dev='master',
        version_kind='stable',
        )

    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to install on',
        )
    parser.set_defaults(
        func=install,
        )

@priority(80)
def make_uninstall(parser):
    """
    Remove Ceph packages from remote hosts.
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to uninstall Ceph from',
        )
    parser.set_defaults(
        func=uninstall,
        )

@priority(80)
def make_purge(parser):
    """
    Remove Ceph packages from remote hosts and purge all data.
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to purge Ceph from',
        )
    parser.set_defaults(
        func=purge,
        )

@priority(80)
def make_purge_data(parser):
    """
    Purge (delete, destroy, discard, shred) any Ceph data from /var/lib/ceph
    """
    parser.add_argument(
        'host',
        metavar='HOST',
        nargs='+',
        help='hosts to purge Ceph data from',
        )
    parser.set_defaults(
        func=purge_data,
        )
<|endoftext|>


<commit_before>import tempfile
import shutil
import requests
import StringIO
import zipfile
import sys
import io
import itertools
from os import listdir
from os.path import join, isdir

def download(url):
    dirpath = tempfile.mkdtemp()
    shutil.rmtree(dirpath)
    r = requests.get(url)
    z = zipfile.ZipFile(StringIO.StringIO(r.content))
    z.extractall(dirpath)

def get_tldr_pages(dirpath):
    return [join(dirpath, f) for f in listdir(dirpath) if f.endswith('.md')]

def parse_file(f):
    def readline(f):
        line = f.readline()
        while line and not line.strip():
            line = f.readline()
        return line.strip()

    commands = []
    with io.open(f, encoding='utf-8') as f:
        main_command = {'cmd': '', 'desc': ''}
        line = readline(f)
        if not line.startswith('#'):
            raise Exception('Parsin err')
        main_command['cmd'] = line[1:].strip().lower()
        while 1:
            line = readline(f)
            if not line.startswith('>'):
                break
            main_command['desc'] += ','+line[1:].strip()
        #commands.append(main_command)
        while line:
            command = {'cmd': '', 'desc': ''}
            if not line.startswith('-'):
                raise Exception('Parsin err')
            command['desc'] = line[1:].strip()
            line = readline(f)
            if not line or not line.startswith('`') or not line.endswith('`'):
                raise Exception('Parsin err')
            command['cmd'] = line[1:-1]
            commands.append(command)
            line = readline(f)
            while line and line.startswith('`') and line.endswith('`'):
                commands.append({'cmd':line[1:-1], 'desc': command['desc']})
                line = readline(f)
    return commands

def process_pages(pages_dir, output_file):
    parsed = list(itertools.chain(*[parse_file(f) for f in get_tldr_pages(pages_dir)]))
    # remove duplicate commands
    # TODO, clean and optimize
    used = []
    strings = []
    for el in parsed:
        if not el['cmd'] in used:
            strings.append(el['cmd']+'##'+el['desc'])
            used.append(el['cmd'])
    with io.open(output_file, "w", encoding="utf-8") as text_file:
            text_file.write('\n'.join(sorted(strings)))

repo = '/home/aminehajyoussef/projects/tldr/'
pages_dir_path = join(repo, 'pages')
for d in listdir(pages_dir_path):
    if isdir(join(pages_dir_path, d)):
        process_pages(join(pages_dir_path, d), d+'.txt')

def _get_platform_dirs():
    dirs = ['common']
    platform = sys.platform
    if platform.startswith('linux'):
        dirs.append('linux')
    elif platform.startswith('darwin'):
        dirs.append('osx')
    elif platform.startswith('sunos'):
        dirs.append('sunos')
    return dirs

<commit_msg>didn\'t mean to push this<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*- #

from __future__ import unicode_literals
from os import environ

SITENAME = u'Kevin Richardson'
AUTHOR = u'Kevin Richardson'
TAGLINE = u'explorer & tinkerer'
SITEURL = 'http://localhost:8000'
FEED_DOMAIN = SITEURL
FEED_ATOM = 'feeds/all.atom.xml'
FEED_RSS = 'feeds/all.rss'
TIMEZONE = 'America/New_York'
DEFAULT_LANG = u'en'
DATE_FORMATS = {
    'en': '%Y-%m-%d',
}
DEFAULT_PAGINATION = 1

THEME = 'themes/pelican-foundation'

# display items
LOGO_URL = 'https://dl.dropboxusercontent.com/u/7030113/www/art-noveau-ornament.png'
MENUITEMS = (
    ('archives', '/archives.html'),
)
DISPLAY_PAGES_ON_MENU = True
FOOTER_MESSAGE = u'This work is licensed under the CC BY-SA.'
TWITTER_USERNAME = u'kfr_2'

#STATIC_PATHS = ()
FILES_TO_COPY = (
    ('extra/README', 'README'),
    ('extra/LICENSE', 'LICENSE'),
    ('extra/CNAME', 'CNAME'),
    ('extra/humans.txt', 'humans.txt'),
    ('extra/favicon.ico', 'favicon.ico'),
    ('extra/404.html', '404.html'),
)

# Plugins and their settings.
PLUGIN_PATH = 'pelican-plugins'
PLUGINS = ['sitemap', 'gist']

GITHUB_USERNAME = 'kfr2'
GITHUB_AUTH_TOKEN = environ.get('GITHUB_AUTH_TOKEN')
if GITHUB_AUTH_TOKEN is None:
    raise NotImplementedError("You should define GITHUB_AUTH_TOKEN in your OS's environment.")

SITEMAP = {
    'format': 'xml',
    'priorities': {
        'articles': 0.5,
        'indexes': 0.5,
        'pages': 0.5
    },
    'changefreqs': {
        'articles': 'weekly',
        'indexes': 'weekly',
        'pages': 'monthly'
    }
}

<commit_msg>Update Twitter handle to kfredrichardson<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*- #

from __future__ import unicode_literals
from os import environ

SITENAME = u'Kevin Richardson'
AUTHOR = u'Kevin Richardson'
TAGLINE = u'explorer & tinkerer'
SITEURL = 'http://localhost:8000'
FEED_DOMAIN = SITEURL
FEED_ATOM = 'feeds/all.atom.xml'
FEED_RSS = 'feeds/all.rss'
TIMEZONE = 'America/New_York'
DEFAULT_LANG = u'en'
DATE_FORMATS = {
    'en': '%Y-%m-%d',
}
DEFAULT_PAGINATION = 1

THEME = 'themes/pelican-foundation'

# display items
LOGO_URL = 'https://dl.dropboxusercontent.com/u/7030113/www/art-noveau-ornament.png'
MENUITEMS = (
    ('archives', '/archives.html'),
)
DISPLAY_PAGES_ON_MENU = True
FOOTER_MESSAGE = u'This work is licensed under the CC BY-SA.'
TWITTER_USERNAME = u'kfredrichardson'

#STATIC_PATHS = ()
FILES_TO_COPY = (
    ('extra/README', 'README'),
    ('extra/LICENSE', 'LICENSE'),
    ('extra/CNAME', 'CNAME'),
    ('extra/humans.txt', 'humans.txt'),
    ('extra/favicon.ico', 'favicon.ico'),
    ('extra/404.html', '404.html'),
)

# Plugins and their settings.
PLUGIN_PATH = 'pelican-plugins'
PLUGINS = ['sitemap', 'gist']

GITHUB_USERNAME = 'kfr2'
GITHUB_AUTH_TOKEN = environ.get('GITHUB_AUTH_TOKEN')
if GITHUB_AUTH_TOKEN is None:
    raise NotImplementedError("You should define GITHUB_AUTH_TOKEN in your OS's environment.")

SITEMAP = {
    'format': 'xml',
    'priorities': {
        'articles': 0.5,
        'indexes': 0.5,
        'pages': 0.5
    },
    'changefreqs': {
        'articles': 'weekly',
        'indexes': 'weekly',
        'pages': 'monthly'
    }
}

<|endoftext|>


<commit_before># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os

from cerbero.config import Platform
from cerbero.utils import shell

class Build (object):
    '''
    Base class for build handlers

    @ivar recipe: the parent recipe
    @type recipe: L{cerbero.recipe.Recipe}
    @ivar config: cerbero's configuration
    @type config: L{cerbero.config.Config}
    '''

    _properties_keys = []

    def configure(self):
        '''
        Configures the module
        '''
        raise NotImplemented("'configure' must be implemented by subclasses")

    def compile(self):
        '''
        Compiles the module
        '''
        raise NotImplemented("'make' must be implemented by subclasses")

    def install(self):
        '''
        Installs the module
        '''
        raise NotImplemented("'install' must be implemented by subclasses")

    def check(self):
        '''
        Runs any checks on the module
        '''
        pass

class CustomBuild(Build):

    def configure(self):
        pass

    def compile(self):
        pass

    def install(self):
        pass

class MakefilesBase (Build):
    '''
    Base class for makefiles build systems like autotools and cmake
    '''

    config_sh = ''
    configure_tpl = ''
    configure_options = ''
    force_configure = False
    make = 'make'
    make_install = 'make install'
    make_check = None
    make_clean = 'make clean'
    use_system_libs = False
    allow_parallel_build = False
    srcdir = '.'

    def __init__(self):
        self._with_system_libs = False
        Build.__init__(self)
        self.make_dir = os.path.abspath(os.path.join(self.build_dir,
                                                     self.srcdir))
        if self.config.allow_parallel_build and self.allow_parallel_build \
                and self.config.num_of_cpus > 1:
            self.make += ' -j%d' % self.config.num_of_cpus

    def system_libs(func):
        ''' Decorator to use system libs'''
        def call(*args):
            self = args[0]
            if self.use_system_libs and self.config.allow_system_libs:
                self._add_system_libs()
            res = func(*args)
            if self.use_system_libs and self.config.allow_system_libs:
                self._restore_pkg_config_path()
            return res

        call.func_name = func.func_name
        return call

    @system_libs
    def configure(self):
        shell.call(self.configure_tpl % {'config-sh': self.config_sh,
                                          'prefix': self.config.prefix,
                                          'libdir': self.config.libdir,
                                          'host': self.config.host,
                                          'target': self.config.target,
                                          'build': self.config.build,
                                          'options': self.configure_options},
                    self.make_dir)

    @system_libs
    def compile(self):
        shell.call(self.make, self.make_dir)

    @system_libs
    def install(self):
        shell.call(self.make_install, self.make_dir)

    @system_libs
    def clean(self):
        shell.call(self.make_clean, self.make_dir)

    @system_libs
    def check(self):
        if self.make_check:
            shell.call(self.make_check, self.build_dir)

    def _add_system_libs(self):
        if self._with_system_libs:
            # Don't mess the env too much
            return
        self.pkgconfiglibdir = os.environ['PKG_CONFIG_LIBDIR']
        self.pkgconfigpath = os.environ['PKG_CONFIG_PATH']
        os.environ['PKG_CONFIG_PATH'] = '%s:%s' % (self.pkgconfigpath,
                                                   self.pkgconfiglibdir)
        del os.environ['PKG_CONFIG_LIBDIR']
        self._with_system_libs = True

    def _restore_pkg_config_path(self):
        os.environ['PKG_CONFIG_PATH'] = self.pkgconfigpath
        os.environ['PKG_CONFIG_LIBDIR'] = self.pkgconfiglibdir
        self._with_system_libs = False

class Autotools (MakefilesBase):
    '''
    Build handler for autotools project
    '''

    autoreconf = False
    autoreconf_sh = 'autoreconf -f -i'
    config_sh = './configure'
    configure_tpl = "%(config-sh)s --prefix %(prefix)s "\
                    "--libdir %(libdir)s %(options)s"
    make_check = 'make check'
    add_host_build_target = True
    can_use_configure_cache = True
    supports_cache_variables = True

    def configure(self):
        if self.supports_non_src_build:
            self.config_sh = os.path.join(self.repo_dir, self.config_sh)
        # skip configure if we are already configured
        if os.path.exists(os.path.join(self.make_dir, 'configure')) and\
                os.path.exists(os.path.join(self.make_dir, 'Makefile')):
            if not self.force_configure and not self.force:
                return

        # Only use --disable-maintainer mode for real autotools based projects
        if os.path.exists(os.path.join(self.make_dir, 'configure.in')) or\
                os.path.exists(os.path.join(self.make_dir, 'configure.ac')):
            self.configure_tpl += " --disable-maintainer-mode"

        if self.autoreconf:
            shell.call(self.autoreconf_sh, self.make_dir)

        if self.config.platform == Platform.WINDOWS and \
                self.supports_cache_variables:
            # On windows, environment variables are upperscase, but we still
            # need to pass things like am_cv_python_platform in lowercase for
            # configure and autogen.sh
            for k, v in os.environ.iteritems():
                if k.islower():
                    self.configure_tpl += ' %s="%s"' % (k, v)

        if self.add_host_build_target:
            if self.config.host is not None:
                self.configure_tpl += ' --host=%(host)s'
            if self.config.build is not None:
                self.configure_tpl += ' --build=%(build)s'
            if self.config.target is not None:
                self.configure_tpl += ' --target=%(target)s'

        if self.config.use_configure_cache and self.can_use_configure_cache:
            cache = os.path.join(self.config.prefix, '.configure.cache')
            self.config_sh += ' --cache-file=%s' % cache

        MakefilesBase.configure(self)

class CMake (MakefilesBase):
    '''
    Build handler for cmake projects
    '''

    config_sh = 'cmake'
    configure_tpl = '%(config-sh)s -DCMAKE_INSTALL_PREFIX=%(prefix)s '\
                    '-DCMAKE_LIBRARY_OUTPUT_PATH=%(libdir)s %(options)s '\
                    '-DCMAKE_BUILD_TYPE=Release '\
                    '-DCMAKE_FIND_ROOT_PATH=$CERBERO_PREFIX '

    def __init__(self):
        MakefilesBase.__init__(self)
        if self.config.target_platform == Platform.WINDOWS:
            self.configure_tpl += ' -DCMAKE_C_COMPILER=$CC '
            self.configure_options += ' -DCMAKE_SYSTEM_NAME=Windows '
        self.configure_options += ' -DLIB_SUFFIX=%s ' % self.config.lib_suffix

class BuildType (object):

    CUSTOM = CustomBuild
    MAKEFILE = MakefilesBase
    AUTOTOOLS = Autotools
    CMAKE = CMake
<commit_msg>build: unify cmake options<commit_after># cerbero - a multi-platform build system for Open Source software
# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import os

from cerbero.config import Platform
from cerbero.utils import shell

class Build (object):
    '''
    Base class for build handlers

    @ivar recipe: the parent recipe
    @type recipe: L{cerbero.recipe.Recipe}
    @ivar config: cerbero's configuration
    @type config: L{cerbero.config.Config}
    '''

    _properties_keys = []

    def configure(self):
        '''
        Configures the module
        '''
        raise NotImplemented("'configure' must be implemented by subclasses")

    def compile(self):
        '''
        Compiles the module
        '''
        raise NotImplemented("'make' must be implemented by subclasses")

    def install(self):
        '''
        Installs the module
        '''
        raise NotImplemented("'install' must be implemented by subclasses")

    def check(self):
        '''
        Runs any checks on the module
        '''
        pass

class CustomBuild(Build):

    def configure(self):
        pass

    def compile(self):
        pass

    def install(self):
        pass

class MakefilesBase (Build):
    '''
    Base class for makefiles build systems like autotools and cmake
    '''

    config_sh = ''
    configure_tpl = ''
    configure_options = ''
    force_configure = False
    make = 'make'
    make_install = 'make install'
    make_check = None
    make_clean = 'make clean'
    use_system_libs = False
    allow_parallel_build = False
    srcdir = '.'

    def __init__(self):
        self._with_system_libs = False
        Build.__init__(self)
        self.make_dir = os.path.abspath(os.path.join(self.build_dir,
                                                     self.srcdir))
        if self.config.allow_parallel_build and self.allow_parallel_build \
                and self.config.num_of_cpus > 1:
            self.make += ' -j%d' % self.config.num_of_cpus

    def system_libs(func):
        ''' Decorator to use system libs'''
        def call(*args):
            self = args[0]
            if self.use_system_libs and self.config.allow_system_libs:
                self._add_system_libs()
            res = func(*args)
            if self.use_system_libs and self.config.allow_system_libs:
                self._restore_pkg_config_path()
            return res

        call.func_name = func.func_name
        return call

    @system_libs
    def configure(self):
        shell.call(self.configure_tpl % {'config-sh': self.config_sh,
                                          'prefix': self.config.prefix,
                                          'libdir': self.config.libdir,
                                          'host': self.config.host,
                                          'target': self.config.target,
                                          'build': self.config.build,
                                          'options': self.configure_options},
                    self.make_dir)

    @system_libs
    def compile(self):
        shell.call(self.make, self.make_dir)

    @system_libs
    def install(self):
        shell.call(self.make_install, self.make_dir)

    @system_libs
    def clean(self):
        shell.call(self.make_clean, self.make_dir)

    @system_libs
    def check(self):
        if self.make_check:
            shell.call(self.make_check, self.build_dir)

    def _add_system_libs(self):
        if self._with_system_libs:
            # Don't mess the env too much
            return
        self.pkgconfiglibdir = os.environ['PKG_CONFIG_LIBDIR']
        self.pkgconfigpath = os.environ['PKG_CONFIG_PATH']
        os.environ['PKG_CONFIG_PATH'] = '%s:%s' % (self.pkgconfigpath,
                                                   self.pkgconfiglibdir)
        del os.environ['PKG_CONFIG_LIBDIR']
        self._with_system_libs = True

    def _restore_pkg_config_path(self):
        os.environ['PKG_CONFIG_PATH'] = self.pkgconfigpath
        os.environ['PKG_CONFIG_LIBDIR'] = self.pkgconfiglibdir
        self._with_system_libs = False

class Autotools (MakefilesBase):
    '''
    Build handler for autotools project
    '''

    autoreconf = False
    autoreconf_sh = 'autoreconf -f -i'
    config_sh = './configure'
    configure_tpl = "%(config-sh)s --prefix %(prefix)s "\
                    "--libdir %(libdir)s %(options)s"
    make_check = 'make check'
    add_host_build_target = True
    can_use_configure_cache = True
    supports_cache_variables = True

    def configure(self):
        if self.supports_non_src_build:
            self.config_sh = os.path.join(self.repo_dir, self.config_sh)
        # skip configure if we are already configured
        if os.path.exists(os.path.join(self.make_dir, 'configure')) and\
                os.path.exists(os.path.join(self.make_dir, 'Makefile')):
            if not self.force_configure and not self.force:
                return

        # Only use --disable-maintainer mode for real autotools based projects
        if os.path.exists(os.path.join(self.make_dir, 'configure.in')) or\
                os.path.exists(os.path.join(self.make_dir, 'configure.ac')):
            self.configure_tpl += " --disable-maintainer-mode"

        if self.autoreconf:
            shell.call(self.autoreconf_sh, self.make_dir)

        if self.config.platform == Platform.WINDOWS and \
                self.supports_cache_variables:
            # On windows, environment variables are upperscase, but we still
            # need to pass things like am_cv_python_platform in lowercase for
            # configure and autogen.sh
            for k, v in os.environ.iteritems():
                if k.islower():
                    self.configure_tpl += ' %s="%s"' % (k, v)

        if self.add_host_build_target:
            if self.config.host is not None:
                self.configure_tpl += ' --host=%(host)s'
            if self.config.build is not None:
                self.configure_tpl += ' --build=%(build)s'
            if self.config.target is not None:
                self.configure_tpl += ' --target=%(target)s'

        if self.config.use_configure_cache and self.can_use_configure_cache:
            cache = os.path.join(self.config.prefix, '.configure.cache')
            self.config_sh += ' --cache-file=%s' % cache

        MakefilesBase.configure(self)

class CMake (MakefilesBase):
    '''
    Build handler for cmake projects
    '''

    config_sh = 'cmake'
    configure_tpl = '%(config-sh)s -DCMAKE_INSTALL_PREFIX=%(prefix)s '\
                    '-DCMAKE_LIBRARY_OUTPUT_PATH=%(libdir)s %(options)s '\
                    '-DCMAKE_BUILD_TYPE=Release '\
                    '-DCMAKE_FIND_ROOT_PATH=$CERBERO_PREFIX '

    def __init__(self):
        MakefilesBase.__init__(self)
        if self.config.target_platform == Platform.WINDOWS:
            self.configure_options += ' -DCMAKE_C_COMPILER=$CC '\
                                      ' -DCMAKE_SYSTEM_NAME=Windows '
        self.configure_options += ' -DLIB_SUFFIX=%s ' % self.config.lib_suffix

class BuildType (object):

    CUSTOM = CustomBuild
    MAKEFILE = MakefilesBase
    AUTOTOOLS = Autotools
    CMAKE = CMake
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

AUTHOR = 'Samuel Roeca'
SITENAME = 'Software Journeyman'

JINJA_ENVIRONMENT = {
    'extensions': [
        'jinja2.ext.i18n',
    ],
}

USE_FOLDER_AS_CATEGORY = True

PATH = 'content'

TIMEZONE = 'EST'

DEFAULT_LANG = 'en'
I18N_TEMPLATES_LANG = 'en'

# Feed generation is usually not desired when developing
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
TRANSLATION_FEED_ATOM = None
AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None

DEFAULT_PAGINATION = 10

# Uncomment following line if you want document-relative URLs when developing
#RELATIVE_URLS = True

# How to extract data from filename
# Currently, only does the slug
# FILENAME_METADATA = '(?P<date>\d{4}-\d{2}-\d{2})_(?P<slug>.*)'
FILENAME_METADATA = '(?P<slug>.*)'

# Ignore caching
LOAD_CONTENT_CACHE = False

# static pathes for publishing
STATIC_PATHS = [
    'images',
    'theme/images',
    'gif',
]

# Code blocks
PYGMENTS_RST_OPTIONS = {
    'linenos': 'inline',  # enable line numbers
}

#######################################################################
# Flex theme-specific configurations
#######################################################################

THEME = 'pelican-themes/Flex'

FAVICON = '/theme/images/favicon.ico'
PYGMENTS_STYLE = 'tango'

SITESUBTITLE = "Sam Roeca's Blog"
SITEDESCRIPTION = "Samuel Roeca's blog"
SITEURL = 'http://localhost:8000'
SITELOGO = '/images/sam-headshot-kepler-300x300.jpg'

MAIN_MENU = True

LINKS = (
    # ('About', '/pages/about.html'),
)

SOCIAL = (
    ('github', 'https://github.com/pappasam'),
    ('linkedin-square', 'https://www.linkedin.com/in/samuel-roeca-23010735'),
    ('facebook','https://www.facebook.com/sam.roeca'),
    ('twitter', 'https://twitter.com/SamRoeca'),
    ('envelope-o', 'mailto:samuel.roeca@gmail.com'),
)

DIRECT_TEMPLATES = [
    'index',
    'categories',
    'authors',
    'archives',
    'tags',
]

MENUITEMS = (
    ('Archives', '/archives.html'),
    ('Categories', '/categories.html'),
    ('Tags', '/tags.html'),
)

#######################################################################
# Pelican Plugins
#######################################################################

PLUGIN_PATHS = ['pelican-plugins']
PLUGINS = [
    'i18n_subsites',
    'sitemap',
    'extract_toc',
    'tipue_search',        # this must be modified for now to work
    'neighbors',
    'assets',              # minifies css assets
    'code_include',
]

# tipue_search
#   see http://archerimagine.com/articles/pelican/integration-problem-with-elegant-theme.html#missing-icons-for-social-links
#   manually modify

# sitemap
SITEMAP = {
    'format': 'xml',
    'priorities': {
        'articles': 1,
        'pages': 1,
        'indexes': 1,
    },
    'changefreqs': {
        'articles': 'always',
        'pages': 'always',
        'indexes': 'always',
    },
}
<commit_msg>Add youtube link<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals

AUTHOR = 'Samuel Roeca'
SITENAME = 'Software Journeyman'

JINJA_ENVIRONMENT = {
    'extensions': [
        'jinja2.ext.i18n',
    ],
}

USE_FOLDER_AS_CATEGORY = True

PATH = 'content'

TIMEZONE = 'EST'

DEFAULT_LANG = 'en'
I18N_TEMPLATES_LANG = 'en'

# Feed generation is usually not desired when developing
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
TRANSLATION_FEED_ATOM = None
AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None

DEFAULT_PAGINATION = 10

# Uncomment following line if you want document-relative URLs when developing
#RELATIVE_URLS = True

# How to extract data from filename
# Currently, only does the slug
# FILENAME_METADATA = '(?P<date>\d{4}-\d{2}-\d{2})_(?P<slug>.*)'
FILENAME_METADATA = '(?P<slug>.*)'

# Ignore caching
LOAD_CONTENT_CACHE = False

# static pathes for publishing
STATIC_PATHS = [
    'images',
    'theme/images',
    'gif',
]

# Code blocks
PYGMENTS_RST_OPTIONS = {
    'linenos': 'inline',  # enable line numbers
}

#######################################################################
# Flex theme-specific configurations
#######################################################################

THEME = 'pelican-themes/Flex'

FAVICON = '/theme/images/favicon.ico'
PYGMENTS_STYLE = 'tango'

SITESUBTITLE = "Sam Roeca's Blog"
SITEDESCRIPTION = "Samuel Roeca's blog"
SITEURL = 'http://localhost:8000'
SITELOGO = '/images/sam-headshot-kepler-300x300.jpg'

MAIN_MENU = True

LINKS = (
    # ('About', '/pages/about.html'),
)

SOCIAL = (
    ('github', 'https://github.com/pappasam'),
    ('linkedin-square', 'https://www.linkedin.com/in/samuel-roeca-23010735'),
    ('facebook','https://www.facebook.com/sam.roeca'),
    ('twitter', 'https://twitter.com/SamRoeca'),
    ('youtube', 'https://www.youtube.com/channel/UCjORdFKiDlqzzW7bWYqXuKA?view_as=subscriber'),
    ('envelope-o', 'mailto:samuel.roeca@gmail.com'),
)

DIRECT_TEMPLATES = [
    'index',
    'categories',
    'authors',
    'archives',
    'tags',
]

MENUITEMS = (
    ('Archives', '/archives.html'),
    ('Categories', '/categories.html'),
    ('Tags', '/tags.html'),
)

#######################################################################
# Pelican Plugins
#######################################################################

PLUGIN_PATHS = ['pelican-plugins']
PLUGINS = [
    'i18n_subsites',
    'sitemap',
    'extract_toc',
    'tipue_search',        # this must be modified for now to work
    'neighbors',
    'assets',              # minifies css assets
    'code_include',
]

# tipue_search
#   see http://archerimagine.com/articles/pelican/integration-problem-with-elegant-theme.html#missing-icons-for-social-links
#   manually modify

# sitemap
SITEMAP = {
    'format': 'xml',
    'priorities': {
        'articles': 1,
        'pages': 1,
        'indexes': 1,
    },
    'changefreqs': {
        'articles': 'always',
        'pages': 'always',
        'indexes': 'always',
    },
}
<|endoftext|>