<commit_before>#!/usr/bin/python

import pywikibot
import re
from datetime import date
import datetime

########
# Changing this to 1 makes your changes live on the report page, do not set to
# live mode unless you have been approved for bot usage. Do not merge commits
# where this is not default to 0
########
live = 0
########

def monthConvert(name):
    '''
    Takes in either the name of the month or the number of the month and returns
    the opposite. An input of str(July) would return int(7) while an input of
    int(6) would return str(June).
    Takes:   int OR string
    Returns: string OR int
    '''
    if type(name) is str:
        if name == "January": return 1
        elif name == "February": return 2
        elif name == "March": return 3
        elif name == "April": return 4
        elif name == "May": return 5
        elif name == "June": return 6
        elif name == "July": return 7
        elif name == "August": return 8
        elif name == "September": return 9
        elif name == "October": return 10
        elif name == "November": return 11
        elif name == "December": return 12
        else: raise ValueError
    elif type(name) is int:
        if name == 1:return('January')
        elif name == 2:return('February')
        elif name == 3:return('March')
        elif name == 4:return('April')
        elif name == 5:return('May')
        elif name == 6:return('June')
        elif name == 7:return('July')
        elif name == 8:return('August')
        elif name == 9:return('September')
        elif name == 10:return('October')
        elif name == 11: return('November')
        elif name == 12: return('December')
        else: raise ValueError

def appendUpdates(toprint,updates,index=3):
    '''
    Takes an iterable array and the output array and returns teh output array
    appended with the marked up iterable array.
    '''
    for item in updates:
        text = '# [['+item[0]+"]] ('''"+str(item[index])+"''' days)\n"
        toprint.append(text)
    return(toprint)

def dateActions(nominList,index):
    '''
    For a given list, it finds the embedded date, how many days ago that date is
    from today, and appends that number to the list. It then returns the list
    '''
    for item in nominList:
        iMatch = datRegex.search(item[index])
        day = int(iMatch.group(1))
        month = monthConvert(str(iMatch.group(2)))
        year = int(iMatch.group(3))
        d0 = date(year, month, day)
        delta = today-d0
        item.append(delta.days)
        #print(delta.days,'days')
    return(nominList)

def sortByKey(nominList,index):
    '''
    Sorts a given list by a given index in a sublist, largest first
    '''
    nominList.sort(key=lambda x: x[index],reverse=True)
    return(nominList)

def wikiTimeStamp():
    '''
    Returns the current time stamp in the style of wikipedia signatures.
    '''
    stamp = str(datetime.datetime.utcnow().hour).zfill(2)+':'\
    +str(datetime.datetime.utcnow().minute).zfill(2)+', '\
    +str(datetime.datetime.utcnow().day)+' '\
    +monthConvert(datetime.datetime.utcnow().month)+' '\
    +str(datetime.datetime.utcnow().year)+' (UTC)'
    return(stamp)

#with open('/data/project/ganreportbot/pywikibot/limit.txt','r') as f:
#    counter = int(f.read().rstrip())
#if counter >= 7:
#    exit()

site = pywikibot.Site('en', 'wikipedia')
page = pywikibot.Page(site,'Wikipedia:Good article nominations')

#Compile regexes
##Finds GAN entries and returns time stamp, title, and the following line
entRegex = re.compile(
        r'\{\{GANentry.*?\|1\=(.*?)\|.*?(\d\d\:\d\d, \d+ .*? \d\d\d\d) \(UTC\)(?=\n(.*?)\n)'
    )
##Finds the Wikipedia UTC Timestamp
datRegex = re.compile(r', (\d+) (.*?) (\d\d\d\d)')

entry   = []
nomin   = []
onRev   = []
onHld   = []
waitg   = []
scnOp   = []
toPrint = []

# Find the Nomination entries and then sort them into on hold,
#     2nd opinion, or on revivew
#   DATA FORMAT
#       match[0] = Title of the nominated article
#       match[1] = Timestamp
#       match[2] = The line following
for match in entRegex.findall(page.text):
    entry.append([match[0],match[1],match[2]])
    if 'GAReview' in match[2]:
        if 'on hold' in match[2]:
            onHld.append([match[0],match[1],match[2]])
        elif '2nd opinion' in match[2]:
            scnOp.append([match[0],match[1],match[2]])
        else:
            onRev.append([match[0],match[1],match[2]])
    else:
        nomin.append([match[0],match[1]])

#Get the date
today = date.today()

#Get backlog stats
noms = len(entry)
inac = len(nomin)
ohld = len(onHld)
orev = len(onRev)
scnd = len(scnOp)

#Get all unreviewed nominations older than 30 days
oldestnoms = nomin
oldestnoms = dateActions(oldestnoms,1)
topTen = []
oldestnoms=sortByKey(oldestnoms,2)
while len(topTen) < 10:
    topTen.append(oldestnoms.pop(0))

#Get all nominations older than 30 days
entry = dateActions(entry,1)
oThirty=[]
for item in entry:
    if int(item[3]) >= 30:
        oThirty.append(item)
oThirty=sortByKey(oThirty,3)

#Get the nominations ON HOLD 7 days or longer
onHld=dateActions(onHld,2)
oldOnHold=[]
for item in onHld:
    if int(item[3]) >= 7:
        oldOnHold.append(item)
oldOnHold=sortByKey(oldOnHold,3)

#Get the nominations ON REVIEW for 7 days or longer
onRev=dateActions(onRev,2)
oldOnRev=[]
for item in onRev:
    if int(item[3]) >= 7:
        oldOnRev.append(item)
oldOnRev=sortByKey(oldOnRev,3)

#Get the nominations ON SECOND OPINION for 7 days or longer
scnOp=dateActions(scnOp,2)
oldScnOp=[]
for item in scnOp:
    if int(item[3]) >= 7:
        oldScnOp.append(item)
oldScnOp=sortByKey(oldScnOp,3)

page = pywikibot.Page(site,'Wikipedia:Good article nominations/Report')

#Make Backlog report
backlogReport = []
for match in re.findall(r'(\d.*?\/>)',page.text):
    backlogReport.append(match+'\n')
curEntry = wikiTimeStamp()+' – '+str(noms)+' nominations outstanding; ' \
    + str(inac)+' not reviewed; [[Image:Symbol wait.svg|15px|On Hold]] x ' \
    + str(ohld)+'; [[Image:Searchtool.svg|15px|Under Review]] x '+str(orev) \
    + '; [[Image:Symbol neutral vote.svg|15px|2nd Opinion Requested]] x ' \
    + str(scnd)+'
'
backlogReport.insert(0,curEntry)
oldLine=backlogReport.pop()

#Make the Page
report = ['{{/top}}\n\n',
          '== Oldest nominations ==\n',
          ":''List of the oldest ten nominations that have had no activity \
          (placed on hold, under review or requesting a 2nd opinion)''\n",
    ]
report = appendUpdates(report,topTen,index=2)
report+= ['\n',
          '== Backlog report ==\n',]

for item in backlogReport:
    report.append(item)

report+= [":''Previous daily backlogs can be viewed at the \
          [[/Backlog archive|backlog archive]].''\n\n",
          '== Exceptions report ==\n',
          '=== Holds over 7 days old ===\n']
report=appendUpdates(report,oldOnHold,index=3)
report+=[
        '\n',
        '=== Old reviews ===\n',
        ":''Nominations that have been marked under review for 7 days or "\
        +"longer.''\n"
    ]
report=appendUpdates(report,oldOnRev,3)
report+=[
    '\n',
    '=== Old requests for 2nd opinion ===\n',
    ":''Nominations that have been marked requesting a second opinion for 7 "\
    +"days or longer.''\n"
]
report=appendUpdates(report,oldScnOp,3)
report+=[
    '\n',
    '=== Old nominations ===\n',
    ":''All nominations that were added 30 days ago or longer, regardless of "\
    +"other activity.''\n"
]
for item in oThirty:
    if any(item[0] in i for i in onHld):
        text = '# [[Image:Symbol wait.svg|15px|On Hold]] [['+item[0]+"]] \
                ('''"+str(item[3])+"''' days)\n"
    elif any(item[0] in i for i in onRev):
        text = '# [[Image:Searchtool.svg|15px|Under Review]] [['+item[0]+"]] \
                ('''"+str(item[3])+"''' days)\n"
    elif any(item[0] in i for i in scnOp):
        text = '# [[Image:Symbol neutral vote.svg|15px|2nd Opinion Requested]] \
                [['+item[0]+"]] ('''"+str(item[3])+"''' days)\n"
    else:
        text = '# [['+item[0]+"]] ('''"+str(item[3])+"''' days)\n"
    report.append(text)

#Get unchanged portions of the page and organize the page
passed = 0
toPrint+=report
toPrint.append('\n')
x=page.text.split('\n')
for line in x:
    if 'The above sections updated at' in line:
        passed=1
        toPrint.append(line+'\n')
    elif passed==1:
        toPrint.append(line+'\n')
    else:
        continue

# Determine if the bot should write to a live page or the test page. Defaults to
#     test page. Value of -1 tests backlog update (not standard because the file
#     size is very big).
if live == 1:
    page.text=''.join(toPrint)
    page.save('Updating exceptions report')
    page = pywikibot.Page(site,'Wikipedia:Good article nominations/Report/Backlog archive')
    page.text+='
\n'
    page.text+=oldLine
    page.save('Update of GAN report backlog')
else:
    page = pywikibot.Page(site,'User:Wugapodes/GANReportBotTest')
    page.text=''.join(toPrint)
    page.save('Testing expanded reporting')
    if live==-1:
        page = pywikibot.Page(site,'User:Wugapodes/GANReportBotTest/Backlog archive')
        testText=page.text
        page.text=testText
        page.save('Testing backlog report updating')

print(wikiTimeStamp())

#with open('/data/project/ganreportbot/pywikibot/limit.txt','w') as f:
#    f.write(counter+1)
<commit_msg>now links to gan review or talk page instead of article<commit_after>#!/usr/bin/python

