<commit_before>#!/usr/bin/env python

import markdown
import os
import re
import shutil
import sys

root_dir = os.path.dirname(__file__)
docs_dir = os.path.join(root_dir, 'docs')
html_dir = os.path.join(root_dir, 'html')

local = not '--deploy' in sys.argv

if local:
    base_url = 'file://%s/' % os.path.normpath(os.path.join(os.getcwd(), html_dir))
    suffix = '.html'
    index = 'index.html'
else:
    base_url = 'http://tomchristie.github.com/django-rest-framework'
    suffix = ''
    index = ''

main_header = '
{{ title }}
'
sub_header = '
{{ title }}
'

page = open(os.path.join(docs_dir, 'template.html'), 'r').read()

# Copy static files
for static in ['css', 'js']:
    source = os.path.join(docs_dir, 'static', static)
    target = os.path.join(html_dir, static)
    if os.path.exists(target):
        shutil.rmtree(target)
    shutil.copytree(source, target)

for (dirpath, dirnames, filenames) in os.walk(docs_dir):
    for filename in filenames:
        if not filename.endswith('.md'):
            continue

        toc = ''
        text = open(os.path.join(dirpath, filename), 'r').read().decode('utf-8')
        for line in text.splitlines():
            if line.startswith('# '):
                title = line[2:].strip()
                template = main_header
            elif line.startswith('## '):
                title = line[3:].strip()
                template = sub_header
            else:
                continue

            anchor = title.lower().replace(' ', '-').replace(':-', '-').replace("'", '').replace('?', '').replace('.', '')
            template = template.replace('{{ title }}', title)
            template = template.replace('{{ anchor }}', anchor)
            toc += template + '\n'

        content = markdown.markdown(text, ['headerid'])

        build_dir = os.path.join(html_dir, dirpath.lstrip(docs_dir))
        build_file = os.path.join(build_dir, filename[:-3] + '.html')

        if not os.path.exists(build_dir):
            os.makedirs(build_dir)
        output = page.replace('{{ content }}', content).replace('{{ toc }}', toc).replace('{{ base_url }}', base_url).replace('{{ suffix }}', suffix).replace('{{ index }}', index)
        output = re.sub(r'a href="([^"]*)\.md"', r'a href="\1.html"', output)
        open(build_file, 'w').write(output.encode('utf-8'))
<commit_msg>Fix up index suffixes<commit_after>#!/usr/bin/env python

import markdown
import os
import re
import shutil
import sys

root_dir = os.path.dirname(__file__)
docs_dir = os.path.join(root_dir, 'docs')
html_dir = os.path.join(root_dir, 'html')

local = not '--deploy' in sys.argv

if local:
    base_url = 'file://%s/' % os.path.normpath(os.path.join(os.getcwd(), html_dir))
    suffix = '.html'
    index = 'index.html'
else:
    base_url = 'http://tomchristie.github.com/django-rest-framework'
    suffix = ''
    index = ''

main_header = '
{{ title }}
'
sub_header = '
{{ title }}
'

page = open(os.path.join(docs_dir, 'template.html'), 'r').read()

# Copy static files
for static in ['css', 'js']:
    source = os.path.join(docs_dir, 'static', static)
    target = os.path.join(html_dir, static)
    if os.path.exists(target):
        shutil.rmtree(target)
    shutil.copytree(source, target)

for (dirpath, dirnames, filenames) in os.walk(docs_dir):
    for filename in filenames:
        if not filename.endswith('.md'):
            continue

        toc = ''
        text = open(os.path.join(dirpath, filename), 'r').read().decode('utf-8')
        for line in text.splitlines():
            if line.startswith('# '):
                title = line[2:].strip()
                template = main_header
            elif line.startswith('## '):
                title = line[3:].strip()
                template = sub_header
            else:
                continue

            anchor = title.lower().replace(' ', '-').replace(':-', '-').replace("'", '').replace('?', '').replace('.', '')
            template = template.replace('{{ title }}', title)
            template = template.replace('{{ anchor }}', anchor)
            toc += template + '\n'

        content = markdown.markdown(text, ['headerid'])

        build_dir = os.path.join(html_dir, dirpath.lstrip(docs_dir))
        build_file = os.path.join(build_dir, filename[:-3] + '.html')

        if not os.path.exists(build_dir):
            os.makedirs(build_dir)
        output = page.replace('{{ content }}', content).replace('{{ toc }}', toc).replace('{{ base_url }}', base_url).replace('{{ suffix }}', suffix).replace('{{ index }}', index)
        output = re.sub(r'a href="([^"]*)\.md"', r'a href="\1%s"' % suffix, output)
        open(build_file, 'w').write(output.encode('utf-8'))
<|endoftext|>


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

# Copyright(C) 2010-2011 Romain Bignon
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.

from PyQt4.QtGui import QFrame, QImage, QPixmap

from weboob.tools.application.qt import QtDo
from weboob.applications.qvideoob.ui.minivideo_ui import Ui_MiniVideo
from .video import Video

class MiniVideo(QFrame):
    def __init__(self, weboob, backend, video, parent=None):
        QFrame.__init__(self, parent)
        self.ui = Ui_MiniVideo()
        self.ui.setupUi(self)

        self.weboob = weboob
        self.backend = backend
        self.video = video
        self.ui.titleLabel.setText(video.title)
        self.ui.backendLabel.setText(backend.name)
        self.ui.durationLabel.setText(unicode(video.duration))
        self.ui.authorLabel.setText(unicode(video.author))
        self.ui.dateLabel.setText(video.date and unicode(video.date) or '')
        if video.rating_max:
            self.ui.ratingLabel.setText('%s / %s' % (video.rating, video.rating_max))
        else:
            self.ui.ratingLabel.setText('%s' % video.rating)

        self.process_thumbnail = QtDo(self.weboob, self.gotThumbnail)
        self.process_thumbnail.do('fillobj', self.video, ['thumbnail'], backends=backend)

    def gotThumbnail(self, backend, video):
        if not backend:
            return

        if video.thumbnail and video.thumbnail.data:
            img = QImage.fromData(video.thumbnail.data)
            self.ui.imageLabel.setPixmap(QPixmap.fromImage(img))

    def enterEvent(self, event):
        self.setFrameShadow(self.Sunken)
        QFrame.enterEvent(self, event)

    def leaveEvent(self, event):
        self.setFrameShadow(self.Raised)
        QFrame.leaveEvent(self, event)

    def mousePressEvent(self, event):
        QFrame.mousePressEvent(self, event)

        video = self.backend.get_video(self.video.id)
        if video:
            video_widget = Video(video, self)
            video_widget.show()
<commit_msg>use fillobj instead of get_video to complete all fields<commit_after># -*- coding: utf-8 -*-

# Copyright(C) 2010-2011 Romain Bignon
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.

from PyQt4.QtGui import QFrame, QImage, QPixmap

from weboob.tools.application.qt import QtDo
from weboob.applications.qvideoob.ui.minivideo_ui import Ui_MiniVideo
from .video import Video

class MiniVideo(QFrame):
    def __init__(self, weboob, backend, video, parent=None):
        QFrame.__init__(self, parent)
        self.ui = Ui_MiniVideo()
        self.ui.setupUi(self)

        self.weboob = weboob
        self.backend = backend
        self.video = video
        self.ui.titleLabel.setText(video.title)
        self.ui.backendLabel.setText(backend.name)
        self.ui.durationLabel.setText(unicode(video.duration))
        self.ui.authorLabel.setText(unicode(video.author))
        self.ui.dateLabel.setText(video.date and unicode(video.date) or '')
        if video.rating_max:
            self.ui.ratingLabel.setText('%s / %s' % (video.rating, video.rating_max))
        else:
            self.ui.ratingLabel.setText('%s' % video.rating)

        self.process_thumbnail = QtDo(self.weboob, self.gotThumbnail)
        self.process_thumbnail.do('fillobj', self.video, ['thumbnail'], backends=backend)

    def gotThumbnail(self, backend, video):
        if not backend:
            return

        if video.thumbnail and video.thumbnail.data:
            img = QImage.fromData(video.thumbnail.data)
            self.ui.imageLabel.setPixmap(QPixmap.fromImage(img))

    def enterEvent(self, event):
        self.setFrameShadow(self.Sunken)
        QFrame.enterEvent(self, event)

    def leaveEvent(self, event):
        self.setFrameShadow(self.Raised)
        QFrame.leaveEvent(self, event)

    def mousePressEvent(self, event):
        QFrame.mousePressEvent(self, event)

        video = self.backend.fillobj(self.video)
        if video:
            video_widget = Video(video, self)
            video_widget.show()
