<commit_before># -*- coding: utf-8 -*-
#!usr/bin/env python

"""script for ddf dataset management tasks"""

import click
import os
import logging

@click.group()
@click.option('--debug/--no-debug', default=False)
def ddf(debug):
    if debug:
        level = logging.DEBUG
    else:
        level = logging.WARNING
    logging.basicConfig(level=level, format='%(asctime)s -%(levelname)s- %(message)s',
                        datefmt="%H:%M:%S"
                        )

# project management
@ddf.command()
def new():
    """create a new ddf project"""
    from cookiecutter.main import cookiecutter
    cookiecutter('https://github.com/semio/ddf_project_template')

@ddf.command()
@click.argument('how', default='ddf', type=click.Choice(['ddf', 'lang', 'langsplit']))
@click.argument('path', default='./')
@click.option('--force', flag_value=True, default=False, help='force deletion')
def cleanup(path, how, force):
    """clean up ddf files or translation files.

    :arguments

    \b
    how: what to clean, choose from 'ddf', 'lang' and 'langsplit'
    path: the dataset path
    """
    from ddf_utils.io import cleanup as cl
    from ddf_utils.ddf_reader import is_dataset
    if force:
        cl(path, how)
    else:
        if not is_dataset(path):
            print('not a dataset path: {}. please set correct path or use --force to force run.'.format(path))
        else:
            cl(path, how)
    click.echo('Done.')

@ddf.command()
@click.argument('path')
@click.option('--update', '-u', 'update', flag_value=True, default=False, help='update existing datapackage.json')
def create_datapackage(path, update):
    """create datapackage.json"""
    from ddf_utils.index import get_datapackage
    import json
    if not update:
        if os.path.exists(os.path.join(path, 'datapackage.json')):
            click.echo('datapackage.json already exists. skipping')
            return
        res = get_datapackage(path)
        with open(os.path.join(path, 'datapackage.json'), 'w', encoding='utf8') as f:
            json.dump(res, f, indent=4, ensure_ascii=False)
    else:
        get_datapackage(path, update_existing=True)
    click.echo('Done.')

# chef and recipe
@ddf.command()
@click.option('--recipe', '-i', type=click.Path(exists=True), required=True)
@click.option('--outdir', '-o', type=click.Path(exists=True))
@click.option('--ddf_dir', type=click.Path(exists=True), default=None)
@click.option('--update', 'update', flag_value=False, help='Not implemented yet')  # not impletmented
@click.option('--dry_run', '-d', 'dry_run', flag_value=True, default=False, help="don't save output to disk")
@click.option('--show-tree', 'show_tree', flag_value=True, default=False, help='show the dependency tree')
def run_recipe(recipe, outdir, ddf_dir, update, dry_run, show_tree):
    """generate new ddf dataset with recipe"""
    import ddf_utils.chef as chef
    from ddf_utils.index import get_datapackage
    import json
    click.echo('building recipe...')
    if ddf_dir:
        recipe = chef.build_recipe(recipe, ddf_dir=ddf_dir)
    else:
        recipe = chef.build_recipe(recipe)
    if show_tree:
        dag = chef.cook.build_dag(recipe)
        dag.tree_view()
        return
    if update:
        pass
    res = chef.run_recipe(recipe)
    if not dry_run:
        click.echo('saving result to disk...')
        chef.dish_to_csv(res, outdir)
        click.echo('creating datapackage file...')
        res = get_datapackage(outdir)
        with open(os.path.join(outdir, 'datapackage.json'), 'w', encoding='utf8') as f:
            json.dump(res, f, indent=4, ensure_ascii=False)
    click.echo("Done.")

# Translation related tasks
@ddf.command()
@click.argument('path', type=click.Path(exists=True))
@click.option('--type', '-t', 'dtype', type=click.Choice(['csv', 'json']), help='split file type')
@click.option('--overwrite/--no-overwrite', default=False, help='overwrite existing files or not')
@click.option('--split_path', default='langsplit', help='path to langsplit folder')
@click.option('--exclude_concept', '-x', 'exclude_concepts', multiple=True,
              help='concepts to exclude', metavar='concept')
def split_translation(path, split_path, dtype, exclude_concepts, overwrite):
    """split ddf files for crowdin translation"""
    from ddf_utils.i18n import split_translations_csv, split_translations_json
    if dtype == 'csv':
        split_translations_csv(path, split_path, exclude_concepts, overwrite)
    elif dtype == 'json':
        split_translations_json(path, split_path, exclude_concepts, overwrite)
    click.echo('Done.')

#TODO: docs
@ddf.command()
@click.argument('path', type=click.Path(exists=True))
@click.option('--overwrite/--no-overwrite', default=False)
@click.option('--type', '-t', 'dtype', type=click.Choice(['json', 'csv']))
@click.option('--split_path', default='langsplit')
@click.option('--lang_path', default='lang')
def merge_translation(path, split_path, lang_path, dtype, overwrite):
    """merge all translation files from crowdin"""
    from ddf_utils.i18n import merge_translations_csv, merge_translations_json
    if dtype == 'csv':
        merge_translations_csv(path, split_path, lang_path, overwrite)
    else:
        merge_translations_json(path, split_path, lang_path, overwrite)
    click.echo('Done.')

if __name__ == '__main__':
    ddf()
<commit_msg>cli docs<commit_after># -*- coding: utf-8 -*-
#!usr/bin/env python

"""script for ddf dataset management tasks"""

import click
import os
import logging

@click.group()
@click.option('--debug/--no-debug', default=False)
def ddf(debug):
    if debug:
        level = logging.DEBUG
    else:
        level = logging.WARNING
    logging.basicConfig(level=level, format='%(asctime)s -%(levelname)s- %(message)s',
                        datefmt="%H:%M:%S"
                        )

# project management
@ddf.command()
def new():
    """create a new ddf project"""
    from cookiecutter.main import cookiecutter
    cookiecutter('https://github.com/semio/ddf_project_template')

@ddf.command()
@click.argument('how', default='ddf', type=click.Choice(['ddf', 'lang', 'langsplit']))
@click.argument('path', default='./')
@click.option('--force', flag_value=True, default=False, help='force deletion')
def cleanup(path, how, force):
    """clean up ddf files or translation files.

    :arguments

    \b
    how: what to clean, choose from 'ddf', 'lang' and 'langsplit'
    path: the dataset path
    """
    from ddf_utils.io import cleanup as cl
    from ddf_utils.ddf_reader import is_dataset
    if force:
        cl(path, how)
    else:
        if not is_dataset(path):
            print('not a dataset path: {}. please set correct path or use --force to force run.'.format(path))
        else:
            cl(path, how)
    click.echo('Done.')

@ddf.command()
@click.argument('path')
@click.option('--update', '-u', 'update', flag_value=True, default=False, help='update existing datapackage.json')
def create_datapackage(path, update):
    """create datapackage.json"""
    from ddf_utils.index import get_datapackage
    import json
    if not update:
        if os.path.exists(os.path.join(path, 'datapackage.json')):
            click.echo('datapackage.json already exists. skipping')
            return
        res = get_datapackage(path)
        with open(os.path.join(path, 'datapackage.json'), 'w', encoding='utf8') as f:
            json.dump(res, f, indent=4, ensure_ascii=False)
    else:
        get_datapackage(path, update_existing=True)
    click.echo('Done.')

# chef and recipe
@ddf.command()
@click.option('--recipe', '-i', type=click.Path(exists=True), required=True)
@click.option('--outdir', '-o', type=click.Path(exists=True))
@click.option('--ddf_dir', type=click.Path(exists=True), default=None)
@click.option('--update', 'update', flag_value=False, help='Not implemented yet')  # not impletmented
@click.option('--dry_run', '-d', 'dry_run', flag_value=True, default=False, help="don't save output to disk")
@click.option('--show-tree', 'show_tree', flag_value=True, default=False, help='show the dependency tree')
def run_recipe(recipe, outdir, ddf_dir, update, dry_run, show_tree):
    """generate new ddf dataset with recipe"""
    import ddf_utils.chef as chef
    from ddf_utils.index import get_datapackage
    import json
    click.echo('building recipe...')
    if ddf_dir:
        recipe = chef.build_recipe(recipe, ddf_dir=ddf_dir)
    else:
        recipe = chef.build_recipe(recipe)
    if show_tree:
        dag = chef.cook.build_dag(recipe)
        dag.tree_view()
        return
    if update:
        pass
    res = chef.run_recipe(recipe)
    if not dry_run:
        click.echo('saving result to disk...')
        chef.dish_to_csv(res, outdir)
        click.echo('creating datapackage file...')
        res = get_datapackage(outdir)
        with open(os.path.join(outdir, 'datapackage.json'), 'w', encoding='utf8') as f:
            json.dump(res, f, indent=4, ensure_ascii=False)
    click.echo("Done.")

# Translation related tasks
@ddf.command()
@click.argument('path', type=click.Path(exists=True))
@click.option('--type', '-t', 'dtype', type=click.Choice(['csv', 'json']), help='split file type')
@click.option('--overwrite/--no-overwrite', default=False, help='overwrite existing files or not')
@click.option('--split_path', default='langsplit', help='path to langsplit folder')
@click.option('--exclude_concept', '-x', 'exclude_concepts', multiple=True,
              help='concepts to exclude', metavar='concept')
def split_translation(path, split_path, dtype, exclude_concepts, overwrite):
    """split ddf files for crowdin translation"""
    from ddf_utils.i18n import split_translations_csv, split_translations_json
    if dtype == 'csv':
        split_translations_csv(path, split_path, exclude_concepts, overwrite)
    elif dtype == 'json':
        split_translations_json(path, split_path, exclude_concepts, overwrite)
    click.echo('Done.')

@ddf.command()
@click.argument('path', type=click.Path(exists=True))
@click.option('--overwrite/--no-overwrite', default=False, help='overwrite existing files or not')
@click.option('--type', '-t', 'dtype', type=click.Choice(['json', 'csv']), help='split file type')
@click.option('--split_path', default='langsplit', help='path to langsplit folder')
@click.option('--lang_path', default='lang', help='path to lang folder')
def merge_translation(path, split_path, lang_path, dtype, overwrite):
    """merge all translation files from crowdin"""
    from ddf_utils.i18n import merge_translations_csv, merge_translations_json
    if dtype == 'csv':
        merge_translations_csv(path, split_path, lang_path, overwrite)
    else:
        merge_translations_json(path, split_path, lang_path, overwrite)
    click.echo('Done.')

if __name__ == '__main__':
    ddf()
<|endoftext|>