import pywikibot
import re
from datetime import date
import datetime

########
# Changing this to 1 makes your changes live on the report page, do not set to
# live mode unless you have been approved for bot usage. Do not merge commits
# where this is not default to 0
########
live = 0
########

def monthConvert(name):
    '''
    Takes in either the name of the month or the number of the month and returns
    the opposite. An input of str(July) would return int(7) while an input of
    int(6) would return str(June).
    Takes:   int OR string
    Returns: string OR int
    '''
    if type(name) is str:
        if name == "January": return 1
        elif name == "February": return 2
        elif name == "March": return 3
        elif name == "April": return 4
        elif name == "May": return 5
        elif name == "June": return 6
        elif name == "July": return 7
        elif name == "August": return 8
        elif name == "September": return 9
        elif name == "October": return 10
        elif name == "November": return 11
        elif name == "December": return 12
        else: raise ValueError
    elif type(name) is int:
        if name == 1:return('January')
        elif name == 2:return('February')
        elif name == 3:return('March')
        elif name == 4:return('April')
        elif name == 5:return('May')
        elif name == 6:return('June')
        elif name == 7:return('July')
        elif name == 8:return('August')
        elif name == 9:return('September')
        elif name == 10:return('October')
        elif name == 11: return('November')
        elif name == 12: return('December')
        else: raise ValueError

def appendUpdates(toprint,updates,index=3):
    '''
    Takes an iterable array and the output array and returns teh output array
    appended with the marked up iterable array.
    '''
    for item in updates:
        text = '# [['+item[0]+"]] ('''"+str(item[index])+"''' days)\n"
        toprint.append(text)
    return(toprint)

def dateActions(nominList,index):
    '''
    For a given list, it finds the embedded date, how many days ago that date is
    from today, and appends that number to the list. It then returns the list
    '''
    for item in nominList:
        iMatch = datRegex.search(item[index])
        day = int(iMatch.group(1))
        month = monthConvert(str(iMatch.group(2)))
        year = int(iMatch.group(3))
        d0 = date(year, month, day)
        delta = today-d0
        item.append(delta.days)
        #print(delta.days,'days')
    return(nominList)

def sortByKey(nominList,index):
    '''
    Sorts a given list by a given index in a sublist, largest first
    '''
    nominList.sort(key=lambda x: x[index],reverse=True)
    return(nominList)

def wikiTimeStamp():
    '''
    Returns the current time stamp in the style of wikipedia signatures.
    '''
    stamp = str(datetime.datetime.utcnow().hour).zfill(2)+':'\
    +str(datetime.datetime.utcnow().minute).zfill(2)+', '\
    +str(datetime.datetime.utcnow().day)+' '\
    +monthConvert(datetime.datetime.utcnow().month)+' '\
    +str(datetime.datetime.utcnow().year)+' (UTC)'
    return(stamp)

#with open('/data/project/ganreportbot/pywikibot/limit.txt','r') as f:
#    counter = int(f.read().rstrip())
#if counter >= 7:
#    exit()

site = pywikibot.Site('en', 'wikipedia')
page = pywikibot.Page(site,'Wikipedia:Good article nominations')

#Compile regexes
##Finds GAN entries and returns time stamp, title, and the following line
entRegex = re.compile(
        r'\{\{GANentry.*?\|1\=(.*?)\|2=(\d+).*?(\d\d\:\d\d, \d+ .*? \d\d\d\d) \(UTC\)(?=\n(.*?)\n)'
    )
##Finds the Wikipedia UTC Timestamp
datRegex = re.compile(r', (\d+) (.*?) (\d\d\d\d)')

entry   = []
nomin   = []
onRev   = []
onHld   = []
waitg   = []
scnOp   = []
toPrint = []
nomsBySection = {}

# Find the Nomination entries and then sort them into on hold,
#     2nd opinion, or on revivew
#   DATA FORMAT
#       match[0] = Title of the nominated article
#       match[1] = Nomination number
#       match[2] = Timestamp
#       match[3] = The line following
for match in entRegex.findall(page.text):
    entry.append([match[0],match[1],match[2],match[3]])
    if 'GAReview' in match[3]:
        if 'on hold' in match[3]:
            onHld.append([match[0],match[1],match[2],match[3]])
        elif '2nd opinion' in match[3]:
            scnOp.append([match[0],match[1],match[2],match[3]])
        else:
            onRev.append([match[0],match[1],match[2],match[3]])
    else:
        nomin.append([match[0],match[1],match[2]])

#Get the date
today = date.today()

#Get backlog stats
noms = len(entry)
inac = len(nomin)
ohld = len(onHld)
orev = len(onRev)
scnd = len(scnOp)

#Get all unreviewed nominations older than 30 days
oldestnoms = nomin
oldestnoms = dateActions(oldestnoms,2)
topTen = []
oldestnoms=sortByKey(oldestnoms,3)
while len(topTen) < 10:
    topTen.append(oldestnoms.pop(0))

#Get all nominations older than 30 days
entry = dateActions(entry,2)
oThirty=[]
for item in entry:
    if int(item[4]) >= 30:
        oThirty.append(item)
oThirty=sortByKey(oThirty,4)

#Get the nominations ON HOLD 7 days or longer
onHld=dateActions(onHld,3)
oldOnHold=[]
for item in onHld:
    if int(item[4]) >= 7:
        oldOnHold.append(item)
oldOnHold=sortByKey(oldOnHold,4)

#Get the nominations ON REVIEW for 7 days or longer
onRev=dateActions(onRev,3)
oldOnRev=[]
for item in onRev:
    if int(item[4]) >= 7:
        oldOnRev.append(item)
oldOnRev=sortByKey(oldOnRev,4)

#Get the nominations ON SECOND OPINION for 7 days or longer
scnOp=dateActions(scnOp,3)
oldScnOp=[]
for item in scnOp:
    if int(item[4]) >= 7:
        oldScnOp.append(item)
oldScnOp=sortByKey(oldScnOp,4)

page = pywikibot.Page(site,'Wikipedia:Good article nominations/Report')

#Make Backlog report
backlogReport = []
for match in re.findall(r'(\d.*?\/>)',page.text):
    backlogReport.append(match+'\n')
curEntry = wikiTimeStamp()+' – '+str(noms)+' nominations outstanding; ' \
    + str(inac)+' not reviewed; [[Image:Symbol wait.svg|15px|On Hold]] x ' \
    + str(ohld)+'; [[Image:Searchtool.svg|15px|Under Review]] x '+str(orev) \
    + '; [[Image:Symbol neutral vote.svg|15px|2nd Opinion Requested]] x ' \
    + str(scnd)+'
'
backlogReport.insert(0,curEntry)
oldLine=backlogReport.pop()

#Make the Page
report = ['{{/top}}\n\n',
          '== Oldest nominations ==\n',
          ":''List of the oldest ten nominations that have had no activity" \
          +"(placed on hold, under review or requesting a 2nd opinion)''\n",
    ]
report = appendUpdates(report,topTen,index=3,rev=False)
report+= ['\n',
          '== Backlog report ==\n',]

for item in backlogReport:
    report.append(item)

report+= [":''Previous daily backlogs can be viewed at the \
          [[/Backlog archive|backlog archive]].''\n\n",
          '== Exceptions report ==\n',
          '=== Holds over 7 days old ===\n']
report=appendUpdates(report,oldOnHold,index=4)
report+=[
        '\n',
        '=== Old reviews ===\n',
        ":''Nominations that have been marked under review for 7 days or "\
        +"longer.''\n"
    ]
report=appendUpdates(report,oldOnRev,4)
report+=[
    '\n',
    '=== Old requests for 2nd opinion ===\n',
    ":''Nominations that have been marked requesting a second opinion for 7 "\
    +"days or longer.''\n"
]
report=appendUpdates(report,oldScnOp,4)
report+=[
    '\n',
    '=== Old nominations ===\n',
    ":''All nominations that were added 30 days ago or longer, regardless of "\
    +"other activity.''\n"
]
for item in oThirty:
    if any(item[0] in i for i in onHld):
        text = '# [[Image:Symbol wait.svg|15px|On Hold]] [[Talk:'+item[0]+"/GA"\
               +str(item[1])+"]] ('''"+str(item[4])+"''' days)\n"
    elif any(item[0] in i for i in onRev):
        text = '# [[Image:Searchtool.svg|15px|Under Review]] [[Talk:'+item[0]\
               +"/GA"+str(item[1])+"]] ('''"+str(item[4])+"''' days)\n"
    elif any(item[0] in i for i in scnOp):
        text = '# [[Image:Symbol neutral vote.svg|15px|2nd Opinion Requested]]'\
                +'[[Talk:'+item[0]+"/GA"+str(item[1])+"]] ('''"+str(item[4])\
                +"''' days)\n"
    else:
        text = '# [[Talk:'+item[0]+"]] ('''"+str(item[4])+"''' days)\n"
    report.append(text)

#Get unchanged portions of the page and organize the page
passed = 0
toPrint+=report
toPrint.append('\n')
x=page.text.split('\n')
for line in x:
    if 'The above sections updated at' in line:
        passed=1
    elif passed==1:
        toPrint.append(line+'\n')
    else:
        continue

# Determine if the bot should write to a live page or the test page. Defaults to
#     test page. Value of -1 tests backlog update (not standard because the file
#     size is very big).
if live == 1:
    page.text=''.join(toPrint)
    page.save('Updating exceptions report')
    page = pywikibot.Page(site,'Wikipedia:Good article nominations/Report/Backlog archive')
    page.text+='
\n'
    page.text+=oldLine
    page.save('Update of GAN report backlog')
else:
    page = pywikibot.Page(site,'User:Wugapodes/GANReportBotTest')
    page.text=''.join(toPrint)
    page.save('Testing expanded reporting')
    if live==-1:
        page = pywikibot.Page(site,'User:Wugapodes/GANReportBotTest/Backlog archive')
        testText=page.text
        page.text=testText
        page.save('Testing backlog report updating')

