<commit_before>#!/usr/bin/env python
#
# Copyright 2018 Ettus Research, a National Instruments Company
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
"""
Utility to update hashes for UHD within meta-ettus.
"""

from __future__ import print_function
import os
import re
import subprocess
import tempfile
import argparse
import shutil
from six import iteritems

UHD_REPO = 'https://github.com/EttusResearch/uhd.git'
UHD_VERSION_FILE = 'meta-ettus-core/recipes-support/uhd/version.inc'
UHD_SRC_FILE = 'meta-ettus-core/recipes-support/uhd/uhd_git_src.inc'
DEVICE_INFO = {
    'n3xx': {
        'fpga_append': [
            'meta-sulfur/recipes-support/uhd/uhd-fpga-images_git.bbappend',
            'meta-sulfur/recipes-kernel/linux-firmware/linux-firmware_git.bbappend',
        ],
    },
    'e320': {
        'fpga_append': [
            'meta-neon/recipes-support/uhd/uhd-fpga-images_git.bbappend',
            'meta-neon/recipes-kernel/linux-firmware/linux-firmware_git.bbappend',
        ],
    },
    'e31x': {
        'fpga_append': [
            'meta-e31x/recipes-support/uhd/uhd-fpga-images_git.bbappend',
            'meta-e31x/recipes-kernel/linux-firmware/linux-firmware_git.bbappend',
        ],
    },
}
BASE_URL = "http://files.ettus.com/binaries/cache"