<commit_before># decode_beacon.py
# Beacon advertisement data decoder
# Copyright (c) 2015 Patrick Van Oosterwijck
# MIT Licensed
#
# For now it only decodes iBeacon and AltBeacon data, it is easily extended
# to support other formats.
# Based on https://github.com/adamf/BLE/blob/master/ble-scanner.py and BlueZ
# source code.

import struct
from collections import namedtuple
import uuid

def decode_ibeacon(ad_struct):
  """Ad structure decoder for iBeacon
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec iBeacon structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'ibeacon' for Apple iBeacon
    uuid: <string> UUID
    major: <int> iBeacon Major
    minor: <int> iBeacon Minor
    rssi_ref: <int> Reference signal @ 1m in dBm
  If this isn't a valid iBeacon structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is the length correct and is our data long enough?
  if adstruct_bytes == 0x1B and adstruct_bytes <= len(ad_struct):
    # Decode the ad structure assuming iBeacon format
    iBeaconData = namedtuple('iBeaconData', 'adstruct_bytes adstruct_type '
                  + 'mfg_id_low mfg_id_high ibeacon_id ibeacon_data_len '
                  + 'uuid major minor rssi_ref')
    bd = iBeaconData._make(struct.unpack('>BBBBBB16sHHb', ad_struct[:27]))
    # Check whether all iBeacon specific values are correct
    if bd.adstruct_bytes == 0x1A and bd.adstruct_type == 0xFF and \
        bd.mfg_id_low == 0x4C and bd.mfg_id_high == 0x00 and \
        bd.ibeacon_id == 0x02 and bd.ibeacon_data_len == 0x15:
      # This is a valid iBeacon ad structure
      # Fill in the return structure with the data we extracted
      ret['type'] = 'ibeacon'
      ret['uuid'] = str(uuid.UUID(bytes=bd.uuid))
      ret['major'] = bd.major
      ret['minor'] = bd.minor
      ret['rssi_ref'] = bd.rssi_ref
  # Return the object
  return ret

def decode_altbeacon(ad_struct):
  """Ad structure decoder for AltBeacon
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec AltBeacon structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'altbeacon' for AltBeacon
    mfg_id: <int> indicating Bluetooth SIG assigned manufacturer code
    beacon_id: <string> hex string representing 20 byte beacon id
    mfg_res: <int> manufacturer reserved value
    rssi_ref: <int> Reference signal @ 1m in dBm
  If this isn't a valid AltBeacon structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is the length correct and is our data long enough?
  if adstruct_bytes == 0x1C and adstruct_bytes <= len(ad_struct):
    # Decode the ad structure assuming AltBeacon format
    AltBeaconData = namedtuple('AltBeaconData', 'adstruct_bytes '
                  + 'adstruct_type mfg_id beacon_code beacon_id '
                  + 'rssi_ref mfg_res')
    bd = AltBeaconData._make(struct.unpack('<BBHH20sbB', ad_struct[:28]))
    # Check whether all AltBeacon specific values are correct
    if bd.adstruct_bytes == 0x1B and bd.adstruct_type == 0xFF and \
        bd.beacon_code == 0xACBE:
      # This is a valid AltBeacon ad structure
      # Fill in the return structure with the data we extracted
      ret['type'] = 'altbeacon'
      ret['mfg_id'] = bd.mfg_id
      ret['beacon_id'] = ''.join('%02x' % ord(c) for c in bd.beacon_id)
      ret['mfg_res'] = bd.mfg_res
      ret['rssi_ref'] = bd.rssi_ref
  # Return the object
  return ret

def decode_eddystone(ad_struct):
  """Ad structure decoder for Eddystone
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec Eddystone structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'eddystone' for Eddystone
  If it is an Eddystone UID ad structure, the dictionary also contains:
    sub_type: <string> 'uid'
    namespace: <string> hex string representing 10 byte namespace
    instance: <string> hex string representing 6 byte instance
    rssi_ref: <int> Reference signal @ 1m in dBm
  If it is an Eddystone URL ad structure, the dictionary also contains:
    sub_type: <string> 'url'
    url: <string> URL
    rssi_ref: <int> Reference signal @ 1m in dBm
  If it is an Eddystone TLM ad structure, the dictionary also contains:
    sub_type: <string> 'tlm'
    tlm_version: <int> Only version 0 is decoded to produce the next fields
    vbatt: <float> battery voltage in V
    temp: <float> temperature in degrees Celsius
    adv_cnt: <int> running count of advertisement frames
    sec_cnt: <float> time in seconds since boot
  If this isn't a valid Eddystone structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is our data long enough to decode as Eddystone?
  if adstruct_bytes >= 5 and adstruct_bytes <= len(ad_struct):
    # Decode the common part of the Eddystone data
    EddystoneCommon = namedtuple('EddystoneCommon', 'adstruct_bytes '
                    + 'service_data eddystone_uuid sub_type')
    ec = EddystoneCommon._make(struct.unpack('<BBHB', ad_struct[:5]))
    # Is this a valid Eddystone ad structure?
    if ec.eddystone_uuid == 0xFEAA and ec.service_data == 0x16:
      # Fill in the return data we know at this point
      ret['type'] = 'eddystone'
      # Now select based on the sub type
      # Is this a UID sub type? (Accomodate beacons that either include or
      # exclude the reserved bytes)
      if ec.sub_type == 0x00 and (ec.adstruct_bytes == 0x15 or
                                  ec.adstruct_bytes == 0x17):
        # Decode Eddystone UID data (without reserved bytes)
        EddystoneUID = namedtuple('EddystoneUID', 'rssi_ref '
                      + 'namespace instance')
        ei = EddystoneUID._make(struct.unpack('>b10s6s', ad_struct[5:22]))
        # Fill in the return structure with the data we extracted
        ret['sub_type'] = 'uid'
        ret['namespace'] = ''.join('%02x' % ord(c) for c in ei.namespace)
        ret['instance'] = ''.join('%02x' % ord(c) for c in ei.instance)
        ret['rssi_ref'] = ei.rssi_ref - 41
      # Is this a URL sub type?
      if ec.sub_type == 0x10:
        # Decode Eddystone URL header
        EddyStoneURL = namedtuple('EddystoneURL', 'rssi_ref url_scheme')
        eu = EddyStoneURL._make(struct.unpack('>bB', ad_struct[5:7]))
        # Fill in the return structure with extracted data and init the URL
        ret['sub_type'] = 'url'
        ret['rssi_ref'] = eu.rssi_ref - 41
        ret['url'] = ['http://www.', 'https://www.', 'http://', 'https://'] \
                      [eu.url_scheme & 0x03]
        # Go through the remaining bytes to build the URL
        for c in ad_struct[7:adstruct_bytes]:
          # Get the character code
          c_code = ord(c)
          # Is this an expansion code?
          if c_code < 14:
            # Add the expansion code
            ret['url'] += ['.com', '.org', '.edu', '.net', '.info', '.biz',
                          '.gov'][c_code if c_code < 7 else c_code - 7]
            # Add the slash if that variant is selected
            if c_code < 7: ret['url'] += '/'
          # Is this a graphic printable ASCII character?
          if c_code > 0x20 and c_code < 0x7F:
            # Add it to the URL
            ret['url'] += c
      # Is this a TLM sub type?
      if ec.sub_type == 0x20 and ec.adstruct_bytes == 0x11:
        # Decode Eddystone telemetry data
        EddystoneTLM = namedtuple('EddystoneTLM', 'tlm_version '
                      + 'vbatt temp adv_cnt sec_cnt')
        et = EddystoneTLM._make(struct.unpack('>BHhLL', ad_struct[5:18]))
        # Fill in generic TLM data
        ret['sub_type'] = 'tlm'
        ret['tlm_version'] = et.tlm_version
        # Fill the return structure with data if version 0
        if et.tlm_version == 0x00:
          ret['vbatt'] = et.vbatt / 1000.0
          ret['temp'] = et.temp / 256.0
          ret['adv_cnt'] = et.adv_cnt
          ret['sec_cnt'] = et.sec_cnt / 10.0
  # Return the object
  return ret

# List of ad_struct decoders for different types of beacon
decode_ad_struct_list = [decode_ibeacon, decode_altbeacon, decode_eddystone]

def decode_ad_report(ad_packet):
  """Decode a Bluetooth LE advertisement report
  Returns a dictionary with the following fields:
    adinfo_bytes: <int> number of bytes this ad info consumed
    type: <string> or None based on decode success
    Plus other beacon specific data
  """
  # Initialize return object
  ret = { 'type': None, 'adinfo_bytes': len(ad_packet) }
  # Check that we have the minimum ad info header length
  if len(ad_packet) >= 9:
    # Decode advertising report header
    AdInfoHeader = namedtuple('AdInfoHeader', 'event bdaddr_type '
                              + 'bdaddr length')
    aih = AdInfoHeader._make(struct.unpack('<BB6sB', ad_packet[:9]))
    # Check if this is valid advertisement info
    if aih.bdaddr_type == 0x00 and aih.length + 10 <= len(ad_packet):
      # This is (likely) valid (many more checks later), update the
      # adinfo length
      ret['adinfo_bytes'] = aih.length + 10
      # Add Bluetooth device address to return object
      ret['bdaddr'] = ':'.join(reversed(['%02X' % ord(b)
                                          for b in aih.bdaddr]))
      # Move to first ad struct
      ad_struct = ad_packet[9:]
      # Create default beacon_data
      beacon_data = {}
      # Iterate over ad structs
      while len(ad_struct) > 1:
        # Try different beacon decoders
        for decoder in decode_ad_struct_list:
          # Run a decoder
          beacon_data = decoder(ad_struct)
          # Stop if this decoder recognized the data
          if beacon_data['type']:
            break
        # Stop if we decoded the beacon data
        if beacon_data['type']:
          break
        # Go to the next ad struct
        ad_struct = ad_struct[beacon_data['adstruct_bytes']:]
      # Add beacon data to return object
      for key, val in beacon_data.iteritems():
        if key != 'adstruct_bytes':
          ret[key] = val
      # Add observed RSSI to return object
      ret['rssi_obs'], = struct.unpack('<b', ad_packet[aih.length + 9])
  # Return the return object
  return ret

def bluez_decode_beacons(bluez_packet):
  """BlueZ event packet decoder
  Identifies a beacon advertisement packet and extracts its data.
  Returns an array with dictionaries containing beacon data.
  """
  # Initialize beacons list
  beacons = []
  # Check if the packet is the minimum length to be able to unpack the
  # BlueZ packet header
  if len(bluez_packet) >= 5:
    # Decode BlueZ header to see if the packet contains LE advertising info
    BlueZHeader = namedtuple('BlueZHeader', 'hci_packet_type event '
                              + 'length meta_event report_num')
    bzh = BlueZHeader._make(struct.unpack('<BBBBB', bluez_packet[:5]))
    # Check if this is a valid LE advertisement packet
    if bzh.hci_packet_type == 0x04 and bzh.event == 0x3E and \
        bzh.meta_event == 0x02 and bzh.report_num > 0 and \
        bzh.length + 3 == len(bluez_packet):
      # Track reports
      reports = bzh.report_num
      # Move to the first advertising report
      ad_packet = bluez_packet[5:]
      # Iterate over the advertising reports
      while reports > 0 and len(ad_packet) >= 9:
        # Decode the advertising report
        ad_report = decode_ad_report(ad_packet)
        # Decrement reports counter
        reports -= 1
        # Move on to the next advertising report
        ad_packet = ad_packet[ad_report['adinfo_bytes']:]
        # Is this a valid beacon?
        if ad_report['type']:
          # Remove the adinfo_bytes
          del ad_report['adinfo_bytes']
          # Add this beacon to the beacons list
          beacons.append(ad_report)
  # Return the beacons list
  return beacons
<commit_msg>Bug fix: accept public and random addresses<commit_after># decode_beacon.py
# Beacon advertisement data decoder
# Copyright (c) 2015 Patrick Van Oosterwijck
# MIT Licensed
#
# For now it only decodes iBeacon and AltBeacon data, it is easily extended
# to support other formats.
# Based on https://github.com/adamf/BLE/blob/master/ble-scanner.py and BlueZ
# source code.

import struct
from collections import namedtuple
import uuid

def decode_ibeacon(ad_struct):
  """Ad structure decoder for iBeacon
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec iBeacon structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'ibeacon' for Apple iBeacon
    uuid: <string> UUID
    major: <int> iBeacon Major
    minor: <int> iBeacon Minor
    rssi_ref: <int> Reference signal @ 1m in dBm
  If this isn't a valid iBeacon structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is the length correct and is our data long enough?
  if adstruct_bytes == 0x1B and adstruct_bytes <= len(ad_struct):
    # Decode the ad structure assuming iBeacon format
    iBeaconData = namedtuple('iBeaconData', 'adstruct_bytes adstruct_type '
                  + 'mfg_id_low mfg_id_high ibeacon_id ibeacon_data_len '
                  + 'uuid major minor rssi_ref')
    bd = iBeaconData._make(struct.unpack('>BBBBBB16sHHb', ad_struct[:27]))
    # Check whether all iBeacon specific values are correct
    if bd.adstruct_bytes == 0x1A and bd.adstruct_type == 0xFF and \
        bd.mfg_id_low == 0x4C and bd.mfg_id_high == 0x00 and \
        bd.ibeacon_id == 0x02 and bd.ibeacon_data_len == 0x15:
      # This is a valid iBeacon ad structure
      # Fill in the return structure with the data we extracted
      ret['type'] = 'ibeacon'
      ret['uuid'] = str(uuid.UUID(bytes=bd.uuid))
      ret['major'] = bd.major
      ret['minor'] = bd.minor
      ret['rssi_ref'] = bd.rssi_ref
  # Return the object
  return ret