print(wikiTimeStamp())

#with open('/data/project/ganreportbot/pywikibot/limit.txt','w') as f:
#    f.write(counter+1)
<|endoftext|>


<commit_before>##############################################################################
#
#    Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Emmanuel Girardin <emmanuel.girardin@outlook.com>
#
#    The licence is in the file __manifest__.py
#
##############################################################################

""" This wrapper allows to scan QRCodes thanks to the ZBar library. When no
ZBar is detected, it apply a few filter on the input image and try the
scanning again. This technique reduces the number of false negative."""
import logging
from PIL import Image

_logger = logging.getLogger(__name__)
try:
    from pyzbar import pyzbar
    import cv2  # we use openCV to repair broken QRCodes.
    import fitz
except ImportError:
    _logger.warning("SBC module needs pyzbar, cv2 and PyMuPDF to work.")

def scan_qrcode(filename, page):
    qrdata = None
    result = _decode(filename, page)
    # map the resulting object to a dictionary compatible with our software
    if result:
        qrdata = {}
        qrdata["data"] = result.data
        qrdata["format"] = result.type
        qrdata["raw"] = result.data
    return qrdata

def _scan(img):
    # convert cv image to raw data
    pil = Image.fromarray(img)
    # extract results
    qrcode = None
    for symbol in pyzbar.decode(pil):
        qrcode = symbol
    return qrcode

def _decode(filename, page):
    # obtain image data
    img = cv2.imread(filename, 0)
    try:
        im = cv2.resize(img, None, fx=0.5, fy=0.5)
    except cv2.error:
        im = img
        _logger.warning("Error resizing image for QRcode detection.")

    if not im:
        return ""
    qrcode = _scan(im)
    if not qrcode:
        zoom_x = 10.0  # horizontal zoom
        zomm_y = 10.0  # vertical zoom
        mat = fitz.Matrix(zoom_x, zomm_y)  # zoom factor 2 in each dimension
        # use 'mat' instead of the identity matrix
        pix = page.getPixmap(matrix=mat, alpha=0)
        pix.writePNG("page%i.png" % page.number)  # store image as a PNG
        # No QR found, so we try to again after an opening operation
        img = cv2.imread(filename, 0)
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
        imgage = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel)
        qrcode = _scan(imgage)
        zoom_factors = [0.4, 0.3, 0.2, 0.6, 0.7, 0.8, 0.9, 1.0]
        tries = 0
        while not qrcode and tries < len(zoom_factors):
            # No QR found, so we try to again after an opening operation
            try:
                im = cv2.resize(img, None, fx=zoom_factors[tries],
                                fy=zoom_factors[tries])
                imgage = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel)
                qrcode = _scan(imgage)
            except cv2.error:
                _logger.warning("Error resizing image for QRcode detection.")
            tries += 1
    return qrcode
<commit_msg>Catch more possible errors during letter import<commit_after>##############################################################################
#
#    Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Emmanuel Girardin <emmanuel.girardin@outlook.com>
#
#    The licence is in the file __manifest__.py
#
##############################################################################

""" This wrapper allows to scan QRCodes thanks to the ZBar library. When no
ZBar is detected, it apply a few filter on the input image and try the
scanning again. This technique reduces the number of false negative."""
import logging
from PIL import Image

_logger = logging.getLogger(__name__)
try:
    from pyzbar import pyzbar
    import cv2  # we use openCV to repair broken QRCodes.
    import fitz
except ImportError:
    _logger.warning("SBC module needs pyzbar, cv2 and PyMuPDF to work.")

def scan_qrcode(filename, page):
    qrdata = None
    result = _decode(filename, page)
    # map the resulting object to a dictionary compatible with our software
    if result:
        qrdata = {}
        qrdata["data"] = result.data
        qrdata["format"] = result.type
        qrdata["raw"] = result.data
    return qrdata

def _scan(img):
    # convert cv image to raw data
    pil = Image.fromarray(img)
    # extract results
    qrcode = None
    for symbol in pyzbar.decode(pil):
        qrcode = symbol
    return qrcode

def _decode(filename, page):
    # obtain image data
    img = cv2.imread(filename, 0)
    try:
        im = cv2.resize(img, None, fx=0.5, fy=0.5)
    except cv2.error:
        im = img
        _logger.warning("Error resizing image for QRcode detection.")

    if im is None:
        return ""
    qrcode = _scan(im)
    if not qrcode:
        zoom_x = 10.0  # horizontal zoom
        zomm_y = 10.0  # vertical zoom
        mat = fitz.Matrix(zoom_x, zomm_y)  # zoom factor 2 in each dimension
        # use 'mat' instead of the identity matrix
        pix = page.getPixmap(matrix=mat, alpha=0)
        pix.writePNG("page%i.png" % page.number)  # store image as a PNG
        # No QR found, so we try to again after an opening operation
        img = cv2.imread(filename, 0)
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
        imgage = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel)
        qrcode = _scan(imgage)
        zoom_factors = [0.4, 0.3, 0.2, 0.6, 0.7, 0.8, 0.9, 1.0]
        tries = 0
        while not qrcode and tries < len(zoom_factors):
            # No QR found, so we try to again after an opening operation
            try:
                im = cv2.resize(img, None, fx=zoom_factors[tries],
                                fy=zoom_factors[tries])
                imgage = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel)
                qrcode = _scan(imgage)
            except cv2.error:
                _logger.warning("Error resizing image for QRcode detection.")
            tries += 1
    return qrcode
<|endoftext|>


<commit_before># import sqlalchemy as sa
from sqlalchemy import Column, update, Index, Integer, Boolean, UnicodeText, func, DateTime, Float, or_, and_
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from zope.sqlalchemy import ZopeTransactionExtension
import transaction
from datetime import datetime

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class PathAndRow_Model(Base):
    '''Model for path and row table.'''
    __tablename__ = 'paths'

    gid = Column(UnicodeText, primary_key=True, autoincrement=True)
    geom = Column(UnicodeText, nullable=False)
    path = Column(Integer, nullable=False)
    row = Column(Integer, nullable=False)
    mode = Column(UnicodeText, nullable=False)

    @classmethod
    def pathandrow(cls, lat, lon):
        """Output path and row that contains lat lon."""
        try:
            scene = (DBSession.query(cls)
                    .filter(func.ST_Within(func.ST_SetSRID(func
                            .ST_MakePoint(lon, lat), 4236), func
                        .ST_SetSRID(cls.geom, 4236)), cls.mode == u'D').all()
                    )
            return scene
        except:
            return u'----'

class SceneList_Model(Base):
    '''Model for AWS S3 scene list.'''
    __tablename__ = 'path_row'
    entityid = Column(UnicodeText, primary_key=True)
    acquisitiondate = Column(DateTime, nullable=False)
    cloudcover = Column(Float, nullable=False)
    path = Column(Integer, nullable=False)
    row = Column(Integer, nullable=False)
    download_url = Column(UnicodeText, nullable=False)

    @classmethod
    def scenelist(cls, pr_output):
        '''For Constantine'''
        new = []
        for x in pr_output:
            new.append(and_(cls.row == x.row, cls.path == x.path))
        return DBSession.query(cls).filter(or_(*new))

class UserJob_Model(Base):
    '''Model for the user job queue. Possible job statuses:
    0 - Created
    1 - Queued
    2 - Processing
    3 - Done (Failed)
    4 - Done (Success)
    '''

    __tablename__ = 'user_job'
    jobid = Column(Integer, primary_key=True)
    entityid = Column(UnicodeText)
    userip = Column(UnicodeText)
    email = Column(UnicodeText)
    band1 = Column(Integer)
    band2 = Column(Integer)
    band3 = Column(Integer)
    jobstatus = Column(Integer, nullable=False)
    starttime = Column(DateTime, nullable=False)
    lastmodified = Column(DateTime, nullable=False)
    status1time = Column(DateTime)
    status2time = Column(DateTime)
    status3time = Column(DateTime)
    status4time = Column(DateTime)
    status5time = Column(DateTime)
    status10time = Column(DateTime)

    @classmethod
    def new_job(cls,
                entityid=entityid,
                band1=4,
                band2=3,
                band3=2,
                jobstatus=0,
                starttime=datetime.utcnow(),
                ):
        '''Create new job in db.'''
        try:
            session = DBSession
            current_time = datetime.utcnow()
            job = UserJob_Model(entityid=entityid,
                                band1=band1,
                                band2=band2,
                                band3=band3,
                                jobstatus=0,
                                starttime=current_time,
                                lastmodified=current_time
                                )
            session.add(job)
            session.flush()
            session.refresh(job)
            pk = job.jobid
            transaction.commit()
        except:
            return None
        try:
            Rendered_Model.add(pk, True)
        except:
            print 'Could not add job to rendered db'
        return pk

    @classmethod
    def set_job_status(cls, jobid, status, url=None):
        '''Set jobstatus for jobid passed in.'''
        table_key = {1: "status1time",
                     2: "status2time",
                     3: "status3time",
                     4: "status4time",
                     5: "status5time",
                     10: "status10time"}
        try:
            current_time = datetime.utcnow()
            DBSession.query(cls).filter(cls.jobid == jobid).update(
                                    {"jobstatus": status,
                                     table_key[int(status)]: current_time,
                                     "lastmodified": current_time
                                     })
        except:
            print 'database write failed'
        # Tell render_cache db we have this image now
        if int(status) == 5:
            try:
                Rendered_Model.update(jobid, False, url)
            except:
                print 'Could not update Rendered db'

    @classmethod
    def job_status(cls, jobid):
        '''Get jobstatus for jobid passed in.'''
        status_key = {0: "In queue",
                      1: "Downloading",
                      2: "Processing",
                      3: "Compressing",
                      4: "Uploading to server",
                      5: "Done",
                      10: "Failed"}
        try:
            job = DBSession.query(cls).get(jobid)
            print job.jobstatus
        except:
            print 'database write failed'
            return None
        return status_key[job.jobstatus]

    @classmethod
    def job_times(cls, jobid):
        '''Get times for jobid passed in.'''
        try:
            job = DBSession.query(cls).get(jobid)
            return job.starttime, job.lastmodified
        except:
            print 'database operation failed'