<|endoftext|>


<commit_before>#!/usr/bin/python
'''*****************************************************************************************************************
    Pi Remind
    By John M. Wargo
    www.johnwargo.com

    This application connects to a Google Calendar and determines whether there are any appointments in the next
    few minutes and flashes some LEDs if there are. The project uses a Raspberry Pi 2 device with a Pimoroni
    Unicorn HAT (an 8x8 matrix of bright, multi-colored LEDs) to display an obnoxious reminder every minute, changing
    color at 10 minutes (white), 5 minutes (yellow) and 2 minutes (red).

    Google Calendar example code: https://developers.google.com/google-apps/calendar/quickstart/python
    Unicorn HAT example code: https://github.com/pimoroni/unicorn-hat/tree/master/python/examples
********************************************************************************************************************'''
# todo: Enforce business day start and end 8 AM to 6 PM?
# todo: Only flash lights if a reminder is set for the appointment
# todo: Implement an interesting pattern for the final appointment alert (swirly lights for example)
# todo: Add support for snooze button
# todo: Add support for cancel button

from __future__ import print_function

import colorsys
import datetime
import os
import sys
import time

import httplib2
import numpy as np
import oauth2client
import unicornhat as lights
from apiclient import discovery
from oauth2client import client
from oauth2client import tools

try:
    import argparse

    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# Google says: If modifying these scopes, delete your previously saved credentials at ~/.credentials/client_secret.json
# On the pi, it's in /root/.credentials/
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Pi Reminder'
CALENDAR_ID = 'primary'
HASH = '#'
HASHES = '########################################'

# Reminder thresholds
FIRST_THRESHOLD = 5  # minutes, white lights before this
# red for anything less than (and including) the second threshold
SECOND_THRESHOLD = 2  # minutes, yellow lights before this

def show_activity_light(status):
    global current_activity_light

    # Turning on or off?
    if status:
        # on
        if current_activity_light > 6:
            current_activity_light = -1
        # increment the current light
        current_activity_light += 1
        # set the pixel
        lights.set_pixel(current_activity_light, 0, 0, 128, 0)
        # show the pixel
        lights.show()
    else:
        lights.off()

def flash_all_lights(flash_count, delay, red, green, blue):
    for index in range(flash_count):
        for y in range(8):
            for x in range(8):
                lights.set_pixel(x, y, red, green, blue)
        lights.show()
        time.sleep(delay)
        lights.off()
        time.sleep(delay)

def flash_random_lights(flash_count, delay):
    # Copied from https://github.com/pimoroni/unicorn-hat/blob/master/python/examples/random_blinky.py
    for index in range(flash_count):
        rand_mat = np.random.rand(8, 8)
        for y in range(8):
            for x in range(8):
                h = 0.1 * rand_mat[x, y]
                s = 0.8
                v = rand_mat[x, y]
                rgb = colorsys.hsv_to_rgb(h, s, v)
                r = int(rgb[0] * 255.0)
                g = int(rgb[1] * 255.0)
                b = int(rgb[2] * 255.0)
                lights.set_pixel(x, y, r, g, b)
        lights.show()
        time.sleep(delay)
        lights.off()
        time.sleep(delay)

def get_credentials():
    # taken from https://developers.google.com/google-apps/calendar/quickstart/python
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        print('Creating', credential_dir)
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'pi_remind.json')
    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else:  # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to', credential_path)
    return credentials

def has_reminder(event):
    # Return true if there's a reminder set for the event
    # First, check to see if there is a default reminder set
    # Yes, I know I could have done this and the next check without using variables
    # this approach just makes the code easier to understand
    has_default_reminder = event['reminders'].get('useDefault')
    if has_default_reminder:
        # if yes, then we're good
        return True
    else:
        # are there overrides set for reminders?
        overrides = event['reminders'].get('overrides')
        if overrides:
            # OK, then we have a reminder to use
            return True
    # if we got this far, then there must not be a reminder set
    return False

def get_next_event(search_limit):
    # modified from https://developers.google.com/google-apps/calendar/quickstart/python
    # get all of the events on the calendar from now through 10 minutes from now
    print(datetime.datetime.now(), 'Getting next event')
    # this 'now' is in a different format (UTC)
    now = datetime.datetime.utcnow()
    then = now + datetime.timedelta(minutes=search_limit)
    # turn on a sequential green LED to show that you're requesting data from the Google Calendar API
    show_activity_light(True)
    try:
        # ask Google for the calendar entries
        events_result = service.events().list(
            # get all of them between now and 10 minutes from now
            calendarId=CALENDAR_ID,
            timeMin=now.isoformat() + 'Z',
            timeMax=then.isoformat() + 'Z',
            singleEvents=True,
            orderBy='startTime').execute()
        # turn off the green LED so you'll know data was returned from the Google calendar API
        show_activity_light(False)
        # Get the event list
        event_list = events_result.get('items', [])
        # did we get a return value?
        if not event_list:
            # no? Then no upcoming events at all, so nothing to do right now
            print(datetime.datetime.now(), 'No entries returned')
            return None
        else:
            # what time is it now?
            current_time = datetime.datetime.now()
            # loop through the events in the list
            for event in event_list:
                # we only care about events that have a start time
                start = event['start'].get('dateTime')
                # return the first event that has a start time
                # so, first, do we have a start time for this event?
                if start:
                    # When does the appointment start?
                    # Convert the string it into a Python dateTime object so we can do math on it
                    event_start = datetime.datetime.strptime(start, '%Y-%m-%dT%H:%M:%S-04:00')
                    # does the event start in the future?
                    if current_time < event_start:
                        # only use events that have a reminder set
                        if has_reminder(event):
                            # no? So we can use it
                            print('Found event:', event['summary'])
                            print('Event starts:', start)
                            # figure out how soon it starts
                            time_delta = event_start - current_time
                            # Round to the nearest minute and return with the object
                            event['num_minutes'] = time_delta.total_seconds() // 60
                            return event
    except:
        # well, something went wrong
        # light up the array with red LEDs to indicate a problem
        flash_all_lights(1, 2, 255, 0, 0)
        # not much else we can do here except to skip this attempt and try again later
        print('Error connecting to calendar:', sys.exc_info()[0], '\n')
    # if we got this far and haven't returned anything, then there's no appointments in the specified time
    # range, or we had an error, so...
    return None

def main():
    # initialize the lastMinute variable to the current time to start
    last_minute = datetime.datetime.now().minute
    # on startup, just use the previous minute as lastMinute
    if last_minute == 0:
        last_minute = 59
    else:
        last_minute -= 1

    # infinite loop to continuously check Google Calendar for future entries
    while 1:
        # get the current minute
        current_minute = datetime.datetime.now().minute
        # is it the same minute as the last time we checked?
        if current_minute != last_minute:
            # reset last_minute to the current_minute, of course
            last_minute = current_minute
            # we've moved a minute, so we have work to do
            # get the next calendar event (within the specified time limit [in minutes])
            next_event = get_next_event(10)
            # do we get an event?
            if next_event is not None:
                num_minutes = next_event['num_minutes']
                if num_minutes != 1:
                    print('Starts in', int(num_minutes), 'minutes\n')
                else:
                    print('Starts in 1.0 minute\n')
                # is the appointment between 10 and 5 minutes from now?
                if num_minutes >= FIRST_THRESHOLD:
                    # Flash the lights in white
                    flash_all_lights(1, 0.25, 255, 255, 255)
                # is the appointment less than 5 minutes but more than 2 minutes from now?
                elif num_minutes > SECOND_THRESHOLD:
                    # Flash the lights yellow
                    flash_all_lights(2, 0.25, 255, 255, 0)
                # hmmm, less than 2 minutes, almost time to start!
                else:
                    # flash the lights red
                    flash_all_lights(3, 0.25, 255, 0, 0)
        # wait a second then check again
        # You can always increase the sleep value below to check less often
        time.sleep(1)

    # this should never happen since the above is an infinite loop
    print('Leaving main()')

# now tell the user what we're doing...
print('\n')
print(HASHES)
print(HASH, 'Pi Remind                           ', HASH)
print(HASH, 'By John M. Wargo (www.johnwargo.com)', HASH)
print(HASHES)

# The app flashes a green light in the first row every time it connects to Google to check the calendar.
# The LED increments every time until it gets to the other side then starts over at the beginning again.
# The current_activity_light variable keeps track of which light lit last. At start it's at -1 and goes from there.
current_activity_light = -1

