Esempio n. 1
0
def piazza_reader(email, password, coursecode):
    # User credentials
    piazza = Piazza()
    # Login
    piazza.user_login(email, password)

    class_dictionary = piazza.get_user_classes()

    # dictionary for 'course code: hash_id'
    coursetohash = {}
    # print(len(class_dictionary))
    for i in range(len(class_dictionary)):
        coursetohash.update(
            {class_dictionary[i]['num']: class_dictionary[i]['nid']})

    print(coursetohash)

    classroom = piazza.network(coursetohash[coursecode])

    # print(coursecode)
    # print(coursetohash[coursecode])

    # go through all the posts, aggregate them in a data-structure
    postquestions = []
    postanswers = []

    # board_posts type is generator: cannot access memory in the lazy list
    board_posts = classroom.iter_all_posts(limit=const_limit)

    # iterate through board posts
    for post in board_posts:
        # get rid of html tags in question in post
        question_string = strip_tags(post["history"][0]["content"])

        # append to questions array
        postquestions.append(question_string)

        # checks if there's an answer associated to the question
        if "children" in post.keys(
        ) and post["children"] and "history" in post["children"][0]:

            # for all answers in a single post (iterate)
            for answer_index in range(len(post["children"][0]["history"])):

                # get rid of html tags for answers in the post, and check if the entry is a string
                if type(post["children"][0]["history"][answer_index]
                        ["content"]) == str:
                    answer_string = strip_tags(post["children"][0]["history"]
                                               [answer_index]["content"])

                    # append to answers array
                    postanswers.append(answer_string)

    # print(postQuestions + postAnswers)
    return " ".join(postquestions + postanswers)
Esempio n. 2
0
def login(email, password):
    piazza = Piazza()
    piazza.user_login(email, password)
    class_dictionary = piazza.get_user_classes()
    return class_dictionary

    courseToHash = {}
    #print(len(class_dictionary))
    for i in range(len(class_dictionary)):
        courseToHash.update(
            {class_dictionary[i]['num']: class_dictionary[i]['nid']})
Esempio n. 3
0
def course_list(email, password):
    # User credentials
    piazza = Piazza()
    # Login
    piazza.user_login(email, password)

    # create class dictionary from user class details: we are interested in the "num" key
    class_dictionary = piazza.get_user_classes()

    course_code_list = []

    for index in range((len(class_dictionary))):
        course_code_list.append(class_dictionary[index]['num'])

    return course_code_list
Esempio n. 4
0
def course_hash(email, password):
    # User credentials
    piazza = Piazza()
    # Login
    piazza.user_login(email, password)

    class_dictionary = piazza.get_user_classes()

    # dictionary for 'course code: hash_id'
    course_to_hash = {}
    # print(len(class_dictionary))
    for i in range(len(class_dictionary)):
        course_to_hash.update(
            {class_dictionary[i]['num']: class_dictionary[i]['nid']})

    return course_to_hash
Esempio n. 5
0
    def get_data(self):
        return ''.join(self.fed)


def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()


p = Piazza()
p.user_login("*****@*****.**", "59170864aS@")
#TODO UPON ASKING FOR USER CREDENTIALS, LOGIN TO THEIR PIAZZA ACCOUNT

stat200101 = p.network("jz1p1pgbr9e15c")
classes = p.get_user_classes()
print(classes)
print(stat200101)

# this gets the contents of a post: the question
tempPost = stat200101.get_post("361")
tempPostContent = tempPost["history"][0]["content"]
strippedQuestion = strip_tags(tempPostContent)
tempPostAns = tempPost["children"][0]["history"][0]["content"]
strippedAns = strip_tags(tempPostAns)

