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

# Importing pygame modules
import random, sys, pygame, time, os
from pygame.locals import *
from sprite_strip_anim import SpriteStripAnim

WINDOWWIDTH     = 640
WINDOWHEIGHT    = 480
FPS             = 30
BUGMOVEH        = 20
BUGMOVEV        = 20
BUGSPACE        = 80
BUGROWHEIGHT    = 50
BUGBOUNDARY     = WINDOWHEIGHT - 100
BUGFIRECHANCE   = .07
BLOCKSPACE      = 200
FACTOR          = 3
MOVERATE        = 9
BULLETSPEED     = 15
BGCOLOR         = (0, 0, 0)
TEXTSHADOWCOLOR = (185,185,185)
TEXTCOLOR       = (255,255,255)

def main():
    global DISPLAYSURF, FPSCLOCK
    # set initial position of the game window
    os.environ['SDL_VIDEO_WINDOW_POS'] = "5,40"
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.display.set_caption("Bugs Invade!")

    while True:
        runGame()
        showGameOverScreen()

def runGame():
    shipSprite = SpriteStripAnim('img\invader.png', (204,154,18,10), 1, 1)
    shipWidth = shipSprite.getWidth() * FACTOR
    shipHeight = shipSprite.getHeight() * FACTOR
    ships = []
    ship_x = 0
    for i in range(3):
        ships.append({'surface': pygame.transform.scale(shipSprite.images[0], (shipWidth,shipHeight)),
                'x': ship_x,
                'y': WINDOWHEIGHT - (shipHeight + 1)
        })
    bulletSprite = SpriteStripAnim('img\invader.png', (89, 188, 10, 10), 1, 1)
    bulletWidth = bulletSprite.getWidth()
    bulletHeight = bulletSprite.getHeight()
    bullets = []
    bugBullets = []

    # make bugs
    bugSprite = SpriteStripAnim('img\invader.png', (0, 144, 18, 10), 2, 1, True, 23)
    bugWidth = bugSprite.getWidth() * FACTOR
    bugHeight = bugSprite.getHeight() * FACTOR
    bugs = []
    for bugRow in range(5):
        bugs.append([])
        for bug in range(6):
            bugs[bugRow].append({'surface': pygame.transform.scale(bugSprite.images[0], (bugWidth,bugHeight)),
                        'image': 0,
                        'x': 0 + (bug * BUGSPACE),
                        'y': bugRow * BUGROWHEIGHT
            })

    # make blocks
    blockSprite = SpriteStripAnim('img\invader.png', (0,166,33,20), 5, 1)
    blockWidth = blockSprite.getWidth() * FACTOR
    blockHeight = blockSprite.getHeight() * FACTOR
    blocks = []
    for i in range(3):
        blocks.append({'surface':pygame.transform.scale(blockSprite.images[0], (blockWidth, blockHeight)),
                       'rect':pygame.Rect((75 + (i * BLOCKSPACE), WINDOWHEIGHT - 100, blockWidth, blockHeight)),
                       'image':0})

    # set initial timers and movement directions
    lastMoveSideways = time.time()
    roundTimer = time.time()
    bugMoveFreq = .75
    bugMoveRight = True
    bugMoveDown = False
    shipMoveLeft = False
    shipMoveRight = False

    while True:
        checkForQuit()
        DISPLAYSURF.fill(BGCOLOR)
        if len(ships) > 0:
            ships[0]['x'] = ship_x
            ships[0]['rect'] = pygame.Rect((ships[0]['x'],
                                ships[0]['y'],
                                shipWidth,
                                shipHeight))
            DISPLAYSURF.blit(ships[0]['surface'],ships[0]['rect'])
        for bugRow in bugs:
            for bug in bugRow:
                bug['rect'] = pygame.Rect((bug['x'],
                                bug['y'],
                                bugWidth,
                                bugHeight))
                DISPLAYSURF.blit(bug['surface'], bug['rect'])
        for block in blocks:
            DISPLAYSURF.blit(block['surface'], block['rect'])

        pygame.display.flip()

        # event handler
        for event in pygame.event.get():
            # keyboard handler
            if event.type == KEYDOWN:
                # left and right keys
                if (event.key == K_LEFT) and (ship_x > 0):
                    shipMoveLeft = True
                    shipMoveRight = False
                elif (event.key == K_RIGHT) and (ship_x < WINDOWWIDTH - shipWidth):
                    shipMoveRight = True
                    shipMoveLeft = False
                # space bar
                if event.key == K_SPACE and bullets == []:
                    bullets.append({'surface':pygame.transform.scale(bulletSprite.images[0], (bulletWidth,bulletHeight)),
                            'x': ship_x + 22,
                            'y': WINDOWHEIGHT - (shipHeight + 1)})
            # releasing left and right keys
            elif event.type == KEYUP:
                if event.key == K_LEFT:
                    shipMoveLeft = False
                elif event.key == K_RIGHT:
                    shipMoveRight = False

        # move ship
        if ship_x <= 0:
            shipMoveLeft = False
        elif ship_x >= (WINDOWWIDTH - shipWidth):
            shipMoveRight = False
        if shipMoveLeft:
            ship_x -= MOVERATE
        elif shipMoveRight:
            ship_x += MOVERATE

        # move ship bullets
        if bullets != []:
            for bullet in bullets[:]:
                bullet['rect'] = pygame.Rect((bullet['x'],
                                bullet['y'],
                                bulletWidth,
                                bulletHeight))
                DISPLAYSURF.blit(bullet['surface'], bullet['rect'])
                if bullet['y'] < 0:
                    bullets.remove(bullet)
                else: # collision detection
                    bugHit = False
                    for bugsRow in range(len(bugs)-1, -1, -1):
                        if bugHit:
                            break
                        for bug in bugs[bugsRow][:]:
                            if bullet['rect'].colliderect(bug['rect']) and not bugHit:
                                bullets.remove(bullet)
                                bugs[bugsRow].remove(bug)
                                if bugs[bugsRow] == []:
                                    del bugs[bugsRow]
                                bugHit = True # break after hitting first bug
                            elif bugHit:
                                break
                    for block in blocks[:]:
                        if bullet['rect'].colliderect(block['rect']):
                            bullets.remove(bullet)
                            if block['image'] < 4:
                                block['image'] += 1
                                block['surface'] = pygame.transform.scale(blockSprite.images[block['image']], (blockWidth,blockHeight))
                            elif block['image'] == 4:
                                blocks.remove(block)
                    if bullets != []:
                        bullet['y'] -= BULLETSPEED

        # move bug bullets
        if bugBullets != []:
            shipHit = False
            for bullet in bugBullets[:]:
                bullet['rect'] = pygame.Rect((bullet['x'],
                                bullet['y'],
                                bulletWidth,
                                bulletHeight))
                DISPLAYSURF.blit(bullet['surface'], bullet['rect'])
                if bullet['y'] > WINDOWHEIGHT:
                    bugBullets.remove(bullet)
                else: # collision detection
                    if not shipHit and bullet['rect'].colliderect(ships[0]['rect']):
                        bugBullets.remove(bullet)
                        del ships[0]
                        ship_x = 0
                        shipHit = True
                        if ships == []:
                            return
                    for block in blocks[:]:
                        if bullet['rect'].colliderect(block['rect']):
                            bugBullets.remove(bullet)
                            if block['image'] < 4:
                                block['image'] += 1
                                block['surface'] = pygame.transform.scale(blockSprite.images[block['image']], (blockWidth,blockHeight))
                            elif block['image'] == 4:
                                blocks.remove(block)
                    if bugBullets != []:
                        bullet['y'] += BULLETSPEED

        # check roundTimer
        if time.time() - roundTimer > 10 and bugMoveFreq > .15:
            bugMoveFreq -= .15
            roundTimer = time.time()

        # move bugs
        if (time.time() - lastMoveSideways) > bugMoveFreq and bugs != []:
            if len(bugs[0]) > 0 or len(bugs[1]) > 0 or len(bugs[2]) > 0:
                # set bug direction
                max_X = 0
                min_X = WINDOWWIDTH
                for bugRow in range(len(bugs)):
                    max_X = max(bugs[bugRow][len(bugs[bugRow])-1]['x'], max_X)
                    min_X = min(bugs[bugRow][0]['x'], min_X)
                if max_X + BUGMOVEH > WINDOWWIDTH - bugWidth:
                    bugMoveRight = False
                    bugMoveDown = True
                elif min_X - BUGMOVEH < 0:
                    bugMoveRight = True
                    bugMoveDown = True
            for bugsRow in bugs:
                for bug in bugsRow:
                    if bugMoveDown:
                        bug['y'] += BUGMOVEV
                        if bug['y'] > BUGBOUNDARY:
                            return
                    if bugMoveRight:
                        bug['x'] += BUGMOVEH
                    else:
                        bug['x'] -= BUGMOVEH
                    # alternate animation
                    if bug['image'] == 0:
                        bug['image'] = 1
                    else:
                        bug['image'] = 0
                    bug['surface'] = pygame.transform.scale(bugSprite.images[bug['image']], (bugWidth,bugHeight))
            if bugMoveDown:
                bugMoveDown = False
            lastMoveSideways = time.time()
            # bugs randomly fire
            fireBugs = []
            fireBugs_X = []
            for bugRow in range(len(bugs)-1, -1, -1):
                for bug in bugs[bugRow]:
                    if bug['x'] not in fireBugs_X:
                        fireBugs.append(bug)
                        fireBugs_X.append(bug['x'])
            for bug in fireBugs:
                if random.random() < BUGFIRECHANCE:
                    bugBullets.append({'surface':pygame.transform.scale(bulletSprite.images[0], (bulletWidth,bulletHeight)),
                            'x': bug['x'] + (bugWidth / 2) - 4,
                            'y': bug['y'] + bugHeight})

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def showGameOverScreen():
    titleSurf = pygame.font.Font('freesansbold.ttf', 100).render('Game Over', True, TEXTSHADOWCOLOR)
    titleRect = titleSurf.get_rect()
    titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
    DISPLAYSURF.blit(titleSurf, titleRect)

    titleSurf = pygame.font.Font('freesansbold.ttf', 100).render('Game Over', True, TEXTCOLOR)
    titleRect = titleSurf.get_rect()
    titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3)
    DISPLAYSURF.blit(titleSurf, titleRect)

    pressKeySurf = pygame.font.Font('freesansbold.ttf', 18).render('Press a key to play.', True, TEXTCOLOR)
    pressKeyRect = pressKeySurf.get_rect()
    pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100)
    DISPLAYSURF.blit(pressKeySurf, pressKeyRect)

    while checkForKeyPress() == None:
        pygame.display.update()
        FPSCLOCK.tick()

