<commit_before>from skimage.measure import regionprops
import numpy as np
import math
import pandas as pd
import collections

def FeatureExtraction(Label, I, K=128, Fs=6, Delta=8):
    """
    Calculate features from a label image.
    Parameters
    ----------
    Label : array_like
        A label image.
    I : array_like
        A intensity image.
    K : Number of points for boundary resampling to calculate fourier
        descriptors. Default value = 128.
    Fs : Number of frequency bins for calculating FSDs. Default value = 6.
    Delta : scalar, used to dilate nuclei and define cytoplasm region.
            Default value = 8.
    Returns
    -------
    df : Pandas data frame.
    ##########     Features Start     ##########
    Slidename and centroids
    -----------------------
    Slide	X	Y
    Morphometry features
    --------------------
    Area	Perimeter	Eccentricity	Circularity
    MajorAxisLength MinorAxisLength	Extent Solidity
    FSDs
    ----
    FSD1	FSD2	FSD3	FSD4	FSD5	FSD6
    Hematoxlyin Features
    --------------------
    HematoxlyinMeanIntensity	HematoxlyinMeanMedianDifferenceIntensity
    HematoxlyinMaxIntensity	HematoxlyinMinIntensity	HematoxlyinStdIntensity
    HematoxlyinEntropy	HematoxlyinEnergy	HematoxlyinSkewness
    HematoxlyinKurtosis	HematoxlyinMeanGradMag	HematoxlyinStdGradMag
    HematoxlyinEntropyGradMag	HematoxlyinEnergyGradMag
    HematoxlyinSkewnessGradMag	HematoxlyinKurtosisGradMag
    HematoxlyinSumCanny	HematoxlyinMeanCanny
    Cytoplas Features
    --------------------
    CytoplasmMeanIntensity	CytoplasmMeanMedianDifferenceIntensity
    CytoplasmMaxIntensity	CytoplasmMinIntensity	CytoplasmStdIntensity
    CytoplasmEntropy	CytoplasmEnergy	CytoplasmSkewness	CytoplasmKurtosis
    CytoplasmMeanGradMag	CytoplasmStdGradMag	CytoplasmEntropyGradMag
    CytoplasmEnergyGradMag	CytoplasmSkewnessGradMag	CytoplasmKurtosisGradMag
    CytoplasmSumCanny	CytoplasmMeanCanny
    Boundary
    --------
    Boundaries: x1,y1;x2,y2;...
    ##########     Features End     ##########
    """

    # initialize centroids
    CentroidX = []
    CentroidY = []

    # initialize morphometry features
    Area = []
    Perimeter = []
    Eccentricity = []
    Circularity = []
    MajorAxisLength = []
    MinorAxisLength = []
    Extent = []
    Solidity = []

    # initialize panda dataframe
    df = pd.DataFrame()

    # extract feature information
    for region in regionprops(Label, I):
        # add centroids
        CentroidX = np.append(CentroidX, region.centroid[0])
        CentroidY = np.append(CentroidY, region.centroid[1])
        # add morphometry features
        Area = np.append(Area, region.area)
        Perimeter = np.append(Perimeter, region.perimeter)
        Eccentricity = np.append(Eccentricity, region.eccentricity)
        Circularity = np.append(
            Circularity,
            4 * math.pi * region.area / math.pow(region.perimeter, 2)
        )
        MajorAxisLength = np.append(MajorAxisLength, region.major_axis_length)
        MinorAxisLength = np.append(MinorAxisLength, region.minor_axis_length)
        Extent = np.append(Extent, region.extent)
        Solidity = np.append(Solidity, region.solidity)

    # add columns to dataframe
    df['X'] = CentroidX
    df['Y'] = CentroidY

    df['Area'] = Area
    df['Perimeter'] = Perimeter
    df['Eccentricity'] = Eccentricity
    df['Circularity'] = Circularity
    df['MajorAxisLength'] = MajorAxisLength
    df['MinorAxisLength'] = MinorAxisLength
    df['Extent'] = Extent
    df['Solidity'] = Solidity

    return df

def GetBounds(bbox, delta, N):
    """
    Returns bounds of object in global label image.
    """
    bounds = np.zeros(4, dtype=np.int8)
    bounds[0] = max(0, math.floor(bbox[0] - delta))
    bounds[1] = min(N-1, math.ceil(bbox[0] + bbox[2] + delta))
    bounds[2] = max(0, math.floor(bbox[1] - delta))
    bounds[3] = min(N-1, math.ceil(bbox[1] + bbox[3] + delta))

    return bounds

def InterpolateArcLength(X, Y, L):
    """
    Resamples boundary points [X, Y] at L total equal arc-length locations.

    Returns
    -------
    iX - L-length vector of horizontal interpolated coordinates with equal
         arc-length spacing.
    iY - L-length vector of vertical interpolated coordinates with equal
         arc-length spacing.
    """

    # length of X
    K = len(X)

    # generate spaced points
    Interval = np.linspace(0, 1, L)

    # get segment lengths
    Lengths = np.sqrt(
        np.power(np.diff(X), 2) + np.power(np.diff(Y), 2)
    )

    # normalize to unit length
    Lengths = Lengths / Lengths.sum()

    # calculate cumulative length along boundary
    Cumulative = np.hstack((0., np.cumsum(Lengths)))

    # place points in 'Interval' along boundary
    Locations = np.digitize(Interval, Cumulative)

    # clip to ends
    Locations[Locations < 1] = 1
    Locations[Locations >= K] = K - 1
    Locations = Locations - 1

    # linear interpolation
    Lie = np.divide(
        (Interval - [Cumulative[i] for i in Locations]),
        [Lengths[i] for i in Locations]
    )

    tX = np.array([X[i] for i in Locations])
    tY = np.array([Y[i] for i in Locations])
    iX = tX + np.multiply(
        np.array([X[i+1] for i in Locations]) - tX, Lie
    )
    iY = tY + np.multiply(
        np.array([Y[i+1] for i in Locations]) - tY, Lie
    )

    iXY = collections.namedtuple('iXY', ['iX', 'iY'])
    Output = iXY(iX, iY)

    return Output

def log2space(a, b, n):
    """
    Returns n logarithmically-spaced points from 2^a to 2^b.
    """

    A = np.power(
        2, [a + x*(b-a)/(n-1) for x in range (0, n-1) ]
    )

    B = np.power(
        2, b
    )

    A = np.hstack((A, B))

    return A
<commit_msg>Update FeatureExtraction.py added log2space function<commit_after>from skimage.measure import regionprops
import numpy as np
import math
import pandas as pd
import collections

def FeatureExtraction(Label, I, K=128, Fs=6, Delta=8):
    """
    Calculate features from a label image.
    Parameters
    ----------
    Label : array_like
        A label image.
    I : array_like
        A intensity image.
    K : Number of points for boundary resampling to calculate fourier
        descriptors. Default value = 128.
    Fs : Number of frequency bins for calculating FSDs. Default value = 6.
    Delta : scalar, used to dilate nuclei and define cytoplasm region.
            Default value = 8.
    Returns
    -------
    df : Pandas data frame.
    ##########     Features Start     ##########
    Slidename and centroids
    -----------------------
    Slide	X	Y
    Morphometry features
    --------------------
    Area	Perimeter	Eccentricity	Circularity
    MajorAxisLength MinorAxisLength	Extent Solidity
    FSDs
    ----
    FSD1	FSD2	FSD3	FSD4	FSD5	FSD6
    Hematoxlyin Features
    --------------------
    HematoxlyinMeanIntensity	HematoxlyinMeanMedianDifferenceIntensity
    HematoxlyinMaxIntensity	HematoxlyinMinIntensity	HematoxlyinStdIntensity
    HematoxlyinEntropy	HematoxlyinEnergy	HematoxlyinSkewness
    HematoxlyinKurtosis	HematoxlyinMeanGradMag	HematoxlyinStdGradMag
    HematoxlyinEntropyGradMag	HematoxlyinEnergyGradMag
    HematoxlyinSkewnessGradMag	HematoxlyinKurtosisGradMag
    HematoxlyinSumCanny	HematoxlyinMeanCanny
    Cytoplas Features
    --------------------
    CytoplasmMeanIntensity	CytoplasmMeanMedianDifferenceIntensity
    CytoplasmMaxIntensity	CytoplasmMinIntensity	CytoplasmStdIntensity
    CytoplasmEntropy	CytoplasmEnergy	CytoplasmSkewness	CytoplasmKurtosis
    CytoplasmMeanGradMag	CytoplasmStdGradMag	CytoplasmEntropyGradMag
    CytoplasmEnergyGradMag	CytoplasmSkewnessGradMag	CytoplasmKurtosisGradMag
    CytoplasmSumCanny	CytoplasmMeanCanny
    Boundary
    --------
    Boundaries: x1,y1;x2,y2;...
    ##########     Features End     ##########
    """

    # initialize centroids
    CentroidX = []
    CentroidY = []

    # initialize morphometry features
    Area = []
    Perimeter = []
    Eccentricity = []
    Circularity = []
    MajorAxisLength = []
    MinorAxisLength = []
    Extent = []
    Solidity = []

    # initialize panda dataframe
    df = pd.DataFrame()

    # extract feature information
    for region in regionprops(Label, I):
        # add centroids
        CentroidX = np.append(CentroidX, region.centroid[0])
        CentroidY = np.append(CentroidY, region.centroid[1])
        # add morphometry features
        Area = np.append(Area, region.area)
        Perimeter = np.append(Perimeter, region.perimeter)
        Eccentricity = np.append(Eccentricity, region.eccentricity)
        Circularity = np.append(
            Circularity,
            4 * math.pi * region.area / math.pow(region.perimeter, 2)
        )
        MajorAxisLength = np.append(MajorAxisLength, region.major_axis_length)
        MinorAxisLength = np.append(MinorAxisLength, region.minor_axis_length)
        Extent = np.append(Extent, region.extent)
        Solidity = np.append(Solidity, region.solidity)

    # add columns to dataframe
    df['X'] = CentroidX
    df['Y'] = CentroidY

    df['Area'] = Area
    df['Perimeter'] = Perimeter
    df['Eccentricity'] = Eccentricity
    df['Circularity'] = Circularity
    df['MajorAxisLength'] = MajorAxisLength
    df['MinorAxisLength'] = MinorAxisLength
    df['Extent'] = Extent
    df['Solidity'] = Solidity

    return df