# Set a specific brightness level for the Pimoroni Unicorn HAT, otherwise it's pretty bright.
# Comment out the line below to see what the default looks like.
# lights.brightness(1)

# flash some random LEDs just for fun...
flash_random_lights(5, 0.1)
# blink all the LEDs green to let the user know the hardware is working
flash_all_lights(1, 1, 0, 128, 0)

# Initialize the Google Calendar API stuff
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)

print('\nApplication initialized\n')

# Now see what we're supposed to do next
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('\nExiting application\n')
        sys.exit(0)
<commit_msg>Added swirl pattern to last reminders<commit_after>#!/usr/bin/python
'''*****************************************************************************************************************
    Pi Remind
    By John M. Wargo
    www.johnwargo.com

    This application connects to a Google Calendar and determines whether there are any appointments in the next
    few minutes and flashes some LEDs if there are. The project uses a Raspberry Pi 2 device with a Pimoroni
    Unicorn HAT (an 8x8 matrix of bright, multi-colored LEDs) to display an obnoxious reminder every minute, changing
    color at 10 minutes (white), 5 minutes (yellow) and 2 minutes (red).

    Google Calendar example code: https://developers.google.com/google-apps/calendar/quickstart/python
    Unicorn HAT example code: https://github.com/pimoroni/unicorn-hat/tree/master/python/examples
********************************************************************************************************************'''
# todo: Enforce business day start and end 8 AM to 6 PM?
# todo: Only flash lights if a reminder is set for the appointment
# todo: Implement an interesting pattern for the final appointment alert (swirly lights for example)
# todo: Add support for snooze button
# todo: Add support for cancel button

from __future__ import print_function

import colorsys
import datetime
import math
import os
import sys
import time

import httplib2
import numpy as np
import oauth2client
import unicornhat as lights
from apiclient import discovery
from oauth2client import client
from oauth2client import tools

try:
    import argparse

    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

# Google says: If modifying these scopes, delete your previously saved credentials at ~/.credentials/client_secret.json
# On the pi, it's in /root/.credentials/
SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Pi Reminder'
CALENDAR_ID = 'primary'
HASH = '#'
HASHES = '########################################'

# Reminder thresholds
FIRST_THRESHOLD = 5  # minutes, white lights before this
# red for anything less than (and including) the second threshold
SECOND_THRESHOLD = 2  # minutes, yellow lights before this

def swirl(x, y, step):
    x -= 4
    y -= 4

    dist = math.sqrt(pow(x, 2) + pow(y, 2)) / 2.0
    angle = (step / 10.0) + (dist * 1.5)
    s = math.sin(angle);
    c = math.cos(angle);

    xs = x * c - y * s;
    ys = x * s + y * c;

    r = abs(xs + ys)
    r = r * 64.0
    r -= 20

    return (r, r + (s * 130), r + (c * 130))

def do_swirl():
    step = 0
    for i in range(100):
        for y in range(8):
            for x in range(8):
                r, g, b = swirl(x, y, step)
                r = int(max(0, min(255, r)))
                g = int(max(0, min(255, g)))
                b = int(max(0, min(255, b)))
                lights.set_pixel(x, y, r, g, b)
        step += 1
        lights.show()
        time.sleep(0.01)

def show_activity_light(status):
    global current_activity_light

    # Turning on or off?
    if status:
        # on
        if current_activity_light > 6:
            current_activity_light = -1
        # increment the current light
        current_activity_light += 1
        # set the pixel
        lights.set_pixel(current_activity_light, 0, 0, 128, 0)
        # show the pixel
        lights.show()
    else:
        lights.off()

def flash_all_lights(flash_count, delay, red, green, blue):
    for index in range(flash_count):
        for y in range(8):
            for x in range(8):
                lights.set_pixel(x, y, red, green, blue)
        lights.show()
        time.sleep(delay)
        lights.off()
        time.sleep(delay)

def flash_random_lights(flash_count, delay):
    # Copied from https://github.com/pimoroni/unicorn-hat/blob/master/python/examples/random_blinky.py
    for index in range(flash_count):
        rand_mat = np.random.rand(8, 8)
        for y in range(8):
            for x in range(8):
                h = 0.1 * rand_mat[x, y]
                s = 0.8
                v = rand_mat[x, y]
                rgb = colorsys.hsv_to_rgb(h, s, v)
                r = int(rgb[0] * 255.0)
                g = int(rgb[1] * 255.0)
                b = int(rgb[2] * 255.0)
                lights.set_pixel(x, y, r, g, b)
        lights.show()
        time.sleep(delay)
        lights.off()
        time.sleep(delay)

def get_credentials():
    # taken from https://developers.google.com/google-apps/calendar/quickstart/python
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        print('Creating', credential_dir)
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'pi_remind.json')
    store = oauth2client.file.Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else:  # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to', credential_path)
    return credentials

def has_reminder(event):
    # Return true if there's a reminder set for the event
    # First, check to see if there is a default reminder set
    # Yes, I know I could have done this and the next check without using variables
    # this approach just makes the code easier to understand
    has_default_reminder = event['reminders'].get('useDefault')
    if has_default_reminder:
        # if yes, then we're good
        return True
    else:
        # are there overrides set for reminders?
        overrides = event['reminders'].get('overrides')
        if overrides:
            # OK, then we have a reminder to use
            return True
    # if we got this far, then there must not be a reminder set
    return False

def get_next_event(search_limit):
    # modified from https://developers.google.com/google-apps/calendar/quickstart/python
    # get all of the events on the calendar from now through 10 minutes from now
    print(datetime.datetime.now(), 'Getting next event')
    # this 'now' is in a different format (UTC)
    now = datetime.datetime.utcnow()
    then = now + datetime.timedelta(minutes=search_limit)
    # turn on a sequential green LED to show that you're requesting data from the Google Calendar API
    show_activity_light(True)
    try:
        # ask Google for the calendar entries
        events_result = service.events().list(
            # get all of them between now and 10 minutes from now
            calendarId=CALENDAR_ID,
            timeMin=now.isoformat() + 'Z',
            timeMax=then.isoformat() + 'Z',
            singleEvents=True,
            orderBy='startTime').execute()
        # turn off the green LED so you'll know data was returned from the Google calendar API
        show_activity_light(False)
        # Get the event list
        event_list = events_result.get('items', [])
        # did we get a return value?
        if not event_list:
            # no? Then no upcoming events at all, so nothing to do right now
            print(datetime.datetime.now(), 'No entries returned')
            return None
        else:
            # what time is it now?
            current_time = datetime.datetime.now()
            # loop through the events in the list
            for event in event_list:
                # we only care about events that have a start time
                start = event['start'].get('dateTime')
                # return the first event that has a start time
                # so, first, do we have a start time for this event?
                if start:
                    # When does the appointment start?
                    # Convert the string it into a Python dateTime object so we can do math on it
                    event_start = datetime.datetime.strptime(start, '%Y-%m-%dT%H:%M:%S-04:00')
                    # does the event start in the future?
                    if current_time < event_start:
                        # only use events that have a reminder set
                        if has_reminder(event):
                            # no? So we can use it
                            print('Found event:', event['summary'])
                            print('Event starts:', start)
                            # figure out how soon it starts
                            time_delta = event_start - current_time
                            # Round to the nearest minute and return with the object
                            event['num_minutes'] = time_delta.total_seconds() // 60
                            return event
    except:
        # well, something went wrong
        # not much else we can do here except to skip this attempt and try again later
        print('Error connecting to calendar:', sys.exc_info()[0], '\n')
        # light up the array with red LEDs to indicate a problem
        flash_all_lights(1, 2, 255, 0, 0)
    # if we got this far and haven't returned anything, then there's no appointments in the specified time
    # range, or we had an error, so...
    return None