def checkForKeyPress():
    checkForQuit()

    for event in pygame.event.get([KEYDOWN, KEYUP, MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION]):
        if event.type in (KEYDOWN, MOUSEBUTTONUP, MOUSEBUTTONDOWN, MOUSEMOTION):
            continue
        return event.key
    return None

def checkForQuit():
    for event in pygame.event.get(QUIT):
        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    main()<commit_msg>Added game over for clearing out the bugs<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Importing pygame modules
import random, sys, pygame, time, os
from pygame.locals import *
from sprite_strip_anim import SpriteStripAnim

WINDOWWIDTH     = 640
WINDOWHEIGHT    = 480
FPS             = 30
BUGMOVEH        = 20
BUGMOVEV        = 20
BUGSPACE        = 80
BUGROWHEIGHT    = 50
BUGBOUNDARY     = WINDOWHEIGHT - 100
BUGFIRECHANCE   = .10
BLOCKSPACE      = 200
FACTOR          = 3
MOVERATE        = 9
BULLETSPEED     = 15
BGCOLOR         = (0, 0, 0)
TEXTSHADOWCOLOR = (185,185,185)
TEXTCOLOR       = (255,255,255)

def main():
    global DISPLAYSURF, FPSCLOCK
    # set initial position of the game window
    os.environ['SDL_VIDEO_WINDOW_POS'] = "5,40"
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.display.set_caption("Bugs Invade!")

    while True:
        runGame()
        showGameOverScreen()

def runGame():
    shipSprite = SpriteStripAnim('img\invader.png', (204,154,18,10), 1, 1)
    shipWidth = shipSprite.getWidth() * FACTOR
    shipHeight = shipSprite.getHeight() * FACTOR
    ships = []
    ship_x = 0
    for i in range(3):
        ships.append({'surface': pygame.transform.scale(shipSprite.images[0], (shipWidth,shipHeight)),
                'x': ship_x,
                'y': WINDOWHEIGHT - (shipHeight + 1)
        })
    bulletSprite = SpriteStripAnim('img\invader.png', (89, 188, 10, 10), 1, 1)
    bulletWidth = bulletSprite.getWidth()
    bulletHeight = bulletSprite.getHeight()
    bullets = []
    bugBullets = []

    # make bugs
    bugSprite = SpriteStripAnim('img\invader.png', (0, 144, 18, 10), 2, 1, True, 23)
    bugWidth = bugSprite.getWidth() * FACTOR
    bugHeight = bugSprite.getHeight() * FACTOR
    bugs = []
    for bugRow in range(5):
        bugs.append([])
        for bug in range(6):
            bugs[bugRow].append({'surface': pygame.transform.scale(bugSprite.images[0], (bugWidth,bugHeight)),
                        'image': 0,
                        'x': 0 + (bug * BUGSPACE),
                        'y': bugRow * BUGROWHEIGHT
            })

    # make blocks
    blockSprite = SpriteStripAnim('img\invader.png', (0,166,33,20), 5, 1)
    blockWidth = blockSprite.getWidth() * FACTOR
    blockHeight = blockSprite.getHeight() * FACTOR
    blocks = []
    for i in range(3):
        blocks.append({'surface':pygame.transform.scale(blockSprite.images[0], (blockWidth, blockHeight)),
                       'rect':pygame.Rect((75 + (i * BLOCKSPACE), WINDOWHEIGHT - 100, blockWidth, blockHeight)),
                       'image':0})

    # set initial timers and movement directions
    lastMoveSideways = time.time()
    roundTimer = time.time()
    bugMoveFreq = .75
    bugMoveRight = True
    bugMoveDown = False
    shipMoveLeft = False
    shipMoveRight = False

    while True:
        checkForQuit()
        DISPLAYSURF.fill(BGCOLOR)
        if len(ships) > 0:
            ships[0]['x'] = ship_x
            ships[0]['rect'] = pygame.Rect((ships[0]['x'],
                                ships[0]['y'],
                                shipWidth,
                                shipHeight))
            DISPLAYSURF.blit(ships[0]['surface'],ships[0]['rect'])
        for bugRow in bugs:
            for bug in bugRow:
                bug['rect'] = pygame.Rect((bug['x'],
                                bug['y'],
                                bugWidth,
                                bugHeight))
                DISPLAYSURF.blit(bug['surface'], bug['rect'])
        for block in blocks:
            DISPLAYSURF.blit(block['surface'], block['rect'])

        pygame.display.flip()

        # event handler
        for event in pygame.event.get():
            # keyboard handler
            if event.type == KEYDOWN:
                # left and right keys
                if (event.key == K_LEFT) and (ship_x > 0):
                    shipMoveLeft = True
                    shipMoveRight = False
                elif (event.key == K_RIGHT) and (ship_x < WINDOWWIDTH - shipWidth):
                    shipMoveRight = True
                    shipMoveLeft = False
                # space bar
                if event.key == K_SPACE and bullets == []:
                    bullets.append({'surface':pygame.transform.scale(bulletSprite.images[0], (bulletWidth,bulletHeight)),
                            'x': ship_x + 22,
                            'y': WINDOWHEIGHT - (shipHeight + 1)})
            # releasing left and right keys
            elif event.type == KEYUP:
                if event.key == K_LEFT:
                    shipMoveLeft = False
                elif event.key == K_RIGHT:
                    shipMoveRight = False

        # move ship
        if ship_x <= 0:
            shipMoveLeft = False
        elif ship_x >= (WINDOWWIDTH - shipWidth):
            shipMoveRight = False
        if shipMoveLeft:
            ship_x -= MOVERATE
        elif shipMoveRight:
            ship_x += MOVERATE

        # move ship bullets
        if bullets != []:
            for bullet in bullets[:]:
                bullet['rect'] = pygame.Rect((bullet['x'],
                                bullet['y'],
                                bulletWidth,
                                bulletHeight))
                DISPLAYSURF.blit(bullet['surface'], bullet['rect'])
                if bullet['y'] < 0:
                    bullets.remove(bullet)
                else: # collision detection
                    bugHit = False
                    for bugsRow in range(len(bugs)-1, -1, -1):
                        if bugHit:
                            break
                        for bug in bugs[bugsRow][:]:
                            if bullet['rect'].colliderect(bug['rect']) and not bugHit:
                                bullets.remove(bullet)
                                bugs[bugsRow].remove(bug)
                                if bugs[bugsRow] == []:
                                    del bugs[bugsRow]
                                bugHit = True # break after hitting first bug
                            elif bugHit:
                                break
                    for block in blocks[:]:
                        if bullet['rect'].colliderect(block['rect']):
                            bullets.remove(bullet)
                            if block['image'] < 4:
                                block['image'] += 1
                                block['surface'] = pygame.transform.scale(blockSprite.images[block['image']], (blockWidth,blockHeight))
                            elif block['image'] == 4:
                                blocks.remove(block)
                    if bugs == []:
                        return
                    if bullets != []:
                        bullet['y'] -= BULLETSPEED

        # move bug bullets
        if bugBullets != []:
            shipHit = False
            for bullet in bugBullets[:]:
                bullet['rect'] = pygame.Rect((bullet['x'],
                                bullet['y'],
                                bulletWidth,
                                bulletHeight))
                DISPLAYSURF.blit(bullet['surface'], bullet['rect'])
                if bullet['y'] > WINDOWHEIGHT:
                    bugBullets.remove(bullet)
                else: # collision detection
                    if not shipHit and bullet['rect'].colliderect(ships[0]['rect']):
                        bugBullets.remove(bullet)
                        del ships[0]
                        ship_x = 0
                        shipHit = True
                        if ships == []:
                            return
                    for block in blocks[:]:
                        if bullet['rect'].colliderect(block['rect']):
                            bugBullets.remove(bullet)
                            if block['image'] < 4:
                                block['image'] += 1
                                block['surface'] = pygame.transform.scale(blockSprite.images[block['image']], (blockWidth,blockHeight))
                            elif block['image'] == 4:
                                blocks.remove(block)
                    if bugBullets != []:
                        bullet['y'] += BULLETSPEED

        # check roundTimer
        if time.time() - roundTimer > 10 and bugMoveFreq > .15:
            bugMoveFreq -= .15
            roundTimer = time.time()

        # move bugs
        if (time.time() - lastMoveSideways) > bugMoveFreq and bugs != []:
            if len(bugs[0]) > 0 or len(bugs[1]) > 0 or len(bugs[2]) > 0:
                # set bug direction
                max_X = 0
                min_X = WINDOWWIDTH
                for bugRow in range(len(bugs)):
                    max_X = max(bugs[bugRow][len(bugs[bugRow])-1]['x'], max_X)
                    min_X = min(bugs[bugRow][0]['x'], min_X)
                if max_X + BUGMOVEH > WINDOWWIDTH - bugWidth:
                    bugMoveRight = False
                    bugMoveDown = True
                elif min_X - BUGMOVEH < 0:
                    bugMoveRight = True
                    bugMoveDown = True
            for bugsRow in bugs:
                for bug in bugsRow:
                    if bugMoveDown:
                        bug['y'] += BUGMOVEV
                        if bug['y'] > BUGBOUNDARY:
                            return
                    if bugMoveRight:
                        bug['x'] += BUGMOVEH
                    else:
                        bug['x'] -= BUGMOVEH
                    # alternate animation
                    if bug['image'] == 0:
                        bug['image'] = 1
                    else:
                        bug['image'] = 0
                    bug['surface'] = pygame.transform.scale(bugSprite.images[bug['image']], (bugWidth,bugHeight))
            if bugMoveDown:
                bugMoveDown = False
            lastMoveSideways = time.time()
            # bugs randomly fire
            fireBugs = []
            fireBugs_X = []
            for bugRow in range(len(bugs)-1, -1, -1):
                for bug in bugs[bugRow]:
                    if bug['x'] not in fireBugs_X:
                        fireBugs.append(bug)
                        fireBugs_X.append(bug['x'])
            for bug in fireBugs:
                if random.random() < BUGFIRECHANCE:
                    bugBullets.append({'surface':pygame.transform.scale(bulletSprite.images[0], (bulletWidth,bulletHeight)),
                            'x': bug['x'] + (bugWidth / 2) - 4,
                            'y': bug['y'] + bugHeight})

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def showGameOverScreen():
    titleSurf = pygame.font.Font('freesansbold.ttf', 100).render('Game Over', True, TEXTSHADOWCOLOR)
    titleRect = titleSurf.get_rect()
    titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
    DISPLAYSURF.blit(titleSurf, titleRect)

    titleSurf = pygame.font.Font('freesansbold.ttf', 100).render('Game Over', True, TEXTCOLOR)
    titleRect = titleSurf.get_rect()
    titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3)
    DISPLAYSURF.blit(titleSurf, titleRect)

    pressKeySurf = pygame.font.Font('freesansbold.ttf', 18).render('Press a key to play.', True, TEXTCOLOR)
    pressKeyRect = pressKeySurf.get_rect()
    pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100)
    DISPLAYSURF.blit(pressKeySurf, pressKeyRect)

    while checkForKeyPress() == None:
        pygame.display.update()
        FPSCLOCK.tick()

