<commit_before>"""Constant and messages definition for MT communication."""

class MID:
    """Values for the message id (MID)"""
    # Error message, 1 data byte
    Error = 0x42
    ErrorCodes = {
        0x03: "Invalid period",
        0x04: "Invalid message",
        0x1E: "Timer overflow",
        0x20: "Invalid baudrate",
        0x21: "Invalid parameter"
    }

    # State MID
    # Wake up procedure
    WakeUp = 0x3E
    # Switch to config state
    GoToConfig = 0x30
    # Switch to measurement state
    GoToMeasurement = 0x10
    # Reset device
    Reset = 0x40

    # Informational messages
    # Request device id
    ReqDID = 0x00
    # DeviceID, 4 bytes: HH HL LH LL
    DeviceID = 0x01
    # Compatibility for XBus Master users
    InitMT = 0x02
    InitMTResults = 0x03
    # Request product code in plain text
    ReqProductCode = 0x1C
    # Product code (max 20 bytes data)
    ProductCode = 0x1D
    # Request firmware revision
    ReqFWRev = 0x12
    # Firmware revision, 3 bytes: major minor rev
    FirmwareRev = 0x13
    # Request data length according to current configuration
    ReqDataLength = 0x0A
    # Data Length, 2 bytes
    DataLength = 0x0B
    # Request GPS status (MTi-G only)
    ReqGPSStatus = 0xA6
    # GPS status (MTi-G only)
    GPSStatus = 0xA7

    # Device specific messages
    # Baudrate, 1 byte
    SetBaudrate = 0x18
    # Error mode, 2 bytes, 0000, 0001, 0002, 0003 (default 0001)
    SetErrorMode = 0xDA
    # Location ID, 2 bytes, arbitrary, default is 0
    SetLocationID = 0x84
    # Restore factory defaults
    RestoreFactoryDef = 0x0E
    # Transmit delay (RS485), 2 bytes, number of clock ticks (1/29.4912 MHz)
    SetTransmitDelay = 0xDC

    # Synchronization messages
    # Synchronization settings (MTi-10/100 series only), N*12 bytes
    SetSyncSettings = 0x2C
    # SyncIn setting (MTi only), (1+) 2 or 4 bytes depending on request
    SetSyncInSettings = 0xD6
    # SyncOut setting (MTi/MTi-G only), (1+) 2 or 4 bytes depending on request
    SetSyncOutSettings = 0xD8

    # Configuration messages
    # Request configuration
    ReqConfiguration = 0x0C
    # Configuration, 118 bytes
    Configuration = 0x0D
    # Output configuration (MTi-10/100 series only), N*4 bytes
    SetOutputConfiguration = 0xC0
    # Sampling period (MTi/MTi-G only), 2 bytes
    SetPeriod = 0x04
    # Skip factor (MTi/MTi-G only), 2 bytes
    SetOutputSkipFactor = 0xD4
    # Object alignment matrix, 9*4 bytes
    SetObjectAlignment = 0xE0
    # Output mode (MTi/MTi-G only), 2 bytes
    SetOutputMode = 0xD0
    # Output settings (MTi/MTi-G only), 4 bytes
    SetOutputSettings = 0xD2

    # Data messages
    # Request MTData message (for 65535 skip factor)
    ReqData = 0x34
    # Legacy data packet
    MTData = 0x32
    # Newer data packet (MTi-10/100 series only)
    MTData2 = 0x36

    # XKF Filter messages
    # Heading (MTi only), 4 bytes
    SetHeading = 0x82
    # Reset orientation, 2 bytes
    ResetOrientation = 0xA4
    # Request UTC time from sensor (MTI-G and MTi-10/100 series)
    ReqUTCTime = 0x60
    # UTC Time (MTI-G and MTi-10/100 series), 12 bytes
    UTCTime = 0x61
    # Request the available XKF scenarios on the device
    ReqAvailableScenarios = 0x62
    # Available Scenarios
    AvailableScenarios = 0x63
    # Current XKF scenario, 2 bytes
    SetCurrentScenario = 0x64
    # Magnitude of the gravity used for the sensor fusion mechanism, 4 bytes
    SetGravityMagnitude = 0x66
    # Lever arm of the GPSin sensor coordinates (MTi-G and MTi-700 only),
    # 3*4 bytes
    SetLeverArmGPS = 0x68
    # Magnetic declination (MTi-G only), 4 bytes
    SetMagneticDeclination = 0x6A
    # Latitude, Longitude and Altitude for local declination and gravity
    # (MTi-10/100 series only), 24 bytes
    SetLatLonAlt = 0x6E
    # Processing flags (not on firmware 2.2 or lower for MTi/MTi-g), 1 byte
    SetProcessingFlags = 0x20
    # Initiate No Rotation procedure (not on MTi-G), 2 bytes
    SetNoRotation = 0x22

def getName(cls, value):
    '''Return the name of the first found member of class cls with given
    value.'''
    for k, v in cls.__dict__.iteritems():
        if v == value:
            return k
    return ''

def getMIDName(mid):
    '''Return the name of a message given the message id.'''
    name = getName(MID, mid)
    if name:
        return name
    if mid & 1:
        name = getName(MID, mid-1)
        if name:
            return name+'Ack'
    return 'unknown MID'

class Baudrates(object):
    """Baudrate information and conversion."""
    # Baudrate mapping between ID and value
    Baudrates = [
        (0x80, 921600),
        (0x0A, 921600),
        (0x00, 460800),
        (0x01, 230400),
        (0x02, 115200),
        (0x03,  76800),
        (0x04,  57600),
        (0x05,  38400),
        (0x06,  28800),
        (0x07,  19200),
        (0x08,  14400),
        (0x09,   9600),
        (0x0B,   4800),
        (0x80, 921600)]

    @classmethod
    def get_BRID(cls, baudrate):
        """Get baudrate id for a given baudrate."""
        for brid, br in cls.Baudrates:
            if baudrate == br:
                return brid
        raise MTException("unsupported baudrate.")

    @classmethod
    def get_BR(cls, baudrate_id):
        """Get baudrate for a given baudrate id."""
        for brid, br in cls.Baudrates:
            if baudrate_id == brid:
                return br
        raise MTException("unknown baudrate id.")

class OutputMode:
    """Values for the output mode."""
    Temp = 0x0001
    Calib = 0x0002
    Orient = 0x0004
    Auxiliary = 0x0008
    Position = 0x0010
    Velocity = 0x0020
    Status = 0x0800
    RAWGPS = 0x1000  # supposed to be incompatible with previous
    RAW = 0x4000  # incompatible with all except RAWGPS

class OutputSettings:
    """Values for the output settings."""
    Timestamp_None = 0x00000000
    Timestamp_SampleCnt = 0x00000001
    OrientMode_Quaternion = 0x00000000
    OrientMode_Euler = 0x00000004
    OrientMode_Matrix = 0x00000008
    CalibMode_AccGyrMag = 0x00000000
    CalibMode_GyrMag = 0x00000010
    CalibMode_AccMag = 0x00000020
    CalibMode_Mag = 0x00000030
    CalibMode_AccGyr = 0x00000040
    CalibMode_Gyr = 0x00000050
    CalibMode_Acc = 0x00000060
    CalibMode_Mask = 0x00000070
    DataFormat_Float = 0x00000000
    DataFormat_12_20 = 0x00000100  # not supported yet
    DataFormat_16_32 = 0x00000200  # not supported yet
    DataFormat_Double = 0x00000300  # not supported yet
    AuxiliaryMode_NoAIN1 = 0x00000400
    AuxiliaryMode_NoAIN2 = 0x00000800
    PositionMode_LLA_WGS84 = 0x00000000
    VelocityMode_MS_XYZ = 0x00000000
    Coordinates_NED = 0x80000000

class XDIGroup:
    """Values for the XDI groups."""
    Temperature = 0x0800
    Timestamp = 0x1000
    OrientationData = 0x2000
    Pressure = 0x3000
    Acceleration = 0x4000
    Position = 0x5000
    AngularVelocity = 0x8000
    GPS = 0x8800
    SensorComponentReadout = 0xA000
    AnalogIn = 0xB000
    Magnetic = 0xC000
    Velocity = 0xD000
    Status = 0xE000

class MTException(Exception):
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return "MT error: " + self.message
<commit_msg>update MIDs<commit_after>"""Constant and messages definition for MT communication."""

class MID:
    """Values for the message id (MID)"""
    # Error message, 1 data byte
    Error = 0x42
    ErrorCodes = {
        0x03: "Invalid period",
        0x04: "Invalid message",
        0x1E: "Timer overflow",
        0x20: "Invalid baudrate",
        0x21: "Invalid parameter"
    }

    # State MID
    # Wake up procedure
    WakeUp = 0x3E
    # Switch to config state
    GoToConfig = 0x30
    # Switch to measurement state
    GoToMeasurement = 0x10
    # Reset device
    Reset = 0x40

    # Informational messages
    # Request device id
    ReqDID = 0x00
    # DeviceID, 4 bytes: HH HL LH LL
    DeviceID = 0x01
    # Request product code in plain text
    ReqProductCode = 0x1C
    # Product code (max 20 bytes data)
    ProductCode = 0x1D
    # Request firmware revision
    ReqFWRev = 0x12
    # Firmware revision, 3 bytes: major minor rev
    FirmwareRev = 0x13

    # Device specific messages
    # Restore factory defaults
    RestoreFactoryDef = 0x0E
    # Baudrate, 1 byte
    SetBaudrate = 0x18
    # Run the built-in self test (MTi-1/10/100 series)
    RunSelftest = 0x24
    # Self test results, 2 bytes
    SelftestAck = 0x25
    # Error mode, 2 bytes, 0000, 0001, 0002, 0003 (default 0001)
    SetErrorMode = 0xDA
    # Transmit delay (RS485), 2 bytes, number of clock ticks (1/29.4912 MHz)
    SetTransmitDelay = 0xDC
    # Set state of OptionFlags (MTi-1/2/3), 4 + 4 bytes
    SetOptionFlags = 0x48
    # Location ID, 2 bytes, arbitrary, default is 0
    SetLocationID = 0x84

    # Synchronization messages
    # Synchronization settings (MTi-1/10/100 series only), N*12 bytes
    SetSyncSettings = 0x2C

    # Configuration messages
    # Request configuration
    ReqConfiguration = 0x0C
    # Configuration, 118 bytes
    Configuration = 0x0D
    # Sampling period (MTi/MTi-G only), 2 bytes
    SetPeriod = 0x04
    # Extended output mode (MTi-10/100), 2 bytes, bit 4 for extended UART
    SetExtOutputMode = 0x86
    # Output configuration (MTi-1/10/100 series only), N*4 bytes
    SetOutputConfiguration = 0xC0
    # Configure NMEA data output (MTi-10/100), 2 bytes
    SetStringOutputTypes = 0x8E
    # Set sensor of local alignment quaternion
    SetAlignmentRotation = 0xEC
    # Output mode (MTi/MTi-G only), 2 bytes
    SetOutputMode = 0xD0
    # Output settings (MTi/MTi-G only), 4 bytes
    SetOutputSettings = 0xD2

    # Data messages
    # Request MTData message (for 65535 skip factor)
    ReqData = 0x34
    # Legacy data packet
    MTData = 0x32
    # Newer data packet (MTi-10/100 series only)
    MTData2 = 0x36

    # XKF Filter messages
    # Reset orientation, 2 bytes
    ResetOrientation = 0xA4
    # Request or set UTC time from sensor (MTI-G and MTi-10/100 series)
    SetUTCTime = 0x60
    # Set correction ticks to UTC time
    AdjustUTCTime = 0xA8
    # UTC Time (MTI-G and MTi-10/100 series), 12 bytes
    UTCTime = 0x61
    # Request the available XKF scenarios on the device
    ReqAvailableScenarios = 0x62
    # Available Scenarios
    AvailableScenarios = 0x63
    # Current XKF scenario, 2 bytes
    SetCurrentScenario = 0x64
    # Magnitude of the gravity used for the sensor fusion mechanism, 4 bytes
    SetGravityMagnitude = 0x66
    # Latitude, Longitude and Altitude for local declination and gravity
    # (MTi-10/100 series only), 24 bytes
    SetLatLonAlt = 0x6E
    # Initiate No Rotation procedure (not on MTi-G), 2 bytes
    SetNoRotation = 0x22