def main():
    # initialize the lastMinute variable to the current time to start
    last_minute = datetime.datetime.now().minute
    # on startup, just use the previous minute as lastMinute
    if last_minute == 0:
        last_minute = 59
    else:
        last_minute -= 1

    # infinite loop to continuously check Google Calendar for future entries
    while 1:
        # get the current minute
        current_minute = datetime.datetime.now().minute
        # is it the same minute as the last time we checked?
        if current_minute != last_minute:
            # reset last_minute to the current_minute, of course
            last_minute = current_minute
            # we've moved a minute, so we have work to do
            # get the next calendar event (within the specified time limit [in minutes])
            next_event = get_next_event(10)
            # do we get an event?
            if next_event is not None:
                num_minutes = next_event['num_minutes']
                if num_minutes != 1:
                    print('Starts in', int(num_minutes), 'minutes\n')
                else:
                    print('Starts in 1.0 minute\n')
                # is the appointment between 10 and 5 minutes from now?
                if num_minutes >= FIRST_THRESHOLD:
                    # Flash the lights in white
                    flash_all_lights(1, 0.25, 255, 255, 255)
                # is the appointment less than 5 minutes but more than 2 minutes from now?
                elif num_minutes > SECOND_THRESHOLD:
                    # Flash the lights yellow
                    flash_all_lights(2, 0.25, 255, 255, 0)
                # hmmm, less than 2 minutes, almost time to start!
                else:
                    do_swirl()
        # wait a second then check again
        # You can always increase the sleep value below to check less often
        time.sleep(1)

    # this should never happen since the above is an infinite loop
    print('Leaving main()')

# now tell the user what we're doing...
print('\n')
print(HASHES)
print(HASH, 'Pi Remind                           ', HASH)
print(HASH, 'By John M. Wargo (www.johnwargo.com)', HASH)
print(HASHES)

# The app flashes a green light in the first row every time it connects to Google to check the calendar.
# The LED increments every time until it gets to the other side then starts over at the beginning again.
# The current_activity_light variable keeps track of which light lit last. At start it's at -1 and goes from there.
current_activity_light = -1

# Set a specific brightness level for the Pimoroni Unicorn HAT, otherwise it's pretty bright.
# Comment out the line below to see what the default looks like.
# lights.brightness(1)

# flash some random LEDs just for fun...
flash_random_lights(5, 0.1)
# blink all the LEDs green to let the user know the hardware is working
flash_all_lights(1, 1, 0, 128, 0)

# Initialize the Google Calendar API stuff
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)

print('\nApplication initialized\n')

# Now see what we're supposed to do next
if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print('\nExiting application\n')
        sys.exit(0)
<|endoftext|>


<commit_before>from collections import namedtuple

import mwparserfromhell as mwp
from mwtypes import Timestamp
from nose.tools import eq_

from .. import enwiki

def test_extractor():

    Revision = namedtuple("Revisions", ['id', 'timestamp', 'sha1', 'text'])

    class Page:

        def __init__(self, title, namespace, revisions):
            self.title = title
            self.namespace = namespace
            self.revisions = revisions

        def __iter__(self):
            return iter(self.revisions)

    revisions = [
        Revision(
            1, Timestamp(0), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub}}..."
        ),
        Revision(
            2, Timestamp(1), "bbb",
            "{{talk page}}{{WikiProject Medicine|class=B}}..."
        ),
        Revision(
            3, Timestamp(2), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub<!--" +
            " test HTML comment -->}}..."
        ),
        Revision(
            4, Timestamp(3), "ccc",
            "{{talk page}}{{WikiProject Medicine|class=C}}..."
        ),
        Revision(
            5, Timestamp(4), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub}}..."
        ),
        Revision(
            6, Timestamp(4), "ccc",
            "{{talk page}}{{WikiProject Medicine|class= C}}..."
        ),
        Revision(
            7, Timestamp(5), "ddd",
            "{{talk page}}{{WikiProject Medicine|class=B}}\n" +
            "{{WP_Hats|class=B}}..."
        )
    ]
    page = Page("Foobar", 1, revisions)

    observations = enwiki.extract(page)
    project_labels = {(ob['project'], ob['wp10']): ob
                      for ob in observations}

    expected = [("medicine", "stub", Timestamp(0)),
                ("medicine", "c", Timestamp(3)),
                ("medicine", "b", Timestamp(5)),
                ("hats", "b", Timestamp(5))]

    print(project_labels)
    for proj, lab, timestamp in expected:
        ob = project_labels[(proj, lab)]
        eq_(ob['timestamp'], timestamp)
<commit_msg>Add example that should break, but needs testing<commit_after>from collections import namedtuple

import mwparserfromhell as mwp
from mwtypes import Timestamp
from nose.tools import eq_

from .. import enwiki

def test_extractor():

    Revision = namedtuple("Revisions", ['id', 'timestamp', 'sha1', 'text'])

    class Page:

        def __init__(self, title, namespace, revisions):
            self.title = title
            self.namespace = namespace
            self.revisions = revisions

        def __iter__(self):
            return iter(self.revisions)

    revisions = [
        Revision(
            1, Timestamp(0), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub}}..."
        ),
        Revision(
            2, Timestamp(1), "bbb",
            "{{talk page}}{{WikiProject Medicine|class=B}}..."
        ),
        Revision(
            3, Timestamp(2), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub<!--" +
            " test HTML comment -->}}..."
        ),
        Revision(
            4, Timestamp(3), "ccc",
            "{{talk page}}{{WikiProject Medicine|class=C}}..."
        ),
        Revision(
            5, Timestamp(4), "aaa",
            "{{talk page}}{{WikiProject Medicine|class=Stub}}..."
        ),
        Revision(
            6, Timestamp(4), "ccc",
            "{{talk page}}{{WikiProject Medicine|class= C}}..."
        ),
        Revision(
            7, Timestamp(5), "ddd",
            "{{talk page}}{{WikiProject Medicine|class=B}}\n" +
            "{{WP_Hats|class=B}}..."
        ),
        Revision(
            8, Timestamp(6), "eee",
            """{{talkheader}}
{{WikiProjectBannerShell|1=
{{WPMILHIST|class=C
<!-- B-Class 5-criteria checklist -->
|B1 <!-- Referencing and citations --> =n
|B2 <!-- Coverage and accuracy --> =y
|B3 <!-- Structure --> =y
|B4 <!-- Grammar and style --> =y
|B5 <!-- Supporting materials --> =y
|National=y|African=y}}
{{AfricaProject|class=C|importance=Top|Djibouti=y|Djibouti-importance=Top}}
}}"""
        )
    ]
    page = Page("Foobar", 1, revisions)

    observations = enwiki.extract(page)
    project_labels = {(ob['project'], ob['wp10']): ob
                      for ob in observations}

    expected = [("medicine", "stub", Timestamp(0)),
                ("medicine", "c", Timestamp(3)),
                ("medicine", "b", Timestamp(5)),
                ("hats", "b", Timestamp(5)),
                ("wpmilhist", "c", Timestamp(6)),
                ("africaproject", "c", Timestamp(6))]

    print(project_labels)
    for proj, lab, timestamp in expected:
        ob = project_labels[(proj, lab)]
        eq_(ob['timestamp'], timestamp)
<|endoftext|>


<commit_before># -- coding: utf-8 --
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 pprint import pprint

def merge(dbag, staticroutes):
    for route in staticroutes['routes']:
        key = route['ip_address']
        revoke = route['revoke']
        if revoke:
            try:
                del dbag[key]
            except KeyError:
                pass
        else:
            dbag[key] = route

    return dbag
<commit_msg>CLOUDSTACK-9256 add unique key for static routes in json<commit_after># -- coding: utf-8 --
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 pprint import pprint

def merge(dbag, staticroutes):
    for route in staticroutes['routes']:
        key = route['network']
        revoke = route['revoke']
        if revoke:
            try:
                del dbag[key]
            except KeyError:
                pass
        else:
            dbag[key] = route

    return dbag
<|endoftext|>


<commit_before>import os
import sys
from waitlist.base import db
from waitlist.storage.database import EveApiScope
base_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(base_path, 'lib'))

api_scopes = ['fleetRead', 'fleetWrite', 'remoteClientUI', 'esi-mail.send_mail.v1']

def createRoles():
    for scope in api_scopes:
        dbscope = db.session.query(EveApiScope).filter(EveApiScope.scopeName == scope).first()
        if dbscope == None:
            dbscope = EveApiScope(scopeName=scope)
            db.session.add(dbscope)

if __name__ == '__main__':
    createRoles()
    db.session.commit()<commit_msg>updated required token scopes<commit_after>import os
import sys
base_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(base_path, 'lib'))
from typing import List

from waitlist.base import db
from waitlist.storage.database import EveApiScope

api_scopes: List[str] = ['esi-ui.open_window.v1', 'esi-fleets.read_fleet.v1', 'esi-fleets.write_fleet.v1', 'esi-mail.send_mail.v1']

def create_roles():
    for scope in api_scopes:
        dbscope = db.session.query(EveApiScope).filter(EveApiScope.scopeName == scope).first()
        if dbscope == None:
            dbscope = EveApiScope(scopeName=scope)
            db.session.add(dbscope)

