def invoke(self, controller, selection):

        target = selection[0]
        consumer = Consumer(target.app_id, target.app_secret)

        def request(client, *args, **kwargs):
            response, body = client.request(*args, **kwargs)
            if response["status"] != "200":
                raise TwitterAPIError(body)
            return body

        try:
            oauth_token = cherrypy.request.params.get("oauth_token")
            oauth_verifier = cherrypy.request.params.get("oauth_verifier")
            oauth_secret_session_key = "twitter_auth.%s.oauth_secret" % self.id

            if not oauth_token or not oauth_verifier:
                # Obtain a request token
                client = Client(consumer)

                location = Location.get_current(relative=False)
                location.query_string["item_action"] = self.id
                callback = quote_plus(str(location))

                body = request(
                    client, "https://api.twitter.com/oauth/request_token"
                    "?oauth_callback=" + callback, "GET")
                data = dict(parse_qsl(body))
                session[oauth_secret_session_key] = data["oauth_token_secret"]

                # Redirect the user to the login form
                auth_url = ("https://api.twitter.com/oauth/authorize?"
                            "oauth_token=%s"
                            "&oauth_callback=%s" %
                            (data["oauth_token"], callback))
                raise cherrypy.HTTPRedirect(auth_url)
            else:
                token = Token(oauth_token, session[oauth_secret_session_key])
                token.set_verifier(oauth_verifier)
                client = Client(consumer, token)
                body = request(client,
                               'https://api.twitter.com/oauth/access_token',
                               "POST")
                data = dict(parse_qsl(body))
                target.auth_token = data["oauth_token"]
                target.auth_secret = data["oauth_token_secret"]
                datastore.commit()

        except TwitterAPIError, ex:
            notify_user(translations(ex), category="error", transient=False)
Example #2
0
    def _load(self):

        from woost.extensions.countries import country, strings

        now = time()

        if self.last_update is None \
        or now - self.last_update >= self.update_frequency * SECONDS_IN_A_DAY:
            try:
                self.update_country_list()
            except:
                pass
            else:
                self.last_update = now
                datastore.commit()
Example #3
0
    def submit(self):

        if self.email or self.hash:
            # Checking hash code
            if generate_confirmation_hash(self.email) == self.hash:
                instance = User.get_instance(email=self.email)
                if instance:
                    # Confirming and enabling user instance
                    instance.set("confirmed_email", True)
                    instance.set("enabled", True)
                    self.confirmed = True
                    datastore.commit()

                    # Autologin after confirmation
                    if self.autologin:
                        self.context["cms"].authentication.set_user_session(
                            instance)
Example #4
0
    def test_after_modify_batched(self):

        from cocktail.persistence import datastore
        from woost.models import ModifyTrigger, Item, User

        # Declare the trigger
        trigger, response_log = self.make_trigger(ModifyTrigger,
                                                  execution_point="after",
                                                  batch_execution=True)

        # Create two items and initialize them. This shouldn't trigger any
        # response, since modifications happen before items are inserted.
        item1 = Item()
        item1.qname = "foo"
        item1.insert()
        item2 = Item()
        item2.global_id = "x1"
        item2.insert()
        datastore.commit()
        assert not response_log

        # Modify the inserted items, but abort the transaction. Again, this
        # shouldn't trigger any response.
        item1.qname = "bar"
        item2.global_id = "x2"
        datastore.abort()
        assert not response_log

        # Modify the inserted items and commit the transaction. This should
        # trigger the response just once.
        item1.qname = "spam"
        item2.global_id = "x3"
        datastore.commit()

        assert len(response_log) == 1
        response = response_log[0]
        assert response["trigger"] is trigger
        assert response["items"] == set([item1, item2])
        assert response["context"]["modified_members"] == {
            item1: set([(Item.qname, None)]),
            item2: set([(Item.global_id, None)])
        }
        assert response["user"] is self.user
        assert response["batch"]