def parse_args():
    """
    Returns the result of parse_args().
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-u', '--uhd-path',
        help="Path to UHD git repository. If not provided, will clone a fresh "
             "repo and use that."
    )
    this_repo_dir = os.path.normpath(
        os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
    parser.add_argument(
        '-m', '--meta-ettus-path', default=this_repo_dir,
        help="Path to the meta-ettus repository."
    )
    parser.add_argument(
        '-r', '--uhd-repo', default=UHD_REPO,
        help="UHD repo URL for cloning"
    )
    parser.add_argument(
        '-b', '--branch',
        help="UHD branch"
    )
    parser.add_argument(
        'devices', default=list(DEVICE_INFO.keys()), nargs='*',
        help="List all devices for which updates shall be performed. Default: "
             "All devices."
    )
    return parser.parse_args()

def check_meta_ettus_path(mep):
    """
    Check if mep is a valid path of a meta-ettus repository.
    """
    return os.path.isdir(os.path.join(mep, 'meta-ettus-core'))

def update_uhd_info(mep, uhd_sha1, branch, version):
    """
    Update current meta-ettus to latest UHD

    mep: meta-ettus path
    uhd_sha1: The git SHA1 for the UHD repo
    branch: The name of the branch we're going to track
    version: The UHD version
    """
    print("### Updating `{}'...".format(UHD_SRC_FILE))
    bbfile = os.path.join(mep, UHD_SRC_FILE)
    bbfile_content = open(bbfile).read()
    bbfile_content = re.sub(
        r'SRCREV = "([a-z0-9]+)"',
        'SRCREV = "{}"'.format(uhd_sha1),
        bbfile_content,
    )
    current_branch = \
        re.search(
            r'SRC_URI = [^;]+;branch=(?P<branch>[^"]+)',
            bbfile_content).group('branch')
    if branch is None:
        print("### FYI: File {} is referring to git branch {}.".format(
            os.path.basename(bbfile), current_branch))
    else:
        print("### Replacing branch name in SRC_URI with {}".format(branch))
        bbfile_content = re.sub(
            r'(SRC_URI = [^;]+;branch=)([^"]+)',
            r'\1' + branch,
            bbfile_content,
        )
    open(bbfile, 'w').write(bbfile_content)
    print("### Setting version to {} in {}".format(
        version, os.path.basename(bbfile)))
    bbfile = os.path.join(mep, UHD_VERSION_FILE)
    bbfile_content = open(bbfile).read()
    bbfile_content = re.sub(
        r'PV = ".*"',
        'PV = "{}"'.format(version),
        bbfile_content,
    )
    open(bbfile, 'w').write(bbfile_content)

def load_manifest(upath):
    """
    Return the manifest as a dictionary
    """
    manifest_path = os.path.join(upath, 'images', 'manifest.txt')
    print("### Reading manifest from {}...".format(manifest_path))
    manifest_contents = open(manifest_path).read()
    manifest = {}
    for line in manifest_contents.split('\n'):
        line_unpacked = line.split()
        try:
            # Check that the line isn't empty or a comment
            if not line_unpacked or line.strip().startswith('#'):
                continue
            target, repo_hash, url, sha256_hash = line_unpacked
            manifest[target] = {
                "repo_hash": repo_hash,
                "url": url,
                "sha256_hash": sha256_hash,
            }
        except ValueError:
            print("WARNING: Invalid line in manifest file:\n"
                  "         {}".format(line))
            continue
    return manifest

def get_uhd_version(upath):
    """
    Return the UHD version
    """
    uhd_version_path = os.path.join(upath,
        'host', 'cmake', 'Modules', 'UHDVersion.cmake')
    print("### Reading UHD version from {}...".format(uhd_version_path))
    uhdver_contents = open(uhd_version_path).read()
    major = re.search(r'set\(UHD_VERSION_MAJOR[ ]+(?P<major>[0-9]+)\)',
        uhdver_contents).group('major')
    api = re.search(r'set\(UHD_VERSION_API[ ]+(?P<api>[0-9]+)\)',
        uhdver_contents).group('api')
    abi = re.search(r'set\(UHD_VERSION_ABI[ ]+(?P<abi>[0-9]+)\)',
        uhdver_contents).group('abi')
    patch = re.search(r'set\(UHD_VERSION_PATCH[ ]+(?P<patch>[a-z0-9]+)\)',
        uhdver_contents).group('patch')
    return ""+major+"."+api+"."+abi+"."+patch

def get_fpga_target_list(src_uri_content):
    """
    sdf
    """
    url_name_pairs = [
        s.strip(" \\\t")
        for s in src_uri_content.strip().split("\n")
    ]
    return [
        u
        for u in url_name_pairs
        if not u.startswith('http')
    ], [
        re.search(
            r'http://[a-z0-9.-/-]+/([a-z0-9_]+)[-a-z0-9]*\.zip;name=([-_a-z0-9]+);?',
            u).groups()
        for u in url_name_pairs
        if u.startswith('http')
    ]

def get_new_src_uri_str(src_uri_key, extra_lines, target_dict, unpack):
    """
    Create the SRC_URI_append... string
    """
    num_leading_spaces = len(src_uri_key) + len(' = " ')
    return src_uri_key + ' = " ' + ' \\\n{spaces}'.format(spaces=' ' * num_leading_spaces).join(extra_lines + [
        "{base_url}/{url};name={name};unpack={unpack}".format(
            base_url=BASE_URL,
            url=t_dict['url'],
            name=name,
            unpack=str(unpack).lower(),
        ) for name, t_dict in iteritems(target_dict)
    ]) + ' \\\n{spaces}"'.format(spaces=' ' * (num_leading_spaces - 2))

def update_fpga_hashes(bbafile, manifest):
    """
    Update the FPGA hashes in the appropriate bbappend file
    """
    print("### Modifying {}...".format(bbafile))
    bbafile_content = open(bbafile).read()
    src_uri_key, src_uri_content = \
        re.search(r'(SRC_URI_append[a-z0-9-_]*)\s+=\s+"([^"]+)"',
                  bbafile_content).groups()
    extra_lines, fpga_target_list = get_fpga_target_list(src_uri_content)
    print("### Found targets:")
    for target, name in fpga_target_list:
        print("### * {}: {}".format(name, target))
    target_dict = {
        name: {
            'target': target,
            'sha': manifest[target]['sha256_hash'],
            'url': manifest[target]['url'],
        }
        for target, name in fpga_target_list
        if target in manifest
    }
    if "uhd-fpga-images" in bbafile:
        unpack=False
    else:
        unpack=True
    bbafile_content, n_subs = re.subn(
        r'SRC_URI_append[a-z0-9-_]*\s+=\s+"[^"]+"',
        get_new_src_uri_str(src_uri_key, extra_lines, target_dict, unpack),
        bbafile_content,
        count=1
    )
    if n_subs != 1:
        print("ERROR: Couldn't find SRC_URI_append string to replace!")
        exit(1)
    for name, t_dict in iteritems(target_dict):
        regex = r'SRC_URI\[{name}.sha256sum\]\s+=\s+"[a-z0-9]+"'.format(name=name)
        new_hash_str = 'SRC_URI[{name}.sha256sum] = "{hash}"'.format(
            name=name,
            hash=t_dict['sha'],
        )
        bbafile_content, n_subs = \
            re.subn(regex, new_hash_str, bbafile_content, count=1)
        if n_subs != 1:
            print("WARNING: Didn't find sha256sum for target {}! Will append."
                  .format(name))
            bbafile_content += "\n" + new_hash_str
    open(bbafile, 'w').write(bbafile_content)

def main():
    """
    Go, go, go!
    """
    args = parse_args()
    print("### Updating meta-ettus...")
    print("### Using meta-ettus repository at: {}".format(args.meta_ettus_path))
    if not check_meta_ettus_path(args.meta_ettus_path):
        print("ERROR: Invalid meta-ettus repository.")
        return False
    temp_dir = None
    if args.uhd_path is None:
        print("### No UHD path given. Cloning fresh repo...")
        temp_dir = tempfile.mkdtemp()
        args.uhd_path = os.path.join(temp_dir, 'uhd')
        subprocess.check_call(['git', 'clone', args.uhd_repo, args.uhd_path])
    print("### Using UHD repo at: {}".format(args.uhd_path))
    if args.branch is not None:
        print("### Switching UHD branch to {} at request of user (-b was provided)".format(args.branch))
        print("##### Note: You will need to switch back if you so desire.")
        subprocess.check_call(
            ['git', 'checkout', args.branch], cwd=args.uhd_path)
    print("### Learning git hash of UHD repository...")
    uhd_git_hash = subprocess.check_output(
        ['git', 'rev-parse', 'HEAD'], cwd=args.uhd_path).decode('utf-8').strip()
    print("### Git hash is: {}".format(uhd_git_hash))
    print("### Learning UHD version...")
    uhd_version = get_uhd_version(args.uhd_path)
    print("### UHD version is: {}".format(uhd_version))
    update_uhd_info(args.meta_ettus_path, uhd_git_hash, args.branch, uhd_version)
    manifest = load_manifest(args.uhd_path)
    for device in args.devices:
        print("### Updating FPGA images for device `{}'...".format(device))
        for bba_file in DEVICE_INFO[device]['fpga_append']:
            update_fpga_hashes(
                os.path.join(args.meta_ettus_path, bba_file), manifest,)
    if temp_dir is not None:
        shutil.rmtree(temp_dir)
    return True

if __name__ == "__main__":
    exit(not main())
<commit_msg>contrib: remove update_uhd.py script<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python -B

# This is an example of how to control the Delcom USBLMP 904x device
#
# Copyright (c) 2015 Aaron Linville <aaron@linville.org>

import argparse
import delcom904x

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = "Convert and generate Chmaber Director log files.")
    parser.add_argument('--list', action='store_true', help = "List all USB devices.")
    parser.add_argument('--info', action='store_true', help = "Returns info on the device.")
    parser.add_argument('--red', action='store_true', help = "Enable the red light.")
    parser.add_argument('--green', action='store_true', help = "Enable the green light.")
    parser.add_argument('--blue', action='store_true', help = "Enable the blue light.")
    parser.add_argument('--flash', action='store_true', help = "Turns on flashing.")
    parser.add_argument('--cycle', action='store_true', help = "Turns on cycling.")
    parser.add_argument('--intensity', nargs = '?', metavar = '80', type=int, help = "Sets brightness: 0-100.")
    parser.add_argument('--buzzer', action='store_true', help = "Buzzes three times.")
    parser.add_argument('--reset', action='store_true', help = "Resets the device.")

    args = parser.parse_args()

    if(args.list):
        delcom904x.list()

    color = 0

    if(args.green):
        color = color | delcom904x.green

    if(args.red):
        color = color | delcom904x.red

    if(args.blue):
        color = color | delcom904x.blue

    light = delcom904x.DelcomMultiColorIndicator()

    if(args.reset):
        light.reset()
        exit()

    cycle_time = 0
    if(args.cycle):
        cycle_time = 100

    light.set_color(color, flashing = args.flash, cycle_time = cycle_time)

    if(args.intensity):
        light.set_intensity(args.intensity, color)

    if(args.buzzer):
        light.enable_buzzer(0, 200, 100, 3)

    if(args.info):
        light.info()
<commit_msg>Fixed setting default times on cycle and flashing options.<commit_after>#!/usr/bin/python -B

# This is an example of how to control the Delcom USBLMP 904x device
#
# Copyright (c) 2015 Aaron Linville <aaron@linville.org>

import argparse
import delcom904x

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description = "Convert and generate Chmaber Director log files.")
    parser.add_argument('--list', action='store_true', help = "List all USB devices.")
    parser.add_argument('--info', action='store_true', help = "Returns info on the device.")
    parser.add_argument('--red', action='store_true', help = "Enable the red light.")
    parser.add_argument('--green', action='store_true', help = "Enable the green light.")
    parser.add_argument('--blue', action='store_true', help = "Enable the blue light.")
    parser.add_argument('--flash', action='store_true', help = "Turns on flashing.")
    parser.add_argument('--cycle', nargs = '?', metavar = '100', const = 100, type=int, help = "Turns on cycling.")
    parser.add_argument('--intensity', nargs = '?', metavar = '80', const = 80, type=int, help = "Sets brightness: 0-100.")
    parser.add_argument('--buzzer', action='store_true', help = "Buzzes three times.")
    parser.add_argument('--reset', action='store_true', help = "Resets the device.")

    args = parser.parse_args()

    if(args.list):
        delcom904x.list()

    color = 0

    if(args.green):
        color = color | delcom904x.green

    if(args.red):
        color = color | delcom904x.red

    if(args.blue):
        color = color | delcom904x.blue

    light = delcom904x.DelcomMultiColorIndicator()

    if(args.reset):
        light.reset()
        exit()

    light.set_color(color, flashing = args.flash, cycle_time = args.cycle)

    if(args.intensity):
        light.set_intensity(args.intensity, color)

    if(args.buzzer):
        light.enable_buzzer(0, 200, 100, 3)

    if(args.info):
        light.info()
<|endoftext|>


<commit_before>from __future__ import absolute_import
from __future__ import division

import base64
import collections
import datetime
import hashlib
import logging
import json
import re
import time

import pytz
import requests
import slumber.exceptions
import xmlrpc2.client

from conveyor.utils import DictDiffer

_normalize_regex = re.compile(r"[^A-Za-z0-9.]+")
_distutils2_version_capture = re.compile("^(.*?)(?:\(([^()]+)\))?$")

logger = logging.getLogger(__name__)

EXPECTED = set(["resource_uri", "downloads", "modified"])

def split_meta(meta):
    meta_split = meta.split(";", 1)
    meta_name, meta_version = _distutils2_version_capture.search(meta_split[0].strip()).groups()
    meta_env = meta_split[1].strip() if len(meta_split) == 2 else ""

    return {
        "name": meta_name,
        "version": meta_version if meta_version is not None else "",
        "environment": meta_env,
    }

def get(d, attr, default=None):
    value = d.get(attr, default)

    if not value or value in ["UNKNOWN", "None"]:
        value = default

    return value

def get_key(prefix, key):
    if not prefix is None:
        return "%s:%s" % (prefix, key)
    return key

class Processor(object):

    def __init__(self, index, warehouse, session=None, store=None, store_prefix=None, *args, **kwargs):
        super(Processor, self).__init__(*args, **kwargs)

        if session is None:
            session = requests.session()

        self.session = session

        self.client = xmlrpc2.client.Client(index, session=self.session)
        self.warehouse = warehouse
        self.store = store
        self.store_prefix = store_prefix

    def get_releases(self, name, version=None):
        if version is None:
            versions = self.client.package_releases(name, True)

            if isinstance(versions, basestring):
                versions = [versions]
        else:
            versions = [version]

        for version in versions:
            item = self.client.release_data(name, version)
            url = self.client.release_urls(item["name"], item["version"])

            if isinstance(url, collections.Mapping):
                urls = [url]
            elif isinstance(url, collections.Iterable):
                urls = url
            else:
                raise RuntimeError("Do not understand the type returned by release_urls")

            # fix classifiers
            item["classifiers"] = sorted(set(get(item, "classifiers", [])))

            files = []

            oldest = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)

            for url in urls:
                data = url.copy()

                try:
                    resp = self.session.get(data["url"], prefetch=True)
                    resp.raise_for_status()
                except Exception:
                    # @@@ Catch the proper exceptions (and do what?)
                    raise

                if oldest > data["upload_time"]:
                    oldest = data["upload_time"]

                data["file_data"] = base64.b64encode(resp.content)
                files.append(data)

            item.update({
                "normalized": _normalize_regex.sub("-", item["name"]).lower(),
                "files": files,
            })

            if files:
                item["guessed_creation"] = oldest

            # Clean up some of the fields that we don't use
            remove_fields = set([
                "_pypi_hidden",
                "_pypi_ordering",
                "cheesecake_code_kwalitee_id",
                "cheesecake_documentation_id",
                "cheesecake_installability_id",
            ])

            item = dict([(k, v) for k, v in item.items() if k not in remove_fields])

            yield item

    def get_or_create_project(self, project):
        normalized = _normalize_regex.sub("-", project).lower()

        # Get or Create Project
        try:
            # Get
            project = self.warehouse.projects(normalized).get()
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            # Create
            project_data = {"name": project}
            project = self.warehouse.projects.post(project_data)

        return project

    def _compute_hash(self, release):
        def _dict_constant_data_structure(dictionary):
            data = []

            for k, v in dictionary.items():
                if isinstance(v, dict):
                    v = _dict_constant_data_structure(v)
                elif isinstance(v, set):
                    v = sorted(v)
                data.append([k, v])

            return sorted(data, key=lambda x: x[0])

        if not hasattr(self, "_computed_hash"):
            self._computed_hash = hashlib.sha512(json.dumps(
                                                    _dict_constant_data_structure(release),
                                                    default=lambda obj: obj.isoformat() if hasattr(obj, "isoformat") else obj)
                                                ).hexdigest()[:32]

        return self._computed_hash

    def release_changed(self, release):
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (release["name"], release["version"]))

        stored_hash = self.store.get(key)
        computed_hash = self._compute_hash(release)

        return not (stored_hash and stored_hash == computed_hash)

    def store_release_hash(self, release):
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (release["name"], release["version"]))
        self.store.set(key, self._compute_hash(release))

    def sync_release(self, release):
        if "/" in release["version"]:
            # We cannot accept versions with a / in it.
            logger.error("Skipping '%s' version '%s' because it contains a '/'", release["name"], release["version"])
            return

        if not self.release_changed(release):
            logger.info("Skipping '%s' version '%s' because it has not changed", release["name"], release["version"])
            return

        logger.info("Syncing '%s' version '%s'", release["name"], release["version"])

        project = self.get_or_create_project(release["name"])

        # Get or Create Version
        version_data = self.to_warehouse_version(release, extra={"project": project["resource_uri"]})

        try:
            # GET
            version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get()
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            # Create
            version = self.warehouse.projects(release["normalized"]).versions().post(version_data)
        else:
            # Update
            version["classifiers"] = sorted(version["classifiers"])
            diff = DictDiffer(version_data, version)
            different = diff.added() | diff.changed() | diff.removed() - (EXPECTED | set(["files"]))

            if "created" in different and not version.get("files", None):
                # The created time is a guess because we don't have any uploaded files
                different.remove("created")

            if different:
                logger.info(
                    "Updating the version for '%s' version '%s'. warehouse: '%s' updated: '%s'",
                    release["name"],
                    release["version"],
                    dict([(k, v) for k, v in version.items() if k in different]),
                    dict([(k, v) for k, v in version_data.items() if k in different]),
                )
                self.warehouse.projects(release["normalized"]).versions(release["version"]).put(version_data)
                version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get()

        # @@@ Check warehouse for a list of files that this version has and delete any ones
        #      that no longer exist.

        _version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get(full=True)

        warehouse_files = set([x["filename"] for x in _version["files"]])
        local_files = set([x["filename"] for x in release["files"]])

        deleted = warehouse_files - local_files

        for filename in deleted:
            logger.info("Deleting the file '%s' from '%s' version '%s'", filename, release["name"], release["version"])
            self.warehouse.projects(release["normalized"]).versions(release["version"]).files(filename).delete()

        for f in release["files"]:
            file_data = self.to_warehouse_file(release, f, extra={"version": version["resource_uri"]})

            try:
                # Get
                vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).get()
            except slumber.exceptions.HttpClientError as e:
                if not e.response.status_code == 404:
                    raise

                # Create
                vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files.post(file_data)
            else:
                # Update
                diff = DictDiffer(file_data, vfile)
                different = diff.added() | (diff.changed() - set(["file"])) | (diff.removed() - EXPECTED)

                if different:
                    logger.info(
                        "Updating the file '%s' for '%s' version '%s'. warehouse: '%s' updated: '%s'",
                        f["filename"],
                        release["name"],
                        release["version"],
                        dict([(k, v) for k, v in vfile.items() if k in different]),
                        dict([(k, v) for k, v in file_data.items() if k in different]),
                    )
                    self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).put(file_data)
                    vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).get()

        self.store_release_hash(release)

    def to_warehouse_version(self, release, extra=None):
        data = {
            "version": release["version"],

            "summary": get(release, "summary", ""),
            "description": get(release, "description", ""),
            "license": get(release, "license", ""),

            "author": {},
            "maintainer": {},

            "classifiers": get(release, "classifiers", []),
            "uris": {},

            "requires_python": get(release, "requires_python", ""),
            "requires_external": get(release, "requires_external", []),

            "platforms": [],
            "supported_platforms": [],
            "keywords": [],

            "yanked": False,
        }

        if get(release, "author", None):
            data["author"]["name"] = release["author"]

        if get(release, "author_email", None):
            data["author"]["email"] = release["author_email"]

        if get(release, "maintainer", None):
            data["maintainer"]["name"] = release["maintainer"]

        if get(release, "maintainer_email", None):
            data["maintainer"]["email"] = release["maintainer_email"]

        if get(release, "download_url"):
            data["uris"]["Download"] = release["download_url"]

        if get(release, "home_page"):
            data["uris"]["Home page"] = release["home_page"]

        if get(release, "bugtrack_url"):
            data["uris"]["Bug tracker"] = release["bugtrack_url"]

        if get(release, "docs_url"):
            data["uris"]["Documentation"] = release["docs_url"]

        if get(release, "platform"):
            platforms = get(release, "platform")

            if isinstance(platforms, basestring):
                platforms = [platforms]

            data["platforms"] = platforms

        if get(release, "supported_platforms"):
            supported_platforms = get(release, "supported_platforms")

            if isinstance(supported_platforms, basestring):
                supported_platforms = [supported_platforms]

            data["supported_platforms"] = supported_platforms

        if get(release, "keywords"):
            keywords = get(release, "keywords")

            # Check for a comma
            if "," in keywords:
                keywords = [x.strip() for x in keywords.split(",")]
            else:
                keywords = [x.strip() for x in keywords.split()]

            data["keywords"] = keywords

        for url in get(release, "project_url", []):
            label, uri = url.split(",", 1)
            data["uris"][label] = uri

        data["requires"] = [split_meta(req) for req in get(release, "requires_dist", [])]
        data["provides"] = [split_meta(req) for req in get(release, "provides_dist", [])]
        data["obsoletes"] = [split_meta(req) for req in get(release, "obsoletes_dist", [])]

        if get(release, "guessed_creation", None) is not None:
            data["created"] = release["guessed_creation"].isoformat()

        if extra is not None:
            data.update(extra)

        return data

    def to_warehouse_file(self, release, file, extra=None):
        data = {
            "file": {"name": file["filename"], "file": file["file_data"]},
            "created": file["upload_time"].isoformat(),
            "type": file["packagetype"],
            "python_version": file["python_version"],
            "comment": file["comment_text"],

            "yanked": False,
        }

        raw_data = base64.b64decode(file["file_data"])

        data.update({
            "digests": {
                "md5": hashlib.md5(raw_data).hexdigest(),
                "sha256": hashlib.sha256(raw_data).hexdigest(),
            },
            "filesize": len(raw_data),
            "filename": file["filename"],
        })

        if extra is not None:
            data.update(extra)

        return data

    def get_warehouse_releases(self, package):
        normalized = _normalize_regex.sub("-", package).lower()

        try:
            project = self.warehouse.projects(normalized).get(full=True)
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            return set()

        return set([x["version"] for x in project["versions"]])

    def delete_project_version(self, package, version):
        normalized = _normalize_regex.sub("-", package).lower()
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (package, version))

        logger.info("Deleting version '%s' of '%s'", version, package)

        self.store.delete(key)
        self.warehouse.projects(normalized).versions(version).delete()

    def delete_project(self, project):
        normalized = _normalize_regex.sub("-", project).lower()
        search_key = get_key(self.store_prefix, "pypi:process:%s:*" % project)

        logger.info("Deleting '%s'", project)

        for k in self.store.keys(search_key):
            self.store.delete(k)

        self.warehouse.projects(normalized).delete()

    def process(self):
        # @@@ Handle Deletion

        logger.info("Starting changed projects synchronization")

        current = time.mktime(datetime.datetime.utcnow().timetuple())

        since = int(float(self.store.get(get_key(self.store_prefix, "pypi:since")))) - 10

        names = set([(c[0], c[1]) for c in self.client.changelog(since)])

        for package in names:
            for release in self.get_releases(package[0], version=package[1]):
                self.sync_release(release)

        self.store.set(get_key(self.store_prefix, "pypi:since"), current)

        logger.info("Finished changed projects synchronization")
<commit_msg>Refactor the Get + Update OR Create Version<commit_after>from __future__ import absolute_import
from __future__ import division

import base64
import collections
import datetime
import hashlib
import logging
import json
import re
import time

import pytz
import requests
import slumber.exceptions
import xmlrpc2.client

from conveyor.utils import DictDiffer

_normalize_regex = re.compile(r"[^A-Za-z0-9.]+")
_distutils2_version_capture = re.compile("^(.*?)(?:\(([^()]+)\))?$")

logger = logging.getLogger(__name__)

EXPECTED = set(["resource_uri", "downloads", "modified"])

def split_meta(meta):
    meta_split = meta.split(";", 1)
    meta_name, meta_version = _distutils2_version_capture.search(meta_split[0].strip()).groups()
    meta_env = meta_split[1].strip() if len(meta_split) == 2 else ""

    return {
        "name": meta_name,
        "version": meta_version if meta_version is not None else "",
        "environment": meta_env,
    }

def get(d, attr, default=None):
    value = d.get(attr, default)

    if not value or value in ["UNKNOWN", "None"]:
        value = default

    return value

def get_key(prefix, key):
    if not prefix is None:
        return "%s:%s" % (prefix, key)
    return key

class Processor(object):

    def __init__(self, index, warehouse, session=None, store=None, store_prefix=None, *args, **kwargs):
        super(Processor, self).__init__(*args, **kwargs)

        if session is None:
            session = requests.session()

        self.session = session

        self.client = xmlrpc2.client.Client(index, session=self.session)
        self.warehouse = warehouse
        self.store = store
        self.store_prefix = store_prefix

    def get_releases(self, name, version=None):
        if version is None:
            versions = self.client.package_releases(name, True)

            if isinstance(versions, basestring):
                versions = [versions]
        else:
            versions = [version]

        for version in versions:
            item = self.client.release_data(name, version)
            url = self.client.release_urls(item["name"], item["version"])

            if isinstance(url, collections.Mapping):
                urls = [url]
            elif isinstance(url, collections.Iterable):
                urls = url
            else:
                raise RuntimeError("Do not understand the type returned by release_urls")

            # fix classifiers
            item["classifiers"] = sorted(set(get(item, "classifiers", [])))

            files = []

            oldest = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)

            for url in urls:
                data = url.copy()

                try:
                    resp = self.session.get(data["url"], prefetch=True)
                    resp.raise_for_status()
                except Exception:
                    # @@@ Catch the proper exceptions (and do what?)
                    raise

                if oldest > data["upload_time"]:
                    oldest = data["upload_time"]

                data["file_data"] = base64.b64encode(resp.content)
                files.append(data)

            item.update({
                "normalized": _normalize_regex.sub("-", item["name"]).lower(),
                "files": files,
            })

            if files:
                item["guessed_creation"] = oldest

            # Clean up some of the fields that we don't use
            remove_fields = set([
                "_pypi_hidden",
                "_pypi_ordering",
                "cheesecake_code_kwalitee_id",
                "cheesecake_documentation_id",
                "cheesecake_installability_id",
            ])

            item = dict([(k, v) for k, v in item.items() if k not in remove_fields])

            yield item

    def get_or_create_project(self, project):
        normalized = _normalize_regex.sub("-", project).lower()

        # Get or Create Project
        try:
            # Get
            project = self.warehouse.projects(normalized).get()
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            # Create
            project_data = {"name": project}
            project = self.warehouse.projects.post(project_data)

        return project

    def get_and_update_or_create_version(self, release, project):
        version_data = self.to_warehouse_version(release, extra={"project": project["resource_uri"]})

        try:
            # GET
            version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get()
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            # Create
            version = self.warehouse.projects(release["normalized"]).versions().post(version_data)
        else:
            # Update
            version["classifiers"] = sorted(version["classifiers"])
            diff = DictDiffer(version_data, version)
            different = diff.added() | diff.changed() | diff.removed() - (EXPECTED | set(["files"]))

            if "created" in different and not version.get("files", None):
                # The created time is a guess because we don't have any uploaded files
                different.remove("created")

            if different:
                logger.info(
                    "Updating the version for '%s' version '%s'. warehouse: '%s' updated: '%s'",
                    release["name"],
                    release["version"],
                    dict([(k, v) for k, v in version.items() if k in different]),
                    dict([(k, v) for k, v in version_data.items() if k in different]),
                )
                self.warehouse.projects(release["normalized"]).versions(release["version"]).put(version_data)
                version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get()

        return version

    def _compute_hash(self, release):
        def _dict_constant_data_structure(dictionary):
            data = []

            for k, v in dictionary.items():
                if isinstance(v, dict):
                    v = _dict_constant_data_structure(v)
                elif isinstance(v, set):
                    v = sorted(v)
                data.append([k, v])

            return sorted(data, key=lambda x: x[0])

        if not hasattr(self, "_computed_hash"):
            self._computed_hash = hashlib.sha512(json.dumps(
                                                    _dict_constant_data_structure(release),
                                                    default=lambda obj: obj.isoformat() if hasattr(obj, "isoformat") else obj)
                                                ).hexdigest()[:32]

        return self._computed_hash

    def release_changed(self, release):
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (release["name"], release["version"]))

        stored_hash = self.store.get(key)
        computed_hash = self._compute_hash(release)

        return not (stored_hash and stored_hash == computed_hash)

    def store_release_hash(self, release):
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (release["name"], release["version"]))
        self.store.set(key, self._compute_hash(release))

    def sync_release(self, release):
        if "/" in release["version"]:
            # We cannot accept versions with a / in it.
            logger.error("Skipping '%s' version '%s' because it contains a '/'", release["name"], release["version"])
            return

        if not self.release_changed(release):
            logger.info("Skipping '%s' version '%s' because it has not changed", release["name"], release["version"])
            return

        logger.info("Syncing '%s' version '%s'", release["name"], release["version"])

        project = self.get_or_create_project(release["name"])
        version = self.get_and_update_or_create_version(release, project)

        # @@@ Check warehouse for a list of files that this version has and delete any ones
        #      that no longer exist.

        _version = self.warehouse.projects(release["normalized"]).versions(release["version"]).get(full=True)

        warehouse_files = set([x["filename"] for x in _version["files"]])
        local_files = set([x["filename"] for x in release["files"]])

        deleted = warehouse_files - local_files

        for filename in deleted:
            logger.info("Deleting the file '%s' from '%s' version '%s'", filename, release["name"], release["version"])
            self.warehouse.projects(release["normalized"]).versions(release["version"]).files(filename).delete()

        for f in release["files"]:
            file_data = self.to_warehouse_file(release, f, extra={"version": version["resource_uri"]})

            try:
                # Get
                vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).get()
            except slumber.exceptions.HttpClientError as e:
                if not e.response.status_code == 404:
                    raise

                # Create
                vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files.post(file_data)
            else:
                # Update
                diff = DictDiffer(file_data, vfile)
                different = diff.added() | (diff.changed() - set(["file"])) | (diff.removed() - EXPECTED)

                if different:
                    logger.info(
                        "Updating the file '%s' for '%s' version '%s'. warehouse: '%s' updated: '%s'",
                        f["filename"],
                        release["name"],
                        release["version"],
                        dict([(k, v) for k, v in vfile.items() if k in different]),
                        dict([(k, v) for k, v in file_data.items() if k in different]),
                    )
                    self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).put(file_data)
                    vfile = self.warehouse.projects(release["normalized"]).versions(release["version"]).files(f["filename"]).get()

        self.store_release_hash(release)

    def to_warehouse_version(self, release, extra=None):
        data = {
            "version": release["version"],

            "summary": get(release, "summary", ""),
            "description": get(release, "description", ""),
            "license": get(release, "license", ""),

            "author": {},
            "maintainer": {},

            "classifiers": get(release, "classifiers", []),
            "uris": {},

            "requires_python": get(release, "requires_python", ""),
            "requires_external": get(release, "requires_external", []),

            "platforms": [],
            "supported_platforms": [],
            "keywords": [],

            "yanked": False,
        }

        if get(release, "author", None):
            data["author"]["name"] = release["author"]

        if get(release, "author_email", None):
            data["author"]["email"] = release["author_email"]

        if get(release, "maintainer", None):
            data["maintainer"]["name"] = release["maintainer"]

        if get(release, "maintainer_email", None):
            data["maintainer"]["email"] = release["maintainer_email"]

        if get(release, "download_url"):
            data["uris"]["Download"] = release["download_url"]

        if get(release, "home_page"):
            data["uris"]["Home page"] = release["home_page"]

        if get(release, "bugtrack_url"):
            data["uris"]["Bug tracker"] = release["bugtrack_url"]

        if get(release, "docs_url"):
            data["uris"]["Documentation"] = release["docs_url"]

        if get(release, "platform"):
            platforms = get(release, "platform")

            if isinstance(platforms, basestring):
                platforms = [platforms]

            data["platforms"] = platforms

        if get(release, "supported_platforms"):
            supported_platforms = get(release, "supported_platforms")

            if isinstance(supported_platforms, basestring):
                supported_platforms = [supported_platforms]

            data["supported_platforms"] = supported_platforms

        if get(release, "keywords"):
            keywords = get(release, "keywords")

            # Check for a comma
            if "," in keywords:
                keywords = [x.strip() for x in keywords.split(",")]
            else:
                keywords = [x.strip() for x in keywords.split()]

            data["keywords"] = keywords

        for url in get(release, "project_url", []):
            label, uri = url.split(",", 1)
            data["uris"][label] = uri

        data["requires"] = [split_meta(req) for req in get(release, "requires_dist", [])]
        data["provides"] = [split_meta(req) for req in get(release, "provides_dist", [])]
        data["obsoletes"] = [split_meta(req) for req in get(release, "obsoletes_dist", [])]

        if get(release, "guessed_creation", None) is not None:
            data["created"] = release["guessed_creation"].isoformat()

        if extra is not None:
            data.update(extra)

        return data

    def to_warehouse_file(self, release, file, extra=None):
        data = {
            "file": {"name": file["filename"], "file": file["file_data"]},
            "created": file["upload_time"].isoformat(),
            "type": file["packagetype"],
            "python_version": file["python_version"],
            "comment": file["comment_text"],

            "yanked": False,
        }

        raw_data = base64.b64decode(file["file_data"])

        data.update({
            "digests": {
                "md5": hashlib.md5(raw_data).hexdigest(),
                "sha256": hashlib.sha256(raw_data).hexdigest(),
            },
            "filesize": len(raw_data),
            "filename": file["filename"],
        })

        if extra is not None:
            data.update(extra)

        return data

    def get_warehouse_releases(self, package):
        normalized = _normalize_regex.sub("-", package).lower()

        try:
            project = self.warehouse.projects(normalized).get(full=True)
        except slumber.exceptions.HttpClientError as e:
            if not e.response.status_code == 404:
                raise

            return set()

        return set([x["version"] for x in project["versions"]])

    def delete_project_version(self, package, version):
        normalized = _normalize_regex.sub("-", package).lower()
        key = get_key(self.store_prefix, "pypi:process:%s:%s" % (package, version))

        logger.info("Deleting version '%s' of '%s'", version, package)

        self.store.delete(key)
        self.warehouse.projects(normalized).versions(version).delete()

    def delete_project(self, project):
        normalized = _normalize_regex.sub("-", project).lower()
        search_key = get_key(self.store_prefix, "pypi:process:%s:*" % project)

        logger.info("Deleting '%s'", project)

        for k in self.store.keys(search_key):
            self.store.delete(k)

        self.warehouse.projects(normalized).delete()

    def process(self):
        # @@@ Handle Deletion

        logger.info("Starting changed projects synchronization")

        current = time.mktime(datetime.datetime.utcnow().timetuple())

        since = int(float(self.store.get(get_key(self.store_prefix, "pypi:since")))) - 10

        names = set([(c[0], c[1]) for c in self.client.changelog(since)])

        for package in names:
            for release in self.get_releases(package[0], version=package[1]):
                self.sync_release(release)

        self.store.set(get_key(self.store_prefix, "pypi:since"), current)

        logger.info("Finished changed projects synchronization")
<|endoftext|>


<commit_before>from Adafruit_BME280 import *
import paho.mqtt.client as paho
import veml6070
import time

broker = "127.0.0.1"
port = 1883

def on_publish(client, userdata, result):  # create function for callback
    print("data published \n")
    pass

def main():
    sensor = BME280(p_mode=BME280_OSAMPLE_8, t_mode=BME280_OSAMPLE_2, h_mode=BME280_OSAMPLE_1, filter=BME280_FILTER_16)
    tstart = time.time()
    client1 = paho.Client("control1")  # create client object
    client1.on_publish = on_publish  # assign function to callback
    client1.connect(broker, port)  # establish connection
    veml = veml6070.Veml6070()
    veml.set_integration_time(veml6070.INTEGRATIONTIME_1T)

    while True:
        vreme = time.strftime("%H:%M:%S")
        degrees = sensor.read_temperature()
        pascals = sensor.read_pressure()
        hectopascals = pascals / 100
        humidity = sensor.read_humidity()
        dew_point = sensor.read_dewpoint()
        uv_raw = veml.get_uva_light_intensity_raw()
        uv = veml.get_uva_light_intensity()
        ret = client1.publish("sensors/temperature", "%0.3f" % (degrees))
        ret = client1.publish("sensors/pressure", "%0.3f" % (hectopascals))
        ret = client1.publish("sensors/humidity", "%0.3f" % (humidity))
        ret = client1.publish("sensors/dewpoint", "%0.3f" % (dew_point))
        ret = client1.publish("sensors/uv", "%0.3f" % (uv))
        ret = client1.publish("sensors/uv_raw", "%0.3f" % (uv_raw))

        file_t = open("temperature.txt", "rw")
        file_p = open("pressure.txt", "rw")
        file_h = open("humidity.txt", "rw")
        file_uv = open("uv.txt", "rw")

        file_t.write("%s" % vreme + " %0.3f" % degrees + "\n")
        file_p.write("%s" % vreme + " %0.3f" % hectopascals + "\n")
        file_h.write("%s" % vreme + " %0.3f" % humidity + "\n")
        file_uv.write("%s" % vreme + " %0.3f" % uv + "\n")

        file_t.close()
        file_p.close()
        file_h.close()
        file_uv.close()

        time.sleep(3)

main()
<commit_msg>sdfgsdgs<commit_after>from Adafruit_BME280 import *
import paho.mqtt.client as paho
import veml6070
import time

broker = "127.0.0.1"
port = 1883

def on_publish(client, userdata, result):  # create function for callback
    print("data published \n")
    pass

def main():
    sensor = BME280(p_mode=BME280_OSAMPLE_8, t_mode=BME280_OSAMPLE_2, h_mode=BME280_OSAMPLE_1, filter=BME280_FILTER_16)
    tstart = time.time()
    client1 = paho.Client("control1")  # create client object
    client1.on_publish = on_publish  # assign function to callback
    client1.connect(broker, port)  # establish connection
    veml = veml6070.Veml6070()
    veml.set_integration_time(veml6070.INTEGRATIONTIME_1T)

    file_t = open("temperature.txt", "rw")
    file_p = open("pressure.txt", "rw")
    file_h = open("humidity.txt", "rw")
    file_uv = open("uv.txt", "rw")

    while True:
        vreme = time.strftime("%H:%M:%S")
        degrees = sensor.read_temperature()
        pascals = sensor.read_pressure()
        hectopascals = pascals / 100
        humidity = sensor.read_humidity()
        dew_point = sensor.read_dewpoint()
        uv_raw = veml.get_uva_light_intensity_raw()
        uv = veml.get_uva_light_intensity()
        ret = client1.publish("sensors/temperature", "%0.3f" % (degrees))
        ret = client1.publish("sensors/pressure", "%0.3f" % (hectopascals))
        ret = client1.publish("sensors/humidity", "%0.3f" % (humidity))
        ret = client1.publish("sensors/dewpoint", "%0.3f" % (dew_point))
        ret = client1.publish("sensors/uv", "%0.3f" % (uv))
        ret = client1.publish("sensors/uv_raw", "%0.3f" % (uv_raw))

        file_t.write("%s" % vreme + " %0.3f" % degrees + "\n")
        file_p.write("%s" % vreme + " %0.3f" % hectopascals + "\n")
        file_h.write("%s" % vreme + " %0.3f" % humidity + "\n")
        file_uv.write("%s" % vreme + " %0.3f" % uv + "\n")

        time.sleep(3)

main()
<|endoftext|>


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

"""Functions for discovering and executing various cookiecutter hooks."""

import errno
import io
import logging
import os
import subprocess
import sys
import tempfile

from jinja2 import Template

from cookiecutter import utils
from .exceptions import FailedHookException

logger = logging.getLogger(__name__)

_HOOKS = [
    'pre_gen_project',
    'post_gen_project',
]
EXIT_SUCCESS = 0

def valid_hook(hook_file, hook_name):
    """Determine if a hook file is valid.

    :param hook_file: The hook file to consider for validity
    :param hook_name: The hook to find
    :return: The hook file validity
    """
    filename = os.path.basename(hook_file)
    basename = os.path.splitext(filename)[0]

    matching_hook = basename == hook_name
    supported_hook = basename in _HOOKS
    backup_file = filename.endswith('~')

    return matching_hook and supported_hook and not backup_file

def find_hook(hook_name, hooks_dir='hooks'):
    """Return a dict of all hook scripts provided.

    Must be called with the project template as the current working directory.
    Dict's key will be the hook/script's name, without extension, while values
    will be the absolute path to the script. Missing scripts will not be
    included in the returned dict.

    :param hook_name: The hook to find
    :param hooks_dir: The hook directory in the template
    :return: The absolute path to the hook script or None
    """
    logger.debug('hooks_dir is {}'.format(os.path.abspath(hooks_dir)))

    if not os.path.isdir(hooks_dir):
        logger.debug('No hooks/ dir in template_dir')
        return None

    for hook_file in os.listdir(hooks_dir):
        if valid_hook(hook_file, hook_name):
            return os.path.abspath(os.path.join(hooks_dir, hook_file))

    return None

def run_script(script_path, cwd='.'):
    """Execute a script from a working directory.

    :param script_path: Absolute path to the script to run.
    :param cwd: The directory to run the script from.
    """
    run_thru_shell = sys.platform.startswith('win')
    if script_path.endswith('.py'):
        script_command = [sys.executable, script_path]
    else:
        script_command = [script_path]

    utils.make_executable(script_path)

    try:
        proc = subprocess.Popen(
            script_command,
            shell=run_thru_shell,
            cwd=cwd
        )
        exit_status = proc.wait()
        if exit_status != EXIT_SUCCESS:
            raise FailedHookException(
                "Hook script failed (exit status: %d)" % exit_status)
    except OSError as oe:
        if oe.errno == errno.ENOEXEC:
            raise FailedHookException(
                "Hook script failed, might be an "
                "empty file or missing a shebang")
        raise FailedHookException(
            "Hook script failed (error: %s)" % oe)

def run_script_with_context(script_path, cwd, context):
    """Execute a script after rendering it with Jinja.

    :param script_path: Absolute path to the script to run.
    :param cwd: The directory to run the script from.
    :param context: Cookiecutter project template context.
    """
    _, extension = os.path.splitext(script_path)

    contents = io.open(script_path, 'r', encoding='utf-8').read()

    with tempfile.NamedTemporaryFile(
        delete=False,
        mode='wb',
        suffix=extension
    ) as temp:
        output = Template(contents).render(**context)
        temp.write(output.encode('utf-8'))

    run_script(temp.name, cwd)

def run_hook(hook_name, project_dir, context):
    """
    Try to find and execute a hook from the specified project directory.

    :param hook_name: The hook to execute.
    :param project_dir: The directory to execute the script from.
    :param context: Cookiecutter project context.
    """
    script = find_hook(hook_name)
    if script is None:
        logger.debug('No hooks found')
        return
    logger.debug('Running hook {}'.format(hook_name))
    run_script_with_context(script, project_dir, context)
<commit_msg>Use str.format for string interpolation<commit_after># -*- coding: utf-8 -*-

"""Functions for discovering and executing various cookiecutter hooks."""

import errno
import io
import logging
import os
import subprocess
import sys
import tempfile

from jinja2 import Template

from cookiecutter import utils
from .exceptions import FailedHookException

logger = logging.getLogger(__name__)

_HOOKS = [
    'pre_gen_project',
    'post_gen_project',
]
EXIT_SUCCESS = 0

def valid_hook(hook_file, hook_name):
    """Determine if a hook file is valid.

    :param hook_file: The hook file to consider for validity
    :param hook_name: The hook to find
    :return: The hook file validity
    """
    filename = os.path.basename(hook_file)
    basename = os.path.splitext(filename)[0]

    matching_hook = basename == hook_name
    supported_hook = basename in _HOOKS
    backup_file = filename.endswith('~')

    return matching_hook and supported_hook and not backup_file

def find_hook(hook_name, hooks_dir='hooks'):
    """Return a dict of all hook scripts provided.

    Must be called with the project template as the current working directory.
    Dict's key will be the hook/script's name, without extension, while values
    will be the absolute path to the script. Missing scripts will not be
    included in the returned dict.

    :param hook_name: The hook to find
    :param hooks_dir: The hook directory in the template
    :return: The absolute path to the hook script or None
    """
    logger.debug('hooks_dir is {}'.format(os.path.abspath(hooks_dir)))

    if not os.path.isdir(hooks_dir):
        logger.debug('No hooks/ dir in template_dir')
        return None

    for hook_file in os.listdir(hooks_dir):
        if valid_hook(hook_file, hook_name):
            return os.path.abspath(os.path.join(hooks_dir, hook_file))

    return None

def run_script(script_path, cwd='.'):
    """Execute a script from a working directory.

    :param script_path: Absolute path to the script to run.
    :param cwd: The directory to run the script from.
    """
    run_thru_shell = sys.platform.startswith('win')
    if script_path.endswith('.py'):
        script_command = [sys.executable, script_path]
    else:
        script_command = [script_path]

    utils.make_executable(script_path)

    try:
        proc = subprocess.Popen(
            script_command,
            shell=run_thru_shell,
            cwd=cwd
        )
        exit_status = proc.wait()
        if exit_status != EXIT_SUCCESS:
            raise FailedHookException(
                'Hook script failed (exit status: {})'.format(exit_status)
            )
    except OSError as os_error:
        if os_error.errno == errno.ENOEXEC:
            raise FailedHookException(
                'Hook script failed, might be an '
                'empty file or missing a shebang'
            )
        raise FailedHookException(
            'Hook script failed (error: {})'.format(os_error)
        )

def run_script_with_context(script_path, cwd, context):
    """Execute a script after rendering it with Jinja.

    :param script_path: Absolute path to the script to run.
    :param cwd: The directory to run the script from.
    :param context: Cookiecutter project template context.
    """
    _, extension = os.path.splitext(script_path)

    contents = io.open(script_path, 'r', encoding='utf-8').read()

    with tempfile.NamedTemporaryFile(
        delete=False,
        mode='wb',
        suffix=extension
    ) as temp:
        output = Template(contents).render(**context)
        temp.write(output.encode('utf-8'))

    run_script(temp.name, cwd)

def run_hook(hook_name, project_dir, context):
    """
    Try to find and execute a hook from the specified project directory.

    :param hook_name: The hook to execute.
    :param project_dir: The directory to execute the script from.
    :param context: Cookiecutter project context.
    """
    script = find_hook(hook_name)
    if script is None:
        logger.debug('No hooks found')
        return
    logger.debug('Running hook {}'.format(hook_name))
    run_script_with_context(script, project_dir, context)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Cool tools
~~~~~~~~~~

The tools for your .cool's.

:copyright: (c) 2017 Massachusetts Institute of Technology
:author: Mirny Lab
:license: BSD

"""
import logging
__version__ = '0.2.0'