if __name__ == '__main__':
    create_roles()
    db.session.commit()<|endoftext|>


<commit_before>#!/usr/bin/env python3
"""
    Implements a custom Distutils build_ext replacement, which handles the
    full extension module build process, from api_gen to C compilation and
    linking.
"""

try:
    from setuptools import Extension
except ImportError:
    from distutils.extension import Extension
from distutils.command.build_ext import build_ext
import sys
import os
import os.path as op
from pathlib import Path

import api_gen
from setup_configure import BuildConfig

src_path = build_path = op.abspath(op.dirname(__file__))

def localpath(*args, root=src_path):
    return op.abspath(op.join(root, *args))

MODULES = ['defs', '_errors', '_objects', '_proxy', 'h5fd', 'h5z',
            'h5', 'h5i', 'h5r', 'utils', '_selector',
            '_conv', 'h5t', 'h5s',
            'h5p',
            'h5d', 'h5a', 'h5f', 'h5g',
            'h5l', 'h5o',
            'h5ds', 'h5ac',
            'h5pl']

COMPILER_SETTINGS = {
   'libraries'      : ['hdf5', 'hdf5_hl'],
   'include_dirs'   : [localpath('lzf')],
   'library_dirs'   : [],
   'define_macros'  : [('H5_USE_18_API', None),
                       ('NPY_NO_DEPRECATED_API', 0),
                      ]
}

EXTRA_SRC = {'h5z': [ localpath("lzf/lzf_filter.c") ]}

# Set the environment variable H5PY_SYSTEM_LZF=1 if we want to
# use the system lzf library
if os.environ.get('H5PY_SYSTEM_LZF', '0') == '1':
    EXTRA_LIBRARIES = {
       'h5z': [ 'lzf' ]
    }
else:
    COMPILER_SETTINGS['include_dirs'] += [localpath('lzf/lzf')]

    EXTRA_SRC['h5z'] += [localpath("lzf/lzf/lzf_c.c"),
                  localpath("lzf/lzf/lzf_d.c")]

    EXTRA_LIBRARIES = {}

if sys.platform.startswith('win'):
    COMPILER_SETTINGS['include_dirs'].append(localpath('windows'))
    COMPILER_SETTINGS['define_macros'].extend([
        ('_HDF5USEDLL_', None),
        ('H5_BUILT_AS_DYNAMIC_LIB', None)
    ])

class h5py_build_ext(build_ext):

    """
        Custom distutils command which encapsulates api_gen pre-building,
        Cython building, and C compilation.

        Also handles making the Extension modules, since we can't rely on
        NumPy being present in the main body of the setup script.
    """

    @staticmethod
    def _make_extensions(config):
        """ Produce a list of Extension instances which can be passed to
        cythonize().

        This is the point at which custom directories, MPI options, etc.
        enter the build process.
        """
        import numpy

        settings = COMPILER_SETTINGS.copy()

        settings['include_dirs'][:0] = config.hdf5_includedirs
        settings['library_dirs'][:0] = config.hdf5_libdirs
        settings['define_macros'].extend(config.hdf5_define_macros)

        try:
            numpy_includes = numpy.get_include()
        except AttributeError:
            # if numpy is not installed get the headers from the .egg directory
            import numpy.core
            numpy_includes = os.path.join(os.path.dirname(numpy.core.__file__), 'include')

        settings['include_dirs'] += [numpy_includes]
        if config.mpi:
            import mpi4py
            settings['include_dirs'] += [mpi4py.get_include()]

        # TODO: should this only be done on UNIX?
        if os.name != 'nt':
            settings['runtime_library_dirs'] = settings['library_dirs']

        def make_extension(module):
            sources = [localpath('h5py', module + '.pyx')] + EXTRA_SRC.get(module, [])
            settings['libraries'] += EXTRA_LIBRARIES.get(module, [])
            return Extension('h5py.' + module, sources, **settings)

        return [make_extension(m) for m in MODULES]

    def finalize_options(self):
        retval = super().finalize_options()

        global build_path
        if (self.build_lib is not None and op.exists(self.build_lib) and
                not self.inplace):
            build_path = op.abspath(self.build_lib)
            print("Updated build directory to: {}".format(build_path))

        return retval

    def run(self):
        """ Distutils calls this method to run the command """

        from Cython import __version__ as cython_version
        from Cython.Build import cythonize
        import numpy

        # This allows ccache to recognise the files when pip builds in a temp
        # directory. It speeds up repeatedly running tests through tox with
        # ccache configured (CC="ccache gcc"). It should have no effect if
        # ccache is not in use.
        os.environ['CCACHE_BASEDIR'] = op.dirname(op.abspath(__file__))
        os.environ['CCACHE_NOHASHDIR'] = '1'

        # Get configuration from environment variables
        config = BuildConfig.from_env()
        config.summarise()

        defs_file = localpath('h5py', 'defs.pyx')
        func_file = localpath('h5py', 'api_functions.txt')

        # Rebuild low-level defs if missing or stale
        if not op.isfile(defs_file) or os.stat(func_file).st_mtime > os.stat(defs_file).st_mtime:
            print("Executing api_gen rebuild of defs")
            api_gen.run()

        header_s = f"""\
# This file is automatically generated by the h5py setup script.  Don't modify.

#ifndef H5PY_CONFIG
#define H5PY_CONFIG

#if defined(__arm64__) && defined(__APPLE__)
#define COMPLEX256_SUPPORT 0
#else
#define COMPLEX256_SUPPORT {int(hasattr(numpy, 'complex256'))}
#endif

#endif
"""
        write_if_changed(localpath('h5py', 'config.h'), header_s)
        write_if_changed(
            localpath('h5py', 'config.h', root=build_path), header_s)

        # Rewrite config.pxi file if needed
        s = f"""\
# This file is automatically generated by the h5py setup script.  Don't modify.

cdef extern from "config.h":

    size_t COMPLEX256_SUPPORT

DEF MPI = {bool(config.mpi)}
DEF ROS3 = {bool(config.ros3)}
DEF HDF5_VERSION = {config.hdf5_version}
DEF SWMR_MIN_HDF5_VERSION = (1,9,178)
DEF VDS_MIN_HDF5_VERSION = (1,9,233)
DEF VOL_MIN_HDF5_VERSION = (1,11,5)
DEF NUMPY_BUILD_VERSION = '{numpy.__version__}'
DEF CYTHON_BUILD_VERSION = '{cython_version}'
"""
        write_if_changed(localpath('h5py', 'config.pxi'), s)
        write_if_changed(localpath('h5py', 'config.pxi', root=build_path), s)

        # Run Cython
        print("Executing cythonize()")
        self.extensions = cythonize(self._make_extensions(config),
                                    force=config.changed() or self.force,
                                    language_level=3)

        # Perform the build
        build_ext.run(self)

        # Record the configuration we built
        config.record_built()

def write_if_changed(target_path, s: str):
    """Overwrite target_path unless the contents already match s

    Avoids changing the mtime when we're just writing the same data.
    """
    p = Path(target_path)
    b = s.encode('utf-8')
    try:
        if p.read_bytes() == b:
            return
    except FileNotFoundError:
        pass

    p.write_bytes(b)
    print(f'Updated {p}')
<commit_msg>Use c-style comment in .h.<commit_after>#!/usr/bin/env python3
"""
    Implements a custom Distutils build_ext replacement, which handles the
    full extension module build process, from api_gen to C compilation and
    linking.
"""

try:
    from setuptools import Extension
except ImportError:
    from distutils.extension import Extension
from distutils.command.build_ext import build_ext
import sys
import os
import os.path as op
from pathlib import Path

import api_gen
from setup_configure import BuildConfig

src_path = build_path = op.abspath(op.dirname(__file__))

def localpath(*args, root=src_path):
    return op.abspath(op.join(root, *args))

MODULES = ['defs', '_errors', '_objects', '_proxy', 'h5fd', 'h5z',
            'h5', 'h5i', 'h5r', 'utils', '_selector',
            '_conv', 'h5t', 'h5s',
            'h5p',
            'h5d', 'h5a', 'h5f', 'h5g',
            'h5l', 'h5o',
            'h5ds', 'h5ac',
            'h5pl']

COMPILER_SETTINGS = {
   'libraries'      : ['hdf5', 'hdf5_hl'],
   'include_dirs'   : [localpath('lzf')],
   'library_dirs'   : [],
   'define_macros'  : [('H5_USE_18_API', None),
                       ('NPY_NO_DEPRECATED_API', 0),
                      ]
}