class DeprecatedMID:
    """Deprecated message Ids."""
    # Informational messages
    # Compatibility for XBus Master users
    InitMT = 0x02
    InitMTResults = 0x03
    # Request data length according to current configuration
    ReqDataLength = 0x0A
    # Data Length, 2 bytes
    DataLength = 0x0B
    # Request GPS status (MTi-G only)
    ReqGPSStatus = 0xA6
    # GPS status (MTi-G only)
    GPSStatus = 0xA7

    # Synchronization messages
    # SyncIn setting (MTi only), (1+) 2 or 4 bytes depending on request
    SetSyncInSettings = 0xD6
    # SyncOut setting (MTi/MTi-G only), (1+) 2 or 4 bytes depending on request
    SetSyncOutSettings = 0xD8

    # Configuration messages
    # Skip factor (MTi/MTi-G only), 2 bytes
    SetOutputSkipFactor = 0xD4
    # Object alignment matrix, 9*4 bytes
    SetObjectAlignment = 0xE0

    # XKF Filter messages
    # Heading (MTi only), 4 bytes
    SetHeading = 0x82
    # Lever arm of the GPSin sensor coordinates (MTi-G and MTi-700 only),
    # 3*4 bytes
    SetLeverArmGPS = 0x68
    # Magnetic declination (MTi-G only), 4 bytes
    SetMagneticDeclination = 0x6A
    # Latitude, Longitude and Altitude for local declination and gravity
    # Processing flags (not on firmware 2.2 or lower for MTi/MTi-g), 1 byte
    SetProcessingFlags = 0x20

def getName(cls, value):
    '''Return the name of the first found member of class cls with given
    value.'''
    for k, v in cls.__dict__.iteritems():
        if v == value:
            return k
    return ''

def getMIDName(mid):
    '''Return the name of a message given the message id.'''
    name = getName(MID, mid)
    if name:
        return name
    if mid & 1:
        name = getName(MID, mid-1)
        if name:
            return name+'Ack'
    return 'unknown MID'

class Baudrates(object):
    """Baudrate information and conversion."""
    # Baudrate mapping between ID and value
    Baudrates = [
        (0x80, 921600),
        (0x0A, 921600),
        (0x00, 460800),
        (0x01, 230400),
        (0x02, 115200),
        (0x03,  76800),
        (0x04,  57600),
        (0x05,  38400),
        (0x06,  28800),
        (0x07,  19200),
        (0x08,  14400),
        (0x09,   9600),
        (0x0B,   4800),
        (0x80, 921600)]

    @classmethod
    def get_BRID(cls, baudrate):
        """Get baudrate id for a given baudrate."""
        for brid, br in cls.Baudrates:
            if baudrate == br:
                return brid
        raise MTException("unsupported baudrate.")

    @classmethod
    def get_BR(cls, baudrate_id):
        """Get baudrate for a given baudrate id."""
        for brid, br in cls.Baudrates:
            if baudrate_id == brid:
                return br
        raise MTException("unknown baudrate id.")

class OutputMode:
    """Values for the output mode."""
    Temp = 0x0001
    Calib = 0x0002
    Orient = 0x0004
    Auxiliary = 0x0008
    Position = 0x0010
    Velocity = 0x0020
    Status = 0x0800
    RAWGPS = 0x1000  # supposed to be incompatible with previous
    RAW = 0x4000  # incompatible with all except RAWGPS

class OutputSettings:
    """Values for the output settings."""
    Timestamp_None = 0x00000000
    Timestamp_SampleCnt = 0x00000001
    OrientMode_Quaternion = 0x00000000
    OrientMode_Euler = 0x00000004
    OrientMode_Matrix = 0x00000008
    CalibMode_AccGyrMag = 0x00000000
    CalibMode_GyrMag = 0x00000010
    CalibMode_AccMag = 0x00000020
    CalibMode_Mag = 0x00000030
    CalibMode_AccGyr = 0x00000040
    CalibMode_Gyr = 0x00000050
    CalibMode_Acc = 0x00000060
    CalibMode_Mask = 0x00000070
    DataFormat_Float = 0x00000000
    DataFormat_12_20 = 0x00000100  # not supported yet
    DataFormat_16_32 = 0x00000200  # not supported yet
    DataFormat_Double = 0x00000300  # not supported yet
    AuxiliaryMode_NoAIN1 = 0x00000400
    AuxiliaryMode_NoAIN2 = 0x00000800
    PositionMode_LLA_WGS84 = 0x00000000
    VelocityMode_MS_XYZ = 0x00000000
    Coordinates_NED = 0x80000000

class XDIGroup:
    """Values for the XDI groups."""
    Temperature = 0x0800
    Timestamp = 0x1000
    OrientationData = 0x2000
    Pressure = 0x3000
    Acceleration = 0x4000
    Position = 0x5000
    AngularVelocity = 0x8000
    GPS = 0x8800
    SensorComponentReadout = 0xA000
    AnalogIn = 0xB000
    Magnetic = 0xC000
    Velocity = 0xD000
    Status = 0xE000

class MTException(Exception):
    def __init__(self, message):
        self.message = message

    def __str__(self):
        return "MT error: " + self.message
<|endoftext|>


<commit_before>import win32com.client
from win32com.client import constants
from os import path, chdir, getcwd

from sys import exit
from optparse import OptionParser

def get_dispatch_format(extension):
    if extension == 'vsd':
        return 'Visio.InvisibleApp'
    if extension == 'vsdx':
        pass    # pass

def get_pages(app, page_num=None):
    """
    app -> page
    if page_num is None, return all pages.
    if page_num is int object, return path_num-th page(fromm 1).
    """
    pages = app.ActiveDocument.Pages
    return [list(pages)[page_num - 1]] if page_num else pages

if __name__ == '__main__':
    # define parser
    parser = OptionParser()
    parser.add_option(
            '-p', '--page',
            action='store',
            type='int',
            dest='page',
            help='transform only one page(set number of this page)'
        )
    (options, argv) = parser.parse_args()

    # if len(arguments) != 2, raise exception
    if len(argv) != 2:
        print('Enter Only input_filename and output_filename')
        exit()

    # define input_filename and output_filename
    in_filename = path.abspath(argv[0])
    out_filename = path.abspath(argv[1])

    # define filename without extension and extension variable
    in_filename_without_extension, in_extension = path.splitext(in_filename)
    out_filename_without_extension, out_extension = path.splitext(out_filename)

    # if file is not found, exit from program
    if not path.exists(in_filename):
        print('File Not Found')
        exit()

    try:
        # make instance for visio
        application = win32com.client.Dispatch(get_dispatch_format(in_extension[1:]))
        application.Visible = False
        document = application.Documents.Open(in_filename)

        # make pages of picture
        pages = get_pages(application, page_num=options.page)

        # define page_names
        if len(pages) == 1:
            page_names = [out_filename]
        else:   # len(pages) >= 2
            page_names = (out_filename_without_extension + str(page_cnt + 1) + out_extension
                    for page_cnt in range(0, len(pages)))

        # Export pages
        for page, page_name in zip(pages, page_names):
            page.Export(page_name)
            print(type(page))

    finally:
        application.Quit()
<commit_msg>add export_img() method<commit_after>import win32com.client
from win32com.client import constants
from os import path, chdir, getcwd

from sys import exit
from optparse import OptionParser

def get_dispatch_format(extension):
    if extension == 'vsd':
        return 'Visio.InvisibleApp'
    if extension == 'vsdx':
        pass    # pass

def get_pages(app, page_num=None):
    """
    app -> page
    if page_num is None, return all pages.
    if page_num is int object, return path_num-th page(fromm 1).
    """
    pages = app.ActiveDocument.Pages
    return [list(pages)[page_num - 1]] if page_num else pages

def export_img(in_filename, out_filename, page_num=None):
    """
    export as image format
    """
    # define filename without extension and extension variable
    in_filename_without_extension, in_extension = path.splitext(in_filename)
    out_filename_without_extension, out_extension = path.splitext(out_filename)

    # if file is not found, exit from program
    if not path.exists(in_filename):
        print('File Not Found')
        exit()

    try:
        # make instance for visio
        application = win32com.client.Dispatch(get_dispatch_format(in_extension[1:]))
        application.Visible = False
        document = application.Documents.Open(in_filename)

        # make pages of picture
        pages = get_pages(application, page_num=options.page)

        # define page_names
        if len(pages) == 1:
            page_names = [out_filename]
        else:   # len(pages) >= 2
            page_names = (out_filename_without_extension + str(page_cnt + 1) + out_extension
                    for page_cnt in range(0, len(pages)))

        # Export pages
        for page, page_name in zip(pages, page_names):
            page.Export(page_name)

    finally:
        application.Quit()

if __name__ == '__main__':
    # define parser
    parser = OptionParser()
    parser.add_option(
            '-p', '--page',
            action='store',
            type='int',
            dest='page',
            help='transform only one page(set number of this page)'
        )
    (options, argv) = parser.parse_args()

    # if len(arguments) != 2, raise exception
    if len(argv) != 2:
        print('Enter Only input_filename and output_filename')
        exit()

    # define input_filename and output_filename
    in_filename = path.abspath(argv[0])
    out_filename = path.abspath(argv[1])

    export_img(in_filename, out_filename, options.page)