class Rendered_Model(Base):
    '''Model for the already rendered files'''
    __tablename__ = 'render_cache'
    id = Column(Integer, primary_key=True)
    jobid = Column(Integer)
    entityid = Column(UnicodeText)
    band1 = Column(Integer)
    band2 = Column(Integer)
    band3 = Column(Integer)
    previewurl = Column(UnicodeText)
    renderurl = Column(UnicodeText)
    rendercount = Column(Integer, default=0)
    currentlyrend = Column(Boolean)

    @classmethod
    def add(cls, jobid, currentlyrend):
        '''Method adds entry into db given jobid and optional url.'''
        jobQuery = DBSession.query(UserJob_Model).get(jobid)
        job = Rendered_Model(entityid=jobQuery.entityid,
                             jobid=jobid,
                             band1=jobQuery.band1,
                             band2=jobQuery.band2,
                             band3=jobQuery.band3,
                             currentlyrend=currentlyrend)
        DBSession.add(job)
        transaction.commit()

    @classmethod
    def update(cls, jobid, currentlyrend, renderurl):
        '''Method updates entry into db given jobid and optional url.'''
        try:
            DBSession.query(cls).filter(cls.jobid == jobid).update({
                "currentlyrend": currentlyrend, "renderurl": renderurl})
        except:
            print 'could not update db'

    @classmethod
    def available(cls, entityid):
        '''Return list of existing jobs for a given sceneID.'''
        try:
            rendered = DBSession.query(cls).filter(cls.entityid == entityid).all()
        except:
            print 'Database query failed'
            return None
        return rendered

    @classmethod
    def already_available(cls, entityid, band1, band2, band3):
        '''Check if given image is already rendered'''
        try:
            output = DBSession.query(cls).filter(cls.entityid == entityid,
                                                 cls.band1 == band1,
                                                 cls.band2 == band2,
                                                 cls.band3 == band3,
                                                 cls.renderurl.isnot(None)).count()
        except:
            print 'Database query failed'
            return None
        if output != 0:
            # if this scene/band has already been requested, increase the count
            existing = DBSession.query(cls).filter(cls.entityid == entityid,
                                                   cls.band1 == band1,
                                                   cls.band2 == band2,
                                                   cls.band3 == band3).update({
                                                   "rendercount": cls.rendercount+1})
        return output != 0
<commit_msg>commit to update status method<commit_after># import sqlalchemy as sa
from sqlalchemy import Column, update, Index, Integer, Boolean, UnicodeText, func, DateTime, Float, or_, and_
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from zope.sqlalchemy import ZopeTransactionExtension
import transaction
from datetime import datetime

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class PathAndRow_Model(Base):
    '''Model for path and row table.'''
    __tablename__ = 'paths'

    gid = Column(UnicodeText, primary_key=True, autoincrement=True)
    geom = Column(UnicodeText, nullable=False)
    path = Column(Integer, nullable=False)
    row = Column(Integer, nullable=False)
    mode = Column(UnicodeText, nullable=False)

    @classmethod
    def pathandrow(cls, lat, lon):
        """Output path and row that contains lat lon."""
        try:
            scene = (DBSession.query(cls)
                    .filter(func.ST_Within(func.ST_SetSRID(func
                            .ST_MakePoint(lon, lat), 4236), func
                        .ST_SetSRID(cls.geom, 4236)), cls.mode == u'D').all()
                    )
            return scene
        except:
            return u'----'

class SceneList_Model(Base):
    '''Model for AWS S3 scene list.'''
    __tablename__ = 'path_row'
    entityid = Column(UnicodeText, primary_key=True)
    acquisitiondate = Column(DateTime, nullable=False)
    cloudcover = Column(Float, nullable=False)
    path = Column(Integer, nullable=False)
    row = Column(Integer, nullable=False)
    download_url = Column(UnicodeText, nullable=False)

    @classmethod
    def scenelist(cls, pr_output):
        '''For Constantine'''
        new = []
        for x in pr_output:
            new.append(and_(cls.row == x.row, cls.path == x.path))
        return DBSession.query(cls).filter(or_(*new))

class UserJob_Model(Base):
    '''Model for the user job queue. Possible job statuses:
    0 - Created
    1 - Queued
    2 - Processing
    3 - Done (Failed)
    4 - Done (Success)
    '''

    __tablename__ = 'user_job'
    jobid = Column(Integer, primary_key=True)
    entityid = Column(UnicodeText)
    userip = Column(UnicodeText)
    email = Column(UnicodeText)
    band1 = Column(Integer)
    band2 = Column(Integer)
    band3 = Column(Integer)
    jobstatus = Column(Integer, nullable=False)
    starttime = Column(DateTime, nullable=False)
    lastmodified = Column(DateTime, nullable=False)
    status1time = Column(DateTime)
    status2time = Column(DateTime)
    status3time = Column(DateTime)
    status4time = Column(DateTime)
    status5time = Column(DateTime)
    status10time = Column(DateTime)

    @classmethod
    def new_job(cls,
                entityid=entityid,
                band1=4,
                band2=3,
                band3=2,
                jobstatus=0,
                starttime=datetime.utcnow(),
                ):
        '''Create new job in db.'''
        try:
            session = DBSession
            current_time = datetime.utcnow()
            job = UserJob_Model(entityid=entityid,
                                band1=band1,
                                band2=band2,
                                band3=band3,
                                jobstatus=0,
                                starttime=current_time,
                                lastmodified=current_time
                                )
            session.add(job)
            session.flush()
            session.refresh(job)
            pk = job.jobid
            transaction.commit()
        except:
            return None
        try:
            Rendered_Model.add(pk, True)
        except:
            print 'Could not add job to rendered db'
        return pk

    @classmethod
    def set_job_status(cls, jobid, status, url=None):
        '''Set jobstatus for jobid passed in.'''
        table_key = {1: "status1time",
                     2: "status2time",
                     3: "status3time",
                     4: "status4time",
                     5: "status5time",
                     10: "status10time"}
        try:
            current_time = datetime.utcnow()
            DBSession.query(cls).filter(cls.jobid == jobid).update(
                                    {"jobstatus": status,
                                     table_key[int(status)]: current_time,
                                     "lastmodified": current_time
                                     })
            transaction.commit()
        except:
            print 'database write failed'
        # Tell render_cache db we have this image now
        if int(status) == 5:
            try:
                Rendered_Model.update(jobid, False, url)
            except:
                print 'Could not update Rendered db'

    @classmethod
    def job_status(cls, jobid):
        '''Get jobstatus for jobid passed in.'''
        status_key = {0: "In queue",
                      1: "Downloading",
                      2: "Processing",
                      3: "Compressing",
                      4: "Uploading to server",
                      5: "Done",
                      10: "Failed"}
        try:
            job = DBSession.query(cls).get(jobid)
            print job.jobstatus
        except:
            print 'database write failed'
            return None
        return status_key[job.jobstatus]

    @classmethod
    def job_times(cls, jobid):
        '''Get times for jobid passed in.'''
        try:
            job = DBSession.query(cls).get(jobid)
            return job.starttime, job.lastmodified
        except:
            print 'database operation failed'

class Rendered_Model(Base):
    '''Model for the already rendered files'''
    __tablename__ = 'render_cache'
    id = Column(Integer, primary_key=True)
    jobid = Column(Integer)
    entityid = Column(UnicodeText)
    band1 = Column(Integer)
    band2 = Column(Integer)
    band3 = Column(Integer)
    previewurl = Column(UnicodeText)
    renderurl = Column(UnicodeText)
    rendercount = Column(Integer, default=0)
    currentlyrend = Column(Boolean)

    @classmethod
    def add(cls, jobid, currentlyrend):
        '''Method adds entry into db given jobid and optional url.'''
        jobQuery = DBSession.query(UserJob_Model).get(jobid)
        job = Rendered_Model(entityid=jobQuery.entityid,
                             jobid=jobid,
                             band1=jobQuery.band1,
                             band2=jobQuery.band2,
                             band3=jobQuery.band3,
                             currentlyrend=currentlyrend)
        DBSession.add(job)
        transaction.commit()

    @classmethod
    def update(cls, jobid, currentlyrend, renderurl):
        '''Method updates entry into db given jobid and optional url.'''
        try:
            DBSession.query(cls).filter(cls.jobid == jobid).update({
                "currentlyrend": currentlyrend, "renderurl": renderurl})
        except:
            print 'could not update db'

    @classmethod
    def available(cls, entityid):
        '''Return list of existing jobs for a given sceneID.'''
        try:
            rendered = DBSession.query(cls).filter(cls.entityid == entityid).all()
        except:
            print 'Database query failed'
            return None
        return rendered

    @classmethod
    def already_available(cls, entityid, band1, band2, band3):
        '''Check if given image is already rendered'''
        try:
            output = DBSession.query(cls).filter(cls.entityid == entityid,
                                                 cls.band1 == band1,
                                                 cls.band2 == band2,
                                                 cls.band3 == band3,
                                                 cls.renderurl.isnot(None)).count()
        except:
            print 'Database query failed'
            return None
        if output != 0:
            # if this scene/band has already been requested, increase the count
            existing = DBSession.query(cls).filter(cls.entityid == entityid,
                                                   cls.band1 == band1,
                                                   cls.band2 == band2,
                                                   cls.band3 == band3).update({
                                                   "rendercount": cls.rendercount+1})
        return output != 0
<|endoftext|>


<commit_before>import os
import sys

(dir, filename) = os.path.split(os.path.abspath(sys.argv[0]))
print(dir)
filenames = os.listdir(dir)
for file in filenames:
    print(file)

