<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

"""Basic webdriver commands used in all pages.

"""

import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.common.keys import Keys

class Page(object):
    """Basic webdriver commands available to all pages.

    All pages inherit from Page.

    """
    _DEBUG_ERROR = ".exception_value"
    _MULTIPLE_ELS = "More than 1 of this element was found on the page."

    def __init__(self, testsetup):
        self.browser = testsetup.browser  # BROWSER TO USE FOR TESTING
        self.base_url = testsetup.base_url
        self.testcase = testsetup

    def _safe_find(self, element):
        self.wait_for_element_present(element)
        elem = self.browser.find_element_by_css_selector(element)
        return elem

    def quit(self):
        """Quit the browser.

        """
        self.browser.quit()

    def close_browser(self):
        self.browser.close()

    def page_refresh(self):
        self.browser.refresh()

    def page_error(self):
        """Return django debug page error information.

        """
        error_text = None
        if self.is_element_present(self._DEBUG_ERROR):
            error_text = self.get_text_by_css(self._DEBUG_ERROR)
        return [error_text, self.current_url()]

    def current_url(self):
        """Return the current page url.

        """
        return self.browser.current_url

    def handle_js_alert(self, action):
        """Accept or reject js alert.

        """
        try:
            print 'Got an alert dialog'
            time.sleep(2)
            a = self.browser.switch_to_alert()
            if action == "accept":
                a.accept()
            elif action == "reject":
                a.dismiss()
        except:
            self.record_error('failed handling the expected alert')

    def check(self, element):
        """Check the box for the element provided by css selector.

        """
        el = self._safe_find(element)
        if not el.is_selected():
            el.click()

    def uncheck(self, element):
        """Uncheck the box for the element provided by css selector.

        """

        el = self._safe_find(element)
        if el.is_selected():
            el.click()

    def select_option_by_text(self, element, text):
        """Select an option based on text of the css selector.

        """
        select = Select(self._safe_find(element))
        select.select_by_visible_text(text)

    def hover_by_css(self, page_element):
        """Hover over element of provided css selector.

        """
        element = self._safe_find(page_element)
        mouseAction = webdriver.ActionChains(self.browser)
        mouseAction.move_to_element(element).perform()

    def click_item_from_pulldown(self, menu_el, menu_item_el):
        """Open a hover pulldown and choose a displayed item.

        """
        self.browser.implicitly_wait(5)
        menu_element = self._safe_find(menu_el)
        menu_item_element = self._safe_find(menu_item_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_element)
                       .click(menu_item_element)
                       .perform())

    def click_item_after_hover(self, menu_el, menu_item_el):
        """Open a hover pulldown and choose a displayed item.

        """
        self.browser.implicitly_wait(5)
        menu_element = self._safe_find(menu_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_element)
                       #.click(menu_item_element)
                       .perform())
        menu_item_element = self._safe_find(menu_item_el)
        self.wait_for_element_visible(menu_item_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_item_element)
                       .click(menu_item_element)
                       .perform())

    def hover_by_element(self, webdriver_object, page_element):
        """Find the css element below the webdriver element object and hover.

        """
        element = webdriver_object.find_element_by_css_selector(page_element)
        mouse = webdriver.ActionChains(self.browser)
        mouse.move_to_element(element).perform()

    def click_by_css(self, element, wait_for_element=None):
        """click based on the css given.

        kwargs no_wait, then use send keys to no wait for page load.
               wait_for_element, wait for a passed in element to display
        """
        elem = self.wait_for_element_present(element)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def clear_text(self, element):
        """Clear text of css element in form.

        """
        elem = self._safe_find(element)
        elem.clear()

    def click_link_text(self, text, wait_for_element=None):
        """Click link text of the element exists, or fail.

        """
        try:
            elem = self.browser.find_element_by_link_text(text)
        except Exception as e:
            self.record_error(e)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def click_link_partial_text(self, text, wait_for_element=None):
        """Click by partial link text or report error is not present.

        """
        try:
            elem = self.browser.find_element_by_partial_link_text(text)
        except Exception as e:
            self.record_error(e)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def has_link_text(self, text, wait_for_element=None):
        """Return whether or not partial link text is present.
        """
        try:
            elem = self.browser.find_element_by_link_text(text)
            return True
        except NoSuchElementException:
            return False

    def type_by_css(self, element, text):
        """Enter text for provided css selector.

        """
        elem = self.wait_for_element_present(element)
        elem.send_keys(text)

    def type_special_key(self, key_name, element="body"):
        """Type a special key -see selenium/webdriver/common/keys.py.

        ex: ARROR_DOWN, TAB, ENTER, SPACE, DOWN...
        If no element is specified, just send the key press to the body.
        """
        elem = self._safe_find(element)
        elem.send_keys(key_name)

    def get_text_by_css(self, element):
        """Get text of given css selector.

        """
        elem = self.wait_for_element_present(element)
        return elem.text

    def get_size_by_css(self, element):
        """Return dict of height and width of element by css selector.

        """
        elem = self._safe_find(element)
        return elem.size

    def submit_form_text_by_css(self, element, text):
        """Submit form using css selector for form element.

        """
        elem = self._safe_find(element)
        elem.send_keys(text)
        time.sleep(1)
        elem.submit()

    def is_element_present(self, element):
        """Return when an element is found on the page.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        return True

    def count_elements_present(self, element):
        """Return the number of elements (css) found on page.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return 0
        return len(elements_found)

    def is_element_visible(self, element):
        """Return whether element (by css) is visible on the page.

        """
        if not self.is_element_present(element):
            return False
        else:
            return any([e.is_displayed() for e in
                        self.browser.find_elements_by_css_selector(element)])

    def is_unique_text_present(self, element, text):
        """Return whether element (by css) text is unique).

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        else:
            element_text = self.browser.find_element_by_css_selector(
                element).text
            if str(element_text) == text:
                return True
            else:
                return False

    def is_text_present(self, element, text):
        """Return whether element (by css) text is present.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        for elem in elements_found:
            if text == elem.text:
                return True
            else:
                return False

    def verify_text_present(self, element, text):
        """Verify element (by css) text is present.

        """
        elements_found = self.browser.find_elements_by_css_selector(element)
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        else:
            element_text = elements_found[0].text
            if text == element_text:
                return True
            else:
                self.record_error('found:' + element_text +
                                'but was expecting: ' + text)
                return False

    def wait_for_element_present(self, element):
        """Wait for element (by css) present on page, within 20 seconds.

        """
        for i in range(20):
            try:
                time.sleep(1)
                if self.is_element_present(element):
                    return self.browser.find_element_by_css_selector(element)
            except:
                pass
        else:
            self.record_error("Element %s is not present." % element)

    def wait_for_element_not_present(self, element):
        """Wait for element (by css) to disappear on page, within 20 seconds.

        """

        for i in range(20):
            try:
                time.sleep(1)
                if self.is_element_present(element) is False:
                    break
            except:
                pass
        else:
            self.record_error("Element %s is still present." % element)

    def wait_for_text_not_present(self, text):
        """Wait for text to disappear on page, within 20 seconds.

        """
        for i in range(20):
            try:
                time.sleep(1)
                if self.is_text_present(text) is False:
                    break
            except:
                pass
        else:
            self.record_error('The text: %s is still present after 20 seconds' % text)

    def wait_for_element_visible(self, element):
        """Wait for element (by css) visible on page, within 20 seconds.

        """

        for i in range(20):
            time.sleep(1)
            if self.is_element_visible(element):
                break
        else:
            self.record_error('The element %s is not visible after 20 seconds' % element)

    def wait_for_element_not_visible(self, element):
        """Wait for element (by css) to be hidden on page, within 20 seconds.

        """
        for i in range(20):
            try:
                time.sleep(1)
                self.browser.find_elements_by_css_selector(
                    element).is_displayed()
            except:
                break
        else:
            self.record_error('The element: %s is still visible after 20 seconds' % element)

    def get_absolute_url(self, url):
        """Return the full url.

        """
        if url.startswith("http"):
            full_url = url
        else:
            full_url = str(self.base_url) + url
        return full_url

    def get_element_attribute(self, element, html_attribute):
        """Return the attribute of an element (by css).

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            self.record_error("%s does not exist on the page" % element)
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        return elements_found[0].get_attribute(html_attribute)

    def get_elements_list(self, element):
        """Return the list of elements (webdriver objects).

        """
        self.wait_for_element_present(element)
        elements_found = self.browser.find_elements_by_css_selector(element)
        return elements_found

    def get_sub_elements_list(self, parent_el, child_el):
        """If the parent element exists, return a list of the child elements.

        """
        if isinstance(parent_el, basestring):
            if not self.is_element_present(parent_el):
                return None
            else:
                parent_el = self.browser.find_element_by_css_selector(parent_el)
        try:
            print 'looking for %s under %s' % (child_el, parent_el.tag_name)
            child_els = parent_el.find_elements_by_css_selector(child_el)
            return child_els
        except NoSuchElementException:
            print 'Did not find any elements'
            return None

    def open_page(self, url):
        """Open a page by the full url.

        """
        self.browser.get(self.get_absolute_url(url))

    def go_back(self):
        """Go back to previous page.

        """
        self.browser.back()

    def page_down(self, elements):
        """Page down to element (by css).

        elements are a list not a single element to try to page down.
        """
        if not isinstance(elements, basestring):
            for x in elements:
                if self.is_element_present(x):
                    elem = self.browser.find_element_by_css_selector(x)
                    break
        else:
            if self.is_element_present(elements):
                elem = self.browser.find_element_by_css_selector(elements)
        try:
            elem.send_keys("PAGE_DOWN")
        except:
            pass #Stupid but Chrome has page down issues.

    def select_from_chosen(self, ui_elem, values):
        """modified from https://gist.github.com/1768479.

        Given the id and value, select the option from the chozen-styled menu.
        This is a total pain in the ass.
        """

        #Find all the chosen parts and pieces.
        chosen_selects = self.browser.find_elements_by_css_selector(ui_elem)
        select = chosen_selects[0]
        select_id = select.get_attribute("id")
        chosen = self.browser.find_element_by_id(select_id + '_chzn')
        results = chosen.find_elements_by_css_selector(".chzn-results li")

        #Work for either a simple string or a list of options.
        if isinstance(values, basestring):
            values = [values]

        #Choose the chosen ones.
        for value in values:
            found = False
            for result in results:
                if result.text == value:
                    found = True
                    print '##### found it!!! %s' % value
                    break

            #In some cases (team videos tab) it would choose the option after the
            # the one that was specified.  So paging down and not doing the found_el
            # resolves that issue.  However, sometimes the page down gets a
            # MoveTargetOutOfBoundsException - but works the other way. So going to
            # try one then do the other.

            if found:
                try:
                    result.send_keys("PAGE_DOWN")
                except:
                    pass #this is stupid but Chrome won't page down.
                try:
                    result.click()
                except:
                    found_el = chosen.find_element_by_css_selector("input").click()
                    result.click()

    def record_error(self, e=None):
        """
            Records an error.
        """
        if not e:
            e = 'webdriver error' + self.browser.current_url
        print '-------------------'
        print 'Error at ' + self.browser.current_url
        print '-------------------'
        raise ValueError(str(e))

<commit_msg>lower wait time since using implicit_wait<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

"""Basic webdriver commands used in all pages.