<|endoftext|>


<commit_before>import hashlib
import hmac
import json
import logging
from functools import wraps

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import user_passes_test
from django.core.mail import mail_admins
from django.http import (
    HttpResponseRedirect,
    HttpResponseForbidden,
    HttpResponseBadRequest,
    HttpResponse,
)
from django.http.request import split_domain_port
from django.urls import reverse
from dropbox import DropboxOAuth2Flow
from dropbox.oauth import (
    BadRequestException,
    BadStateException,
    CsrfException,
    NotApprovedException,
    ProviderException,
)

from dropboxer.models import DropboxUser
from dropboxer.tasks import process_changes

logger = logging.getLogger(__name__)

def _get_dropbox_auth_flow(request):
    redirect_uri = request.build_absolute_uri(reverse('dropbox_auth_finish'))
    domain, port = split_domain_port(request.get_host())
    local_domains = ('localhost', '127.0.0.1', '[::1]')
    if (request.scheme == 'http' and domain not in local_domains):
        # Force redirect_uri to use https, even if scheme is http
        redirect_uri = 'https://' + redirect_uri[7:]
    return DropboxOAuth2Flow(
        settings.DROPBOX_APP_KEY,
        settings.DROPBOX_APP_SECRET,
        redirect_uri,
        request.session,
        'dropbox-auth-csrf-token'
    )

def dropbox_required(view_func):

    @wraps(view_func)
    def wrapped(request, *args, **kwargs):
        dropbox_user = DropboxUser.objects.get_or_none(user=request.user)
        if dropbox_user and dropbox_user.access_token:
            return view_func(request, *args, **kwargs)
        if not dropbox_user or not dropbox_user.access_token:
            authorize_url = _get_dropbox_auth_flow(request).start()
            return HttpResponseRedirect(authorize_url)

    return wrapped

@user_passes_test(lambda u: u.is_staff)
def dropbox_auth_start(request):
    authorize_url = _get_dropbox_auth_flow(request).start()
    return HttpResponseRedirect(authorize_url)

@user_passes_test(lambda u: u.is_staff)
def dropbox_auth_finish(request):
    try:
        oauth_result = (
            _get_dropbox_auth_flow(request).finish(request.GET)
        )
    except BadRequestException:
        return HttpResponseBadRequest()
    except BadStateException:
        # Start the auth flow again.
        return HttpResponseRedirect(reverse('dropbox_auth_start'))
    except CsrfException:
        return HttpResponseForbidden()
    except NotApprovedException:
        messages.warning(request, 'Dropbox authentication was not approved.')
        return HttpResponseRedirect(reverse('dashboard'))
    except ProviderException as err:
        logger.exception('Error authenticating Dropbox', err)
        return HttpResponseForbidden()
    DropboxUser.objects.update_or_create(
        user=request.user,
        defaults={
            'account': oauth_result.account_id,
            'access_token': oauth_result.access_token
        }
    )
    messages.success(request, 'Dropbox authentication successful.')
    return HttpResponseRedirect(reverse('dashboard'))

@user_passes_test(lambda u: u.is_staff)
def dropbox_logout(request):
    dropbox_user = DropboxUser.objects.get(user=request.user)
    dropbox_user.access_token = ''
    dropbox_user.save()
    messages.info(request, 'You have disconnected your Dropbox account.')
    return HttpResponseRedirect(reverse('dashboard'))

@user_passes_test(lambda u: u.is_staff)
@dropbox_required
def check_dropbox(request):
    """
    Schedule Dropbox to be checked, and return to dashboard.
    """
    process_changes.delay(request.user.get_username())
    messages.info(request, 'Checking Dropbox for changes.')
    return HttpResponseRedirect(reverse('dashboard'))

def webhook(request):
    """
    Dropbox notifies this view when files have changed
    """
    def get_challenge_response(request_):
        challenge = request_.GET.get('challenge', '')
        response = HttpResponse(challenge, content_type='text/plain')
        response['X-Content-Type-Options'] = 'nosniff'
        return response

    def verify_signature(request_):
        signature = request_.headers.get('X-Dropbox-Signature')
        request_hash = hmac.new(
            settings.DROPBOX_APP_SECRET, request_.body, hashlib.sha256
        ).hexdigest()
        return hmac.compare_digest(signature, request_hash)

    if request.method == 'GET':
        return get_challenge_response(request)

    if request.method == 'POST':
        if not verify_signature(request):
            return HttpResponseForbidden()

        notification = json.loads(request.body)
        for account in notification['list_folder']['accounts']:
            dropbox_user = DropboxUser.objects.get_or_none(account=account)
            if dropbox_user:
                process_changes.delay(dropbox_user.user.get_username())
        return HttpResponse('Accepted', content_type='text/plain', status=202)
<commit_msg>Add logging for dropboxer<commit_after>import hashlib
import hmac
import json
import logging
from functools import wraps

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import user_passes_test
from django.http import (
    HttpResponseRedirect,
    HttpResponseForbidden,
    HttpResponseBadRequest,
    HttpResponse,
)
from django.http.request import split_domain_port
from django.urls import reverse
from dropbox import DropboxOAuth2Flow
from dropbox.oauth import (
    BadRequestException,
    BadStateException,
    CsrfException,
    NotApprovedException,
    ProviderException,
)

from dropboxer.models import DropboxUser
from dropboxer.tasks import process_changes

logger = logging.getLogger(__name__)

def _get_dropbox_auth_flow(request):
    redirect_uri = request.build_absolute_uri(reverse('dropbox_auth_finish'))
    domain, port = split_domain_port(request.get_host())
    local_domains = ('localhost', '127.0.0.1', '[::1]')
    if (request.scheme == 'http' and domain not in local_domains):
        # Force redirect_uri to use https, even if scheme is http
        redirect_uri = 'https://' + redirect_uri[7:]
    return DropboxOAuth2Flow(
        settings.DROPBOX_APP_KEY,
        settings.DROPBOX_APP_SECRET,
        redirect_uri,
        request.session,
        'dropbox-auth-csrf-token'
    )

def dropbox_required(view_func):

    @wraps(view_func)
    def wrapped(request, *args, **kwargs):
        dropbox_user = DropboxUser.objects.get_or_none(user=request.user)
        if dropbox_user and dropbox_user.access_token:
            return view_func(request, *args, **kwargs)
        if not dropbox_user or not dropbox_user.access_token:
            authorize_url = _get_dropbox_auth_flow(request).start()
            return HttpResponseRedirect(authorize_url)

    return wrapped

@user_passes_test(lambda u: u.is_staff)
def dropbox_auth_start(request):
    authorize_url = _get_dropbox_auth_flow(request).start()
    return HttpResponseRedirect(authorize_url)

@user_passes_test(lambda u: u.is_staff)
def dropbox_auth_finish(request):
    try:
        oauth_result = (
            _get_dropbox_auth_flow(request).finish(request.GET)
        )
    except BadRequestException:
        return HttpResponseBadRequest()
    except BadStateException:
        # Start the auth flow again.
        return HttpResponseRedirect(reverse('dropbox_auth_start'))
    except CsrfException:
        return HttpResponseForbidden()
    except NotApprovedException:
        messages.warning(request, 'Dropbox authentication was not approved.')
        return HttpResponseRedirect(reverse('dashboard'))
    except ProviderException as err:
        logger.exception('Error authenticating Dropbox', err)
        return HttpResponseForbidden()
    DropboxUser.objects.update_or_create(
        user=request.user,
        defaults={
            'account': oauth_result.account_id,
            'access_token': oauth_result.access_token
        }
    )
    messages.success(request, 'Dropbox authentication successful.')
    return HttpResponseRedirect(reverse('dashboard'))

@user_passes_test(lambda u: u.is_staff)
def dropbox_logout(request):
    dropbox_user = DropboxUser.objects.get(user=request.user)
    dropbox_user.access_token = ''
    dropbox_user.save()
    messages.info(request, 'You have disconnected your Dropbox account.')
    return HttpResponseRedirect(reverse('dashboard'))

@user_passes_test(lambda u: u.is_staff)
@dropbox_required
def check_dropbox(request):
    """
    Schedule Dropbox to be checked, and return to dashboard.
    """
    process_changes.delay(request.user.get_username())
    messages.info(request, 'Checking Dropbox for changes.')
    return HttpResponseRedirect(reverse('dashboard'))

def webhook(request):
    """
    Dropbox notifies this view when files have changed
    """
    def get_challenge_response(request_):
        challenge = request_.GET.get('challenge', '')
        response = HttpResponse(challenge, content_type='text/plain')
        response['X-Content-Type-Options'] = 'nosniff'
        return response

    def verify_signature(request_):
        signature = request_.headers.get('X-Dropbox-Signature')
        request_hash = hmac.new(
            settings.DROPBOX_APP_SECRET, request_.body, hashlib.sha256
        ).hexdigest()
        return hmac.compare_digest(signature, request_hash)

    if request.method == 'GET':
        logger.info('Dropbox webhook: Challenge request')
        return get_challenge_response(request)

    if request.method == 'POST':
        logger.info('Dropbox webhook: Notification')
        if not verify_signature(request):
            logger.info('Dropbox webhook: Verification failed')
            return HttpResponseForbidden()

        logger.debug(f'Dropbox webhook: Request body: \n{request.body}')
        notification = json.loads(request.body)
        for account in notification['list_folder']['accounts']:
            dropbox_user = DropboxUser.objects.get_or_none(account=account)
            if dropbox_user:
                process_changes.delay(dropbox_user.user.get_username())
        return HttpResponse('Accepted', content_type='text/plain', status=202)
<|endoftext|>


<commit_before>
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""python 2.5 builtin _ast compatibility module