EXTRA_SRC = {'h5z': [ localpath("lzf/lzf_filter.c") ]}

# Set the environment variable H5PY_SYSTEM_LZF=1 if we want to
# use the system lzf library
if os.environ.get('H5PY_SYSTEM_LZF', '0') == '1':
    EXTRA_LIBRARIES = {
       'h5z': [ 'lzf' ]
    }
else:
    COMPILER_SETTINGS['include_dirs'] += [localpath('lzf/lzf')]

    EXTRA_SRC['h5z'] += [localpath("lzf/lzf/lzf_c.c"),
                  localpath("lzf/lzf/lzf_d.c")]

    EXTRA_LIBRARIES = {}

if sys.platform.startswith('win'):
    COMPILER_SETTINGS['include_dirs'].append(localpath('windows'))
    COMPILER_SETTINGS['define_macros'].extend([
        ('_HDF5USEDLL_', None),
        ('H5_BUILT_AS_DYNAMIC_LIB', None)
    ])

class h5py_build_ext(build_ext):

    """
        Custom distutils command which encapsulates api_gen pre-building,
        Cython building, and C compilation.

        Also handles making the Extension modules, since we can't rely on
        NumPy being present in the main body of the setup script.
    """

    @staticmethod
    def _make_extensions(config):
        """ Produce a list of Extension instances which can be passed to
        cythonize().

        This is the point at which custom directories, MPI options, etc.
        enter the build process.
        """
        import numpy

        settings = COMPILER_SETTINGS.copy()

        settings['include_dirs'][:0] = config.hdf5_includedirs
        settings['library_dirs'][:0] = config.hdf5_libdirs
        settings['define_macros'].extend(config.hdf5_define_macros)

        try:
            numpy_includes = numpy.get_include()
        except AttributeError:
            # if numpy is not installed get the headers from the .egg directory
            import numpy.core
            numpy_includes = os.path.join(os.path.dirname(numpy.core.__file__), 'include')

        settings['include_dirs'] += [numpy_includes]
        if config.mpi:
            import mpi4py
            settings['include_dirs'] += [mpi4py.get_include()]

        # TODO: should this only be done on UNIX?
        if os.name != 'nt':
            settings['runtime_library_dirs'] = settings['library_dirs']

        def make_extension(module):
            sources = [localpath('h5py', module + '.pyx')] + EXTRA_SRC.get(module, [])
            settings['libraries'] += EXTRA_LIBRARIES.get(module, [])
            return Extension('h5py.' + module, sources, **settings)

        return [make_extension(m) for m in MODULES]

    def finalize_options(self):
        retval = super().finalize_options()

        global build_path
        if (self.build_lib is not None and op.exists(self.build_lib) and
                not self.inplace):
            build_path = op.abspath(self.build_lib)
            print("Updated build directory to: {}".format(build_path))

        return retval

    def run(self):
        """ Distutils calls this method to run the command """

        from Cython import __version__ as cython_version
        from Cython.Build import cythonize
        import numpy

        # This allows ccache to recognise the files when pip builds in a temp
        # directory. It speeds up repeatedly running tests through tox with
        # ccache configured (CC="ccache gcc"). It should have no effect if
        # ccache is not in use.
        os.environ['CCACHE_BASEDIR'] = op.dirname(op.abspath(__file__))
        os.environ['CCACHE_NOHASHDIR'] = '1'

        # Get configuration from environment variables
        config = BuildConfig.from_env()
        config.summarise()

        defs_file = localpath('h5py', 'defs.pyx')
        func_file = localpath('h5py', 'api_functions.txt')

        # Rebuild low-level defs if missing or stale
        if not op.isfile(defs_file) or os.stat(func_file).st_mtime > os.stat(defs_file).st_mtime:
            print("Executing api_gen rebuild of defs")
            api_gen.run()

        header_s = f"""\
// This file is automatically generated by the h5py setup script.  Don't modify.

#ifndef H5PY_CONFIG
#define H5PY_CONFIG

#if defined(__arm64__) && defined(__APPLE__)
#define COMPLEX256_SUPPORT 0
#else
#define COMPLEX256_SUPPORT {int(hasattr(numpy, 'complex256'))}
#endif

#endif
"""
        write_if_changed(localpath('h5py', 'config.h'), header_s)
        write_if_changed(
            localpath('h5py', 'config.h', root=build_path), header_s)

        # Rewrite config.pxi file if needed
        s = f"""\
# This file is automatically generated by the h5py setup script.  Don't modify.

cdef extern from "config.h":

    size_t COMPLEX256_SUPPORT

DEF MPI = {bool(config.mpi)}
DEF ROS3 = {bool(config.ros3)}
DEF HDF5_VERSION = {config.hdf5_version}
DEF SWMR_MIN_HDF5_VERSION = (1,9,178)
DEF VDS_MIN_HDF5_VERSION = (1,9,233)
DEF VOL_MIN_HDF5_VERSION = (1,11,5)
DEF NUMPY_BUILD_VERSION = '{numpy.__version__}'
DEF CYTHON_BUILD_VERSION = '{cython_version}'
"""
        write_if_changed(localpath('h5py', 'config.pxi'), s)
        write_if_changed(localpath('h5py', 'config.pxi', root=build_path), s)

        # Run Cython
        print("Executing cythonize()")
        self.extensions = cythonize(self._make_extensions(config),
                                    force=config.changed() or self.force,
                                    language_level=3)

        # Perform the build
        build_ext.run(self)

        # Record the configuration we built
        config.record_built()

def write_if_changed(target_path, s: str):
    """Overwrite target_path unless the contents already match s

    Avoids changing the mtime when we're just writing the same data.
    """
    p = Path(target_path)
    b = s.encode('utf-8')
    try:
        if p.read_bytes() == b:
            return
    except FileNotFoundError:
        pass

    p.write_bytes(b)
    print(f'Updated {p}')
<|endoftext|>


<commit_before>
import ast
import errno
import os
import platform
import shutil
import stat
import subprocess
import sys

from distutils import log
from distutils.command.build_ext import build_ext
from distutils.command.sdist import sdist
from distutils.errors import DistutilsError

PY3 = sys.version_info[0] == 3

def makedirs(path):
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno==errno.EEXIST and os.path.isdir(path) and os.access(path, os.R_OK | os.W_OK | os.X_OK):
            return
        raise

def rmtree(path):
    def remove_readonly(func, path, excinfo):
        os.chmod(path, stat.S_IWRITE)
        func(path)

    try:
        shutil.rmtree(path, onerror=remove_readonly)
    except OSError as e:
        if e.errno != errno.ENOENT:
            raise