print('*****************************************************')
updir = os.path.abspath('..')
print(updir)
filenames = os.listdir(updir)
for file in filenames:
    print(file)

print('*****************************************************')
os.chdir(updir)
upupdir = os.path.abspath('..')
print(upupdir)
filenames = os.listdir(upupdir)
for file in filenames:
    print(file)

print('*****************************************************')
os.chdir(upupdir)
upupupdir = os.path.abspath('..')
print(upupupdir)
filenames = os.listdir(upupupdir)
for file in filenames:
    print(file)<commit_msg>Add a level of uper directory<commit_after>import os
import sys

(dir, filename) = os.path.split(os.path.abspath(sys.argv[0]))
print(dir)
filenames = os.listdir(dir)
for file in filenames:
    print(file)

print()
print()
print()
print('*****************************************************')
updir = os.path.abspath('..')
print(updir)
filenames = os.listdir(updir)
for file in filenames:
    print(file)

print()
print()
print()
print('*****************************************************')
os.chdir(updir)
upupdir = os.path.abspath('..')
print(upupdir)
filenames = os.listdir(upupdir)
for file in filenames:
    print(file)

print()
print()
print()
print('*****************************************************')
os.chdir(upupdir)
upupupdir = os.path.abspath('..')
print(upupupdir)
filenames = os.listdir(upupupdir)
for file in filenames:
    print(file)

print()
print()
print()
print('*****************************************************')
os.chdir(upupupdir)
upupupupdir = os.path.abspath('..')
print(upupupupdir)
filenames = os.listdir(upupupupdir)
for file in filenames:
    print(file)<|endoftext|>


<commit_before>#!/usr/bin/env python
"""Defines the main menu module for a program that inputs a MemberHub directory dump,
a school roster, and a hub map to perform analyses on the MemberHub directory.
"""

import directory_tools
import roster_tools
import hub_map_tools
import import_file_tools
import family
import person

### TBD - Need to confirm Student Indicator with Loren
constant STUDENT_INDICATOR = "SA"

def FindMissingEmail(directory):
    """menu.FindMissingEmail
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have an
    email address associated with their entry.
    ASSUMPTIONS:
    None.
    """
    adult_count = no_email_count = 0
    for entry_family in directory:
        for adult in entry_family.adults:
            adult_count += 1
            if adult.DoesNotListEmailAddress():
                print "The entry for this person does not have an email address:",
                adult.Print()
                no_email_count += 1

    print "Found %d out of %d adults with missing email addresses" % \
          (no_email_count, adult_count)

def FindOrphans(directory):
    """menu.FindOrphans
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the children in the directory who do not have an
    parent associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = orphan_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsOrphan():
            print "The entry for this family does not identify parents:",
            entry_family.Print()
            orphan_count += 1

    print "Found %d families without adults out of %d families" % \
          (orphan_count, family_count)

def FindChildless(directory):
    """menu.FindChildless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have a
    child associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = childless_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsChildless():
            print "The entry for this family does not identify children:",
            entry_family.Print()
            childless_count += 1

    print "Found %d families without children out of %d families" % \
          (childless_count, family_count)

def FindHubless(arg_list):
    """menu.FindHubless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    map_d     = arg_list[1]
    hubless   = []

    child_count = adult_count = 0

    for directory_family in directory:
        for adult in directory_family.adults:
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, adult.hubs):
                print "Found adult not in a classroom hub.  Current hubs = (%s).  Name = " % adult.hubs,
                adult.Print()
                adult_count += 1
                hubless.append(adult)

        for child in directory_family.children:
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, child.hubs):
                print "Found child not in a classroom hub.  Current hubs =  (%s).  Name = " % child.hubs,
                child.Print()
                child_count += 1
                hubless.append(child)

    print "Found %d children who are not in a classroom hub." % child_count
    print "Found %d adults who are not in at least one classroom hub." % adult_count

    return hubless

def PrintHubless(arg_list):
    discard = FindHubless(arg_list)

def MakeImportForHubless(arg_list):
    """menu.MakeImportForHubless
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    Creates a comma-separated text file that can be imported into MemberHub to assign
    hub IDs to existing directory entries.
    ASSUMPTIONS:
    None.
    """
    directory   = arg_list[0]
    map_d       = arg_list[1]
    roster      = arg_list[2]
    hubless     = FindHubless(arg_list)
    update_hubs = []

    hubed_count = hubless_count = 0

    for hubless_person in hubless:
        for roster_family in roster:
            found_person = roster_family.FindPersonInFamily(hubless_person)
            if not found_person == None:
                hubless_person.hubs = found_person.hubs
                update_hubs.append(hubless_person)
                hubed_count += 1
                break
        else:
            print "Did not find match for this person in the roster:",
            hubless_person.Print()
            hubless_count += 1

    print "Processed %d entries that were not in any classroom hub." % len(hubless)
    print "Was able to find classroom hubs for %d entries." % hubed_count
    print "Was not able to find classroom hubs for %d entries." % hubless_count

    import_file_tools.CreateHublessImportFile(update_hubs)

def FindEntriless(arg_list):
    """menu.FindEntriless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - roster    -- list containing the school roster families
    OUTPUTS:
    - entriless -- returns list of families in the school roster that could not
                   be found in the directory
    Also prints to standard output the names in the school roster who are not in the
    MemberHub directory.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    entriless = []

    for roster_family in roster:

        for directory_family in directory:
            if directory_family.IsSameFamily(roster_family):
                if directory_family.HasNewChildren(roster_family):
                    temp_family = family.Family()
                    temp_family.FormFamilyWithNewChildren(directory_family,roster_family)
                    print "Found family in directory with new child in roster:",
                    temp_family.Print()
                    entriless.append(temp_family)
                break

        else:
            print "Did not find this family from the roster in the directory:",
            roster_family.Print()
            entriless.append(roster_family)

    print "Found %d people on the roster who were not in the directory" % len(entriless)
    return entriless

def PrintNotInDirectory(arg_list):
    discard = FindEntriless(arg_list)

def MakeImportNotInDirectory(arg_list):
    """menu.MakeImportNotInDirectory
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    map_d     = arg_list[2]
    entriless = FindEntriless(arg_list)

    import_file_tools.CreateNewMemberImport(entriless)

def MakeStudentImportFile(arg_list):
    """menu.MakeStudentImportFile
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    students  = []

    ## For each family in the roster ...
    for roster_family in roster:
        ## ...find the corresponding family in the directory
        for directory_family in directory:
            if directory_family.IsSameFamily(roster_family):
                ## For each child in the roster family...
                for roster_child in roster_family.children:
                    ## ...find the corresponding child in the directory family
                    for directory_child in directory_family.children:
                        if directory_child.IsSame(roster_child):
                            ## instantiate a new Directory Person object, and copy the directory child into it
                            temp_child = person.DirectoryPerson()
                            temp_child = directory_child
                            ## clear the temporary object's hubs
                            temp_child.hubs = []
                            ## populate the temporary object's hubs with the roster child's hubs
                            ## modified with the student indicator appended
                            for hub in roster_child.hubs:
                                ## TBD - is student_hub a necessary step?
                                student_hub = hub + STUDENT_INDICATOR
                                temp_child.hubs.append(student_hub)
                            ## add the temporary child object to the list of students
                            students.append(temp_child)
                    else:
                        print "Did not find this child in the family:  ",
                        roster_child.Print()
                ## Found the roster family in the directory, so break out of the directory_family loop
                break
        else:
            print "Did not find this family from the roster in the directory:",
            roster_family.Print()

    print "Found %d students on the roster who were in the directory" % len(students)

    ## Create an import file with all the students
    import_file_tools.CreateHublessImportFile(students)

def MakePrompt(choices):
    choice_list = sorted(choices)
    guts = '\n'.join(['(%s)%s' % (choice[0], choice[1:])
                      for choice in choice_list])
    return 'Choose:\n' + guts + '\nOr press <enter> to quit '

def RunMenu(directory, roster, map_d):
    """Runs the user interface for dictionary manipulation."""
    # The choices dictionary has function names for values.
    choices = {'1 - Find Missing Email':
                    {'Function':FindMissingEmail,'Arg':directory},
               '2 - Find Orphans':
                    {'Function':FindOrphans,'Arg':directory},
               '3 - Find Childless':
                    {'Function':FindChildless,'Arg':directory},
               '4 - Find Not In Classroom Hub':
                    {'Function':PrintHubless,'Arg':[directory,map_d]},
               '5 - Make Import File for Not In Classroom Hub':
                    {'Function':MakeImportForHubless,'Arg':[directory,map_d,roster]},
               '6 - Find Not in Directory':
                    {'Function':PrintNotInDirectory,'Arg':[directory,roster]},
               '7 - Make Import File for Not In Directory':
                    {'Function':MakeImportNotInDirectory,'Arg':[directory,roster,map_d]},
               '8 - Make Student Hub Population Import File':
                    {'Function':MakeStudentImportFile,'Arg':[directory,roster]}}

    prompt = MakePrompt(choices)

    while True:
        raw_choice = raw_input(prompt)
        if not raw_choice:
            break
        given_choice = raw_choice[0].lower()
        for maybe_choice in choices:
            if maybe_choice[0] == given_choice:
                # The appropriate function is called
                # using the dictionary value for the name
                # of the function.
                choices[maybe_choice]['Function'](choices[maybe_choice]['Arg'])
                break
        else:
            print '%s is not an acceptible choice.' % raw_choice

def main():
    directory = directory_tools.ReadDirectory()
    roster    = roster_tools.ReadRoster()
    map_d     = hub_map_tools.ReadMap()
    RunMenu(directory, roster, map_d)

if __name__ == '__main__':
    main()
<commit_msg>Corrected logic in MakeStudentImportFile<commit_after>#!/usr/bin/env python
"""Defines the main menu module for a program that inputs a MemberHub directory dump,
a school roster, and a hub map to perform analyses on the MemberHub directory.
"""

