<commit_before># Copyright 2020 Google LLC
#
# 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
#
#     https://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.

# [START composer_dataflow_dag]

"""Example Airflow DAG that creates a Cloud Dataproc cluster, runs the Hadoop
wordcount example, and deletes the cluster.

This DAG relies on three Airflow variables
https://airflow.apache.org/concepts.html#variables
* project_id - Google Cloud Project ID to use for the Cloud Dataflow cluster.
* gce_zone - Google Compute Engine zone where Cloud Dataflow cluster should be
  created.
* gce_region - Google Compute Engine region where Cloud Dataflow cluster should be
  created.
Learn more about the difference between the two here:
https://cloud.google.com/compute/docs/regions-zones
* bucket_path - Google Cloud Storage bucket where you've stored the User Defined
Function (.js), the input file (.txt), and the JSON schema (.json).
"""

import datetime

from airflow import models
from airflow.contrib.operators.dataflow_operator import DataflowTemplateOperator
from airflow.utils.dates import days_ago

bucket_path = models.Variable.get("bucket_path")
project_id = models.Variable.get("project_id")
gce_zone = models.Variable.get("gce_zone")
gce_region = models.Variable.get("gce_region")

default_args = {
    # Tell airflow to start one day ago, so that it runs as soon as you upload it
    "start_date": days_ago(1),
    "dataflow_default_options": {
        "project": project_id,
        # Set to your region
        "region": gce_region,
        # Set to your zone
        "zone": gce_zone,
        # This is a subfolder for storing temporary files, like the staged pipeline job.
        "temp_location": bucket_path + "/tmp/",
    },
}

# Define a DAG (directed acyclic graph) of tasks.
# Any task you create within the context manager is automatically added to the
# DAG object.
with models.DAG(
    # The id you will see in the DAG airflow page
    "composer_dataflow_dag",
    default_args=default_args,
    # The interval with which to schedule the DAG
    schedule_interval=datetime.timedelta(days=1),  # Override to match your needs
) as dag:

    start_template_job = DataflowTemplateOperator(
        # The task id of your job
        task_id="dataflow_operator_transform_csv_to_bq",
        # The name of the template that you're using.
        # Below is a list of all the templates you can use.
        # For versions in non-production environments, use the subfolder 'latest'
        # https://cloud.google.com/dataflow/docs/guides/templates/provided-batch#gcstexttobigquery
        template="gs://dataflow-templates/latest/GCS_Text_to_BigQuery",
        # Use the link above to specify the correct parameters for your template.
        parameters={
            "javascriptTextTransformFunctionName": "transformCSVtoJSON",
            "JSONPath": bucket_path + "/jsonSchema.json",
            "javascriptTextTransformGcsPath": bucket_path + "/transformCSVtoJSON.js",
            "inputFilePattern": bucket_path + "/inputFile.txt",
            "outputTable": project_id + ":average_weather.average_weather",
            "bigQueryLoadingTemporaryDirectory": bucket_path + "/tmp/",
        },
    )

