Permalink
Browse files

Merge branch 'refactoring' into dns

  • Loading branch information...
2 parents f7a46a7 + 41da806 commit d42c3e683bd3140812ecfbcf8f5ddfd5d48d407f @sigsalerno sigsalerno committed Dec 19, 2012
Showing with 843 additions and 104 deletions.
  1. +1 −0 nodeshot/__init__.py
  2. +46 −0 nodeshot/contrib/hardware/admin.py
  3. +74 −0 nodeshot/contrib/hardware/fixtures/device_models.json
  4. +38 −0 nodeshot/contrib/hardware/fixtures/manufacturers.json
  5. +74 −8 nodeshot/contrib/hardware/models.py
  6. +1 −1 nodeshot/core/api/urls.py
  7. +0 −3 nodeshot/core/base/admin.py
  8. +10 −0 nodeshot/core/base/choices.py
  9. +21 −0 nodeshot/core/base/managers.py
  10. +33 −0 nodeshot/core/base/resources.py
  11. +2 −1 nodeshot/core/mailing/models/inward.py
  12. +59 −39 nodeshot/core/mailing/resources.py
  13. +1 −1 nodeshot/core/network/admin.py
  14. +10 −1 nodeshot/core/network/models/ip.py
  15. +17 −15 nodeshot/core/nodes/resources.py
  16. +1 −1 nodeshot/core/services/admin.py
  17. +3 −3 nodeshot/core/zones/admin.py
  18. +7 −3 nodeshot/core/zones/fixtures/test_zones.json
  19. 0 nodeshot/core/zones/management/__init__.py
  20. 0 nodeshot/core/zones/management/commands/__init__.py
  21. +79 −0 nodeshot/core/zones/management/commands/externalzones.py
  22. +14 −0 nodeshot/core/zones/managers.py
  23. +6 −6 nodeshot/core/zones/models/zone.py
  24. +32 −6 nodeshot/core/zones/models/zone_external.py
  25. +30 −9 nodeshot/core/zones/resources.py
  26. +46 −0 nodeshot/dependencies/widgets.py
  27. 0 nodeshot/extra/__init__.py
  28. +64 −0 nodeshot/extra/interoperability/BaseInterop.py
  29. +48 −0 nodeshot/extra/interoperability/GeoRSS.py
  30. +58 −0 nodeshot/extra/interoperability/NodeshotOld.py
  31. +39 −0 nodeshot/extra/interoperability/ProvinciaWIFI.py
  32. 0 nodeshot/extra/interoperability/__init__.py
  33. +19 −7 projects/ninux/ninux/settings.example.py
  34. +10 −0 requirements.txt
