Skip to content

Commit

Permalink
Merge pull request #186 from kula1922/feature/script-to-generate-end-…
Browse files Browse the repository at this point in the history
…date-of-deprecation

Added commands to generate reports from database and base command class
  • Loading branch information
mkurek committed Jul 25, 2014
2 parents a2c3e73 + 17a5753 commit f87339f
Show file tree
Hide file tree
Showing 36 changed files with 787 additions and 109 deletions.
101 changes: 101 additions & 0 deletions src/ralph_pricing/management/commands/_pricing_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import abc
import logging
import textwrap
from optparse import make_option

from bob.csvutil import UnicodeWriter
from django.core.management.base import BaseCommand


logger = logging.getLogger(__name__)

DEFAULT_ENCODING = 'utf-8'
DEFAULT_CSV_ENCODING = 'cp1250'


class PricingBaseCommand(BaseCommand):
"""
Class contains standard options like generate to csv or generate to file.
"""

__metaclass__ = abc.ABCMeta

HEADERS = []
requires_model_validation = True
option_list = BaseCommand.option_list + (
make_option(
'-d', '--delimiter',
dest='delimiter',
default=';',
help="Delimiter for csv file",
),
make_option(
'-e', '--encoding',
dest='encoding',
default=None,
help="Output encoding",
),
make_option(
'-f', '--file_path',
dest='file_path',
default=None,
help="Name of file of generated report",
),
)

@property
def help(self):
return textwrap.dedent(self.__doc__).strip()

@abc.abstractmethod
def get_data(self, *args, **options):
"""
Abstract Method for collects and prepare data
:return list results: list of lists, nested list represents single row
"""
pass

def get_prepared_data(self, *args, **options):
"""
Prepare data for print on screen or send to client. For example
encoding each cell.
:return list results: list of lists, nested list represents single row
"""
data = self.get_data(*args, **options)
return [self.HEADERS] + map(lambda x: map(unicode, x), data)

def handle(self, *args, **options):
"""
Main method, use methods for colleting data and send results on screen
:param string delimiter: Delimiter for csv format
"""
# apply default encoding depending on output type
if not options.get('encoding'):
if options['file_path']:
options['encoding'] = DEFAULT_CSV_ENCODING
else:
options['encoding'] = DEFAULT_ENCODING

if options['file_path']:
writer = UnicodeWriter(
open(options['file_path'], 'w'),
delimiter=str(options['delimiter']),
encoding=options['encoding'],
)
else:
writer = UnicodeWriter(
self.stdout,
delimiter=str(options['delimiter']),
encoding=options['encoding'],
)
writer.writerows(self.get_prepared_data(*args, **options))
54 changes: 54 additions & 0 deletions src/ralph_pricing/management/commands/pricing_asset_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import logging

from django.db.models import Count

from ralph_assets.models import AssetModel
from ralph_pricing.management.commands._pricing_base import PricingBaseCommand


logger = logging.getLogger(__name__)


class Command(PricingBaseCommand):
"""Generate report with assets, devices and date of end deprecation"""
HEADERS = [
'Asset Model Name',
'Manufacturer',
'Category',
'Power consumption',
'Height of device',
'Cores count',
'Type',
'Assets count',
]

def get_data(self, *args, **options):
"""
Collect assets from data center and match it to devices from ralph.
Calculate date of end deprecation.
:param string file_path: path to file
"""
results = []
asset_models = AssetModel.objects.annotate(
assets_count=Count('assets'),
)
for asset_model in asset_models:
results.append([
asset_model.name,
asset_model.manufacturer,
asset_model.category,
asset_model.power_consumption,
asset_model.height_of_device,
asset_model.cores_count,
asset_model.type,
asset_model.assets_count,
])
return results
124 changes: 124 additions & 0 deletions src/ralph_pricing/management/commands/pricing_assets_with_devices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import logging

from dateutil.relativedelta import relativedelta

from ralph.discovery.models import Device
from ralph_assets.models import Asset, AssetType
from ralph_pricing.management.commands._pricing_base import PricingBaseCommand


logger = logging.getLogger(__name__)


class Command(PricingBaseCommand):
"""Generate report with assets, devices and date of end deprecation"""
HEADERS = [
'Asset ID',
'Asset SN',
'Asset Barcode',
'Venture',
'Device Name',
'Deprecated date',
]

def get_data(self, *args, **options):
"""
Collect assets from data center and match it to devices from ralph.
Calculate date of end deprecation.
:param string file_path: path to file
"""
results = []
assets = Asset.objects.filter(
type=AssetType.data_center
).select_related('device_info').order_by('id')
devices = self.get_device_ids_and_names(assets)

for asset in assets:
results.append([
asset.id,
asset.sn,
asset.barcode,
asset.venture,
self.get_device_name_from_asset(asset, devices),
self.get_deprecated_date(asset),
])

return results

def get_device_name_from_asset(self, asset, devices):
"""
Choose template and create results container. For example csv
require headers.
:param object asset: Single asset object
:param dict devices: Dict with device id as key and name as value
:returns string: name of device or None
:rtype string:
"""
if asset.device_info and asset.device_info.ralph_device_id:
return devices[asset.device_info.ralph_device_id]

def _get_device_ids(self, assets):
"""
Create list of device id matched with assets.
:param object assets: Assets for which device ids will return
:returns list: List of device ids
:rtype list:
"""
device_ids = []
for asset in assets:
if asset.device_info:
device_ids.append(asset.device_info.ralph_device_id)
return device_ids

def _get_ralph_devices(self, assets):
"""
Get ralph devices.
:param object assets: Assets for which device ids will return
:returns list: List of devices from ralph
:rtype list:
"""
return Device.objects.filter(
id__in=self._get_device_ids(assets)
)

def get_device_ids_and_names(self, assets):
"""
Generate dict with device id as a name and device name as value
:param object assets: Assets for which device ids will return
:returns list: List of device ids and names
:rtype list:
"""
devices = {}
for device in self._get_ralph_devices(assets):
devices[device.id] = device.name
return devices

def get_deprecated_date(self, asset):
"""
Calculate end deprecation date for single asset
:param object asset: Single asset
:returns string: Date of end deprecation or message
:rtype string:
"""
if asset.force_deprecation:
return 'Deprecated'
if not asset.invoice_date:
return 'No invoice date'
if asset.deprecation_end_date:
return asset.deprecation_end_date
return asset.invoice_date + relativedelta(
months=asset.get_deprecation_months(),
)
80 changes: 0 additions & 80 deletions src/ralph_pricing/management/commands/pricing_fix_blades.py

This file was deleted.

Loading

0 comments on commit f87339f

Please sign in to comment.