def checkForKeyPress():
    checkForQuit()

    for event in pygame.event.get([KEYDOWN, KEYUP, MOUSEBUTTONDOWN, MOUSEBUTTONUP, MOUSEMOTION]):
        if event.type in (KEYDOWN, MOUSEBUTTONUP, MOUSEBUTTONDOWN, MOUSEMOTION):
            continue
        return event.key
    return None

def checkForQuit():
    for event in pygame.event.get(QUIT):
        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    main()<|endoftext|>


<commit_before>"""
Buildtime Trend python library.

Features :
- parse input files with timestamps,
- retrieve and parse Travis CI build logfiles
- analyse the data
- store the results in XML format or Keen.io database
- other supporting tools

Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>

This file is part of buildtimetrend/python-lib
<https://github.com/buildtimetrend/python-lib/>

This program 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
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import logging

NAME = "buildtimetrend"
VERSION = "0.3.dev22"
SCHEMA_VERSION = "3"
USER_AGENT = "%s/%s" % (NAME, VERSION)

def get_logger():
    """Return logger object."""
    return logging.getLogger(NAME)

def set_loglevel(loglevel):
    """
    Set loglevel.

    Based on example on https://docs.python.org/2/howto/logging.html

    Assuming loglevel is bound to the string value obtained from the
    command line argument. Convert to upper case to allow the user to
    specify --log=DEBUG or --log=debug
    """
    if loglevel is None or type(loglevel) is not str:
        raise TypeError("param %s should be a string" % 'loglevel')

    numeric_level = getattr(logging, loglevel.upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError('Invalid log level: %s' % loglevel)

    # create handler
    log_handler = logging.StreamHandler()
    log_handler.setLevel(numeric_level)

    # remove default log handlers
    logger.handlers = []

    # setup logger
    logger.setLevel(numeric_level)
    logger.addHandler(log_handler)
    logger.info("Set loglevel to %s (%d)", loglevel.upper(), numeric_level)

logger = get_logger()
set_loglevel("WARNING")
<commit_msg>increment build number<commit_after>"""
Buildtime Trend python library.

Features :
- parse input files with timestamps,
- retrieve and parse Travis CI build logfiles
- analyse the data
- store the results in XML format or Keen.io database
- other supporting tools

Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>

This file is part of buildtimetrend/python-lib
<https://github.com/buildtimetrend/python-lib/>

This program 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
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import logging

NAME = "buildtimetrend"
VERSION = "0.3.dev23"
SCHEMA_VERSION = "3"
USER_AGENT = "%s/%s" % (NAME, VERSION)

def get_logger():
    """Return logger object."""
    return logging.getLogger(NAME)

