Browse Source

Make metaclass for lazy init objects

devel
bashmak 8 years ago
parent
commit
a4d914c7f2
  1. 10
      agent/core.py
  2. 6
      agent/mod_mikrotik.py
  3. 37
      djing/lib/decorators.py

10
agent/core.py

@ -1,4 +1,4 @@
from abc import ABCMeta, abstractmethod
from abc import ABC, abstractmethod
from typing import Iterator, Any, Tuple, Optional
from .structs import AbonStruct, TariffStruct, VectorAbon, VectorTariff, IpStruct
@ -15,7 +15,7 @@ class NasNetworkError(Exception):
# Communicate with NAS
class BaseTransmitter(metaclass=ABCMeta):
class BaseTransmitter(ABC):
@abstractmethod
def add_user_range(self, user_list: VectorAbon):
"""add subscribers list to NAS"""
@ -106,12 +106,6 @@ class BaseTransmitter(metaclass=ABCMeta):
def sync_nas(self, users_from_db: Iterator):
list_for_add, list_for_del = self._diff_users(users_from_db)
if len(list_for_del) > 0:
print('FOR DELETE')
for ld in list_for_del:
print(ld)
self.remove_user_range(list_for_del)
if len(list_for_add) > 0:
print('FOR ADD')
for la in list_for_add:
print(la)
self.add_user_range(list_for_add)

6
agent/mod_mikrotik.py

@ -1,10 +1,12 @@
import re
import socket
import binascii
from abc import ABCMeta
from hashlib import md5
from ipaddress import ip_network
from typing import Iterable, Optional, Tuple, Generator, Dict
from djing.lib.decorators import LazyInitMetaclass
from .structs import TariffStruct, AbonStruct, IpStruct, VectorAbon, VectorTariff
from . import settings as local_settings
from django.conf import settings
@ -30,8 +32,6 @@ class ApiRos(object):
sk.connect((ip, port or 8728))
self.sk = sk
self.currenttag = 0
def login(self, username, pwd):
if self.is_login:
return
@ -172,7 +172,7 @@ class IpAddressListObj(IpStruct):
self.mk_id = str(mk_id).replace('*', '')
class MikrotikTransmitter(BaseTransmitter, ApiRos):
class MikrotikTransmitter(BaseTransmitter, ApiRos, metaclass=type('_ABC_Lazy_mcs', (ABCMeta, LazyInitMetaclass), {})):
def __init__(self, login=None, password=None, ip=None, port=None):
ip = ip or getattr(local_settings, 'NAS_IP')

37
djing/lib/decorators.py

@ -55,3 +55,40 @@ def hash_auth_view(fn):
else:
return HttpResponseForbidden('Access Denied')
return wrapped
# Lazy initialize metaclass
class LazyInitMetaclass(type):
"""
Type this metaclass if you want to make your object with lazy initialize.
Method __init__ called only when you try to call something method
from object of your class.
"""
def __new__(mcs, name: str, bases: tuple, attrs: dict):
new_class_new = super(LazyInitMetaclass, mcs).__new__
def _lazy_call_decorator(fn):
def wrapped(self, *args, **kwargs):
if not self._is_initialized:
self._lazy_init(*self._args, **self._kwargs)
return fn(self, *args, **kwargs)
return wrapped
# Apply decorator to all public class methods
new_attrs = {k: _lazy_call_decorator(v) for k, v in attrs.items() if not k.startswith('__') and not k.endswith('__') and callable(v)}
if new_attrs:
attrs.update(new_attrs)
attrs['_is_initialized'] = False
new_class = new_class_new(mcs, name, bases, attrs)
real_init = getattr(new_class, '__init__')
def _lazy_init(self, *args, **kwargs):
self._args = args
self._kwargs = kwargs
setattr(new_class, '__init__', _lazy_init)
setattr(new_class, '_lazy_init', real_init)
return new_class
Loading…
Cancel
Save