import directory_tools
import roster_tools
import hub_map_tools
import import_file_tools
import family
import person

### TBD - Need to confirm Student Indicator with Loren
constant STUDENT_INDICATOR = "SA"

def FindMissingEmail(directory):
    """menu.FindMissingEmail
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have an
    email address associated with their entry.
    ASSUMPTIONS:
    None.
    """
    adult_count = no_email_count = 0
    for entry_family in directory:
        for adult in entry_family.adults:
            adult_count += 1
            if adult.DoesNotListEmailAddress():
                print "The entry for this person does not have an email address:",
                adult.Print()
                no_email_count += 1

    print "Found %d out of %d adults with missing email addresses" % \
          (no_email_count, adult_count)

def FindOrphans(directory):
    """menu.FindOrphans
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the children in the directory who do not have an
    parent associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = orphan_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsOrphan():
            print "The entry for this family does not identify parents:",
            entry_family.Print()
            orphan_count += 1

    print "Found %d families without adults out of %d families" % \
          (orphan_count, family_count)

def FindChildless(directory):
    """menu.FindChildless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    OUTPUTS:
    Prints to standard output the adults in the directory who do not have a
    child associated with their entry.
    ASSUMPTIONS:
    None.
    """
    family_count = childless_count = 0

    for entry_family in directory:
        family_count += 1
        if entry_family.IsChildless():
            print "The entry for this family does not identify children:",
            entry_family.Print()
            childless_count += 1

    print "Found %d families without children out of %d families" % \
          (childless_count, family_count)

def FindHubless(arg_list):
    """menu.FindHubless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    map_d     = arg_list[1]
    hubless   = []

    child_count = adult_count = 0

    for directory_family in directory:
        for adult in directory_family.adults:
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, adult.hubs):
                print "Found adult not in a classroom hub.  Current hubs = (%s).  Name = " % adult.hubs,
                adult.Print()
                adult_count += 1
                hubless.append(adult)

        for child in directory_family.children:
            if not hub_map_tools.IsAnyHubClassroomHub(map_d, child.hubs):
                print "Found child not in a classroom hub.  Current hubs =  (%s).  Name = " % child.hubs,
                child.Print()
                child_count += 1
                hubless.append(child)

    print "Found %d children who are not in a classroom hub." % child_count
    print "Found %d adults who are not in at least one classroom hub." % adult_count

    return hubless

def PrintHubless(arg_list):
    discard = FindHubless(arg_list)

def MakeImportForHubless(arg_list):
    """menu.MakeImportForHubless
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Prints to standard output the names in the directory who are not members of
    at least one classroom hub.
    Creates a comma-separated text file that can be imported into MemberHub to assign
    hub IDs to existing directory entries.
    ASSUMPTIONS:
    None.
    """
    directory   = arg_list[0]
    map_d       = arg_list[1]
    roster      = arg_list[2]
    hubless     = FindHubless(arg_list)
    update_hubs = []

    hubed_count = hubless_count = 0

    for hubless_person in hubless:
        for roster_family in roster:
            found_person = roster_family.FindPersonInFamily(hubless_person)
            if not found_person == None:
                hubless_person.hubs = found_person.hubs
                update_hubs.append(hubless_person)
                hubed_count += 1
                break
        else:
            print "Did not find match for this person in the roster:",
            hubless_person.Print()
            hubless_count += 1

    print "Processed %d entries that were not in any classroom hub." % len(hubless)
    print "Was able to find classroom hubs for %d entries." % hubed_count
    print "Was not able to find classroom hubs for %d entries." % hubless_count

    import_file_tools.CreateHublessImportFile(update_hubs)

def FindEntriless(arg_list):
    """menu.FindEntriless
    INPUTS:
    - directory -- list containing the MemberHub directory families
    - roster    -- list containing the school roster families
    OUTPUTS:
    - entriless -- returns list of families in the school roster that could not
                   be found in the directory
    Also prints to standard output the names in the school roster who are not in the
    MemberHub directory.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    entriless = []

    for roster_family in roster:

        for directory_family in directory:
            if directory_family.IsSameFamily(roster_family):
                if directory_family.HasNewChildren(roster_family):
                    temp_family = family.Family()
                    temp_family.FormFamilyWithNewChildren(directory_family,roster_family)
                    print "Found family in directory with new child in roster:",
                    temp_family.Print()
                    entriless.append(temp_family)
                break

        else:
            print "Did not find this family from the roster in the directory:",
            roster_family.Print()
            entriless.append(roster_family)

    print "Found %d people on the roster who were not in the directory" % len(entriless)
    return entriless

def PrintNotInDirectory(arg_list):
    discard = FindEntriless(arg_list)

def MakeImportNotInDirectory(arg_list):
    """menu.MakeImportNotInDirectory
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    - map_d     -- dictionary mapping teacher names to hub IDs
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    map_d     = arg_list[2]
    entriless = FindEntriless(arg_list)

    import_file_tools.CreateNewMemberImport(entriless)

def MakeStudentImportFile(arg_list):
    """menu.MakeStudentImportFile
    INPUTS:
    - directory -- dictionary containing the MemberHub directory
    - roster    -- dictionary containing the school roster
    OUTPUTS:
    Creates a comma-separated text file that can be imported into MemberHub to create
    directory entries for people who are in the roster, but not already in the directory.
    Includes hub ID assignments for these people.
    ASSUMPTIONS:
    None.
    """
    directory = arg_list[0]
    roster    = arg_list[1]
    students  = []

    ## For each family in the roster ...
    for roster_family in roster:
        ## ...find the corresponding family in the directory
        for directory_family in directory:
            if directory_family.IsSameFamily(roster_family):
                ## For each child in the roster family...
                for roster_child in roster_family.children:
                    ## ...find the corresponding child in the directory family
                    directory_child = directory_family.FindChildInFamily(roster_child)
                    if directory_child != None:
                        ## instantiate a new Directory Person object, and copy the directory child into it
                        temp_child = person.DirectoryPerson()
                        temp_child = directory_child
                        ## clear the temporary object's hubs
                        temp_child.hubs = []
                        ## populate the temporary object's hubs with the roster child's hubs
                        ## modified with the student indicator appended
                        for hub in roster_child.hubs:
                            ## TBD - is student_hub a necessary step?
                            student_hub = hub + STUDENT_INDICATOR
                            temp_child.hubs.append(student_hub)
                        ## add the temporary child object to the list of students
                        students.append(temp_child)
                    else:
                        print "##################"
                        print "Did not find this child",
                        roster_child.Print()
                        print " in the family: "
                        directory_family.Print()
                ## Found the roster family in the directory, so break out of the directory_family loop
                break
        else:
            print "Did not find this family from the roster in the directory:",
            roster_family.Print()

    print "Found %d students on the roster who were in the directory" % len(students)

    ## Create an import file with all the students
    import_file_tools.CreateHublessImportFile(students)

def MakePrompt(choices):
    choice_list = sorted(choices)
    guts = '\n'.join(['(%s)%s' % (choice[0], choice[1:])
                      for choice in choice_list])
    return 'Choose:\n' + guts + '\nOr press <enter> to quit '

def RunMenu(directory, roster, map_d):
    """Runs the user interface for dictionary manipulation."""
    # The choices dictionary has function names for values.
    choices = {'1 - Find Missing Email':
                    {'Function':FindMissingEmail,'Arg':directory},
               '2 - Find Orphans':
                    {'Function':FindOrphans,'Arg':directory},
               '3 - Find Childless':
                    {'Function':FindChildless,'Arg':directory},
               '4 - Find Not In Classroom Hub':
                    {'Function':PrintHubless,'Arg':[directory,map_d]},
               '5 - Make Import File for Not In Classroom Hub':
                    {'Function':MakeImportForHubless,'Arg':[directory,map_d,roster]},
               '6 - Find Not in Directory':
                    {'Function':PrintNotInDirectory,'Arg':[directory,roster]},
               '7 - Make Import File for Not In Directory':
                    {'Function':MakeImportNotInDirectory,'Arg':[directory,roster,map_d]},
               '8 - Make Student Hub Population Import File':
                    {'Function':MakeStudentImportFile,'Arg':[directory,roster]}}

    prompt = MakePrompt(choices)

    while True:
        raw_choice = raw_input(prompt)
        if not raw_choice:
            break
        given_choice = raw_choice[0].lower()
        for maybe_choice in choices:
            if maybe_choice[0] == given_choice:
                # The appropriate function is called
                # using the dictionary value for the name
                # of the function.
                choices[maybe_choice]['Function'](choices[maybe_choice]['Arg'])
                break
        else:
            print '%s is not an acceptible choice.' % raw_choice

def main():
    directory = directory_tools.ReadDirectory()
    roster    = roster_tools.ReadRoster()
    map_d     = hub_map_tools.ReadMap()
    RunMenu(directory, roster, map_d)

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


<commit_before>import os
import colors
from colors import bcolors