def exec_process(cmdline, silent=True, input=None, **kwargs):
    """Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.
    Optionally prints stdout and stderr while running."""
    try:
        sub = subprocess.Popen(args=cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
        stdout, stderr = sub.communicate(input=input)
        returncode = sub.returncode
        if PY3:
            stderr = stderr.decode(sys.stderr.encoding)
            stdout = stdout.decode(sys.stdout.encoding)
        if not silent:
            sys.stdout.write(stdout)
            sys.stderr.write(stderr)
    except OSError as e:
        if e.errno == errno.ENOENT:
            raise DistutilsError('"%s" is not present on this system' % cmdline[0])
        else:
            raise
    if returncode != 0:
        output = 'stderr:\n%s\nstdout:\n%s' % (stderr.rstrip("\n"), stdout.rstrip("\n"))
        raise DistutilsError('Got return value %d while executing "%s", output was:\n%s' % (returncode, " ".join(cmdline), output))
    return stdout

def prepare_windows_env(env):
    env.pop('VS140COMNTOOLS', None)
    env.pop('VS120COMNTOOLS', None)
    env.pop('VS110COMNTOOLS', None)
    if sys.version_info < (3, 3):
        env.pop('VS100COMNTOOLS', None)
        env['GYP_MSVS_VERSION'] = '2008'
    else:
        env['GYP_MSVS_VERSION'] = '2010'

    if not env.get('PYTHON', '').endswith('.exe'):
        env.pop('PYTHON', None)

    if env.get('PYTHON'):
        return  # Already manually set by user.

    if sys.version_info[:2] == (2, 7):
        env['PYTHON'] = sys.executable
        return  # The current executable is fine.

    # Try if `python` on PATH is the right one. If we would execute
    # `python` directly the current executable might be used so we
    # delegate this to cmd.
    cmd = ['cmd.exe', '/C',  'python', '-c', 'import sys; '
           'v = str(sys.version_info[:2]); sys.stdout.write(v); '
           'sys.stdout.flush()']
    try:
        sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        stdout, _ = sub.communicate()
        version = ast.literal_eval(stdout.decode(sys.stdout.encoding).strip())
        if version == (2, 7):
            return  # Python on PATH is fine
    except OSError:
        pass

    # Check default install locations
    path = os.path.join('%SYSTEMDRIVE%', 'Python27', 'python.exe')
    path = os.path.expandvars(path)
    if os.path.isfile(path):
        log.info('Using "%s" to build libuv...' % path)
        env['PYTHON'] = path
    else:
        raise DistutilsError('No appropriate Python version found. An '
                             'installation of 2.7 is required to '
                             'build libuv. You can set the environment '
                             'variable "PYTHON" to point to a custom '
                             'installation location.')

class libuv_build_ext(build_ext):
    libuv_dir      = os.path.join('deps', 'libuv')
    libuv_repo     = 'https://github.com/libuv/libuv.git'
    libuv_branch   = 'v1.x'
    libuv_revision = '93877b1'
    libuv_patches  = []

    user_options = build_ext.user_options
    user_options.extend([
        ("libuv-clean-compile", None, "Clean libuv tree before compilation"),
        ("libuv-force-fetch", None, "Remove libuv (if present) and fetch it again"),
        ("libuv-verbose-build", None, "Print output of libuv build process"),
        ("use-system-libuv", None, "Use the system provided libuv, instead of the bundled one")
    ])
    boolean_options = build_ext.boolean_options
    boolean_options.extend(["libuv-clean-compile", "libuv-force-fetch", "libuv-verbose-build", "use-system-libuv"])

    def initialize_options(self):
        build_ext.initialize_options(self)
        self.libuv_clean_compile = 0
        self.libuv_force_fetch = 0
        self.libuv_verbose_build = 0
        self.use_system_libuv = 0

    def build_extensions(self):
        self.force = self.force or self.libuv_force_fetch or self.libuv_clean_compile
        if self.use_system_libuv:
            if sys.platform == 'win32':
                raise DistutilsError('using a system provided libuv is unsupported on Windows')
            self.compiler.add_library('uv')
        else:
            if sys.platform == 'win32':
                self.libuv_lib = os.path.join(self.libuv_dir, 'Release', 'lib', 'libuv.lib')
            else:
                self.libuv_lib = os.path.join(self.libuv_dir, '.libs', 'libuv.a')
            self.get_libuv()
            # Set compiler options
            self.extensions[0].extra_objects.extend([self.libuv_lib])
            self.compiler.add_include_dir(os.path.join(self.libuv_dir, 'include'))
        if sys.platform.startswith('linux'):
            self.compiler.add_library('rt')
        elif sys.platform == 'win32':
            self.extensions[0].define_macros.append(('WIN32', 1))
            self.extensions[0].extra_link_args.extend(['/NODEFAULTLIB:libcmt', '/LTCG'])
            self.compiler.add_library('advapi32')
            self.compiler.add_library('iphlpapi')
            self.compiler.add_library('psapi')
            self.compiler.add_library('shell32')
            self.compiler.add_library('userenv')
            self.compiler.add_library('ws2_32')
        elif sys.platform.startswith('freebsd'):
            self.compiler.add_library('kvm')
        build_ext.build_extensions(self)

    def get_libuv(self):
        #self.debug_mode =  bool(self.debug) or hasattr(sys, 'gettotalrefcount')
        def download_libuv():
            log.info('Downloading libuv...')
            makedirs(self.libuv_dir)
            exec_process(['git', 'clone', '-b', self.libuv_branch, self.libuv_repo, self.libuv_dir])
            exec_process(['git', 'reset', '--hard', self.libuv_revision], cwd=self.libuv_dir)
        def patch_libuv():
            if self.libuv_patches:
                log.info('Patching libuv...')
                for patch_file in self.libuv_patches:
                    exec_process(['patch', '--forward', '-d', self.libuv_dir, '-p0', '-i', os.path.abspath(patch_file)])
        def build_libuv():
            cflags = '-fPIC'
            env = os.environ.copy()
            env['CFLAGS'] = ' '.join(x for x in (cflags, env.get('CFLAGS', None), env.get('ARCHFLAGS', None)) if x)
            log.info('Building libuv...')
            if sys.platform == 'win32':
                prepare_windows_env(env)
                libuv_arch = {'32bit': 'x86', '64bit': 'x64'}[platform.architecture()[0]]
                exec_process(['cmd.exe', '/C', 'vcbuild.bat', libuv_arch, 'release'], cwd=self.libuv_dir, env=env, shell=True, silent=not self.libuv_verbose_build)
            else:
                exec_process(['sh', 'autogen.sh'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
                exec_process(['./configure'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
                exec_process(['make'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
        if self.libuv_force_fetch:
            rmtree('deps')
        if not os.path.exists(self.libuv_dir):
            try:
                download_libuv()
            except BaseException:
                rmtree('deps')
                raise
            patch_libuv()
            build_libuv()
        else:
            if self.libuv_clean_compile:
                if sys.platform == 'win32':
                    env = os.environ.copy()
                    prepare_windows_env(env)
                    exec_process(['cmd.exe', '/C', 'vcbuild.bat', 'clean'], cwd=self.libuv_dir, env=env, shell=True)
                    rmtree(os.path.join(self.libuv_dir, 'Release'))
                else:
                    exec_process(['make', 'clean'], cwd=self.libuv_dir)
                    exec_process(['make', 'distclean'], cwd=self.libuv_dir)
            if not os.path.exists(self.libuv_lib):
                log.info('libuv needs to be compiled.')
                build_libuv()
            else:
                log.info('No need to build libuv.')

class libuv_sdist(sdist):
    libuv_dir      = os.path.join('deps', 'libuv')
    libuv_repo     = libuv_build_ext.libuv_repo
    libuv_branch   = libuv_build_ext.libuv_branch
    libuv_revision = libuv_build_ext.libuv_revision
    libuv_patches  = libuv_build_ext.libuv_patches

    gyp_dir = os.path.join(libuv_dir, 'build', 'gyp')
    gyp_repo = 'https://chromium.googlesource.com/external/gyp.git'

    def initialize_options(self):
        sdist.initialize_options(self)
        rmtree('deps')
        makedirs(self.libuv_dir)
        log.info('Downloading libuv...')
        exec_process(['git', 'clone', '-b', self.libuv_branch, self.libuv_repo, self.libuv_dir])
        exec_process(['git', 'checkout', self.libuv_revision], cwd=self.libuv_dir)
        if self.libuv_patches:
            log.info('Patching libuv...')
            for patch_file in self.libuv_patches:
                exec_process(['patch', '--forward', '-d', self.libuv_dir, '-p0', '-i', os.path.abspath(patch_file)])
        rmtree(os.path.join(self.libuv_dir, '.git'))

        log.info('Downloading gyp...')
        exec_process(['git', 'clone', self.gyp_repo, self.gyp_dir])
        rmtree(os.path.join(self.gyp_dir, 'test'))
        rmtree(os.path.join(self.gyp_dir, '.git'))

<commit_msg>core: raised libuv revision to tag 1.8.0<commit_after>
import ast
import errno
import os
import platform
import shutil
import stat
import subprocess
import sys

from distutils import log
from distutils.command.build_ext import build_ext
from distutils.command.sdist import sdist
from distutils.errors import DistutilsError

PY3 = sys.version_info[0] == 3

def makedirs(path):
    try:
        os.makedirs(path)
    except OSError as e:
        if e.errno==errno.EEXIST and os.path.isdir(path) and os.access(path, os.R_OK | os.W_OK | os.X_OK):
            return
        raise

def rmtree(path):
    def remove_readonly(func, path, excinfo):
        os.chmod(path, stat.S_IWRITE)
        func(path)

    try:
        shutil.rmtree(path, onerror=remove_readonly)
    except OSError as e:
        if e.errno != errno.ENOENT:
            raise

def exec_process(cmdline, silent=True, input=None, **kwargs):
    """Execute a subprocess and returns the returncode, stdout buffer and stderr buffer.
    Optionally prints stdout and stderr while running."""
    try:
        sub = subprocess.Popen(args=cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
        stdout, stderr = sub.communicate(input=input)
        returncode = sub.returncode
        if PY3:
            stderr = stderr.decode(sys.stderr.encoding)
            stdout = stdout.decode(sys.stdout.encoding)
        if not silent:
            sys.stdout.write(stdout)
            sys.stderr.write(stderr)
    except OSError as e:
        if e.errno == errno.ENOENT:
            raise DistutilsError('"%s" is not present on this system' % cmdline[0])
        else:
            raise
    if returncode != 0:
        output = 'stderr:\n%s\nstdout:\n%s' % (stderr.rstrip("\n"), stdout.rstrip("\n"))
        raise DistutilsError('Got return value %d while executing "%s", output was:\n%s' % (returncode, " ".join(cmdline), output))
    return stdout

def prepare_windows_env(env):
    env.pop('VS140COMNTOOLS', None)
    env.pop('VS120COMNTOOLS', None)
    env.pop('VS110COMNTOOLS', None)
    if sys.version_info < (3, 3):
        env.pop('VS100COMNTOOLS', None)
        env['GYP_MSVS_VERSION'] = '2008'
    else:
        env['GYP_MSVS_VERSION'] = '2010'

    if not env.get('PYTHON', '').endswith('.exe'):
        env.pop('PYTHON', None)

    if env.get('PYTHON'):
        return  # Already manually set by user.

    if sys.version_info[:2] == (2, 7):
        env['PYTHON'] = sys.executable
        return  # The current executable is fine.

    # Try if `python` on PATH is the right one. If we would execute
    # `python` directly the current executable might be used so we
    # delegate this to cmd.
    cmd = ['cmd.exe', '/C',  'python', '-c', 'import sys; '
           'v = str(sys.version_info[:2]); sys.stdout.write(v); '
           'sys.stdout.flush()']
    try:
        sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        stdout, _ = sub.communicate()
        version = ast.literal_eval(stdout.decode(sys.stdout.encoding).strip())
        if version == (2, 7):
            return  # Python on PATH is fine
    except OSError:
        pass

    # Check default install locations
    path = os.path.join('%SYSTEMDRIVE%', 'Python27', 'python.exe')
    path = os.path.expandvars(path)
    if os.path.isfile(path):
        log.info('Using "%s" to build libuv...' % path)
        env['PYTHON'] = path
    else:
        raise DistutilsError('No appropriate Python version found. An '
                             'installation of 2.7 is required to '
                             'build libuv. You can set the environment '
                             'variable "PYTHON" to point to a custom '
                             'installation location.')

class libuv_build_ext(build_ext):
    libuv_dir      = os.path.join('deps', 'libuv')
    libuv_repo     = 'https://github.com/libuv/libuv.git'
    libuv_branch   = 'v1.x'
    libuv_revision = '5467299'
    libuv_patches  = []

    user_options = build_ext.user_options
    user_options.extend([
        ("libuv-clean-compile", None, "Clean libuv tree before compilation"),
        ("libuv-force-fetch", None, "Remove libuv (if present) and fetch it again"),
        ("libuv-verbose-build", None, "Print output of libuv build process"),
        ("use-system-libuv", None, "Use the system provided libuv, instead of the bundled one")
    ])
    boolean_options = build_ext.boolean_options
    boolean_options.extend(["libuv-clean-compile", "libuv-force-fetch", "libuv-verbose-build", "use-system-libuv"])

    def initialize_options(self):
        build_ext.initialize_options(self)
        self.libuv_clean_compile = 0
        self.libuv_force_fetch = 0
        self.libuv_verbose_build = 0
        self.use_system_libuv = 0

    def build_extensions(self):
        self.force = self.force or self.libuv_force_fetch or self.libuv_clean_compile
        if self.use_system_libuv:
            if sys.platform == 'win32':
                raise DistutilsError('using a system provided libuv is unsupported on Windows')
            self.compiler.add_library('uv')
        else:
            if sys.platform == 'win32':
                self.libuv_lib = os.path.join(self.libuv_dir, 'Release', 'lib', 'libuv.lib')
            else:
                self.libuv_lib = os.path.join(self.libuv_dir, '.libs', 'libuv.a')
            self.get_libuv()
            # Set compiler options
            self.extensions[0].extra_objects.extend([self.libuv_lib])
            self.compiler.add_include_dir(os.path.join(self.libuv_dir, 'include'))
        if sys.platform.startswith('linux'):
            self.compiler.add_library('rt')
        elif sys.platform == 'win32':
            self.extensions[0].define_macros.append(('WIN32', 1))
            self.extensions[0].extra_link_args.extend(['/NODEFAULTLIB:libcmt', '/LTCG'])
            self.compiler.add_library('advapi32')
            self.compiler.add_library('iphlpapi')
            self.compiler.add_library('psapi')
            self.compiler.add_library('shell32')
            self.compiler.add_library('userenv')
            self.compiler.add_library('ws2_32')
        elif sys.platform.startswith('freebsd'):
            self.compiler.add_library('kvm')
        build_ext.build_extensions(self)

    def get_libuv(self):
        #self.debug_mode =  bool(self.debug) or hasattr(sys, 'gettotalrefcount')
        def download_libuv():
            log.info('Downloading libuv...')
            makedirs(self.libuv_dir)
            exec_process(['git', 'clone', '-b', self.libuv_branch, self.libuv_repo, self.libuv_dir])
            exec_process(['git', 'reset', '--hard', self.libuv_revision], cwd=self.libuv_dir)
        def patch_libuv():
            if self.libuv_patches:
                log.info('Patching libuv...')
                for patch_file in self.libuv_patches:
                    exec_process(['patch', '--forward', '-d', self.libuv_dir, '-p0', '-i', os.path.abspath(patch_file)])
        def build_libuv():
            cflags = '-fPIC'
            env = os.environ.copy()
            env['CFLAGS'] = ' '.join(x for x in (cflags, env.get('CFLAGS', None), env.get('ARCHFLAGS', None)) if x)
            log.info('Building libuv...')
            if sys.platform == 'win32':
                prepare_windows_env(env)
                libuv_arch = {'32bit': 'x86', '64bit': 'x64'}[platform.architecture()[0]]
                exec_process(['cmd.exe', '/C', 'vcbuild.bat', libuv_arch, 'release'], cwd=self.libuv_dir, env=env, shell=True, silent=not self.libuv_verbose_build)
            else:
                exec_process(['sh', 'autogen.sh'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
                exec_process(['./configure'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
                exec_process(['make'], cwd=self.libuv_dir, env=env, silent=not self.libuv_verbose_build)
        if self.libuv_force_fetch:
            rmtree('deps')
        if not os.path.exists(self.libuv_dir):
            try:
                download_libuv()
            except BaseException:
                rmtree('deps')
                raise
            patch_libuv()
            build_libuv()
        else:
            if self.libuv_clean_compile:
                if sys.platform == 'win32':
                    env = os.environ.copy()
                    prepare_windows_env(env)
                    exec_process(['cmd.exe', '/C', 'vcbuild.bat', 'clean'], cwd=self.libuv_dir, env=env, shell=True)
                    rmtree(os.path.join(self.libuv_dir, 'Release'))
                else:
                    exec_process(['make', 'clean'], cwd=self.libuv_dir)
                    exec_process(['make', 'distclean'], cwd=self.libuv_dir)
            if not os.path.exists(self.libuv_lib):
                log.info('libuv needs to be compiled.')
                build_libuv()
            else:
                log.info('No need to build libuv.')

class libuv_sdist(sdist):
    libuv_dir      = os.path.join('deps', 'libuv')
    libuv_repo     = libuv_build_ext.libuv_repo
    libuv_branch   = libuv_build_ext.libuv_branch
    libuv_revision = libuv_build_ext.libuv_revision
    libuv_patches  = libuv_build_ext.libuv_patches

    gyp_dir = os.path.join(libuv_dir, 'build', 'gyp')
    gyp_repo = 'https://chromium.googlesource.com/external/gyp.git'

    def initialize_options(self):
        sdist.initialize_options(self)
        rmtree('deps')
        makedirs(self.libuv_dir)
        log.info('Downloading libuv...')
        exec_process(['git', 'clone', '-b', self.libuv_branch, self.libuv_repo, self.libuv_dir])
        exec_process(['git', 'checkout', self.libuv_revision], cwd=self.libuv_dir)
        if self.libuv_patches:
            log.info('Patching libuv...')
            for patch_file in self.libuv_patches:
                exec_process(['patch', '--forward', '-d', self.libuv_dir, '-p0', '-i', os.path.abspath(patch_file)])
        rmtree(os.path.join(self.libuv_dir, '.git'))

        log.info('Downloading gyp...')
        exec_process(['git', 'clone', self.gyp_repo, self.gyp_dir])
        rmtree(os.path.join(self.gyp_dir, 'test'))
        rmtree(os.path.join(self.gyp_dir, '.git'))

<|endoftext|>