def decode_altbeacon(ad_struct):
  """Ad structure decoder for AltBeacon
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec AltBeacon structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'altbeacon' for AltBeacon
    mfg_id: <int> indicating Bluetooth SIG assigned manufacturer code
    beacon_id: <string> hex string representing 20 byte beacon id
    mfg_res: <int> manufacturer reserved value
    rssi_ref: <int> Reference signal @ 1m in dBm
  If this isn't a valid AltBeacon structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is the length correct and is our data long enough?
  if adstruct_bytes == 0x1C and adstruct_bytes <= len(ad_struct):
    # Decode the ad structure assuming AltBeacon format
    AltBeaconData = namedtuple('AltBeaconData', 'adstruct_bytes '
                  + 'adstruct_type mfg_id beacon_code beacon_id '
                  + 'rssi_ref mfg_res')
    bd = AltBeaconData._make(struct.unpack('<BBHH20sbB', ad_struct[:28]))
    # Check whether all AltBeacon specific values are correct
    if bd.adstruct_bytes == 0x1B and bd.adstruct_type == 0xFF and \
        bd.beacon_code == 0xACBE:
      # This is a valid AltBeacon ad structure
      # Fill in the return structure with the data we extracted
      ret['type'] = 'altbeacon'
      ret['mfg_id'] = bd.mfg_id
      ret['beacon_id'] = ''.join('%02x' % ord(c) for c in bd.beacon_id)
      ret['mfg_res'] = bd.mfg_res
      ret['rssi_ref'] = bd.rssi_ref
  # Return the object
  return ret

def decode_eddystone(ad_struct):
  """Ad structure decoder for Eddystone
  Returns a dictionary with the following fields if the ad structure is a
  valid mfg spec Eddystone structure:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: <string> 'eddystone' for Eddystone
  If it is an Eddystone UID ad structure, the dictionary also contains:
    sub_type: <string> 'uid'
    namespace: <string> hex string representing 10 byte namespace
    instance: <string> hex string representing 6 byte instance
    rssi_ref: <int> Reference signal @ 1m in dBm
  If it is an Eddystone URL ad structure, the dictionary also contains:
    sub_type: <string> 'url'
    url: <string> URL
    rssi_ref: <int> Reference signal @ 1m in dBm
  If it is an Eddystone TLM ad structure, the dictionary also contains:
    sub_type: <string> 'tlm'
    tlm_version: <int> Only version 0 is decoded to produce the next fields
    vbatt: <float> battery voltage in V
    temp: <float> temperature in degrees Celsius
    adv_cnt: <int> running count of advertisement frames
    sec_cnt: <float> time in seconds since boot
  If this isn't a valid Eddystone structure, it returns a dict with these
  fields:
    adstruct_bytes: <int> Number of bytes this ad structure consumed
    type: None for unknown
  """
  # Get the length of the ad structure (including the length byte)
  adstruct_bytes = ord(ad_struct[0]) + 1
  # Create the return object
  ret = { 'adstruct_bytes': adstruct_bytes, 'type': None }
  # Is our data long enough to decode as Eddystone?
  if adstruct_bytes >= 5 and adstruct_bytes <= len(ad_struct):
    # Decode the common part of the Eddystone data
    EddystoneCommon = namedtuple('EddystoneCommon', 'adstruct_bytes '
                    + 'service_data eddystone_uuid sub_type')
    ec = EddystoneCommon._make(struct.unpack('<BBHB', ad_struct[:5]))
    # Is this a valid Eddystone ad structure?
    if ec.eddystone_uuid == 0xFEAA and ec.service_data == 0x16:
      # Fill in the return data we know at this point
      ret['type'] = 'eddystone'
      # Now select based on the sub type
      # Is this a UID sub type? (Accomodate beacons that either include or
      # exclude the reserved bytes)
      if ec.sub_type == 0x00 and (ec.adstruct_bytes == 0x15 or
                                  ec.adstruct_bytes == 0x17):
        # Decode Eddystone UID data (without reserved bytes)
        EddystoneUID = namedtuple('EddystoneUID', 'rssi_ref '
                      + 'namespace instance')
        ei = EddystoneUID._make(struct.unpack('>b10s6s', ad_struct[5:22]))
        # Fill in the return structure with the data we extracted
        ret['sub_type'] = 'uid'
        ret['namespace'] = ''.join('%02x' % ord(c) for c in ei.namespace)
        ret['instance'] = ''.join('%02x' % ord(c) for c in ei.instance)
        ret['rssi_ref'] = ei.rssi_ref - 41
      # Is this a URL sub type?
      if ec.sub_type == 0x10:
        # Decode Eddystone URL header
        EddyStoneURL = namedtuple('EddystoneURL', 'rssi_ref url_scheme')
        eu = EddyStoneURL._make(struct.unpack('>bB', ad_struct[5:7]))
        # Fill in the return structure with extracted data and init the URL
        ret['sub_type'] = 'url'
        ret['rssi_ref'] = eu.rssi_ref - 41
        ret['url'] = ['http://www.', 'https://www.', 'http://', 'https://'] \
                      [eu.url_scheme & 0x03]
        # Go through the remaining bytes to build the URL
        for c in ad_struct[7:adstruct_bytes]:
          # Get the character code
          c_code = ord(c)
          # Is this an expansion code?
          if c_code < 14:
            # Add the expansion code
            ret['url'] += ['.com', '.org', '.edu', '.net', '.info', '.biz',
                          '.gov'][c_code if c_code < 7 else c_code - 7]
            # Add the slash if that variant is selected
            if c_code < 7: ret['url'] += '/'
          # Is this a graphic printable ASCII character?
          if c_code > 0x20 and c_code < 0x7F:
            # Add it to the URL
            ret['url'] += c
      # Is this a TLM sub type?
      if ec.sub_type == 0x20 and ec.adstruct_bytes == 0x11:
        # Decode Eddystone telemetry data
        EddystoneTLM = namedtuple('EddystoneTLM', 'tlm_version '
                      + 'vbatt temp adv_cnt sec_cnt')
        et = EddystoneTLM._make(struct.unpack('>BHhLL', ad_struct[5:18]))
        # Fill in generic TLM data
        ret['sub_type'] = 'tlm'
        ret['tlm_version'] = et.tlm_version
        # Fill the return structure with data if version 0
        if et.tlm_version == 0x00:
          ret['vbatt'] = et.vbatt / 1000.0
          ret['temp'] = et.temp / 256.0
          ret['adv_cnt'] = et.adv_cnt
          ret['sec_cnt'] = et.sec_cnt / 10.0
  # Return the object
  return ret

# List of ad_struct decoders for different types of beacon
decode_ad_struct_list = [decode_ibeacon, decode_altbeacon, decode_eddystone]

def decode_ad_report(ad_packet):
  """Decode a Bluetooth LE advertisement report
  Returns a dictionary with the following fields:
    adinfo_bytes: <int> number of bytes this ad info consumed
    type: <string> or None based on decode success
    Plus other beacon specific data
  """
  # Initialize return object
  ret = { 'type': None, 'adinfo_bytes': len(ad_packet) }
  # Check that we have the minimum ad info header length
  if len(ad_packet) >= 9:
    # Decode advertising report header
    AdInfoHeader = namedtuple('AdInfoHeader', 'event bdaddr_type '
                              + 'bdaddr length')
    aih = AdInfoHeader._make(struct.unpack('<BB6sB', ad_packet[:9]))
    # Check if this is valid advertisement info
    if aih.bdaddr_type <= 0x01 and aih.length + 10 <= len(ad_packet):
      # This is (likely) valid (many more checks later), update the
      # adinfo length
      ret['adinfo_bytes'] = aih.length + 10
      # Add Bluetooth device address to return object
      ret['bdaddr'] = ':'.join(reversed(['%02X' % ord(b)
                                          for b in aih.bdaddr]))
      # Move to first ad struct
      ad_struct = ad_packet[9:]
      # Create default beacon_data
      beacon_data = {}
      # Iterate over ad structs
      while len(ad_struct) > 1:
        # Try different beacon decoders
        for decoder in decode_ad_struct_list:
          # Run a decoder
          beacon_data = decoder(ad_struct)
          # Stop if this decoder recognized the data
          if beacon_data['type']:
            break
        # Stop if we decoded the beacon data
        if beacon_data['type']:
          break
        # Go to the next ad struct
        ad_struct = ad_struct[beacon_data['adstruct_bytes']:]
      # Add beacon data to return object
      for key, val in beacon_data.iteritems():
        if key != 'adstruct_bytes':
          ret[key] = val
      # Add observed RSSI to return object
      ret['rssi_obs'], = struct.unpack('<b', ad_packet[aih.length + 9])
  # Return the return object
  return ret

def bluez_decode_beacons(bluez_packet):
  """BlueZ event packet decoder
  Identifies a beacon advertisement packet and extracts its data.
  Returns an array with dictionaries containing beacon data.
  """
  # Initialize beacons list
  beacons = []
  # Check if the packet is the minimum length to be able to unpack the
  # BlueZ packet header
  if len(bluez_packet) >= 5:
    # Decode BlueZ header to see if the packet contains LE advertising info
    BlueZHeader = namedtuple('BlueZHeader', 'hci_packet_type event '
                              + 'length meta_event report_num')
    bzh = BlueZHeader._make(struct.unpack('<BBBBB', bluez_packet[:5]))
    # Check if this is a valid LE advertisement packet
    if bzh.hci_packet_type == 0x04 and bzh.event == 0x3E and \
        bzh.meta_event == 0x02 and bzh.report_num > 0 and \
        bzh.length + 3 == len(bluez_packet):
      # Track reports
      reports = bzh.report_num
      # Move to the first advertising report
      ad_packet = bluez_packet[5:]
      # Iterate over the advertising reports
      while reports > 0 and len(ad_packet) >= 9:
        # Decode the advertising report
        ad_report = decode_ad_report(ad_packet)
        # Decrement reports counter
        reports -= 1
        # Move on to the next advertising report
        ad_packet = ad_packet[ad_report['adinfo_bytes']:]
        # Is this a valid beacon?
        if ad_report['type']:
          # Remove the adinfo_bytes
          del ad_report['adinfo_bytes']
          # Add this beacon to the beacons list
          beacons.append(ad_report)
  # Return the beacons list
  return beacons
<|endoftext|>


<commit_before>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  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 time

from robot import utils
from robot.reporting.parsingcontext import TextIndex

class JsExecutionResult(object):

    def __init__(self, suite, statistics, errors, strings, basemillis,
                 split_results=None):
        self.suite = suite
        self.strings = strings
        self.data = self._get_data(statistics, errors, basemillis)
        self.split_results = split_results or []

    def _get_data(self, statistics, errors, basemillis):
        gentime = time.localtime()
        return {
            'stats': statistics,
            'errors': errors,
            'baseMillis': basemillis,
            'generatedMillis': long(time.mktime(gentime) * 1000) - basemillis,
            'generatedTimestamp': utils.format_time(gentime, gmtsep=' ')
        }

    def remove_keywords(self):
        self._remove_keywords_from_suite(self.suite)
        self._prune_unused_indices()

    def remove_errors(self):
        self.data.pop('errors')

    def _remove_keywords_from_suite(self, suite):
        suite[8] = []
        for subsuite in suite[6]:
            self._remove_keywords_from_suite(subsuite)
        for test in suite[7]:
            test[-1] = []

    def _prune_unused_indices(self):
        used = self._collect_used_indices(self.suite, set())
        remap = {}
        self.strings = \
            list(self._prune(self.strings, used, remap))
        self._remap_indices(self.suite, remap)

    def _prune(self, data, used, index_remap, map_index=None, offset_increment=1):
        offset = 0
        for index, text in enumerate(data):
            index = map_index(index) if map_index else index
            if index in used:
                index_remap[index] = index - offset
                yield text
            else:
                offset += offset_increment

    def _remap_indices(self, data, remap):
        for i, item in enumerate(data):
            if isinstance(item, TextIndex):
                data[i] = remap[item]
            elif isinstance(item, list):
                self._remap_indices(item, remap)

    def _collect_used_indices(self, data, result):
        for item in data:
            if isinstance(item, TextIndex):
                result.add(item)
            elif isinstance(item, list):
                self._collect_used_indices(item, result)
            elif isinstance(item, dict):
                self._collect_used_indices(item.values(), result)
                self._collect_used_indices(item.keys(), result)
        return result
<commit_msg>cleanup<commit_after>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  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 time

from robot import utils
from robot.reporting.parsingcontext import TextIndex

class JsExecutionResult(object):

    def __init__(self, suite, statistics, errors, strings, basemillis,
                 split_results=None):
        self.suite = suite
        self.strings = strings
        self.data = self._get_data(statistics, errors, basemillis)
        self.split_results = split_results or []

    def _get_data(self, statistics, errors, basemillis):
        gentime = time.localtime()
        return {
            'stats': statistics,
            'errors': errors,
            'baseMillis': basemillis,
            'generatedMillis': long(time.mktime(gentime) * 1000) - basemillis,
            'generatedTimestamp': utils.format_time(gentime, gmtsep=' ')
        }

    # TODO: Combine remove_keywords and remove_errors
    # into remove_data_not_needed_in_report or something similar.
    # The code related to removing should also be moved into a separate object.

    def remove_keywords(self):
        self._remove_keywords_from_suite(self.suite)
        self._prune_unused_indices()

    def remove_errors(self):
        self.data.pop('errors')

    def _remove_keywords_from_suite(self, suite):
        suite[8] = []
        for subsuite in suite[6]:
            self._remove_keywords_from_suite(subsuite)
        for test in suite[7]:
            test[-1] = []

    def _prune_unused_indices(self):
        used = self._collect_used_indices(self.suite, set())
        remap = {}
        self.strings = \
            list(self._prune(self.strings, used, remap))
        self._remap_indices(self.suite, remap)

    def _prune(self, data, used, index_remap):
        offset = 0
        for index, text in enumerate(data):
            if index in used:
                index_remap[index] = index - offset
                yield text
            else:
                offset += 1

    def _remap_indices(self, data, remap):
        for i, item in enumerate(data):
            if isinstance(item, TextIndex):
                data[i] = remap[item]
            elif isinstance(item, list):
                self._remap_indices(item, remap)

    def _collect_used_indices(self, data, result):
        for item in data:
            if isinstance(item, TextIndex):
                result.add(item)
            elif isinstance(item, list):
                self._collect_used_indices(item, result)
        return result
<|endoftext|>


<commit_before>#  Copyright 2008-2012 Nokia Siemens Networks Oyj
#
#  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.
from robotide.pluginapi import Plugin
from robotide.testsearch.testsdialog import TestsDialog
from robotide.utils import overrides
from robotide.widgets import ImageProvider
from robotide.widgets.list import ListModel

class TestSearchPlugin(Plugin):

    def enable(self):
        self.register_search_action('Search Tests', self.show_search_for, ImageProvider().TEST_SEARCH_ICON)

    def show_search_for(self, text):
        d = TestsDialog(text, _TestSearchListModel(self._search(text, self.frame._controller.data)))
        d.add_selection_listener(self._foo)
        d.Show()
        d.set_focus_to_first_match()

    def _foo(self, test):
        self.tree.select_node_by_data(test)

    def _search(self, text, data):
        for test in data.tests:
            if text in test.name or text in [str(tag) for tag in test.tags]:
                yield test
        for s in data.suites:
            for test in self._search(text, s):
                yield test

class _TestSearchListModel(ListModel):

    def __init__(self, tests):
        self._tests = list(tests)

    @property
    @overrides(ListModel)
    def count(self):
        return len(self._tests)

    def __getitem__(self, item):
        return self._tests[item]

    def item_text(self, row, col):
        return self._tests[row].longname

<commit_msg>testsearch: Call select in UI Thread<commit_after>#  Copyright 2008-2012 Nokia Siemens Networks Oyj
#
#  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 wx
from robotide.pluginapi import Plugin
from robotide.testsearch.testsdialog import TestsDialog
from robotide.utils import overrides
from robotide.widgets import ImageProvider
from robotide.widgets.list import ListModel

class TestSearchPlugin(Plugin):

    def enable(self):
        self.register_search_action('Search Tests', self.show_search_for, ImageProvider().TEST_SEARCH_ICON)

    def show_search_for(self, text):
        d = TestsDialog(text, _TestSearchListModel(self._search(text, self.frame._controller.data)))
        d.add_selection_listener(self._foo)
        d.Show()
        d.set_focus_to_first_match()

    def _foo(self, test):
        wx.CallAfter(self.tree.select_node_by_data, test)

    def _search(self, text, data):
        for test in data.tests:
            if text in test.name or text in [str(tag) for tag in test.tags]:
                yield test
        for s in data.suites:
            for test in self._search(text, s):
                yield test

class _TestSearchListModel(ListModel):

    def __init__(self, tests):
        self._tests = list(tests)

    @property
    @overrides(ListModel)
    def count(self):
        return len(self._tests)

    def __getitem__(self, item):
        return self._tests[item]

    def item_text(self, row, col):
        return self._tests[row].longname

<|endoftext|>


<commit_before>import re

from django import forms
from django.contrib import admin

import requests

from .models import ShortURL
from .models import ShortURLAlias
from .widgets import DatalistTextInput

class ShortURLAliasAdminForm(forms.ModelForm):
    def clean_alias(self):
        """
        Validate characters for the provided alias.
        """
        alias = self.cleaned_data.get('alias')
        if bool(re.compile(r'[^a-zA-Z0-9-]').search(alias)):
            raise forms.ValidationError("Alias contains invalid characters")
        return alias

class ShortURLAliasInline(admin.StackedInline):
    model = ShortURLAlias
    form = ShortURLAliasAdminForm

class ShortURLAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ShortURLAdminForm, self).__init__(*args, **kwargs)
        self.fields['campaign'].widget = DatalistTextInput(choices=ShortURL.objects.get_unique_list('campaign'))
        self.fields['medium'].widget = DatalistTextInput(choices=ShortURL.objects.get_unique_list('medium'))

    def clean_long_url(self):
        """
        Validate connectivity to the provided target URL.
        """
        url = self.cleaned_data.get('long_url')
        try:
            r = requests.head(url, allow_redirects=True, timeout=3.0)
        except requests.exceptions.ConnectionError:
            raise forms.ValidationError("Error connecting to URL")
        except requests.exceptions.SSLError:
            raise forms.ValidationError("Invalid SSL certificate")
        except requests.exceptions.Timeout:
            raise forms.ValidationError("Timeout connecting to URL")

        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError:
            raise forms.ValidationError("Invalid status returned (%d)" % r.status_code)

        return r.url

class ShortURLAdmin(admin.ModelAdmin):
    form = ShortURLAdminForm
    inlines = [ShortURLAliasInline]
    list_display = ('long_url', 'short_url', 'hits', 'last_used', 'campaign', 'medium')
    _list_display = list_display
    list_filter = ('campaign', 'medium')
    _list_filter = list_filter
    ordering = ['-last_used']
    readonly_fields = ('created', 'short_url', 'get_tracking_url', 'qr_code', 'hits', 'last_used')
    search_fields = ['long_url', 'campaign', 'shorturlalias__alias']

    fieldsets = ((None, {'fields': ('long_url', 'short_url', 'get_tracking_url')}),
                 ('Google', {'fields': ('campaign', 'medium', 'content')}),
                 ('Additional Info', {'fields': ('description', 'qr_code')}),
                 ('Short URL Usage', {'classes': ('collapse grp-collapse grp-closed'),
                                      'fields': ('hits', 'created', 'last_used')}))

    def changelist_view(self, request, extra_context=None):
        """
        Inject additional filtering options for superusers.
        """
        if request.user.is_superuser:
            self.list_filter = self._list_filter + ('creator__username',)
            self.list_display = self._list_display + ('creator',)
        else:
            self.list_filter = self._list_filter
            self.list_display = self._list_display
        return super(ShortURLAdmin, self).changelist_view(request, extra_context=extra_context)

    def has_change_permission(self, request, obj=None):
        """
        Users should only be able to modify ``ShortURL``s they own,
        except for superusers.
        """
        has_class_permission = super(ShortURLAdmin, self).has_change_permission(request, obj)
        if not has_class_permission:
            return False
        if obj is not None and not request.user.is_superuser and request.user.id != obj.creator.id:
            return False
        return True

    def has_delete_permission(self, request, obj=None):
        """
        Users should only be able to delete ``ShortURL``s they own,
        except for superusers.
        """
        has_class_permission = super(ShortURLAdmin, self).has_delete_permission(request, obj)
        if not has_class_permission:
            return False
        if obj is not None and not request.user.is_superuser and request.user.id != obj.creator.id:
            return False
        return True

    def queryset(self, request):
        """
        Superusers can view all ``ShortURL``s. Non-superusers should
        only be able to view their own.
        """
        qs = super(ShortURLAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(creator=request.user)

    def save_model(self, request, obj, form, change):
        """
        On first save, set the ``ShortURL`` creator to the current
        user. On subsequent saves, skip this step.
        """
        if not change:
            obj.creator = request.user
        obj.save()

admin.site.register(ShortURL, ShortURLAdmin)
<commit_msg>Fix admin display CSS classes<commit_after>import re

from django import forms
from django.contrib import admin

import requests

from .models import ShortURL
from .models import ShortURLAlias
from .widgets import DatalistTextInput

class ShortURLAliasAdminForm(forms.ModelForm):
    def clean_alias(self):
        """
        Validate characters for the provided alias.
        """
        alias = self.cleaned_data.get('alias')
        if bool(re.compile(r'[^a-zA-Z0-9-]').search(alias)):
            raise forms.ValidationError("Alias contains invalid characters")
        return alias

class ShortURLAliasInline(admin.StackedInline):
    model = ShortURLAlias
    form = ShortURLAliasAdminForm

class ShortURLAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ShortURLAdminForm, self).__init__(*args, **kwargs)
        self.fields['campaign'].widget = DatalistTextInput(choices=ShortURL.objects.get_unique_list('campaign'))
        self.fields['medium'].widget = DatalistTextInput(choices=ShortURL.objects.get_unique_list('medium'))

    def clean_long_url(self):
        """
        Validate connectivity to the provided target URL.
        """
        url = self.cleaned_data.get('long_url')
        try:
            r = requests.head(url, allow_redirects=True, timeout=3.0)
        except requests.exceptions.ConnectionError:
            raise forms.ValidationError("Error connecting to URL")
        except requests.exceptions.SSLError:
            raise forms.ValidationError("Invalid SSL certificate")
        except requests.exceptions.Timeout:
            raise forms.ValidationError("Timeout connecting to URL")

        try:
            r.raise_for_status()
        except requests.exceptions.HTTPError:
            raise forms.ValidationError("Invalid status returned (%d)" % r.status_code)

        return r.url

class ShortURLAdmin(admin.ModelAdmin):
    form = ShortURLAdminForm
    inlines = [ShortURLAliasInline]
    list_display = ('long_url', 'short_url', 'hits', 'last_used', 'campaign', 'medium')
    _list_display = list_display
    list_filter = ('campaign', 'medium')
    _list_filter = list_filter
    ordering = ['-last_used']
    readonly_fields = ('created', 'short_url', 'get_tracking_url', 'qr_code', 'hits', 'last_used')
    search_fields = ['long_url', 'campaign', 'shorturlalias__alias']

    fieldsets = ((None, {'fields': ('long_url', 'short_url', 'get_tracking_url')}),
                 ('Google', {'fields': ('campaign', 'medium', 'content')}),
                 ('Additional Info', {'fields': ('description', 'qr_code')}),
                 ('Short URL Usage', {'classes': ('collapse', 'grp-collapse', 'grp-closed'),
                                      'fields': ('hits', 'created', 'last_used')}))

    def changelist_view(self, request, extra_context=None):
        """
        Inject additional filtering options for superusers.
        """
        if request.user.is_superuser:
            self.list_filter = self._list_filter + ('creator__username',)
            self.list_display = self._list_display + ('creator',)
        else:
            self.list_filter = self._list_filter
            self.list_display = self._list_display
        return super(ShortURLAdmin, self).changelist_view(request, extra_context=extra_context)

    def has_change_permission(self, request, obj=None):
        """
        Users should only be able to modify ``ShortURL``s they own,
        except for superusers.
        """
        has_class_permission = super(ShortURLAdmin, self).has_change_permission(request, obj)
        if not has_class_permission:
            return False
        if obj is not None and not request.user.is_superuser and request.user.id != obj.creator.id:
            return False
        return True

    def has_delete_permission(self, request, obj=None):
        """
        Users should only be able to delete ``ShortURL``s they own,
        except for superusers.
        """
        has_class_permission = super(ShortURLAdmin, self).has_delete_permission(request, obj)
        if not has_class_permission:
            return False
        if obj is not None and not request.user.is_superuser and request.user.id != obj.creator.id:
            return False
        return True

    def queryset(self, request):
        """
        Superusers can view all ``ShortURL``s. Non-superusers should
        only be able to view their own.
        """
        qs = super(ShortURLAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(creator=request.user)

    def save_model(self, request, obj, form, change):
        """
        On first save, set the ``ShortURL`` creator to the current
        user. On subsequent saves, skip this step.
        """
        if not change:
            obj.creator = request.user
        obj.save()

admin.site.register(ShortURL, ShortURLAdmin)
<|endoftext|>


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

#   Copyright (c) 2010-2014, MIT Probabilistic Computing Project
#
#   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 gzip
import pickle

import bayeslite.core as core
from bayeslite.sqlite3_util import sqlite3_exec_1

renamed_column_types = {
    'continuous': 'numerical',
    'multinomial': 'categorical',
}

allowed_column_types = {
    'categorical',
    'cyclic',
    'ignore',
    'key',
    'numerical',
}

def bayesdb_load_legacy_models(bdb, table_name, pathname, ifnotexists=False,
        gzipped=None):

    # Load the pickled file -- gzipped, if gzipped is true or if
    # gzipped is not specified and the file ends in .pkl.gz.
    pickled = None
    with open(pathname, 'rb') as f:
        if gzipped or (gzipped is None and pathname.endswith('.pkl.gz')):
            with gzip.GzipFile(fileobj=f) as gzf:
                pickled = pickle.load(gzf)
        else:
            pickled = pickle.load(f)

    # Pick apart the schema and model data.
    #
    # XXX Support even older models formats, from before the schema
    # was included.  Not sure exactly how they were structured.
    if 'schema' not in pickled:
        raise IOError('Invalid legacy model: missing schema')
    if 'models' not in pickled:
        raise IOError('Invalid legacy model: missing models')
    schema = pickled['schema']
    models = pickled['models']

    # Make sure the schema looks sensible.  Map legacy cctypes to
    # modern cctypes.
    if not isinstance(schema, dict):
        raise IOError('Invalid legacy model: schema is not a dict')
    for column_name in schema:
        column_schema = schema[column_name]
        if not isinstance(column_schema, dict):
            raise IOError('Invalid legacy model: column schema is not a dict')
        if not 'cctype' in column_schema:
            raise IOError('Invalid legacy model: column schema missing cctype')
        if column_schema['cctype'] in renamed_column_types:
            column_schema['cctype'] = \
                renamed_column_types[column_schema['cctype']]
        if column_schema['cctype'] not in allowed_column_types:
            raise IOError('Invalid legacy model: unknown column type')

    # XXX Check whether the schema resembles a sane btable schema.
    # XXX Check whether models is a dict mapping integers to thetas.
    # XXX Check whether the thetas look sensible.

    column_types = dict((column_name.lower(),
            schema[column_name]['cctype'].lower())
        for column_name in schema)

    # Ready to update the database.  Do it in a savepoint in case
    # anything goes wrong.
    with bdb.savepoint():

        # Ensure the table exists as a btable.
        if core.bayesdb_table_exists(bdb, table_name):
            # Table exists as a btable.  If there are existing models,
            # fail.  If there are no existing models, change the schema.
            table_id = core.bayesdb_table_id(bdb, table_name)
            if column_types != bayesdb_column_types(bdb, table_id):
                if 0 < core.bayesdb_nmodels(bdb, table_id):
                    raise ValueError('legacy models mismatch schema: %s' %
                        (table_name,))
                # XXX Name this operation: DROP BTABLE ...
                bdb.sqlite.execute('''
                    DELETE FROM bayesdb_table_column WHERE table_id = ?
                ''', (table_id,))
                bdb.sqlite.execute('DELETE FROM bayesdb_table WHERE id = ?',
                    (table_id,))
                core.bayesdb_import_sqlite_table(bdb, table_name,
                    column_types=column_types)
        else:
            # Table does not exist as a btable.  Create the btable,
            # assuming that a SQL table exists.  If no SQL table existed
            # by this name, tough: caller should have imported it before.
            core.bayesdb_import_sqlite_table(bdb, table_name,
                column_types=column_types)

        # Determine where to start numbering the new models.
        table_id = core.bayesdb_table_id(bdb, table_name)
        modelno_max_sql = '''
            SELECT MAX(modelno) FROM bayesdb_model WHERE table_id = ?
        '''
        modelno_max = sqlite3_exec_1(bdb.sqlite, modelno_max_sql, (table_id,))
        modelno_start = 0 if modelno_max is None else modelno_max + 1

        # XXX Urk.  Need a serious story about engine identifiers.
        engine_sql = 'SELECT id FROM bayesdb_engine WHERE name = ?'
        engine_id = sqlite3_exec_1(bdb.sqlite, engine_sql, ('crosscat',))

        # Consistently number the models consecutively in order of the
        # external numbering starting at the smallest nonnegative
        # model number not currently used.  Do not vary based on the
        # ordering of Python dict iteration.
        for i, modelno_ext in enumerate(sorted(models.keys())):
            modelno = modelno_start + i
            theta = models[modelno_ext]
            core.bayesdb_init_model(bdb, table_id, modelno, engine_id, theta)

def bayesdb_column_types(bdb, table_id):
    M_c = core.bayesdb_metadata(bdb, table_id)
    metadata = M_c['column_metadata']
    return dict((core.bayesdb_column_name(bdb, table_id, colno).lower(),
            metadata[colno]['modeltype'].lower())
        for colno in core.bayesdb_column_numbers(bdb, table_id))
<commit_msg>Properly case-fold column names in legacy models.<commit_after># -*- coding: utf-8 -*-

#   Copyright (c) 2010-2014, MIT Probabilistic Computing Project
#
#   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 gzip
import pickle

import bayeslite.core as core

from bayeslite.sqlite3_util import sqlite3_exec_1
from bayeslite.util import casefold

renamed_column_types = {
    'continuous': 'numerical',
    'multinomial': 'categorical',
}

allowed_column_types = {
    'categorical',
    'cyclic',
    'ignore',
    'key',
    'numerical',
}

def bayesdb_load_legacy_models(bdb, table_name, pathname, ifnotexists=False,
        gzipped=None):

    # Load the pickled file -- gzipped, if gzipped is true or if
    # gzipped is not specified and the file ends in .pkl.gz.
    pickled = None
    with open(pathname, 'rb') as f:
        if gzipped or (gzipped is None and pathname.endswith('.pkl.gz')):
            with gzip.GzipFile(fileobj=f) as gzf:
                pickled = pickle.load(gzf)
        else:
            pickled = pickle.load(f)

    # Pick apart the schema and model data.
    #
    # XXX Support even older models formats, from before the schema
    # was included.  Not sure exactly how they were structured.
    if 'schema' not in pickled:
        raise IOError('Invalid legacy model: missing schema')
    if 'models' not in pickled:
        raise IOError('Invalid legacy model: missing models')
    schema = pickled['schema']
    models = pickled['models']

    # Make sure the schema looks sensible.  Map legacy cctypes to
    # modern cctypes.
    if not isinstance(schema, dict):
        raise IOError('Invalid legacy model: schema is not a dict')
    for column_name in schema:
        column_schema = schema[column_name]
        if not isinstance(column_schema, dict):
            raise IOError('Invalid legacy model: column schema is not a dict')
        if not 'cctype' in column_schema:
            raise IOError('Invalid legacy model: column schema missing cctype')
        if column_schema['cctype'] in renamed_column_types:
            column_schema['cctype'] = \
                renamed_column_types[column_schema['cctype']]
        if column_schema['cctype'] not in allowed_column_types:
            raise IOError('Invalid legacy model: unknown column type')

    # XXX Check whether the schema resembles a sane btable schema.
    # XXX Check whether models is a dict mapping integers to thetas.
    # XXX Check whether the thetas look sensible.

    column_types = dict((casefold(column_name),
                         casefold(schema[column_name]['cctype']))
        for column_name in schema)

    # Ready to update the database.  Do it in a savepoint in case
    # anything goes wrong.
    with bdb.savepoint():

        # Ensure the table exists as a btable.
        if core.bayesdb_table_exists(bdb, table_name):
            # Table exists as a btable.  If there are existing models,
            # fail.  If there are no existing models, change the schema.
            table_id = core.bayesdb_table_id(bdb, table_name)
            if column_types != bayesdb_column_types(bdb, table_id):
                if 0 < core.bayesdb_nmodels(bdb, table_id):
                    raise ValueError('legacy models mismatch schema: %s' %
                        (table_name,))
                # XXX Name this operation: DROP BTABLE ...
                bdb.sqlite.execute('''
                    DELETE FROM bayesdb_table_column WHERE table_id = ?
                ''', (table_id,))
                bdb.sqlite.execute('DELETE FROM bayesdb_table WHERE id = ?',
                    (table_id,))
                core.bayesdb_import_sqlite_table(bdb, table_name,
                    column_types=column_types)
        else:
            # Table does not exist as a btable.  Create the btable,
            # assuming that a SQL table exists.  If no SQL table existed
            # by this name, tough: caller should have imported it before.
            core.bayesdb_import_sqlite_table(bdb, table_name,
                column_types=column_types)

        # Determine where to start numbering the new models.
        table_id = core.bayesdb_table_id(bdb, table_name)
        modelno_max_sql = '''
            SELECT MAX(modelno) FROM bayesdb_model WHERE table_id = ?
        '''
        modelno_max = sqlite3_exec_1(bdb.sqlite, modelno_max_sql, (table_id,))
        modelno_start = 0 if modelno_max is None else modelno_max + 1

        # XXX Urk.  Need a serious story about engine identifiers.
        engine_sql = 'SELECT id FROM bayesdb_engine WHERE name = ?'
        engine_id = sqlite3_exec_1(bdb.sqlite, engine_sql, ('crosscat',))

        # Consistently number the models consecutively in order of the
        # external numbering starting at the smallest nonnegative
        # model number not currently used.  Do not vary based on the
        # ordering of Python dict iteration.
        for i, modelno_ext in enumerate(sorted(models.keys())):
            modelno = modelno_start + i
            theta = models[modelno_ext]
            core.bayesdb_init_model(bdb, table_id, modelno, engine_id, theta)

def bayesdb_column_types(bdb, table_id):
    M_c = core.bayesdb_metadata(bdb, table_id)
    metadata = M_c['column_metadata']
    return dict((casefold(core.bayesdb_column_name(bdb, table_id, colno)),
                 casefold(metadata[colno]['modeltype']))
        for colno in core.bayesdb_column_numbers(bdb, table_id))
<|endoftext|>


<commit_before>#!/usr/bin/python
import os

import itertools

class DictionaryMaker:
	def __init__(self):
		self.aditionalData = []
		self.simpleCollection = ["admin","adm","adm","2015","2016","2017","2014","2013",".","-","_","@"]
		self.convinationLevel = 2
		self.domainName = False
		self.fullName = False
		self.address = False
		self.importantDate = False
		self.identification = False

	def welcome(self):
		print("Welcome human, Please answer the following questions...")
		self.getInput()
		self.processInput()
		self.generateDictionary()

	def getInput(self):
		print("It is possible to enter an empty response...")
		self.convinationLevel = int(raw_input("convination level:"))
		self.makeQuestion("domain name?","domainName")
		self.makeQuestion("address?","address")
		self.makeQuestion("full name?","fullName")
		self.makeQuestion("birthdate or important date?(dd-mm-yyyy)","importantDate")
		self.makeQuestion("identifier or identification number?", "identification")
		self.makeQuestion("aditional data?","aditionalData")

	def processNumbers(self,inStr):
		numbers = [str(s) for s in inStr.split() if s.isdigit()]
		response = []
		for number in numbers:
			for i in range(1, len(number)):
				res = itertools.product(number,repeat = i)
				for convination in res:
					response.append(''.join(convination))
		return response

	def processStr(self,inStr):
		response = [str(s) for s in inStr.split() if not s.isdigit()]
		response.append(inStr)
		response.append("".join(inStr.split()))
		return response
	def processDomain(self,inStr):
		response = []
		response.append(inStr)
		response.extend(inStr.split("."))
		return response
	def processAddress(self,inStr):
		response = []
		response.append(inStr)
		response.extend(inStr.split())
		response.append(''.join(inStr.split()))
		response.extend(self.processNumbers(inStr))
		response.extend(self.processStr(inStr))
		return response
	def processDate(self,inStr):
		response = []
		if "/" in inStr:
			response.extend(inStr.split("/"))
		if "-" in inStr:
			response.extend(inStr.split("-"))
		return response
	def processIdentification(self,inStr):
                numbers = [str(s) for s in inStr.split() if s.isdigit()]
                response = []
                for number in numbers:
                        for i in range(1, len(number)):
				response.append(number[0:i])
				response.append(number[:i])
		response = self.cleanList(response)
                return response
	def makeQuestion(self,questionStr,storeStr):
		nextQuestion = True

		if not getattr(self,storeStr):
			setattr(self,storeStr, [])

		storeSelf = getattr(self,storeStr)

		while nextQuestion:
			tempAnswer = raw_input(questionStr + " (empty = next question)")
			if tempAnswer != "":
				storeSelf.append(tempAnswer)
			else:
				nextQuestion = False
		setattr(self,storeStr,storeSelf)
	def processInput(self):
		print("Starting processing...")
        	if len(self.domainName) > 0:
			print("processing domain name...")
			for domain in self.domainName:
            			self.simpleCollection.extend(self.processDomain(domain))
		if len(self.fullName) > 0:
			print("processing full name...")
			for fullName in self.fullName:
				self.simpleCollection.extend(self.processStr(fullName))
        	if len(self.address) > 0:
			print("processing address...")
			for address in self.address:
            			self.simpleCollection.extend(self.processAddress(address))
        	if len(self.aditionalData) > 0:
			print("processing additional data...")
            		for data in self.aditionalData:
                		self.simpleCollection.extend(self.processStr(data))
		if len(self.importantDate) > 0:
			print("processing dates...")
			for date in self.importantDate:
				self.simpleCollection.extend(self.processDate(date))
		if len(self.identification) > 0:
			print("processing identification...")
			for identification in self.identification:
				self.simpleCollection.extend(self.processIdentification(identification))
		tempTitles = []
		for text in self.simpleCollection:
			if not str(text).title() in tempTitles:
				tempTitles.append(str(text).title())
		self.simpleCollection.extend(tempTitles)

        	self.greenPrint("Done")
	def cleanList(self,list):
		cleanList = []
		for strItem in list:
			if strItem.strip() not in cleanList:
				cleanList.append(strItem)
		return cleanList
	def greenPrint(self, text):
		print '\033[92m' + text + " " + u'\u2713' + '\033[0m'

	def generateDictionary(self):
		print "writing file..."
		lines = []
		for i in range(1, self.convinationLevel + 1):
			# print self.simpleCollection
			res = itertools.product(self.simpleCollection, repeat=i)
			for j in res:
				posiblePass = ''.join(j)
				lines.append(posiblePass)

		lines = self.cleanList(lines)
		self.makeFile(lines)
		self.greenPrint("write file done")

	def makeFile(self, lines):
		with open('pass.txt', 'a') as passFile:
			for line in lines:
				passFile.write(line+'\n')

dictionaryMaker  = DictionaryMaker()
dictionaryMaker.welcome()
<commit_msg>procesamiento distinto para nombre<commit_after>#!/usr/bin/python
import os

import itertools

class DictionaryMaker:
	def __init__(self):
		self.aditionalData = []
		self.simpleCollection = ["admin","adm","adm","2015","2016","2017","2014","2013",".","-","_","@"]
		self.convinationLevel = 2
		self.domainName = False
		self.fullName = False
		self.address = False
		self.importantDate = False
		self.identification = False

	def welcome(self):
		print("Welcome human, Please answer the following questions...")
		self.getInput()
		self.processInput()
		self.generateDictionary()

	def getInput(self):
		print("It is possible to enter an empty response...")
		self.convinationLevel = int(raw_input("convination level:"))
		self.makeQuestion("domain name?","domainName")
		self.makeQuestion("address?","address")
		self.makeQuestion("full name?","fullName")
		self.makeQuestion("birthdate or important date?(dd-mm-yyyy)","importantDate")
		self.makeQuestion("identifier or identification number?", "identification")
		self.makeQuestion("aditional data?","aditionalData")

	def processNumbers(self,inStr):
		numbers = [str(s) for s in inStr.split() if s.isdigit()]
		response = []
		for number in numbers:
			for i in range(1, len(number)):
				res = itertools.product(number,repeat = i)
				for convination in res:
					response.append(''.join(convination))
		return response

	def processStr(self,inStr):
		response = [str(s) for s in inStr.split() if not s.isdigit()]
		response.append(inStr)
		response.append("".join(inStr.split()))
		return response
	def processName(self,inStr):
		response = self.processStr(inStr)
		words = [str(s) for s in inStr.split() if not s.isdigit()]
		for word in words:
			response.append(word[0])
		return response
	def processDomain(self,inStr):
		response = []
		response.append(inStr)
		response.extend(inStr.split("."))
		return response
	def processAddress(self,inStr):
		response = []
		response.append(inStr)
		response.extend(inStr.split())
		response.append(''.join(inStr.split()))
		response.extend(self.processNumbers(inStr))
		response.extend(self.processStr(inStr))
		return response
	def processDate(self,inStr):
		response = []
		date = []
		if "/" in inStr:
			response.extend(inStr.split("/"))
		if "-" in inStr:
			response.extend(inStr.split("-"))
		date.extend(response)
		if len(response) == 3 and len(response[2]) == 4:
			response.append(response[2][:2])
			response.append(response[2][2:])
		response.append(''.join(date))
		response.append('-'.join(date))
		response.append('='.join(date))
		return response
	def processIdentification(self,inStr):
                numbers = [str(s) for s in inStr.split() if s.isdigit()]
                response = []
                for number in numbers:
                        for i in range(1, len(number)):
				response.append(number[0:i])
				response.append(number[:i])
		response = self.cleanList(response)
                return response
	def makeQuestion(self,questionStr,storeStr):
		nextQuestion = True

		if not getattr(self,storeStr):
			setattr(self,storeStr, [])

		storeSelf = getattr(self,storeStr)

		while nextQuestion:
			tempAnswer = raw_input(questionStr + " (empty = next question)")
			if tempAnswer != "":
				storeSelf.append(tempAnswer)
			else:
				nextQuestion = False
		setattr(self,storeStr,storeSelf)
	def processInput(self):
		print("Starting processing...")
        	if len(self.domainName) > 0:
			print("processing domain name...")
			for domain in self.domainName:
            			self.simpleCollection.extend(self.processDomain(domain))
		if len(self.fullName) > 0:
			print("processing full name...")
			for fullName in self.fullName:
				self.simpleCollection.extend(self.processName(fullName))
        	if len(self.address) > 0:
			print("processing address...")
			for address in self.address:
            			self.simpleCollection.extend(self.processAddress(address))
        	if len(self.aditionalData) > 0:
			print("processing additional data...")
            		for data in self.aditionalData:
                		self.simpleCollection.extend(self.processStr(data))
		if len(self.importantDate) > 0:
			print("processing dates...")
			for date in self.importantDate:
				self.simpleCollection.extend(self.processDate(date))
		if len(self.identification) > 0:
			print("processing identification...")
			for identification in self.identification:
				self.simpleCollection.extend(self.processIdentification(identification))
		tempTitles = []
		for text in self.simpleCollection:
			if not str(text).title() in tempTitles:
				tempTitles.append(str(text).title())
		self.simpleCollection.extend(tempTitles)

        	self.greenPrint("Done")
	def cleanList(self,list):
		cleanList = []
		for strItem in list:
			if strItem.strip() not in cleanList:
				cleanList.append(strItem)
		return cleanList
	def greenPrint(self, text):
		print '\033[92m' + text + " " + u'\u2713' + '\033[0m'

	def generateDictionary(self):
		print "writing file..."
		lines = []
		for i in range(1, self.convinationLevel + 1):
			# print self.simpleCollection
			res = itertools.product(self.simpleCollection, repeat=i)
			for j in res:
				posiblePass = ''.join(j)
				lines.append(posiblePass)

		lines = self.cleanList(lines)
		self.makeFile(lines)
		self.greenPrint("write file done")

	def makeFile(self, lines):
		with open('pass.txt', 'a') as passFile:
			for line in lines:
				passFile.write(line+'\n')

dictionaryMaker  = DictionaryMaker()
dictionaryMaker.welcome()
<|endoftext|>


<commit_before># mammon - utility/third-party stuff, each thing has it's own header and provenance
# information.

# CaseInsensitiveDict from requests.
#
# Copyright 2015 Kenneth Reitz
#
#   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 collections

class CaseInsensitiveDict(collections.MutableMapping):
    """
    A case-insensitive ``dict``-like object.
    Implements all methods and operations of
    ``collections.MutableMapping`` as well as dict's ``copy``. Also
    provides ``lower_items``.
    All keys are expected to be strings. The structure remembers the
    case of the last key to be set, and ``iter(instance)``,
    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
    will contain case-sensitive keys. However, querying and contains
    testing is case insensitive::
        cid = CaseInsensitiveDict()
        cid['Accept'] = 'application/json'
        cid['aCCEPT'] == 'application/json'  # True
        list(cid) == ['Accept']  # True
    For example, ``headers['content-encoding']`` will return the
    value of a ``'Content-Encoding'`` response header, regardless
    of how the header name was originally stored.
    If the constructor, ``.update``, or equality comparison
    operations are given keys that have equal ``.casefold()``s, the
    behavior is undefined.
    """
    def __init__(self, data=None, **kwargs):
        self._store = dict()
        if data is None:
            data = {}
        self.update(data, **kwargs)

    def __setitem__(self, key, value):
        # Use the lowercased key for lookups, but store the actual
        # key alongside the value.
        self._store[key.casefold()] = (key, value)

    def __getitem__(self, key):
        return self._store[key.casefold()][1]

    def __delitem__(self, key):
        del self._store[key.casefold()]

    def __iter__(self):
        return (casedkey for casedkey, mappedvalue in self._store.values())

    def __len__(self):
        return len(self._store)

    def lower_items(self):
        """Like iteritems(), but with all lowercase keys."""
        return (
            (lowerkey, keyval[1])
            for (lowerkey, keyval)
            in self._store.items()
        )

    def __eq__(self, other):
        if isinstance(other, collections.Mapping):
            other = CaseInsensitiveDict(other)
        else:
            return NotImplemented
        # Compare insensitively
        return dict(self.lower_items()) == dict(other.lower_items())

    # Copy is required
    def copy(self):
        return CaseInsensitiveDict(self._store.values())

    def __repr__(self):
        return str(dict(self.items()))

# a modified ExpiringDict implementation
#
# Copyright 2013-2015 Rackspace
#
#   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.

class ExpiringDict(collections.OrderedDict):
    def __init__(self, max_len, max_age_seconds):
        collections.OrderedDict.__init__(self)
        self.max_len = max_len
        self.max_age = max_age_seconds

    def __contains__(self, key):
        try:
            item = OrderedDict.__getitem__(self, key)
            if time.time() - item[1] < self.max_age:
                return True
            else:
                del self[key]
        except KeyError:
            pass
        return False

    def __getitem__(self, key, with_age=False, max_age=None):
        item = OrderedDict.__getitem__(self, key)
        item_age = time.time() - item[1]
        if not max_age:
            max_age = self.max_age
        if item_age < max_age:
            if with_age:
                return item[0], item_age
            else:
                return item[0]
        else:
            del self[key]
            raise KeyError(key)

    def __setitem__(self, key, value):
        if len(self) == self.max_len:
            self.popitem(last=False)
        OrderedDict.__setitem__(self, key, (value, time.time()))

    def pop(self, key, default=None):
        try:
            item = OrderedDict.__getitem__(self, key)
            del self[key]
            return item[0]
        except KeyError:
            return default

    def get(self, key, default=None, with_age=False, max_age=None):
        try:
            return self.__getitem__(key, with_age, max_age)
        except KeyError:
            if with_age:
                return default, None
            else:
                return default

    def put(self, key, value, ts=None):
        if len(self) == self.max_len:
            self.popitem(last=False)
        if not ts:
            ts = time.time()
        OrderedDict.__setitem__(self, key, (value, ts))

    def items(self):
        r = []
        for key in self:
            try:
                r.append((key, self[key]))
            except KeyError:
                pass
        return r

    def values(self):
        r = []
        for key in self:
            try:
                r.append(self[key])
            except KeyError:
                pass
        return r

    def fromkeys(self):
        raise NotImplementedError()
    def iteritems(self):
        raise NotImplementedError()
    def itervalues(self):
        raise NotImplementedError()
    def viewitems(self):
        raise NotImplementedError()
    def viewkeys(self):
        raise NotImplementedError()
    def viewvalues(self):
        raise NotImplementedError()

# fast irc casemapping validation
# part of mammon, under mammon license.
import string

special = '_-|^{}[]`'

nick_allowed_chars = string.ascii_letters + string.digits + special
nick_allowed_chars_tbl = str.maketrans('', '', nick_allowed_chars)

first_nick_allowed_chars = string.ascii_letters + special

def validate_nick(nick):
    if nick[0] not in first_nick_allowed_chars:
        return False
    remainder = nick[1:]
    badchars = remainder.translate(nick_allowed_chars_tbl)
    return badchars == ''

chan_allowed_chars = string.ascii_letters + string.digits + special + '`~!@#$%^&*()+=|\\<>/?'
chan_allowed_chars_tbl = str.maketrans('', '', chan_allowed_chars)

def validate_chan(chan_name):
    if chan_name[0] != '#':
        return False
    badchars = chan_name[1:].translate(chan_allowed_chars_tbl)
    return badchars == ''
<commit_msg>mammon.utility: we have to casefold the keys in our expiringdict.<commit_after># mammon - utility/third-party stuff, each thing has it's own header and provenance
# information.

# CaseInsensitiveDict from requests.
#
# Copyright 2015 Kenneth Reitz
#
#   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 collections

class CaseInsensitiveDict(collections.MutableMapping):
    """
    A case-insensitive ``dict``-like object.
    Implements all methods and operations of
    ``collections.MutableMapping`` as well as dict's ``copy``. Also
    provides ``lower_items``.
    All keys are expected to be strings. The structure remembers the
    case of the last key to be set, and ``iter(instance)``,
    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
    will contain case-sensitive keys. However, querying and contains
    testing is case insensitive::
        cid = CaseInsensitiveDict()
        cid['Accept'] = 'application/json'
        cid['aCCEPT'] == 'application/json'  # True
        list(cid) == ['Accept']  # True
    For example, ``headers['content-encoding']`` will return the
    value of a ``'Content-Encoding'`` response header, regardless
    of how the header name was originally stored.
    If the constructor, ``.update``, or equality comparison
    operations are given keys that have equal ``.casefold()``s, the
    behavior is undefined.
    """
    def __init__(self, data=None, **kwargs):
        self._store = dict()
        if data is None:
            data = {}
        self.update(data, **kwargs)

    def __setitem__(self, key, value):
        # Use the lowercased key for lookups, but store the actual
        # key alongside the value.
        self._store[key.casefold()] = (key, value)

    def __getitem__(self, key):
        return self._store[key.casefold()][1]

    def __delitem__(self, key):
        del self._store[key.casefold()]

    def __iter__(self):
        return (casedkey for casedkey, mappedvalue in self._store.values())

    def __len__(self):
        return len(self._store)

    def lower_items(self):
        """Like iteritems(), but with all lowercase keys."""
        return (
            (lowerkey, keyval[1])
            for (lowerkey, keyval)
            in self._store.items()
        )

    def __eq__(self, other):
        if isinstance(other, collections.Mapping):
            other = CaseInsensitiveDict(other)
        else:
            return NotImplemented
        # Compare insensitively
        return dict(self.lower_items()) == dict(other.lower_items())

    # Copy is required
    def copy(self):
        return CaseInsensitiveDict(self._store.values())

    def __repr__(self):
        return str(dict(self.items()))

# a modified ExpiringDict implementation
#
# Copyright 2013-2015 Rackspace
#
#   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.

class ExpiringDict(collections.OrderedDict):
    def __init__(self, max_len, max_age_seconds):
        collections.OrderedDict.__init__(self)
        self.max_len = max_len
        self.max_age = max_age_seconds

    def __contains__(self, key):
        try:
            item = OrderedDict.__getitem__(self, key.casefold())
            if time.time() - item[1] < self.max_age:
                return True
            else:
                del self[key.casefold()]
        except KeyError:
            pass
        return False

    def __getitem__(self, key, with_age=False, max_age=None):
        item = OrderedDict.__getitem__(self, key.casefold())
        item_age = time.time() - item[1]
        if not max_age:
            max_age = self.max_age
        if item_age < max_age:
            if with_age:
                return item[0], item_age
            else:
                return item[0]
        else:
            del self[key.casefold()]
            raise KeyError(key.casefold())

    def __setitem__(self, key, value):
        if len(self) == self.max_len:
            self.popitem(last=False)
        OrderedDict.__setitem__(self, key.casefold(), (value, time.time()))

    def pop(self, key, default=None):
        try:
            item = OrderedDict.__getitem__(self, key.casefold())
            del self[key.casefold()]
            return item[0]
        except KeyError:
            return default

    def get(self, key, default=None, with_age=False, max_age=None):
        try:
            return self.__getitem__(key.casefold(), with_age, max_age)
        except KeyError:
            if with_age:
                return default, None
            else:
                return default

    def put(self, key, value, ts=None):
        if len(self) == self.max_len:
            self.popitem(last=False)
        if not ts:
            ts = time.time()
        OrderedDict.__setitem__(self, key.casefold(), (value, ts))

    def items(self):
        r = []
        for key in self:
            try:
                r.append((key, self[key]))
            except KeyError:
                pass
        return r

    def values(self):
        r = []
        for key in self:
            try:
                r.append(self[key])
            except KeyError:
                pass
        return r

    def fromkeys(self):
        raise NotImplementedError()
    def iteritems(self):
        raise NotImplementedError()
    def itervalues(self):
        raise NotImplementedError()
    def viewitems(self):
        raise NotImplementedError()
    def viewkeys(self):
        raise NotImplementedError()
    def viewvalues(self):
        raise NotImplementedError()

# fast irc casemapping validation
# part of mammon, under mammon license.
import string

special = '_-|^{}[]`'

nick_allowed_chars = string.ascii_letters + string.digits + special
nick_allowed_chars_tbl = str.maketrans('', '', nick_allowed_chars)

first_nick_allowed_chars = string.ascii_letters + special

def validate_nick(nick):
    if nick[0] not in first_nick_allowed_chars:
        return False
    remainder = nick[1:]
    badchars = remainder.translate(nick_allowed_chars_tbl)
    return badchars == ''

chan_allowed_chars = string.ascii_letters + string.digits + special + '`~!@#$%^&*()+=|\\<>/?'
chan_allowed_chars_tbl = str.maketrans('', '', chan_allowed_chars)

def validate_chan(chan_name):
    if chan_name[0] != '#':
        return False
    badchars = chan_name[1:].translate(chan_allowed_chars_tbl)
    return badchars == ''
<|endoftext|>


<commit_before>"""
Created on 10 Jan 2017

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)