# go through all the posts, aggregate them in a datastructure
# store that in for easy access
postQuestions = []
postAnswers = []
postQuestions2 = {}
Esempio n. 6
0
def getPiazzaInfo(username, password):
    # get our api
    from piazza_api import Piazza
    import time

    # initalize piazza client
    p = Piazza()
    # login
    p.user_login(email=username, password=password)

    # get our class list
    classes = p.get_user_classes()

    # information for all classes
    classesInfo = []
    # iterate till we have one item per class in the list,
    # containing all needed elements for that class
    for c in classes:
        # individual class information
        classInfo = {}
        # set class name and number as per piazza
        classInfo['name'] = c['name']
        classInfo['number'] = c['num']
        # get url/nid of the class
        curClass = p.network(c['nid'])

        # get our iterator for the posts of that class
        posts = curClass.iter_all_posts(limit=5)

        # store post info in here
        neededInfo = []

        # since piazza api has a speed limit,
        # we are enclosing the data in a try catch
        try:
            # iterate through posts
            for post in posts:
                # store post information in here
                postInfo = {}

                # set post subject and content
                postInfo['subject'] = post['history'][0]['subject']
                postInfo['content'] = post['history'][0]['content']

                # store followups information here
                postInfo['followUps'] = []

                # iterate through 'main' follow ups
                for mainFollowUp in post['children']:

                    # if the follow up has a subject, then
                    # it is valid
                    if 'subject' in mainFollowUp:
                        # store followup info here
                        followUp = {}

                        # set followup information
                        followUp['mainComment'] = mainFollowUp['subject']

                        # store and iterate through follow up responses
                        followUp['subComments'] = []
                        for subComment in mainFollowUp['children']:
                            followUp['subComments'].append(
                                subComment['subject'])

                        # append followup to followups
                        postInfo['followUps'].append(followUp)

                # append post to posts
                neededInfo.append(postInfo)

            # store posts information for a class
            classInfo['posts'] = neededInfo

            # add class information to our list
            classesInfo.append(classInfo)
        except:
            # if we tried too fast,
            # then there was an error
            print("piazza api trying too fast!")

    # return our object of class informations
    return classesInfo
Esempio n. 7
0
def piazza_parse(pi_url):
    temp = ""
    p = Piazza()
    p.user_login(email=os.environ['EMAIL'], password=os.environ['PASSWORD'])
    classes = p.get_user_classes()

    #piazza_url = urlparse(sys.argv[1])
    piazza_url = urlparse(pi_url)

    class_id = piazza_url.path.split('/')[2]
    post_num = piazza_url.query.split('=')[1]

    # Returns a class network
    class_net = p.network(class_id)

    post = class_net.get_post(post_num)

    class_name = "None"
    for i in classes:
        if i['nid'] == class_id:
            class_name = i['num']
    question = post["history"][0]["content"]
    subject = post["history"][0]["subject"]

    # print("QUESTION JSON")
    # print('-----------------')
    # print(post["history"][0])
    # print()

    temp += "__**CLASS NAME**__\n"
    temp += class_name + '\n\n'
    temp += "__**SUBJECT**__\n"
    temp += subject + '\n\n'

    # Content of post that includes html tags
    #
    # print("CONTENT")
    # print('-----------------')
    # print(question)
    # print()

    temp += "__**CONTENT**__\n"
    question_text = BeautifulSoup(question, features='lxml').text
    temp += question_text + '\n\n'

    answers = post["children"]

    #TODO concatenate all answers? or just one
    #temp += answers

    s_answer_json = None
    i_answer_json = None

    for answer in answers:
        if answer['type'] == 's_answer':
            s_answer_json = answer
        elif answer['type'] == 'i_answer':
            i_answer_json = answer

    if s_answer_json is not None:
        temp += "__**STUDENT ANSWER**__\n"
        s_answer = s_answer_json['history'][0]['content']
        s_answer_text = BeautifulSoup(s_answer, features='lxml').text
        temp += s_answer_text + '\n\n'

    if i_answer_json is not None:
        temp += "__**INSTRUCTOR ANSWER**__\n"
        i_answer = i_answer_json['history'][0]['content']
        i_answer_text = BeautifulSoup(i_answer, features='lxml').text
        temp += i_answer_text

    #     print(i_answer_text)
    # print()

    return temp