Example #5
0
    def invoke(self, controller, selection):
        clipboard = get_block_clipboard_contents()

        if not clipboard:
            notify_user(
                translations("woost.block_clipboard.empty"),
                "error"
            )
        else:
            try:
                block = Block.require_instance(clipboard["block"])
                src_parent = Item.require_instance(clipboard["block_parent"])
                src_slot = type(src_parent).get_member(clipboard["block_slot"])
            except:
                notify_user(
                    translations("woost.block_clipboard.error"),
                    "error"
                )
            else:
                # Remove the block from the source location
                if clipboard["mode"] == "cut":
                    if isinstance(src_slot, schema.Reference):
                        src_parent.set(src_slot, None)
                    elif isinstance(src_slot, schema.Collection):
                        src_collection = src_parent.get(src_slot)
                        schema.remove(src_collection, block)
                # Or copy it
                elif clipboard["mode"] == "copy":
                    block = block.create_copy()
                    block.insert()

                # Add the block to its new position
                add_block(
                    block, 
                    controller.block_parent,
                    controller.block_slot,
                    positioning = self.block_positioning,
                    anchor = controller.block
                )

                datastore.commit()
                del session[BLOCK_CLIPBOARD_SESSION_KEY]
                focus_block(block)
Example #6
0
                        def batched_response(successful, responses):
                            if successful:
                                try:
                                    for response in responses:
                                        response.execute(
                                            trigger_targets,
                                            user,
                                            batch = True,
                                            modified_members = modified_members,
                                            **context
                                        )

                                    datastore.commit()

                                except Exception, ex:
                                    warn("The following exception was raised "
                                         "by a deferred trigger response:")
                                    print_exc()
                                    datastore.abort()
    def submit(self): 
        FormControllerMixin.submit(self)
        
        export_events = []
        tracker = StatusTracker()

        @when(tracker.file_processed)
        def handle_file_processed(event):
            if event.status == "failed":
                event.error_handled = True
            export_events.append(event)

        form = self.form_data

        user = get_current_user()
        user.require_permission(
            ExportationPermission,
            destination = form["destination"]
        )
        
        destination = form["destination"]
        snapshoter = form["snapshoter"]

        context = self.form_data.copy()

        exporter_context = destination.export(
            snapshoter,
            self.selection,
            update_only = form["update_only"],
            status_tracker = tracker,
            context = context
        )

        # View class
        self.view_class = destination.view_class(exporter_context)
        
        self.output["export_events"] = export_events
        self.output.update(
            **destination.output(exporter_context)
        )

        datastore.commit()
Example #8
0
    def invoke(self, controller, selection):

        collection = controller.block_parent.get(controller.block_slot)
        
        try:
            index = collection.index(selection[0])
        except ValueError:
            index = None        

        schema.remove(collection, selection[0])
        datastore.commit()

        # Focus the block that was nearest to the removed block
        if index is None or not collection:
            adjacent_block = controller.block_parent
        elif index > 0:
            adjacent_block = collection[index - 1]
        else:
            adjacent_block = collection[0]
        
        focus_block(adjacent_block)
Example #9
0
    def test_after_insert_batched(self):

        from cocktail.persistence import datastore
        from woost.models import InsertTrigger, Item

        # Declare the trigger
        trigger, response_log = self.make_trigger(InsertTrigger,
                                                  execution_point="after",
                                                  batch_execution=True)

        # Insert new items, but abort the transaction
        # (the trigger shouldn't be called)
        item1 = Item()
        item1.insert()
        assert not response_log

        item2 = Item()
        item2.insert()
        assert not response_log

        datastore.abort()
        assert not response_log

        # Create and insert two items, and commit the transaction. The response
        # should be triggered just once.
        item1 = Item()
        item1.insert()
        item2 = Item()
        item2.insert()
        datastore.commit()

        assert len(response_log) == 1

        response = response_log[0]
        assert response["trigger"] is trigger
        assert response["items"] == set([item1, item2])
        assert response["user"] is self.user
        assert response["batch"]
    def submit(self):

        self.imported_files = []

        file = self.form_data["upload"]["file"]
        zip_file = ZipFile(file)

        upload_path = app.path("upload")
        temp_dir = mkdtemp()

        try:
            with changeset_context(get_current_user()):
                for file_path in zip_file.namelist():

                    file_name = os.path.basename(file_path)

                    # Skip directories
                    if not file_name:
                        continue

                    source = zip_file.open(file_path)
                    temp_file = os.path.join(temp_dir, file_name)
                    dest = open(temp_file, "wb")
                    copyfileobj(source, dest)
                    source.close()
                    dest.close()

                    try:
                        imported_file = File.from_path(temp_file, upload_path)
                        imported_file.insert()
                        self.imported_files.append(imported_file)
                    finally:
                        os.remove(temp_file)

            datastore.commit()
        finally:
            os.rmdir(temp_dir)
