Plone API remove_user from group does not seem to work - plone

I am trying to remove all users from a group using the Plone.Api method (within Plone4).
So I wrote this code:
users = api.user.get_users(groupname="The Test Group")
for user in users:
api.group.remove_user(groupname="The Test Group", username=user.id)
But the api.group.remove_user call does not seem to function. What is the proper way to remove users from a group within plone?
I paused this within my ipdb
This are the results from my calls:
ipdb> api.group.get(groupname=group_name)
<GroupData at /Plone/portal_groupdata/groupname:61fbc50d623142d7887384d70f25358b used for /Plone/acl_users/source_groups>
So far so good, I store this in a variable so I can try this again later (for the group argument).
ipdb> grp = api.group.get(groupname=group_name)
ipdb> api.user.get_users(groupname=group_name)
[<MemberData at /Plone/portal_memberdata/stolas#domain.org used for /Plone/acl_users>]
I notice I get my user from the group. Thus I am really in this group.
ipdb> user.id
'stolas#domain.org'
ipdb> api.group.remove_user(group=grp, username=user.id)
I try the remove call again, and check if my member is still within the group.
ipdb> api.user.get_users(groupname=group_name)
[<MemberData at /Plone/portal_memberdata/stolas#domain.org used for /Plone/acl_users>]
I still am..
Should I reindex security or something like that?
ps.
I also gave with api.env.adopt_roles(['Manager']) a try and the getToolByName(getSite(), 'portal_groups')
method portal_groups.removePrincipalFromGroup everthing rendered to a false.

plone.api uses the group tool to remove group memberships:
portal_groups = portal.get_tool('portal_groups')
portal_groups.removePrincipalFromGroup(user_id, group_id)
I guess your api.user.get_users(groupname="The Test Group") call returns an empty set.
Since you should pass the group name (group ID). Now you pass the group title.
The api.group.remove_user would also accept a group object instead of the group name.
Arguments ``groupname`` and ``group`` are mutually exclusive. You can
either set one or the other, but not both.

As I could not delete it as a user I thought of the following:
with api.env.adopt_roles(['Manager']):
api.user.delete(user=self.context)
parent = self.context.getParentNode()
parent.manage_delObjects([self.context.getId()])
As the user delete might fail I deleted the object as a Manager. This seemd to work without a Hitch.

Related

HFM Extract data to file is resulting in Parent Child error

I am trying to do a simple extract in HFM and I keep getting this error.
"Parent-Child name must be specified for Entity dimension due to value: [Parent Total]
Member found that requires parent name:"
All the members in the extract are valid members, this was verified using a smart view extract
The entity dimension does contain alternate hierarchies, i.e. the member in my extract does have two parents
This extract runs successfully when the expand only selection is selected
This is being done via Workiva-WData
The integration user has this level of access
Any help would be much appreciated.
I have tried running almost every combination of member and expand function available, BASE, ALLMEMBERS, IPARENTS, all result in that error.

id parameter in R simmer package

There are several functions in the R simmer package that have the argument id = 0. Usually the functions are associated with selecting a certain resource (e.g. seize_selected). I haven't been able to find any documentation on what this parameter does other than selection identifier for nested usage. Does anyone know what this means or have a use case for setting this to something other than its default value of 0?
I'm trying to see if it will help me select a coupled resource. For example, if I select "Bar1" resource, then I have to select "Server1" as a related resource. The wording of the reference makes me think this might help, but I'm not sure.
Yes, that's exactly what it is for. If you select a second resource, you lose your previous selection... unless you give it a different id. So, in your case:
... %>%
select("Bar1", id=0) %>%
...
select("Server1", id=1) %>%
...
and then you can use those ids in other activities to refer to those selections.

Adding a user-filled value as well as a pick value for google appmaker

I would like to define a field, where there is a list of allowed values as well as give user the option to type it in. For example, I list a bunch of previous jobs that the applicant can have, plus have them pick other and fill it in as well.
Is it possible to do this with one field or do I need two fields where the user has to type it in? Is there a doc. or sample or tutorial I can look up? Thanks.
Here is a super simple Tags sample:
https://drive.google.com/open?id=0BxtQI4fTAVQqcUx4OUJfQ1JYV2c
To cover your exact use case you just need to:
Add logic to check if record already exists
1.1 If record doesn't exist, then create one
Create relation between records
If you don't care about duplicates in your database, then you can skip step 1 and always do 1.1 and 2.

dynamodb creating a string set

I have a lot of objects with unique IDs. Every object can have several labels associated to it, like this:
123: ['a', 'hello']
456: ['dsajdaskldjs']
789: (no labels associated yet)
I'm not planning to store all objects in DynamoDB, only these sets of labels. So it would make sense to add labels like that:
find a record with (id = needed_id)
if there is one, and it has a set named label_set, add a label to this set
if there is no record with such id, or the existing record doesn't have an attribute named label_set, create a record and an attribute, and initialize the attribute with a set consisting of the label
if I used sets of numbers, I could use just ADD operation of UPDATE command. This command does exactly what I described. However, this does not work with sets of strings:
If no item matches the specified primary key:
ADD— Creates an item with supplied primary key and number (or set of numbers) for the attribute value. Not valid for a string type.
so I have to use a PUT operation with Expected set to {"label_set":{"Exists":false}}, followed (in case it fails) by an ADD operation. These are two operations, and it kinda sucks (since you pay per operation, the costs of this will be 2 times more than they could be).
This limitations seems really weird to me. Why are something what works with numbers sets would not work with string sets? Maybe I'm doing something wrong.
Using many records like (123, 'a'), (123, 'hello') instead of one record per object with a set is not a solutions: I want to get all the values from the set at once, without any scans.
I use string sets from the Java SDK the way you describe all the time and it works for me. Perhaps it has changed? I basically follow the pattern in this doc:
http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_UpdateItem.html
ADD— Only use the add action for numbers or if the target attribute is
a set (including string sets). ADD does not work if the target
attribute is a single string value or a scalar binary value. The
specified value is added to a numeric value (incrementing or
decrementing the existing numeric value) or added as an additional
value in a string set. If a set of values is specified, the values are
added to the existing set. For example if the original set is [1,2]
and supplied value is [3], then after the add operation the set is
[1,2,3], not [4,5]. An error occurs if an Add action is specified for
a set attribute and the attribute type specified does not match the
existing set type.
If you use ADD for an attribute that does not exist, the attribute and
its values are added to the item.
When your set is empty, it means the attribute isn't present. You can still ADD to it. In fact, a pattern that I've found useful is to simply ADD without even checking for the item. If it doesn't exist, it will create a new item using the specified key and create the attribute set with the value(s) I am adding. If the item exists but the attribute doesn't, it creates the attribute set and adds the value(s). If they both exist, it just adds the value(s).
The only piece that caught me up at first was that the value I had to add was a SS (String set) even if it was only one string value. From DynamoDB's perspective, you are always merging sets, even if the existing set is an empty set (missing) or the new set only contains one value.
IMO, from the way you've described your intent, you would be better off not specifying an existing condition at all. You are having to do two steps because you are enforcing two different situations but you are trying to perform the same action in both. So might as well just blindly add the label and let DynamoDB handle the rest.
Maybe you could: (pseudo code)
try:
add_with_update_item(hash_key=42, "label")
except:
element = new Element(hash_key=42, labels=["label"])
element.save()
With this graceful recovery approach, you need 1 call in the general case, 2 otherwise.
You are unable to use sets to do what you want because Dynamo Db doesn't support empty sets. I would suggest just using a string with a custom schema and building the set from that yourself.
To avoid two operations, you can add a "ConditionExpression" to your item.
For example, add this field/value to your item:
"ConditionExpression": "attribute_not_exists(RecordID) and attribute_not_exists(label_set)"
Source documentation.
Edit: I found a really good guide about how to use the conditional statements

How can I get results for a dimension (custom variables), where the value is not set?

I am using custom variables to track order ids. In order to aggregate analytics data into out data warehouse, I want to select a number of metrics with the custom variable as a dimension. However, if I do so, I will not get the entries where the variable is not set (E.g. sessions that didn't result in a sale). I need to get these as well.
Can I write a filter or segment that selects only the entries that doesn't have a particular custom variable? I have tried:
segment=dynamic::ga:customVarValue1==
But that doesn't seem to work (It gives no results back).
Basically I'm looking for the equivalent to where ga:customVarValue1 is null in sql.
In short, it's not possible to get the nullset data, as explained by a Google rep:
For some dimensions, GA uses the default value of (not set).
Custom Variable do not have a default value, so if a hit does not have a
custom variable associated with it, all the other dimensions in the query
are not added to the reports.
The original answer is a little confusing, but when you read between the lines it suggests that they throw out these "empty" values when they run their aggregates.
The "correct" approach, as he explains, is to set a default value for any row you want reported:
If you need to see the (not set) value, you could try sending a default
value for custom variables.
For example if you use visitor level custom vars to track member vs
non-member, you should always set non-member as a default for everybody;
then modify to member once they register.
Details are here: http://groups.google.com/group/google-analytics-data-export-api/browse_thread/thread/cd078ddb26ca18d5?pli=1
I've just had some success solving this by using a Regex to capture users or sessions where the custom dimension has no value. In my case I want to separate logged in and logged out users.
The Regex .+ will capture any non-empty value, so can be used to get the job done.
The filters for my Returning users segment is matches regex: .+ like this:
For the Customer prospects I used: does not match regex: .+ like this:
It's early days, but this appears to be working:

Resources