example use:
./socket_receiver.py | ./csv_writer.py status.csv -e | ./histo_chart.py val.loc.lat -v -e -o lat.csv -x 50.8228 50.8232
./socket_receiver.py | ./csv_writer.py status.csv -e | ./histo_chart.py val.loc.lng -v -e -o lng.csv -x -0.1233 -0.1227
"""

from collections import OrderedDict

from scs_core.data.datum import Datum
from scs_core.data.json import JSONable

# --------------------------------------------------------------------------------------------------------------------

class GPSLocation(JSONable):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_jdict(cls, jdict):
        if not jdict:
            return None

        lat = jdict.get('lat')
        lng = jdict.get('lng')
        alt = jdict.get('alt')

        quality = jdict.get('qual')

        return GPSLocation(lat, lng, alt, quality)

    @classmethod
    def construct(cls, gga):
        if gga is None:
            return None

        loc = gga.loc
        alt = None if gga.alt is None else round(gga.alt)
        quality = gga.quality

        if loc is None:
            return GPSLocation(None, None, alt, quality)

        lat = loc.deg_lat()
        lng = loc.deg_lng()

        return GPSLocation(lat, lng, alt, quality)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, lat, lng, alt, quality):
        """
        Constructor
        """
        self.__lat = lat                    # degrees north of the equator
        self.__lng = lng                    # degrees west of Greenwich
        self.__alt = alt                    # metres above sea level

        self.__quality = quality            # 0, 2 or 3

    # ----------------------------------------------------------------------------------------------------------------

    def as_json(self):
        jdict = OrderedDict()

        jdict['lat'] = self.lat
        jdict['lng'] = self.lng
        jdict['alt'] = self.alt

        jdict['qual'] = self.quality

        return jdict

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def lat(self):
        return self.__lat

    @property
    def lng(self):
        return self.__lng

    @property
    def alt(self):
        return self.__alt

    @property
    def quality(self):
        return self.__quality

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "GPSLocation:{lat:%s, lng:%s, alt:%s, quality:%s}" % (self.lat, self.lng, self.alt, self.quality)
<commit_msg>Added altitude to GPSLocation.<commit_after>"""
Created on 10 Jan 2017