:author:    Sylvain Thenault
:copyright: 2008 LOGILAB S.A. (Paris, FRANCE)
:contact:   http://www.logilab.fr/ -- mailto:python-projects@logilab.org
:copyright: 2008 Sylvain Thenault
:contact:   mailto:thenault@gmail.com
"""

__docformat__ = "restructuredtext en"

from _ast import (Assert, Assign, AugAssign,
                  Break,
                  Compare, Continue,
                  Delete, Dict,
                  Ellipsis, Exec,
                  For,
                  Global,
                  If, Import,
                  Lambda, List, ListComp,
                  Module,
                  Name,
                  Pass, Print,
                  Raise, Return,
                  Slice, Sub, Subscript,
                  TryExcept, TryFinally, Tuple,
                  While, With,
                  Yield,
                  )

from _ast import (AST as Node,
                  Attribute as Getattr,
                  Call as CallFunc,
                  ClassDef as Class,
                  FunctionDef as Function,
                  GeneratorExp as GenExpr,
                  Repr as Backquote,

                  Expr as Discard,
                  ImportFrom as From,
                  excepthandler as ExceptHandler,
                  comprehension as ListCompFor,
                  keyword as Keyword
                  )

# XXX : AugLoad, AugStore, Attribute
#       BoolOp
#       Del, Delete
#       Expr, Expression, ExtSlice
#       IfExp, Index, Interactive,
#       Load,
#       Param
#       Store, Suite
#       UnaryOp
from _ast import Num, Str, Eq, alias, arguments, comprehension

COMPREHENSIONS_SCOPES = (comprehension,)

from _ast import (Add as _Add, Div as _Div, FloorDiv as _FloorDiv,
                  Mod as _Mod, Mult as _Mult, Pow as _Pow, Sub as _Sub,
                  BitAnd as _BitAnd, BitOr as _BitOr, BitXor as _BitXor,
                  LShift as _LShift, RShift as _RShift)
BIN_OP_CLASSES = {_Add: '+',
                  _BitAnd: '&',
                  _BitOr: '|',
                  _BitXor: '^',
                  _Div: '/',
                  _FloorDiv: '//',
                  _Mod: '%',
                  _Mult: '*',
                  _Pow: '**',
                  _Sub: '-',
                  _LShift: '<<',
                  _RShift: '>>'}

from _ast import And as _And, Or as _Or
BOOL_OP_CLASSES = {_And: 'and',
                   _Or: 'or'}

from _ast import UAdd as _UAdd, USub as _USub, Not as _Not, Invert as _Invert
UNARY_OP_CLASSES = {_UAdd: '+',
                    _USub: '-',
                    _Not: 'not',
                    _Invert: '~'}

from _ast import BinOp, BoolOp, UnaryOp

from _ast import (Eq as _Eq, Gt as _Gt, GtE as _GtE, In as _In, Is as _Is,
                  IsNot as _IsNot, Lt as _Lt, LtE as _LtE, NotEq as _NotEq,
                  NotIn as _NotIn)
CMP_OP_CLASSES = {_Eq: '==',
                  _Gt: '>',
                  _GtE: '>=',
                  _In: 'in',
                  _Is: 'is',
                  _IsNot: 'is not',
                  _Lt: '<',
                  _LtE: '<=',
                  _NotEq: '!=',
                  _NotIn: 'not in',
                  }

# FIXME : can't replace totally by Const : Str needed in _init_set_doc
Num._astng_fields = ()
Str._astng_fields = ()

class Const(Node):
    """represent a Str or Num node"""

class EmptyNode(Node):
    """represent a Empty node for compatibility"""

# scoped nodes ################################################################

def _init_set_doc(node):
    node.doc = None
    try:
        if isinstance(node.body[0], Discard) and isinstance(node.body[0].value, Str):
            node.doc = node.body[0].value.s
    except IndexError:
        pass # ast built from scratch

def _init_function(node):
    argnames = []
    for arg in node.args.args:
        if isinstance(arg, Name):
            argnames.append(arg.id )
        elif isinstance(arg, Tuple):
            argnames.extend( elt.id for elt in arg.elts )
    node.argnames = argnames
    node.defaults = node.args.defaults
    if node.args.vararg:
        node.argnames.append(node.args.vararg)
    if node.args.kwarg:
        node.argnames.append(node.args.kwarg)

init_class = _init_set_doc

def init_function(node):
    _init_set_doc(node)
    _init_function(node)

def init_lambda(node):
    _init_function(node)

init_module = _init_set_doc

##  init_<node> functions #####################################################

def init_assattr(node):
    pass

def init_assert(node):
    node.fail = node.msg
    del node.msg

def init_assign(node):
    pass
def init_asslist(node):
    pass

def init_assname(node):
    pass

def init_asstuple(node):
    pass

def init_augassign(node):
    pass

def init_backquote(node):
    pass

def init_binop(node):
    node.op = BIN_OP_CLASSES[node.op.__class__]

def init_boolop(node):
    node.op = BOOL_OP_CLASSES[node.op.__class__]

def init_callfunc(node):
    node.args.extend(node.keywords)
    del node.keywords

def init_compare(node):
    node.ops = [(CMP_OP_CLASSES[op.__class__], expr)
                for op, expr in zip(node.ops, node.comparators)]
    del node.comparators

def init_dict(node):
    node.items = zip(node.keys, node.values)
    del node.keys, node.values

def init_discard(node):
    pass

def init_exec(node):
    node.expr = node.body
    del node.body

def init_getattr(node):
    node.attrname = node.attr
    node.expr = node.value
    del node.attr, node.value

def init_for(node):
    pass

def _recurse_if(ifnode, tests, orelse):
    """recurse on nested If nodes"""
    tests.append( (ifnode.test, ifnode.body) )
    del ifnode.test, ifnode.body
    if ifnode.orelse:
        if isinstance( ifnode.orelse[0], If):
            tests, orelse =  _recurse_if(ifnode.orelse[0], tests, orelse)
            del ifnode.orelse[0]
        else:
            orelse = ifnode.orelse
    return tests, orelse

def init_if(node):
    tests, orelse = _recurse_if(node, [], [])
    node.tests = tests
    node.orelse = orelse

def init_import(node):
    node.names = [(alias.name, alias.asname) for alias in node.names]

def init_import_from(node):
    init_import(node)
    node.modname = node.module
    del node.module

def init_keyword(node):
    pass

def init_list(node):
    pass

def init_listcomp(node):
    pass

def init_listcompfor(node):
    pass

def init_name(node):
    node.name = node.id
    del node.id

def init_num(node):
    node.__class__ = Const
    node.value = node.n
    node.name = "int" # compiler compat
    del node.n

def init_print(node):
    pass

def init_raise(node):
    pass

def init_slice(node):
    pass

def init_str(node):
    node.__class__ = Const
    node.value = node.s
    node.name = "str" # compiler compat
    del node.s

def init_subscript(node):
    node.expr = node.value
    slices = node.slice
    if hasattr(slices, 'value'): # Index
        node.subs = [slices.value]
        node.sliceflag = 'index'
    elif hasattr(slices, 'lower'): # Slice
        node.subs = [slices.lower, slices.upper]
        if slices.step:
            node.subs.append(slices.step)
        node.sliceflag = 'slice'
    del node.slice, node.value

def init_try_except(node):
    pass

def init_try_finally(node):
    pass

def init_tuple(node):
    pass

def init_unaryop(node):
    node.op = UNARY_OP_CLASSES[node.op.__class__]

def init_while(node):
    pass

# raw building ################################################################

def _add_docstring(node, doc):
    node.doc = doc
#     if doc:
#         expr = Expr()
#         node.body.append(expr)
#         expr.parent = None
#         docstr = Str()
#         docstr.s = doc
#         expr.value = docstr
#         docstr.parent = expr

def module_factory(doc):
    node = Module()
    node.body = []
    _add_docstring(node, doc)
    return node

def dict_factory():
    return Dict()

def import_from_factory(modname, membername):
    node = From()
    node.level = 0
    node.module = modname
    aliasnode = alias()
    aliasnode.parent = node
    aliasnode.name = membername
    aliasnode.asname = None
    node.names = [aliasnode]
    return node

def _const_factory(value):
    if isinstance(value, (int, long, complex, basestring)):
        node = Const()
    else:
        raise Exception(repr(value))
    node.value = value
    return node

def function_factory(name, args, defaults, flag=0, doc=None):
    """create and initialize a astng Function node"""
    node = Function()
    node.body = []
    node.name = name
    argsnode = arguments()
    argsnode.args = []
    for arg in args:
        argsnode.args.append(Name())
        argsnode.args[-1].name = arg
        argsnode.args[-1].parent = argsnode
    argsnode.defaults = []
    for default in defaults:
        argsnode.defaults.append(const_factory(default))
        argsnode.defaults[-1].parent = argsnode
    argsnode.kwarg = None # XXX
    argsnode.vararg = None # XXX
    argsnode.parent = node
    node.args = argsnode
    _add_docstring(node, doc)
    return node

def class_factory(name, basenames=None, doc=None):
    """create and initialize a astng Class node"""
    node = Class()
    node.body = []
    node.name = name
    # XXX to check
    node.bases = []
    for base in basenames:
        basenode = Name()
        basenode.name = base
        node.bases.append(basenode)
        basenode.parent = node
    _add_docstring(node, doc)
    return node

class Proxy_(object): pass

from _ast import Load as _Load, Store as _Store, Del as _Del
def native_repr_tree(node, indent='', _done=None):
    if _done is None:
        _done = set()
    if node in _done:
        print ('loop in tree: %r (%s)' % (node, getattr(node, 'lineno', None)))
        return
    _done.add(node)
    print indent + str(node)
    if type(node) is str: # XXX crash on Globals
        return
    indent += '    '
    d = node.__dict__
    if hasattr(node, '_attributes'):
        for a in node._attributes:
            attr = d[a]
            if attr is None:
                continue
            print indent + a, repr(attr)
    for f in node._fields or ():
        attr = d[f]
        if attr is None:
            continue
        if type(attr) is list:
            if not attr: continue
            print indent + f + ' ['
            for elt in attr:
                native_repr_tree(elt, indent, _done)
            print indent + ']'
            continue
        if isinstance(attr, (_Load, _Store, _Del)):
            continue
        if isinstance(attr, Node):
            print indent + f
            native_repr_tree(attr, indent, _done)
        else:
            print indent + f, repr(attr)
<commit_msg>flags for _ast.Function / _ast.Lambda nodes<commit_after>
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""python 2.5 builtin _ast compatibility module

:author:    Sylvain Thenault
:copyright: 2008 LOGILAB S.A. (Paris, FRANCE)
:contact:   http://www.logilab.fr/ -- mailto:python-projects@logilab.org
:copyright: 2008 Sylvain Thenault
:contact:   mailto:thenault@gmail.com
"""

__docformat__ = "restructuredtext en"

from _ast import (Assert, Assign, AugAssign,
                  Break,
                  Compare, Continue,
                  Delete, Dict,
                  Ellipsis, Exec,
                  For,
                  Global,
                  If, Import,
                  Lambda, List, ListComp,
                  Module,
                  Name,
                  Pass, Print,
                  Raise, Return,
                  Slice, Sub, Subscript,
                  TryExcept, TryFinally, Tuple,
                  While, With,
                  Yield,
                  )

from _ast import (AST as Node,
                  Attribute as Getattr,
                  Call as CallFunc,
                  ClassDef as Class,
                  FunctionDef as Function,
                  GeneratorExp as GenExpr,
                  Repr as Backquote,

                  Expr as Discard,
                  ImportFrom as From,
                  excepthandler as ExceptHandler,
                  comprehension as ListCompFor,
                  keyword as Keyword
                  )