Esempio n. 8
0
class PiazzaCompileBot(object):
    
    def __init__(self):
        self.p = Piazza()
        self.p.user_login(PIAZZA_USER, PIAZZA_PASS)
        self.uid = self.p.get_user_profile()['user_id']

        classes = self.p.get_user_classes()
        self.classes = []

        print 'Now watching posts for the following {0} classes:'.format(len(classes))
        for c in classes:
            print '{0} ({1}, {2})'.format(c['num'], c['name'], c['term'])
            self.classes.append(self.p.network(c['nid']))

            self.filter = UnreadFilter()

    def check(self):
        for c in self.classes:

            # ensure we go through the entire feed if there are more posts to read
            feed = {'more': True}
            while feed['more']:
                # filter for only updated posts
                feed = c.get_filtered_feed(self.filter)
                for feed_post in feed['feed']:
                    # get the post number and retrieve the post
                    post = c.get_post(feed_post['nr'])
                    if self.already_compiled(post):
                        print 'Post %s already compiled' % post['id']
                        break
                    post_text = post['history'][0]['content']

                    print 'Checking post %s for code' % post['id']

                    # parse the text in the post
                    # example text:
                    """
                    <p></p><p>I&#39;m having an issue, please help!</p>
                    <p>CompileBot! python</p>
                    <pre>def __init__(self):
                        print &#39;blah&#39;</pre>
                    <p>Input:</p>
                    <pre>blah</pre>
                    """
                    soup = BeautifulSoup(post_text.replace("<br />", "\n"))
                    # Look for p tags
                    tags = soup.find_all('p')
                    for tag in tags:
                        try:
                            m = None if not tag.contents else re.search(r'(?i)CompileBot[.?;:!]*\s*(?P<args>.*)\s*', tag.contents[0])
                            if m is not None and tag.next_sibling and tag.next_sibling.next_sibling:
                                # look for code
                                code = None
                                cur_tag = tag.next_sibling.next_sibling
                                if cur_tag and cur_tag.name == 'pre':
                                    code = cur_tag.contents[0]

                                # look for optional stdin
                                if code is not None:
                                    stdin = ''
                                    if cur_tag.next_sibling and cur_tag.next_sibling.next_sibling:
                                        cur_tag = cur_tag.next_sibling.next_sibling
                                        try:
                                            if cur_tag.name == 'p' and bool(re.match('input', cur_tag.contents[0], re.I)) and cur_tag.next_sibling:
                                                cur_tag = cur_tag.next_sibling.next_sibling
                                                if cur_tag and cur_tag.name == 'pre':
                                                    stdin = cur_tag.contents[0]
                                                    cur_tag = cur_tag.next_sibling
                                        except Exception as e:
                                            pass
                                    else:
                                        pass
                                    code = urllib.unquote(code)
                                    stdin = urllib.unquote(stdin)
                                    try:
                                        lang, opts = m.group('args').split(' -', 1)
                                        opts = ('-' + opts).split()
                                    except ValueError:
                                        # No additional opts found
                                        lang, opts = m.group('args'), []
                                    lang = lang.strip()
                                    print 'Attempting compile for post {0}: language={1}, args={2}'.format(post['id'], lang, opts)
                                    try:
                                        details = self.compile(code, lang, stdin=stdin)
                                        print "Compiled ideone submission {link} for comment {id}".format(link=details['link'], id=post['id'])
                                        # The ideone submission result value indicaties the final state of
                                        # the program. If the program compiled and ran successfully the
                                        # result is 15. Other codes indicate various errors.
                                        result_code = details['result']
                                        # The user is alerted of any errors via message reply unless they
                                        # include an option to include errors in the reply.
                                        if result_code in [11, 12, 15]:
                                            text = self.format_reply(details, opts)
                                            ideone_link = "http://ideone.com/{}".format(details['link'])
                                            text += "Ideone link: %s" % ideone_link
                                            print 'Compilation success!\n%s' % text
                                            c.add_followup(post['id'], text)
                                            print 'Posted results to Piazza'
                                        else:
                                            error_text = {
                                                11: COMPILE_ERROR_TEXT,
                                                12: RUNTIME_ERROR_TEXT,
                                                13: TIMEOUT_ERROR_TEXT,
                                                17: MEMORY_ERROR_TEXT,
                                                19: ILLEGAL_ERROR_TEXT,
                                                20: INTERNAL_ERROR_TEXT
                                            }.get(result_code, '')
                                            # Include any output from the submission in the reply.
                                            if details['cmpinfo']:
                                                error_text += "Compiler Output:\n{}\n".format(
                                                                    self.code_block(details['cmpinfo']))
                                            if details['output']:
                                                error_text += "Output:\n{}\n".format(
                                                        self.code_block(details['output']))
                                            if details['stderr']:
                                                error_text += "Error Output:\n{}\n".format(
                                                                    self.code_block(details['stderr']))
                                            print 'Error: %s' % error_text
                                    except ideone.IdeoneError as e:
                                        c.add_followup(post['id'], 'An Ideone error occurred.\n%s' % self.code_block(e))
                                        print e
                        except ValueError as e:
                            import traceback, os.path, sys
                            top = traceback.extract_tb(sys.exc_info()[2])[-1]
                            print 'Parse failed: {0}'.format(', '.join([type(e).__name__, os.path.basename(top[0]), str(top[1])]))

    def already_compiled(self, post):
        children = post['children']
        for child in children:
            if child['uid'] == self.uid:
                return True
        return False

    def compile(self, source, lang, stdin=''):
        """Compile and evaluate source sode using the ideone API and return
        a dict containing the output details.
        Keyword arguments:
        source -- a string containing source code to be compiled and evaluated
        lang -- the programming language pertaining to the source code
        stdin -- optional "standard input" for the program
        >>> d = compile('print("Hello World")', 'python')
        >>> d['output']
        Hello World
        """
        lang = LANG_ALIASES.get(lang.lower(), lang)
        # Login to ideone and create a submission
        i = ideone.Ideone(IDEONE_USER, IDEONE_PASS)
        sub = i.create_submission(source, language_name=lang, std_input=stdin)
        sub_link = sub['link']
        details = i.submission_details(sub_link)
        # The status of the submission indicates whether or not the source has
        # finished executing. A status of 0 indicates the submission is finished.
        while details['status'] != 0:
            details = i.submission_details(sub_link)
            time.sleep(3)
        details['link'] = sub_link
        return details

    def format_reply(self, details, opts):
        """Returns a reply that contains the output from a ideone submission's
        details along with optional additional information.
        """
        head, body, extra, = '', '', ''
        # Combine information that will go before the output.
        if '--source' in opts:
            head += 'Source:\n{}\n\n'.format(self.code_block(details['source']))
        if '--input' in opts:
        # Combine program output and runtime error output.
            head += 'Input:\n{}\n\n'.format(self.code_block(details['input']))
        output = details['output'] + details['stderr']
        # Truncate the output if it contains an excessive
        # amount of line breaks or if it is too long.
        if output.count('\n') > LINE_LIMIT:
            lines = output.split('\n')
            # If message contains an excessive amount of duplicate lines,
            # truncate to a small amount of lines to discourage spamming
            if len(set(lines)) < 5:
                lines_allowed = 2
            else:
                lines_allowed = 51
            output = '\n'.join(lines[:lines_allowed])
            output += "\n..."
        # Truncate the output if it is too long.
        if len(output) > 8000:
            output = output[:8000] + '\n    ...\n'
        body += 'Output:\n{}\n\n'.format(self.code_block(output))
        if details['cmpinfo']:
            body += 'Compiler Info:\n{}\n\n'.format(details['cmpinfo'])
        # Combine extra runtime information.
        if '--date' in opts:
            extra += "Date: {}\n\n".format(details['date'])
        if '--memory' in opts:
            extra += "Memory Usage: {} bytes\n\n".format(details['memory'])
        if '--time' in opts:
            extra += "Execution Time: {} seconds\n\n".format(details['time'])
        if '--version' in opts:
            extra += "Version: {}\n\n".format(details['langVersion'])
        # To ensure the reply is less than 10000 characters long, shorten
        # sections of the reply until they are of adequate length. Certain
        # sections with less priority will be shortened before others.
        total_len = 0
        for section in (FOOTER, body, head, extra):
            if len(section) + total_len > 9800:
                section = section[:9800 - total_len] + '\n...\n'
                total_len += len(section)
        reply_text = head + body + extra
        return reply_text

    def code_block(self, output):
        return "<pre>{0}</pre>".format(output)
