コード例 #1
0
    def test_infinite_loop(self, form: Form):
        def callback(elem, page_index, elem_index):
            if page_index == 0 and elem_index == 0:
                return 'First'
            return Value.EMPTY

        with pytest.raises(InfiniteLoop):
            form.fill(callback, fill_optional=False)
コード例 #2
0
def form_with_dump(url, session=None):
    form_data = []

    form = Form()
    orig_parse = form._parse

    def dump(data):
        # replace video url
        data = rewrite_links(data)
        # erase the form url
        data[Form._DocIndex.URL] = '0' * len(data[Form._DocIndex.URL])
        nonlocal form_data
        form_data = data
        return orig_parse(data)

    form._parse = dump
    form.load(url, session=session)

    return form, form_data
コード例 #3
0
 def form():
     """
     A form with 3 pages, each has 2 dropdowns.
     Each dropdown has three options:
         - "Go to the first page"
         - "Go to the second page"
         - "Go to submit page"
     """
     pages = [Page.first()] + [
         TestTransitions._page(100000 + 1000 * i) for i in range(2)
     ]
     for page in pages:
         for i in range(2):
             options = [
                 ActionOption(value=f'First',
                              other=False,
                              action=_Action.FIRST),
                 ActionOption(value=f'Second',
                              other=False,
                              action=pages[1].id),
                 ActionOption(value=f'Submit',
                              other=False,
                              action=_Action.SUBMIT),
             ]
             page.append(
                 TestTransitions._dropdown(
                     id_=page.id + 100 * i,  # just unique ids
                     entry_id=page.id + 100 * i + 10,
                     options=options))
     form = Form()
     form.pages = pages
     form._resolve_actions()
     form.is_loaded = True
     return form
コード例 #4
0
 def test_submit_not_loaded(self):
     form = Form()
     with pytest.raises(FormNotLoaded):
         form.submit()
コード例 #5
0
 def test_fill_not_loaded(self):
     form = Form()
     with pytest.raises(FormNotLoaded):
         form.fill()
コード例 #6
0
def main():
    ua = FakeUserAgent()
    # A session for form loading and submission
    sess = requests.session()
    sess.headers['User-Agent'] = ua.chrome

    # Mean time between submissions
    mean_dt = 60

    parser = argparse.ArgumentParser()
    parser.add_argument(
        'url',
        help='The form url (https://docs.google.com/forms/d/e/.../viewform)')
    args = parser.parse_args()

    form = Form()
    form.load(args.url, session=sess)
    filler = Filler()

    # Show the form
    print(form.to_str(2))

    # Use filler to cache custom callback values, if needed (will be reused later)
    form.fill(filler.callback, fill_optional=True)

    # Show the form with answers
    print(form.to_str(2, include_answer=True))
    print()

    for i in range(10):
        last = time_now()
        print(f'[{asctime()}] Submit {i+1}... ', end='')
        sep = ''
        filled = False
        for _ in range(10):
            # Retry if InfiniteLoop is raised
            try:
                form.fill(filler.callback, fill_optional=True)
                filled = True
                break
            except InfiniteLoop:
                sep = ' '
                print('X', end='')
                sleep(0.1)
            except ValidationError as err:
                # Most probably the default callback failed on an element with a validator.
                print(f'{sep}Failed: {err}')
                sleep(1)
                break

        if not filled:
            continue

        try:
            form.submit(session=sess)
            # You may want to use history emulation:
            #   submission is faster, but it is still experimental
            # form.submit(session=sess, emulate_history=True)
            print(sep + 'OK', end='')
        except ClosedForm:
            print(sep + 'Form is closed')
            break
        except RuntimeError:
            # Incorrect response code or page prediction failed
            print(sep + 'Failed', end='')

        # Poisson distribution for (submissions / timeframe)
        delta = random.expovariate(1 / mean_dt)
        print(f', sleeping for {round(delta)}s')
        sleep(max(0.0, last + delta - time_now()))
コード例 #7
0
 def load_dump(form_type):
     url = getattr(fake_urls.FormUrl, form_type)
     form = Form()
     form.load(url, session=fake_session)
     return form
コード例 #8
0
 def load_form(url):
     form = Form()
     form.load(url, session=session)
     return form