class Menu:
    """docstring for Menu"""
    def __init__(self):
        self.option = 0
        self.suboption_menu = 0

    def clean_screen(self):
        os.system('cls' if os.name == 'nt' else 'clear')

    def blue_world(self):
        print(bcolors.bblue)

    def normal_world(self):
        print(bcolors.ENDC)

    def welcome_message(self):

        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                            WELCOME TO TWEETSTAT
        ---------------------------------------------------------

                      Get Twitter user\'s profile info

           Remember: \"with great power comes great responsibility\"

        """+bcolors.ENDC)
        self.blue_world()

    def print_main_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                           TweetStat Main Menu
        ---------------------------------------------------------

        0 --> User stat\'s                 1 --> RT\'s zone
        2 --> Fav\'s zone                  3 --> Follower\'s zone
                   -1 --> Exit          4 --> Extra
        """+bcolors.ENDC)
        self.blue_world()

    def print_user_menu(self):

        self.clean_screen()
        print(bcolors.BOLD+"""
      ---------------------------------------------------------
                       User stat\'s zone menu
      ---------------------------------------------------------

              0 --> More mentioned users.
              1 --> Users who mentioned you more.
              2 --> Relations between you and other user.
             -1 --> Back

            More comming soon

            """+bcolors.ENDC)
        self.blue_world()

    def print_rt_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           RT\'s zone menu
        ---------------------------------------------------------

                0 --> More rted users.
                1 --> User that make more rt\'s.
                2 --> Most retweeted tweets.
               -1 --> Back

            """+bcolors.ENDC)
        self.blue_world()

    def print_fav_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           Fav\'s zone menu
        ---------------------------------------------------------
                0 --> More fav users.
                1 --> Most faved tweets.
               -1 --> Back

            """+bcolors.ENDC)
        self.blue_world()

    def log_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                              Log Screen
        ---------------------------------------------------------

            To get access to TWEETSTAT, please introduce an

                     user screen name without @

            """+bcolors.ENDC)
        self.blue_world()

        usuario = input(bcolors.BOLD+'Tell me an user\'s screen name: '+bcolors.ENDC+bcolors.bblue)

        if usuario[0] == '@':
            usuario = usuario[1:]

        print("""

            """)

        return usuario

    def print_follower_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           Follower\'s zone menu
        ---------------------------------------------------------
                0 --> Not follow back.
                1 --> New followers.
                2 --> Last unfollows.
               -1 --> Back
            """+bcolors.ENDC)

    def continue_(self):

        wait = input(bcolors.BOLD+"""

Press any key to continue..."""+bcolors.ENDC)
        self.blue_world()

    def print_exit_log(self):
        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                            Exiting of TweetStat
        ---------------------------------------------------------

                      Thank you for using TweetStat.

             Remember what uncle Ben said once before he died:

              \"With great power comes great responsibility\"

            """+bcolors.ENDC)
        self.blue_world()

    def extra(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                              TWEETSTAT
        ---------------------------------------------------------

           TweetStat is an oupen source code with GNU-3 License

           The authors of this dangerous work are:

             Marta Gómez     --> https://github.com/mgmacias95
             Braulio Vargas  --> https://github.com/BraulioV

                        Press -1 to go back

            """+bcolors.ENDC)
        self.blue_world()

    def set_main_menu_opt(self):

        num_opts = 4

        self.option = int(input(bcolors.BOLD+"Choose a valid option: "+bcolors.ENDC+bcolors.bblue))

        if self.option < -1 or self.option > num_opts:
            print(bcolors.BOLD+bcolors.FAIL+"Oups! Something is wrong with your choice D:"+bcolors.ENDC+bcolors.bblue)

            while self.option < -1 or self.option > num_opts:
                self.option = int(input(bcolors.BOLD+"Try to choose a valid option: "+bcolors.ENDC+bcolors.bblue))

    def set_submenu_opt(self, num_opts):
        self.suboption_menu = int(input(bcolors.BOLD+"Choose a valid option: "+bcolors.ENDC+bcolors.bblue))

        if self.suboption_menu < -1 or self.suboption_menu > num_opts:
            print(bcolors.BOLD+bcolors.FAIL+"Oups! Something is wrong with your choice."+bcolors.ENDC+bcolors.bblue)

            while self.suboption_menu < -1 or self.suboption_menu > num_opts:
                self.suboption_menu = int(input(bcolors.BOLD+"Try to choose a valid option: "+bcolors.ENDC+bcolors.bblue))
<commit_msg>ops el acento<commit_after>import os
import colors
from colors import bcolors

class Menu:
    """docstring for Menu"""
    def __init__(self):
        self.option = 0
        self.suboption_menu = 0

    def clean_screen(self):
        os.system('cls' if os.name == 'nt' else 'clear')

    def blue_world(self):
        print(bcolors.bblue)

    def normal_world(self):
        print(bcolors.ENDC)

    def welcome_message(self):

        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                            WELCOME TO TWEETSTAT
        ---------------------------------------------------------

                      Get Twitter user\'s profile info

           Remember: \"with great power comes great responsibility\"

        """+bcolors.ENDC)
        self.blue_world()

    def print_main_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                           TweetStat Main Menu
        ---------------------------------------------------------

        0 --> User stat\'s                 1 --> RT\'s zone
        2 --> Fav\'s zone                  3 --> Follower\'s zone
                   -1 --> Exit          4 --> Extra
        """+bcolors.ENDC)
        self.blue_world()

    def print_user_menu(self):

        self.clean_screen()
        print(bcolors.BOLD+"""
      ---------------------------------------------------------
                       User stat\'s zone menu
      ---------------------------------------------------------

              0 --> More mentioned users.
              1 --> Users who mentioned you more.
              2 --> Relations between you and other user.
             -1 --> Back

            More comming soon

            """+bcolors.ENDC)
        self.blue_world()

    def print_rt_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           RT\'s zone menu
        ---------------------------------------------------------

                0 --> More rted users.
                1 --> User that make more rt\'s.
                2 --> Most retweeted tweets.
               -1 --> Back

            """+bcolors.ENDC)
        self.blue_world()

    def print_fav_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           Fav\'s zone menu
        ---------------------------------------------------------
                0 --> More fav users.
                1 --> Most faved tweets.
               -1 --> Back

            """+bcolors.ENDC)
        self.blue_world()

    def log_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                              Log Screen
        ---------------------------------------------------------

            To get access to TWEETSTAT, please introduce an

                     user screen name without @

            """+bcolors.ENDC)
        self.blue_world()

        usuario = input(bcolors.BOLD+'Tell me an user\'s screen name: '+bcolors.ENDC+bcolors.bblue)

        if usuario[0] == '@':
            usuario = usuario[1:]

        print("""

            """)

        return usuario

    def print_follower_menu(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                           Follower\'s zone menu
        ---------------------------------------------------------
                0 --> Not follow back.
                1 --> New followers.
                2 --> Last unfollows.
               -1 --> Back
            """+bcolors.ENDC)

    def continue_(self):

        wait = input(bcolors.BOLD+"""

Press any key to continue..."""+bcolors.ENDC)
        self.blue_world()

    def print_exit_log(self):
        self.clean_screen()

        print(bcolors.BOLD+"""

        ---------------------------------------------------------
                            Exiting of TweetStat
        ---------------------------------------------------------

                      Thank you for using TweetStat.

             Remember what uncle Ben said once before he died:

              \"With great power comes great responsibility\"

            """+bcolors.ENDC)
        self.blue_world()

    def extra(self):
        self.clean_screen()

        print(bcolors.BOLD+"""
        ---------------------------------------------------------
                              TWEETSTAT
        ---------------------------------------------------------

           TweetStat is an oupen source code with GNU-3 License

           The authors of this dangerous work are:

             Marta Gomez     --> https://github.com/mgmacias95
             Braulio Vargas  --> https://github.com/BraulioV

                        Press -1 to go back

            """+bcolors.ENDC)
        self.blue_world()

    def set_main_menu_opt(self):

        num_opts = 4

        self.option = int(input(bcolors.BOLD+"Choose a valid option: "+bcolors.ENDC+bcolors.bblue))

        if self.option < -1 or self.option > num_opts:
            print(bcolors.BOLD+bcolors.FAIL+"Oups! Something is wrong with your choice D:"+bcolors.ENDC+bcolors.bblue)

            while self.option < -1 or self.option > num_opts:
                self.option = int(input(bcolors.BOLD+"Try to choose a valid option: "+bcolors.ENDC+bcolors.bblue))

    def set_submenu_opt(self, num_opts):
        self.suboption_menu = int(input(bcolors.BOLD+"Choose a valid option: "+bcolors.ENDC+bcolors.bblue))

        if self.suboption_menu < -1 or self.suboption_menu > num_opts:
            print(bcolors.BOLD+bcolors.FAIL+"Oups! Something is wrong with your choice."+bcolors.ENDC+bcolors.bblue)

            while self.suboption_menu < -1 or self.suboption_menu > num_opts:
                self.suboption_menu = int(input(bcolors.BOLD+"Try to choose a valid option: "+bcolors.ENDC+bcolors.bblue))
<|endoftext|>


<commit_before>import pygame
from material_manager import MaterialManager
from actor import Actor
from input_manager import Actions, CustomEvents

class InventoryMenu(object):
    def __init__(self, config):
        self.enabled = False
        self.material_manager = MaterialManager(config["material_file"])

        dirt = self.material_manager.get_material("dirt", (50,50))
        stone = self.material_manager.get_material("stone", (50,50))

        dirt_actor = Actor(dirt.surface, 5, 5)
        dirt_actor.position = (10, 10)
        dirt_actor.mat_name = "dirt"
        stone_actor = Actor(stone.surface, 5, 5)
        stone_actor.position = (70, 10)
        stone_actor.mat_name = "stone"

        self.actors = [dirt_actor, stone_actor]

    def _handle_events(self, events):
        for event in events:
            event_name = event if isinstance(event, int) else event[0]

            if event_name == Actions.USER_MENU_CLICK:
                for actor in self.actors:
                    rect = actor.get_rect()
                    rect.move_ip(self.surface_position)
                    if rect.collidepoint(event[1]):
                        pygame.event.post(pygame.event.Event(CustomEvents.CLOSEINV))
                        pygame.event.post(pygame.event.Event(CustomEvents.CHOOSEMAT, name=actor.mat_name))

    def doFrame(self, screen, delta, events):
        if self.enabled:
            self.surface_position = ((screen.get_width() / 4), (screen.get_height() / 4))
            self.surface = pygame.Surface((screen.get_width() / 2, screen.get_height() / 2))
            self.surface.fill((255, 0, 0))
            self.surface.set_alpha(200)

            self._handle_events(events)

            for actor in self.actors:
                actor.update(delta, 10)
                self.surface.blit(actor.surface, actor.position)

            screen.blit(self.surface, self.surface_position)
<commit_msg>highlighting in inventory<commit_after>import pygame
from material_manager import MaterialManager
from actor import Actor
from input_manager import Actions, CustomEvents

