From b5f5291e14ca0521d97cc63c02e35d424e20be05 Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Sat, 11 Nov 2023 17:11:18 -0800 Subject: [PATCH] Added options to `gam report ` `addcsvdata ` `shownoactivities` --- docs/GamUpdates.md | 12 +++++- docs/How-to-Upgrade-from-Standard-GAM.md | 4 +- docs/Reports.md | 45 ++++++++++++++++++++ docs/Users-Gmail-Delegates.md | 17 ++++++++ docs/Version-and-Help.md | 12 +++--- src/GamCommands.txt | 1 + src/GamUpdate.txt | 10 +++++ src/gam/__init__.py | 54 ++++++++++++++++++++---- 8 files changed, 138 insertions(+), 17 deletions(-) diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index dc16294e..b9430c26 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,7 +10,15 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation -Updated `gam import|insert message` to allow `replace ` as documented. +### 6.65.08 + +Added option `addcsvdata ` to `gam report ` that adds +additional columns of data to the CSV file output. + +Added option `shownoactivities` to `gam report ` that causes GAM to display +a row with a key value of `NoActivities` when there are no activities to report. + +For example, to find Shared Drives with no activity, see: https://github.com/taers232c/GAMADV-XTD3/wiki/Reports#find-shared-drives-with-no-activity ### 6.65.07 @@ -47,6 +55,8 @@ in the last 30 days. gam user user@domain.com print messages querytime30d -30d query "after:#querytime30d# is:unread" ``` +Updated `gam import|insert message` to allow `replace ` as documented. + Updated non-owner permission handling in `gam copy|move drivefile`. ### 6.65.04 diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index b45c7986..a1e9c2eb 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found -GAMADV-XTD3 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.10.8 64-bit final MacOS High Sierra 10.13.6 x86_64 @@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt. C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt C:\GAMADV-XTD3>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAMADV-XTD3 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.0 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Reports.md b/docs/Reports.md index 4ecf2ce0..02b47f22 100644 --- a/docs/Reports.md +++ b/docs/Reports.md @@ -3,6 +3,7 @@ - [Collections of Users](Collections-of-Users) - [Definitions](#definitions) - [Activity reports](#activity-reports) + - [Find Shared Drives with no activity](#find-shared-drives-with-no-activity) - [Customer and user reports parameters](#customer-and-user-reports-parameters) - [Customer usage reports](#customer-usage-reports) - [Customer reports](#customer-reports) @@ -59,6 +60,7 @@ gam report [todrive *] [groupidfilter ] [maxactivities ] [maxresults ] [countsonly [summary] [eventrowfilter]] + (addcsvdata )* [shownoactivities] ``` Select the application with ``. @@ -101,6 +103,12 @@ Limit the total number of activites. Limit the number of activities downloaded per API call; infrequently used. * `maxresults ` +Add additional columns of data from the command line to the output. +* `addcsvdata ` + +Display a row with a key value of `NoActivities` when there are no activities to report. +* `shownoactivities` + By default, individual event details are displayed, these options modify what's displayed. * `countsonly` - Limit the display to the number of occurences of each event for each user * `countsonly summary` - Limit the display to the number of occurences of each event summarized across all users @@ -121,6 +129,43 @@ Number of files summarized across all users ``` gam config csv_output_row_filter "doc_title:regex:\.xyz" report drive event create yesterday countsonly summary eventrowfilter ``` +## Find Shared Drives with no activity + +Remember that activity events are only available for the past 180 days. + +Get Shared Drives ID and Name +``` +gam redirect csv ./SharedDrives.csv print shareddrives fields id,name +``` +Options: +* `maxactivities 1` - Limits the number of activities displayed for Shared Drives with activity. +* `shownoactivities` - Displays a row for Shared Drives with no activity. +* `addcsvdata shared_drive_id "~id"` adds the Shared Drive ID to the output. +* `addcsvdata shared_drive_name "~name"` adds the Shared Drive name to the output. + +Get activities with minimal activty data. +``` +gam config csv_output_header_filter "name,id.time,shared_drive_id,shared_drive_name" redirect csv ./SharedDrivesActivity.csv multiprocess redirect stderr - multiprocess csv SharedDrives.csv gam report drive filter "shared_drive_id==~~id~~" maxactivities 1 shownoactivities addcsvdata shared_drive_id "~id" addcsvdata shared_drive_name "~name" + +Example output from SharedDrivesActivity.csv: + +name,id.time,shared_drive_id,shared_drive_name +NoActivities,,0AERPpMc23znvUkPXYZ,Shared Drive 1 +view,2023-10-18T21:27:51-07:00,0AMhgLk82dhsuUkPXYZ,Shared Drive 2 +edit,2023-09-05T15:27:01-07:00,0AM8lpdkkJaKYUkPXYZ,Shared Drive 3 +``` + +Get activities with full activty data. +``` +gam redirect csv ./SharedDrivesActivity.csv multiprocess redirect stderr - multiprocess csv SharedDrives.csv gam report drive filter "shared_drive_id==~~id~~" maxactivities 1 shownoactivities addcsvdata shared_drive_id "~id" addcsvdata shared_drive_name "~name" + +Example output from SharedDrivesActivity.csv: + +name,actor.callerType,actor.email,actor.key,actor.profileId,actor_is_collaborator_account,added_role,billable,destination_folder_id,destination_folder_title,doc_id,doc_title,doc_type,id.applicationName,id.customerId,id.time,id.uniqueQualifier,ipAddress,is_encrypted,membership_change_type,new_settings_state,old_settings_state,originating_app_id,owner,owner_is_shared_drive,owner_is_team_drive,owner_team_drive_id,primary_event,removed_role,shared_drive_id,shared_drive_name,shared_drive_settings_change_type,target,team_drive_id,team_drive_settings_change_type,type,visibility +NoActivities,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0AERPpMc23znvUkPXYZ,Shared Drive 1,,,,,, +view,,user1@domain.com,,100016760394505151666,False,,True,,,1SDNu-yzDapqjdJq4y4xKDUATJlOPRIBodpGGeGt1n4I,Digital Poetry Journal,document,drive,C03kt1z99,2023-10-18T21:27:51-07:00,-2856812962461786835,2600:1700:9580:f4b0:2127:3b2:dd21:3806,False,,,,263492796725,Shared Drive 2,True,True,0AMhgLk82dhsuUkPXYZ,True,,0AMhgLk82dhsuUkPXYZ,Shared Drive 2,,,0AMhgLk82dhsuUkPXYZ,,access,people_with_link +edit,,user2@domain.com,,104066776037911136666,False,,True,,,1ZwHi_v-JVXH8W6zwgb7QYoUHrZD6NzIshJEqoTCaDD0,High School Scavenger Hunt,form,drive,C03kt1z99,2023-09-05T15:27:01-07:00,-1272095408714453395,50.204.178.246,False,,,,,Shared Drive 3,True,True,0AM8lpdkkJaKYUkPXYZ,True,,0AM8lpdkkJaKYUkPXYZ,Shared Drive 3,,,0AM8lpdkkJaKYUkPXYZ,,access,shared_internally +``` ## Customer and user reports parameters Display the valid parameters for customer and user reports. diff --git a/docs/Users-Gmail-Delegates.md b/docs/Users-Gmail-Delegates.md index 8cb66f0d..0f775a96 100644 --- a/docs/Users-Gmail-Delegates.md +++ b/docs/Users-Gmail-Delegates.md @@ -6,6 +6,7 @@ - [Delete Gmail delegates](#delete-gmail-delegates) - [Update Gmail delegates](#update-gmail-delegates) - [Display Gmail delegates](#display-gmail-delegates) +- [Delete all delegates for a user](#delete-all-delegates-for-a-user) ## API documentation * https://developers.google.com/gmail/api/v1/reference/users/settings/delegates @@ -66,3 +67,19 @@ This involves an extra API call per delegate email address. By default, `show delegates` displays indented keys and values; use the `csv` option to have just the values shown as a comma separated list. + +## Delete all delegates for a user +``` +$ gam redirect csv ./Delegates.csv user testsimple print delegates +Getting all Delegates for testsimple@domain.com +$ gam redirect stdout - multiprocess csv Delegates.csv gam user "~User" delete delegate "~delegateAddress" +2023-11-10T06:56:04.118-08:00,0/3,Using 3 processes... +2023-11-10T06:56:04.123-08:00,0,Processing item 3/3 +User: testsimple@domain.com, Delete 1 Delegate + User: testsimple@domain.com, Delegate: testuser1@domain.com, Deleted +User: testsimple@domain.com, Delete 1 Delegate + User: testsimple@domain.com, Delegate: testuser2@domain.com, Deleted +User: testsimple@domain.com, Delete 1 Delegate + User: testsimple@domain.com, Delegate: testgroup@domain.com, Deleted +2023-11-10T06:56:07.253-08:00,0/3,Processing complete +``` diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 51922a91..11b11d2a 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -4,7 +4,7 @@ Print the current version of Gam with details ``` gam version -GAMADV-XTD3 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.0 64-bit final MacOS Monterey 12.7 x86_64 @@ -16,7 +16,7 @@ Time: 2023-06-02T21:10:00-07:00 Print the current version of Gam with details and time offset information ``` gam version timeoffset -GAMADV-XTD3 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.0 64-bit final MacOS Monterey 12.7 x86_64 @@ -28,7 +28,7 @@ Your system time differs from www.googleapis.com by less than 1 second Print the current version of Gam with extended details and SSL information ``` gam version extended -GAMADV-XTD3 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.0 64-bit final MacOS Monterey 12.7 x86_64 @@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64 Path: /Users/Admin/bin/gamadv-xtd3 Version Check: Current: 5.35.08 - Latest: 6.65.07 + Latest: 6.65.08 echo $? 1 ``` @@ -73,7 +73,7 @@ echo $? Print the current version number without details ``` gam version simple -6.65.07 +6.65.08 ``` In Linux/MacOS you can do: ``` @@ -83,7 +83,7 @@ echo $VER Print the current version of Gam and address of this Wiki ``` gam help -GAM 6.65.07 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.65.08 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.12.0 64-bit final MacOS Monterey 12.7 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index b698c78f..3d7d631b 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -4138,6 +4138,7 @@ gam report [todrive *] [groupidfilter ] [maxactivities ] [maxresults ] [countsonly [summary] [eventrowfilter]] + (addcsvdata )* [shownoactivities] ::= accounts| diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index cd7644c1..c7bed1a3 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -2,6 +2,16 @@ Merged GAM-Team version +6.65.08 + +Added option `addcsvdata ` to `gam report ` that adds +additional columns of data to the CSV file output. + +Added option `shownoactivities` to `gam report ` that causes GAM to display +a row with a key value of `NoActivities` when there are no activities to report. + +For example, to find Shared Drives with no activity, see: https://github.com/taers232c/GAMADV-XTD3/wiki/Reports#find-shared-drives-with-no-activity + 6.65.07 Updated `gam delete building` to handle the following error: diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 9166f351..d153737d 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -12763,7 +12763,7 @@ REPORTS_PARAMETERS_SIMPLE_TYPES = ['intValue', 'boolValue', 'datetimeValue', 'st # [([start|startdate ] [end|enddate ])|(range )| # thismonth|(previousmonths )] # [fields|parameters )] -# gam report usage |customer [todrive *] +# gam report usage customer [todrive *] # [([start|startdate ] [end|enddate ])|(range )| # thismonth|(previousmonths )] # [fields|parameters )] @@ -13042,6 +13042,7 @@ REPORT_ACTIVITIES_TIME_OBJECTS = {'time'} # [groupidfilter ] # [maxactivities ] [maxresults ] # [countsonly [summary] [eventrowfilter]] +# (addcsvdata )* [shownoactivities] # gam report users|user [todrive *] # [(user all|)|(orgunit|org|ou [showorgunit])|(select )] # [allverifyuser ] @@ -13320,6 +13321,8 @@ def doReport(): usageReports = customerReports or userReports activityReports = not usageReports dataRequiredServices = set() + addCSVData = {} + showNoActivities = False if usageReports: includeServices = set() while Cmd.ArgumentsRemaining(): @@ -13396,6 +13399,11 @@ def doReport(): eventRowFilter = True elif activityReports and myarg == 'groupidfilter': groupIdFilter = getString(Cmd.OB_STRING) + elif activityReports and myarg == 'addcsvdata': + k = getString(Cmd.OB_STRING) + addCSVData[k] = getString(Cmd.OB_STRING, minLen=0) + elif activityReports and myarg == 'shownoactivities': + showNoActivities = True elif not customerReports and myarg.startswith('filtertime'): filterTimes[myarg] = getTimeOrDeltaFromNow() elif not customerReports and myarg in {'filter', 'filters'}: @@ -13596,6 +13604,8 @@ def doReport(): startDateTime += oneDay csvPF.writeCSVfile(f'Customer Report - {tryDate}') else: # activityReports + if addCSVData: + csvPF.AddTitles(sorted(addCSVData.keys())) if select: pageMessage = None normalizeUsers = True @@ -13690,6 +13700,8 @@ def doReport(): row = flattenJSON(event) row.update(activity_row) if not countsOnly: + if addCSVData: + row.update(addCSVData) csvPF.WriteRowTitles(row) elif csvPF.CheckRowTitles(row): if not summary: @@ -13709,22 +13721,48 @@ def doReport(): eventCounts.setdefault(event['name'], 0) eventCounts[event['name']] += 1 if not countsOnly: + if not csvPF.rows and showNoActivities: + row = {'name': 'NoActivities'} + if addCSVData: + row.update(addCSVData) + csvPF.WriteRowTitles(row) csvPF.SetSortTitles(['name']) else: if eventRowFilter: csvPF.SetRowFilter([], GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE]) if not summary: csvPF.SetTitles('emailAddress') - for actor, events in iter(eventCounts.items()): - row = {'emailAddress': actor} - for event, count in iter(events.items()): - row[event] = count - csvPF.WriteRowTitles(row) + if addCSVData: + csvPF.AddTitles(sorted(addCSVData.keys())) + if eventCounts: + for actor, events in iter(eventCounts.items()): + row = {'emailAddress': actor} + for event, count in iter(events.items()): + row[event] = count + if addCSVData: + row.update(addCSVData) + csvPF.WriteRowTitles(row) + elif showNoActivities: + row = {'emailAddress': 'NoActivities'} + if addCSVData: + row.update(addCSVData) + csvPF.WriteRow(row) csvPF.SetSortTitles(['emailAddress']) else: csvPF.SetTitles(['event', 'count']) - for event in sorted(eventCounts): - csvPF.WriteRow({'event': event, 'count': eventCounts[event]}) + if addCSVData: + csvPF.AddTitles(sorted(addCSVData.keys())) + if eventCounts: + for event in sorted(eventCounts): + row = {'event': event, 'count': eventCounts[event]} + if addCSVData: + row.update(addCSVData) + csvPF.WriteRow(row) + elif showNoActivities: + row = {'event': 'NoActivities', 'count': 0} + if addCSVData: + row.update(addCSVData) + csvPF.WriteRow(row) csvPF.writeCSVfile(f'{report.capitalize()} Activity Report') # Substitute for #user#, #email#, #usernamne#