def GetBounds(bbox, delta, N):
    """
    Returns bounds of object in global label image.
    """
    bounds = np.zeros(4, dtype=np.int8)
    bounds[0] = max(0, math.floor(bbox[0] - delta))
    bounds[1] = min(N-1, math.ceil(bbox[0] + bbox[2] + delta))
    bounds[2] = max(0, math.floor(bbox[1] - delta))
    bounds[3] = min(N-1, math.ceil(bbox[1] + bbox[3] + delta))

    return bounds

def InterpolateArcLength(X, Y, L):
    """
    Resamples boundary points [X, Y] at L total equal arc-length locations.

    Returns
    -------
    iX - L-length vector of horizontal interpolated coordinates with equal
         arc-length spacing.
    iY - L-length vector of vertical interpolated coordinates with equal
         arc-length spacing.
    """

    # length of X
    K = len(X)

    # generate spaced points
    Interval = np.linspace(0, 1, L)

    # get segment lengths
    Lengths = np.sqrt(
        np.power(np.diff(X), 2) + np.power(np.diff(Y), 2)
    )

    # normalize to unit length
    Lengths = Lengths / Lengths.sum()

    # calculate cumulative length along boundary
    Cumulative = np.hstack((0., np.cumsum(Lengths)))

    # place points in 'Interval' along boundary
    Locations = np.digitize(Interval, Cumulative)

    # clip to ends
    Locations[Locations < 1] = 1
    Locations[Locations >= K] = K - 1
    Locations = Locations - 1

    # linear interpolation
    Lie = np.divide(
        (Interval - [Cumulative[i] for i in Locations]),
        [Lengths[i] for i in Locations]
    )

    tX = np.array([X[i] for i in Locations])
    tY = np.array([Y[i] for i in Locations])
    iX = tX + np.multiply(
        np.array([X[i+1] for i in Locations]) - tX, Lie
    )
    iY = tY + np.multiply(
        np.array([Y[i+1] for i in Locations]) - tY, Lie
    )

    iXY = collections.namedtuple('iXY', ['iX', 'iY'])
    Output = iXY(iX, iY)

    return Output

def log2space(a, b, n):
    """
    Returns n logarithmically-spaced points from 2^a to 2^b.
    """

    A = np.power(
        2, [a + x*(b-a)/(n-1) for x in range(0, n-1)]
    )

    B = np.power(
        2, b
    )

    A = np.hstack((A, B))

    return A
<|endoftext|>


<commit_before>"""Wrapper around Pandoc. Used by builder."""

from __future__ import print_function

import sys
import subprocess
from . import gitutils

PANDOC_PATH = "pandoc"
FROM_PARAMS = "-f markdown_strict+simple_tables+multiline_tables+grid_tables+pipe_tables+table_captions+fenced_code_blocks+line_blocks+definition_lists+all_symbols_escapable+strikeout+superscript+subscript+lists_without_preceding_blankline+implicit_figures+raw_tex+citations+tex_math_dollars+header_attributes+auto_identifiers+startnum+footnotes+inline_notes+fenced_code_attributes+intraword_underscores+escaped_line_breaks"
LATEX_PARAMS = "--no-tex-ligatures --smart --normalize --listings --latex-engine=xelatex"

def generate_variable(key, value):
    """Generate a ``--variable key=value`` entry."""

    return '--variable "%s"="%s"' % (key, value)

def generate_command(params, output_file, src_file, cfg):
    """Generate the entire Pandoc command with params to invoke."""

    params = ["-o " + output_file, FROM_PARAMS, LATEX_PARAMS, params]

    for key, value in cfg.items():
        if key in ("title", "second_title", "year", "date", "title_page", "tof", "toc"):
            params.append(generate_variable(key, value))
        elif key == "template":
            params.append('--template="%s.tex"' % value)
        elif key == "lang":
            if value in ("russian", "english"):
                params.append(generate_variable(value, "true"))
            else:
                params.append(generate_variable("russian", "true"))
        elif key == "version":
            if value == "auto":
                params.append(generate_variable(key, gitutils.get_version()))
            else:
                params.append(generate_variable(key, value))
        elif key == "company":
            if value in ("restream", "undev"):
                params.append(generate_variable(value, "true"))
            else:
                raise RuntimeError("Unsupported company: %s" % value)
        elif key in ("type", "alt_doc_type"):
            if value:
                params.append(generate_variable(key, value))
        elif key == "filters":
            for filt in value:
                params.append("-F %s" % filt)
        elif key == "file_name":
            pass
        else:
            print("Unsupported config key: %s" % key)

    return ' '.join([PANDOC_PATH] + params + [src_file])

def run(command, src_dir):
    """Invoke the Pandoc executable with the generated params."""

    print("Baking output... ", end='')
    sys.stdout.flush()

    try:
        subprocess.check_output(
            command,
            cwd=src_dir,
            stderr=subprocess.PIPE,
            shell=True
        )

        print("Done!")

    except subprocess.CalledProcessError as e:
        quit(e.stderr.decode())