# XXX : AugLoad, AugStore, Attribute
#       BoolOp
#       Del, Delete
#       Expr, Expression, ExtSlice
#       IfExp, Index, Interactive,
#       Load,
#       Param
#       Store, Suite
#       UnaryOp
from _ast import Num, Str, Eq, alias, arguments, comprehension

COMPREHENSIONS_SCOPES = (comprehension,)

from _ast import (Add as _Add, Div as _Div, FloorDiv as _FloorDiv,
                  Mod as _Mod, Mult as _Mult, Pow as _Pow, Sub as _Sub,
                  BitAnd as _BitAnd, BitOr as _BitOr, BitXor as _BitXor,
                  LShift as _LShift, RShift as _RShift)
BIN_OP_CLASSES = {_Add: '+',
                  _BitAnd: '&',
                  _BitOr: '|',
                  _BitXor: '^',
                  _Div: '/',
                  _FloorDiv: '//',
                  _Mod: '%',
                  _Mult: '*',
                  _Pow: '**',
                  _Sub: '-',
                  _LShift: '<<',
                  _RShift: '>>'}

from _ast import And as _And, Or as _Or
BOOL_OP_CLASSES = {_And: 'and',
                   _Or: 'or'}

from _ast import UAdd as _UAdd, USub as _USub, Not as _Not, Invert as _Invert
UNARY_OP_CLASSES = {_UAdd: '+',
                    _USub: '-',
                    _Not: 'not',
                    _Invert: '~'}

from _ast import BinOp, BoolOp, UnaryOp

from _ast import (Eq as _Eq, Gt as _Gt, GtE as _GtE, In as _In, Is as _Is,
                  IsNot as _IsNot, Lt as _Lt, LtE as _LtE, NotEq as _NotEq,
                  NotIn as _NotIn)
CMP_OP_CLASSES = {_Eq: '==',
                  _Gt: '>',
                  _GtE: '>=',
                  _In: 'in',
                  _Is: 'is',
                  _IsNot: 'is not',
                  _Lt: '<',
                  _LtE: '<=',
                  _NotEq: '!=',
                  _NotIn: 'not in',
                  }

# FIXME : can't replace totally by Const : Str needed in _init_set_doc
Num._astng_fields = ()
Str._astng_fields = ()

class Const(Node):
    """represent a Str or Num node"""

class EmptyNode(Node):
    """represent a Empty node for compatibility"""

# scoped nodes ################################################################

def _init_set_doc(node):
    node.doc = None
    try:
        if isinstance(node.body[0], Discard) and isinstance(node.body[0].value, Str):
            node.doc = node.body[0].value.s
    except IndexError:
        pass # ast built from scratch

init_class = _init_set_doc

def _init_function(node):
    argnames = []
    for arg in node.args.args:
        if isinstance(arg, Name):
            argnames.append(arg.id )
        elif isinstance(arg, Tuple):
            argnames.extend( elt.id for elt in arg.elts )
    node.argnames = argnames
    node.defaults = node.args.defaults
    if node.args.vararg:
        node.argnames.append(node.args.vararg)
    if node.args.kwarg:
        node.argnames.append(node.args.kwarg)
    flags = 0
    if node.args.vararg:
        flags += 4
    if node.args.kwarg:
        flags += 8
    node.flags = flags
    del node.args

def init_function(node):
    _init_set_doc(node)
    _init_function(node)

def init_lambda(node):
    _init_function(node)

init_module = _init_set_doc

##  init_<node> functions #####################################################

def init_assattr(node):
    pass

def init_assert(node):
    node.fail = node.msg
    del node.msg

def init_assign(node):
    pass
def init_asslist(node):
    pass

def init_assname(node):
    pass

def init_asstuple(node):
    pass

def init_augassign(node):
    pass

def init_backquote(node):
    pass

def init_binop(node):
    node.op = BIN_OP_CLASSES[node.op.__class__]

def init_boolop(node):
    node.op = BOOL_OP_CLASSES[node.op.__class__]

def init_callfunc(node):
    node.args.extend(node.keywords)
    del node.keywords

def init_compare(node):
    node.ops = [(CMP_OP_CLASSES[op.__class__], expr)
                for op, expr in zip(node.ops, node.comparators)]
    del node.comparators

def init_dict(node):
    node.items = zip(node.keys, node.values)
    del node.keys, node.values

def init_discard(node):
    pass

def init_exec(node):
    node.expr = node.body
    del node.body

def init_getattr(node):
    node.attrname = node.attr
    node.expr = node.value
    del node.attr, node.value

def init_for(node):
    pass

def _recurse_if(ifnode, tests, orelse):
    """recurse on nested If nodes"""
    tests.append( (ifnode.test, ifnode.body) )
    del ifnode.test, ifnode.body
    if ifnode.orelse:
        if isinstance( ifnode.orelse[0], If):
            tests, orelse =  _recurse_if(ifnode.orelse[0], tests, orelse)
            del ifnode.orelse[0]
        else:
            orelse = ifnode.orelse
    return tests, orelse

def init_if(node):
    tests, orelse = _recurse_if(node, [], [])
    node.tests = tests
    node.orelse = orelse

def init_import(node):
    node.names = [(alias.name, alias.asname) for alias in node.names]

def init_import_from(node):
    init_import(node)
    node.modname = node.module
    del node.module

def init_keyword(node):
    pass

def init_list(node):
    pass

def init_listcomp(node):
    pass

def init_listcompfor(node):
    pass

def init_name(node):
    node.name = node.id
    del node.id

def init_num(node):
    node.__class__ = Const
    node.value = node.n
    node.name = "int" # compiler compat
    del node.n

def init_print(node):
    pass

def init_raise(node):
    pass

def init_slice(node):
    pass

def init_str(node):
    node.__class__ = Const
    node.value = node.s
    node.name = "str" # compiler compat
    del node.s

def init_subscript(node):
    node.expr = node.value
    slices = node.slice
    if hasattr(slices, 'value'): # Index
        node.subs = [slices.value]
        node.sliceflag = 'index'
    elif hasattr(slices, 'lower'): # Slice
        node.subs = [slices.lower, slices.upper]
        if slices.step:
            node.subs.append(slices.step)
        node.sliceflag = 'slice'
    del node.slice, node.value

def init_try_except(node):
    pass

def init_try_finally(node):
    pass

def init_tuple(node):
    pass

def init_unaryop(node):
    node.op = UNARY_OP_CLASSES[node.op.__class__]

def init_while(node):
    pass

# raw building ################################################################

def _add_docstring(node, doc):
    node.doc = doc
#     if doc:
#         expr = Expr()
#         node.body.append(expr)
#         expr.parent = None
#         docstr = Str()
#         docstr.s = doc
#         expr.value = docstr
#         docstr.parent = expr

def module_factory(doc):
    node = Module()
    node.body = []
    _add_docstring(node, doc)
    return node

def dict_factory():
    return Dict()

def import_from_factory(modname, membername):
    node = From()
    node.level = 0
    node.module = modname
    aliasnode = alias()
    aliasnode.parent = node
    aliasnode.name = membername
    aliasnode.asname = None
    node.names = [aliasnode]
    return node

def _const_factory(value):
    if isinstance(value, (int, long, complex, basestring)):
        node = Const()
    else:
        raise Exception(repr(value))
    node.value = value
    return node

def function_factory(name, args, defaults, flag=0, doc=None):
    """create and initialize a astng Function node"""
    node = Function()
    node.body = []
    node.name = name
    argsnode = arguments()
    argsnode.args = []
    for arg in args:
        argsnode.args.append(Name())
        argsnode.args[-1].name = arg
        argsnode.args[-1].parent = argsnode
    argsnode.defaults = []
    for default in defaults:
        argsnode.defaults.append(const_factory(default))
        argsnode.defaults[-1].parent = argsnode
    argsnode.kwarg = None # XXX
    argsnode.vararg = None # XXX
    argsnode.parent = node
    node.args = argsnode
    _add_docstring(node, doc)
    return node

def class_factory(name, basenames=None, doc=None):
    """create and initialize a astng Class node"""
    node = Class()
    node.body = []
    node.name = name
    # XXX to check
    node.bases = []
    for base in basenames:
        basenode = Name()
        basenode.name = base
        node.bases.append(basenode)
        basenode.parent = node
    _add_docstring(node, doc)
    return node

class Proxy_(object): pass

from _ast import Load as _Load, Store as _Store, Del as _Del
def native_repr_tree(node, indent='', _done=None):
    if _done is None:
        _done = set()
    if node in _done:
        print ('loop in tree: %r (%s)' % (node, getattr(node, 'lineno', None)))
        return
    _done.add(node)
    print indent + str(node)
    if type(node) is str: # XXX crash on Globals
        return
    indent += '    '
    d = node.__dict__
    if hasattr(node, '_attributes'):
        for a in node._attributes:
            attr = d[a]
            if attr is None:
                continue
            print indent + a, repr(attr)
    for f in node._fields or ():
        attr = d[f]
        if attr is None:
            continue
        if type(attr) is list:
            if not attr: continue
            print indent + f + ' ['
            for elt in attr:
                native_repr_tree(elt, indent, _done)
            print indent + ']'
            continue
        if isinstance(attr, (_Load, _Store, _Del)):
            continue
        if isinstance(attr, Node):
            print indent + f
            native_repr_tree(attr, indent, _done)
        else:
            print indent + f, repr(attr)
<|endoftext|>


<commit_before># -*- coding:utf-8 -*-

# Copyright 2015 NEC Corporation.                                          #
#                                                                          #
# Licensed under the Apache License, Version 2.0 (the "License");          #
# you may not use this file except in compliance with the License.         #
# You may obtain a copy of the License at                                  #
#                                                                          #
#   http://www.apache.org/licenses/LICENSE-2.0                             #
#                                                                          #
# Unless required by applicable law or agreed to in writing, software      #
# distributed under the License is distributed on an "AS IS" BASIS,        #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and      #
# limitations under the License.                                           #

import copy
import signal
import sys
import threading
import time
from functools import partial