def set_loglevel(loglevel):
    """
    Set loglevel.

    Based on example on https://docs.python.org/2/howto/logging.html

    Assuming loglevel is bound to the string value obtained from the
    command line argument. Convert to upper case to allow the user to
    specify --log=DEBUG or --log=debug
    """
    if loglevel is None or type(loglevel) is not str:
        raise TypeError("param %s should be a string" % 'loglevel')

    numeric_level = getattr(logging, loglevel.upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError('Invalid log level: %s' % loglevel)

    # create handler
    log_handler = logging.StreamHandler()
    log_handler.setLevel(numeric_level)

    # remove default log handlers
    logger.handlers = []

    # setup logger
    logger.setLevel(numeric_level)
    logger.addHandler(log_handler)
    logger.info("Set loglevel to %s (%d)", loglevel.upper(), numeric_level)

logger = get_logger()
set_loglevel("WARNING")
<|endoftext|>


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

#==========================================================================
#
#   Copyright Insight Software Consortium
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0.txt
#
#   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 __future__ import print_function

usage = """usage: BuildHeaderTest.py <module_name> <module_source_path> <module_binary_path> <maximum_number_of_headers>

This script generates a a source file designed to check the headers in each
module.  The generated HeaderTest can be found in the module binary 'test'
directory in a file itk<module_name>HeaderTest#.cxx.  This contains a null
main(), but includes all the classes in the module.  The primary purpose of this
test is to make sure there are not missing module dependencies.  It also tests
for syntax and missing #include's.
"""

# Headers to not test because of dependecy issues, etc.
BANNED_HEADERS = set(('itkExceptionObject.h', # There is a pre-processor check so people use itkMacro.h instead.
    'itkFFTWForwardFFTImageFilter.h',
    'itkFFTWInverseFFTImageFilter.h',
    'itkFFTWRealToHalfHermitianForwardFFTImageFilter.h',
    'itkFFTWHalfHermitianToRealInverseFFTImageFilter.h',
    'itkFFTWComplexToComplexFFTImageFilter.h',
    'itkFFTWCommon.h',
    'itkPyBuffer.h', # needs Python.h, etc
    'itkVanHerkGilWermanErodeDilateImageFilter.h', # circular include's
    'itkBSplineDeformableTransform.h',   # deprecated
    'vtkCaptureScreen.h',  # these includes require VTK
    'itkBSplineDeformableTransformInitializer.h'))

HEADER = """/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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.
 *
 *=========================================================================*/

// This file has been generated by BuildHeaderTest.py
// To regenerate, build the ITKHeaderTests target.
// This is a test to include each header file for Insight.

"""

TRAILER = """
#include <cstdlib> // needed for EXIT_SUCCESS macro

int main ( int , char* [] )
{

  return EXIT_SUCCESS;
}
"""

import glob
import os
import sys

if len(sys.argv) < 6:
    print(usage)
    sys.exit(1)

def main():
    module_name        = sys.argv[1]
    module_source_path = sys.argv[2]
    module_binary_path = sys.argv[3]
    maximum_number_of_headers = int(sys.argv[4])
    test_num           = int(sys.argv[5])

    # Get all the header files.
    include_dir = os.path.join(module_source_path, 'include')
    h_files = glob.glob(os.path.join(include_dir, '*.h'))
    h_files = [os.path.basename(h) for h in h_files]

    added_header_idx = maximum_number_of_headers * (test_num - 1)
    test_source_path = os.path.join(module_binary_path, 'test')
    if not os.path.exists(test_source_path):
        os.makedirs(test_source_path)
    test_source_file = os.path.join(test_source_path,
        str(module_name) + 'HeaderTest' + str(test_num) + '.cxx')

    test_src = open(test_source_file, 'w')
    try:
        test_src.write(HEADER)

        if added_header_idx + maximum_number_of_headers > len(h_files):
            max_idx = added_header_idx + len(h_files) % maximum_number_of_headers
        else:
            max_idx = added_header_idx + maximum_number_of_headers
        for i in range(added_header_idx, max_idx):
            # Use the .hxx if possible.
            hxx_file = h_files[i][:-1] + 'hxx'
            # Files that include VTK headers need to link to VTK.
            if h_files[i] in BANNED_HEADERS or h_files[i].lower().find('vtk') != -1:
                to_include = '// #include "' + h_files[i] + '" // Banned in BuildHeaderTest.py\n'
            elif os.path.exists(os.path.join(module_source_path, 'include',
                hxx_file)):
                to_include = '#include "' + hxx_file + '"\n'
            else:
                to_include = '#include "' + h_files[i] + '"\n'

            test_src.write(to_include)

        test_src.write(TRAILER)
    finally:
        test_src.close()

    return 0

if __name__ == "__main__":
    ret = main()
    sys.exit(ret)
<commit_msg>TEST: There are no banned headers in BuildHeaderTest for OTB<commit_after>#!/usr/bin/env python

#==========================================================================
#
#   Copyright Insight Software Consortium
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#          http://www.apache.org/licenses/LICENSE-2.0.txt
#
#   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 __future__ import print_function

usage = """usage: BuildHeaderTest.py <module_name> <module_source_path> <module_binary_path> <maximum_number_of_headers>

This script generates a a source file designed to check the headers in each
module.  The generated HeaderTest can be found in the module binary 'test'
directory in a file itk<module_name>HeaderTest#.cxx.  This contains a null
main(), but includes all the classes in the module.  The primary purpose of this
test is to make sure there are not missing module dependencies.  It also tests
for syntax and missing #include's.
"""

# Headers to not test because of dependecy issues, etc.
BANNED_HEADERS = set(()) # No banned headers in OTB for now

HEADER = """/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  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.
 *
 *=========================================================================*/

// This file has been generated by BuildHeaderTest.py
// To regenerate, build the ITKHeaderTests target.
// This is a test to include each header file for Insight.

"""

TRAILER = """
#include <cstdlib> // needed for EXIT_SUCCESS macro

int main ( int , char* [] )
{

  return EXIT_SUCCESS;
}
"""

import glob
import os
import sys

if len(sys.argv) < 6:
    print(usage)
    sys.exit(1)

def main():
    module_name        = sys.argv[1]
    module_source_path = sys.argv[2]
    module_binary_path = sys.argv[3]
    maximum_number_of_headers = int(sys.argv[4])
    test_num           = int(sys.argv[5])

    # Get all the header files.
    include_dir = os.path.join(module_source_path, 'include')
    h_files = glob.glob(os.path.join(include_dir, '*.h'))
    h_files = [os.path.basename(h) for h in h_files]

    added_header_idx = maximum_number_of_headers * (test_num - 1)
    test_source_path = os.path.join(module_binary_path, 'test')
    if not os.path.exists(test_source_path):
        os.makedirs(test_source_path)
    test_source_file = os.path.join(test_source_path,
        str(module_name) + 'HeaderTest' + str(test_num) + '.cxx')

    test_src = open(test_source_file, 'w')
    try:
        test_src.write(HEADER)

        if added_header_idx + maximum_number_of_headers > len(h_files):
            max_idx = added_header_idx + len(h_files) % maximum_number_of_headers
        else:
            max_idx = added_header_idx + maximum_number_of_headers
        for i in range(added_header_idx, max_idx):
            # Use the .hxx if possible.
            hxx_file = h_files[i][:-1] + 'hxx'
            # Files that include VTK headers need to link to VTK.
            if h_files[i] in BANNED_HEADERS or h_files[i].lower().find('vtk') != -1:
                to_include = '// #include "' + h_files[i] + '" // Banned in BuildHeaderTest.py\n'
            elif os.path.exists(os.path.join(module_source_path, 'include',
                hxx_file)):
                to_include = '#include "' + hxx_file + '"\n'
            else:
                to_include = '#include "' + h_files[i] + '"\n'

            test_src.write(to_include)

        test_src.write(TRAILER)
    finally:
        test_src.close()

    return 0

if __name__ == "__main__":
    ret = main()
    sys.exit(ret)
<|endoftext|>


<commit_before>from django.db.models.fields import AutoField

from qryresultwrapper import QryResultWrapper
from utils import modelinstance_to_dict
from exceptions import PermissionDenied
from filterspec import FilterSpecs

def _require_metaattr(cls, attr):
    """ Note that this method is also used in ``devilry.restful``. """
    if not hasattr(cls._meta, attr):
        raise ValueError('{modulename}.{classname}.Meta is missing the '
                         'required "{attr}" attribute.'.format(modulename=cls.__module__,
                                                               classname=cls.__name__,
                                                               attr=attr))
def _require_attr(cls, attr):
    if not hasattr(cls, attr):
        raise ValueError('{modulename}.{classname} is missing the '
                         'required "{attr}" attribute.'.format(modulename=cls.__module__,
                                                               classname=cls.__name__,
                                                               attr=attr))

def _create_meta_ediablefields(cls):
    if hasattr(cls._meta, 'editablefields'):
        editablefields = cls._meta.editablefields
    else:
        editablefields = cls._meta.resultfields.localfields_aslist()
        pk = cls._meta.model._meta.pk
        if pk.get_attname() in editablefields:
            if isinstance(pk, AutoField):
                editablefields.remove(pk.get_attname())
    cls._meta.editablefields = set(editablefields)

def _create_meta_ediable_fieldgroups(cls):
    if not hasattr(cls._meta, 'editable_fieldgroups'):
        cls._meta.editable_fieldgroups = cls._meta.resultfields.localfieldgroups_aslist()

class SimplifiedModelApi(object):
    """
    Base class for all simplified APIs.
    """
    @classmethod
    def write_authorize(cls, user, obj):
        raise NotImplementedError()

    @classmethod
    def read_authorize(cls, user, obj):
        cls.write_authorize(user, obj)

    @classmethod
    def _getwrapper(cls, idorkw):
        if isinstance(idorkw, dict):
            kw = idorkw
        else:
            kw = dict(pk=idorkw)
        try:
            return cls._meta.model.objects.get(**kw)
        except cls._meta.model.DoesNotExist, e:
            raise PermissionDenied() # Raise permission denied instead of "does not exist" to make it impossible to "brute force" query for existing items

    @classmethod
    def _writeauth_get(cls, user, idorkw):
        obj = cls._getwrapper(idorkw)
        cls.write_authorize(user, obj)
        return obj

    @classmethod
    def _set_values(cls, obj, field_values):
        for fieldname, value in field_values.iteritems():
            if not fieldname in cls._meta.editablefields:
                raise PermissionDenied('Field {fieldname} can not be edited.'.format(fieldname=fieldname))
            setattr(obj, fieldname, value)

    @classmethod
    def _readauth_get(cls, user, idorkw):
        obj = cls._getwrapper(idorkw)
        cls.read_authorize(user, obj)
        return obj

    @classmethod
    def handle_fieldgroups(cls, user,
                           result_fieldgroups, search_fieldgroups,
                           **validatedfilters):
        """
        Can be overridden to change fieldgroups before they are sent into the
        QryResultWrapper. For example, if certain fieldgroups contain
        senstive data for anonymous assignments, we can add those fieldgroups
        if a filter for a specific assignment is provided in ``filters`` and
        that assignment is not anonymous.

        :param validatedfilters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`. Do **NOT** change this.

        :return: (result_fieldgroups, search_fieldgroups)
        """
        return result_fieldgroups, search_fieldgroups

    @classmethod
    def create_searchqryset(cls, user):
        """
        Create search queryset.

        :return: A Django QuerySet.
        """
        raise NotImplementedError()

    @classmethod
    def _create_search_qryresultwrapper(cls, user,
                                       result_fieldgroups, search_fieldgroups,
                                       **validatedfilters):
        """
        :param validatedfilters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`.

        :return: A :class:`QryResultWrapper`.
        """
        qryset = cls.create_searchqryset(user)
        qryset = qryset.filter(**validatedfilters)
        result_fieldgroups, search_fieldgroups = cls.handle_fieldgroups(user,
                                                                        result_fieldgroups,
                                                                        search_fieldgroups,
                                                                        **validatedfilters)
        resultfields = cls._meta.resultfields.aslist(result_fieldgroups)
        searchfields = cls._meta.searchfields.aslist(search_fieldgroups)
        result = QryResultWrapper(resultfields, searchfields, qryset)
        return result

    @classmethod
    def create(cls, user, **field_values):
        """ Create the given object.

        :param user: Django user object.
        :field_values: The values to set on the given object.
        :return: The primary key of the newly created object.
        :throws PermissionDenied:
            If the given user does not have permission to edit this object,
            if the object does not exist, or if any of the ``field_values``
            is not in ``cls._meta.editablefields``.
        """
        obj =  cls._meta.model()
        cls._set_values(obj, field_values)
        cls.write_authorize(user, obj) # Important that this is after parentnode is set on Nodes, or admins on parentnode will not be permitted!
        obj.full_clean()
        obj.save()
        return obj.pk

    @classmethod
    def read(cls, user, idorkw, result_fieldgroups=[]):
        """ Read the requested item and return a dict with the fields specified
        in ``Meta.resultfields`` and additional fields specified in
        ``result_fieldgroups``.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :param result_fieldgroups:
            Fieldgroups from the additional_fieldgroups specified in
            ``result_fieldgroups``.

        :throws PermissionDenied:
            If the given user does not have permission to view this object, or
            if the object does not exist.
        """
        obj = cls._readauth_get(user, idorkw) # authorization in cls._readauth_get
        resultfields = cls._meta.resultfields.aslist(result_fieldgroups)
        #if hasattr(cls, 'filter_read_resultfields'):
            #resultfields = cls.filter_read_resultfields(user, obj, resultfields)
        return modelinstance_to_dict(obj, resultfields)

    @classmethod
    def insecure_read_model(cls, user, idorkw):
        """ Read the requested item and return a django model object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.

        :throws PermissionDenied:
            If the given user does not have permission to
            view this object, or if the object does not exist.
        """
        return cls._writeauth_get(user, idorkw)

    @classmethod
    def update(cls, user, idorkw, **field_values):
        """ Update the given object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :field_values: The values to set on the given object.
        :return: The primary key of the updated object.
        :throws PermissionDenied:
            If the given user does not have permission to edit this object,
            if the object does not exist, or if any of the ``field_values``
            is not in ``cls._meta.editablefields``.
        """
        obj = cls._getwrapper(idorkw)
        cls._set_values(obj, field_values)
        # Important to write authorize after _set_values in case any attributes
        # used in write_authorize is changed by _set_values.
        cls.write_authorize(user, obj)
        obj.full_clean()
        obj.save()
        return obj.pk

    @classmethod
    def delete(cls, user, idorkw):
        """ Delete the given object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :return: The primary key of the deleted object.
        :throws PermissionDenied:
            If the given user does not have permission to delete this object, or
            if the object does not exist.
        """
        obj = cls._writeauth_get(user, idorkw) # authorization in cls._writeauth_get
        pk = obj.pk
        obj.delete()
        return pk

    @classmethod
    def search(cls, user,
               query = '', start = 0, limit = 50, orderby = None,
               result_fieldgroups=None, search_fieldgroups=None,
               **filters):
        """ Search for objects.

        :param query:
            A string to search for within the model specified in
            ``Meta.model``. The fields to search for is specified in
            ``Meta.search_fieldgroups``.
        :param start:
            Return results from this index in the results from the given
            ``query``. Defaults to ``0``.
        :param limit:
            Limit results to this number of items. Defaults to ``50``.
        :param orderby:
            Order the result by these fields. For example, if
            ``Meta.resultfields`` contains the short_name and long_name fields,
            we can order our results by ascending short_name and descending
            long_name as this: ``orderby=('short_name', '-long_name')``.
            This defaults to ``cls._meta.ordering`` (see
            :ref:`devilry.simplified.simplified_modelapi`).
        :type orderby:
            List of fieldnames. Fieldnames can be prefixed by ``'-'`` for
            descending ordering.
        :param result_fieldgroups:
            Adds additional fields to the result. Available values are the
            fieldgroups in ``Meta.resultfields.additional_fieldgroups``.
        :param search_fieldgroups:
            Adds additional fields which are searched for the ``query`` string.
            Available values are the fieldgroups in
            ``Meta.searchfields.additional_fieldgroups``.
        :param filters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`. These filters are validated
            by :meth:`devilry.simplified.FilterSpecs.validate` before
            they are applied.

        :return: The result of the search.
        :rtype: QryResultWrapper
        """
        cls._meta.filters.validate(filters) # NOTE: This _must_ be before filters are sent on to user specified methods to ensure the filters are validated.
        result = cls._create_search_qryresultwrapper(user,
                                                    result_fieldgroups, search_fieldgroups,
                                                    **filters)
        orderby = orderby or cls._meta.ordering
        result._query_order_and_limit(query = query,
                                    start = start,
                                    limit = limit,
                                    orderby = orderby)
        return result

def simplified_modelapi(cls):
    """ Decorator which creates a simplified API for a Django model.

    The ``cls`` must have an inner class named ``Meta`` with
    the following attributes:

        model
            Then Django model. **Required**.
        methods
            A list of supported CRUD+S methods. **Required**. Legal values are:

                - create
                - read
                - insecure_read_model
                - update
                - delete
        resultfields
            A :class:`FieldSpec` which defines what fields to
            return from ``read()`` and ``search()``. **Required**.
        searchfields
            A :class:`FieldSpec` which defines what fields to
            search in ``search()``. **Required**.
        editablefields
            A list of fields that are editable. If this is not specified,
            it defaults to ``resultfields.localfields_aslist()`` with
            the primary key field removed if it is a AutoField.

            Only fields in this set may be given as ``field_values``
            to ``update()`` or ``create()``. Furthermore, these
            fields are used to generate forms in :ref:`restful`.
        editable_fieldgroups
            A list of result field groups which should at least contain
            all fields in ``editablefields``. Defaults to
            ``resultfields.localfieldgroups_aslist()``
        filters
            A :class:`devilry.simplified.FilterSpecs` limiting the possible
            filters to perform. Defaults to an empty ``FilterSpec``.

    The ``cls`` must have the following methods for handling permissions:

        read_authorize
            Authorization method used for each call to ``read()``.
        write_authorize
            Authorization method used for each call to any CRUD+S
            method except for ``read()``.
        create_searchqryset
            Method used to create the queryset filtered in search().
            Required if ``"search"`` is in ``Meta.methods``.

    The decorator adds the following attributes to ``cls``:

        _meta
            Alias for the Meta class (above).
        _meta.editablefields
        supports_create
            Boolean variable: is ``'create'`` in ``_meta.methods``.
        supports_read
            Boolean variable: is ``'read'`` in ``_meta.methods``.
        supports_insecure_read_model
            Boolean variable: is ``'insecure_read_model'`` in ``_meta.methods``.
        supports_update
            Boolean variable: is ``'update'`` in ``_meta.methods``.
        supports_delete
            Boolean variable: is ``'delete'`` in ``_meta.methods``.
    """
    #bases = tuple([SimplifiedBase] + list(cls.__bases__))
    #cls = type(cls.__name__, bases, dict(cls.__dict__))
    meta = cls.Meta
    cls._meta = meta
    cls._meta.ordering = cls._meta.model._meta.ordering

    # Check required meta options
    _require_metaattr(cls, 'model')
    _require_metaattr(cls, 'methods')
    _require_metaattr(cls, 'resultfields')
    _require_metaattr(cls, 'searchfields')
    _create_meta_ediablefields(cls)
    _create_meta_ediable_fieldgroups(cls)
    cls._meta.methods = set(cls._meta.methods)

    if not hasattr(cls._meta, 'filters'):
        cls._meta.filters = FilterSpecs()

    # Dynamically remove create(), read(), insecure_read_model(), update(), delete() if not supported
    cls._all_crud_methods = ('create', 'read', 'insecure_read_model', 'update', 'delete')
    for method in cls._all_crud_methods:
        if not method in cls._meta.methods:
            setattr(cls, method, None)

    for method in cls._all_crud_methods:
        setattr(cls, 'supports_{0}'.format(method), method in cls._meta.methods)
    return cls
<commit_msg>simplified: Docs.<commit_after>from django.db.models.fields import AutoField

from qryresultwrapper import QryResultWrapper
from utils import modelinstance_to_dict
from exceptions import PermissionDenied
from filterspec import FilterSpecs

def _require_metaattr(cls, attr):
    """ Note that this method is also used in ``devilry.restful``. """
    if not hasattr(cls._meta, attr):
        raise ValueError('{modulename}.{classname}.Meta is missing the '
                         'required "{attr}" attribute.'.format(modulename=cls.__module__,
                                                               classname=cls.__name__,
                                                               attr=attr))
def _require_attr(cls, attr):
    if not hasattr(cls, attr):
        raise ValueError('{modulename}.{classname} is missing the '
                         'required "{attr}" attribute.'.format(modulename=cls.__module__,
                                                               classname=cls.__name__,
                                                               attr=attr))

def _create_meta_ediablefields(cls):
    if hasattr(cls._meta, 'editablefields'):
        editablefields = cls._meta.editablefields
    else:
        editablefields = cls._meta.resultfields.localfields_aslist()
        pk = cls._meta.model._meta.pk
        if pk.get_attname() in editablefields:
            if isinstance(pk, AutoField):
                editablefields.remove(pk.get_attname())
    cls._meta.editablefields = set(editablefields)

def _create_meta_ediable_fieldgroups(cls):
    if not hasattr(cls._meta, 'editable_fieldgroups'):
        cls._meta.editable_fieldgroups = cls._meta.resultfields.localfieldgroups_aslist()

class SimplifiedModelApi(object):
    """
    Base class for all simplified APIs.
    """
    @classmethod
    def write_authorize(cls, user, obj):
        raise NotImplementedError()

    @classmethod
    def read_authorize(cls, user, obj):
        cls.write_authorize(user, obj)

    @classmethod
    def _getwrapper(cls, idorkw):
        if isinstance(idorkw, dict):
            kw = idorkw
        else:
            kw = dict(pk=idorkw)
        try:
            return cls._meta.model.objects.get(**kw)
        except cls._meta.model.DoesNotExist, e:
            raise PermissionDenied() # Raise permission denied instead of "does not exist" to make it impossible to "brute force" query for existing items

    @classmethod
    def _writeauth_get(cls, user, idorkw):
        obj = cls._getwrapper(idorkw)
        cls.write_authorize(user, obj)
        return obj

    @classmethod
    def _set_values(cls, obj, field_values):
        for fieldname, value in field_values.iteritems():
            if not fieldname in cls._meta.editablefields:
                raise PermissionDenied('Field {fieldname} can not be edited.'.format(fieldname=fieldname))
            setattr(obj, fieldname, value)

    @classmethod
    def _readauth_get(cls, user, idorkw):
        obj = cls._getwrapper(idorkw)
        cls.read_authorize(user, obj)
        return obj

    @classmethod
    def handle_fieldgroups(cls, user,
                           result_fieldgroups, search_fieldgroups,
                           **validatedfilters):
        """
        Can be overridden to change fieldgroups before they are sent into the
        QryResultWrapper. For example, if certain fieldgroups contain
        senstive data for anonymous assignments, we can add those fieldgroups
        if a filter for a specific assignment is provided in ``filters`` and
        that assignment is not anonymous.

        :param validatedfilters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`. Do **NOT** change this.

        :return: (result_fieldgroups, search_fieldgroups)
        """
        return result_fieldgroups, search_fieldgroups

    @classmethod
    def create_searchqryset(cls, user):
        """
        Create search queryset.

        :return: A Django QuerySet.
        """
        raise NotImplementedError()

    @classmethod
    def _create_search_qryresultwrapper(cls, user,
                                       result_fieldgroups, search_fieldgroups,
                                       **validatedfilters):
        """
        :param validatedfilters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`.

        :return: A :class:`QryResultWrapper`.
        """
        qryset = cls.create_searchqryset(user)
        qryset = qryset.filter(**validatedfilters)
        result_fieldgroups, search_fieldgroups = cls.handle_fieldgroups(user,
                                                                        result_fieldgroups,
                                                                        search_fieldgroups,
                                                                        **validatedfilters)
        resultfields = cls._meta.resultfields.aslist(result_fieldgroups)
        searchfields = cls._meta.searchfields.aslist(search_fieldgroups)
        result = QryResultWrapper(resultfields, searchfields, qryset)
        return result

    @classmethod
    def create(cls, user, **field_values):
        """ Create the given object.

        :param user: Django user object.
        :field_values: The values to set on the given object.
        :return: The primary key of the newly created object.
        :throws PermissionDenied:
            If the given user does not have permission to edit this object,
            if the object does not exist, or if any of the ``field_values``
            is not in ``cls._meta.editablefields``.
        """
        obj =  cls._meta.model()
        cls._set_values(obj, field_values)
        cls.write_authorize(user, obj) # Important that this is after parentnode is set on Nodes, or admins on parentnode will not be permitted!
        obj.full_clean()
        obj.save()
        return obj.pk

    @classmethod
    def read(cls, user, idorkw, result_fieldgroups=[]):
        """ Read the requested item and return a dict with the fields specified
        in ``Meta.resultfields`` and additional fields specified in
        ``result_fieldgroups``.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :param result_fieldgroups:
            Fieldgroups from the additional_fieldgroups specified in
            ``result_fieldgroups``.

        :throws PermissionDenied:
            If the given user does not have permission to view this object, or
            if the object does not exist.
        """
        obj = cls._readauth_get(user, idorkw) # authorization in cls._readauth_get
        resultfields = cls._meta.resultfields.aslist(result_fieldgroups)
        #if hasattr(cls, 'filter_read_resultfields'):
            #resultfields = cls.filter_read_resultfields(user, obj, resultfields)
        return modelinstance_to_dict(obj, resultfields)

    @classmethod
    def insecure_read_model(cls, user, idorkw):
        """ Read the requested item and return a django model object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.

        :throws PermissionDenied:
            If the given user does not have permission to
            view this object, or if the object does not exist.
        """
        return cls._writeauth_get(user, idorkw)

    @classmethod
    def update(cls, user, idorkw, **field_values):
        """ Update the given object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :field_values: The values to set on the given object.
        :return: The primary key of the updated object.
        :throws PermissionDenied:
            If the given user does not have permission to edit this object,
            if the object does not exist, or if any of the ``field_values``
            is not in ``cls._meta.editablefields``.
        """
        obj = cls._getwrapper(idorkw)
        cls._set_values(obj, field_values)
        # Important to write authorize after _set_values in case any attributes
        # used in write_authorize is changed by _set_values.
        cls.write_authorize(user, obj)
        obj.full_clean()
        obj.save()
        return obj.pk

    @classmethod
    def delete(cls, user, idorkw):
        """ Delete the given object.

        :param user: Django user object.
        :param idorkw: Id of object or kwargs to the get method of the configured model.
        :return: The primary key of the deleted object.
        :throws PermissionDenied:
            If the given user does not have permission to delete this object, or
            if the object does not exist.
        """
        obj = cls._writeauth_get(user, idorkw) # authorization in cls._writeauth_get
        pk = obj.pk
        obj.delete()
        return pk

    @classmethod
    def search(cls, user,
               query = '', start = 0, limit = 50, orderby = None,
               result_fieldgroups=None, search_fieldgroups=None,
               **filters):
        """ Search for objects.

        :param query:
            A string to search for within the model specified in
            ``Meta.model``. The fields to search for is specified in
            ``Meta.search_fieldgroups``.
        :param start:
            Return results from this index in the results from the given
            ``query``. Defaults to ``0``.
        :param limit:
            Limit results to this number of items. Defaults to ``50``.
        :param orderby:
            Order the result by these fields. For example, if
            ``Meta.resultfields`` contains the short_name and long_name fields,
            we can order our results by ascending short_name and descending
            long_name as this: ``orderby=('short_name', '-long_name')``.
            This defaults to ``cls._meta.ordering`` (see
            :func:`devilry.simplified.simplified_modelapi`).
        :type orderby:
            List of fieldnames. Fieldnames can be prefixed by ``'-'`` for
            descending ordering.
        :param result_fieldgroups:
            Adds additional fields to the result. Available values are the
            fieldgroups in ``Meta.resultfields.additional_fieldgroups``.
        :param search_fieldgroups:
            Adds additional fields which are searched for the ``query`` string.
            Available values are the fieldgroups in
            ``Meta.searchfields.additional_fieldgroups``.
        :param filters:
            Filters which are applied to the QuerySet returned by
            :meth:`create_searchqryset`. These filters are validated
            by :meth:`devilry.simplified.FilterSpecs.validate` before
            they are applied.

        :return: The result of the search.
        :rtype: QryResultWrapper
        """
        cls._meta.filters.validate(filters) # NOTE: This _must_ be before filters are sent on to user specified methods to ensure the filters are validated.
        result = cls._create_search_qryresultwrapper(user,
                                                    result_fieldgroups, search_fieldgroups,
                                                    **filters)
        orderby = orderby or cls._meta.ordering
        result._query_order_and_limit(query = query,
                                    start = start,
                                    limit = limit,
                                    orderby = orderby)
        return result

def simplified_modelapi(cls):
    """ Decorator which creates a simplified API for a Django model.

    The ``cls`` must have an inner class named ``Meta`` with
    the following attributes:

        model
            Then Django model. **Required**.
        methods
            A list of supported CRUD+S methods. **Required**. Legal values are:

                - create
                - read
                - insecure_read_model
                - update
                - delete
        resultfields
            A :class:`FieldSpec` which defines what fields to
            return from ``read()`` and ``search()``. **Required**.
        searchfields
            A :class:`FieldSpec` which defines what fields to
            search in ``search()``. **Required**.
        editablefields
            A list of fields that are editable. If this is not specified,
            it defaults to ``resultfields.localfields_aslist()`` with
            the primary key field removed if it is a AutoField.

            Only fields in this set may be given as ``field_values``
            to ``update()`` or ``create()``. Furthermore, these
            fields are used to generate forms in :ref:`restful`.
        editable_fieldgroups
            A list of result field groups which should at least contain
            all fields in ``editablefields``. Defaults to
            ``resultfields.localfieldgroups_aslist()``
        filters
            A :class:`devilry.simplified.FilterSpecs` limiting the possible
            filters to perform. Defaults to an empty ``FilterSpec``.

    The ``cls`` must have the following methods for handling permissions:

        read_authorize
            Authorization method used for each call to ``read()``.
        write_authorize
            Authorization method used for each call to any CRUD+S
            method except for ``read()``.
        create_searchqryset
            Method used to create the queryset filtered in search().
            Required if ``"search"`` is in ``Meta.methods``.

    The decorator adds the following attributes to ``cls``:

        _meta
            Alias for the Meta class (above).
        supports_create
            Boolean variable: is ``'create'`` in ``_meta.methods``.
        supports_read
            Boolean variable: is ``'read'`` in ``_meta.methods``.
        supports_insecure_read_model
            Boolean variable: is ``'insecure_read_model'`` in ``_meta.methods``.
        supports_update
            Boolean variable: is ``'update'`` in ``_meta.methods``.
        supports_delete
            Boolean variable: is ``'delete'`` in ``_meta.methods``.

    """
    #bases = tuple([SimplifiedBase] + list(cls.__bases__))
    #cls = type(cls.__name__, bases, dict(cls.__dict__))
    meta = cls.Meta
    cls._meta = meta
    cls._meta.ordering = cls._meta.model._meta.ordering

    # Check required meta options
    _require_metaattr(cls, 'model')
    _require_metaattr(cls, 'methods')
    _require_metaattr(cls, 'resultfields')
    _require_metaattr(cls, 'searchfields')
    _create_meta_ediablefields(cls)
    _create_meta_ediable_fieldgroups(cls)
    cls._meta.methods = set(cls._meta.methods)

    if not hasattr(cls._meta, 'filters'):
        cls._meta.filters = FilterSpecs()

    # Dynamically remove create(), read(), insecure_read_model(), update(), delete() if not supported
    cls._all_crud_methods = ('create', 'read', 'insecure_read_model', 'update', 'delete')
    for method in cls._all_crud_methods:
        if not method in cls._meta.methods:
            setattr(cls, method, None)

    for method in cls._all_crud_methods:
        setattr(cls, 'supports_{0}'.format(method), method in cls._meta.methods)
    return cls
<|endoftext|>


<commit_before># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
  'targets': [
    {
      'target_name': 'All',
      'type': 'none',
      'xcode_create_dependents_test_runner': 1,
      'dependencies': [
        '../app/app.gyp:*',
        '../base/base.gyp:*',
        '../chrome/chrome.gyp:*',
        '../ipc/ipc.gyp:*',
        '../media/media.gyp:*',
        '../net/net.gyp:*',
        '../printing/printing.gyp:*',
        '../sdch/sdch.gyp:*',
        '../skia/skia.gyp:*',
        '../testing/gmock.gyp:*',
        '../testing/gtest.gyp:*',
        '../third_party/bzip2/bzip2.gyp:*',
        '../third_party/codesighs/codesighs.gyp:*',
        '../third_party/ffmpeg/ffmpeg.gyp:*',
        '../third_party/icu/icu.gyp:*',
        '../third_party/libjpeg/libjpeg.gyp:*',
        '../third_party/libpng/libpng.gyp:*',
        '../third_party/libxml/libxml.gyp:*',
        '../third_party/libxslt/libxslt.gyp:*',
        '../third_party/lzma_sdk/lzma_sdk.gyp:*',
        '../third_party/modp_b64/modp_b64.gyp:*',
        '../third_party/npapi/npapi.gyp:*',
        '../third_party/sqlite/sqlite.gyp:*',
        '../third_party/zlib/zlib.gyp:*',
        '../webkit/tools/test_shell/test_shell.gyp:*',
        '../webkit/webkit.gyp:*',
        'util/build_util.gyp:*',
        'temp_gyp/googleurl.gyp:*',
      ],
      'conditions': [
        ['javascript_engine=="v8"', {
          'dependencies': [
            '../v8/tools/gyp/v8.gyp:*',
          ],
        }],
        ['OS=="linux"', {
          'dependencies': [
            '../breakpad/breakpad.gyp:*',
            '../sandbox/sandbox.gyp:*',
            '../third_party/harfbuzz/harfbuzz.gyp:*',
            '../tools/gtk_clipboard_dump/gtk_clipboard_dump.gyp:*',
            '../tools/xdisplaycheck/xdisplaycheck.gyp:*',
            '../courgette/courgette.gyp:*',
          ],
          'conditions': [
            ['branding=="Chrome"', {
              'dependencies': [
                '../chrome/installer/installer.gyp:linux_packages',
              ],
            }],
          ],
        }],
        ['OS=="win"', {
          'dependencies': [
            '../breakpad/breakpad.gyp:*',
            '../chrome/app/locales/locales.gyp:*',
            '../courgette/courgette.gyp:*',
            '../gears/gears.gyp:*',
            '../rlz/rlz.gyp:*',
            '../sandbox/sandbox.gyp:*',
            '../third_party/bsdiff/bsdiff.gyp:*',
            '../third_party/bspatch/bspatch.gyp:*',
            '../third_party/cld/cld.gyp:*',
            '../third_party/tcmalloc/tcmalloc.gyp:*',
            '../tools/memory_watcher/memory_watcher.gyp:*',
          ],
        }, {
          'dependencies': [
            '../third_party/libevent/libevent.gyp:*',
          ],
        }],
        ['OS=="win" or (OS=="linux" and toolkit_views==1)', {
          'dependencies': [
            '../views/views.gyp:*',
          ],
        }],
      ],
    },
  ],
  'conditions': [
    ['OS=="mac"', {
      'targets': [
        {
          # Target to build everything plus the dmg.  We don't put the dmg
          # in the All target because developers really don't need it.
          'target_name': 'all_and_dmg',
          'type': 'none',
          'dependencies': [
            'All',
            '../chrome/chrome.gyp:build_app_dmg',
          ],
        },
        # These targets are here so the build bots can use them to build
        # subsets of a full tree for faster cycle times.
        {
          'target_name': 'chromium_builder_dbg',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
          ],
        },
        {
          'target_name': 'chromium_builder_rel',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../chrome/chrome.gyp:memory_test',
            '../chrome/chrome.gyp:page_cycler_tests',
            '../chrome/chrome.gyp:startup_tests',
            '../chrome/chrome.gyp:tab_switching_test',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
            '../chrome/chrome.gyp:url_fetch_test',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
          ],
        },
      ],  # targets
    }], # OS="mac"
    ['OS=="win"', {
      'targets': [
        # These targets are here so the build bots can use them to build
        # subsets of a full tree for faster cycle times.
        {
          'target_name': 'chromium_builder',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../chrome/chrome.gyp:browser_tests',
            '../chrome/chrome.gyp:interactive_ui_tests',
            '../chrome/chrome.gyp:memory_test',
            '../chrome/chrome.gyp:page_cycler_tests',
            '../chrome/chrome.gyp:plugin_tests',
            '../chrome/chrome.gyp:startup_tests',
            '../chrome/chrome.gyp:tab_switching_test',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
            '../chrome/chrome.gyp:url_fetch_test',
            '../chrome/installer/installer.gyp:installer_util_unittests',
            '../chrome/installer/installer.gyp:mini_installer_test',
            # mini_installer_tests depends on mini_installer. This should be
            # defined in installer.gyp.
            '../chrome/installer/mini_installer.gyp:mini_installer',
            '../courgette/courgette.gyp:courgette_unittests',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
            '../webkit/tools/test_shell/test_shell.gyp:npapi_layout_test_plugin',
            # TODO(nsylvain) ui_tests.exe depends on test_shell_common.
            # This should:
            # 1) not be the case. OR.
            # 2) be expressed in the ui tests dependencies.
            '../webkit/tools/test_shell/test_shell.gyp:test_shell_common',
            'temp_gyp/googleurl.gyp:googleurl_unittests',
          ],
        },
        {
          'target_name': 'purify_builder_ui',
          'type': 'none',
          'dependencies': [
            '../chrome/chrome.gyp:ui_tests',
          ],
        },
        {
          'target_name': 'purify_builder_unit',
          'type': 'none',
          'dependencies': [
            '../chrome/chrome.gyp:unit_tests',
          ],
        },
        {
          'target_name': 'purify_builder_webkit',
          'type': 'none',
          'dependencies': [
            '../webkit/tools/test_shell/test_shell.gyp:test_shell_tests',
            '../webkit/tools/test_shell/test_shell.gyp:test_shell',
          ],
        },
      ],  # targets
    }], # OS="win"
  ], # conditions
}
<commit_msg>The builders should build sync_unit_tests.<commit_after># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
  'targets': [
    {
      'target_name': 'All',
      'type': 'none',
      'xcode_create_dependents_test_runner': 1,
      'dependencies': [
        '../app/app.gyp:*',
        '../base/base.gyp:*',
        '../chrome/chrome.gyp:*',
        '../ipc/ipc.gyp:*',
        '../media/media.gyp:*',
        '../net/net.gyp:*',
        '../printing/printing.gyp:*',
        '../sdch/sdch.gyp:*',
        '../skia/skia.gyp:*',
        '../testing/gmock.gyp:*',
        '../testing/gtest.gyp:*',
        '../third_party/bzip2/bzip2.gyp:*',
        '../third_party/codesighs/codesighs.gyp:*',
        '../third_party/ffmpeg/ffmpeg.gyp:*',
        '../third_party/icu/icu.gyp:*',
        '../third_party/libjpeg/libjpeg.gyp:*',
        '../third_party/libpng/libpng.gyp:*',
        '../third_party/libxml/libxml.gyp:*',
        '../third_party/libxslt/libxslt.gyp:*',
        '../third_party/lzma_sdk/lzma_sdk.gyp:*',
        '../third_party/modp_b64/modp_b64.gyp:*',
        '../third_party/npapi/npapi.gyp:*',
        '../third_party/sqlite/sqlite.gyp:*',
        '../third_party/zlib/zlib.gyp:*',
        '../webkit/tools/test_shell/test_shell.gyp:*',
        '../webkit/webkit.gyp:*',
        'util/build_util.gyp:*',
        'temp_gyp/googleurl.gyp:*',
      ],
      'conditions': [
        ['javascript_engine=="v8"', {
          'dependencies': [
            '../v8/tools/gyp/v8.gyp:*',
          ],
        }],
        ['OS=="linux"', {
          'dependencies': [
            '../breakpad/breakpad.gyp:*',
            '../sandbox/sandbox.gyp:*',
            '../third_party/harfbuzz/harfbuzz.gyp:*',
            '../tools/gtk_clipboard_dump/gtk_clipboard_dump.gyp:*',
            '../tools/xdisplaycheck/xdisplaycheck.gyp:*',
            '../courgette/courgette.gyp:*',
          ],
          'conditions': [
            ['branding=="Chrome"', {
              'dependencies': [
                '../chrome/installer/installer.gyp:linux_packages',
              ],
            }],
          ],
        }],
        ['OS=="win"', {
          'dependencies': [
            '../breakpad/breakpad.gyp:*',
            '../chrome/app/locales/locales.gyp:*',
            '../courgette/courgette.gyp:*',
            '../gears/gears.gyp:*',
            '../rlz/rlz.gyp:*',
            '../sandbox/sandbox.gyp:*',
            '../third_party/bsdiff/bsdiff.gyp:*',
            '../third_party/bspatch/bspatch.gyp:*',
            '../third_party/cld/cld.gyp:*',
            '../third_party/tcmalloc/tcmalloc.gyp:*',
            '../tools/memory_watcher/memory_watcher.gyp:*',
          ],
        }, {
          'dependencies': [
            '../third_party/libevent/libevent.gyp:*',
          ],
        }],
        ['OS=="win" or (OS=="linux" and toolkit_views==1)', {
          'dependencies': [
            '../views/views.gyp:*',
          ],
        }],
      ],
    },
  ],
  'conditions': [
    ['OS=="mac"', {
      'targets': [
        {
          # Target to build everything plus the dmg.  We don't put the dmg
          # in the All target because developers really don't need it.
          'target_name': 'all_and_dmg',
          'type': 'none',
          'dependencies': [
            'All',
            '../chrome/chrome.gyp:build_app_dmg',
          ],
        },
        # These targets are here so the build bots can use them to build
        # subsets of a full tree for faster cycle times.
        {
          'target_name': 'chromium_builder_dbg',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
          ],
        },
        {
          'target_name': 'chromium_builder_rel',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../chrome/chrome.gyp:memory_test',
            '../chrome/chrome.gyp:page_cycler_tests',
            '../chrome/chrome.gyp:startup_tests',
            '../chrome/chrome.gyp:tab_switching_test',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
            '../chrome/chrome.gyp:url_fetch_test',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
          ],
        },
      ],  # targets
    }], # OS="mac"
    ['OS=="win"', {
      'targets': [
        # These targets are here so the build bots can use them to build
        # subsets of a full tree for faster cycle times.
        {
          'target_name': 'chromium_builder',
          'type': 'none',
          'dependencies': [
            '../app/app.gyp:app_unittests',
            '../chrome/chrome.gyp:browser_tests',
            '../chrome/chrome.gyp:interactive_ui_tests',
            '../chrome/chrome.gyp:memory_test',
            '../chrome/chrome.gyp:page_cycler_tests',
            '../chrome/chrome.gyp:plugin_tests',
            '../chrome/chrome.gyp:startup_tests',
            '../chrome/chrome.gyp:sync_unit_tests',
            '../chrome/chrome.gyp:tab_switching_test',
            '../chrome/chrome.gyp:ui_tests',
            '../chrome/chrome.gyp:unit_tests',
            '../chrome/chrome.gyp:url_fetch_test',
            '../chrome/installer/installer.gyp:installer_util_unittests',
            '../chrome/installer/installer.gyp:mini_installer_test',
            # mini_installer_tests depends on mini_installer. This should be
            # defined in installer.gyp.
            '../chrome/installer/mini_installer.gyp:mini_installer',
            '../courgette/courgette.gyp:courgette_unittests',
            '../ipc/ipc.gyp:ipc_tests',
            '../media/media.gyp:media_unittests',
            '../printing/printing.gyp:printing_unittests',
            '../webkit/tools/test_shell/test_shell.gyp:npapi_layout_test_plugin',
            # TODO(nsylvain) ui_tests.exe depends on test_shell_common.
            # This should:
            # 1) not be the case. OR.
            # 2) be expressed in the ui tests dependencies.
            '../webkit/tools/test_shell/test_shell.gyp:test_shell_common',
            'temp_gyp/googleurl.gyp:googleurl_unittests',
          ],
        },
        {
          'target_name': 'purify_builder_ui',
          'type': 'none',
          'dependencies': [
            '../chrome/chrome.gyp:ui_tests',
          ],
        },
        {
          'target_name': 'purify_builder_unit',
          'type': 'none',
          'dependencies': [
            '../chrome/chrome.gyp:unit_tests',
          ],
        },
        {
          'target_name': 'purify_builder_webkit',
          'type': 'none',
          'dependencies': [
            '../webkit/tools/test_shell/test_shell.gyp:test_shell_tests',
            '../webkit/tools/test_shell/test_shell.gyp:test_shell',
          ],
        },
      ],  # targets
    }], # OS="win"
  ], # conditions
}
<|endoftext|>