Example #11
0
    def test_edit(self):

        datastore.sync()
        container = EditTestModel()
        container.description = "test_edit container"

        part = EditTestModel()
        part.description = "test_edit part"
        container.part = part

        container.insert()
        datastore.commit()

        browser.open("/en/cms/content/%d/fields" % container.id)
        admin_login()

        assert not browser.is_element_present(
            "css=.part_field .control .select")
        assert not browser.is_element_present("css=.part_field .control .new")
        assert not browser.is_element_present(
            "css=.part_field .control .unlink")
        assert browser.get_value("edited_item_part") == str(part.id)

        browser.click("css=.part_field .control .edit")
        browser.wait_for_page_to_load(10000)

        browser.type("edited_item_description", "modified test_edit part")
        browser.click("css=.save_action")
        browser.wait_for_page_to_load(10000)

        browser.click("css=.cancel_action")
        browser.wait_for_page_to_load(10000)

        datastore.sync()
        assert browser.get_value("edited_item_part") == str(part.id)
        assert part.description == "modified test_edit part"
Example #12
0
    def test_modify_batched_order(self):

        from cocktail.persistence import datastore
        from woost.models import ModifyTrigger, Item, User

        trigger, response_log = self.make_trigger(
            ModifyTrigger,
            execution_point="after",
            batch_execution=True,
            matching_members=["woost.models.item.Item.global_id"])

        # Modifying a member that is not covered by the trigger should alter
        # the context passed to responses, even if it is modified before the
        # member that actions the response
        item = Item()
        item.insert()
        item.qname = "foo"
        item.global_id = "x1"
        datastore.commit()

        response = response_log[0]
        assert response["context"]["modified_members"] == {
            item: set([(Item.qname, None), (Item.global_id, None)])
        }
Example #13
0
    def test_after_delete_batched(self):

        from cocktail.persistence import datastore
        from woost.models import DeleteTrigger, Item

        # Declare the trigger
        trigger, response_log = self.make_trigger(DeleteTrigger,
                                                  execution_point="after",
                                                  batch_execution=True)

        # Create and insert two items
        item1 = Item()
        item1.insert()
        item2 = Item()
        item2.insert()
        datastore.commit()

        # Delete the items, but abort the transaction. This shouldn't trigger
        # the response.
        item1.delete()
        item2.delete()
        datastore.abort()
        assert not response_log

        # Delete the inserted items and commit the transaction. This should
        # trigger the response just once.
        item1.delete()
        item2.delete()
        datastore.commit()

        assert len(response_log) == 1
        response = response_log[0]
        assert response["trigger"] is trigger
        assert response["items"] == set([item1, item2])
        assert response["user"] is self.user
        assert response["batch"]
Example #14
0
    def test_after_modify(self):

        from cocktail.persistence import datastore
        from woost.models import ModifyTrigger, Item

        # Declare the trigger
        trigger, response_log = self.make_trigger(ModifyTrigger,
                                                  execution_point="after",
                                                  batch_execution=False)

        # Create an item and initialize it. This shouldn't trigger any
        # response, since modifications happen before the item is inserted.
        item = Item()
        item.qname = "foo"
        item.insert()
        datastore.commit()
        assert not response_log

        # Modify the inserted item, but abort the transaction. Again, this
        # shouldn't trigger any response.
        item.qname = "bar"
        datastore.abort()
        assert not response_log

        # Modify the inserted item and commit the transaction. This should
        # trigger the response.
        item.qname = "spam"
        datastore.commit()

        assert len(response_log) == 1
        response = response_log[0]
        assert response["trigger"] is trigger
        assert response["items"] == [item]
        assert response["context"]["member"] is Item.qname
        assert response["user"] is self.user
        assert not response["batch"]