from org.o3project.odenos.core.component.network.flow.ofpflow.ofp_flow_match import OFPFlowMatch
from org.o3project.odenos.core.component.network.flow.basic.basic_flow import BasicFlow
from org.o3project.odenos.core.component.network.flow.basic.basic_flow_match import BasicFlowMatch
from org.o3project.odenos.core.component.network.flow.basic.flow_action_output import FlowActionOutput
from org.o3project.odenos.core.component.network.flow.flow import Flow
from org.o3project.odenos.core.component.network.flow.flow_set import FlowSet
from org.o3project.odenos.core.component.network.flow.ofpflow.ofp_flow import OFPFlow
from org.o3project.odenos.core.component.network.packet.in_packet import InPacket
from org.o3project.odenos.core.component.network.packet.ofp_in_packet import OFPInPacket
from org.o3project.odenos.core.component.network.packet.ofp_out_packet import OFPOutPacket
from org.o3project.odenos.core.component.network.packet.out_packet import OutPacket
from org.o3project.odenos.core.component.network.packet.packet import Packet
from org.o3project.odenos.core.component.network.packet.packet_status import PacketStatus
from org.o3project.odenos.core.component.network.topology.link import Link
from org.o3project.odenos.core.component.network.topology.node import Node
from org.o3project.odenos.core.component.network.topology.port import Port
from org.o3project.odenos.core.component.network.topology.topology import Topology
from org.o3project.odenos.core.util.network_interface import NetworkInterface
from org.o3project.odenos.core.util.remote_object_interface import RemoteObjectInterface
from org.o3project.odenos.core.util.system_manager_interface import SystemManagerInterface
from org.o3project.odenos.remoteobject.manager.system.component_connection import ComponentConnection
from org.o3project.odenos.remoteobject.manager.system.component_connection_logic_and_network import ComponentConnectionLogicAndNetwork
from org.o3project.odenos.remoteobject.message.request import Request
from org.o3project.odenos.remoteobject.message.response import Response
from org.o3project.odenos.remoteobject.object_property import ObjectProperty
from org.o3project.odenos.remoteobject.transport.message_dispatcher import MessageDispatcher

def signal_handler(num, stack, obj):
    print 'Received signal %d' % num
    del obj
    sys.exit()

class ServerThread(threading.Thread):
    def __init__(self, dispatcher):
        threading.Thread.__init__(self)
        self.disp = dispatcher

    def run(self):
        self.disp.start()

class OdenosConfigurator(object):
    CM1 = "romgr1"
    CM2 = "romgr2"
    CM3 = "romgr3"
    DEF_ATTR = {"oper_status": "UP"}
    DEF_VENDOR = "VENDOR1"

    def __init__(self, dispatcher):
        self.disp = dispatcher
        self.sysmgr = SystemManagerInterface(self.disp)
        self.stations = {}
        self.packet_id = 0;

    def __init__(self):
        bound_func = partial(signal_handler, obj=self)
        signal.signal(signal.SIGINT, bound_func)
        signal.signal(signal.SIGTERM, bound_func)

        self.disp = MessageDispatcher()
        self.thread = ServerThread(self.disp)
        self.thread.start()

        self.sysmgr = SystemManagerInterface(self.disp)
        self.stations = {}
        self.packet_id = 0;

    def __del__(self):
        self.thread.join()
        self.disp.stop()

    def create_component(self, type, name, cm_id):
        obj = ObjectProperty(type, name)
        obj.set_property("version", "1")
        obj.set_property(ObjectProperty.CM_ID, cm_id)
        ret = self.sysmgr.put_components(obj).status_code
        if ret != 201:
            print "failed to create(ret): " + type + " " + name + " @ " + cm_id
        return RemoteObjectInterface(self.disp, name)

    def create_aggregator(self, name, cm_id=CM1):
        return self.create_component("Aggregator", name, cm_id)

    def create_federator(self, name, cm_id=CM1):
        return self.create_component("Federator", name, cm_id)

    def get_fed_boundaries(self, federator):
        resp = federator._get_object_to_remote_object("settings/boundaries")
        if resp.is_error(Request.Method.GET):
            return None
        return resp.body

    def get_ll_boundaries(self, linklayerizer):
        return self.get_fed_boundaries(linklayerizer)

    def set_fed_boundaries(self, federator, boundaries):
        n = 0
        for ports in boundaries:
            net1 = ports[0][0]
            net2 = ports[1][0]
            phy_port1 = ports[0][1]
            phy_port2 = ports[1][1]
            port1 = net1.get_physical_port(phy_port1)
            port2 = net2.get_physical_port(phy_port2)
            while not port1:
                print "cannot get port by %s from %s" % (phy_port1, net1.network_id)
                port1 = net1.get_physical_port(phy_port1)
                time.sleep(2)
            while not port2:
                print "cannot get port by %s from %s" % (phy_port2, net2.network_id)
                port2 = net2.get_physical_port(phy_port2)
                time.sleep(2)

            bond_id = "bond_%s" % str(n)
            bond = {"id": bond_id, "type": "Federator",
                     "network1": net1.network_id,
                     "node1": port1.node_id, "port1": port1.port_id,
                     "network2": net2.network_id,
                     "node2": port2.node_id, "port2": port2.port_id
                 }
            n = n + 1
            federator._put_object_to_remote_object("settings/boundaries/%s" % bond_id, bond)

    def set_ll_boundaries(self, linklayerizer, boundaries):
        n = 0
        for ports in boundaries:
            net1 = ports[0][0]
            net2 = ports[1][0]
            phy_port1 = ports[0][1]
            phy_port2 = ports[1][1]
            port1 = net1.get_physical_port(phy_port1)
            port2 = net2.get_physical_port(phy_port2)
            while not port1:
                print "cannot get port by %s from %s" % (phy_port1, net1.network_id)
                port1 = net1.get_physical_port(phy_port1)
                time.sleep(2)
            while not port2:
                print "cannot get port by %s from %s" % (phy_port2, net2.network_id)
                port2 = net2.get_physical_port(phy_port2)
                time.sleep(2)

            bond_id = "bond_" + str(n) + "_low_" + port1.port_id + "_up_" +  port2.port_id
            bond = {"id": bond_id, "type": "LinkLayerizer",
                     "lower_nw": net1.network_id,
                     "lower_nw_node": port1.node_id, "lower_nw_port": port1.port_id,
                     "upper_nw": net2.network_id,
                     "upper_nw_node": port2.node_id, "upper_nw_port": port2.port_id
                 }
            n = n + 1
            linklayerizer._put_object_to_remote_object("settings/boundaries/%s" % bond_id, bond)

    def create_l2switch(self, name, cm_id=CM1):
        return self.create_component("LearningSwitch", name, cm_id)

    def create_linklayerizer(self, name, cm_id=CM1):
        return self.create_component("LinkLayerizer", name, cm_id)

    def create_dummydriver(self, name, cm_id=CM1):
        return self.create_component("DummyDriver", name, cm_id)

    def create_ofdriver(self, name, cm_id=CM3):
        return self.create_component("OpenFlowDriver", name, cm_id)

    def create_network(self, name, cm_id=CM1):
        self.create_component("Network", name, cm_id)
        return NetworkInterface(self.disp, name)

    def get_network(self, name):
        return NetworkInterface(self.disp, name)

    def create_node(self, network, node_id, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"physical_id": node_id})
        if not attr.has_key("vendor"):
          attr.update({"vendor": self.DEF_VENDOR})
        return network.put_node(Node("Node", "0", node_id, {}, attr))

    def create_port(self, network, node_id, port_id, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"physical_id": "%s@%s" % (port_id, node_id)})
        attr.update({"max_bandwidth": "10000000"})
        attr.update({"unreserved_bandwidth": "10000000"})
        if not attr.has_key("vendor"):
          attr.update({"vendor": self.DEF_VENDOR})
        return network.put_port(Port("Port", "0", port_id, node_id, "", "", attr))

    def create_link(self, network, link_id, snode, sport, dnode, dport, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"max_bandwidth": "10000000"})
        attr.update({"unreserved_bandwidth": "10000000"})
        return network.put_link(Link("Link", "0", link_id, snode, sport, dnode, dport, attr))

    def create_simple_basicFlow(self, network, flow_id,
                                in_node, in_port, path, out_node, out_port, attr={}):
        matches = []
        matches.append(BasicFlowMatch("BasicFlowMatch", in_node, in_port))
        edge_actions = {}
        edge_actions[out_node] = [FlowActionOutput("FlowActionOutput", out_port)]
        attributes = attr
        flow = BasicFlow("BasicFlow", "0", flow_id, "simple_basicFlow",
                True, None, None, attributes, matches, path, edge_actions)
        return network.put_flow(flow)

    def create_ofp_flow(self, network, flow_id, matches, path, edge_actions):
        attributes = {}
        flow = OFPFlow("OFPFlow", "0", flow_id, "flowSetter",
                      True, None, None, attributes, matches,
                      None, None, path, edge_actions)
        return network.put_flow(flow)

    def add_ofp_inpacket(self, network, node_id, port_id, header, data, attr={}):
        self.packet_id = self.packet_id + 1
        attr = copy.deepcopy(attr)
        network.post_in_packet(
            OFPInPacket(str(self.packet_id),
                        "OFPInPacket", attr, node_id, port_id, header, data))

    def add_station(self, network, sid, node_id, port_id, mac):
        self.stations.update(
            {sid:{"network": network, "node_id": node_id, "port_id": port_id, "mac": mac}})

    def ping(self, src_sid, dst_sid):
        src = self.stations[src_sid]
        dst = self.stations[dst_sid]
        data = "deadbeef"
        header = OFPFlowMatch("OFPFlowMatch", src["node_id"], src["port_id"])
        header.eth_src = src["mac"]
        header.eth_dst = dst["mac"]
        self.add_ofp_inpacket(src["network"], src["node_id"], src["port_id"], header, data)

    def create_slicer(self, name, cm_id=CM1):
        return self.create_component("Slicer", name, cm_id)

    def set_slice_condition(self, slicer, priority, cond_id, conn_id, match):
        path = "settings/slice_condition_table/%s/conditions/%s" % (priority, cond_id)
        body = {"id": cond_id, "type":"BasicSliceCondition", "connection": conn_id}
        body.update(match)
        slicer._put_object_to_remote_object(path, body)

    def create_ofpslicer(self, name, cm_id=CM1):
        return self.create_component("OpenFlowSlicer", name, cm_id)

    def set_ofpslice_condition(self, slicer, priority, cond_id, conn_id, match):
        path = "settings/slice_condition_table/%s/conditions/%s" % (priority, cond_id)
        body = {"id": cond_id, "type":"OpenFlowSliceCondition", "connection": conn_id}
        body.update(match)
        slicer._put_object_to_remote_object(path, body)

    def connect(self, logic, network, type):
        conn_id = logic.object_id + "-" + network.object_id
        conn = ComponentConnectionLogicAndNetwork(
            conn_id, type, ComponentConnection.State.INITIALIZING,
            logic.object_id, network.object_id)
        if self.sysmgr.put_connection(conn).status_code != 201:
            print "failed to connect(ret): " + conn_id + " as " + type
        return conn_id
<commit_msg>update python/configurator.py<commit_after># -*- coding:utf-8 -*-