# [END composer_dataflow_dag]
<commit_msg>chore: fix comments on Dataflow example (#4484)<commit_after># Copyright 2020 Google LLC
#
# 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
#
#     https://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.

# [START composer_dataflow_dag]

"""Example Airflow DAG that creates a Cloud Dataflow workflow which takes a
text file and adds the rows to a BigQuery table.

This DAG relies on four Airflow variables
https://airflow.apache.org/concepts.html#variables
* project_id - Google Cloud Project ID to use for the Cloud Dataflow cluster.
* gce_zone - Google Compute Engine zone where Cloud Dataflow cluster should be
  created.
* gce_region - Google Compute Engine region where Cloud Dataflow cluster should be
  created.
Learn more about the difference between the two here:
https://cloud.google.com/compute/docs/regions-zones
* bucket_path - Google Cloud Storage bucket where you've stored the User Defined
Function (.js), the input file (.txt), and the JSON schema (.json).
"""

import datetime

from airflow import models
from airflow.contrib.operators.dataflow_operator import DataflowTemplateOperator
from airflow.utils.dates import days_ago

bucket_path = models.Variable.get("bucket_path")
project_id = models.Variable.get("project_id")
gce_zone = models.Variable.get("gce_zone")
gce_region = models.Variable.get("gce_region")

default_args = {
    # Tell airflow to start one day ago, so that it runs as soon as you upload it
    "start_date": days_ago(1),
    "dataflow_default_options": {
        "project": project_id,
        # Set to your region
        "region": gce_region,
        # Set to your zone
        "zone": gce_zone,
        # This is a subfolder for storing temporary files, like the staged pipeline job.
        "temp_location": bucket_path + "/tmp/",
    },
}

# Define a DAG (directed acyclic graph) of tasks.
# Any task you create within the context manager is automatically added to the
# DAG object.
with models.DAG(
    # The id you will see in the DAG airflow page
    "composer_dataflow_dag",
    default_args=default_args,
    # The interval with which to schedule the DAG
    schedule_interval=datetime.timedelta(days=1),  # Override to match your needs
) as dag:

    start_template_job = DataflowTemplateOperator(
        # The task id of your job
        task_id="dataflow_operator_transform_csv_to_bq",
        # The name of the template that you're using.
        # Below is a list of all the templates you can use.
        # For versions in non-production environments, use the subfolder 'latest'
        # https://cloud.google.com/dataflow/docs/guides/templates/provided-batch#gcstexttobigquery
        template="gs://dataflow-templates/latest/GCS_Text_to_BigQuery",
        # Use the link above to specify the correct parameters for your template.
        parameters={
            "javascriptTextTransformFunctionName": "transformCSVtoJSON",
            "JSONPath": bucket_path + "/jsonSchema.json",
            "javascriptTextTransformGcsPath": bucket_path + "/transformCSVtoJSON.js",
            "inputFilePattern": bucket_path + "/inputFile.txt",
            "outputTable": project_id + ":average_weather.average_weather",
            "bigQueryLoadingTemporaryDirectory": bucket_path + "/tmp/",
        },
    )

# [END composer_dataflow_dag]
<|endoftext|>


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

# Max Basescu
# mbasesc1@jhu.edu
#
# This script takes user specified details containing:
# Laps - the number of laps to run the program for
# Rat number - the current rat's identification number
# Training day - the current day of training
# dTheta0 - the initial angle interval between feedings
# dTheta1 - the final angle interval between feedings
#
# Across the trial, the angle interval between feedings is
# transitioned linearly from dTheta0 to dTheta1 with
# +- 20deg randomness

import math
import csv
import time
import random
import RPi.GPIO as GPIO
import Adafruit_CharLCD as LCD
import UserInput as UINPUT

# Initialize the LCD using the pins
lcd = LCD.Adafruit_CharLCDPlate()
lcd.show_cursor(True)

# Setup GPIO pins for motor pulsing and encoder reading
motorPin = 17
ledPin = 18
buttonPin = 25
encoderPinA = 22
encoderPinB = 23
GPIO.setup(motorPin, GPIO.OUT)
GPIO.setup(ledPin, GPIO.OUT)
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(encoderPinA, GPIO.IN)
GPIO.setup(encoderPinB, GPIO.IN)

# Set backlight color to blue
lcd.set_color(0.0, 0.0, 1.0)
lcd.clear()

# Initialization of current angle, theta
theta = 0

# Number of encoder readings per revolution
thetaLap = 8192

# Duration of motor per feeding
pulseDur = 4800 # ms

# Triggered by an interrupt from the button, this function
# starts the motor and logs the event
def buttonPress(ch):
	try:
		global f, buttonFeedStart, buttonIsFeeding

		# Only do stuff if we're not already pulsing
		if tCurr - buttonFeedStart > pulseDur:
			f.write('event | time={},manFeed=1\n'.format(tCurr))
			GPIO.output(motorPin, True)
			GPIO.output(ledPin, True)
			buttonFeedStart = tCurr
			buttonIsFeeding = True

	except:
		pass

# Triggered by an edge on pin A, this function modifies
# the value of theta according to the encoder state
def readEncoderA(ch):
	global theta

	# Grab readings from the pins
	aState = GPIO.input(encoderPinA)
	bState = GPIO.input(encoderPinB)

	# Look for rising edge on A
	if aState == True:
		# Check direction of encoder turning
		if bState == False:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

	# There's a falling edge on A
	else:
		# Check direction of encoder turning
		if bState == True:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

# Triggered by an edge on pin B, this function modifies
# the value of theta according to the encoder state
def readEncoderB(ch):
	global theta

	# Grab readings from the pins
	aState = GPIO.input(encoderPinA)
	bState = GPIO.input(encoderPinB)

	# Look for rising edge on B
	if bState == True:
		# Check direction of encoder turning
		if aState == True:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

	# There's a falling edge on B
	else:
		# Check direction of encoder turning
		if aState == False:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

# Attach interrupts
GPIO.add_event_detect(encoderPinA, GPIO.BOTH, callback = readEncoderA)
GPIO.add_event_detect(encoderPinB, GPIO.BOTH, callback = readEncoderB)
GPIO.add_event_detect(buttonPin, GPIO.RISING, callback = buttonPress, bouncetime = pulseDur)

# Converts encoder angle to degrees
def toDeg(ang):
	return int(float(ang) / thetaLap * 360)

# Converts degrees to encoder angle
def toEnc(ang):
	return int(float(ang) / 360 * thetaLap)

print("Press Ctrl-C to quit.")

# Default string values
lapsStr = "0    "
ratStr = "0    "
dayStr = "0    "
dTheta0Str = "0    "
dTheta1Str = "0    "

# Loading previous entries from params file
paramsFile = 'params.csv'
try:
	pFile = open(paramsFile, 'r+')
	params = next(csv.reader(pFile, delimiter=','))
	lapsStr = params[0]
	ratStr = params[1]
	dayStr = params[2]
	dTheta0Str = params[3]
	dTheta1Str = params[4]
except:
	pFile = open(paramsFile, 'w') # Create the file

# Gets various fields from user (third argument specifies minimum input accepted)
laps = UINPUT.genForm(lcd, 'Laps', lapsStr, 1)
print('# of Laps: ' + str(laps))
goal = laps * 360 # Converting laps into goal degrees
ratNum = UINPUT.genForm(lcd, 'Rat Num', ratStr, 0)
print('Rat Num: ' + str(ratNum))
day = UINPUT.genForm(lcd, 'Day', dayStr, 0)
print('Day: ' + str(day))
dTheta0 = UINPUT.genForm(lcd, 'dTheta0', dTheta0Str, 0)
print('dTheta0: ' + str(dTheta0))
dTheta1 = UINPUT.genForm(lcd, 'dTheta1', dTheta1Str, 0)
print('dTheta1: ' + str(dTheta1))

# Write new parameters to file
pFile.seek(0)
pFile.write('{:<5},{:<5},{:<5},{:<5},{:<5}'.format(str(laps), str(ratNum), str(day), str(dTheta0), str(dTheta1)))
pFile.close()

# Clear display and set color to red for trial
lcd.clear()
lcd.set_color(1.0, 0.0, 0.0)

# Stop showing cursor on screen
lcd.show_cursor(False)

# Local base path to log folder
logBase = 'logs/'

# Opens log file
fName = logBase + time.strftime("%y%m%d") + "_rat" + str(ratNum) + "_day" + str(day) + "_training.dat"
f = open(fName, "a")

# Prints info, then converts values in degrees into values compatible with encoder readings
f.write('\nglobal | dTheta0={},dTheta1={},pulseDur={},goal={}\n'.format(dTheta0, dTheta1, pulseDur, goal))
dTheta0 = toEnc(dTheta0)
dTheta1 = toEnc(dTheta1)
goal = toEnc(goal)

# Writes general trial info including timestamp
f.write('global | rat={},day={}\n'.format(ratNum,day))
f.write('global | year={},month={},date={},hour={},min={},sec={}\n\n'.format(time.strftime('%Y'),time.strftime('%m'),time.strftime('%d'),time.strftime('%H'),time.strftime('%M'),time.strftime('%S')))

# Begin running actual training program:

# Variable initialization
theta = 0 # Zero out theta
isFeeding = False # Whether or not the motor is currently pulsing
feedStart = 0 # Contains the time at which the motor was started
buttonFeedStart = 0 # Contains the time at which the button was pressed
buttonIsFeeding = False # Whether or not there is a button pulse going
nextFeedAng = 0 # Stores next angle at which to begin feeding
tInit = time.time() # Establish offset time

# Until the rat has run the specified number of laps
while theta < goal:
	tCurr = int(math.floor((time.time() - tInit) * 1000)) # Grabs current time in milliseconds
	f.write('data | time={},theta={}\n'.format(tCurr, theta))

	# If we're at the end of a button pulse
	if tCurr - buttonFeedStart >= pulseDur and buttonIsFeeding == True:
		buttonIsFeeding = False

		# Stop pulsing motor
		GPIO.output(motorPin, False)
		GPIO.output(ledPin, False)

		# Write disable to log
		f.write('event | time={},manFeed=0\n'.format(tCurr))

	# Arrived at feeding location
	if not isFeeding and theta >= nextFeedAng:
		feedStart = tCurr
		isFeeding = True

		# Begin pulsing motor
		GPIO.output(ledPin, True)
		GPIO.output(motorPin, True)

		# Write enable to log
		f.write('event | time={},feed=1\n'.format(tCurr))

	# End of feeding period
	elif isFeeding and tCurr - feedStart >= pulseDur:
		isFeeding = False

		# Stop pulsing motor
		GPIO.output(ledPin, False)
		GPIO.output(motorPin, False)

		# Calculate current interval between feedings and next feed angle
		dTheta = dTheta0 + (dTheta1 - dTheta0) * theta / goal
		nextFeedAng = theta + dTheta + random.randint(-455, 455)

		# Write disable to log
		f.write('event | time={},feed=0\n'.format(tCurr))

	time.sleep(0.01) # Wait 10 ms

# Update time and write end of session to file
tCurr = int(math.floor((time.time() - tInit) * 1000))
f.write('event | time={},goal=1\n#\n'.format(tCurr))

# Turn motor off if it's on
GPIO.output(motorPin, False)
GPIO.output(ledPin, False)
GPIO.cleanup()
f.close()
exit(0)
<commit_msg>Reverted pulse duration due to switch back to 9v<commit_after># coding: utf-8
#!/usr/bin/python

# Max Basescu
# mbasesc1@jhu.edu
#
# This script takes user specified details containing:
# Laps - the number of laps to run the program for
# Rat number - the current rat's identification number
# Training day - the current day of training
# dTheta0 - the initial angle interval between feedings
# dTheta1 - the final angle interval between feedings
#
# Across the trial, the angle interval between feedings is
# transitioned linearly from dTheta0 to dTheta1 with
# +- 20deg randomness

import math
import csv
import time
import random
import RPi.GPIO as GPIO
import Adafruit_CharLCD as LCD
import UserInput as UINPUT

# Initialize the LCD using the pins
lcd = LCD.Adafruit_CharLCDPlate()
lcd.show_cursor(True)

# Setup GPIO pins for motor pulsing and encoder reading
motorPin = 17
ledPin = 18
buttonPin = 25
encoderPinA = 22
encoderPinB = 23
GPIO.setup(motorPin, GPIO.OUT)
GPIO.setup(ledPin, GPIO.OUT)
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(encoderPinA, GPIO.IN)
GPIO.setup(encoderPinB, GPIO.IN)

# Set backlight color to blue
lcd.set_color(0.0, 0.0, 1.0)
lcd.clear()

# Initialization of current angle, theta
theta = 0

# Number of encoder readings per revolution
thetaLap = 8192

# Duration of motor per feeding
pulseDur = 2100 # ms

# Triggered by an interrupt from the button, this function
# starts the motor and logs the event
def buttonPress(ch):
	try:
		global f, buttonFeedStart, buttonIsFeeding

		# Only do stuff if we're not already pulsing
		if tCurr - buttonFeedStart > pulseDur:
			f.write('event | time={},manFeed=1\n'.format(tCurr))
			GPIO.output(motorPin, True)
			GPIO.output(ledPin, True)
			buttonFeedStart = tCurr
			buttonIsFeeding = True

	except:
		pass

# Triggered by an edge on pin A, this function modifies
# the value of theta according to the encoder state
def readEncoderA(ch):
	global theta

	# Grab readings from the pins
	aState = GPIO.input(encoderPinA)
	bState = GPIO.input(encoderPinB)

	# Look for rising edge on A
	if aState == True:
		# Check direction of encoder turning
		if bState == False:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

	# There's a falling edge on A
	else:
		# Check direction of encoder turning
		if bState == True:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

# Triggered by an edge on pin B, this function modifies
# the value of theta according to the encoder state
def readEncoderB(ch):
	global theta

	# Grab readings from the pins
	aState = GPIO.input(encoderPinA)
	bState = GPIO.input(encoderPinB)

	# Look for rising edge on B
	if bState == True:
		# Check direction of encoder turning
		if aState == True:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

	# There's a falling edge on B
	else:
		# Check direction of encoder turning
		if aState == False:
			theta -= 1 # CW
		else:
			theta += 1 # CCW

# Attach interrupts
GPIO.add_event_detect(encoderPinA, GPIO.BOTH, callback = readEncoderA)
GPIO.add_event_detect(encoderPinB, GPIO.BOTH, callback = readEncoderB)
GPIO.add_event_detect(buttonPin, GPIO.RISING, callback = buttonPress, bouncetime = pulseDur)

# Converts encoder angle to degrees
def toDeg(ang):
	return int(float(ang) / thetaLap * 360)

# Converts degrees to encoder angle
def toEnc(ang):
	return int(float(ang) / 360 * thetaLap)

print("Press Ctrl-C to quit.")

# Default string values
lapsStr = "0    "
ratStr = "0    "
dayStr = "0    "
dTheta0Str = "0    "
dTheta1Str = "0    "

# Loading previous entries from params file
paramsFile = 'params.csv'
try:
	pFile = open(paramsFile, 'r+')
	params = next(csv.reader(pFile, delimiter=','))
	lapsStr = params[0]
	ratStr = params[1]
	dayStr = params[2]
	dTheta0Str = params[3]
	dTheta1Str = params[4]
except:
	pFile = open(paramsFile, 'w') # Create the file

# Gets various fields from user (third argument specifies minimum input accepted)
laps = UINPUT.genForm(lcd, 'Laps', lapsStr, 1)
print('# of Laps: ' + str(laps))
goal = laps * 360 # Converting laps into goal degrees
ratNum = UINPUT.genForm(lcd, 'Rat Num', ratStr, 0)
print('Rat Num: ' + str(ratNum))
day = UINPUT.genForm(lcd, 'Day', dayStr, 0)
print('Day: ' + str(day))
dTheta0 = UINPUT.genForm(lcd, 'dTheta0', dTheta0Str, 0)
print('dTheta0: ' + str(dTheta0))
dTheta1 = UINPUT.genForm(lcd, 'dTheta1', dTheta1Str, 0)
print('dTheta1: ' + str(dTheta1))

# Write new parameters to file
pFile.seek(0)
pFile.write('{:<5},{:<5},{:<5},{:<5},{:<5}'.format(str(laps), str(ratNum), str(day), str(dTheta0), str(dTheta1)))
pFile.close()

# Clear display and set color to red for trial
lcd.clear()
lcd.set_color(1.0, 0.0, 0.0)

# Stop showing cursor on screen
lcd.show_cursor(False)

# Local base path to log folder
logBase = 'logs/'

# Opens log file
fName = logBase + time.strftime("%y%m%d") + "_rat" + str(ratNum) + "_day" + str(day) + "_training.dat"
f = open(fName, "a")

# Prints info, then converts values in degrees into values compatible with encoder readings
f.write('\nglobal | dTheta0={},dTheta1={},pulseDur={},goal={}\n'.format(dTheta0, dTheta1, pulseDur, goal))
dTheta0 = toEnc(dTheta0)
dTheta1 = toEnc(dTheta1)
goal = toEnc(goal)

# Writes general trial info including timestamp
f.write('global | rat={},day={}\n'.format(ratNum,day))
f.write('global | year={},month={},date={},hour={},min={},sec={}\n\n'.format(time.strftime('%Y'),time.strftime('%m'),time.strftime('%d'),time.strftime('%H'),time.strftime('%M'),time.strftime('%S')))

# Begin running actual training program:

# Variable initialization
theta = 0 # Zero out theta
isFeeding = False # Whether or not the motor is currently pulsing
feedStart = 0 # Contains the time at which the motor was started
buttonFeedStart = 0 # Contains the time at which the button was pressed
buttonIsFeeding = False # Whether or not there is a button pulse going
nextFeedAng = 0 # Stores next angle at which to begin feeding
tInit = time.time() # Establish offset time

# Until the rat has run the specified number of laps
while theta < goal:
	tCurr = int(math.floor((time.time() - tInit) * 1000)) # Grabs current time in milliseconds
	f.write('data | time={},theta={}\n'.format(tCurr, theta))

	# If we're at the end of a button pulse
	if tCurr - buttonFeedStart >= pulseDur and buttonIsFeeding == True:
		buttonIsFeeding = False

		# Stop pulsing motor
		GPIO.output(motorPin, False)
		GPIO.output(ledPin, False)

		# Write disable to log
		f.write('event | time={},manFeed=0\n'.format(tCurr))

	# Arrived at feeding location
	if not isFeeding and theta >= nextFeedAng:
		feedStart = tCurr
		isFeeding = True

		# Begin pulsing motor
		GPIO.output(ledPin, True)
		GPIO.output(motorPin, True)

		# Write enable to log
		f.write('event | time={},feed=1\n'.format(tCurr))

	# End of feeding period
	elif isFeeding and tCurr - feedStart >= pulseDur:
		isFeeding = False

		# Stop pulsing motor
		GPIO.output(ledPin, False)
		GPIO.output(motorPin, False)

		# Calculate current interval between feedings and next feed angle
		dTheta = dTheta0 + (dTheta1 - dTheta0) * theta / goal
		nextFeedAng = theta + dTheta + random.randint(-455, 455)

		# Write disable to log
		f.write('event | time={},feed=0\n'.format(tCurr))

	time.sleep(0.01) # Wait 10 ms

# Update time and write end of session to file
tCurr = int(math.floor((time.time() - tInit) * 1000))
f.write('event | time={},goal=1\n#\n'.format(tCurr))

# Turn motor off if it's on
GPIO.output(motorPin, False)
GPIO.output(ledPin, False)
GPIO.cleanup()
f.close()
exit(0)
<|endoftext|>


<commit_before>from __future__ import with_statement

import os
import subprocess
import tempfile
import shutil
import re

from contextlib import contextmanager

def resize(src, target, width, height):
    """ Resizes a source image to given dimensions and stores the resized image as target

        src: Full path to image to be resized.

        target: Full path where to store resized image. (Path does not need to exist before)

        width: Width of the resized image.

        height: Height of the resized image.

    """
    command = '-trim  -resize  %dx%d>  -size  %dx%d  xc:white  +swap  -gravity  center  -composite' % (width, height, width, height)

    execute(command, src, target);

def execute(command, src, target):
    if os.path.isfile(target):
        return
    _findAndVerifySource(src)
    _prepareTargetFolder(target)
    _callImageMagick(command, src, target);

def _findAndVerifySource(src):
    if (_hasExtension(src)):
        if not os.path.isfile(src):
            raise IOError("Source image not found: %s." % src)
        return src
    else:
        return _guessAndAppendExtension(src);

def _hasExtension(file):
    return re.match('^.*\.\w{3-4}$', file)

exts = ('.png', '.jpg', '.jpeg', '.gif')
def _guessAndAppendExtension(srcWithoutExtension):
    for ext in exts:
        file = srcWithoutExtension + ext
        if (os.path.isfile(file)):
            return file

    raise IOError("Source image not found: %s. Tried with following extensions: %s" %(srcWithoutExtension,", ".join(exts)) )

def _prepareTargetFolder(target):
    (target_path, _) = os.path.split(target)

    if not os.path.isdir(target_path):
        os.makedirs(target_path)

def _callImageMagick(command, src, target):
    with temp_file(target) as tmp_target:
        args = ['convert', src] + command.split('  ')
        args.append(tmp_target)
        subprocess.check_call(args)

    shutil.copymode(src, target)

@contextmanager
def temp_file(target):
    """ Wraps a filename with a temporary filename. If working with the temporary file is successful
    the temporary file will be renamed to the target filename.

    target: filename that the temporary file should be renamed to if no exceptions are raised
    """
    temp = None
    try:
        temp = _create_tempfile_for_target(target)
        yield temp
        _replace_target_file_with_temp_file(temp, target)
    finally:
        _remove_tempfile(temp)

def _create_tempfile_for_target(target):
    (_, target_filename) = os.path.split(target)
    target_fileending = target_filename.split(".")[-1]
    (_, temp_file) = tempfile.mkstemp(suffix="." + target_fileending)
    return temp_file

def _replace_target_file_with_temp_file(temp_file, target):
    shutil.move(temp_file, target)

def _remove_tempfile(temp_file):
    if temp_file and os.path.isfile(temp_file):
        os.remove(temp_file)

<commit_msg>Fixed bug when file suffix was empty<commit_after>from __future__ import with_statement

import os
import subprocess
import tempfile
import shutil
import re

from contextlib import contextmanager

def resize(src, target, width, height):
    """ Resizes a source image to given dimensions and stores the resized image as target

        src: Full path to image to be resized.

        target: Full path where to store resized image. (Path does not need to exist before)

        width: Width of the resized image.

        height: Height of the resized image.

    """
    command = '-trim  -resize  %dx%d>  -size  %dx%d  xc:white  +swap  -gravity  center  -composite' % (width, height, width, height)

    execute(command, src, target);

def execute(command, src, target):
    if os.path.isfile(target):
        return
    src = _findAndVerifySource(src)
    _prepareTargetFolder(target)
    _callImageMagick(command, src, target);

def _findAndVerifySource(src):
    if (_hasExtension(src)):
        if not os.path.isfile(src):
            raise IOError("Source image not found: %s." % src)
        return src
    else:
        return _guessAndAppendExtension(src);

def _hasExtension(file):
    return re.match(r'.*\.\w{3,4}', file)

exts = ('.png', '.jpg', '.jpeg', '.gif')
def _guessAndAppendExtension(srcWithoutExtension):
    for ext in exts:
        file = srcWithoutExtension + ext
        if (os.path.isfile(file)):
            return file

    raise IOError("Source image not found: %s. Tried with following extensions: %s" %(srcWithoutExtension,", ".join(exts)) )

def _prepareTargetFolder(target):
    (target_path, _) = os.path.split(target)

    if not os.path.isdir(target_path):
        os.makedirs(target_path)

def _callImageMagick(command, src, target):
    with temp_file(target) as tmp_target:
        args = ['convert', src] + command.split('  ')
        args.append(tmp_target)
        subprocess.check_call(args)

    shutil.copymode(src, target)

@contextmanager
def temp_file(target):
    """ Wraps a filename with a temporary filename. If working with the temporary file is successful
    the temporary file will be renamed to the target filename.

    target: filename that the temporary file should be renamed to if no exceptions are raised
    """
    temp = None
    try:
        temp = _create_tempfile_for_target(target)
        yield temp
        _replace_target_file_with_temp_file(temp, target)
    finally:
        _remove_tempfile(temp)

def _create_tempfile_for_target(target):
    (_, target_filename) = os.path.split(target)
    target_fileending = target_filename.split(".")[-1]
    (_, temp_file) = tempfile.mkstemp(suffix="." + target_fileending)
    return temp_file

def _replace_target_file_with_temp_file(temp_file, target):
    shutil.move(temp_file, target)

def _remove_tempfile(temp_file):
    if temp_file and os.path.isfile(temp_file):
        os.remove(temp_file)

<|endoftext|>


<commit_before>import re

from datetime import datetime
from collections import OrderedDict

from simocracy import flagConverter
from footballMatchAnalyzer.footballStatElement import FootballStatElement

class FootballMatch:
	"""
	Fußballspiel
	"""

	"""
	Team, dessen Statistik erstellt wird, Basierend auf FLAGGENKÜRZEL
	"""
	mainTeam = ["UNS"]

	"""
	Liste der Nachfolgerstaaten, FLAGGENKÜRZEL, Schema Vorgänger -> Aktueller Staat (bzw. Nachfolger)
	"""
	sucessor = []

	_tournament = ""
	@property
	def tournament(self):
		return self._tournament
	@tournament.setter
	def tournament(self, value):
		s = value.strip()
		self._Tournament = s.replace("-", "") if (len(s) < 3) else s

	date = datetime.min

	_city = ""
	@property
	def city(self):
		return self._city
	@city.setter
	def city(self, value):
		self._city = value.strip()

	_stadium = ""
	@property
	def stadium(self):
		return self._stadium
	@stadium.setter
	def stadium(self, value):
		self._stadium = value.strip()

	_homeTeam = ""
	@property
	def homeTeam(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._homeTeam
	@homeTeam.setter
	def homeTeam(self, value):
		self._homeTeam = value.strip().replace("'", "")

	_awayTeam = ""
	@property
	def awayTeam(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._awayTeam
	@awayTeam.setter
	def awayTeam(self, value):
		self._awayTeam = value.strip().replace("'", "")

	@property
	def opponentTeam(self):
		"""
		Gegnerteam für Sortierung nach Gegner
		"""
		for s in self.mainTeam:
			if s in self.awayTeam:
				return self.homeTeam
			return self.awayTeam

	"""
	-1 wenn kein Spielergebnis
	"""
	resultHome = ""

	"""
	-1 wenn kein Spielergebnis
	"""
	resultAway = ""

	@property
	def result(self):
		"""
		Vollständiges Spielergebnis
		"""
		if (self.resultHome < 0 or self.resultAway < 0):
			return "X"
		else:
			return str(self.resultHome) + ":" + str(self.resultAway)

	spectators = 0
	isSoldOut = False

	_referee = ""
	@property
	def referee(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._referee
	@referee.setter
	def referee(self, value):
		self._referee = value.strip().replace("'", "")

	"""
	Quellcode im Wiki
	"""
	sourceCode = ""

	def __init__(self, tournament, date, city, stadium, homeTeam, awayTeam, result, spectators, soldOut, referee, source):
			self.tournament = tournament;
			self.setDate(date);
			self.city = city;
			self.stadium = stadium;
			self.homeTeam = homeTeam;
			self.awayTeam = awayTeam;
			self.setResults(result);
			self.setSpectators(spectators);
			self.SetIsSoldOut(soldOut);
			self.referee = referee;
			self.sourceCode = source;

	def setDate(self, date):
		try:
			exactDatePattern = r"((\d{1,2})\.)?((\d{1,2})\.)?(\d{2,4})"
			exactDateMatch = re.match(exactDatePattern, date)
			if not exactDateMatch is None:
				matchStr = exactDateMatch.group(0)
				if len(exactDateMatch.group(5)) < 4:
					matchStr = matchStr[:len(matchStr)-2] + "20" + matchStr[len(matchStr)-2:]
				if exactDateMatch.group(2) is None:
					datepstr = "%Y"
				elif exactDateMatch.group(4) is None:
					datepstr = "%m.%Y"
				else:
					datepstr = "%d.%m.%Y"
				parsedDate = datetime.strptime(matchStr, datepstr)
				self.date = parsedDate

		except:
			self.date = datetime.min

	def setResults(self, result):
		resPattern = r"(\d+):(\d+)"
		resMatch = re.match(resPattern, result)
		if not resMatch is None:
			self.resultHome = int(resMatch.group(1))
			self.resultAway = int(resMatch.group(2))
		else:
			self.resultHome = -1;
			self.resultAway = -1;

	def setSpectators(self, spectators):
		try:
			sp = spectators.replace(".","").replace("'","").replace(" ","")
			self.spectators = int(sp)
		except:
			self.spectators = 0

	def SetIsSoldOut(self, soldOut):
		self.isSoldOut = len(soldOut.strip()) > 0

	@staticmethod
	def getMatchList(matches):
		"""
		Parsed die Matches in FootballMatch-Objekte
		matches (Match-Collection): Matches
		return: Liste mit FootballMatch
		"""
		matchList = []
		for match in matches:
			matchList.append(match)
		return matchList

	@staticmethod
	def groupByOpponents(matches):
		"""
		Analysiert die Statistik und gibt diese nach Gegnern gruppiert und alphabetisch sortiert zurück
		matches (Enumerable<FootballMatch>): Spiele
		return (OrderedDict<string, FootballStatElement>): Statistik
		"""
		dic = {}
		flagTempRegex = re.compile(r"\{\{([^\|\}]*)(\|([^\}\|]*))?(\|([^\}\|]*))?\}\}")
		for match in matches:
			flagMatch = flagTempRegex.match(match.opponentTeam)

			flag = flagMatch.group(1)
			if len(flag.strip()) < 1:
				continue

			# {{GRA|Grafenberg}} -> Grafenberg
			if not flagMatch.group(3) is None and not "=" in flagMatch.group(3) and re.match(r"\d+", flagMatch.group(3)) is None:
				name = flagMatch.group(3)
			# {{GRA|b=20|Grafenberg}} -> Grafenberg
			elif not flagMatch.group(5) is None and not "=" in flagMatch.group(5) and re.match(r"\d+", flagMatch.group(5)) is None:
				name = flagMatch.group(5)
			# {{GRA}} -> "" -> {{GRA}} Grafenberg -> Grafenberg
			else:
				name = flagTempRegex.sub("", match.opponentTeam).strip()

			isNoneFlag = "?" in flag
			isDummyName = "#" in name
			flag = flagConverter.getFlag(name if isNoneFlag else flag)
			name = flagConverter.getStateName(flag if isDummyName else name)

			if not name in dic:
				fse = FootballStatElement(name, flag)
				dic[name] = fse
			dic[name].addMatch(match)

		sdic = OrderedDict(sorted(dic.items()))
		return sdic

	@staticmethod
	def getOpponentTableCode(opponents):
		"""
		Ausgabe der Bilanz von MainTeam nach Gegnern
		opponents: Bilanz als OrderedDict<string, FootballStatElement>
		return: Bilanz als Wikicode

		"""
		text = ("=== Nach Gegner ===\n"
				""
				"{| class=\"wikitable sortable\" style=\"text-align:center;\"\n"
				"|-\n"
				"! Mannschaft\n"
				"! Sp.\n"
				"! S\n"
				"! U\n"
				"! N\n"
				"! T\n"
				"! GT\n"
				"! TD\n"
				"! P")
		for opp in opponents:
			if not opp.Flag in FootballMatch.mainTeam:
				text = str.format("{0}\n{1}", text, opp.opponentWikicode)

		text = str.format("{0}\n|}}\nStand: <drechner eing=\"j\" day=\"j\">{1:%Y-%m-%d %H:%M}</drechner>", text, datetime.datetime.now())

		return text

	@staticmethod
	def sortForYears(matches):
		dic = {int:FootballStatElement}
		for match in machtes:
			if not match.date is datetime.min:
				if not match.date.year in dic:
					fse = FootballStatElement(match.date.year)
					dic[match.date.year] = fse
				dic[match.date.year].addMatch(match)

		sdic = OrderedDict(sorted(dic.items()))
		return sdic

	@staticmethod
	def getYearTableCode(years):
		text = ("=== Nach Jahr ===\n"
				"{| class=\"wikitable sortable\" style=\"text-align:center;\"\n"
				"|-\n"
				"! Jahr\n"
				"! Sp.\n"
				"! S\n"
				"! U\n"
				"! N\n"
				"! T\n"
				"! GT\n"
				"! TD\n"
				"! P")

		allWon = 0;
		allDrawn = 0;
		allLose = 0;
		allGoalsFor = 0;
		allGoalsAgainst = 0;

		for year in years:
			allWon += year.win
			allDrawn += year.drawn
			allLose += year.lose
			allGoalsFor += year.goalsFor
			allGoalsAgainst += year.goalsAgainst

			text = str.format("{0}|n{1}", text, year.yearWikicode)

		played = allWon + allDrawn + allLose
		allGoalDiff = allGoalsFor - allGoalsAgainst
		points = allWon * 3 + allDrawn

		text = str.format("{0}\n|-\n! Ges. || {1} || {2} || {3} || {4} || {5} || {6} || {7:+0;-0;+0} || {8}\n|}}" +
					"\nStand: <drechner eing=\"j\" day=\"j\">{9:%Y-%m-%d %H:%M}</drechner>",
				text, played, allWon, allDrawn, allLose, allGoalsFor, allGoalsAgainst, allGoalDiff, points, datetime.datetime.now())

		return text

	def analyseFootballStats(articleName, mainTeams):
		"""
		Analysiert und wertet die Statistik einer Fußballnationalmannschaft aus
		articleName: Artikel mit der Statistik
		mainTeams[]: Mainteams, auf die ausgewertet werden soll
		"""
		MainTeam = mainTeams<commit_msg>added analyseFootballStats<commit_after>import re
from datetime import datetime
from collections import OrderedDict

from simocracy import flagConverter
from simocracy import wiki
from footballMatchAnalyzer.footballStatElement import FootballStatElement

class FootballMatch:
	"""
	Fußballspiel
	"""

	"""
	Team, dessen Statistik erstellt wird, Basierend auf FLAGGENKÜRZEL
	"""
	mainTeam = ["UNS"]

	"""
	Liste der Nachfolgerstaaten, FLAGGENKÜRZEL, Schema Vorgänger -> Aktueller Staat (bzw. Nachfolger)
	"""
	sucessor = []

	_tournament = ""
	@property
	def tournament(self):
		return self._tournament
	@tournament.setter
	def tournament(self, value):
		s = value.strip()
		self._Tournament = s.replace("-", "") if (len(s) < 3) else s

	date = datetime.min

	_city = ""
	@property
	def city(self):
		return self._city
	@city.setter
	def city(self, value):
		self._city = value.strip()

	_stadium = ""
	@property
	def stadium(self):
		return self._stadium
	@stadium.setter
	def stadium(self, value):
		self._stadium = value.strip()

	_homeTeam = ""
	@property
	def homeTeam(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._homeTeam
	@homeTeam.setter
	def homeTeam(self, value):
		self._homeTeam = value.strip().replace("'", "")

	_awayTeam = ""
	@property
	def awayTeam(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._awayTeam
	@awayTeam.setter
	def awayTeam(self, value):
		self._awayTeam = value.strip().replace("'", "")

	@property
	def opponentTeam(self):
		"""
		Gegnerteam für Sortierung nach Gegner
		"""
		for s in self.mainTeam:
			if s in self.awayTeam:
				return self.homeTeam
			return self.awayTeam

	"""
	-1 wenn kein Spielergebnis
	"""
	resultHome = ""

	"""
	-1 wenn kein Spielergebnis
	"""
	resultAway = ""

	@property
	def result(self):
		"""
		Vollständiges Spielergebnis
		"""
		if (self.resultHome < 0 or self.resultAway < 0):
			return "X"
		else:
			return str(self.resultHome) + ":" + str(self.resultAway)

	spectators = 0
	isSoldOut = False

	_referee = ""
	@property
	def referee(self):
		"""
		Inkl. Flaggenkürzel
		"""
		return self._referee
	@referee.setter
	def referee(self, value):
		self._referee = value.strip().replace("'", "")

	"""
	Quellcode im Wiki
	"""
	sourceCode = ""

	def __init__(self, tournament, date, city, stadium, homeTeam, awayTeam, result, spectators, soldOut, referee, source):
			self.tournament = tournament;
			self.setDate(date);
			self.city = city;
			self.stadium = stadium;
			self.homeTeam = homeTeam;
			self.awayTeam = awayTeam;
			self.setResults(result);
			self.setSpectators(spectators);
			self.SetIsSoldOut(soldOut);
			self.referee = referee;
			self.sourceCode = source;

	def setDate(self, date):
		try:
			exactDatePattern = r"((\d{1,2})\.)?((\d{1,2})\.)?(\d{2,4})"
			exactDateMatch = re.match(exactDatePattern, date)
			if not exactDateMatch is None:
				matchStr = exactDateMatch.group(0)
				if len(exactDateMatch.group(5)) < 4:
					matchStr = matchStr[:len(matchStr)-2] + "20" + matchStr[len(matchStr)-2:]
				if exactDateMatch.group(2) is None:
					datepstr = "%Y"
				elif exactDateMatch.group(4) is None:
					datepstr = "%m.%Y"
				else:
					datepstr = "%d.%m.%Y"
				parsedDate = datetime.strptime(matchStr, datepstr)
				self.date = parsedDate

		except:
			self.date = datetime.min

	def setResults(self, result):
		resPattern = r"(\d+):(\d+)"
		resMatch = re.match(resPattern, result)
		if not resMatch is None:
			self.resultHome = int(resMatch.group(1))
			self.resultAway = int(resMatch.group(2))
		else:
			self.resultHome = -1;
			self.resultAway = -1;

	def setSpectators(self, spectators):
		try:
			sp = spectators.replace(".","").replace("'","").replace(" ","")
			self.spectators = int(sp)
		except:
			self.spectators = 0

	def SetIsSoldOut(self, soldOut):
		self.isSoldOut = len(soldOut.strip()) > 0

def getMatchList(matches):
	"""
	Parsed die Matches in FootballMatch-Objekte
	matches (Match-Collection): Matches
	return: Liste mit FootballMatch
	"""
	matchList = []
	for match in matches:
		matchList.append(match)
	return matchList

def groupByOpponents(matches):
	"""
	Analysiert die Statistik und gibt diese nach Gegnern gruppiert und alphabetisch sortiert zurück
	matches (Enumerable<FootballMatch>): Spiele
	return (OrderedDict<string, FootballStatElement>): Statistik
	"""
	dic = {}
	flagTempRegex = re.compile(r"\{\{([^\|\}]*)(\|([^\}\|]*))?(\|([^\}\|]*))?\}\}")
	for match in matches:
		flagMatch = flagTempRegex.match(match.opponentTeam)

		flag = flagMatch.group(1)
		if len(flag.strip()) < 1:
			continue

		# {{GRA|Grafenberg}} -> Grafenberg
		if not flagMatch.group(3) is None and not "=" in flagMatch.group(3) and re.match(r"\d+", flagMatch.group(3)) is None:
			name = flagMatch.group(3)
		# {{GRA|b=20|Grafenberg}} -> Grafenberg
		elif not flagMatch.group(5) is None and not "=" in flagMatch.group(5) and re.match(r"\d+", flagMatch.group(5)) is None:
			name = flagMatch.group(5)
		# {{GRA}} -> "" -> {{GRA}} Grafenberg -> Grafenberg
		else:
			name = flagTempRegex.sub("", match.opponentTeam).strip()

		isNoneFlag = "?" in flag
		isDummyName = "#" in name
		flag = flagConverter.getFlag(name if isNoneFlag else flag)
		name = flagConverter.getStateName(flag if isDummyName else name)

		if not name in dic:
			fse = FootballStatElement(name, flag)
			dic[name] = fse
		dic[name].addMatch(match)

	sdic = OrderedDict(sorted(dic.items()))
	return sdic

def getOpponentTableCode(opponents):
	"""
	Ausgabe der Bilanz von MainTeam nach Gegnern
	opponents: Bilanz als OrderedDict<string, FootballStatElement>
	return: Bilanz als Wikicode

	"""
	text = ("=== Nach Gegner ===\n"
			""
			"{| class=\"wikitable sortable\" style=\"text-align:center;\"\n"
			"|-\n"
			"! Mannschaft\n"
			"! Sp.\n"
			"! S\n"
			"! U\n"
			"! N\n"
			"! T\n"
			"! GT\n"
			"! TD\n"
			"! P")
	for opp in opponents:
		if not opp.Flag in FootballMatch.mainTeam:
			text = str.format("{0}\n{1}", text, opp.opponentWikicode)

	text = str.format("{0}\n|}}\nStand: <drechner eing=\"j\" day=\"j\">{1:%Y-%m-%d %H:%M}</drechner>", text, datetime.datetime.now())

	return text

def sortForYears(matches):
	dic = {int:FootballStatElement}
	for match in machtes:
		if not match.date is datetime.min:
			if not match.date.year in dic:
				fse = FootballStatElement(match.date.year)
				dic[match.date.year] = fse
			dic[match.date.year].addMatch(match)

	sdic = OrderedDict(sorted(dic.items()))
	return sdic

def getYearTableCode(years):
	text = ("=== Nach Jahr ===\n"
			"{| class=\"wikitable sortable\" style=\"text-align:center;\"\n"
			"|-\n"
			"! Jahr\n"
			"! Sp.\n"
			"! S\n"
			"! U\n"
			"! N\n"
			"! T\n"
			"! GT\n"
			"! TD\n"
			"! P")

	allWon = 0;
	allDrawn = 0;
	allLose = 0;
	allGoalsFor = 0;
	allGoalsAgainst = 0;

	for year in years:
		allWon += year.win
		allDrawn += year.drawn
		allLose += year.lose
		allGoalsFor += year.goalsFor
		allGoalsAgainst += year.goalsAgainst

		text = str.format("{0}|n{1}", text, year.yearWikicode)

	played = allWon + allDrawn + allLose
	allGoalDiff = allGoalsFor - allGoalsAgainst
	points = allWon * 3 + allDrawn

	text = str.format("{0}\n|-\n! Ges. || {1} || {2} || {3} || {4} || {5} || {6} || {7:+0;-0;+0} || {8}\n|}}" +
				"\nStand: <drechner eing=\"j\" day=\"j\">{9:%Y-%m-%d %H:%M}</drechner>",
			text, played, allWon, allDrawn, allLose, allGoalsFor, allGoalsAgainst, allGoalDiff, points, datetime.datetime.now())

	return text

def analyseFootballStats(articleName, mainTeams):
	"""
	Analysiert und wertet die Statistik einer Fußballnationalmannschaft aus
	articleName: Artikel mit der Statistik
	mainTeams[]: Mainteams, auf die ausgewertet werden soll
	"""
	MainTeam = mainTeams

	"""
	Gruppen:
	1: Turnier
	2: Datum
	3: Ort
	4: Stadion
	5: Heimteam
	6: Gastteam
	7: Endergebnis (120 min)
	8: Zuschauer
	9: Wenn nicht leer: Ausverkauft
	10: Schiedsrichter
	"""
	matchRegexPat = r"\|(.*[^\|\r\n]*)\s*[\r\n|\|]\|\s*([^\|\r\n]*)?\s*[\r\n|\|]\|\s*(\{\{.+\}\}[^\|\r\n]*)[\r\n\|]\|\s*([^\|\r\n]*)?\s*[\r\n\|]\|\s*('{0,3}\{\{.+\}\}[^\|\r\n]*)?\s*[\r\n\|]\|\s*('{0,3}\{\{.+\}\}[^\|\r\n]*)?\s*[\r\n\|]\|\s*[^\|]*\|\s*'''([^']*)'''[^\|\r\n]*?\s*[\r\n\|]\|\s*([\d\.]*)(\s*\(a\))?\s*[\r\n\|]\|\s*(\{\{.*\}\}[^\|\r\n]*)?"

	print("Lade Artikel " + articleName)
	p = wiki.Article(articleName)

	# Abschnitte analysieren
	sectionMatches = re.match(r"(^={1,6}(.*)?={1,6}\s*?$)", p.text, re.RegexFlag.MULTILINE)

	counter = 0
	opponentSection = 0
	yearSection = 0
	for sectMatch in sectionMatches:
		counter += 1
		if "Nach Gegner" in sectMatch:
			opponentSection = counter
		elif "Nach Jahr" in sectMatch:
			yearSection = counter

	matchesRegex = re.match(matchRegexPat, p.text)
	footballMatchList = getMatchList(matchesRegex)
	print(len(footballMatchList) + " Spiele gefunden")

	# Gegnerstats
	if opponentSection > 0:
		return

	# Jahresstats
	if yearSection > 0:
		return<|endoftext|>


<commit_before>'''

Key plots to illustrate results

'''
import numpy as np
import pickle

import catalog as Cat
import evolver as Evol
import observables as Obvs
import util as UT

import matplotlib.pyplot as plt
import bovy_plot as bovy
from ChangTools.plotting import prettyplot
from ChangTools.plotting import prettycolors

def siglogMstar_tduty(nsnap0):
    ''' Plot sigma_logM*(M_halo = 10^12) as a function of t_duty (the duty cycle
    timescale)
    '''
    pretty_colors = prettycolors()
    fig = plt.figure()
    sub = fig.add_subplot(111)

    fig_data = []
    tdutys = np.array([0.5, 1., 5., 10.])
    #tdutys = np.array([1., 5.])

    for i_a, abias in enumerate([0., 0.1, 0.2, 0.3]):
        if abias == 0.:
            sfh = 'random_step_fluct'
        else:
            sfh = 'random_step_abias2'
        sigmaMstar = np.repeat(-999., len(tdutys))

        for i_t, tduty in enumerate(tdutys):  # t_duty
            # load in subhalo catalog
            subhist = Cat.PureCentralHistory(nsnap_ancestor=nsnap0)
            subcat = subhist.Read()

            # load in generic theta (parameter values)
            theta = Evol.defaultTheta(sfh)
            theta['sfh']['dt_min'] = tduty
            theta['sfh']['dt_max'] = tduty
            theta['mass']['t_step'] = 0.05
            if theta['mass']['t_step'] > tduty/10.:
                theta['mass']['t_step'] = tduty/10.
            if abias > 0.:
                theta['sfh']['t_abias'] = 2.  # assembly bias timescale
                theta['sfh']['sigma_corr'] = abias
            else:
                theta['sfh']['t_abias'] = None   # assembly bias timescale

            eev = Evol.Evolver(subcat, theta, nsnap0=nsnap0)
            eev.Initiate()
            eev.Evolve()

            # galaxy/subhalo catalog
            subcat = eev.SH_catalog

            isSF = np.where(subcat['gclass'] == 'star-forming')[0]

            smhmr = Obvs.Smhmr()
            m_mid, mu_mstar, sig_mstar, cnts = smhmr.Calculate(subcat['halo.m'][isSF], subcat['m.star'][isSF])
            sig_mstar_mh12 = smhmr.sigma_logMstar(subcat['halo.m'][isSF], subcat['m.star'][isSF], Mhalo=12.)
            sigmaMstar[i_t] = sig_mstar_mh12

            # save data
            fig_datum = {
                    'sfh': sfh,
                    'tduty': tduty,
                    'sigma_corr': abias,
                    't_abias': theta['t_abias'],
                    'theta': theta,
                    'smhmr': [m_mid, mu_mstar, sig_mstar, cnts],
                    'sigmaM*(Mh12)': sig_mstar_mh12
                    }
            fig_data.append(fig_datum)

        sfh_label = ''.join(['$\sigma_{corr} = ', str(abias), ', ',
            't_{abias} = ', str(theta['sfh']['t_abias']), '$'])
        sub.scatter(tdutys, sigmaMstar, lw=0, s=20, c=pretty_colors[i_a], label=sfh_label)
        sub.plot(tdutys, sigmaMstar, lw=2, c=pretty_colors[i_a])

    sub.plot([0., 11.], [0.2, 0.2], lw=3, ls='--', c='k', label='Obsv.')

    sub.legend(loc='lower right')

    sub.set_xlim([0., 11.])
    sub.set_ylim([0., 0.6])
    fig.savefig(''.join([UT.fig_dir(), 'sigmalogMstar_tduty.png']), bbox_inches='tight')

    # dump to pickle file
    pickle.dump(fig_data, open(''.join([UT.dat_dir(), 'fig_data/sigmalogMstar_tduty.p']), 'wb'))

    f = open(''.join([UT.dat_dir(), 'fig_data/sigmalogMstar_tduty.dat']), 'w')
    f.write('# SFH, t_duty [Gyr], sigma_corr, t_abias, SMHMR sigma logMstar at Mhalo=10^12 \n')
    for datum in fig_data:
        out_line = '\t'.join([datum['sfh'], str(datum['tduty']), str(datum['sigma_corr']),
            str(datum['t_abias']), str(datum['sigmaM*(Mh12)'])])+'\n'
        f.write(out_line)
    f.close()

    return None

if __name__=='__main__':
    siglogMstar_tduty(15)
<commit_msg>more minor bugs fixed<commit_after>'''

Key plots to illustrate results

'''
import numpy as np
import pickle

import catalog as Cat
import evolver as Evol
import observables as Obvs
import util as UT

import matplotlib.pyplot as plt
import bovy_plot as bovy
from ChangTools.plotting import prettyplot
from ChangTools.plotting import prettycolors

def siglogMstar_tduty(nsnap0):
    ''' Plot sigma_logM*(M_halo = 10^12) as a function of t_duty (the duty cycle
    timescale)
    '''
    pretty_colors = prettycolors()
    fig = plt.figure()
    sub = fig.add_subplot(111)

    fig_data = []
    tdutys = np.array([0.5, 1., 5., 10.])
    #tdutys = np.array([1., 5.])

    for i_a, abias in enumerate([0., 0.1, 0.2, 0.3]):
        if abias == 0.:
            sfh = 'random_step_fluct'
        else:
            sfh = 'random_step_abias2'
        sigmaMstar = np.repeat(-999., len(tdutys))

        for i_t, tduty in enumerate(tdutys):  # t_duty
            # load in subhalo catalog
            subhist = Cat.PureCentralHistory(nsnap_ancestor=nsnap0)
            subcat = subhist.Read()

            # load in generic theta (parameter values)
            theta = Evol.defaultTheta(sfh)
            theta['sfh']['dt_min'] = tduty
            theta['sfh']['dt_max'] = tduty
            theta['mass']['t_step'] = 0.05
            if theta['mass']['t_step'] > tduty/10.:
                theta['mass']['t_step'] = tduty/10.
            if abias > 0.:
                theta['sfh']['t_abias'] = 2.  # assembly bias timescale
                theta['sfh']['sigma_corr'] = abias
            else:
                theta['sfh']['t_abias'] = None   # assembly bias timescale

            eev = Evol.Evolver(subcat, theta, nsnap0=nsnap0)
            eev.Initiate()
            eev.Evolve()

            # galaxy/subhalo catalog
            subcat = eev.SH_catalog

            isSF = np.where(subcat['gclass'] == 'star-forming')[0]

            smhmr = Obvs.Smhmr()
            m_mid, mu_mstar, sig_mstar, cnts = smhmr.Calculate(subcat['halo.m'][isSF], subcat['m.star'][isSF])
            sig_mstar_mh12 = smhmr.sigma_logMstar(subcat['halo.m'][isSF], subcat['m.star'][isSF], Mhalo=12.)
            sigmaMstar[i_t] = sig_mstar_mh12

            # save data
            fig_datum = {
                    'sfh': sfh,
                    'tduty': tduty,
                    'sigma_corr': abias,
                    't_abias': theta['sfh']['t_abias'],
                    'theta': theta,
                    'smhmr': [m_mid, mu_mstar, sig_mstar, cnts],
                    'sigmaM*(Mh12)': sig_mstar_mh12
                    }
            fig_data.append(fig_datum)

        sfh_label = ''.join(['$\sigma_{corr} = ', str(abias), ', ',
            't_{abias} = ', str(theta['sfh']['t_abias']), '$'])
        sub.scatter(tdutys, sigmaMstar, lw=0, s=20, c=pretty_colors[i_a], label=sfh_label)
        sub.plot(tdutys, sigmaMstar, lw=2, c=pretty_colors[i_a])

    sub.plot([0., 11.], [0.2, 0.2], lw=3, ls='--', c='k', label='Obsv.')

    sub.legend(loc='lower right')

    sub.set_xlim([0., 11.])
    sub.set_ylim([0., 0.6])
    fig.savefig(''.join([UT.fig_dir(), 'sigmalogMstar_tduty.png']), bbox_inches='tight')

    # dump to pickle file
    pickle.dump(fig_data, open(''.join([UT.dat_dir(), 'fig_data/sigmalogMstar_tduty.p']), 'wb'))

    f = open(''.join([UT.dat_dir(), 'fig_data/sigmalogMstar_tduty.dat']), 'w')
    f.write('# SFH, t_duty [Gyr], sigma_corr, t_abias, SMHMR sigma logMstar at Mhalo=10^12 \n')
    for datum in fig_data:
        out_line = '\t'.join([datum['sfh'], str(datum['tduty']), str(datum['sigma_corr']),
            str(datum['t_abias']), str(datum['sigmaM*(Mh12)'])])+'\n'
        f.write(out_line)
    f.close()

    return None

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


<commit_before>class UsageRecord(object):
    def __init__(self, data):
        self._data = data

    def __getitem__(self, key):
        return self._data[key]

    @property
    def type(self):
        return self._data[" UsageType"]

    @property
    def value(self):
        return int(self._data[" UsageValue"])

    @property
    def resource(self):
        return self._data[" Resource"]

    @property
    def area(self):
        if self.type.startswith("EUC1-"):
            return "EU (Frankfurt)"

    @property
    def is_data_transfer(self):
        return "DataTransfer" in self.type or "CloudFront" in self.type
<commit_msg>Remove __getitem__ from UsageRecord<commit_after>class UsageRecord(object):
    def __init__(self, data):
        self._data = data

    @property
    def type(self):
        return self._data[" UsageType"]

    @property
    def value(self):
        return int(self._data[" UsageValue"])

    @property
    def resource(self):
        return self._data[" Resource"]

    @property
    def area(self):
        if self.type.startswith("EUC1-"):
            return "EU (Frankfurt)"

    @property
    def is_data_transfer(self):
        return "DataTransfer" in self.type or "CloudFront" in self.type
<|endoftext|>


<commit_before>#!/usr/bin/env python
# Author:  csiu
# Created: 2015-04-24
import argparse
import re
import os
import sys
import pandas as pd

import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
from rpy2.robjects.lib import ggplot2
from rpy2.robjects import r

from utils import get_value_from_keycolonvalue_list, ensure_dir

usage = """Generate plots (pie + histogram) with R via rpy2

Depends on:
- pandas     (python module)
- rpy2       (python module)
- ggplot2    (R package)
"""
def _filterPredictionsByClass_reformat2gff(infile, outdir, keep='prom'):
    outfile = os.path.join(outdir, os.path.basename(infile)+'.filtered')
    with open(outfile, 'w') as out:
        with open(infile) as f:
            for l in f:
                l = l.strip().split('\t')
                classlabel = l[13]

                if classlabel == keep:
                    newinfo = ';'.join([l[8],
                                        'prior_prom:' + l[9],
                                        'prior_back:' + l[10],
                                        'prob_prom:' + l[11],
                                        'prob_back:' + l[12],
                                        'class:' + classlabel])
                    newline = '\t'.join(l[0:8] + [newinfo])
                    out.write(newline + '\n')
    return outfile

def _read_dat(gff_infile):
    dat = {}
    n = 0
    with open(gff_infile) as f:
        for l in f:
            n += 1

            l = l.strip().split('\t')
            chrom = l[0]
            tstart = l[3]
            tstop  = l[4]
            strand = l[6]
            tss = ','.join([chrom, tstart, tstop, strand])

            info  = l[8].split(';')
            mirna_id = get_value_from_keycolonvalue_list('mirbase_id', info)
            mstart = get_value_from_keycolonvalue_list('mirna_start', info)
            mstop  = get_value_from_keycolonvalue_list('mirna_start', info)
            label = get_value_from_keycolonvalue_list('mirna_label', info)

            if label == '': label = 'NA'
            mirna = ','.join([chrom, mstart, mstop, strand])

            features = l[7].split(';')
            corr = get_value_from_keycolonvalue_list('corr', features)
            if get_value_from_keycolonvalue_list('mirna_prox', features) != 0:
                distance = get_value_from_keycolonvalue_list('distance', info)
                if distance == '': distance = 0

            dat[n] = [tss, mirna, mirna_id, label, distance, abs(float(distance)), corr]

    dat = pd.DataFrame.from_dict(dat, orient='index')
    dat.columns = ['tss', 'mirna', 'mirna_id', 'label', 'Distance', 'distance', 'correlation']
    return dat

def _item_findClosestPartner(dat, item):
    df = dat[dat['label'] != 'NA'] ## remove invalid pairs

    xindex = []
    for i in df[item].unique():
        subm = df[df[item] == i]

        ## min distance
        submd = subm[subm['distance'] == subm['distance'].min()]

        ## absmax correlation
        l = submd['correlation'].astype(float).abs()
        l = l[l == l.max()]

        xindex.append(l.index[0])
    return dat[dat.index.isin(xindex)]

def _plt_percountr(dat, independentpdf=False, fname='xpercount.pdf'):
    def _filt_dat(dat, item, getlabel=True):
        df = pd.DataFrame(dat[item].value_counts())
        df.columns = ['count']
        if getlabel: df['label'] = [list(dat[dat[item] == i]['label'])[0] for i in df.index]
        n  = len(df)
        mx = max(df['count'])
        return df, n, mx

    dat = dat[dat['label'] != 'NA']

    ## NUMBER OF MIRNA PER TSS
    df, n, mx = _filt_dat(dat, 'tss', False)
    df = {'count': robjects.IntVector(df['count'])}
    df = robjects.DataFrame(df)

    pt = ggplot2.ggplot(df) + \
        ggplot2.geom_histogram(binwidth=1, origin=-.5, alpha=.5, position="identity") + \
        ggplot2.xlim(-.5, mx+1) + \
        ggplot2.aes_string(x='count') + \
        ggplot2.ggtitle('TSS [Total = %s]' % n) + \
        ggplot2.labs(x='Number of miRNA per TSS (max = %s)' % mx)

    pt_den = ggplot2.ggplot(df) + \
        ggplot2.aes_string(x='count', y='..density..') + \
        ggplot2.geom_density(binwidth=1, alpha=.5, origin=-.5) + \
        ggplot2.geom_histogram(binwidth=1, alpha=.33, position='identity', origin=-.5) + \
        ggplot2.ggtitle('TSS [Total = %s]' % n) + \
        ggplot2.labs(x='Number of miRNA per TSS (max = %s)' % mx)

    ## NUMBER OF TSS PER MIRNA
    df, n, mx = _filt_dat(dat, 'mirna')
    df = {'count': robjects.IntVector(df['count']),
          'label': robjects.StrVector(df['label']) }
    df = robjects.DataFrame(df)

    pm = ggplot2.ggplot(df) + \
        ggplot2.geom_histogram(binwidth=1, origin=-.5, alpha=.5, position="identity") + \
        ggplot2.xlim(-.5, mx+1) + \
        ggplot2.aes_string(x='count', fill='label') + \
        ggplot2.ggtitle('miRNA [Total = %s]' % n) + \
        ggplot2.labs(x='Number of TSS per miRNA (max = %s)' % mx)

    pm_den = ggplot2.ggplot(df) + \
        ggplot2.aes_string(x='count', fill='label', y='..density..') + \
        ggplot2.geom_density(binwidth=1, alpha=.5, origin=-.5) + \
        ggplot2.geom_histogram(binwidth=1, alpha=.33, position='identity', origin=-.5) + \
        ggplot2.ggtitle('miRNA [Total = %s]' % n) + \
        ggplot2.labs(x='Number of TSS per miRNA (max = %s)' % mx)

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(fname)
        pt.plot()
        pt_den.plot()
        pm.plot()
        pm_den.plot()
        grdevices.dev_off()
    else:
        pt.plot()
        pt_den.plot()
        pm.plot()
        pm_den.plot()
    return

def _plt_distr(dat, col, title='', pfill='label', independentpdf=False, fname='xdistr.pdf'):
    df = dat[dat[pfill] != 'NA'] ## remove invalid pairs
    n  = len(df)
    df = {col: robjects.FloatVector(list(df[col])),
          pfill: robjects.StrVector(list(df[pfill]))}
    df = robjects.DataFrame(df)

    pp = ggplot2.ggplot(df) + \
        ggplot2.ggtitle('%s [Total = %s]' % (title, n))

    ## Plot1: counts
    p1 = pp + ggplot2.aes_string(x=col, fill=pfill)

    ## Plot2: density
    p2 = pp + \
        ggplot2.aes_string(x=col, fill=pfill, y='..density..') + \
        ggplot2.geom_density(alpha=.5, origin=-500)

    if col == 'distance':
        p1 = p1 + \
            ggplot2.geom_histogram(binwidth=1000, alpha=.5, position='identity', origin=-500) + \
            ggplot2.xlim(-1000, 51000)

        p2 = p2 + \
            ggplot2.geom_histogram(binwidth=1000, alpha=.33, position='identity', origin=-500) + \
            ggplot2.xlim(-1000, 51000)
    else:
        p1 = p1 + \
            ggplot2.geom_histogram(alpha=.5, position='identity')

        p2 = p2 + \
            ggplot2.geom_histogram(alpha=.33, position='identity')

        if col == 'correlation':
            p1 = p1 + ggplot2.xlim(-1.1, 1.1)
            p2 = p2 + ggplot2.xlim(-1.1, 1.1)

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(file=fname)
        p1.plot()
        p2.plot()
        grdevices.dev_off()
    else:
        p1.plot()
        p2.plot()
    return

def _plt_pier(dat, title='', rm_na=False, col='label',
              independentpdf=False, fname='xpire.pdf'):
    x = dat[col]
    if rm_na: x = x[x != 'NA']
    x = x.value_counts()
    _sum = sum(x)

    r.assign('n', len(x))

    slices = robjects.FloatVector(x)
    pct  = ['%0.1f%%' % float(float(i)*100/_sum) for i in x]
    lbls = ['%s %s' % i  for i in zip(x.index, pct)]
    lbls   = robjects.StrVector(lbls)

    ggcolors = r('''
      gg_color_hue <- function(n){
            hues = seq(15, 375, length=n+1)
            hcl(h=hues, l=65, c=100)[1:n]
            }

      rev(gg_color_hue(n))
    ''')

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(pdf)

    r.pie(slices,
          labels=lbls,
          init_angle=90,
          col=ggcolors,
          main=title)
    r.text(-1, -1, '[Total = %s]' % _sum)

    if independentpdf:
        grdevices.dev_off()
    return

def main(infile, outdir):
    outdir = os.path.abspath(outdir)
    ensure_dir(outdir, False)

    infile = _filterPredictionsByClass_reformat2gff(infile, outdir)

    bname = os.path.basename(infile)
    pdf_rplots = os.path.join(outdir, bname + '.plots.pdf')

    dat = _read_dat(infile)
    dat_mirna = _item_findClosestPartner(dat, 'mirna')
    dat_tss   = _item_findClosestPartner(dat, 'tss')

    grdevices = importr('grDevices')
    grdevices.pdf(file=pdf_rplots)

    _plt_pier(dat, 'All TSS-[miRNA,NA] pairs')
    _plt_pier(dat, 'All valid TSS-miRNA pairs', True)
    _plt_distr(dat, 'distance',    'All valid tss-miRNA pairs')
    _plt_distr(dat, 'correlation', 'All valid tss-miRNA pairs')

    _plt_percountr(dat)

    _plt_pier(dat_tss,   'Distinct TSS (label from closest miRNA)')
    _plt_distr(dat_tss, 'distance',    'TSS to closest miRNA')
    _plt_distr(dat_tss, 'correlation', 'TSS to closest miRNA')

    _plt_pier(dat_mirna, 'Distinct miRNA')
    _plt_distr(dat_mirna, 'distance',    'miRNA to closest TSS')
    _plt_distr(dat_mirna, 'correlation', 'miRNA to closest TSS')

    grdevices.dev_off()
    return pdf_rplots

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=usage,
                                     formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('-i', '--infile', dest='infile',
                        required=True,
                        help='''path to input file;
e.g. output of "label.py"
"label:" should be contained in the info column (9)''')

    parser.add_argument('-o', '--outdir', dest='outdir',
                        default='../Testout-plot',
                        help='''specify path to output directory''')

    ##get at the arguments
    args = parser.parse_args()

    ## do something..
    main(args.infile, args.outdir)
<commit_msg>made it so that plots are generated even when correlation feature is not extracted<commit_after>#!/usr/bin/env python
# Author:  csiu
# Created: 2015-04-24
import argparse
import re
import os
import sys
import pandas as pd

import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
from rpy2.robjects.lib import ggplot2
from rpy2.robjects import r

from utils import get_value_from_keycolonvalue_list, ensure_dir

usage = """Generate plots (pie + histogram) with R via rpy2

Depends on:
- pandas     (python module)
- rpy2       (python module)
- ggplot2    (R package)
"""
def _filterPredictionsByClass_reformat2gff(infile, outdir, keep='prom'):
    outfile = os.path.join(outdir, os.path.basename(infile)+'.filtered')
    with open(outfile, 'w') as out:
        with open(infile) as f:
            for l in f:
                l = l.strip().split('\t')
                classlabel = l[13]

                if classlabel == keep:
                    newinfo = ';'.join([l[8],
                                        'prior_prom:' + l[9],
                                        'prior_back:' + l[10],
                                        'prob_prom:' + l[11],
                                        'prob_back:' + l[12],
                                        'class:' + classlabel])
                    newline = '\t'.join(l[0:8] + [newinfo])
                    out.write(newline + '\n')
    return outfile

def _read_dat(gff_infile):
    dat = {}
    n = 0
    with open(gff_infile) as f:
        for l in f:
            n += 1

            l = l.strip().split('\t')
            chrom = l[0]
            tstart = l[3]
            tstop  = l[4]
            strand = l[6]
            tss = ','.join([chrom, tstart, tstop, strand])

            info  = l[8].split(';')
            mirna_id = get_value_from_keycolonvalue_list('mirbase_id', info)
            mstart = get_value_from_keycolonvalue_list('mirna_start', info)
            mstop  = get_value_from_keycolonvalue_list('mirna_start', info)
            label = get_value_from_keycolonvalue_list('mirna_label', info)

            if label == '': label = 'NA'
            mirna = ','.join([chrom, mstart, mstop, strand])

            features = l[7].split(';')
            corr = get_value_from_keycolonvalue_list('corr', features)
            if get_value_from_keycolonvalue_list('mirna_prox', features) != 0:
                distance = get_value_from_keycolonvalue_list('distance', info)
                if distance == '': distance = 0

            dat[n] = [tss, mirna, mirna_id, label, distance, abs(float(distance)), corr]

    dat = pd.DataFrame.from_dict(dat, orient='index')
    dat.columns = ['tss', 'mirna', 'mirna_id', 'label', 'Distance', 'distance', 'correlation']
    return dat

def _item_findClosestPartner(dat, item, ignoreCorr):
    df = dat[dat['label'] != 'NA'] ## remove invalid pairs

    xindex = []
    for i in df[item].unique():
        subm = df[df[item] == i]

        ## min distance
        submd = subm[subm['distance'] == subm['distance'].min()]

        if ignoreCorr:
            l = submd
        else:
            ## absmax correlation
            l = submd['correlation'].astype(float).abs()
            l = l[l == l.max()]

        xindex.append(l.index[0])
    return dat[dat.index.isin(xindex)]

def _plt_percountr(dat, independentpdf=False, fname='xpercount.pdf'):
    def _filt_dat(dat, item, getlabel=True):
        df = pd.DataFrame(dat[item].value_counts())
        df.columns = ['count']
        if getlabel: df['label'] = [list(dat[dat[item] == i]['label'])[0] for i in df.index]
        n  = len(df)
        mx = max(df['count'])
        return df, n, mx

    dat = dat[dat['label'] != 'NA']

    ## NUMBER OF MIRNA PER TSS
    df, n, mx = _filt_dat(dat, 'tss', False)
    df = {'count': robjects.IntVector(df['count'])}
    df = robjects.DataFrame(df)

    pt = ggplot2.ggplot(df) + \
        ggplot2.geom_histogram(binwidth=1, origin=-.5, alpha=.5, position="identity") + \
        ggplot2.xlim(-.5, mx+1) + \
        ggplot2.aes_string(x='count') + \
        ggplot2.ggtitle('TSS [Total = %s]' % n) + \
        ggplot2.labs(x='Number of miRNA per TSS (max = %s)' % mx)

    pt_den = ggplot2.ggplot(df) + \
        ggplot2.aes_string(x='count', y='..density..') + \
        ggplot2.geom_density(binwidth=1, alpha=.5, origin=-.5) + \
        ggplot2.geom_histogram(binwidth=1, alpha=.33, position='identity', origin=-.5) + \
        ggplot2.ggtitle('TSS [Total = %s]' % n) + \
        ggplot2.labs(x='Number of miRNA per TSS (max = %s)' % mx)

    ## NUMBER OF TSS PER MIRNA
    df, n, mx = _filt_dat(dat, 'mirna')
    df = {'count': robjects.IntVector(df['count']),
          'label': robjects.StrVector(df['label']) }
    df = robjects.DataFrame(df)

    pm = ggplot2.ggplot(df) + \
        ggplot2.geom_histogram(binwidth=1, origin=-.5, alpha=.5, position="identity") + \
        ggplot2.xlim(-.5, mx+1) + \
        ggplot2.aes_string(x='count', fill='label') + \
        ggplot2.ggtitle('miRNA [Total = %s]' % n) + \
        ggplot2.labs(x='Number of TSS per miRNA (max = %s)' % mx)

    pm_den = ggplot2.ggplot(df) + \
        ggplot2.aes_string(x='count', fill='label', y='..density..') + \
        ggplot2.geom_density(binwidth=1, alpha=.5, origin=-.5) + \
        ggplot2.geom_histogram(binwidth=1, alpha=.33, position='identity', origin=-.5) + \
        ggplot2.ggtitle('miRNA [Total = %s]' % n) + \
        ggplot2.labs(x='Number of TSS per miRNA (max = %s)' % mx)

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(fname)
        pt.plot()
        pt_den.plot()
        pm.plot()
        pm_den.plot()
        grdevices.dev_off()
    else:
        pt.plot()
        pt_den.plot()
        pm.plot()
        pm_den.plot()
    return

def _plt_distr(dat, col, title='', pfill='label', independentpdf=False, fname='xdistr.pdf'):
    df = dat[dat[pfill] != 'NA'] ## remove invalid pairs
    n  = len(df)
    df = {col: robjects.FloatVector(list(df[col])),
          pfill: robjects.StrVector(list(df[pfill]))}
    df = robjects.DataFrame(df)

    pp = ggplot2.ggplot(df) + \
        ggplot2.ggtitle('%s [Total = %s]' % (title, n))

    ## Plot1: counts
    p1 = pp + ggplot2.aes_string(x=col, fill=pfill)

    ## Plot2: density
    p2 = pp + \
        ggplot2.aes_string(x=col, fill=pfill, y='..density..') + \
        ggplot2.geom_density(alpha=.5, origin=-500)

    if col == 'distance':
        p1 = p1 + \
            ggplot2.geom_histogram(binwidth=1000, alpha=.5, position='identity', origin=-500) + \
            ggplot2.xlim(-1000, 51000)

        p2 = p2 + \
            ggplot2.geom_histogram(binwidth=1000, alpha=.33, position='identity', origin=-500) + \
            ggplot2.xlim(-1000, 51000)
    else:
        p1 = p1 + \
            ggplot2.geom_histogram(alpha=.5, position='identity')

        p2 = p2 + \
            ggplot2.geom_histogram(alpha=.33, position='identity')

        if col == 'correlation':
            p1 = p1 + ggplot2.xlim(-1.1, 1.1)
            p2 = p2 + ggplot2.xlim(-1.1, 1.1)

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(file=fname)
        p1.plot()
        p2.plot()
        grdevices.dev_off()
    else:
        p1.plot()
        p2.plot()
    return

def _plt_pier(dat, title='', rm_na=False, col='label',
              independentpdf=False, fname='xpire.pdf'):
    x = dat[col]
    if rm_na: x = x[x != 'NA']
    x = x.value_counts()
    _sum = sum(x)

    r.assign('n', len(x))

    slices = robjects.FloatVector(x)
    pct  = ['%0.1f%%' % float(float(i)*100/_sum) for i in x]
    lbls = ['%s %s' % i  for i in zip(x.index, pct)]
    lbls   = robjects.StrVector(lbls)

    ggcolors = r('''
      gg_color_hue <- function(n){
            hues = seq(15, 375, length=n+1)
            hcl(h=hues, l=65, c=100)[1:n]
            }

      rev(gg_color_hue(n))
    ''')

    if independentpdf:
        grdevices = importr('grDevices')
        grdevices.pdf(pdf)

    r.pie(slices,
          labels=lbls,
          init_angle=90,
          col=ggcolors,
          main=title)
    r.text(-1, -1, '[Total = %s]' % _sum)

    if independentpdf:
        grdevices.dev_off()
    return

def main(infile, outdir):
    outdir = os.path.abspath(outdir)
    ensure_dir(outdir, False)

    infile = _filterPredictionsByClass_reformat2gff(infile, outdir)

    bname = os.path.basename(infile)
    pdf_rplots = os.path.join(outdir, bname + '.plots.pdf')

    dat = _read_dat(infile)

    if all(dat['correlation'] == ''):
        ignoreCorr = True
    else:
        ignoreCorr = False

    dat_mirna = _item_findClosestPartner(dat, 'mirna', ignoreCorr)
    dat_tss   = _item_findClosestPartner(dat, 'tss',   ignoreCorr)

    grdevices = importr('grDevices')
    grdevices.pdf(file=pdf_rplots)

    _plt_pier(dat, 'All TSS-[miRNA,NA] pairs')
    _plt_pier(dat, 'All valid TSS-miRNA pairs', True)
    _plt_distr(dat, 'distance',    'All valid tss-miRNA pairs')
    if not ignoreCorr: _plt_distr(dat, 'correlation', 'All valid tss-miRNA pairs')

    _plt_percountr(dat)

    _plt_pier(dat_tss,   'Distinct TSS (label from closest miRNA)')
    _plt_distr(dat_tss, 'distance',    'TSS to closest miRNA')
    if not ignoreCorr: _plt_distr(dat_tss, 'correlation', 'TSS to closest miRNA')

    _plt_pier(dat_mirna, 'Distinct miRNA')
    _plt_distr(dat_mirna, 'distance',    'miRNA to closest TSS')
    if not ignoreCorr: _plt_distr(dat_mirna, 'correlation', 'miRNA to closest TSS')

    grdevices.dev_off()
    print pdf_rplots
    return pdf_rplots

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=usage,
                                     formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('-i', '--infile', dest='infile',
                        required=True,
                        help='''path to input file;
e.g. output of "label.py"
"label:" should be contained in the info column (9)''')

    parser.add_argument('-o', '--outdir', dest='outdir',
                        default='../Testout-plot',
                        help='''specify path to output directory''')

    ##get at the arguments
    args = parser.parse_args()

    ## do something..
    main(args.infile, args.outdir)
<|endoftext|>


<commit_before>from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.models import User
from django.conf import settings
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django_xhtml2pdf.utils import generate_pdf
from .forms import ClientForm
from .forms import ContactForm
from .forms import EstimateForm
from .forms import InvoiceForm
from .forms import MailForm
from .forms import ProjectForm
from .forms import TaskForm
from .forms import TimeForm
from .models import Client
from .models import Company
from .models import Contact
from .models import Estimate
from .models import Invoice
from .models import Project
from .models import Task
from .models import Time
from .utils import entries_total
from .utils import paginate

# Create your views here.

@staff_member_required
def client(request, pk=None):
    context = {}
    client = get_object_or_404(Client, pk=pk)
    projects = Project.objects.filter(client=client)
    context['client'] = client
    context['projects'] = projects
    return render(request, 'client.html', context)

@staff_member_required
def client_edit(request, pk=None):
    context = {}

    if pk is None:
        form = ClientForm()
    else:
        client = get_object_or_404(Client, pk=pk)
        form = ClientForm(instance=client)

    if request.method == 'POST':

        if pk is None:
            form = ClientForm(request.POST)
        else:
            form = ClientForm(request.POST, instance=client)

        if form.is_valid():
            client = form.save()
            return HttpResponseRedirect(reverse('client_index'))

    context['form'] = form
    return render(request, 'client_edit.html', context)

@staff_member_required
def client_index(request):
    context = {}
    clients = Client.objects.filter(active=True)
    page = request.GET.get('page')
    context['items'] = paginate(clients, page)
    return render(request, 'client_index.html', context)

@staff_member_required
def contact(request, pk=None):
    context = {}
    contact = get_object_or_404(Contact, pk=pk)
    context['contact'] = contact
    return render(request, 'contact.html', context)

@staff_member_required
def contact_edit(request, pk=None):
    context = {}
    contact = None

    if pk is None:
        form = ContactForm()
    else:
        contact = get_object_or_404(Contact, pk=pk)
        form = ContactForm(instance=contact)

    if request.method == 'POST':

        if pk is None:
            form = ContactForm(request.POST)
        else:
            form = ContactForm(request.POST, instance=contact)

        if form.is_valid():
            contact = form.save()
            return HttpResponseRedirect(reverse('contact_index'))

    context['contact'] = contact
    context['form'] = form
    return render(request, 'contact_edit.html', context)

@staff_member_required
def contact_index(request):
    context = {}
    contacts = Contact.objects.filter(active=True)
    page = request.GET.get('page')
    context['items'] = paginate(contacts, page)
    return render(request, 'contact_index.html', context)

@staff_member_required
def estimate(request, pk=None):
    context = {}

    company = Company.objects.get()
    if company:
        context['company'] = company

    estimate = get_object_or_404(Estimate, pk=pk)
    context['estimate'] = estimate

    times = Time.objects.filter(client=estimate.client)
    entries, total = entries_total(times)

    context['entries'] = entries
    context['total'] = total

    pdf = request.GET.get('pdf')
    if pdf:
        response = HttpResponse(content_type='application/pdf')
        return generate_pdf('estimate_table.html',
                            context=context,
                            file_object=response)
    else:
        return render(request, 'estimate.html', context)

@staff_member_required
def estimate_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = EstimateForm()
        else:
            client = get_object_or_404(Client, pk=client)
            estimate = Estimate(client=client)
            form = EstimateForm(instance=estimate)
    else:
        estimate = get_object_or_404(Estimate, pk=pk)
        form = EstimateForm(instance=estimate)

    if request.method == 'POST':

        if pk is None:
            form = EstimateForm(request.POST)
        else:
            estimate = get_object_or_404(Estimate, pk=pk)
            form = EstimateForm(request.POST, instance=estimate)

        if form.is_valid():
            estimate = form.save()
            return HttpResponseRedirect(reverse('estimate_index'))

    context['form'] = form
    return render(request, 'estimate_edit.html', context)

@staff_member_required
def estimate_index(request):
    context = {}
    estimates = Estimate.objects.all()
    context['estimates'] = estimates
    return render(request, 'estimate_index.html', context)

def home(request):
    context = {}
    clients = Client.objects.all()
    context['request'] = request
    context['clients'] = clients
    return render(request, 'home.html', context)

@staff_member_required
def invoice(request, pk=None):
    context = {}

    company = Company.objects.get()
    if company:
        context['company'] = company

    invoice = get_object_or_404(Invoice, pk=pk)
    context['invoice'] = invoice

    times = Time.objects.filter(client=invoice.client)
    entries, total = entries_total(times)

    context['entries'] = entries
    context['total'] = total

    pdf = request.GET.get('pdf')
    if pdf:
        response = HttpResponse(content_type='application/pdf')
        return generate_pdf('invoice_table.html',
                            context=context,
                            file_object=response)
    else:
        return render(request, 'invoice.html', context)

@staff_member_required
def invoice_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = InvoiceForm()
        else:
            client = get_object_or_404(Client, pk=client)
            invoice = Invoice(client=client)
            form = InvoiceForm(instance=invoice)
    else:
        invoice = get_object_or_404(Invoice, pk=pk)
        form = InvoiceForm(instance=invoice)

    if request.method == 'POST':

        if pk is None:
            form = InvoiceForm(request.POST)
        else:
            invoice = get_object_or_404(Invoice, pk=pk)
            form = InvoiceForm(request.POST, instance=invoice)

        if form.is_valid():
            invoice = form.save()
            return HttpResponseRedirect(reverse('invoice_index'))

    context['form'] = form
    return render(request, 'invoice_edit.html', context)

@staff_member_required
def invoice_index(request):
    client = None
    context = {}
    invoices = []
    for invoice in Invoice.objects.all():
        clients = Client.objects.filter(project=invoice.project)
        if len(clients) > 0:
            client = clients[0]
        invoices.append([invoice, client])
    context['invoices'] = invoices

    return render(request, 'invoice_index.html', context)

@staff_member_required
def project(request, pk=None):
    context = {}
    project = get_object_or_404(Project, pk=pk)
    times = Time.objects.filter(project=project)
    context['project'] = project
    context['times'] = times
    return render(request, 'project.html', context)

@staff_member_required
def project_edit(request, pk=None):
    context = {}

    client = request.GET.get('client', None)

    if pk is None:
        if client is None:
            form = ProjectForm()
        else:
            client = get_object_or_404(Client, pk=client)
            project = Project(client=client)
            form = ProjectForm(instance=project)
    else:
        project = get_object_or_404(Project, pk=pk)
        form = ProjectForm(instance=project)

    if request.method == 'POST':

        if pk is None:
            form = ProjectForm(request.POST)
        else:
            project = get_object_or_404(Project, pk=pk)
            form = ProjectForm(request.POST, instance=project)

        if form.is_valid():
            project = form.save()
            return HttpResponseRedirect(reverse('project_index'))

    context['form'] = form
    return render(request, 'project_edit.html', context)

@staff_member_required
def project_index(request, pk=None):
    context = {}
    projects = Project.objects.all()
    page = request.GET.get('page')
    context['items'] = paginate(projects, page)
    return render(request, 'project_index.html', context)

@staff_member_required
def task(request, pk=None):
    context = {}
    task = get_object_or_404(Task, pk=pk)
    context['task'] = task
    return render(request, 'task.html', context)

@staff_member_required
def task_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TaskForm()
        else:
            project = get_object_or_404(Project, pk=project)
            task = Task(project=project)
            form = TaskForm(instance=task)
    else:
        task = get_object_or_404(Task, pk=pk)
        form = TaskForm(instance=task)

    if request.method == 'POST':

        if pk is None:
            form = TaskForm(request.POST)
        else:
            task = get_object_or_404(Task, pk=pk)
            form = TaskForm(request.POST, instance=task)

        if form.is_valid():
            task = form.save()
            return HttpResponseRedirect(reverse('task_index'))

    context['form'] = form
    return render(request, 'task_edit.html', context)

@staff_member_required
def task_index(request):
    context = {}
    tasks = Task.objects.all()
    context['tasks'] = tasks
    return render(request, 'task_index.html', context)

@login_required
def time(request, pk=None):
    context = {}
    entry = get_object_or_404(Time, pk=pk)
    context['entry'] = entry
    return render(request, 'time.html', context)

@login_required
def time_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TimeForm()
        else:
            project = get_object_or_404(Project, pk=project)
            time = Time(project=project)
            form = TimeForm(instance=time)
    else:
        time = get_object_or_404(Time, pk=pk)
        form = TimeForm(instance=time)

    if request.method == 'POST':

        if pk is None:
            form = TimeForm(request.POST)
        else:
            time = get_object_or_404(Time, pk=pk)
            form = TimeForm(request.POST, instance=time)

        if form.is_valid():
            time = form.save()
            return HttpResponseRedirect(reverse('entry_index'))

    context['form'] = form
    return render(request, 'time_edit.html', context)

@login_required
def time_index(request):
    context = {}
    entries = Time.objects.all()
    context['entries'] = entries
    return render(request, 'time_index.html', context)

@login_required
def user(request, pk=None):
    context = {}
    user = get_object_or_404(User, pk=pk)
    context['request'] = request
    context['user'] = user

    if request.user.pk == int(pk) or request.user.is_staff:
        return render(request, 'user.html', context)
    else:
        return HttpResponseRedirect(reverse('home'))

@staff_member_required
def user_index(request):
    context = {}
    users = User.objects.all()
    context['users'] = users
    return render(request, 'user_index.html', context)

@staff_member_required
def user_mail(request, pk=None):
    context = {}
    recipients = []
    user = get_object_or_404(User, pk=pk)
    if request.method == 'POST':
        form = MailForm(request.POST)
        if form.is_valid():
            sender = settings.DEFAULT_FROM_EMAIL
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            recipients.append(user.email)
            send_mail(subject,
                      message,
                      sender,
                      recipients,
                      fail_silently=False)
            messages.add_message(request, messages.SUCCESS, 'Success!')
            return HttpResponseRedirect(reverse('user_index'))
    else:
        form = MailForm()
    context['form'] = form
    context['user'] = user
    return render(request, 'user_mail.html', context)
<commit_msg>Update<commit_after>from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.models import User
from django.conf import settings
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django_xhtml2pdf.utils import generate_pdf
from .forms import ClientForm
from .forms import ContactForm
from .forms import EstimateForm
from .forms import InvoiceForm
from .forms import MailForm
from .forms import ProjectForm
from .forms import TaskForm
from .forms import TimeForm
from .models import Client
from .models import Company
from .models import Contact
from .models import Estimate
from .models import Invoice
from .models import Project
from .models import Task
from .models import Time
from .utils import entries_total
from .utils import paginate

# Create your views here.

@staff_member_required
def client(request, pk=None):
    context = {}
    client = get_object_or_404(Client, pk=pk)
    projects = Project.objects.filter(client=client)
    context['client'] = client
    context['projects'] = projects
    return render(request, 'client.html', context)

@staff_member_required
def client_edit(request, pk=None):
    context = {}

    if pk is None:
        form = ClientForm()
    else:
        client = get_object_or_404(Client, pk=pk)
        form = ClientForm(instance=client)

    if request.method == 'POST':

        if pk is None:
            form = ClientForm(request.POST)
        else:
            form = ClientForm(request.POST, instance=client)

        if form.is_valid():
            client = form.save()
            return HttpResponseRedirect(reverse('client_index'))

    context['form'] = form
    return render(request, 'client_edit.html', context)

@staff_member_required
def client_index(request):
    context = {}
    clients = Client.objects.filter(active=True)
    page = request.GET.get('page')
    context['items'] = paginate(clients, page)
    return render(request, 'client_index.html', context)

@staff_member_required
def contact(request, pk=None):
    context = {}
    contact = get_object_or_404(Contact, pk=pk)
    context['contact'] = contact
    return render(request, 'contact.html', context)

@staff_member_required
def contact_edit(request, pk=None):
    context = {}
    contact = None

    if pk is None:
        form = ContactForm()
    else:
        contact = get_object_or_404(Contact, pk=pk)
        form = ContactForm(instance=contact)

    if request.method == 'POST':

        if pk is None:
            form = ContactForm(request.POST)
        else:
            form = ContactForm(request.POST, instance=contact)

        if form.is_valid():
            contact = form.save()
            return HttpResponseRedirect(reverse('contact_index'))

    context['contact'] = contact
    context['form'] = form
    return render(request, 'contact_edit.html', context)

@staff_member_required
def contact_index(request):
    context = {}
    contacts = Contact.objects.filter(active=True)
    page = request.GET.get('page')
    context['items'] = paginate(contacts, page)
    return render(request, 'contact_index.html', context)

@staff_member_required
def estimate(request, pk=None):
    context = {}

    company = Company.get_solo()
    if company:
        context['company'] = company

    estimate = get_object_or_404(Estimate, pk=pk)
    context['estimate'] = estimate

    times = Time.objects.filter(client=estimate.client)
    entries, total = entries_total(times)

    context['entries'] = entries
    context['total'] = total

    pdf = request.GET.get('pdf')
    if pdf:
        response = HttpResponse(content_type='application/pdf')
        return generate_pdf('estimate_table.html',
                            context=context,
                            file_object=response)
    else:
        return render(request, 'estimate.html', context)

@staff_member_required
def estimate_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = EstimateForm()
        else:
            client = get_object_or_404(Client, pk=client)
            estimate = Estimate(client=client)
            form = EstimateForm(instance=estimate)
    else:
        estimate = get_object_or_404(Estimate, pk=pk)
        form = EstimateForm(instance=estimate)

    if request.method == 'POST':

        if pk is None:
            form = EstimateForm(request.POST)
        else:
            estimate = get_object_or_404(Estimate, pk=pk)
            form = EstimateForm(request.POST, instance=estimate)

        if form.is_valid():
            estimate = form.save()
            return HttpResponseRedirect(reverse('estimate_index'))

    context['form'] = form
    return render(request, 'estimate_edit.html', context)

@staff_member_required
def estimate_index(request):
    context = {}
    estimates = Estimate.objects.all()
    context['estimates'] = estimates
    return render(request, 'estimate_index.html', context)

def home(request):
    context = {}
    clients = Client.objects.all()
    context['request'] = request
    context['clients'] = clients
    return render(request, 'home.html', context)

@staff_member_required
def invoice(request, pk=None):
    context = {}

    company = Company.get_solo()
    if company:
        context['company'] = company

    invoice = get_object_or_404(Invoice, pk=pk)
    context['invoice'] = invoice

    times = Time.objects.filter(client=invoice.client)
    entries, total = entries_total(times)

    context['entries'] = entries
    context['total'] = total

    pdf = request.GET.get('pdf')
    if pdf:
        response = HttpResponse(content_type='application/pdf')
        return generate_pdf('invoice_table.html',
                            context=context,
                            file_object=response)
    else:
        return render(request, 'invoice.html', context)

@staff_member_required
def invoice_edit(request, client=None, pk=None):
    context = {}

    if pk is None:
        if client is None:
            form = InvoiceForm()
        else:
            client = get_object_or_404(Client, pk=client)
            invoice = Invoice(client=client)
            form = InvoiceForm(instance=invoice)
    else:
        invoice = get_object_or_404(Invoice, pk=pk)
        form = InvoiceForm(instance=invoice)

    if request.method == 'POST':

        if pk is None:
            form = InvoiceForm(request.POST)
        else:
            invoice = get_object_or_404(Invoice, pk=pk)
            form = InvoiceForm(request.POST, instance=invoice)

        if form.is_valid():
            invoice = form.save()
            return HttpResponseRedirect(reverse('invoice_index'))

    context['form'] = form
    return render(request, 'invoice_edit.html', context)

@staff_member_required
def invoice_index(request):
    client = None
    context = {}
    invoices = []
    for invoice in Invoice.objects.all():
        clients = Client.objects.filter(project=invoice.project)
        if len(clients) > 0:
            client = clients[0]
        invoices.append([invoice, client])
    context['invoices'] = invoices

    return render(request, 'invoice_index.html', context)

@staff_member_required
def project(request, pk=None):
    context = {}
    project = get_object_or_404(Project, pk=pk)
    times = Time.objects.filter(project=project)
    context['project'] = project
    context['times'] = times
    return render(request, 'project.html', context)

@staff_member_required
def project_edit(request, pk=None):
    context = {}

    client = request.GET.get('client', None)

    if pk is None:
        if client is None:
            form = ProjectForm()
        else:
            client = get_object_or_404(Client, pk=client)
            project = Project(client=client)
            form = ProjectForm(instance=project)
    else:
        project = get_object_or_404(Project, pk=pk)
        form = ProjectForm(instance=project)

    if request.method == 'POST':

        if pk is None:
            form = ProjectForm(request.POST)
        else:
            project = get_object_or_404(Project, pk=pk)
            form = ProjectForm(request.POST, instance=project)

        if form.is_valid():
            project = form.save()
            return HttpResponseRedirect(reverse('project_index'))

    context['form'] = form
    return render(request, 'project_edit.html', context)

@staff_member_required
def project_index(request, pk=None):
    context = {}
    projects = Project.objects.all()
    page = request.GET.get('page')
    context['items'] = paginate(projects, page)
    return render(request, 'project_index.html', context)

@staff_member_required
def task(request, pk=None):
    context = {}
    task = get_object_or_404(Task, pk=pk)
    context['task'] = task
    return render(request, 'task.html', context)

@staff_member_required
def task_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TaskForm()
        else:
            project = get_object_or_404(Project, pk=project)
            task = Task(project=project)
            form = TaskForm(instance=task)
    else:
        task = get_object_or_404(Task, pk=pk)
        form = TaskForm(instance=task)

    if request.method == 'POST':

        if pk is None:
            form = TaskForm(request.POST)
        else:
            task = get_object_or_404(Task, pk=pk)
            form = TaskForm(request.POST, instance=task)

        if form.is_valid():
            task = form.save()
            return HttpResponseRedirect(reverse('task_index'))

    context['form'] = form
    return render(request, 'task_edit.html', context)

@staff_member_required
def task_index(request):
    context = {}
    tasks = Task.objects.all()
    context['tasks'] = tasks
    return render(request, 'task_index.html', context)

@login_required
def time(request, pk=None):
    context = {}
    entry = get_object_or_404(Time, pk=pk)
    context['entry'] = entry
    return render(request, 'time.html', context)

@login_required
def time_edit(request, pk=None):
    context = {}

    project = request.GET.get('project', None)

    if pk is None:
        if project is None:
            form = TimeForm()
        else:
            project = get_object_or_404(Project, pk=project)
            time = Time(project=project)
            form = TimeForm(instance=time)
    else:
        time = get_object_or_404(Time, pk=pk)
        form = TimeForm(instance=time)

    if request.method == 'POST':

        if pk is None:
            form = TimeForm(request.POST)
        else:
            time = get_object_or_404(Time, pk=pk)
            form = TimeForm(request.POST, instance=time)

        if form.is_valid():
            time = form.save()
            return HttpResponseRedirect(reverse('entry_index'))

    context['form'] = form
    return render(request, 'time_edit.html', context)

@login_required
def time_index(request):
    context = {}
    entries = Time.objects.all()
    context['entries'] = entries
    return render(request, 'time_index.html', context)

@login_required
def user(request, pk=None):
    context = {}
    user = get_object_or_404(User, pk=pk)
    context['request'] = request
    context['user'] = user

    if request.user.pk == int(pk) or request.user.is_staff:
        return render(request, 'user.html', context)
    else:
        return HttpResponseRedirect(reverse('home'))

@staff_member_required
def user_index(request):
    context = {}
    users = User.objects.all()
    context['users'] = users
    return render(request, 'user_index.html', context)

@staff_member_required
def user_mail(request, pk=None):
    context = {}
    recipients = []
    user = get_object_or_404(User, pk=pk)
    if request.method == 'POST':
        form = MailForm(request.POST)
        if form.is_valid():
            sender = settings.DEFAULT_FROM_EMAIL
            subject = form.cleaned_data['subject']
            message = form.cleaned_data['message']
            recipients.append(user.email)
            send_mail(subject,
                      message,
                      sender,
                      recipients,
                      fail_silently=False)
            messages.add_message(request, messages.SUCCESS, 'Success!')
            return HttpResponseRedirect(reverse('user_index'))
    else:
        form = MailForm()
    context['form'] = form
    context['user'] = user
    return render(request, 'user_mail.html', context)
<|endoftext|>