Example #15
0
 def invoke(self, controller, selection):
     Configuration.instance.common_blocks.append(selection[0])
     datastore.commit()
     focus_block(selection[0])
Example #16
0
        def _process_comments(event):

            # Comments variables initialization
            comments_user_collection = None
            comments_schema = None
            comment_errors = None
            comment_data = {}

            controller = event.source
            comment_model = \
                resolve(getattr(controller, "comment_model", Comment))
            publishable = controller.context["publishable"]
            user = get_current_user()

            if publishable is not None and publishable.allow_comments:

                # Comments collection
                comments_user_collection = UserCollection(comment_model)
                comments_user_collection.allow_type_selection = False
                comments_user_collection.allow_filters = False
                comments_user_collection.allow_language_selection = False
                comments_user_collection.allow_member_selection = False
                comments_user_collection.params.prefix = "comments_"
                comments_user_collection.base_collection = publishable.comments

                # Show the last comments page if not specified
                if "comments_page" not in cherrypy.request.params:
                    div, mod = divmod(len(comments_user_collection.subset),
                                      comments_user_collection.page_size)
                    comments_page = div - 1 if not mod and div != 0 else div
                    cherrypy.request.params.update(
                        comments_page=str(comments_page))

                # Adapting the comments model
                comments_schema = CommentsExtension.instance._adapt_comments_schema(
                    comment_model)

                if user.anonymous \
                and getattr(CommentsExtension.instance, "captcha_enabled", False):
                    comments_schema.add_member(ReCaptcha("captcha"))

                # Insert a new comment
                if cherrypy.request.method == "POST" \
                and "post_comment" in cherrypy.request.params:

                    with changeset_context(user):
                        get_parameter(comments_schema,
                                      target=comment_data,
                                      errors="ignore")

                        comment_errors = schema.ErrorList(
                            comments_schema.get_errors(comment_data))

                        if not comment_errors:
                            comment = comment_model()

                            adapter = CommentsExtension.instance._create_comments_adapter(
                                comment_model)
                            adapter.import_object(
                                comment_data,
                                comment,
                                source_schema=comments_schema,
                                target_schema=comment_model)

                            comment.publishable = publishable
                            user.require_permission(CreatePermission,
                                                    target=comment)

                            comment.insert()
                            datastore.commit()
                            CommentsExtension.instance._after_process_comments(
                                comment)
                else:
                    comment_errors = schema.ErrorList([])

            # Update the output
            controller.output.update(
                comments_user_collection=comments_user_collection,
                comments_schema=comments_schema,
                comment_errors=comment_errors,
                comment_data=comment_data)
Example #17
0
    def save_item(self):

        for i in range(self.MAX_TRANSACTION_ATTEMPTS):
            user = get_current_user()
            stack_node = self.stack_node
            item = stack_node.item
            is_new = not item.is_inserted
            changeset = None

            with restricted_modification_context(
                item, 
                user, 
                member_subset = set(stack_node.form_schema.members())
            ):
                with changeset_context(author = user) as changeset:
                    self._apply_changes(item)
            try:
                datastore.commit()
            except ConflictError:
                datastore.abort()
                datastore.sync()
            else:
                break

        change = changeset.changes.get(item.id) if changeset else None

        # Edit stack event
        stack_node.committed(
            user = user,
            changeset = changeset
        )

        # Application-wide event
        if change is not None:
            self.context["cms"].item_saved(
                item = item,
                user = user,
                is_new = is_new,
                change = change
            )

        # User notification
        stack_node.item_saved_notification(is_new, change)

        # A new item was created
        if is_new:

            # The edit operation was the root of the edit stack; redirect the
            # browser to the new item
            if len(self.edit_stack) == 1:
                if self.edit_stack.root_url:
                    self.edit_stack.go_back()
                else:
                    raise cherrypy.HTTPRedirect(
                        self.edit_uri(item)
                    )

            # The edit operation was nested; relate the created item to its
            # owner, and redirect the browser to the owner
            elif isinstance(stack_node.parent_node, RelationNode):
                member = stack_node.parent_node.member
                parent_edit_node = stack_node.get_ancestor_node(EditNode)
                parent_edit_node.relate(member, item)
                self.edit_stack.go(-3)

        if stack_node.parent_node is None and self.edit_stack.root_url:
            self.edit_stack.go_back()