# Copyright 2015 NEC Corporation.                                          #
#                                                                          #
# Licensed under the Apache License, Version 2.0 (the "License");          #
# you may not use this file except in compliance with the License.         #
# You may obtain a copy of the License at                                  #
#                                                                          #
#   http://www.apache.org/licenses/LICENSE-2.0                             #
#                                                                          #
# Unless required by applicable law or agreed to in writing, software      #
# distributed under the License is distributed on an "AS IS" BASIS,        #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and      #
# limitations under the License.                                           #

import copy
import signal
import sys
import threading
import time
from functools import partial

from org.o3project.odenos.core.component.network.flow.ofpflow.ofp_flow_match import OFPFlowMatch
from org.o3project.odenos.core.component.network.flow.basic.basic_flow import BasicFlow
from org.o3project.odenos.core.component.network.flow.basic.basic_flow_match import BasicFlowMatch
from org.o3project.odenos.core.component.network.flow.basic.flow_action_output import FlowActionOutput
from org.o3project.odenos.core.component.network.flow.flow import Flow
from org.o3project.odenos.core.component.network.flow.flow_set import FlowSet
from org.o3project.odenos.core.component.network.flow.ofpflow.ofp_flow import OFPFlow
from org.o3project.odenos.core.component.network.packet.in_packet import InPacket
from org.o3project.odenos.core.component.network.packet.ofp_in_packet import OFPInPacket
from org.o3project.odenos.core.component.network.packet.ofp_out_packet import OFPOutPacket
from org.o3project.odenos.core.component.network.packet.out_packet import OutPacket
from org.o3project.odenos.core.component.network.packet.packet import Packet
from org.o3project.odenos.core.component.network.packet.packet_status import PacketStatus
from org.o3project.odenos.core.component.network.topology.link import Link
from org.o3project.odenos.core.component.network.topology.node import Node
from org.o3project.odenos.core.component.network.topology.port import Port
from org.o3project.odenos.core.component.network.topology.topology import Topology
from org.o3project.odenos.core.util.network_interface import NetworkInterface
from org.o3project.odenos.core.util.remote_object_interface import RemoteObjectInterface
from org.o3project.odenos.core.util.system_manager_interface import SystemManagerInterface
from org.o3project.odenos.remoteobject.manager.system.component_connection import ComponentConnection
from org.o3project.odenos.remoteobject.manager.system.component_connection_logic_and_network import ComponentConnectionLogicAndNetwork
from org.o3project.odenos.remoteobject.message.request import Request
from org.o3project.odenos.remoteobject.message.response import Response
from org.o3project.odenos.remoteobject.object_property import ObjectProperty
from org.o3project.odenos.remoteobject.transport.message_dispatcher import MessageDispatcher

def signal_handler(num, stack, obj):
    print 'Received signal %d' % num
    del obj
    sys.exit()

class ServerThread(threading.Thread):
    def __init__(self, dispatcher):
        threading.Thread.__init__(self)
        self.disp = dispatcher

    def run(self):
        self.disp.start()

class OdenosConfigurator(object):
    CM1 = "romgr1"
    CM2 = "romgr2"
    CM3 = "romgr3"
    DEF_ATTR = {"oper_status": "UP"}
    DEF_VENDOR = "VENDOR1"

    def __init__(self, dispatcher=None):
      if dispatcher is None:
        bound_func = partial(signal_handler, obj=self)
        signal.signal(signal.SIGINT, bound_func)
        signal.signal(signal.SIGTERM, bound_func)

      self.disp = MessageDispatcher()
      if dispatcher is None:
        self.thread = ServerThread(self.disp)
        self.thread.start()

      self.sysmgr = SystemManagerInterface(self.disp)
      self.stations = {}
      self.packet_id = 0;

    def __del__(self):
        self.thread.join()
        self.disp.stop()

    def create_component(self, type, name, cm_id):
        obj = ObjectProperty(type, name)
        obj.set_property("version", "1")
        obj.set_property(ObjectProperty.CM_ID, cm_id)
        ret = self.sysmgr.put_components(obj).status_code
        if ret != 201:
            print "failed to create(ret): " + type + " " + name + " @ " + cm_id
        return RemoteObjectInterface(self.disp, name)

    def create_aggregator(self, name, cm_id=CM1):
        return self.create_component("Aggregator", name, cm_id)

    def create_federator(self, name, cm_id=CM1):
        return self.create_component("Federator", name, cm_id)

    def get_fed_boundaries(self, federator):
        resp = federator._get_object_to_remote_object("settings/boundaries")
        if resp.is_error(Request.Method.GET):
            return None
        return resp.body

    def get_ll_boundaries(self, linklayerizer):
        return self.get_fed_boundaries(linklayerizer)

    def set_fed_boundaries(self, federator, boundaries):
        n = 0
        for ports in boundaries:
            net1 = ports[0][0]
            net2 = ports[1][0]
            phy_port1 = ports[0][1]
            phy_port2 = ports[1][1]
            port1 = net1.get_physical_port(phy_port1)
            port2 = net2.get_physical_port(phy_port2)
            while not port1:
                print "cannot get port by %s from %s" % (phy_port1, net1.network_id)
                port1 = net1.get_physical_port(phy_port1)
                time.sleep(2)
            while not port2:
                print "cannot get port by %s from %s" % (phy_port2, net2.network_id)
                port2 = net2.get_physical_port(phy_port2)
                time.sleep(2)

            bond_id = "bond_%s" % str(n)
            bond = {"id": bond_id, "type": "Federator",
                     "network1": net1.network_id,
                     "node1": port1.node_id, "port1": port1.port_id,
                     "network2": net2.network_id,
                     "node2": port2.node_id, "port2": port2.port_id
                 }
            n = n + 1
            federator._put_object_to_remote_object("settings/boundaries/%s" % bond_id, bond)

    def set_ll_boundaries(self, linklayerizer, boundaries):
        n = 0
        for ports in boundaries:
            net1 = ports[0][0]
            net2 = ports[1][0]
            phy_port1 = ports[0][1]
            phy_port2 = ports[1][1]
            port1 = net1.get_physical_port(phy_port1)
            port2 = net2.get_physical_port(phy_port2)
            while not port1:
                print "cannot get port by %s from %s" % (phy_port1, net1.network_id)
                port1 = net1.get_physical_port(phy_port1)
                time.sleep(2)
            while not port2:
                print "cannot get port by %s from %s" % (phy_port2, net2.network_id)
                port2 = net2.get_physical_port(phy_port2)
                time.sleep(2)

            bond_id = "bond_" + str(n) + "_low_" + port1.port_id + "_up_" +  port2.port_id
            bond = {"id": bond_id, "type": "LinkLayerizer",
                     "lower_nw": net1.network_id,
                     "lower_nw_node": port1.node_id, "lower_nw_port": port1.port_id,
                     "upper_nw": net2.network_id,
                     "upper_nw_node": port2.node_id, "upper_nw_port": port2.port_id
                 }
            n = n + 1
            linklayerizer._put_object_to_remote_object("settings/boundaries/%s" % bond_id, bond)

    def create_l2switch(self, name, cm_id=CM1):
        return self.create_component("LearningSwitch", name, cm_id)

    def create_linklayerizer(self, name, cm_id=CM1):
        return self.create_component("LinkLayerizer", name, cm_id)

    def create_dummydriver(self, name, cm_id=CM1):
        return self.create_component("DummyDriver", name, cm_id)

    def create_ofdriver(self, name, cm_id=CM3):
        return self.create_component("OpenFlowDriver", name, cm_id)

    def create_network(self, name, cm_id=CM1):
        self.create_component("Network", name, cm_id)
        return NetworkInterface(self.disp, name)

    def get_network(self, name):
        return NetworkInterface(self.disp, name)

    def create_node(self, network, node_id, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"physical_id": node_id})
        if not attr.has_key("vendor"):
          attr.update({"vendor": self.DEF_VENDOR})
        return network.put_node(Node("Node", "0", node_id, {}, attr))

    def create_port(self, network, node_id, port_id, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"physical_id": "%s@%s" % (port_id, node_id)})
        attr.update({"max_bandwidth": "10000000"})
        attr.update({"unreserved_bandwidth": "10000000"})
        if not attr.has_key("vendor"):
          attr.update({"vendor": self.DEF_VENDOR})
        return network.put_port(Port("Port", "0", port_id, node_id, "", "", attr))

    def create_link(self, network, link_id, snode, sport, dnode, dport, attr=DEF_ATTR):
        attr = copy.deepcopy(attr)
        attr.update({"max_bandwidth": "10000000"})
        attr.update({"unreserved_bandwidth": "10000000"})
        return network.put_link(Link("Link", "0", link_id, snode, sport, dnode, dport, attr))

    def create_simple_basicFlow(self, network, flow_id,
                                in_node, in_port, path, out_node, out_port, attr={}):
        matches = []
        matches.append(BasicFlowMatch("BasicFlowMatch", in_node, in_port))
        edge_actions = {}
        edge_actions[out_node] = [FlowActionOutput("FlowActionOutput", out_port)]
        attributes = attr
        flow = BasicFlow("BasicFlow", "0", flow_id, "simple_basicFlow",
                True, None, None, attributes, matches, path, edge_actions)
        return network.put_flow(flow)

    def create_ofp_flow(self, network, flow_id, matches, path, edge_actions):
        attributes = {}
        flow = OFPFlow("OFPFlow", "0", flow_id, "flowSetter",
                      True, None, None, attributes, matches,
                      None, None, path, edge_actions)
        return network.put_flow(flow)

    def add_ofp_inpacket(self, network, node_id, port_id, header, data, attr={}):
        self.packet_id = self.packet_id + 1
        attr = copy.deepcopy(attr)
        network.post_in_packet(
            OFPInPacket(str(self.packet_id),
                        "OFPInPacket", attr, node_id, port_id, header, data))

    def add_station(self, network, sid, node_id, port_id, mac):
        self.stations.update(
            {sid:{"network": network, "node_id": node_id, "port_id": port_id, "mac": mac}})

    def ping(self, src_sid, dst_sid):
        src = self.stations[src_sid]
        dst = self.stations[dst_sid]
        data = "deadbeef"
        header = OFPFlowMatch("OFPFlowMatch", src["node_id"], src["port_id"])
        header.eth_src = src["mac"]
        header.eth_dst = dst["mac"]
        self.add_ofp_inpacket(src["network"], src["node_id"], src["port_id"], header, data)

    def create_slicer(self, name, cm_id=CM1):
        return self.create_component("Slicer", name, cm_id)

    def set_slice_condition(self, slicer, priority, cond_id, conn_id, match):
        path = "settings/slice_condition_table/%s/conditions/%s" % (priority, cond_id)
        body = {"id": cond_id, "type":"BasicSliceCondition", "connection": conn_id}
        body.update(match)
        slicer._put_object_to_remote_object(path, body)

    def create_ofpslicer(self, name, cm_id=CM1):
        return self.create_component("OpenFlowSlicer", name, cm_id)

    def set_ofpslice_condition(self, slicer, priority, cond_id, conn_id, match):
        path = "settings/slice_condition_table/%s/conditions/%s" % (priority, cond_id)
        body = {"id": cond_id, "type":"OpenFlowSliceCondition", "connection": conn_id}
        body.update(match)
        slicer._put_object_to_remote_object(path, body)

    def connect(self, logic, network, type):
        conn_id = logic.object_id + "-" + network.object_id
        conn = ComponentConnectionLogicAndNetwork(
            conn_id, type, ComponentConnection.State.INITIALIZING,
            logic.object_id, network.object_id)
        if self.sysmgr.put_connection(conn).status_code != 201:
            print "failed to connect(ret): " + conn_id + " as " + type
        return conn_id