View
@@ -0,0 +1 @@
+VERSION = (2, 0, 'alpha', 0)
@@ -0,0 +1,46 @@
+from django.contrib import admin
+from django.conf import settings
+from django.db import models
+from nodeshot.core.base.admin import BaseAdmin, BaseStackedInline
+from nodeshot.dependencies.widgets import AdvancedFileInput
+from models import Manufacturer, MacPrefix, DeviceModel, Device2Model
+
+class MacPrefixInline(admin.StackedInline):
+ model = MacPrefix
+ extra = 0
+ inline_classes = ('grp-collapse grp-open',)
+
+class ManufacturerAdmin(BaseAdmin):
+ list_display = ('name', 'logo_img_tag', 'url_tag', 'added', 'updated')
+ list_display_links = ('name', 'logo_img_tag')
+ search_fields = ('name',)
+ inlines = [MacPrefixInline]
+
+ formfield_overrides = {
+ models.ImageField: {'widget': AdvancedFileInput(image_width=250)},
+ }
+
+class DeviceModelAdmin(BaseAdmin):
+ list_display = ('name', 'image_img_tag', 'added', 'updated')
+ list_display_links = ('name', 'image_img_tag')
+ search_fields = ('name',)
+
+ formfield_overrides = {
+ models.ImageField: {'widget': AdvancedFileInput(image_width=250)},
+ }
+
+admin.site.register(Manufacturer, ManufacturerAdmin)
+admin.site.register(DeviceModel, DeviceModelAdmin)
+
+from nodeshot.core.network.models import Device
+from nodeshot.core.network.admin import DeviceAdmin
+
+class Device2ModelInline(admin.StackedInline):
+ model = Device2Model
+ inline_classes = ('grp-collapse grp-open',)
+
+class ExtendedDeviceAdmin(DeviceAdmin):
+ inlines = DeviceAdmin.inlines.insert(0, Device2ModelInline)
+
+admin.site.unregister(Device)
+admin.site.register(Device, DeviceAdmin)
@@ -0,0 +1,74 @@
+[
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 1,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanostation M5",
+ "image": "devices/images/nanostationM5.jpg",
+ "datasheet": "devices/datasheets/nanostationM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ },
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 2,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanostation M2",
+ "image": "devices/images/nanostationM2.jpg",
+ "datasheet": "devices/datasheets/nanostationM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ },
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 3,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanostation Loco M5",
+ "image": "devices/images/nanostation-loco-M5.jpg",
+ "datasheet": "devices/datasheets/nanostationM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ },
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 4,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanostation Loco M2",
+ "image": "devices/images/nanostation-loco-M5.jpg",
+ "datasheet": "devices/datasheets/nanostationM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ },
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 5,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanobridge M5",
+ "image": "devices/images/nanobridgeM5.jpg",
+ "datasheet": "devices/datasheets/nanobridgeM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ },
+ {
+ "model": "hardware.DeviceModel",
+ "pk": 6,
+ "fields": {
+ "manufacturer": 1,
+ "name": "Nanobridge M2",
+ "image": "devices/images/nanobridgeM2.jpg",
+ "datasheet": "devices/datasheets/nanobridgeM.pdf",
+ "cpu": "Atheros MIPS 24KC, 400 MHz",
+ "ram": "33554432"
+ }
+ }
+]
@@ -0,0 +1,38 @@
+[
+ {
+ "model": "hardware.Manufacturer",
+ "pk": 1,
+ "fields": {
+ "name": "Ubiquiti Networks",
+ "url": "http://www.ubnt.com/",
+ "logo": "manufacturers/ubiquiti.png"
+ }
+ },
+ {
+ "model": "hardware.Manufacturer",
+ "pk": 2,
+ "fields": {
+ "name": "Mikrotic",
+ "url": "http://www.mikrotik.com/",
+ "logo": "manufacturers/mikrotic.png"
+ }
+ },
+ {
+ "model": "hardware.Manufacturer",
+ "pk": 3,
+ "fields": {
+ "name": "D-Link",
+ "url": "http://www.dlink.com/",
+ "logo": "manufacturers/dlink.jpg"
+ }
+ },
+ {
+ "model": "hardware.Manufacturer",
+ "pk": 4,
+ "fields": {
+ "name": "TP-Link",
+ "url": "http://www.tp-link.com/",
+ "logo": "manufacturers/tplink.png"
+ }
+ }
+]
@@ -1,25 +1,91 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
+from django.conf import settings
from nodeshot.core.base.models import BaseDate, BaseAccessLevel
from nodeshot.core.network.models import Device, Interface
from nodeshot.core.base.choices import POLARIZATIONS
-class Manufacturer(BaseDate):
- name = models.CharField(_('name'), max_length=50)
+class Manufacturer(BaseDate):
+ name = models.CharField(_('name'), max_length=50, unique=True)
url = models.URLField(_('url'))
+ logo = models.ImageField(_('logo'), blank=True, upload_to='manufacturers/')
+
+ class Meta:
+ verbose_name = _('Manufacturer')
+ verbose_name_plural = _('Manufacturers')
+ ordering = ['name']
+
+ def __unicode__(self, *args, **kwargs):
+ return self.name
+
+ def url_tag(self):
+ return '<a href="%s" target="_blank">%s</a>' % (self.url, self.url)
+
+ def logo_url(self):
+ return '%s%s' % (settings.MEDIA_URL, self.logo)
+
+ def logo_img_tag(self):
+ return '<img src="%s" alt="" style="width:250px" />' % self.logo_url()
+
+ url_tag.allow_tags = True
+ logo_img_tag.allow_tags = True
+
+class MacPrefix(models.Model):
+ manufacturer = models.ForeignKey(Manufacturer, verbose_name=_('manufacturer'))
+ prefix = models.CharField(_('mac address prefix'), max_length=8, unique=True)
+
+ class Meta:
+ verbose_name = _('MAC Prefix')
+ verbose_name_plural = _('MAC Prefixes')
class DeviceModel(BaseDate):
- name = models.CharField(_('name'), max_length=50, unique=True)
manufacturer = models.ForeignKey(Manufacturer)
- image = models.ImageField(_('image'), upload_to='devices/images/', blank=True, null=True)
- manual = models.FileField(_('manual'), upload_to='devices/manuals/', blank=True, null=True)
- mac_prefix = models.CharField(_('mac address prefix'), max_length=17, blank=True, null=True)
+ name = models.CharField(_('name'), max_length=50, unique=True)
+ image = models.ImageField(_('image'), upload_to='devices/images/', blank=True)
+ datasheet = models.FileField(_('datasheet'), upload_to='devices/datasheets/', blank=True)
+ cpu = models.CharField(_('CPU'), max_length=255, blank=True)
+ ram = models.IntegerField(_('RAM'), blank=True)
class Meta:
db_table = 'hardware_device_model'
+ verbose_name = _('Device Model')
+ verbose_name_plural = _('Device Models')
+
+ def __unicode__(self, *args, **kwargs):
+ return self.name
+
+ def image_url(self):
+ return '%s%s' % (settings.MEDIA_URL, self.image)
+
+ def image_img_tag(self):
+ return '<img src="%s" alt="" style="width:80px" />' % self.image_url()
+
+ image_img_tag.allow_tags = True
-class Devicel2Model(models.Model):
+class Device2Model(models.Model):
device = models.OneToOneField(Device, verbose_name=_('device'))
+ model = models.ForeignKey(DeviceModel)
+ cpu = models.CharField(_('CPU'), max_length=255, blank=True)
+ ram = models.IntegerField(_('RAM'), blank=True)
+
+ class Meta:
+ verbose_name = _('Device Model Information')
+ verbose_name_plural = _('Device Model Information')
+
+ def __unicode__(self):
+ return '%s (%s)' % (self.device.name, self.model.name)
+
+ def save(self, *args, **kwargs):
+ """ when creating a new record fill CPU and RAM info if available """
+ if not self.id or (not self.cpu and not self.ram):
+ # if self.model.cpu is not empty
+ if self.model.cpu:
+ self.cpu = self.model.cpu
+ # if self.model.ram is not empty
+ if self.model.ram:
+ self.ram = self.model.ram
+
+ super(Device2Model, self).save(*args, **kwargs)
class AntennaModel(BaseDate):
name = models.CharField(_('name'), max_length=50, unique=True)
@@ -36,8 +102,8 @@ class Meta:
db_table = 'hardware_antenna_model'
class Antenna(BaseDate):
- radio = models.ForeignKey(Interface)
model = models.ForeignKey(AntennaModel)
+ radio = models.ForeignKey(Interface)
polarization = models.CharField(_('Polarization'), max_length='20', choices=POLARIZATIONS)
azimuth = models.FloatField(_('azimuth'))
elevation = models.FloatField(_('elevation'))
@@ -27,7 +27,7 @@
# loop over attributes and determine which resources will be imported
for attr in attrs:
# select only attributes which are named SomethingResource except ModelResource wich is a base class
- if 'Resource' in attr and attr != 'ModelResource':
+ if 'Resource' in attr and attr != 'ModelResource' and attr != 'Resource':
# register resource
# eg: v1_api.register(NodeResource())
v1_api.register(getattr(resources, attr)())
@@ -9,9 +9,6 @@ class BaseAdmin(admin.ModelAdmin):
save_on_top = True
readonly_fields = ['added', 'updated']
- #class Meta:
- # abstract = True
-
class BaseStackedInline(admin.StackedInline):
readonly_fields = ('added', 'updated')
extra = 0
@@ -10,6 +10,16 @@
(4, _('mantainance')),
)
+# convenience for readability of the previous costant
+NODE_STATUS_NAME = {
+ 'archived': NODE_STATUS[0][0],
+ 'potential': NODE_STATUS[1][0],
+ 'planned': NODE_STATUS[2][0],
+ 'testing': NODE_STATUS[3][0],
+ 'active': NODE_STATUS[4][0],
+ 'mantainance': NODE_STATUS[5][0],
+}
+
ROUTING_PROTOCOLS = (
('batman', 'Batman-adv'),
('babel', 'Babel'),
@@ -0,0 +1,21 @@
+from django.db.models import Manager
+from django.db.models.query import QuerySet
+
+class PublicQuerySet(QuerySet):
+ """ Custom query set, make possible to chain custom filters """
+
+ def published(self):
+ """ return only published items """
+ return self.filter(is_published=True)
+
+class PublicManager(Manager):
+ """ Returns published items """
+
+ def get_query_set(self):
+ return PublicQuerySet(self.model, using=self._db)
+
+ def __getattr__(self, attr, *args):
+ try:
+ return getattr(self.__class__, attr, *args)
+ except AttributeError:
+ return getattr(self.get_query_set(), attr, *args)
@@ -0,0 +1,33 @@
+from django.core.urlresolvers import reverse
+from tastypie.resources import ModelResource
+from tastypie.bundle import Bundle
+
+class BaseSlugResource(ModelResource):
+ """ Base Model Resource which contains 'get_slug_detail_uri' method and overrides get_resource_uri """
+
+ class Meta:
+ abstract = True
+
+ def get_slug_detail_uri(self, bundle):
+ """ returns detail uri with slug field instead of primary key """
+ # retrieve keyword arguments, delete pk and add slug to the dictionary
+ kwargs = self.resource_uri_kwargs(bundle)
+ del kwargs['pk']
+ kwargs['slug'] = bundle.obj.slug
+ # return generated uri
+ return reverse('api_dispatch_detail', kwargs=kwargs)
+
+ def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_list'):
+ """
+ Custom get_resource_uri which returns a slug based detail uri when necessary
+ """
+ if bundle_or_obj is not None:
+ url_name = 'api_dispatch_detail'
+
+ if isinstance(bundle_or_obj, Bundle):
+ return self.get_slug_detail_uri(bundle_or_obj)
+
+ try:
+ return self._build_reverse_url(url_name, kwargs=self.resource_uri_kwargs(bundle_or_obj))
+ except NoReverseMatch:
+ return ''
@@ -31,8 +31,9 @@ class Inward(BaseDate):
])
ip = models.GenericIPAddressField(verbose_name=_('ip address'), blank=True, null=True)
user_agent = models.CharField(max_length=255, blank=True)
- http_referer = models.CharField(max_length=255, blank=True)
accept_language = models.CharField(max_length=255, blank=True)
+ # who fucking cares
+ #http_referer = models.CharField(max_length=255, blank=True)
class Meta:
verbose_name = _('Inward message')
Oops, something went wrong.

0 comments on commit d42c3e6

Please sign in to comment.