"""

import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.common.keys import Keys

class Page(object):
    """Basic webdriver commands available to all pages.

    All pages inherit from Page.

    """
    _DEBUG_ERROR = ".exception_value"
    _MULTIPLE_ELS = "More than 1 of this element was found on the page."

    def __init__(self, testsetup):
        self.browser = testsetup.browser  # BROWSER TO USE FOR TESTING
        self.base_url = testsetup.base_url
        self.testcase = testsetup

    def _safe_find(self, element):
        self.wait_for_element_present(element)
        elem = self.browser.find_element_by_css_selector(element)
        return elem

    def quit(self):
        """Quit the browser.

        """
        self.browser.quit()

    def close_browser(self):
        self.browser.close()

    def page_refresh(self):
        self.browser.refresh()

    def page_error(self):
        """Return django debug page error information.

        """
        error_text = None
        if self.is_element_present(self._DEBUG_ERROR):
            error_text = self.get_text_by_css(self._DEBUG_ERROR)
        return [error_text, self.current_url()]

    def current_url(self):
        """Return the current page url.

        """
        return self.browser.current_url

    def handle_js_alert(self, action):
        """Accept or reject js alert.

        """
        try:
            print 'Got an alert dialog'
            time.sleep(2)
            a = self.browser.switch_to_alert()
            if action == "accept":
                a.accept()
            elif action == "reject":
                a.dismiss()
        except:
            self.record_error('failed handling the expected alert')

    def check(self, element):
        """Check the box for the element provided by css selector.

        """
        el = self._safe_find(element)
        if not el.is_selected():
            el.click()

    def uncheck(self, element):
        """Uncheck the box for the element provided by css selector.

        """

        el = self._safe_find(element)
        if el.is_selected():
            el.click()

    def select_option_by_text(self, element, text):
        """Select an option based on text of the css selector.

        """
        select = Select(self._safe_find(element))
        select.select_by_visible_text(text)

    def hover_by_css(self, page_element):
        """Hover over element of provided css selector.

        """
        element = self._safe_find(page_element)
        mouseAction = webdriver.ActionChains(self.browser)
        mouseAction.move_to_element(element).perform()

    def click_item_from_pulldown(self, menu_el, menu_item_el):
        """Open a hover pulldown and choose a displayed item.

        """
        self.browser.implicitly_wait(5)
        menu_element = self._safe_find(menu_el)
        menu_item_element = self._safe_find(menu_item_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_element)
                       .click(menu_item_element)
                       .perform())

    def click_item_after_hover(self, menu_el, menu_item_el):
        """Open a hover pulldown and choose a displayed item.

        """
        self.browser.implicitly_wait(5)
        menu_element = self._safe_find(menu_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_element)
                       #.click(menu_item_element)
                       .perform())
        menu_item_element = self._safe_find(menu_item_el)
        self.wait_for_element_visible(menu_item_el)
        mouseAction = (webdriver.ActionChains(self.browser)
                       .move_to_element(menu_item_element)
                       .click(menu_item_element)
                       .perform())

    def hover_by_element(self, webdriver_object, page_element):
        """Find the css element below the webdriver element object and hover.

        """
        element = webdriver_object.find_element_by_css_selector(page_element)
        mouse = webdriver.ActionChains(self.browser)
        mouse.move_to_element(element).perform()

    def click_by_css(self, element, wait_for_element=None):
        """click based on the css given.

        kwargs no_wait, then use send keys to no wait for page load.
               wait_for_element, wait for a passed in element to display
        """
        elem = self.wait_for_element_present(element)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def clear_text(self, element):
        """Clear text of css element in form.

        """
        elem = self._safe_find(element)
        elem.clear()

    def click_link_text(self, text, wait_for_element=None):
        """Click link text of the element exists, or fail.

        """
        try:
            elem = self.browser.find_element_by_link_text(text)
        except Exception as e:
            self.record_error(e)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def click_link_partial_text(self, text, wait_for_element=None):
        """Click by partial link text or report error is not present.

        """
        try:
            elem = self.browser.find_element_by_partial_link_text(text)
        except Exception as e:
            self.record_error(e)
        elem.click()
        if wait_for_element:
            self.wait_for_element_present(wait_for_element)

    def has_link_text(self, text, wait_for_element=None):
        """Return whether or not partial link text is present.
        """
        try:
            elem = self.browser.find_element_by_link_text(text)
            return True
        except NoSuchElementException:
            return False

    def type_by_css(self, element, text):
        """Enter text for provided css selector.

        """
        elem = self.wait_for_element_present(element)
        elem.send_keys(text)

    def type_special_key(self, key_name, element="body"):
        """Type a special key -see selenium/webdriver/common/keys.py.

        ex: ARROR_DOWN, TAB, ENTER, SPACE, DOWN...
        If no element is specified, just send the key press to the body.
        """
        elem = self._safe_find(element)
        elem.send_keys(key_name)

    def get_text_by_css(self, element):
        """Get text of given css selector.

        """
        elem = self.wait_for_element_present(element)
        return elem.text

    def get_size_by_css(self, element):
        """Return dict of height and width of element by css selector.

        """
        elem = self._safe_find(element)
        return elem.size

    def submit_form_text_by_css(self, element, text):
        """Submit form using css selector for form element.

        """
        elem = self._safe_find(element)
        elem.send_keys(text)
        time.sleep(1)
        elem.submit()

    def is_element_present(self, element):
        """Return when an element is found on the page.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        return True

    def count_elements_present(self, element):
        """Return the number of elements (css) found on page.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return 0
        return len(elements_found)

    def is_element_visible(self, element):
        """Return whether element (by css) is visible on the page.

        """
        if not self.is_element_present(element):
            return False
        else:
            return any([e.is_displayed() for e in
                        self.browser.find_elements_by_css_selector(element)])

    def is_unique_text_present(self, element, text):
        """Return whether element (by css) text is unique).

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        else:
            element_text = self.browser.find_element_by_css_selector(
                element).text
            if str(element_text) == text:
                return True
            else:
                return False

    def is_text_present(self, element, text):
        """Return whether element (by css) text is present.

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            return False
        for elem in elements_found:
            if text == elem.text:
                return True
            else:
                return False

    def verify_text_present(self, element, text):
        """Verify element (by css) text is present.

        """
        elements_found = self.browser.find_elements_by_css_selector(element)
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        else:
            element_text = elements_found[0].text
            if text == element_text:
                return True
            else:
                self.record_error('found:' + element_text +
                                'but was expecting: ' + text)
                return False

    def wait_for_element_present(self, element, wait_time=5):
        """Wait for element (by css) present on page, within x seconds.

           Settings the default to 5 since we shouldn't have to wait long for
           most things.  Using implicit_wait in webdriver_base so this
           is a multiplied by the implicit wait value.

        """
        for i in range(wait_time):
            try:
                time.sleep(1)
                if self.is_element_present(element):
                    return self.browser.find_element_by_css_selector(element)
            except:
                pass
        else:
            self.record_error("Element %s is not present." % element)

    def wait_for_element_not_present(self, element, wait_time=10):
        """Wait for element (by css) to disappear on page, within 10 seconds.

           Settings the default to 10 since we shouldn't have to wait long for
           most things.  Using implicit_wait in webdriver_base so this
           is a multiplied by the implicit wait value.

        """

        for i in range(wait_time):
            try:
                time.sleep(1)
                if self.is_element_present(element) is False:
                    break
            except:
                pass
        else:
            self.record_error("Element %s is still present." % element)

    def wait_for_text_not_present(self, text):
        """Wait for text to disappear on page, within 20 seconds.

        """
        for i in range(20):
            try:
                time.sleep(1)
                if self.is_text_present(text) is False:
                    break
            except:
                pass
        else:
            self.record_error('The text: %s is still present after 20 seconds' % text)

    def wait_for_element_visible(self, element):
        """Wait for element (by css) visible on page, within 20 seconds.

        """

        for i in range(20):
            time.sleep(1)
            if self.is_element_visible(element):
                break
        else:
            self.record_error('The element %s is not visible after 20 seconds' % element)

    def wait_for_element_not_visible(self, element):
        """Wait for element (by css) to be hidden on page, within 20 seconds.

        """
        for i in range(20):
            try:
                time.sleep(1)
                self.browser.find_elements_by_css_selector(
                    element).is_displayed()
            except:
                break
        else:
            self.record_error('The element: %s is still visible after 20 seconds' % element)

    def get_absolute_url(self, url):
        """Return the full url.

        """
        if url.startswith("http"):
            full_url = url
        else:
            full_url = str(self.base_url) + url
        return full_url

    def get_element_attribute(self, element, html_attribute):
        """Return the attribute of an element (by css).

        """
        try:
            elements_found = self.browser.find_elements_by_css_selector(
                element)
        except NoSuchElementException:
            self.record_error("%s does not exist on the page" % element)
        if len(elements_found) > 1:
            self.record_error(MULTIPLE_ELS % element)
        return elements_found[0].get_attribute(html_attribute)

    def get_elements_list(self, element):
        """Return the list of elements (webdriver objects).

        """
        self.wait_for_element_present(element)
        elements_found = self.browser.find_elements_by_css_selector(element)
        return elements_found

    def get_sub_elements_list(self, parent_el, child_el):
        """If the parent element exists, return a list of the child elements.

        """
        if isinstance(parent_el, basestring):
            if not self.is_element_present(parent_el):
                return None
            else:
                parent_el = self.browser.find_element_by_css_selector(parent_el)
        try:
            print 'looking for %s under %s' % (child_el, parent_el.tag_name)
            child_els = parent_el.find_elements_by_css_selector(child_el)
            return child_els
        except NoSuchElementException:
            print 'Did not find any elements'
            return None

    def open_page(self, url):
        """Open a page by the full url.

        """
        self.browser.get(self.get_absolute_url(url))

    def go_back(self):
        """Go back to previous page.

        """
        self.browser.back()

    def page_down(self, elements):
        """Page down to element (by css).

        elements are a list not a single element to try to page down.
        """
        if not isinstance(elements, basestring):
            for x in elements:
                if self.is_element_present(x):
                    elem = self.browser.find_element_by_css_selector(x)
                    break
        else:
            if self.is_element_present(elements):
                elem = self.browser.find_element_by_css_selector(elements)
        try:
            elem.send_keys("PAGE_DOWN")
        except:
            pass #Stupid but Chrome has page down issues.

    def select_from_chosen(self, ui_elem, values):
        """modified from https://gist.github.com/1768479.

        Given the id and value, select the option from the chozen-styled menu.
        This is a total pain in the ass.
        """

        #Find all the chosen parts and pieces.
        chosen_selects = self.browser.find_elements_by_css_selector(ui_elem)
        select = chosen_selects[0]
        select_id = select.get_attribute("id")
        chosen = self.browser.find_element_by_id(select_id + '_chzn')
        results = chosen.find_elements_by_css_selector(".chzn-results li")

        #Work for either a simple string or a list of options.
        if isinstance(values, basestring):
            values = [values]

        #Choose the chosen ones.
        for value in values:
            found = False
            for result in results:
                if result.text == value:
                    found = True
                    print '##### found it!!! %s' % value
                    break

            #In some cases (team videos tab) it would choose the option after the
            # the one that was specified.  So paging down and not doing the found_el
            # resolves that issue.  However, sometimes the page down gets a
            # MoveTargetOutOfBoundsException - but works the other way. So going to
            # try one then do the other.

            if found:
                try:
                    result.send_keys("PAGE_DOWN")
                except:
                    pass #this is stupid but Chrome won't page down.
                try:
                    result.click()
                except:
                    found_el = chosen.find_element_by_css_selector("input").click()
                    result.click()

    def record_error(self, e=None):
        """
            Records an error.
        """
        if not e:
            e = 'webdriver error' + self.browser.current_url
        print '-------------------'
        print 'Error at ' + self.browser.current_url
        print '-------------------'
        raise ValueError(str(e))

<|endoftext|>


<commit_before># Copyright (c) 2009 gocept gmbh & co. kg
# See also LICENSE.txt

from zeit.content.cp.i18n import MessageFactory as _
import lxml.etree
import lxml.objectify
import rwproperty
import zeit.cms.content.property
import zeit.cms.repository.interfaces
import zeit.cms.syndication.feed
import zeit.cms.syndication.interfaces
import zeit.content.cp.block
import zeit.content.cp.interfaces
import zope.component
import zope.container.interfaces
import zope.interface
import zope.schema

# TeaserList reuses Feed for its "list of ICMSContent" behaviour
class TeaserList(zeit.content.cp.block.Block,
                 zeit.cms.syndication.feed.Feed):

    zope.interface.implementsOnly(
        zeit.content.cp.interfaces.ITeaserList,
        zeit.cms.syndication.interfaces.IFeed,
        zope.container.interfaces.IContained)

    # XXX XSLT must drop these
    _autopilot = zeit.cms.content.property.ObjectPathProperty('.autopilot')
    referenced_cp = zeit.cms.content.property.SingleResource('.referenced_cp')

    # overriden so that super.insert() and updateOrder() work
    @property
    def entries(self):
        return self.xml

    def iterentries(self):
        if self.autopilot:
            repository = zope.component.getUtility(
                zeit.cms.repository.interfaces.IRepository)
            return [repository.getContent(id) for id in self.keys()]
        else:
            return super(TeaserList, self).iterentries()

    def keys(self):
        if self.autopilot:
            return zeit.content.cp.interfaces.ILeadTeasers(self.referenced_cp)
        else:
            return super(TeaserList, self).keys()

    def insert(self, *args, **kw):
        self._forbidden_on_autopilot('insert', *args, **kw)

    def remove(self, *args, **kw):
        self._forbidden_on_autopilot('remove', *args, **kw)

    def updateOrder(self, *args, **kw):
        self._forbidden_on_autopilot('updateOrder', *args, **kw)

    def _forbidden_on_autopilot(self, method, *args, **kw):
        if self.autopilot:
            raise RuntimeError("%s: '%s' is forbidden while on autopilot"
                               % (self, method))
        else:
            return getattr(super(TeaserList, self), method)(*args, **kw)

    @rwproperty.getproperty
    def autopilot(self):
        return self._autopilot

    @rwproperty.setproperty
    def autopilot(self, autopilot):
        if autopilot and self.referenced_cp is None:
            raise ValueError(
                'Cannot activate autopilot without referenced centerpage.')
        if autopilot == self._autopilot:
            return

        # we need to manipulate self.entries, which is only allowed while not
        # on autopilot. Thus we switch the autopilot mode at different times.
        if not autopilot:
            self._autopilot = autopilot
            if hasattr(self.xml, 'xi_include'):
                self.xml.remove(self.xml.xi_include)

            if self.referenced_cp:
                repository = zope.component.getUtility(
                    zeit.cms.repository.interfaces.IRepository)
                for position, id in enumerate(
                    zeit.content.cp.interfaces.ILeadTeasers(
                        self.referenced_cp)):
                    self.insert(position, repository.getContent(id))
        else:
            self.clear()
            # XXX what is the actual syntax for xi:include needed here?
            self.xml.append(lxml.objectify.E.xi_include(
                href=self.referenced_cp.uniqueId))
            self._autopilot = autopilot

    def clear(self):
        if not self.autopilot:
            for entry in self:
                self.remove(entry)

    @rwproperty.getproperty
    def layout(self):
        for layout in zeit.content.cp.layout.LayoutSource():
            if layout.id == self.xml.get('module'):
                return layout

    @rwproperty.setproperty
    def layout(self, layout):
        self.xml.set('module', layout.id)

TeaserListFactory = zeit.content.cp.block.blockFactoryFactory(
    zeit.content.cp.interfaces.IRegion,
    TeaserList, 'teaser', _('List of teasers'))

@zope.component.adapter(zeit.content.cp.interfaces.ICenterPage)
@zope.interface.implementer(zeit.content.cp.interfaces.ILeadTeasers)
def lead_teasers_for_centerpage(cp):
    result = []
    for block in cp['lead'].values():
        if zeit.content.cp.interfaces.ITeaserList.providedBy(block):
            try:
                result.append(iter(block).next().uniqueId)
            except StopIteration:
                pass
    return result
<commit_msg>condingstyle<commit_after># Copyright (c) 2009 gocept gmbh & co. kg
# See also LICENSE.txt

from zeit.content.cp.i18n import MessageFactory as _
import lxml.etree
import lxml.objectify
import rwproperty
import zeit.cms.content.property
import zeit.cms.repository.interfaces
import zeit.cms.syndication.feed
import zeit.cms.syndication.interfaces
import zeit.content.cp.block
import zeit.content.cp.interfaces
import zope.component
import zope.container.interfaces
import zope.interface
import zope.schema

class TeaserList(zeit.content.cp.block.Block,
                 zeit.cms.syndication.feed.Feed):

    # TeaserList reuses Feed for its "list of ICMSContent" behaviour

    zope.interface.implementsOnly(
        zeit.content.cp.interfaces.ITeaserList,
        zeit.cms.syndication.interfaces.IFeed,
        zope.container.interfaces.IContained)

    # XXX XSLT must drop these
    _autopilot = zeit.cms.content.property.ObjectPathProperty('.autopilot')
    referenced_cp = zeit.cms.content.property.SingleResource('.referenced_cp')

    @property
    def entries(self):
        # overriden so that super.insert() and updateOrder() work
        return self.xml

    def iterentries(self):
        if self.autopilot:
            repository = zope.component.getUtility(
                zeit.cms.repository.interfaces.IRepository)
            return [repository.getContent(id) for id in self.keys()]
        else:
            return super(TeaserList, self).iterentries()

    def keys(self):
        if self.autopilot:
            return zeit.content.cp.interfaces.ILeadTeasers(self.referenced_cp)
        else:
            return super(TeaserList, self).keys()

    def insert(self, *args, **kw):
        self._forbidden_on_autopilot('insert', *args, **kw)

    def remove(self, *args, **kw):
        self._forbidden_on_autopilot('remove', *args, **kw)

    def updateOrder(self, *args, **kw):
        self._forbidden_on_autopilot('updateOrder', *args, **kw)

    def _forbidden_on_autopilot(self, method, *args, **kw):
        if self.autopilot:
            raise RuntimeError("%s: '%s' is forbidden while on autopilot"
                               % (self, method))
        else:
            return getattr(super(TeaserList, self), method)(*args, **kw)

    @rwproperty.getproperty
    def autopilot(self):
        return self._autopilot

    @rwproperty.setproperty
    def autopilot(self, autopilot):
        if autopilot and self.referenced_cp is None:
            raise ValueError(
                'Cannot activate autopilot without referenced centerpage.')
        if autopilot == self._autopilot:
            return

        # we need to manipulate self.entries, which is only allowed while not
        # on autopilot. Thus we switch the autopilot mode at different times.
        if not autopilot:
            self._autopilot = autopilot
            if hasattr(self.xml, 'xi_include'):
                self.xml.remove(self.xml.xi_include)

            if self.referenced_cp:
                repository = zope.component.getUtility(
                    zeit.cms.repository.interfaces.IRepository)
                for position, id in enumerate(
                    zeit.content.cp.interfaces.ILeadTeasers(
                        self.referenced_cp)):
                    self.insert(position, repository.getContent(id))
        else:
            self.clear()
            # XXX what is the actual syntax for xi:include needed here?
            self.xml.append(lxml.objectify.E.xi_include(
                href=self.referenced_cp.uniqueId))
            self._autopilot = autopilot

    def clear(self):
        if not self.autopilot:
            for entry in self:
                self.remove(entry)

    @rwproperty.getproperty
    def layout(self):
        for layout in zeit.content.cp.layout.LayoutSource():
            if layout.id == self.xml.get('module'):
                return layout

    @rwproperty.setproperty
    def layout(self, layout):
        self.xml.set('module', layout.id)

TeaserListFactory = zeit.content.cp.block.blockFactoryFactory(
    zeit.content.cp.interfaces.IRegion,
    TeaserList, 'teaser', _('List of teasers'))

@zope.component.adapter(zeit.content.cp.interfaces.ICenterPage)
@zope.interface.implementer(zeit.content.cp.interfaces.ILeadTeasers)
def lead_teasers_for_centerpage(cp):
    result = []
    for block in cp['lead'].values():
        if zeit.content.cp.interfaces.ITeaserList.providedBy(block):
            try:
                result.append(iter(block).next().uniqueId)
            except StopIteration:
                pass
    return result
<|endoftext|>


<commit_before>#
# Copyright (c) 2004-2005 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
import callbacks
from deps import deps
from lib import log
from lib import util
from local import database
from repository import changeset
from repository import repository
from repository.filecontainer import BadContainer
import conaryclient
import os
import sys
import thread

# FIXME client should instantiated once per execution of the command line
# conary client

class UpdateCallback(callbacks.LineOutput, callbacks.UpdateCallback):

    def done(self):
        self._message('')

    def _message(self, text):
        callbacks.LineOutput._message(self, text)

    def update(self):
        self.lock.acquire()
        t = ""

        if self.csText:
            t = self.csText + ' '

        if self.updateText:
	    if self.updateHunk is not None and self.updateHunk[1] != 1:
		if self.csText is None:
		    ofText = " of %d" % self.updateHunk[1]
		else:
		    ofText = ""

		job = "Job %d%s: %s%s" % (self.updateHunk[0],
					  ofText,
					  self.updateText[0].lower(),
					  self.updateText[1:])

            t += self.updateText

	if t and len(t) < 76:
	    t += '...'

        self._message(t)
        self.lock.release()

    def updateMsg(self, text):
        self.updateText = text
        self.update()

    def csMsg(self, text):
        self.csText = text
        self.update()

    def preparingChangeSet(self):
        self.updateMsg("Preparing changeset")

    def resolvingDependencies(self):
        self.updateMsg("Resolving dependencies")

    def updateDone(self):
        self.updateText = None

    def _downloading(self, msg, got, need):
        if got == need:
            self.csText = None
        elif need != 0:
            if self.csHunk is None or self.csHunk[1] == 1 or \
		    not self.updateText:
                self.csMsg("%s (%d%% of %dk)"
                           % (msg, (got * 100) / need, need / 1024))
            else:
                self.csMsg("%s %d of %d (%d%%)"
                           % ((msg,) + self.csHunk + (((got * 100) / need),)))

        self.update()

    def downloadingFileContents(self, got, need):
        self._downloading('Downloading files for changeset', got, need)

    def downloadingChangeSet(self, got, need):
        self._downloading('Downloading', got, need)

    def requestingFileContents(self):
        if self.csHunk is None:
            self.csMsg("Requesting file contents")
        else:
            self.csMsg("Requesting file contents for changeset %d of %d" % self.csHunk)

    def requestingChangeSet(self):
        if self.csHunk is None:
            self.csMsg("Requesting changeset")
        else:
            self.csMsg("Requesting changeset %d of %d" % self.csHunk)

    def creatingRollback(self):
        self.updateMsg("Creating rollback")

    def preparingUpdate(self, troveNum, troveCount):
        self.updateMsg("Preparing update (%d of %d)" %
		      (troveNum, troveCount))

    def restoreFiles(self, size, totalSize):
        if totalSize != 0:
            self.restored += size
            self.updateMsg("Writing %dk of %dk (%d%%)"
                        % (self.restored / 1024 , totalSize / 1024,
                           (self.restored * 100) / totalSize))

    def removeFiles(self, fileNum, total):
        if total != 0:
            self.updateMsg("Removing %d of %d (%d%%)"
                        % (fileNum , total, (fileNum * 100) / total))

    def creatingDatabaseTransaction(self, troveNum, troveCount):
        self.updateMsg("Creating database transaction (%d of %d)" %
		      (troveNum, troveCount))

    def runningPreTagHandlers(self):
        self.updateMsg("Running tag pre-scripts")

    def runningPostTagHandlers(self):
        self.updateMsg("Running tag post-scripts")

    def committingTransaction(self):
        self.updateMsg("Committing database transaction")

    def setChangesetHunk(self, num, total):
        self.csHunk = (num, total)

    def setUpdateHunk(self, num, total):
        self.restored = 0
        self.updateHunk = (num, total)

    def __init__(self):
        callbacks.LineOutput.__init__(self)
        self.restored = 0
        self.csHunk = None
        self.updateHunk = None
        self.csText = None
        self.updateText = None
        self.lock = thread.allocate_lock()

def displayUpdateJobInfo(cs, verbose=False):
    indent = '    '
    new = []
    for x in cs.iterNewTroveList():
        oldVersion = x.getOldVersion()
        newVersion = x.getNewVersion()
        oldFlavor = x.getOldFlavor()
        newFlavor = x.getNewFlavor()
        if newVersion:
            newTVersion = newVersion.trailingRevision()
        if oldVersion:
            oldTVersion = oldVersion.trailingRevision()

        if verbose:
            if newVersion:
                newInfo = '%s[%s]' % (newVersion.asString(),
                                      deps.formatFlavor(newFlavor))
            if oldVersion:
                oldInfo = '%s[%s]' % (oldVersion.asString(),
                                      deps.formatFlavor(oldFlavor))
        else:
            if oldVersion:
                oldInfo = oldTVersion.asString()

            if newVersion:
                newInfo = newTVersion.asString()

        if not oldVersion:
            # if there is no oldVersion, this is a new trove
            new.append(("%s (%s)" % (x.getName(), newInfo), 'N'))
            continue

        if oldVersion.branch() != newVersion.branch():
            kind = 'Br'
            oldInfo = oldVersion.asString()
            newInfo = newVersion.asString()
        elif oldTVersion.getVersion() != newTVersion.getVersion():
            kind = 'V'
        elif oldTVersion.getSourceCount() != \
                                    newTVersion.getSourceCount():
            kind = 'S'
        else:
            kind = 'B'
        if oldFlavor != newFlavor:
            flavors = deps.flavorDifferences([oldFlavor, newFlavor])
            oldFlavor = flavors[oldFlavor]
            newFlavor = flavors[newFlavor]
            if not verbose and oldFlavor:
                oldInfo = '%s[%s]' % (oldInfo, deps.formatFlavor(oldFlavor))
            if not verbose and newFlavor:
                newInfo = '%s[%s]' % (newInfo, deps.formatFlavor(newFlavor))

        new.append(("%s (%s -> %s)" % (x.getName(), oldInfo, newInfo), kind))

    new.sort()
    new = [ "%s %s" % (x[1], x[0]) for x in new ]
    if verbose:
        formatter = lambda x: '%s[%s]' % (x[1].asString(),
                                          deps.formatFlavor(x[2]))
    else:
        formatter = lambda x: x[1].trailingRevision().asString()

    old = []
    old += [ "D %s (%s deleted)" % (x[0], formatter(x))
                                     for x in cs.getOldTroveList() ]
    old.sort()

    if not new and not old:
        print indent + "Nothing is affected by this update."

    if new:
        print indent + ("\n%s" %indent).join(new)

    if old:
        print indent + ("\n%s" %indent).join(old)

def displayUpdateInfo(updJob, verbose=False):
    totalJobs = len(updJob.getChangeSets())
    for num, cs in enumerate(updJob.getChangeSets()):
        if totalJobs > 1:
            print 'Job %d of %d:' %(num + 1, totalJobs)
        displayUpdateJobInfo(cs, verbose)
    return

def doUpdate(cfg, pkgList, replaceFiles = False, tagScript = None,
                                  keepExisting = False, depCheck = True,
                                  depsRecurse = True, test = False,
                                  justDatabase = False, recurse = True,
                                  info = False, updateByDefault = True,
                                  callback = None, split = True,
                                  sync = False):
    if not callback:
        callback = callbacks.UpdateCallback()

    applyList = []

    if type(pkgList) is str:
        pkgList = ( pkgList, )
    for pkgStr in pkgList:
        if os.path.exists(pkgStr) and os.path.isfile(pkgStr):
            try:
                cs = changeset.ChangeSetFromFile(pkgStr)
            except BadContainer, msg:
                # ensure that it is obvious that a file is being referenced
                if pkgStr[0] not in './':
                    pkgStr = './' + pkgStr
                log.error("'%s' is not a valid conary changeset: %s" %
                          (pkgStr, msg))
                sys.exit(1)
            applyList.append(cs)
        else:
            troveSpec = parseTroveSpec(pkgStr)
            if troveSpec[0][0] == '-':
                applyList.append((troveSpec[0], troveSpec[1:],
                                  (None, None), False))
            elif troveSpec[0][0] == '+':
                applyList.append((troveSpec[0], (None, None),
                                  troveSpec[1:], True))
            elif updateByDefault:
                applyList.append((troveSpec[0], (None, None),
                                  troveSpec[1:], True))
            else:
                applyList.append((troveSpec[0], troveSpec[1:],
                                  (None, None), False))

    # dedup
    applyList = set(applyList)
    try:
        _updateTroves(cfg, applyList, replaceFiles = replaceFiles,
                      tagScript = tagScript,
                      keepExisting = keepExisting, depCheck = depCheck,
                      depsRecurse = depsRecurse, test = test,
                      justDatabase = justDatabase, recurse = recurse,
                      info = info, updateByDefault = updateByDefault,
                      callback = callback, split = split, sync = sync)
    except conaryclient.DependencyFailure, e:
        # XXX print dependency errors because the testsuite
        # prefers it
        print e
    except repository.TroveNotFound, e:
        log.error(e)
    except conaryclient.UpdateError, e:
        log.error(e)
    except repository.CommitError, e:
        log.error(e)
    except changeset.PathIdsConflictError, e:
        log.error(e)

def _updateTroves(cfg, applyList, replaceFiles = False, tagScript = None,
                                  keepExisting = False, depCheck = True,
                                  depsRecurse = True, test = False,
                                  justDatabase = False, recurse = True,
                                  info = False, updateByDefault = True,
                                  callback = None, split=True,
                                  sync = False):

    client = conaryclient.ConaryClient(cfg)

    if not info:
	client.checkWriteableRoot()

    (updJob, suggMap) = \
    client.updateChangeSet(applyList, depsRecurse = depsRecurse,
                           resolveDeps = depCheck,
                           keepExisting = keepExisting,
                           test = test, recurse = recurse,
                           updateByDefault = updateByDefault,
                           callback = callback, split = split,
                           sync = sync)

    if info:
        callback.done()
        displayUpdateInfo(updJob)
        return

    if suggMap:
        callback.done()
        print "Including extra troves to resolve dependencies:"
        print "   ",
        items = {}
        for suggList in suggMap.itervalues():
            # remove duplicates
            items.update(dict.fromkeys([(x[0], x[1]) for x in suggList]))

        items = items.keys()
        items.sort()
        print "%s" % (" ".join(["%s(%s)" %
                       (x[0], x[1].trailingRevision().asString())
                       for x in items]))

        keepExisting = False

    client.applyUpdate(updJob, replaceFiles, tagScript, test = test,
                       justDatabase = justDatabase,
                       localRollbacks = cfg.localRollbacks,
                       callback = callback, autoLockList = cfg.lockTroves)

def updateAll(cfg, info = False, depCheck = True, replaceFiles = False,
              depsRecurse = True, test = False, showItems = False):
    client = conaryclient.ConaryClient(cfg)
    updateItems = client.fullUpdateItemList()

    if showItems:
        for (name, version, flavor) in sorted(updateItems, key=lambda x:x[0]):
            if version and flavor:
                print "%s=%s[%s]" % (name, version.asString(),
                                     deps.formatFlavor(flavor))
            elif flavor:
                print "%s[%s]" % (name, deps.formatFlavor(flavor))
            elif version:
                print "%s=%s" % (name, version.asString())
            else:
                print name

        return

    try:
        callback = UpdateCallback()
        _updateTroves(cfg, updateItems, replaceFiles = replaceFiles,
                      depCheck = depCheck, depsRecurse = depsRecurse,
                      test = test, info = info, callback = callback)
    except conaryclient.DependencyFailure, e:
        log.error(e)
    except conaryclient.UpdateError, e:
        log.error(e)
    except repository.CommitError, e:
        log.error(e)
    except changeset.PathIdsConflictError, e:
        log.error(e)

def changeLocks(cfg, troveStrList, lock = True):
    client = conaryclient.ConaryClient(cfg)
    troveList = []
    for item in troveStrList:
        name, ver, flv = parseTroveSpec(item)
        troves = client.db.findTrove(None, (name, ver, flv))
        troveList += troves

    client.lockTroves(troveList, lock = lock)

def parseTroveSpec(specStr):
    if specStr.find('[') > 0 and specStr[-1] == ']':
        specStr = specStr[:-1]
        l = specStr.split('[')
        if len(l) != 2:
            raise TroveSpecError, "bad trove spec %s]" % specStr
        specStr, flavorSpec = l
        flavor = deps.parseFlavor(flavorSpec)
        if flavor is None:
            raise TroveSpecError, "bad flavor [%s]" % flavorSpec
    else:
        flavor = None

    if specStr.find("=") >= 0:
        l = specStr.split("=")
        if len(l) != 2:
            raise TroveSpecError, "too many ='s in %s" %specStr
        name, versionSpec = l
    else:
        name = specStr
        versionSpec = None

    return (name, versionSpec, flavor)

def toTroveSpec(name, versionStr, flavor):
    disp = [name]
    if versionStr:
        disp.extend(('=', versionStr))
    if flavor:
        disp.extend(('[', deps.formatFlavor(flavor), ']'))
    return ''.join(disp)

class TroveSpecError(Exception):

    pass

<commit_msg>fix updateall to use the new update syntax<commit_after>#
# Copyright (c) 2004-2005 rPath, Inc.
#
# This program is distributed under the terms of the Common Public License,
# version 1.0. A copy of this license should have been distributed with this
# source file in a file called LICENSE. If it is not present, the license
# is always available at http://www.opensource.org/licenses/cpl.php.
#
# This program is distributed in the hope that it will be useful, but
# without any waranty; without even the implied warranty of merchantability
# or fitness for a particular purpose. See the Common Public License for
# full details.
#
import callbacks
from deps import deps
from lib import log
from lib import util
from local import database
from repository import changeset
from repository import repository
from repository.filecontainer import BadContainer
import conaryclient
import os
import sys
import thread

# FIXME client should instantiated once per execution of the command line
# conary client

class UpdateCallback(callbacks.LineOutput, callbacks.UpdateCallback):

    def done(self):
        self._message('')

    def _message(self, text):
        callbacks.LineOutput._message(self, text)

    def update(self):
        self.lock.acquire()
        t = ""

        if self.csText:
            t = self.csText + ' '

        if self.updateText:
	    if self.updateHunk is not None and self.updateHunk[1] != 1:
		if self.csText is None:
		    ofText = " of %d" % self.updateHunk[1]
		else:
		    ofText = ""

		job = "Job %d%s: %s%s" % (self.updateHunk[0],
					  ofText,
					  self.updateText[0].lower(),
					  self.updateText[1:])

            t += self.updateText

	if t and len(t) < 76:
	    t += '...'

        self._message(t)
        self.lock.release()

    def updateMsg(self, text):
        self.updateText = text
        self.update()

    def csMsg(self, text):
        self.csText = text
        self.update()

    def preparingChangeSet(self):
        self.updateMsg("Preparing changeset")

    def resolvingDependencies(self):
        self.updateMsg("Resolving dependencies")

    def updateDone(self):
        self.updateText = None

    def _downloading(self, msg, got, need):
        if got == need:
            self.csText = None
        elif need != 0:
            if self.csHunk is None or self.csHunk[1] == 1 or \
		    not self.updateText:
                self.csMsg("%s (%d%% of %dk)"
                           % (msg, (got * 100) / need, need / 1024))
            else:
                self.csMsg("%s %d of %d (%d%%)"
                           % ((msg,) + self.csHunk + (((got * 100) / need),)))

        self.update()

    def downloadingFileContents(self, got, need):
        self._downloading('Downloading files for changeset', got, need)

    def downloadingChangeSet(self, got, need):
        self._downloading('Downloading', got, need)

    def requestingFileContents(self):
        if self.csHunk is None:
            self.csMsg("Requesting file contents")
        else:
            self.csMsg("Requesting file contents for changeset %d of %d" % self.csHunk)

    def requestingChangeSet(self):
        if self.csHunk is None:
            self.csMsg("Requesting changeset")
        else:
            self.csMsg("Requesting changeset %d of %d" % self.csHunk)

    def creatingRollback(self):
        self.updateMsg("Creating rollback")

    def preparingUpdate(self, troveNum, troveCount):
        self.updateMsg("Preparing update (%d of %d)" %
		      (troveNum, troveCount))

    def restoreFiles(self, size, totalSize):
        if totalSize != 0:
            self.restored += size
            self.updateMsg("Writing %dk of %dk (%d%%)"
                        % (self.restored / 1024 , totalSize / 1024,
                           (self.restored * 100) / totalSize))

    def removeFiles(self, fileNum, total):
        if total != 0:
            self.updateMsg("Removing %d of %d (%d%%)"
                        % (fileNum , total, (fileNum * 100) / total))

    def creatingDatabaseTransaction(self, troveNum, troveCount):
        self.updateMsg("Creating database transaction (%d of %d)" %
		      (troveNum, troveCount))

    def runningPreTagHandlers(self):
        self.updateMsg("Running tag pre-scripts")

    def runningPostTagHandlers(self):
        self.updateMsg("Running tag post-scripts")

    def committingTransaction(self):
        self.updateMsg("Committing database transaction")

    def setChangesetHunk(self, num, total):
        self.csHunk = (num, total)

    def setUpdateHunk(self, num, total):
        self.restored = 0
        self.updateHunk = (num, total)

    def __init__(self):
        callbacks.LineOutput.__init__(self)
        self.restored = 0
        self.csHunk = None
        self.updateHunk = None
        self.csText = None
        self.updateText = None
        self.lock = thread.allocate_lock()

def displayUpdateJobInfo(cs, verbose=False):
    indent = '    '
    new = []
    for x in cs.iterNewTroveList():
        oldVersion = x.getOldVersion()
        newVersion = x.getNewVersion()
        oldFlavor = x.getOldFlavor()
        newFlavor = x.getNewFlavor()
        if newVersion:
            newTVersion = newVersion.trailingRevision()
        if oldVersion:
            oldTVersion = oldVersion.trailingRevision()

        if verbose:
            if newVersion:
                newInfo = '%s[%s]' % (newVersion.asString(),
                                      deps.formatFlavor(newFlavor))
            if oldVersion:
                oldInfo = '%s[%s]' % (oldVersion.asString(),
                                      deps.formatFlavor(oldFlavor))
        else:
            if oldVersion:
                oldInfo = oldTVersion.asString()

            if newVersion:
                newInfo = newTVersion.asString()

        if not oldVersion:
            # if there is no oldVersion, this is a new trove
            new.append(("%s (%s)" % (x.getName(), newInfo), 'N'))
            continue

        if oldVersion.branch() != newVersion.branch():
            kind = 'Br'
            oldInfo = oldVersion.asString()
            newInfo = newVersion.asString()
        elif oldTVersion.getVersion() != newTVersion.getVersion():
            kind = 'V'
        elif oldTVersion.getSourceCount() != \
                                    newTVersion.getSourceCount():
            kind = 'S'
        else:
            kind = 'B'
        if oldFlavor != newFlavor:
            flavors = deps.flavorDifferences([oldFlavor, newFlavor])
            oldFlavor = flavors[oldFlavor]
            newFlavor = flavors[newFlavor]
            if not verbose and oldFlavor:
                oldInfo = '%s[%s]' % (oldInfo, deps.formatFlavor(oldFlavor))
            if not verbose and newFlavor:
                newInfo = '%s[%s]' % (newInfo, deps.formatFlavor(newFlavor))

        new.append(("%s (%s -> %s)" % (x.getName(), oldInfo, newInfo), kind))

    new.sort()
    new = [ "%s %s" % (x[1], x[0]) for x in new ]
    if verbose:
        formatter = lambda x: '%s[%s]' % (x[1].asString(),
                                          deps.formatFlavor(x[2]))
    else:
        formatter = lambda x: x[1].trailingRevision().asString()

    old = []
    old += [ "D %s (%s deleted)" % (x[0], formatter(x))
                                     for x in cs.getOldTroveList() ]
    old.sort()

    if not new and not old:
        print indent + "Nothing is affected by this update."

    if new:
        print indent + ("\n%s" %indent).join(new)

    if old:
        print indent + ("\n%s" %indent).join(old)

def displayUpdateInfo(updJob, verbose=False):
    totalJobs = len(updJob.getChangeSets())
    for num, cs in enumerate(updJob.getChangeSets()):
        if totalJobs > 1:
            print 'Job %d of %d:' %(num + 1, totalJobs)
        displayUpdateJobInfo(cs, verbose)
    return

def doUpdate(cfg, pkgList, replaceFiles = False, tagScript = None,
                                  keepExisting = False, depCheck = True,
                                  depsRecurse = True, test = False,
                                  justDatabase = False, recurse = True,
                                  info = False, updateByDefault = True,
                                  callback = None, split = True,
                                  sync = False):
    if not callback:
        callback = callbacks.UpdateCallback()

    applyList = []

    if type(pkgList) is str:
        pkgList = ( pkgList, )
    for pkgStr in pkgList:
        if os.path.exists(pkgStr) and os.path.isfile(pkgStr):
            try:
                cs = changeset.ChangeSetFromFile(pkgStr)
            except BadContainer, msg:
                # ensure that it is obvious that a file is being referenced
                if pkgStr[0] not in './':
                    pkgStr = './' + pkgStr
                log.error("'%s' is not a valid conary changeset: %s" %
                          (pkgStr, msg))
                sys.exit(1)
            applyList.append(cs)
        else:
            troveSpec = parseTroveSpec(pkgStr)
            if troveSpec[0][0] == '-':
                applyList.append((troveSpec[0], troveSpec[1:],
                                  (None, None), False))
            elif troveSpec[0][0] == '+':
                applyList.append((troveSpec[0], (None, None),
                                  troveSpec[1:], True))
            elif updateByDefault:
                applyList.append((troveSpec[0], (None, None),
                                  troveSpec[1:], True))
            else:
                applyList.append((troveSpec[0], troveSpec[1:],
                                  (None, None), False))

    # dedup
    applyList = set(applyList)
    try:
        _updateTroves(cfg, applyList, replaceFiles = replaceFiles,
                      tagScript = tagScript,
                      keepExisting = keepExisting, depCheck = depCheck,
                      depsRecurse = depsRecurse, test = test,
                      justDatabase = justDatabase, recurse = recurse,
                      info = info, updateByDefault = updateByDefault,
                      callback = callback, split = split, sync = sync)
    except conaryclient.DependencyFailure, e:
        # XXX print dependency errors because the testsuite
        # prefers it
        print e
    except repository.TroveNotFound, e:
        log.error(e)
    except conaryclient.UpdateError, e:
        log.error(e)
    except repository.CommitError, e:
        log.error(e)
    except changeset.PathIdsConflictError, e:
        log.error(e)

def _updateTroves(cfg, applyList, replaceFiles = False, tagScript = None,
                                  keepExisting = False, depCheck = True,
                                  depsRecurse = True, test = False,
                                  justDatabase = False, recurse = True,
                                  info = False, updateByDefault = True,
                                  callback = None, split=True,
                                  sync = False):

    client = conaryclient.ConaryClient(cfg)

    if not info:
	client.checkWriteableRoot()

    (updJob, suggMap) = \
    client.updateChangeSet(applyList, depsRecurse = depsRecurse,
                           resolveDeps = depCheck,
                           keepExisting = keepExisting,
                           test = test, recurse = recurse,
                           updateByDefault = updateByDefault,
                           callback = callback, split = split,
                           sync = sync)

    if info:
        callback.done()
        displayUpdateInfo(updJob)
        return

    if suggMap:
        callback.done()
        print "Including extra troves to resolve dependencies:"
        print "   ",
        items = {}
        for suggList in suggMap.itervalues():
            # remove duplicates
            items.update(dict.fromkeys([(x[0], x[1]) for x in suggList]))

        items = items.keys()
        items.sort()
        print "%s" % (" ".join(["%s(%s)" %
                       (x[0], x[1].trailingRevision().asString())
                       for x in items]))

        keepExisting = False

    client.applyUpdate(updJob, replaceFiles, tagScript, test = test,
                       justDatabase = justDatabase,
                       localRollbacks = cfg.localRollbacks,
                       callback = callback, autoLockList = cfg.lockTroves)

def updateAll(cfg, info = False, depCheck = True, replaceFiles = False,
              depsRecurse = True, test = False, showItems = False):
    client = conaryclient.ConaryClient(cfg)
    updateItems = client.fullUpdateItemList()

    applyList = [ (x[0], (None, None), x[1:], True) for x in updateItems ]

    if showItems:
        for (name, version, flavor) in sorted(updateItems, key=lambda x:x[0]):
            if version and flavor:
                print "%s=%s[%s]" % (name, version.asString(),
                                     deps.formatFlavor(flavor))
            elif flavor:
                print "%s[%s]" % (name, deps.formatFlavor(flavor))
            elif version:
                print "%s=%s" % (name, version.asString())
            else:
                print name

        return

    try:
        callback = UpdateCallback()
        _updateTroves(cfg, applyList, replaceFiles = replaceFiles,
                      depCheck = depCheck, depsRecurse = depsRecurse,
                      test = test, info = info, callback = callback)
    except conaryclient.DependencyFailure, e:
        log.error(e)
    except conaryclient.UpdateError, e:
        log.error(e)
    except repository.CommitError, e:
        log.error(e)
    except changeset.PathIdsConflictError, e:
        log.error(e)

def changeLocks(cfg, troveStrList, lock = True):
    client = conaryclient.ConaryClient(cfg)
    troveList = []
    for item in troveStrList:
        name, ver, flv = parseTroveSpec(item)
        troves = client.db.findTrove(None, (name, ver, flv))
        troveList += troves

    client.lockTroves(troveList, lock = lock)

def parseTroveSpec(specStr):
    if specStr.find('[') > 0 and specStr[-1] == ']':
        specStr = specStr[:-1]
        l = specStr.split('[')
        if len(l) != 2:
            raise TroveSpecError, "bad trove spec %s]" % specStr
        specStr, flavorSpec = l
        flavor = deps.parseFlavor(flavorSpec)
        if flavor is None:
            raise TroveSpecError, "bad flavor [%s]" % flavorSpec
    else:
        flavor = None

    if specStr.find("=") >= 0:
        l = specStr.split("=")
        if len(l) != 2:
            raise TroveSpecError, "too many ='s in %s" %specStr
        name, versionSpec = l
    else:
        name = specStr
        versionSpec = None

    return (name, versionSpec, flavor)

def toTroveSpec(name, versionStr, flavor):
    disp = [name]
    if versionStr:
        disp.extend(('=', versionStr))
    if flavor:
        disp.extend(('[', deps.formatFlavor(flavor), ']'))
    return ''.join(disp)

class TroveSpecError(Exception):

    pass

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import six
from .traversal import TraversalPath

class FilterAtom(object):
    """
    Base filter statement
    """
    def __call__(self, resource):
        raise NotImplementedError()

    def any(self, collection):
        return any(self(i) for i in collection)

    def all(self, collection):
        return all(self(i) for i in collection)

class And(FilterAtom):
    def __init__(self, *atoms):
        self._atoms = atoms

    def __add__(self, other):
        if isinstance(other, self.__class__):
            return And(self._atoms + other._atoms)
        raise TypeError("{} not supported for this operation".format(other))

    def __call__(self, resource):
        return all(a(resource) for a in self._atoms)

class Or(FilterAtom):
    def __init__(self, *atoms):
        self._atoms = atoms

    def __add__(self, other):
        if isinstance(other, self.__class__):
            return And(self._atoms + other._atoms)
        raise TypeError("{} not supported for this operation".format(other))

    def __call__(self, resource):
        return any(a(resource) for a in self._atoms)

class FilterComparison(FilterAtom):
    """
    Base class for filter operator atoms
    """
    def __init__(self, field, value, operation=None):
        self.field = TraversalPath.parse(field)
        self.value = value
        self.operation = operation

    def __call__(self, resource):
        try:
            value = self.field.get_value(resource)
        except KeyError:
            return False
        else:
            if self.operation:
                value = self.operation(value)
            return self.compare(value)

    def compare(self, value):
        raise NotImplementedError()

class Equal(FilterComparison):
    def compare(self, value):
        return value == self.value

class NotEqual(FilterComparison):
    def compare(self, value):
        return value != self.value

class LessThan(FilterComparison):
    def compare(self, value):
        return value < self.value

class LessThanOrEqual(FilterComparison):
    def compare(self, value):
        return value <= self.value

class GreaterThan(FilterComparison):
    def compare(self, value):
        return value > self.value

class GreaterThanOrEqual(FilterComparison):
    def compare(self, value):
        return value >= self.value

FILTER_OPERATOR_MAP = {
    "=": Equal, "eq": Equal,
    "!=": NotEqual, "<>": NotEqual, "neq": NotEqual,
    "<": LessThan, "lt": LessThan,
    "<=": LessThanOrEqual, "lte": LessThanOrEqual,
    ">": GreaterThan, "gt": GreaterThan,
    ">=": GreaterThan, "gte": GreaterThan,
    "in": "In",
    "is": "Is"
}

TOKEN_SEPARATORS = ' \n'
START_GROUP = '('
END_GROUP = ')'
STRING_DELIMITERS = '"'

def split_atoms(expression):
    atoms = []
    start_idx = 0
    in_string = False
    for idx, c in enumerate(expression.strip(TOKEN_SEPARATORS)):
        if c in STRING_DELIMITERS:
            if in_string:
                pass

def parse_filter_expression(expression):
    current_atoms = atoms = []
<commit_msg>Allow comparisons to be added<commit_after># -*- coding: utf-8 -*-
import six
from .traversal import TraversalPath

class FilterAtom(object):
    """
    Base filter statement
    """
    def __call__(self, resource):
        raise NotImplementedError()

    def any(self, collection):
        return any(self(i) for i in collection)

    def all(self, collection):
        return all(self(i) for i in collection)

class And(FilterAtom):
    def __init__(self, *atoms):
        self._atoms = atoms

    def __add__(self, other):
        if isinstance(other, self.__class__):
            return And(self._atoms + other._atoms)
        elif isinstance(other, FilterComparison):
            self._atoms += other
            return self
        raise TypeError("{} not supported for this operation".format(other))

    def __call__(self, resource):
        return all(a(resource) for a in self._atoms)

class Or(FilterAtom):
    def __init__(self, *atoms):
        self._atoms = atoms

    def __add__(self, other):
        if isinstance(other, self.__class__):
            return Or(self._atoms + other._atoms)
        elif isinstance(other, FilterComparison):
            self._atoms += other
            return self
        raise TypeError("{} not supported for this operation".format(other))

    def __call__(self, resource):
        return any(a(resource) for a in self._atoms)

class FilterComparison(FilterAtom):
    """
    Base class for filter operator atoms
    """
    def __init__(self, field, value, operation=None):
        self.field = TraversalPath.parse(field)
        self.value = value
        self.operation = operation

    def __call__(self, resource):
        try:
            value = self.field.get_value(resource)
        except KeyError:
            return False
        else:
            if self.operation:
                value = self.operation(value)
            return self.compare(value)

    def compare(self, value):
        raise NotImplementedError()

class Equal(FilterComparison):
    def compare(self, value):
        return value == self.value

class NotEqual(FilterComparison):
    def compare(self, value):
        return value != self.value

class LessThan(FilterComparison):
    def compare(self, value):
        return value < self.value

class LessThanOrEqual(FilterComparison):
    def compare(self, value):
        return value <= self.value

class GreaterThan(FilterComparison):
    def compare(self, value):
        return value > self.value

class GreaterThanOrEqual(FilterComparison):
    def compare(self, value):
        return value >= self.value

FILTER_OPERATOR_MAP = {
    "=": Equal, "eq": Equal,
    "!=": NotEqual, "<>": NotEqual, "neq": NotEqual,
    "<": LessThan, "lt": LessThan,
    "<=": LessThanOrEqual, "lte": LessThanOrEqual,
    ">": GreaterThan, "gt": GreaterThan,
    ">=": GreaterThan, "gte": GreaterThan,
    "in": "In",
    "is": "Is"
}

TOKEN_SEPARATORS = ' \n'
START_GROUP = '('
END_GROUP = ')'
STRING_DELIMITERS = '"'

def split_atoms(expression):
    atoms = []
    start_idx = 0
    in_string = False
    for idx, c in enumerate(expression.strip(TOKEN_SEPARATORS)):
        if c in STRING_DELIMITERS:
            if in_string:
                pass

def parse_filter_expression(expression):
    current_atoms = atoms = []
<|endoftext|>