Esempio n. 9
0
from piazza_api import Piazza
from bs4 import BeautifulSoup
import requests
from lxml import html
import lxml.html
import pandas as pd
import re

p = Piazza()

# In[2]:

person = p.user_login('*****@*****.**', 'PASSWORD')
user_profile = p.get_user_profile()
print()
user_classes = p.get_user_classes()
print(p)
CSE110 = p.network("jebhpmejaa92vh")
print(type(CSE110))
#CSE110.get_post(10)

#posts = CSE110.iter_all_posts(limit=1)
#for post in posts:
#    for i in post:
#        print(i)

# In[3]:

for i in CSE110.feed_filters:
    print(i)
print(type(CSE110.feed_filters))
Esempio n. 10
0
def piazza_parse(pi_url):
    '''
    Called by connect.py to get post from Piazza.
    It will format the post json into a more readable message for server.
    '''

    # Create Piazza object, login, and get the users classes
    temp = ""
    p = Piazza()
    p.user_login(email=os.environ['EMAIL'], password=os.environ['PASSWORD'])
    classes = p.get_user_classes()

    # Parse the piazza url into components
    piazza_url = urlparse(pi_url)

    # Get class id and the post number from piazza_url
    class_id = piazza_url.path.split('/')[2]
    post_num = piazza_url.query.split('=')[1]

    # Returns a class network
    class_net = p.network(class_id)

    # Get the piazza post from the post number and class network
    post = class_net.get_post(post_num)

    # Get class name
    class_name = "None"
    for i in classes:
        if i['nid'] == class_id:
            class_name = i['num']

    # Get question and subject of the post
    question = post["history"][0]["content"]
    subject = post["history"][0]["subject"]

    # Format class name, subject, and post content for Discord
    temp += "__**CLASS NAME**__\n"
    temp += class_name + '\n\n'
    temp += "__**SUBJECT**__\n"
    temp += subject + '\n\n'
    temp += "__**CONTENT**__\n"
    question_text = BeautifulSoup(question, features='lxml').text
    temp += question_text + '\n\n'

    # Get answers json
    answers = post["children"]

    # Init student and instructor json answers
    s_answer_json = None
    i_answer_json = None

    # Assign student and instructor answers if they exist
    for answer in answers:
        if answer['type'] == 's_answer':
            s_answer_json = answer
        elif answer['type'] == 'i_answer':
            i_answer_json = answer

    # Format student and/or instructor answer if they exist
    if s_answer_json is not None:
        temp += "__**STUDENT ANSWER**__\n"
        s_answer = s_answer_json['history'][0]['content']
        s_answer_text = BeautifulSoup(s_answer, features='lxml').text
        temp += s_answer_text + '\n\n'

    if i_answer_json is not None:
        temp += "__**INSTRUCTOR ANSWER**__\n"
        i_answer = i_answer_json['history'][0]['content']
        i_answer_text = BeautifulSoup(i_answer, features='lxml').text
        temp += i_answer_text

    return temp