<commit_before>import os
import boto
from boto.s3.key import Key
import msmbuilder.version

# The secret key is available as a secure environment variable
# on travis-ci to push the build documentation to Amazon S3.
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
BUCKET_NAME = 'msmbuilder.org'

bucket_name = AWS_ACCESS_KEY_ID.lower() + '-' + BUCKET_NAME
conn = boto.connect_s3(AWS_ACCESS_KEY_ID,
            AWS_SECRET_ACCESS_KEY)
bucket = conn.get_bucket(BUCKET_NAME)

root = 'doc/_build'
for dirpath, dirnames, filenames in os.walk(root):
    for filename in filenames:
        fn = os.path.join(dirpath, filename)
        print 'Uploading', fn, '...'
        k = Key(bucket)
        if not msmbuilder.version.release:
            prefix = 'latest'
        else:
            prefix = msmbuilder.version.short_version
        k.key =  os.path.join(prefix, os.path.relpath(fn, root))
        k.set_contents_from_filename(fn)
<commit_msg>Update push-docs-to-s3.py<commit_after>import os
import boto
from boto.s3.key import Key
from boto.s3.connection import SubdomainCallingFormat
import msmbuilder.version

# The secret key is available as a secure environment variable
# on travis-ci to push the build documentation to Amazon S3.
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
BUCKET_NAME = 'msmbuilder.org'

bucket_name = AWS_ACCESS_KEY_ID.lower() + '-' + BUCKET_NAME
conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, calling_format=SubdomainCallingFormat)
bucket = conn.get_bucket(BUCKET_NAME)

root = 'doc/_build'
for dirpath, dirnames, filenames in os.walk(root):
    for filename in filenames:
        fn = os.path.join(dirpath, filename)
        print 'Uploading', fn, '...'
        k = Key(bucket)
        if not msmbuilder.version.release:
            prefix = 'latest'
        else:
            prefix = msmbuilder.version.short_version
        k.key =  os.path.join(prefix, os.path.relpath(fn, root))
        k.set_contents_from_filename(fn)
<|endoftext|>