<|endoftext|>


<commit_before>from random import randint
from copy import deepcopy

class Ship(object):
    def __init__(self, name, cost, tech, attack, defense, damage):
        self.name = name
        self.cost = cost
        self.tech = tech
        self.attack = attack
        self.defense = defense
        self.damage = damage

global ships
ships = {
        'Frigate' : Ship('Frigate',     5, 1.,  1, 2, 5),
        'Destroyer': Ship('Destroyer',  10, 2.,  2, 3, 11),
        'Cruiser': Ship('Cruiser',    20, 3.5, 4, 6, 24),
        'Battleship': Ship('Battleship', 40, 5.5, 8, 12,53),
        'Dreadnought': Ship('Dreadnought', 80, 9., 16, 24,116),
        'SuperDreadnought': Ship('SuperDreadnought', 160, 15., 32, 48, 255)
       }

class Fleet(object):
    def __init__(self, frigates=0, destroyers=0, cruisers=0, battleships=0,
            dreadnoughts=0, superdreadnoughts=0):
        global ships
        self.ships = []
        self.ships.append((ships['Frigate'], frigates))
        self.ships.append((ships['Destroyer'], destroyers))
        self.ships.append((ships['Cruiser'], cruisers))
        self.ships.append((ships['Battleship'], battleships))
        self.ships.append((ships['Dreadnought'], dreadnoughts))
        self.ships.append((ships['SuperDreadnought'], superdreadnoughts))

    def number_of_ships(self):
        return sum([s[1] for s in self.ships])

    def fleet_destroyed(self):
        """Has the fleet been destroyed?"""
        return 0 == self.number_of_ships()

    def get_ship_by_index(self, i):
        count = 0
        for idx, (ship, n) in enumerate(self.ships):
            count += n
            if i < count and count > 0:
                return idx
        raise Exception("Could not find ship by index " + str(i))

    def get_random_ship(self):
        total_ships = self.number_of_ships()
        which_lost = randint(0, total_ships - 1)
        idx = self.get_ship_by_index(which_lost)
        return idx

    def destroy_ship(self, idx):
        self.ships[idx] = (self.ships[idx][0], self.ships[idx][1] - 1)
        if self.ships[idx][1] < 0:
            raise Exception("destroy_ship destroyed a non-existent ship")

class Fight(object):
    def __init__(self, attacker, defender):
        self.attacker = deepcopy(attacker)
        self.defender = deepcopy(defender)

    def determine_losses(self, fleet, damage):
        while True:  # Until damage < 1
            victim = fleet.get_random_ship()
            fleet.destroy_ship(victim)
            damage -= fleet.ships[victim][0].damage
            if fleet.number_of_ships() == 0:
                damage = 0
            if damage < 1:
                break

    def round(self):
        attack_damage = 0.0
        for ship in self.attacker.ships:
            a = ship[0].attack
            attack_damage += randint(0, a + 1) + a

        defense_damage = 0.0
        for ship in self.defender.ships:
            d = ship[0].defense
            defense_damage += randint(0, d + 1) + d

        attack_succeeds = None
        if self.defender.fleet_destroyed():
            attack_succeeds = True
        else:
            self.determine_losses(self.attacker, defense_damage)
            self.determine_losses(self.defender, attack_damage)

        if self.defender.fleet_destroyed():
            attack_succeeds = True
        if self.attacker.fleet_destroyed():
            attack_succeeds = False
        return attack_succeeds

    def fight(self):
        while True:
            attack_succeeds = self.round()
            if attack_succeeds is not None:
                return attack_succeeds

"""
Runs a series of mock battles between two fleets, and
predicts the probability that the attacker will win against
the defender.

Example Usage:
    import dominions_calc as dc
    dc.chance_of_winning(dc.Fleet(frigates=29,destroyers=2), dc.Fleet(frigates=20))
    Attacker has 43.00% chance of winning.
"""
def chance_of_winning(attacker, defender):
    n = 100
    wins = 0
    for i in range(n):
        attacker_won = Fight(attacker, defender).fight()
        if attacker_won:
            wins += 1
    percent = 100. * float(wins) / n
    print("Attacker has %.1f%% chance of winning." % percent)
    return percent

<commit_msg>added population and production calculations to dominions_calc<commit_after>"""Dominions Calc, a utility to help with Dominions math,
By Braddock Gaskill (braddock@braddock.com) 2017"""

from random import randint
from copy import deepcopy
from math import floor, sqrt
from itertools import islice

class Ship(object):
    """Represents a class of ship, and the defining characteristics"""
    def __init__(self, name, cost, tech, attack, defense, damage):
        self.name = name
        self.cost = cost
        self.tech = tech
        self.attack = attack
        self.defense = defense
        self.damage = damage

global ships
ships = {
        'Frigate' : Ship('Frigate',     5, 1.,  1, 2, 5),
        'Destroyer': Ship('Destroyer',  10, 2.,  2, 3, 11),
        'Cruiser': Ship('Cruiser',    20, 3.5, 4, 6, 24),
        'Battleship': Ship('Battleship', 40, 5.5, 8, 12,53),
        'Dreadnought': Ship('Dreadnought', 80, 9., 16, 24,116),
        'SuperDreadnought': Ship('SuperDreadnought', 160, 15., 32, 48, 255)
       }

class Fleet(object):
    """Represents a fleet of ships"""
    def __init__(self, frigates=0, destroyers=0, cruisers=0, battleships=0,
            dreadnoughts=0, superdreadnoughts=0):
        global ships
        self.ships = []
        self.ships.append((ships['Frigate'], frigates))
        self.ships.append((ships['Destroyer'], destroyers))
        self.ships.append((ships['Cruiser'], cruisers))
        self.ships.append((ships['Battleship'], battleships))
        self.ships.append((ships['Dreadnought'], dreadnoughts))
        self.ships.append((ships['SuperDreadnought'], superdreadnoughts))

    def number_of_ships(self):
        return sum([s[1] for s in self.ships])

    def fleet_destroyed(self):
        """Has the fleet been destroyed?"""
        return 0 == self.number_of_ships()

    def get_ship_by_index(self, i):
        count = 0
        for idx, (ship, n) in enumerate(self.ships):
            count += n
            if i < count and count > 0:
                return idx
        raise Exception("Could not find ship by index " + str(i))

    def get_random_ship(self):
        total_ships = self.number_of_ships()
        which_lost = randint(0, total_ships - 1)
        idx = self.get_ship_by_index(which_lost)
        return idx

    def destroy_ship(self, idx):
        self.ships[idx] = (self.ships[idx][0], self.ships[idx][1] - 1)
        if self.ships[idx][1] < 0:
            raise Exception("destroy_ship destroyed a non-existent ship")

class Fight(object):
    """Represents a fight between two fleets"""

    def __init__(self, attacker, defender):
        self.attacker = deepcopy(attacker)
        self.defender = deepcopy(defender)

    def determine_losses(self, fleet, damage):
        """Determine the ships destroyed in one round of fighting"""
        while True:  # Until damage < 1
            victim = fleet.get_random_ship()
            fleet.destroy_ship(victim)
            damage -= fleet.ships[victim][0].damage
            if fleet.number_of_ships() == 0:
                damage = 0
            if damage < 1:
                break

    def round(self):
        """One round of fighting
        return - True if the attacker wins (defender destroyed),
                 false if the defender wins (attacker destroyed),
                 None if neither side wins yet.
        """
        attack_damage = 0.0
        for ship in self.attacker.ships:
            a = ship[0].attack
            attack_damage += randint(0, a + 1) + a

        defense_damage = 0.0
        for ship in self.defender.ships:
            d = ship[0].defense
            defense_damage += randint(0, d + 1) + d

        attack_succeeds = None
        if self.defender.fleet_destroyed():
            attack_succeeds = True
        else:
            self.determine_losses(self.attacker, defense_damage)
            self.determine_losses(self.defender, attack_damage)

        if self.defender.fleet_destroyed():
            attack_succeeds = True
        if self.attacker.fleet_destroyed():
            attack_succeeds = False
        return attack_succeeds

    def fight(self):
        """Perform rounds of fighting until one fleet is destroyed.
        return value - True if the attacker wins, false if the defender wins"""
        while True:
            attack_succeeds = self.round()
            if attack_succeeds is not None:
                return attack_succeeds

def chance_of_winning(attacker, defender):
"""
Runs a series of mock battles between two fleets, and
predicts the probability that the attacker will win against
the defender.

Example Usage:
    import dominions_calc as dc
    dc.chance_of_winning(dc.Fleet(frigates=29,destroyers=2), dc.Fleet(frigates=20))
    Attacker has 43.00% chance of winning.
"""
    n = 100
    wins = 0
    for i in range(n):
        attacker_won = Fight(attacker, defender).fight()
        if attacker_won:
            wins += 1
    percent = 100. * float(wins) / n
    print("Attacker has %.1f%% chance of winning." % percent)
    return percent

def population_gen(start_pop, habitability, owned=True):
    """This generator yields the population as it grows
    for a planet"""
    pop = start_pop
    while True:
        if owned:
            divisor = 1000.
        else:
            divisor = 2000.
        pop = floor(pop * ((float(habitability) / divisor) + 1.05))
        yield pop

def population(n, start_pop, habitability, owned=True):
    """Project population into the future.  Returns a list,
    one population per turn.  n specifies the number of turns
    to return"""
    return list(islice(population_gen(start_pop, habitability, owned), n))

def production(pop, level, industry_percent):
    """Compute the production of technology and industry units
    for the given population and industrial level.
    pop = population of planet
    level = industry level of planet
    industry_percent = percentage of workforce allocated
                       to industry (vs technology)

    Returns a tuple (industry_units, tech_units)"""
    pop = float(pop)
    level = float(level)
    industry_fraction = (industry_percent / 100.)
    tech_fraction = 1 - industry_fraction
    iu = floor(industry_fraction * (pop / 1000.) * sqrt(level))
    tu = floor(tech_fraction * (pop / 2500.) * sqrt(level))
    return (iu, tu)

<|endoftext|>