Esempio n. 11
0
def piazza_parse(pi_url, email, passwd, author):
    '''
    Called by connect.py to get post from Piazza.
    It will format the post json into a more readable message for server.
    '''

    # Create Piazza object, login, and get the users classes
    data = {}
    p = Piazza()
    p.user_login(email=email, password=passwd)
    classes = p.get_user_classes()

    # Parse the piazza url into components
    piazza_url = urlparse(pi_url)

    # Get class id and the post number from piazza_url
    class_id = piazza_url.path.split('/')[2]
    post_num = piazza_url.query.split('=')[1]

    # Returns a class network
    class_net = p.network(class_id)

    # Get the piazza post from the post number and class network
    post = class_net.get_post(post_num)

    # Get class name
    class_name = "None"
    for i in classes:
        if i['nid'] == class_id:
            class_name = i['num']

    # Get question and subject of the post
    question = post["history"][0]["content"]
    subject = post["history"][0]["subject"]

    # Format data to return
    data.setdefault("class_name", class_name)
    if not data['class_name']:
        data['class_name'] = ZERO_WHITE_SPACE
    data.setdefault("question", subject)
    if not data['question']:
        data['question'] = ZERO_WHITE_SPACE
    # data.setdefault("subject", subject)
    data.setdefault("question_text",
                    BeautifulSoup(question, features='lxml').text)
    if not data['question_text']:
        data['question_text'] = ZERO_WHITE_SPACE
    if not data['question_text']:
        data['question'] = ZERO_WHITE_SPACE
    data.setdefault("answer", {'instructor': '', 'student': ''})

    # Get answers json
    answers = post["children"]

    # Assign student and instructor answers if they exist
    for answer in answers:
        if answer['type'] == 's_answer':
            data['answer']['student'] = BeautifulSoup(
                answer['history'][0]['content'], features='lxml').text
        elif answer['type'] == 'i_answer':
            data['answer']['instructor'] = BeautifulSoup(
                answer['history'][0]['content'], features='lxml').text

    return embed_creator(data, pi_url, author)