from . import io
from . import lib
from .lib import numutils
<commit_msg>Version bump<commit_after># -*- coding: utf-8 -*-
"""
Cool tools
~~~~~~~~~~

The tools for your .cool's.

:copyright: (c) 2017 Massachusetts Institute of Technology
:author: Mirny Lab
:license: BSD

"""
import logging
__version__ = '0.3.0'

from . import io
from . import lib
from .lib import numutils
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
from sys import argv

class Memes:
    """
    Meme commands
    """
    def __init__(self, bot):
        self.bot = bot
        print('Addon "{}" loaded'.format(self.__class__.__name__))

    async def _meme(self, ctx, msg):
        author = ctx.message.author
        if ctx.message.channel.name[0:5] == "help-" or "assistance" in ctx.message.channel.name or (self.bot.nomemes_role in author.roles):
            await self.bot.delete_message(ctx.message)
            try:
                await self.bot.send_message(author, "Meme commands are disabled in this channel, or your privileges have been revoked.")
            except discord.errors.Forbidden:
                await self.bot.say(author.mention + " Meme commands are disabled in this channel, or your privileges have been revoked.")
        else:
            await self.bot.say(self.bot.escape_name(ctx.message.author.display_name) + ": " + msg)

    # list memes
    @commands.command(name="listmemes", pass_context=True)
    async def _listmemes(self, ctx):
        """List meme commands."""
        # this feels wrong...
        funcs = dir(self)
        msg = "```\n"
        msg += ", ".join(func for func in funcs if func != "bot" and func[0] != "_")
        msg += "```"
        await self._meme(ctx, msg)

    # 3dshacks memes
    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def s_99(self, ctx):
        """Memes."""
        await self._meme(ctx, "**ALL HAIL BRITANNIA!**")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def screams(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/j0Dkv2Z.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def eeh(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/2SBC1Qo.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def dubyadud(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/Sohsi8s.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def megumi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/GMRp1dj.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori(self, ctx):
        """Memes."""
        await self._meme(ctx, "https://i.imgur.com/WLncIsi.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori3(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/so8thgu.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori4(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/267IXh1.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori5(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/lKcsiBP.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori6(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/SIJzpau.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def shotsfired(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/zf2XrNk.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def rusure(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/dqh3fNi.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def r34(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/sjQZKBF.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lenny(self, ctx):
        """Memes."""
        await self._meme(ctx, "( ͡° ͜ʖ ͡°)")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def rip(self, ctx):
        """Memes."""
        await self._meme(ctx, "Press F to pay respects.")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def permabrocked(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/ARsOh3p.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def knp(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/EsJ191C.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lucina(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/tnWSXf7.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lucina2(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/ZPMveve.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def xarec(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/A59RbRT.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def clap(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/UYbIZYs.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def ayyy(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/bgvuHAd.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def hazel(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/vpu8bX3.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def thumbsup(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/hki1IIs.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def pbanjo(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/sBJKzuK.png")

    # Cute commands :3
    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headpat(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/7V6gIIW.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headpat2(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/djhHX0n.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def sudoku(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/VHlIZRC.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def baka(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/OyjCHNe.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def mugi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/lw80tT0.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lisp(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/RQeZErU.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def dev(self, ctx):
        """Reminds user where they are."""
        await self.bot.say("You seem to be in <#196635781798952960>.")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headrub(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/j6xSoKv.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def blackalabi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/JzFem4y.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def nom(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/p1r53ni.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def soghax(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/oQJy2eN.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def whatisr(self, ctx):
        """MEMES?"""
        await self._meme(ctx, "http://i.imgur.com/Z8HhfzJ.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def helpers(self, ctx):
        """MEMES?"""
        await self._meme(ctx, "http://i.imgur.com/0v1EgMX.png")

# Load the extension
def setup(bot):
    bot.add_cog(Memes(bot))
<commit_msg>you seem to be in dev<commit_after>import discord
from discord.ext import commands
from sys import argv

class Memes:
    """
    Meme commands
    """
    def __init__(self, bot):
        self.bot = bot
        print('Addon "{}" loaded'.format(self.__class__.__name__))

    async def _meme(self, ctx, msg):
        author = ctx.message.author
        if ctx.message.channel.name[0:5] == "help-" or "assistance" in ctx.message.channel.name or (self.bot.nomemes_role in author.roles):
            await self.bot.delete_message(ctx.message)
            try:
                await self.bot.send_message(author, "Meme commands are disabled in this channel, or your privileges have been revoked.")
            except discord.errors.Forbidden:
                await self.bot.say(author.mention + " Meme commands are disabled in this channel, or your privileges have been revoked.")
        else:
            await self.bot.say(self.bot.escape_name(ctx.message.author.display_name) + ": " + msg)

    # list memes
    @commands.command(name="listmemes", pass_context=True)
    async def _listmemes(self, ctx):
        """List meme commands."""
        # this feels wrong...
        funcs = dir(self)
        msg = "```\n"
        msg += ", ".join(func for func in funcs if func != "bot" and func[0] != "_")
        msg += "```"
        await self._meme(ctx, msg)

    # 3dshacks memes
    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def s_99(self, ctx):
        """Memes."""
        await self._meme(ctx, "**ALL HAIL BRITANNIA!**")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def screams(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/j0Dkv2Z.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def eeh(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/2SBC1Qo.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def dubyadud(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/Sohsi8s.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def megumi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/GMRp1dj.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori(self, ctx):
        """Memes."""
        await self._meme(ctx, "https://i.imgur.com/WLncIsi.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori3(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/so8thgu.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori4(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/267IXh1.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori5(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/lKcsiBP.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def inori6(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/SIJzpau.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def shotsfired(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/zf2XrNk.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def rusure(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/dqh3fNi.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def r34(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/sjQZKBF.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lenny(self, ctx):
        """Memes."""
        await self._meme(ctx, "( ͡° ͜ʖ ͡°)")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def rip(self, ctx):
        """Memes."""
        await self._meme(ctx, "Press F to pay respects.")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def permabrocked(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/ARsOh3p.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def knp(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/EsJ191C.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lucina(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/tnWSXf7.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lucina2(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/ZPMveve.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def xarec(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/A59RbRT.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def clap(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/UYbIZYs.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def ayyy(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/bgvuHAd.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def hazel(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/vpu8bX3.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def thumbsup(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/hki1IIs.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def pbanjo(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/sBJKzuK.png")

    # Cute commands :3
    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headpat(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/7V6gIIW.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headpat2(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/djhHX0n.gifv")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def sudoku(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/VHlIZRC.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def baka(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/OyjCHNe.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def mugi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/lw80tT0.gif")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def lisp(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/RQeZErU.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def dev(self, ctx):
        """Reminds user where they are."""
        await self.bot.say("You {}seem to be in <#196635781798952960>.".format("do not " if ctx.message.channel.name != "dev" else ""))

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def headrub(self, ctx):
        """Cute"""
        await self._meme(ctx, "http://i.imgur.com/j6xSoKv.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def blackalabi(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/JzFem4y.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def nom(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/p1r53ni.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def soghax(self, ctx):
        """Memes."""
        await self._meme(ctx, "http://i.imgur.com/oQJy2eN.png")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def whatisr(self, ctx):
        """MEMES?"""
        await self._meme(ctx, "http://i.imgur.com/Z8HhfzJ.jpg")

    @commands.command(pass_context=True, hidden=True)
    @commands.cooldown(rate=1, per=5.0, type=commands.BucketType.channel)
    async def helpers(self, ctx):
        """MEMES?"""
        await self._meme(ctx, "http://i.imgur.com/0v1EgMX.png")

# Load the extension
def setup(bot):
    bot.add_cog(Memes(bot))
<|endoftext|>