def to_pdf(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to PDF via Pandoc."""

    pandoc_command = generate_command(
        "-t latex",
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)

def to_docx(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to Docx via Pandoc."""

    pandoc_command = generate_command(
        '--reference-docx="ref.docx"',
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)

def to_tex(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to TeX via Pandoc."""

    pandoc_command = generate_command(
        "-t latex",
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)
<commit_msg>Pandoc: Wrap long lines.<commit_after>"""Wrapper around Pandoc. Used by builder."""

from __future__ import print_function

import sys
import subprocess
from . import gitutils

PANDOC_PATH = "pandoc"

FROM_PARAMS = "-f markdown_strict+simple_tables+multiline_tables+grid_tables+\
pipe_tables+table_captions+fenced_code_blocks+line_blocks+definition_lists+\
all_symbols_escapable+strikeout+superscript+subscript+\
lists_without_preceding_blankline+implicit_figures+raw_tex+citations+\
tex_math_dollars+header_attributes+auto_identifiers+startnum+footnotes+\
inline_notes+fenced_code_attributes+intraword_underscores+escaped_line_breaks"

LATEX_PARAMS = "--no-tex-ligatures --smart --normalize --listings \
--latex-engine=xelatex"

def generate_variable(key, value):
    """Generate a ``--variable key=value`` entry."""

    return '--variable "%s"="%s"' % (key, value)

def generate_command(params, output_file, src_file, cfg):
    """Generate the entire Pandoc command with params to invoke."""

    params = ["-o " + output_file, FROM_PARAMS, LATEX_PARAMS, params]

    for key, value in cfg.items():
        if key in ("title", "second_title", "year", "date", "title_page", "tof", "toc"):
            params.append(generate_variable(key, value))
        elif key == "template":
            params.append('--template="%s.tex"' % value)
        elif key == "lang":
            if value in ("russian", "english"):
                params.append(generate_variable(value, "true"))
            else:
                params.append(generate_variable("russian", "true"))
        elif key == "version":
            if value == "auto":
                params.append(generate_variable(key, gitutils.get_version()))
            else:
                params.append(generate_variable(key, value))
        elif key == "company":
            if value in ("restream", "undev"):
                params.append(generate_variable(value, "true"))
            else:
                raise RuntimeError("Unsupported company: %s" % value)
        elif key in ("type", "alt_doc_type"):
            if value:
                params.append(generate_variable(key, value))
        elif key == "filters":
            for filt in value:
                params.append("-F %s" % filt)
        elif key == "file_name":
            pass
        else:
            print("Unsupported config key: %s" % key)

    return ' '.join([PANDOC_PATH] + params + [src_file])

def run(command, src_dir):
    """Invoke the Pandoc executable with the generated params."""

    print("Baking output... ", end='')
    sys.stdout.flush()

    try:
        subprocess.check_output(
            command,
            cwd=src_dir,
            stderr=subprocess.PIPE,
            shell=True
        )

        print("Done!")

    except subprocess.CalledProcessError as e:
        quit(e.stderr.decode())

def to_pdf(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to PDF via Pandoc."""

    pandoc_command = generate_command(
        "-t latex",
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)

def to_docx(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to Docx via Pandoc."""

    pandoc_command = generate_command(
        '--reference-docx="ref.docx"',
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)

def to_tex(src_file, output_file, tmp_path, cfg):
    """Convert Markdown to TeX via Pandoc."""

    pandoc_command = generate_command(
        "-t latex",
        output_file,
        src_file,
        cfg
    )
    run(pandoc_command, tmp_path)
<|endoftext|>


<commit_before>import nflgame # https://github.com/BurntSushi/nflgame

def byeweek(team, year):
    # takes team symbol (3 letters) and year of bye week
    # returns bye week, 0 if no result, does not work for bye weeks that have not yet happened
    gameweeks = []
    for x in range(1, 18):
        games = nflgame.games(year, week=x, home=None, away=None, kind='REG', started=False)
        if games == []:
            return 0
        weekteams = []
        for i in games:
            weekteams.append(i.home)
            weekteams.append(i.away)
        if team not in weekteams and weekteams!=[]:
            return x
    return 0

def flexstats(name, year, wk):
    # takes players full name, year of game, week of game(s)
    # applies for all players that can play in the flex (RB, WR, TE)
    playerlist = nflgame.find(name, team=None)
    if playerlist == []:
        return False
    else:
        player = playerlist[0]
        rushyds=0
        rushtd=0
        recyds=0
        rectd=0
        games = nflgame.games(year, week=wk)
        gameplayers = nflgame.combine_game_stats(games)
        for p in gameplayers.rushing():
            if p.name == player.gsis_name:
                rushyds=p.rushing_yds
                rushtd=p.rushing_tds
        for p in gameplayers.receiving():
            if p.name == player.gsis_name:
                recyds=p.receiving_yds
                rectd=p.receiving_tds
    return [rushyds, rushtd, recyds, rectd]
    # returns rushing yards, rushing tds, receiving yard, receiving tds

def qbstats(name, year, wk):
    # takes players full name, year of game, week of game(s)
    # applies for all quarterbacks
    playerlist = nflgame.find(name, team=None)
    if playerlist == []:
        return False
    else:
        player = playerlist[0]
        passyds=0
        passtd=0
        inter=0
        rushyds=0
        rushtd=0
        games = nflgame.games(year, week=wk)
        gameplayers = nflgame.combine_game_stats(games)
        for p in gameplayers.passing():
            if p.name == player.gsis_name:
                passyds=p.passing_yds
                passtd=p.passing_tds
                inter=p.passing_ints
        for p in gameplayers.rushing():
            if p.name == player.gsis_name:
                rushyds=p.rushing_yds
                rushtd=p.rushing_tds
        return [passyds, passtd, inter, rushyds, rushtd]

# Note: still need to add some stats such as fumbles<commit_msg>Changed to Dictionary<commit_after>import nflgame # https://github.com/BurntSushi/nflgame

def byeweek(team, year):
    # takes team symbol (3 letters) and year of bye week
    # returns bye week, 0 if no result, does not work for bye weeks that have not yet happened
    gameweeks = []
    for x in range(1, 18):
        games = nflgame.games(year, week=x, home=None, away=None, kind='REG', started=False)
        if games == []:
            return 0
        weekteams = []
        for i in games:
            weekteams.append(i.home)
            weekteams.append(i.away)
        if team not in weekteams and weekteams!=[]:
            return x
    return 0

def flexstats(name, year, wk):
    # takes players full name, year of game, week of game(s)
    # applies for all players that can play in the flex (RB, WR, TE)
    playerlist = nflgame.find(name, team=None)
    if playerlist == []:
        return False
    else:
        player = playerlist[0]
        stats = {'rushing_yds':0, 'rushing_tds':0, 'receiving_yds':0, 'receiving_tds':0}
        games = nflgame.games(year, week=wk)
        gameplayers = nflgame.combine_game_stats(games)
        for p in gameplayers.rushing():
            if p.name == player.gsis_name:
                stats['rushing_yds']=p.rushing_yds
                stats['rushing_tds']=p.rushing_tds
        for p in gameplayers.receiving():
            if p.name == player.gsis_name:
                stats['receiving_yds']=p.receiving_yds
                stats['receiving_tds']=p.receiving_tds
    return stats
    # returns rushing yards, rushing tds, receiving yard, receiving tds

def qbstats(name, year, wk):
    # takes players full name, year of game, week of game(s)
    # applies for all quarterbacks
    playerlist = nflgame.find(name, team=None)
    if playerlist == []:
        return False
    else:
        player = playerlist[0]
        stats = {'rushing_yds':0, 'rushing_tds':0, 'passing_yds':0, 'passing_tds':0, 'passing_ints':0}
        games = nflgame.games(year, week=wk)
        gameplayers = nflgame.combine_game_stats(games)
        for p in gameplayers.passing():
            if p.name == player.gsis_name:
                stats['passing_yds']=p.passing_yds
                stats['passing_tds']=p.passing_tds
                stats['passing_ints']=p.passing_ints
        for p in gameplayers.rushing():
            if p.name == player.gsis_name:
                stats['rushing_yds']=p.rushing_yds
                stats['rushing_tds']=p.rushing_tds
        return stats

# Note: still need to add some stats such as fumbles, change to dictionary not array<|endoftext|>


<commit_before>from django.contrib.postgres.search import SearchQuery
from django.db.models import Count, Sum
from django.db.models import F

# from django.views.decorators.cache import cache_page
# from django.utils.decorators import method_decorator

from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from rest_framework.response import Response

from .. import models
from .. import serializers

class CoordinatesPagination(PageNumberPagination):
    page_query_param = "page"
    page_size = 500

class FinancialYearViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.FinancialYear.objects.all()
    serializer_class = serializers.FinancialYearSerializer

class BudgetPhaseViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.BudgetPhase.objects.all()
    serializer_class = serializers.BudgetPhaseSerializer

class ProjectViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.Project.objects.all()
    serializer_class = serializers.ProjectSerializer

    def get_queryset(self):
        queryset = models.Project.objects.prefetch_related(
            "geography",
            "expenditure",
            "expenditure__budget_phase",
            "expenditure__financial_year",
        ).all()
        geo = self.request.query_params.get("geo", None)
        if geo is not None:
            queryset = queryset.filter(geography__geo_code=geo)
        return queryset

    def get_serializer_context(self, **kwargs):
        context = super(ProjectViewSet, self).get_serializer_context(**kwargs)
        if "full" in self.request.query_params:
            context["full"] = True
        return context

class ProjectCoordinates(generics.ListCreateAPIView):
    queryset = models.Project.objects.prefetch_related(
        "expenditure",
        "expenditure__budget_phase",
        "expenditure__financial_year",
        "geography",
    )
    serializer_class = serializers.GeoProjectSerializer
    pagination_class = CoordinatesPagination

    fieldmap = {
        "function": "function",
        "project_type": "project_type",
        "municipality": "geography__name",
        "province": "geography__province_name",
        "budget_phase": "expenditure__budget_phase__name",
        "financial_year": "expenditure__financial_year__budget_year",
    }

    def list(self, request):
        search_query = request.GET.get("q", "")
        queryset = self.get_queryset()
        queryset = self.filters(queryset, request.GET)
        queryset = self.text_search(queryset, search_query)
        queryset = self.paginate_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)

        return self.get_paginated_response(serializer.data)

    def text_search(self, qs, text):
        if len(text) == 0:
            return qs

        return qs.filter(content_search=SearchQuery(text))

    def filters(self, queryset, params):
        query_dict = {}
        for k, v in self.fieldmap.items():
            if k in params:
                query_dict[v] = params[k]

        return queryset.filter(**query_dict)

class ProjectSearch(generics.ListCreateAPIView):
    queryset = models.Project.objects.prefetch_related(
        "expenditure",
        "expenditure__budget_phase",
        "expenditure__financial_year",
        "geography",
    ).all()
    serializer_class = serializers.ProjectSerializer
    pagination_class = PageNumberPagination
    fieldmap = {
        "municipality": "geography__name",
        "function": "function",
        "project_type": "project_type",
        "province": "geography__province_name",
        "budget_phase": "expenditure__budget_phase__name",
        "financial_year": "expenditure__financial_year__budget_year",
    }

    order_fields = {
        "project_description": "project_description",
        "total_forecast_budget": "expenditure__amount",
        "project_type": "project_type",
        "function": "function",
    }

    def list(self, request):
        search_query = request.GET.get("q", "")
        order_field = request.GET.get("ordering", "")

        queryset = self.get_queryset()
        queryset = self.add_filters(queryset, request.GET)
        queryset = self.text_search(queryset, search_query)
        facets = self.get_facets(queryset)
        queryset = self.order_by(queryset, order_field)

        aggregations = self.aggregations(queryset, request.GET)

        queryset = self.paginate_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)
        data = {
            "projects": serializer.data,
            "facets": facets,
            "aggregations": aggregations,
        }

        return self.get_paginated_response(data)

    def text_search(self, qs, text):
        if len(text) == 0:
            return qs

        return qs.filter(content_search=SearchQuery(text))

    def aggregations(self, qs, params):
        # TODO - not sure where to put these magic values
        financial_year = params.get("financial_year", "2019/2020")
        budget_phase = params.get("budget_phase", "Budget Year")

        return {"total": qs.total_value(financial_year, budget_phase)}

    def add_filters(self, qs, params):
        """
        Going to hard code params for budget phase and financial year,
        """
        query_dict = {}
        for k, v in ProjectSearch.fieldmap.items():
            if k in params:
                query_dict[v] = params[k]

        return qs.filter(**query_dict)

    def order_by(self, qs, field):
        prefix = ""
        if len(field) > 0 and field[0] == "-":
            prefix = "-"
            field = field[1:]

        order_by = ProjectSearch.order_fields.get(field, "-project_description")

        return qs.order_by(f"{prefix}{order_by}")

    def get_facets(self, qs):
        def facet_query(field):
            return qs.values(field).annotate(count=Count(field))

        facet_muni = facet_query("geography__name")
        facet_type = facet_query("project_type")
        facet_function = facet_query("function")
        facet_province = facet_query("geography__province_name")
        js = {
            "municipality": facet_muni,
            "type": facet_type,
            "function": facet_function,
            "province": facet_province,
        }
        return js
<commit_msg>Filter projects by latest implementation year<commit_after>from django.contrib.postgres.search import SearchQuery
from django.db.models import Count, Sum
from django.db.models import F

# from django.views.decorators.cache import cache_page
# from django.utils.decorators import method_decorator

from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from rest_framework.response import Response

from .. import models
from .. import serializers

class CoordinatesPagination(PageNumberPagination):
    page_query_param = "page"
    page_size = 500

class FinancialYearViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.FinancialYear.objects.all()
    serializer_class = serializers.FinancialYearSerializer

class BudgetPhaseViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.BudgetPhase.objects.all()
    serializer_class = serializers.BudgetPhaseSerializer

class ProjectViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = models.Project.objects.all()
    serializer_class = serializers.ProjectSerializer

    def get_queryset(self):
        queryset = models.Project.objects.prefetch_related(
            "geography",
            "expenditure",
            "expenditure__budget_phase",
            "expenditure__financial_year",
        ).all()
        geo = self.request.query_params.get("geo", None)
        if geo is not None:
            queryset = queryset.filter(geography__geo_code=geo)
        return queryset

    def get_serializer_context(self, **kwargs):
        context = super(ProjectViewSet, self).get_serializer_context(**kwargs)
        if "full" in self.request.query_params:
            context["full"] = True
        return context

class ProjectCoordinates(generics.ListCreateAPIView):
    queryset = models.Project.objects.prefetch_related(
        "expenditure",
        "expenditure__budget_phase",
        "expenditure__financial_year",
        "geography",
    )
    serializer_class = serializers.GeoProjectSerializer
    pagination_class = CoordinatesPagination

    fieldmap = {
        "function": "function",
        "project_type": "project_type",
        "municipality": "geography__name",
        "province": "geography__province_name",
        "budget_phase": "expenditure__budget_phase__name",
        "financial_year": "expenditure__financial_year__budget_year",
    }

    def list(self, request):
        search_query = request.GET.get("q", "")
        queryset = self.get_queryset()
        queryset = self.filters(queryset, request.GET)
        queryset = self.text_search(queryset, search_query)
        queryset = self.paginate_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)

        return self.get_paginated_response(serializer.data)

    def text_search(self, qs, text):
        if len(text) == 0:
            return qs

        return qs.filter(content_search=SearchQuery(text))

    def filters(self, queryset, params):
        query_dict = {}
        for k, v in self.fieldmap.items():
            if k in params:
                query_dict[v] = params[k]

        return queryset.filter(**query_dict)

class ProjectSearch(generics.ListCreateAPIView):
    queryset = models.Project.objects.prefetch_related(
        "expenditure",
        "expenditure__budget_phase",
        "expenditure__financial_year",
        "geography",
    ).all()
    serializer_class = serializers.ProjectSerializer
    pagination_class = PageNumberPagination
    fieldmap = {
        "municipality": "geography__name",
        "function": "function",
        "project_type": "project_type",
        "province": "geography__province_name",
        "budget_phase": "expenditure__budget_phase__name",
        "financial_year": "expenditure__financial_year__budget_year",
    }

    order_fields = {
        "project_description": "project_description",
        "total_forecast_budget": "expenditure__amount",
        "project_type": "project_type",
        "function": "function",
    }

    def list(self, request):
        search_query = request.GET.get("q", "")
        order_field = request.GET.get("ordering", "")

        queryset = self.get_queryset()
        queryset = self.add_filters(queryset, request.GET)
        queryset = self.text_search(queryset, search_query)
        facets = self.get_facets(queryset)
        queryset = self.order_by(queryset, order_field)

        aggregations = self.aggregations(queryset, request.GET)

        queryset = self.paginate_queryset(queryset)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(queryset, many=True)
        data = {
            "projects": serializer.data,
            "facets": facets,
            "aggregations": aggregations,
        }

        return self.get_paginated_response(data)

    def text_search(self, qs, text):
        if len(text) == 0:
            return qs

        return qs.filter(content_search=SearchQuery(text))

    def aggregations(self, qs, params):
        # TODO - not sure where to put these magic values
        financial_year = params.get("financial_year", "2019/2020")
        budget_phase = params.get("budget_phase", "Budget Year")

        return {"total": qs.total_value(financial_year, budget_phase)}

    def add_filters(self, qs, params):
        """
        Going to hard code params for budget phase and financial year,
        """
        qs = qs.filter(latest_implementation_year__budget_year=params['financial_year'])

        query_dict = {}
        for k, v in ProjectSearch.fieldmap.items():
            if k in params:
                query_dict[v] = params[k]

        return qs.filter(**query_dict)

    def order_by(self, qs, field):
        prefix = ""
        if len(field) > 0 and field[0] == "-":
            prefix = "-"
            field = field[1:]

        order_by = ProjectSearch.order_fields.get(field, "-project_description")

        return qs.order_by(f"{prefix}{order_by}")

    def get_facets(self, qs):
        def facet_query(field):
            return qs.values(field).annotate(count=Count(field))

        facet_muni = facet_query("geography__name")
        facet_type = facet_query("project_type")
        facet_function = facet_query("function")
        facet_province = facet_query("geography__province_name")
        js = {
            "municipality": facet_muni,
            "type": facet_type,
            "function": facet_function,
            "province": facet_province,
        }
        return js
<|endoftext|>


<commit_before><commit_msg>INST: fixed fsl linking<commit_after><|endoftext|>


<commit_before>from matplotlib import patches as patches
from matplotlib.collections import LineCollection
from matplotlib.path import Path
import numpy as np

import param

from ..core import Element
from ..element import Annotation, Contours
from .plot import Plot

class AnnotationPlot(Plot):
    """
    Draw the Annotation element on the supplied axis. Supports axis
    vlines, hlines, arrows (with or without labels), boxes and
    arbitrary polygonal lines. Note, unlike other Plot types,
    AnnotationPlot must always operate on a supplied axis as
    Annotations may only be used as part of Overlays.
    """

    style_opts = ['alpha', 'color', 'edgecolors', 'facecolors',
                  'linewidth', 'linestyle', 'rotation', 'family',
                  'weight', 'fontsize', 'visible', 'edgecolor']

    def __init__(self, annotation, **params):
        self._annotation = annotation
        super(AnnotationPlot, self).__init__(annotation, **params)
        self._warn_invalid_intervals(self._map)
        self.handles['annotations'] = []

        line_only = ['linewidth', 'linestyle']
        arrow_opts = [opt for opt in self.style_opts if opt not in line_only]
        line_opts = line_only + ['color']
        self.opt_filter = {'hline': line_opts, 'vline': line_opts,
                           'line': line_opts,
                           '<': arrow_opts, '^': arrow_opts,
                           '>': arrow_opts, 'v': arrow_opts,
                           'spline': line_opts + ['edgecolor']}

    def _warn_invalid_intervals(self, vmap):
        "Check if the annotated intervals have appropriate keys"
        dim_labels = [d.name for d in self._map.key_dimensions]

        mismatch_set = set()
        for annotation in vmap.values():
            for spec in annotation.data:
                interval = spec[-1]
                if interval is None or dim_labels == ['Default']:
                    continue
                mismatches = set(interval.keys()) - set(dim_labels)
                mismatch_set = mismatch_set | mismatches

        if mismatch_set:
            mismatch_list= ', '.join('%r' % el for el in mismatch_set)
            self.warning("Invalid annotation interval key(s) ignored: %r" % mismatch_list)

    def _active_interval(self, key, interval):
        """
        Given an interval specification, determine whether the
        annotation should be shown or not.
        """
        dim_labels = [d.name for d in self._map.key_dimensions]
        if (interval is None) or dim_labels == ['Default']:
            return True

        key = key if isinstance(key, tuple) else (key,)
        key_dict = dict(zip(dim_labels, key))
        for key, (start, end) in interval.items():
            if (start is not None) and key_dict.get(key, -float('inf')) <= start:
                return False
            if (end is not None) and key_dict.get(key, float('inf')) > end:
                return False

        return True

    def _draw_annotations(self, annotation, key):
        """
        Draw the elements specified by the Annotation ViewableElement on the
        axis, return a list of handles.
        """
        handles = []
        opts = self.settings.closest(annotation, 'style').settings
        color = opts.get('color', 'k')

        for spec in annotation.data:
            mode, info, interval = spec[0], spec[1:-1], spec[-1]
            opts = dict(el for el in opts.items()
                        if el[0] in self.opt_filter[mode])

            if not self._active_interval(key, interval):
                continue
            if mode == 'vline':
                handles.append(self.ax.axvline(spec[1], **opts))
                continue
            elif mode == 'hline':
                handles.append(self.ax.axhline(spec[1], **opts))
                continue
            elif mode == 'line':
                line = LineCollection([np.array(info[0])], **opts)
                self.ax.add_collection(line)
                handles.append(line)
                continue
            elif mode == 'spline':
                verts, codes = info
                patch = patches.PathPatch(Path(verts, codes),
                                          facecolor='none', **opts)
                self.ax.add_patch(patch)
                continue

            text, xy, points, arrowstyle = info
            arrowprops = dict(arrowstyle=arrowstyle, color=color)
            if mode in ['v', '^']:
                xytext = (0, points if mode=='v' else -points)
            elif mode in ['>', '<']:
                xytext = (points if mode=='<' else -points, 0)
            arrow = self.ax.annotate(text, xy=xy, textcoords='offset points',
                                     xytext=xytext, ha="center", va="center",
                                     arrowprops=arrowprops, **opts)
            handles.append(arrow)
        return handles

    def __call__(self, lbrt=None):
        handles = self._draw_annotations(self._map.last, list(self._map.keys())[-1])
        self.handles['annotations'] = handles
        return self._finalize_axis(self._keys[-1])

    def update_handles(self, annotation, key, lbrt=None):
        # Clear all existing annotations
        for element in self.handles['annotations']:
            element.remove()

        self.handles['annotations'] = self._draw_annotations(annotation, key)

class ContourPlot(Plot):

    style_opts = ['alpha', 'color', 'linestyle', 'linewidth', 'visible']

    def __init__(self, *args, **params):
        self.aspect = 'equal'
        super(ContourPlot, self).__init__(*args, **params)

    def __call__(self, lbrt=None):
        lines = self._map.last

        style = self.settings.closest(lines, 'style')[self.cyclic_index]
        line_segments = LineCollection(lines.data, zorder=self.zorder, **style)
        self.handles['line_segments'] = line_segments
        self.ax.add_collection(line_segments)

        return self._finalize_axis(self._keys[-1], lbrt=lbrt)

    def update_handles(self, view, key, lbrt=None):
        self.handles['line_segments'].set_paths(view.data)

Plot.defaults.update({Annotation: AnnotationPlot,
                      Contours: ContourPlot})<commit_msg>Updated annotation plotting to work with new annotation subclasses<commit_after>from matplotlib import patches as patches
from matplotlib.collections import LineCollection
from matplotlib.path import Path
import numpy as np

import param

from ..core import Element
from ..element import Annotation, Contours, VLine, HLine, Arrow, Spline, Text
from .plot import Plot

class AnnotationPlot(Plot):
    """
    AnnotationPlot handles the display of all annotation elements.
    """

    def __init__(self, annotation, **params):
        self._annotation = annotation
        super(AnnotationPlot, self).__init__(annotation, **params)
        self.handles['annotations'] = []

    def __call__(self, lbrt=None):
        annotation = self._map.last
        opts = self.settings.closest(annotation, 'style')[self.cyclic_index]
        handle = self.draw_annotation(annotation, annotation.data, opts)
        self.handles['annotations'].append(handle)
        return self._finalize_axis(self._keys[-1])

    def update_handles(self, annotation, key, lbrt=None):
        # Clear all existing annotations
        for element in self.handles['annotations']:
            element.remove()

        opts = self.settings.closest(annotation, 'style')[self.cyclic_index]
        self.draw_annotation(annotation, annotation.data, opts)

class VLinePlot(AnnotationPlot):
    "Draw a vertical line on the axis"

    def __init__(self, annotation, **params):
        super(VLinePlot, self).__init__(annotation, **params)

    def draw_annotation(self, annotation, position, opts):
        return self.ax.axvline(position, **opts)

class HLinePlot(AnnotationPlot):
    "Draw a horizontal line on the axis"

    def __init__(self, annotation, **params):
        super(HLinePlot, self).__init__(annotation, **params)

    def draw_annotation(self, annotation, position, opts):
        "Draw a horizontal line on the axis"
        return self.ax.axhline(position, **opts)

class ArrowPlot(AnnotationPlot):
    "Draw an arrow using the information supplied to the Arrow annotation"

    def __init__(self, annotation, **params):
        super(ArrowPlot, self).__init__(annotation, **params)

    def draw_annotation(self, annotation, data, opts):
        direction, text, xy, points, arrowstyle = data
        arrowprops = {'arrowstyle':arrowstyle}
        if 'color' in opts:
            arrowprops['color'] = opts['color']
        if direction in ['v', '^']:
            xytext = (0, points if direction=='v' else -points)
        elif direction in ['>', '<']:
            xytext = (points if direction=='<' else -points, 0)
        return self.ax.annotate(text, xy=xy, textcoords='offset points',
                                xytext=xytext, ha="center", va="center",
                                arrowprops=arrowprops, **opts)

class SplinePlot(AnnotationPlot):
    "Draw the supplied Spline annotation (see Spline docstring)"

    def __init__(self, annotation, **params):
        super(SplinePlot, self).__init__(annotation, **params)

    def draw_annotation(self, annotation, data, opts):
        verts, codes = data
        patch = patches.PathPatch(Path(verts, codes),
                                  facecolor='none', edgecolor='b', **opts)
        self.ax.add_patch(patch)
        return patch

class TextPlot(AnnotationPlot):
    "Draw the Text annotation object"

    def __init__(self, annotation, **params):
        super(TextPlot, self).__init__(annotation, **params)

    def draw_annotation(self, annotation, data, opts):
        (x,y, text, fontsize,
         horizontalalignment, verticalalignment, rotation) = data
        return self.ax.text(x,y, text,
                            horizontalalignment = horizontalalignment,
                            verticalalignment = verticalalignment,
                            rotation=rotation,
                            fontsize=fontsize, **opts)

class ContourPlot(Plot):

    style_opts = ['alpha', 'color', 'linestyle', 'linewidth', 'visible']

    def __init__(self, *args, **params):
        self.aspect = 'equal'
        super(ContourPlot, self).__init__(*args, **params)

    def __call__(self, lbrt=None):
        lines = self._map.last

        style = self.settings.closest(lines, 'style')[self.cyclic_index]
        line_segments = LineCollection(lines.data, zorder=self.zorder, **style)
        self.handles['line_segments'] = line_segments
        self.ax.add_collection(line_segments)

        return self._finalize_axis(self._keys[-1], lbrt=lbrt)

    def update_handles(self, view, key, lbrt=None):
        self.handles['line_segments'].set_paths(view.data)

Plot.defaults.update({
    Contours: ContourPlot,

    VLine:VLinePlot,
    HLine:HLinePlot,
    Arrow:ArrowPlot,
    Spline:SplinePlot,

    Text:TextPlot
})
<|endoftext|>


<commit_before>import os
import commands
from msct_parser import Parser
import sys

def install_external_packages(target_os, path_sct='', issudo=''):
    if not path_sct:
        status_sct, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    package_list = []
    # search through folder to grab libraries that correspond to the OS
    for filename in os.listdir(path_sct + '/external/'):
        if target_os in filename:
            package_list.append(path_sct + '/external/' + filename)

    for package in package_list:
        print "Trying to install: " + package
        cmd = issudo + "pip install " + package
        status, output = commands.getstatusoutput(cmd)
        if status != 0:
            print '\nERROR! \n' + output + '\nExit program.\n'
        else:
            print output

    return status

def get_parser():
    # Initialize parser
    parser = Parser(__file__)

    # Mandatory arguments
    parser.usage.set_description("")

    parser.add_option(name="-a",
                      type_value=None,
                      description="If provided, compile with sudo.",
                      mandatory=False)

    return parser

if __name__ == "__main__":
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    import platform
    target_os = platform.system().lower()
    if target_os == 'darwin':
        target_os = 'osx'

    issudo = ''
    if "-a" in arguments:
        issudo = 'sudo '

    status = install_external_packages(target_os)

    if status != 0:
        sys.exit(2)
<commit_msg>INST: fixed bug on install_external<commit_after>#!/usr/bin/env python
#
# Install external packages.
#

import os
import commands
from msct_parser import Parser
import sys

def install_external_packages(target_os, path_sct='', issudo=''):
    if not path_sct:
        status_sct, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    package_list = []
    # search through folder to grab libraries that correspond to the OS
    for filename in os.listdir(path_sct + '/external/'):
        if target_os in filename:
            package_list.append(path_sct + '/external/' + filename)

    for package in package_list:
        print "Trying to install: " + package
        cmd = issudo + "pip install " + package
        status, output = commands.getstatusoutput(cmd)
        if status != 0:
            print '\nERROR! \n' + output + '\nExit program.\n'
        else:
            print output

    return status

def get_parser():
    # Initialize parser
    parser = Parser(__file__)

    # Mandatory arguments
    parser.usage.set_description("")

    parser.add_option(name="-a",
                      type_value=None,
                      description="If provided, compile with sudo.",
                      mandatory=False)

    return parser

if __name__ == "__main__":
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    import platform
    target_os = platform.system().lower()
    if target_os == 'darwin':
        target_os = 'osx'

    issudo = ''
    if "-a" in arguments:
        issudo = 'sudo '

    status = install_external_packages(target_os)

    if status != 0:
        sys.exit(2)
<|endoftext|>


<commit_before>from django.core.exceptions import PermissionDenied

from rest_framework import serializers
from drf_extra_fields.geo_fields import PointField

from login.permissions import get_permissions
from .models import Hospital, Equipment, HospitalEquipment

# HospitalEquipment serializers

class HospitalEquipmentSerializer(serializers.ModelSerializer):
    hospital_name = serializers.CharField(source='hospital.name')
    equipment_name = serializers.CharField(source='equipment.name')
    equipment_etype = serializers.CharField(source='equipment.type')

    class Meta:
        model = HospitalEquipment
        fields = ('hospital_id', 'hospital_name',
                  'equipment_id', 'equipment_name', 'equipment_etype',
                  'value', 'comment',
                  'updated_by', 'updated_on')
        read_only_fields = ('hospital_id', 'hospital_name',
                            'equipment_id', 'equipment_name', 'equipment_etype',
                            'updated_by',)

    def validate(self, data):
        # call super
        validated_data = super().validate(data)

        # TODO: validate equipment value using equipment_etype
        return validated_data

# EquipmentMetadata serializer

class EquipmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Equipment
        fields = '__all__'

# Hospital serializer
# TODO: Handle equipment in create and update

class HospitalSerializer(serializers.ModelSerializer):
    hospitalequipments = HospitalEquipmentSerializer(many=True, read_only=True)
    location = PointField(required=False)

    class Meta:
        model = Hospital
        fields = ['id',
                  'number', 'street', 'unit', 'neighborhood',
                  'city', 'state', 'zipcode', 'country',
                  'location',
                  'name',
                  'comment', 'updated_by', 'updated_on',
                  'hospitalequipments']
        read_only_fields = ('updated_by',)
        depth = 1

    def create(self, validated_data):

        # get current user
        user = validated_data['updated_by']

        # check credentials
        # only super can create
        if not user.is_superuser:
            raise PermissionDenied()

        return super().create(validated_data)

    def update(self, instance, validated_data):

        # get current user
        user = validated_data['updated_by']

        # check credentials
        if not user.is_superuser:

            # serializer.instance will always exist!
            # if not user.profile.hospitals.filter(can_write=True,
            #                                     hospital=instance.id):
            if not get_permissions(user).check_can_write(hospital=instance.id):
                raise PermissionDenied()

        return super().update(instance, validated_data)

<commit_msg>Modifying HospitalSerializer to include equipment.<commit_after>from django.core.exceptions import PermissionDenied

from rest_framework import serializers
from drf_extra_fields.geo_fields import PointField

from login.permissions import get_permissions
from .models import Hospital, Equipment, HospitalEquipment

# HospitalEquipment serializers

class HospitalEquipmentSerializer(serializers.ModelSerializer):
    hospital_name = serializers.CharField(source='hospital.name')
    equipment_name = serializers.CharField(source='equipment.name')
    equipment_etype = serializers.CharField(source='equipment.type')

    class Meta:
        model = HospitalEquipment
        fields = ('hospital_id', 'hospital_name',
                  'equipment_id', 'equipment_name', 'equipment_etype',
                  'value', 'comment',
                  'updated_by', 'updated_on')
        read_only_fields = ('hospital_id', 'hospital_name',
                            'equipment_id', 'equipment_name', 'equipment_etype',
                            'updated_by',)

    def validate(self, data):
        # call super
        validated_data = super().validate(data)

        # TODO: validate equipment value using equipment_etype
        return validated_data

# EquipmentMetadata serializer

class EquipmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Equipment
        fields = '__all__'

# Hospital serializer
# TODO: Handle equipment in create and update

class HospitalSerializer(serializers.ModelSerializer):
    hospitalequipments_set = HospitalEquipmentSerializer(many=True, read_only=True)
    location = PointField(required=False)

    class Meta:
        model = Hospital
        fields = ['id',
                  'number', 'street', 'unit', 'neighborhood',
                  'city', 'state', 'zipcode', 'country',
                  'location',
                  'name',
                  'comment', 'updated_by', 'updated_on',
                  'hospitalequipments_set']
        read_only_fields = ('updated_by',)

    def create(self, validated_data):

        # get current user
        user = validated_data['updated_by']

        # check credentials
        # only super can create
        if not user.is_superuser:
            raise PermissionDenied()

        return super().create(validated_data)

    def update(self, instance, validated_data):

        # get current user
        user = validated_data['updated_by']

        # check credentials
        if not user.is_superuser:

            # serializer.instance will always exist!
            # if not user.profile.hospitals.filter(can_write=True,
            #                                     hospital=instance.id):
            if not get_permissions(user).check_can_write(hospital=instance.id):
                raise PermissionDenied()

        return super().update(instance, validated_data)

<|endoftext|>


<commit_before>#!/usr/bin/python
#
# author:
#
# date:
# description:
#
import numpy
import theano
from theano import tensor
from blocks import initialization
from blocks.bricks.recurrent import SimpleRecurrent
from blocks.bricks import Linear, Softmax, Tanh
from blocks.bricks.lookup import LookupTable

from dataset import createDataset
train_data,vocab_size = createDataset()

def initLayers(layers):
    for l in layers: l.initialize()

HIDDEN_DIM = 100
VOCAB_DIM = vocab_size

# input
x = tensor.ivector('inchar')
y = tensor.imatrix('outchar')

#
W = LookupTable(
    dim = HIDDEN_DIM,
    length = VOCAB_DIM,
    weights_init = initialization.IsotropicGaussian(0.01),
    biases_init = initialization.Constant(0)
)
# recurrent history weight
H = SimpleRecurrent(
    dim = HIDDEN_DIM,
    activation = Tanh(),
    weights_init = initialization.IsotropicGaussian(0.01)
)
#
S = Linear(
    input_dim = HIDDEN_DIM,
    output_dim = VOCAB_DIM,
    weights_init = initialization.IsotropicGaussian(0.01),
    biases_init = initialization.Constant(0)
)

A = Softmax()

initLayers([W,H,S])
y_hat = A.apply(S.apply(H.apply(W.apply(x))))
cost = softmax.categorical_cross_entropy(y, y_hat).mean()

main_loop = MainLoop(
    data_stream = DataStream(
        train_data
    ),
    algorithm   = GradientDescent(
        cost=cost,
        parameters=cg.parameters,
        step_rule=Scale(learning_rate=0.1)),
        extensions = [
            DataStreamMonitoring(variables=[cost]),
            FinishAfter(after_n_epochs=10),
            Printing(),
            #TrainingDataMonitoring([cost,], after_batch=True),
        ]
)
main_loop.run()
#f = theano.function([x], out, updates=...)
<commit_msg>updated rnn, but still throws errors<commit_after>#!/usr/bin/python
#
# author:
#
# date:
# description:
#
import numpy
import theano
from theano import tensor
from blocks import initialization
from blocks.bricks.recurrent import SimpleRecurrent
from blocks.bricks import Linear, Tanh, Rectifier, NDimensionalSoftmax
from blocks.bricks.lookup import LookupTable
from blocks.bricks.cost import CategoricalCrossEntropy

from dataset import createDataset
train_data,vocab_size = createDataset()

def initLayers(layers):
    for l in layers: l.initialize()

HIDDEN_DIM = 100
VOCAB_DIM = vocab_size

# input
x = tensor.imatrix('inchar')
y = tensor.tensor3('outchar')

#
W = LookupTable(
    dim = HIDDEN_DIM,
    length = VOCAB_DIM,
    weights_init = initialization.IsotropicGaussian(0.01),
    biases_init = initialization.Constant(0)
)
# recurrent history weight
H = SimpleRecurrent(
    dim = HIDDEN_DIM,
    activation = Rectifier(),
    weights_init = initialization.IsotropicGaussian(0.01)
)
#
S = Linear(
    input_dim = HIDDEN_DIM,
    output_dim = VOCAB_DIM,
    weights_init = initialization.IsotropicGaussian(0.01),
    biases_init = initialization.Constant(0)
)

A = NDimensionalSoftmax()

initLayers([W,H,S])
activations = W.apply(x)
hiddens = H.apply(activations)
activations2 = S.apply(hiddens)
y_hat = A.apply(activations2)
cost = CategoricalCrossEntropy(y, y_hat, extra_ndim=1).mean()

"""
main_loop = MainLoop(
    data_stream = DataStream(
        train_data
    ),
    algorithm = GradientDescent(
        cost  = cost,
        parameters = cg.parameters,
        step_rule = Scale(learning_rate=0.1)),
        extensions = [
            DataStreamMonitoring(variables=[cost]),
            FinishAfter(after_n_epochs=10),
            Printing(),
            #TrainingDataMonitoring([cost,], after_batch=True),
        ]
)
main_loop.run()
"""
#f = theano.function([x], out, updates=...)
<|endoftext|>


<commit_before># -*- mode: python; coding: utf-8 -*-
# Copyright 2017 the HERA Collaboration
# Licensed under the 2-clause BSD license.
"""
Common utility fuctions

"""
from __future__ import absolute_import, division, print_function

import collections
from math import floor
import six
from astropy.time import Time
from astropy.time import Time
from astropy.time import TimeDelta
from astropy import coordinates as coord
from astropy import units as u
import numpy as np
import datetime

if six.PY2:
    def str_to_bytes(s):
        return s

    def bytes_to_str(b):
        return b
else:
    def str_to_bytes(s):
        return s.encode('utf8')

    def bytes_to_str(b):
        return b.decode('utf8')

def LSTScheduler(starttime, LSTbin_size, longitude=21.25):
    """Round a time to the nearest LST bin for a given longitude on the globe

    LSTbins run from 0 to 24 hours and step according to LSTbin_size.

    Parameters
    -----
    starttime: astropy.time.Time
               Target schedule time
    LSTbin_size: float
                 lst bin size in seconds
    longitude: float
               telescope longitude in degrees

    Returns
    -----
    schedule time          :  astropy.time.Time
                              time of next LST bin
    schedule sidereal time :  astropy.coord.Angle
                              sidereal time of next LST bin
    """
    sidesec = u.Quantity(1, 'sday').to('day').value  # length of sidereal second in SI seconds.
    locate = coord.EarthLocation(lon=longitude * u.deg, lat=-30 * u.deg)  # HERA location, #XXX get the HERA location programmatically
    if not isinstance(starttime, Time):
        raise TypeError("starttime is not a valid Astropy Time object")
    starttime.location = locate
    numChunks = (24 * 60 * 60) / LSTbin_size  # seconds in a day
    lstGrid = np.linspace(0, int(numChunks), int(numChunks) + 1, dtype=int) * LSTbin_size
    hmsList = [None] * (int(numChunks + 1))

    # convert the grid in seconds to HMS
    for i, sec in enumerate(lstGrid):  # make a grid of our evenly chunked LST times starting from 00h00m00s on the current day
        hrs = int(lstGrid[i] / 3600)
        mins = int((lstGrid[i] % 3600) / 60)
        secs = int(lstGrid[i] - int(hrs * 3600) - int(mins * 60))
        if hrs == 24:
            hrs = int(0)
        hms_str = '%02dh%02dm%02ds' % (hrs, mins, secs)
        hmsList[i] = hms_str
    lstAngleGrid = coord.Angle(hmsList)  # turn LST grid into angle array
    for i, hour in enumerate(lstAngleGrid):
        if hour >= starttime.sidereal_time('apparent'):  # Find the timeslot our target is in
            diffSide = hour - starttime.sidereal_time('apparent')  # get difference in sidereal
            diffSecs = diffSide.hms[2] * sidesec  # convert difference to SI seconds
            break
    dt = TimeDelta((diffSecs), format='sec')
    scheduleTime = starttime + dt  # adjust target time by difference to get start time
    return scheduleTime, hour

def calculate_obsid(starttime):
    """
    Create a new obsid using Astropy to compute the gps second.

    Parameters:
    ------------
    starttime: astropy time object
      observation starttime

    Returns:
    --------
    obid
    """
    if not isinstance(starttime, Time):
        raise ValueError('starttime must be an astropy Time object')

    return int(floor(starttime.gps))

def get_iterable(x):
    """Helper function to ensure iterability."""
    if isinstance(x, str):
        return (x,)
    else:
        try:
            iter(x)
        except TypeError:
            return (x,)
    return x

def _reraise_context(fmt, *args):
    """Reraise an exception with its message modified to specify additional context.

    This function tries to help provide context when a piece of code
    encounters an exception while trying to get something done, and it wishes
    to propagate contextual information farther up the call stack. It is a
    consistent way to do it for both Python 2 and 3, since Python 2 does not
    provide Python 3’s `exception chaining <https://www.python.org/dev/peps/pep-3134/>`_ functionality.
    Instead of that more sophisticated infrastructure, this function just
    modifies the textual message associated with the exception being raised.
    If only a single argument is supplied, the exception text is prepended with
    the stringification of that argument. If multiple arguments are supplied,
    the first argument is treated as an old-fashioned ``printf``-type
    (``%``-based) format string, and the remaining arguments are the formatted
    values.
    Borrowed from pwkit (https://github.com/pkgw/pwkit/blob/master/pwkit/__init__.py)
    Example usage::
      from hera_mc.utils import reraise_context
      filename = 'my-filename.txt'
      try:
        f = filename.open('rt')
        for line in f.readlines():
          # do stuff ...
      except Exception as e:
        reraise_context('while reading "%r"', filename)
        # The exception is reraised and so control leaves this function.
    If an exception with text ``"bad value"`` were to be raised inside the
    ``try`` block in the above example, its text would be modified to read
    ``"while reading \"my-filename.txt\": bad value"``.
    """
    import sys

    if len(args):
        cstr = fmt % args
    else:
        cstr = six.text_type(fmt)

    ex = sys.exc_info()[1]

    if isinstance(ex, EnvironmentError):
        ex.strerror = '%s: %s' % (cstr, ex.strerror)
        ex.args = (ex.errno, ex.strerror)
    else:
        if len(ex.args):
            cstr = '%s: %s' % (cstr, ex.args[0])
        ex.args = (cstr, ) + ex.args[1:]

    raise
<commit_msg>de-align things.<commit_after># -*- mode: python; coding: utf-8 -*-
# Copyright 2017 the HERA Collaboration
# Licensed under the 2-clause BSD license.
"""
Common utility fuctions

"""
from __future__ import absolute_import, division, print_function

import collections
from math import floor
import six
from astropy.time import Time
from astropy.time import Time
from astropy.time import TimeDelta
from astropy import coordinates as coord
from astropy import units as u
import numpy as np
import datetime

if six.PY2:
    def str_to_bytes(s):
        return s

    def bytes_to_str(b):
        return b
else:
    def str_to_bytes(s):
        return s.encode('utf8')

    def bytes_to_str(b):
        return b.decode('utf8')

def LSTScheduler(starttime, LSTbin_size, longitude=21.25):
    """Round a time to the nearest LST bin for a given longitude on the globe

    LSTbins run from 0 to 24 hours and step according to LSTbin_size.

    Parameters
    -----
    starttime : astropy.time.Time
               Target schedule time
    LSTbin_size : float
                 lst bin size in seconds
    longitude : float
               telescope longitude in degrees

    Returns
    -----
    schedule time :  astropy.time.Time
                              time of next LST bin
    schedule sidereal time :  astropy.coord.Angle
                              sidereal time of next LST bin
    """
    sidesec = u.Quantity(1, 'sday').to('day').value  # length of sidereal second in SI seconds.
    locate = coord.EarthLocation(lon=longitude * u.deg, lat=-30 * u.deg)  # HERA location, #XXX get the HERA location programmatically
    if not isinstance(starttime, Time):
        raise TypeError("starttime is not a valid Astropy Time object")
    starttime.location = locate
    numChunks = (24 * 60 * 60) / LSTbin_size  # seconds in a day
    lstGrid = np.linspace(0, int(numChunks), int(numChunks) + 1, dtype=int) * LSTbin_size
    hmsList = [None] * (int(numChunks + 1))

    # convert the grid in seconds to HMS
    for i, sec in enumerate(lstGrid):  # make a grid of our evenly chunked LST times starting from 00h00m00s on the current day
        hrs = int(lstGrid[i] / 3600)
        mins = int((lstGrid[i] % 3600) / 60)
        secs = int(lstGrid[i] - int(hrs * 3600) - int(mins * 60))
        if hrs == 24:
            hrs = int(0)
        hms_str = '%02dh%02dm%02ds' % (hrs, mins, secs)
        hmsList[i] = hms_str
    lstAngleGrid = coord.Angle(hmsList)  # turn LST grid into angle array
    for i, hour in enumerate(lstAngleGrid):
        if hour >= starttime.sidereal_time('apparent'):  # Find the timeslot our target is in
            diffSide = hour - starttime.sidereal_time('apparent')  # get difference in sidereal
            diffSecs = diffSide.hms[2] * sidesec  # convert difference to SI seconds
            break
    dt = TimeDelta((diffSecs), format='sec')
    scheduleTime = starttime + dt  # adjust target time by difference to get start time
    return scheduleTime, hour

def calculate_obsid(starttime):
    """
    Create a new obsid using Astropy to compute the gps second.

    Parameters:
    ------------
    starttime: astropy time object
      observation starttime

    Returns:
    --------
    obid
    """
    if not isinstance(starttime, Time):
        raise ValueError('starttime must be an astropy Time object')

    return int(floor(starttime.gps))

def get_iterable(x):
    """Helper function to ensure iterability."""
    if isinstance(x, str):
        return (x,)
    else:
        try:
            iter(x)
        except TypeError:
            return (x,)
    return x

def _reraise_context(fmt, *args):
    """Reraise an exception with its message modified to specify additional context.

    This function tries to help provide context when a piece of code
    encounters an exception while trying to get something done, and it wishes
    to propagate contextual information farther up the call stack. It is a
    consistent way to do it for both Python 2 and 3, since Python 2 does not
    provide Python 3’s `exception chaining <https://www.python.org/dev/peps/pep-3134/>`_ functionality.
    Instead of that more sophisticated infrastructure, this function just
    modifies the textual message associated with the exception being raised.
    If only a single argument is supplied, the exception text is prepended with
    the stringification of that argument. If multiple arguments are supplied,
    the first argument is treated as an old-fashioned ``printf``-type
    (``%``-based) format string, and the remaining arguments are the formatted
    values.
    Borrowed from pwkit (https://github.com/pkgw/pwkit/blob/master/pwkit/__init__.py)
    Example usage::
      from hera_mc.utils import reraise_context
      filename = 'my-filename.txt'
      try:
        f = filename.open('rt')
        for line in f.readlines():
          # do stuff ...
      except Exception as e:
        reraise_context('while reading "%r"', filename)
        # The exception is reraised and so control leaves this function.
    If an exception with text ``"bad value"`` were to be raised inside the
    ``try`` block in the above example, its text would be modified to read
    ``"while reading \"my-filename.txt\": bad value"``.
    """
    import sys

    if len(args):
        cstr = fmt % args
    else:
        cstr = six.text_type(fmt)

    ex = sys.exc_info()[1]

    if isinstance(ex, EnvironmentError):
        ex.strerror = '%s: %s' % (cstr, ex.strerror)
        ex.args = (ex.errno, ex.strerror)
    else:
        if len(ex.args):
            cstr = '%s: %s' % (cstr, ex.args[0])
        ex.args = (cstr, ) + ex.args[1:]

    raise
<|endoftext|>


<commit_before>from flask import Flask, render_template, request, session, url_for, redirect, json

import json
import requests
import os
import wordcloud as wc
import re
from PIL import Image, ImageDraw
from io import BytesIO
from extract_topics import cluster_topics

app = Flask(__name__)
app.secret_key = os.environ['secret_key']

client_id = os.environ['client_id']
client_secret = os.environ['client_secret']

###########################################################################################

        Methods

###########################################################################################

# Required Parameters: - Access Code  - Client ID  - Client secret
# Output: - A JSON object containing a valid access token
def getAccessToken(code):
    url = "https://api.ciscospark.com/v1/access_token"
    data = {
        'grant_type': 'authorization_code',
        'client_id': client_id,
        'client_secret': client_secret,
        'code': code,
        'redirect_uri': 'http://localhost:8080/oauth'
    }
    accessData = requests.post(url, data)
    return accessData.json()

# Required Data: - Access Token
# Output: - A dictionary containing the room names and their corresponding id
def listRooms():
    url = "https://api.ciscospark.com/v1/rooms"
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomData = (requests.get(url, headers=headers)).json()

    roomDict = {}
    for item in roomData["items"]:
        roomDict[item["title"]] = item["id"]
    return roomDict

# Required Data: - Room ID
# Output: - A JSON containing the messages of the corresponding room
def getMessages(roomId):
    url = (
        "https://api.ciscospark.com/v1/messages?roomId=%s" %roomId+
        "&max=1000"
    )
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomMessages = requests.get(url, headers=headers)
    return roomMessages.json()

# Required Parameters: - Access Token
# Output: - A JSON object containing the user's Cisco Spark details
def getUserProfile():
    url = "https://api.ciscospark.com/v1/people/me"
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    userDetails = requests.get(url, headers=headers)
    return userDetails.json()

# Required Data: - Room ID
# Output: - A list containing the display names of its group members
def getMembers(roomId):
    url = (
        "https://api.ciscospark.com/v1/memberships?roomId=%s" %roomId
    )
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomMembers = (requests.get(url, headers=headers)).json()

    members = []
    for roomMem in roomMembers["items"]:
        members.append(roomMem["personDisplayName"])

    return members

#Generate wordcloud
def generate_wordcloud(outputImgPath, inputText):
    wordcloud = wc.WordCloud(font_path = '/System/Library/Fonts/HelveticaNeue.dfont',
        height = 400, width = 600, margin=2, background_color='white',
        ranks_only=None, prefer_horizontal=.9, mask=None, scale=1, color_func=None,
        max_font_size=180, min_font_size=4, font_step=2, max_words=40, relative_scaling=0.3,
        regexp=None, collocations=True, random_state=None, mode="RGB",
        colormap=None, normalize_plurals=True)
    wordcloud.generate(inputText)
    image = wordcloud.to_image()

    image.save(outputImgPath, format='png')

    filepath = re.sub(r'static/', '', outputImgPath)
    return(filepath)

###########################################################################################

        URL Routes

###########################################################################################

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))

@app.route('/chat/<roomName>/<topic>')
def topicMessages(roomName, topic):

    topicNumber = 'topic'+str(topic)
    topiclist = session['topic']
    topicMessage = topiclist[topicNumber]["messages"]
    topicMessage = topicMessage[::-1]

    return render_template("messages.html", name = session['displayName'], room = roomName, topic = ('Topic ' + str(topic)), topicMessage = topicMessage)

@app.route('/chat/<roomName>')
def wordCloud(roomName):
    roomId = session['rooms_dict'].get(roomName)
    roomMessages = getMessages(roomId)

    processed_data = cluster_topics("room_messages.json")

    session['topic'] = processed_data

    #process JSON, extract topics
    jsonTopics = json.loads(open('clustered_topics.json').read())

    jsonTopicsStr = str(jsonTopics)

    #count number of topics
    matches = re.findall("('topic)\d+(':)", jsonTopicsStr)

    numTopics = len(matches)
    topics = [None] * numTopics
    msgs = [None] * numTopics

    #get messages from topics
    for i in range(0, numTopics):
        print(str(i))
        topicKey = 'topic' + str(i)
        topics[i] = jsonTopics[topicKey]
        msgs[i] = str(topics[i]['messages'])

    filenames = []
    #generate wordclouds
    for i in range(0, numTopics):
        filename = 'static/wordcloudimage' + str(i) + '.png'
        path = generate_wordcloud(filename, msgs[i])
        filenames.append(path)

    return render_template("wordClouds.html", room = roomName, name = session['displayName'], imageArr=filenames)

# 'Main' page with a list of all the rooms, and its users, that the user is a member of
@app.route('/main')
def main():
    displayName = session.get("displayName", False)
    if not displayName:
        return redirect(url_for('index'), code=302)

    roomSession = session.get("rooms_dict", False)
    if not roomSession:
        roomDict = listRooms()
        session['rooms_dict'] = roomDict

    roomDict = session['rooms_dict']
    rooms = list(roomDict.keys())

    participants = []
    for room in rooms[:6]:
        room_id = roomDict.get(room)
        participants.append(getMembers(room_id))

    return render_template("main.html", name = displayName, rooms = rooms[:6], members = participants)

# 'Authorised' page which redirects the user if the login was valid
@app.route('/oauth')
def oauth():
    code = request.args.get("code")

    data = getAccessToken(code)
    session['access_token'] = data['access_token']

    userDetails = getUserProfile()
    session['displayName'] = userDetails['displayName']

    return render_template("authorise.html")

# Redirect to authorisation URL (Cisco Spark login & Authorisation) using a 'GET' request
@app.route('/authorise', methods=['GET'])
def authorise():
    url = (
        "https://api.ciscospark.com/v1/authorize?"+
        "client_id=%s" %client_id+
        "&response_type=code"+
        "&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth"+
        "&scope=spark%3Aall%20spark-admin%3Aroles_read%20spark%3Akms%20spark-admin%3Aorganizations_read%20spark-admin%3Apeople_read"
    )
    return redirect(url, code=302)

@app.route('/')
def index():
    session.clear()
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080)<commit_msg>Fixed small error<commit_after>from flask import Flask, render_template, request, session, url_for, redirect, json

import json
import requests
import os
import wordcloud as wc
import re
from PIL import Image, ImageDraw
from io import BytesIO
from extract_topics import cluster_topics

app = Flask(__name__)
app.secret_key = os.environ['secret_key']

client_id = os.environ['client_id']
client_secret = os.environ['client_secret']

###########################################################################################

        #Methods

###########################################################################################

# Required Parameters: - Access Code  - Client ID  - Client secret
# Output: - A JSON object containing a valid access token
def getAccessToken(code):
    url = "https://api.ciscospark.com/v1/access_token"
    data = {
        'grant_type': 'authorization_code',
        'client_id': client_id,
        'client_secret': client_secret,
        'code': code,
        'redirect_uri': 'http://localhost:8080/oauth'
    }
    accessData = requests.post(url, data)
    return accessData.json()

# Required Data: - Access Token
# Output: - A dictionary containing the room names and their corresponding id
def listRooms():
    url = "https://api.ciscospark.com/v1/rooms"
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomData = (requests.get(url, headers=headers)).json()

    roomDict = {}
    for item in roomData["items"]:
        roomDict[item["title"]] = item["id"]
    return roomDict

# Required Data: - Room ID
# Output: - A JSON containing the messages of the corresponding room
def getMessages(roomId):
    url = (
        "https://api.ciscospark.com/v1/messages?roomId=%s" %roomId+
        "&max=1000"
    )
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomMessages = requests.get(url, headers=headers)
    return roomMessages.json()

# Required Parameters: - Access Token
# Output: - A JSON object containing the user's Cisco Spark details
def getUserProfile():
    url = "https://api.ciscospark.com/v1/people/me"
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    userDetails = requests.get(url, headers=headers)
    return userDetails.json()

# Required Data: - Room ID
# Output: - A list containing the display names of its group members
def getMembers(roomId):
    url = (
        "https://api.ciscospark.com/v1/memberships?roomId=%s" %roomId
    )
    headers = {
        'Content-type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + session['access_token']
    }
    roomMembers = (requests.get(url, headers=headers)).json()

    members = []
    for roomMem in roomMembers["items"]:
        members.append(roomMem["personDisplayName"])

    return members

#Generate wordcloud
def generate_wordcloud(outputImgPath, inputText):
    wordcloud = wc.WordCloud(font_path = '/System/Library/Fonts/HelveticaNeue.dfont',
        height = 400, width = 600, margin=2, background_color='white',
        ranks_only=None, prefer_horizontal=.9, mask=None, scale=1, color_func=None,
        max_font_size=180, min_font_size=4, font_step=2, max_words=40, relative_scaling=0.3,
        regexp=None, collocations=True, random_state=None, mode="RGB",
        colormap=None, normalize_plurals=True)
    wordcloud.generate(inputText)
    image = wordcloud.to_image()

    image.save(outputImgPath, format='png')

    filepath = re.sub(r'static/', '', outputImgPath)
    return(filepath)

###########################################################################################

        #URL Routes

###########################################################################################

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))

@app.route('/chat/<roomName>/<topic>')
def topicMessages(roomName, topic):

    topicNumber = 'topic'+str(topic)
    topiclist = session['topic']
    topicMessage = topiclist[topicNumber]["messages"]
    topicMessage = topicMessage[::-1]

    return render_template("messages.html", name = session['displayName'], room = roomName, topic = ('Topic ' + str(topic)), topicMessage = topicMessage)

@app.route('/chat/<roomName>')
def wordCloud(roomName):
    roomId = session['rooms_dict'].get(roomName)
    roomMessages = getMessages(roomId)

    processed_data = cluster_topics("room_messages.json")

    session['topic'] = processed_data

    #process JSON, extract topics
    jsonTopics = json.loads(open('clustered_topics.json').read())

    jsonTopicsStr = str(jsonTopics)

    #count number of topics
    matches = re.findall("('topic)\d+(':)", jsonTopicsStr)

    numTopics = len(matches)
    topics = [None] * numTopics
    msgs = [None] * numTopics

    #get messages from topics
    for i in range(0, numTopics):
        print(str(i))
        topicKey = 'topic' + str(i)
        topics[i] = jsonTopics[topicKey]
        msgs[i] = str(topics[i]['messages'])

    filenames = []
    #generate wordclouds
    for i in range(0, numTopics):
        filename = 'static/wordcloudimage' + str(i) + '.png'
        path = generate_wordcloud(filename, msgs[i])
        filenames.append(path)

    return render_template("wordClouds.html", room = roomName, name = session['displayName'], imageArr=filenames)

# 'Main' page with a list of all the rooms, and its users, that the user is a member of
@app.route('/main')
def main():
    displayName = session.get("displayName", False)
    if not displayName:
        return redirect(url_for('index'), code=302)

    roomSession = session.get("rooms_dict", False)
    if not roomSession:
        roomDict = listRooms()
        session['rooms_dict'] = roomDict

    roomDict = session['rooms_dict']
    rooms = list(roomDict.keys())

    participants = []
    for room in rooms[:6]:
        room_id = roomDict.get(room)
        participants.append(getMembers(room_id))

    return render_template("main.html", name = displayName, rooms = rooms[:6], members = participants)

# 'Authorised' page which redirects the user if the login was valid
@app.route('/oauth')
def oauth():
    code = request.args.get("code")

    data = getAccessToken(code)
    session['access_token'] = data['access_token']

    userDetails = getUserProfile()
    session['displayName'] = userDetails['displayName']

    return render_template("authorise.html")

# Redirect to authorisation URL (Cisco Spark login & Authorisation) using a 'GET' request
@app.route('/authorise', methods=['GET'])
def authorise():
    url = (
        "https://api.ciscospark.com/v1/authorize?"+
        "client_id=%s" %client_id+
        "&response_type=code"+
        "&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth"+
        "&scope=spark%3Aall%20spark-admin%3Aroles_read%20spark%3Akms%20spark-admin%3Aorganizations_read%20spark-admin%3Apeople_read"
    )
    return redirect(url, code=302)

@app.route('/')
def index():
    session.clear()
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080)<|endoftext|>