-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #186 from kula1922/feature/script-to-generate-end-…
…date-of-deprecation Added commands to generate reports from database and base command class
- Loading branch information
Showing
36 changed files
with
787 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
54
src/ralph_pricing/management/commands/pricing_asset_models.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
124
src/ralph_pricing/management/commands/pricing_assets_with_devices.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
80
src/ralph_pricing/management/commands/pricing_fix_blades.py
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.