@author: Bruno Beloff (bruno.beloff@southcoastscience.com)

example use:
./socket_receiver.py | ./csv_writer.py status.csv -e | ./histo_chart.py val.loc.lat -v -e -o lat.csv -x 50.8228 50.8232
./socket_receiver.py | ./csv_writer.py status.csv -e | ./histo_chart.py val.loc.lng -v -e -o lng.csv -x -0.1233 -0.1227
"""

from collections import OrderedDict

from scs_core.data.json import JSONable

# --------------------------------------------------------------------------------------------------------------------

class GPSLocation(JSONable):
    """
    classdocs
    """

    # ----------------------------------------------------------------------------------------------------------------

    @classmethod
    def construct_from_jdict(cls, jdict):
        if not jdict:
            return None

        lat = jdict.get('lat')
        lng = jdict.get('lng')
        alt = jdict.get('alt')

        quality = jdict.get('qual')

        return GPSLocation(lat, lng, alt, quality)

    @classmethod
    def construct(cls, gga):
        if gga is None:
            return None

        loc = gga.loc
        alt = None if gga.alt is None else round(gga.alt)
        quality = gga.quality

        if loc is None:
            return GPSLocation(None, None, alt, quality)

        lat = loc.deg_lat()
        lng = loc.deg_lng()

        return GPSLocation(lat, lng, alt, quality)

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, lat, lng, alt, quality):
        """
        Constructor
        """
        self.__lat = lat                    # degrees north of the equator
        self.__lng = lng                    # degrees west of Greenwich
        self.__alt = alt                    # metres above sea level

        self.__quality = quality            # 0, 2 or 3

    # ----------------------------------------------------------------------------------------------------------------

    def as_json(self):
        jdict = OrderedDict()

        jdict['lat'] = self.lat
        jdict['lng'] = self.lng
        jdict['alt'] = self.alt

        jdict['qual'] = self.quality

        return jdict

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def lat(self):
        return self.__lat

    @property
    def lng(self):
        return self.__lng

    @property
    def alt(self):
        return self.__alt

    @property
    def quality(self):
        return self.__quality

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "GPSLocation:{lat:%s, lng:%s, alt:%s, quality:%s}" % (self.lat, self.lng, self.alt, self.quality)
<|endoftext|>