INV_HIGHLIGHT_COLOR = (0,0,0)

class InventoryMenu(object):
    def __init__(self, config):
        self.enabled = False
        self.material_manager = MaterialManager(config["material_file"])

        dirt = self.material_manager.get_material("dirt", (50,50))
        stone = self.material_manager.get_material("stone", (50,50))

        dirt_actor = Actor(dirt.surface, 5, 5)
        dirt_actor.position = (10, 10)
        dirt_actor.mat_name = "dirt"
        stone_actor = Actor(stone.surface, 5, 5)
        stone_actor.position = (70, 10)
        stone_actor.mat_name = "stone"

        self.actors = [dirt_actor, stone_actor]

    def _handle_events(self, events):
        for event in events:
            event_name = event if isinstance(event, int) else event[0]

            if event_name == Actions.USER_MENU_CLICK:
                for actor in self.actors:
                    rect = actor.get_rect()
                    rect.move_ip(self.surface_position)
                    if rect.collidepoint(event[1]):
                        pygame.event.post(pygame.event.Event(CustomEvents.CLOSEINV))
                        pygame.event.post(pygame.event.Event(CustomEvents.CHOOSEMAT, name=actor.mat_name))

    def doFrame(self, screen, delta, events):
        if self.enabled:
            self.surface_position = ((screen.get_width() / 4), (screen.get_height() / 4))
            self.surface = pygame.Surface((screen.get_width() / 2, screen.get_height() / 2))
            self.surface.fill((255, 0, 0))
            self.surface.set_alpha(200)

            self._handle_events(events)

            mouse_pos = pygame.mouse.get_pos()

            for actor in self.actors:
                actor.update(delta, 10)
                self.surface.blit(actor.surface, actor.position)

                #highlight it if the mouse is on top
                rect = actor.get_rect()
                rect.move_ip(self.surface_position)
                if rect.collidepoint(mouse_pos):
                    pygame.draw.rect(self.surface, INV_HIGHLIGHT_COLOR, actor.get_rect(), 2)

            screen.blit(self.surface, self.surface_position)
<|endoftext|>


<commit_before># Run the following command to test:
#
#     (in /usr/local/googkit)
#     $ python -m {test_module_name}
#
# See also: http://docs.python.org/3.3/library/unittest.html#command-line-interfacejjkkjj
#
# We cannot use unittest.mock on python 2.x!
# Please install the Mock module when you use Python 2.x.
#
#     $ easy_install -U Mock
#
# See also: http://www.voidspace.org.uk/python/mock/#installing

import unittest
import os
import re

try:
    # Python 3.3 or later
    import unittest.mock as mock
except ImportError:
    # Python 2.x or 3.2-
    import mock

import lib.path
from lib.error import GoogkitError
from test.stub_stdout import StubStdout

class TestPath(unittest.TestCase):
    def test_project_root_on_grandchild(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/googkit.cfg',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_root(), '/dir1/dir2')

    def test_project_root_on_current(self):
        def side_effect(path):
            if os.path.normpath(path) == '/dir1/dir2/dir3/dir4/googkit.cfg':
                return True
            else:
                return False

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_root(), '/dir1/dir2/dir3/dir4')

    def test_project_root_with_on_unrelated(self):
        with mock.patch('os.path.exists', return_value = False):
            self.assertEqual(lib.path.project_root(), None)

    def test_project_config_on_groundchild(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/googkit.cfg',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_config(), '/dir1/dir2/googkit.cfg')

    def test_project_config_on_current(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4',
                '/dir1/dir2/dir3/dir4/googkit.cfg'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_config(), '/dir1/dir2/dir3/dir4/googkit.cfg')

    def test_project_config_with_on_unrelated(self):
        with mock.patch('os.path.exists', return_value = False):
            with self.assertRaises(GoogkitError):
                lib.path.project_config()

    def test_user_config_on_groundchild(self):
        def side_effect_expand_user(path):
            return re.sub(r'~', '/home/user', path)

        with mock.patch('os.path.expanduser', side_effect = side_effect_expand_user), \
                mock.patch('os.path.exists'):

            self.assertEqual(lib.path.user_config(), '/home/user/.googkit')

    def test_user_config_with_file_missing(self):
        def side_effect_expand_user(path):
            return re.sub(r'~', '/home/user', path)

        def side_effect_exists(path):
            exists = [
                '/',
                '/home',
                '/home/user',
                '/home/user/.googkit']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.expanduser', side_effect = side_effect_expand_user), \
                mock.patch('os.path.exists', side_effect = side_effect_exists):
            self.assertEqual(lib.path.user_config(), '/home/user/.googkit')

    def test_default_config(self):
        def side_effect_exists(path):
            exists = [
                '/',
                '/dummy',
                '/dummy/usr',
                '/dummy/usr/local',
                '/dummy/usr/local/googkit',
                '/dummy/usr/local/googkit/config',
                '/dummy/usr/local/googkit/config/default.cfg']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.exists', side_effect = side_effect_exists), \
                mock.patch('lib.path.googkit_root', return_value = '/dummy/usr/local/googkit'):
            self.assertEqual(lib.path.default_config(), '/dummy/usr/local/googkit/config/default.cfg')

    def test_default_config_with_file_missing(self):
        def side_effect_exists(path):
            exists = [
                '/',
                '/dummy',
                '/dummy/usr',
                '/dummy/usr/local',
                '/dummy/usr/local/googkit',
                '/dummy/usr/local/googkit/config']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.exists', side_effect = side_effect_exists), \
                mock.patch('lib.path.googkit_root', return_value = '/dummy/usr/local/googkit'):
            with self.assertRaises(GoogkitError):
                lib.path.default_config()
<commit_msg>Add a test for lib.path.googkit_root<commit_after># Run the following command to test:
#
#     (in /usr/local/googkit)
#     $ python -m {test_module_name}
#
# See also: http://docs.python.org/3.3/library/unittest.html#command-line-interfacejjkkjj
#
# We cannot use unittest.mock on python 2.x!
# Please install the Mock module when you use Python 2.x.
#
#     $ easy_install -U Mock
#
# See also: http://www.voidspace.org.uk/python/mock/#installing

import unittest
import os
import re

try:
    # Python 3.3 or later
    import unittest.mock as mock
except ImportError:
    # Python 2.x or 3.2-
    import mock

import lib.path
from lib.error import GoogkitError
from test.stub_stdout import StubStdout

class TestPath(unittest.TestCase):
    def test_project_root_on_grandchild(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/googkit.cfg',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_root(), '/dir1/dir2')

    def test_project_root_on_current(self):
        def side_effect(path):
            if os.path.normpath(path) == '/dir1/dir2/dir3/dir4/googkit.cfg':
                return True
            else:
                return False

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_root(), '/dir1/dir2/dir3/dir4')

    def test_project_root_with_on_unrelated(self):
        with mock.patch('os.path.exists', return_value = False):
            self.assertEqual(lib.path.project_root(), None)

    def test_project_config_on_groundchild(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/googkit.cfg',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_config(), '/dir1/dir2/googkit.cfg')

    def test_project_config_on_current(self):
        def side_effect(path):
            exists = [
                '/',
                '/dir1',
                '/dir1/dir2',
                '/dir1/dir2/dir3',
                '/dir1/dir2/dir3/dir4',
                '/dir1/dir2/dir3/dir4/googkit.cfg'
            ]

            return os.path.normpath(path) in exists

        with mock.patch('os.getcwd', return_value = '/dir1/dir2/dir3/dir4'), \
                mock.patch('os.path.exists', side_effect = side_effect):
            self.assertEqual(lib.path.project_config(), '/dir1/dir2/dir3/dir4/googkit.cfg')

    def test_project_config_with_on_unrelated(self):
        with mock.patch('os.path.exists', return_value = False):
            with self.assertRaises(GoogkitError):
                lib.path.project_config()

    def test_user_config_on_groundchild(self):
        def side_effect_expand_user(path):
            return re.sub(r'~', '/home/user', path)

        with mock.patch('os.path.expanduser', side_effect = side_effect_expand_user), \
                mock.patch('os.path.exists'):

            self.assertEqual(lib.path.user_config(), '/home/user/.googkit')

    def test_user_config_with_file_missing(self):
        def side_effect_expand_user(path):
            return re.sub(r'~', '/home/user', path)

        def side_effect_exists(path):
            exists = [
                '/',
                '/home',
                '/home/user',
                '/home/user/.googkit']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.expanduser', side_effect = side_effect_expand_user), \
                mock.patch('os.path.exists', side_effect = side_effect_exists):
            self.assertEqual(lib.path.user_config(), '/home/user/.googkit')

    def test_default_config(self):
        def side_effect_exists(path):
            exists = [
                '/',
                '/dummy',
                '/dummy/usr',
                '/dummy/usr/local',
                '/dummy/usr/local/googkit',
                '/dummy/usr/local/googkit/config',
                '/dummy/usr/local/googkit/config/default.cfg']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.exists', side_effect = side_effect_exists), \
                mock.patch('lib.path.googkit_root', return_value = '/dummy/usr/local/googkit'):
            self.assertEqual(lib.path.default_config(), '/dummy/usr/local/googkit/config/default.cfg')

    def test_default_config_with_file_missing(self):
        def side_effect_exists(path):
            exists = [
                '/',
                '/dummy',
                '/dummy/usr',
                '/dummy/usr/local',
                '/dummy/usr/local/googkit',
                '/dummy/usr/local/googkit/config']

            return os.path.normpath(path) in exists

        with mock.patch('os.path.exists', side_effect = side_effect_exists), \
                mock.patch('lib.path.googkit_root', return_value = '/dummy/usr/local/googkit'):
            with self.assertRaises(GoogkitError):
                lib.path.default_config()

    def test_googkit_root(self):
        with mock.patch('lib.path.__file__', new = '/dummy/googkit/lib/path.py'):
            self.assertEqual(lib.path.googkit_root(), '/dummy/googkit')
<|endoftext|>