Example #18
0
 def remove_produced_member(self):
     model = self.get_produced_member()
     if model is not None:
         model.select().delete_items()
         datastore.commit()
         self.base_model.remove_derived_schema(model)
Example #19
0
from cocktail.persistence import datastore
from woost.models import File
import _PROJECT_NAME_


def main():

    params = argv[1:]

    if not params:
        print "Usage: %s filelist" % argv[0]
        exit(1)

    for param in params:
        for path in glob(param):
            print "Importing " + styled(path, style="bold") + "...",
            try:
                file = File.from_path(
                    path, resource_filename("_PROJECT_NAME_", "upload"))
                file.insert()
            except Exception, ex:
                print styled(str(ex), "red")
            else:
                print styled("File #" + str(file.id), "green")

    datastore.commit()


if __name__ == "__main__":
    main()
Example #20
0
 def commit_order_payment(event):
     datastore.commit()
    def invoke(self, controller, selection):

        publication_target = selection[0]
        code = cherrypy.request.params.get("code")
        error = cherrypy.request.params.get("error")
        error_reason = cherrypy.request.params.get("error_reason")
        error_description = cherrypy.request.params.get("error_description")

        # Authorization failed
        if error:
            notify_user(translations(
                "woost.extensions.facebookauthentication."
                "fbpublish_auth.error", ),
                        category="error",
                        transient=False)

        # Authorization successful
        elif code:
            location = Location.get_current(relative=False)
            del location.query_string["code"]

            auth_url = ("https://graph.facebook.com/oauth/access_token?"
                        "client_id=%s"
                        "&redirect_uri=%s"
                        "&client_secret=%s"
                        "&code=%s" %
                        (publication_target.app_id, quote_plus(str(location)),
                         publication_target.app_secret, code))
            response = urlopen(auth_url)
            response_status = response.getcode()
            response_body = response.read()

            if response_status < 200 or response_status > 299:
                notify_user(translations(
                    "woost.extensions.facebookauthentication."
                    "fbpublish_auth.oauth_error",
                    response=response_body),
                            category="error",
                            transient=False)
                return

            auth_token = response_body.split("&")[0].split("=")[1]

            # Facebook pages require an additional authentication step
            fb_page_id = cherrypy.request.params.get("fb_page")

            if fb_page_id:
                accounts_url = (
                    "https://graph.facebook.com/%s/accounts?access_token=%s" %
                    (publication_target.administrator_id, auth_token))
                response_data = urlopen(accounts_url).read()
                json = loads(response_data)

                for account in json["data"]:
                    if account["id"] == fb_page_id:
                        auth_token = account["access_token"]
                        break
                else:
                    auth_token = None

            publication_target.auth_token = auth_token
            datastore.commit()

            notify_user(translations("woost.extensions.facebookauthentication."
                                     "fbpublish_auth.success"),
                        category="success")

        # Begin authorization request
        else:
            # Determine if the selected graph URL is a Facebook Page
            graph_url = "http://graph.facebook.com/%s?metadata=1" \
                      % publication_target.graph_object_id
            response_data = urlopen(graph_url).read()
            json = loads(response_data)
            fb_page_id = json["metadata"]["type"] == "page" and json["id"]

            location = Location.get_current(relative=False)
            location.query_string["item_action"] = self.id

            permissions = "publish_stream,offline_access,user_photos"

            if fb_page_id:
                location.query_string["fb_page"] = fb_page_id
                permissions += ",manage_pages"

            auth_url = ("https://www.facebook.com/dialog/oauth?"
                        "client_id=%s"
                        "&redirect_uri=%s"
                        "&scope=%s" % (publication_target.app_id,
                                       quote_plus(str(location)), permissions))
            raise cherrypy.HTTPRedirect(auth_url)