Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve displays #16

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SPDX-FileCopyrightText: 2024 Ville Eurométropole Strasbourg
SPDX-License-Identifier: MIT
-->

# GRISTcli Command Line Interface (CLI) for Grist
# GristCTL : Command Line Interface (CLI) for Grist

[![img](https://img.shields.io/badge/code.gouv.fr-contributif-blue.svg)](https://code.gouv.fr/documentation/#quels-degres-douverture-pour-les-codes-sources)
[![REUSE status](https://api.reuse.software/badge/github.com/Ville-Eurometropole-Strasbourg/grist-ctl)](https://api.reuse.software/info/github.com/Ville-Eurometropole-Strasbourg/grist-ctl)
Expand Down Expand Up @@ -125,27 +125,27 @@ GRIST_TOKEN="user session token"
GRIST_URL="https://<GRIST server URL, without /api>"
```


## Usage

List of commands :

- `config`: configure gristctl
- `config` : configure url & token of Grist server
- `delete doc <id>` : delete a document
- `delete user <id>` : delete a user
- `delete workspace <id>` : delete a workspace
- `get doc <id>` : document details
- `get doc <id>` access : list of document access rights
- `get doc <id>` excel : export document as an Excel file (xlsx) in stdout
- `get doc <id>` grist : export document as a Grist file (Sqlite) in stdout
- `get doc <id>` table <tableName> : export content of a document's table as a CSV file (xlsx) in stdout
- `get org` : organization list
- `get org <id>` : organization details
- `get doc <id>` : document details
- `get doc <id> access` : list of document access rights
- `get doc <id> grist` : export document as a Grist file (Sqlite) in stdout
- `get doc <id> excel` : export document as an Excel file (xlsx) in stdout
- `get doc <id> table <tableName>` : export content of a document's table as a CSV file (xlsx) in stdout
- `purge doc <id> [<number of states to keep>]`: purges document history (retains last 3 operations by default)
- `get workspace <id>`: workspace details
- `get workspace <id> access`: list of workspace access rights
- `delete doc <id>`: delete a document
- `delete workspace <id>` : delete a workspace
- `delete user <id>` : delete a user
- `import users` : imports users from standard input
- `get users` : displays all user rights
- `get workspace <id> access` : list of workspace access rights
- `get workspace <id>` : workspace details
- `import users` : imports users from standard input
- `purge doc <id> [<number of states to keep>]` : purges document history (retains last 3 operations by default)
- `version` : displays the version of the program

### List Grist organization

Expand Down Expand Up @@ -235,10 +235,10 @@ foreach ($grp in ('a', 'u')) {
```

```bash
cat ga_grist_pu.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Direction-"$2";viewers"}' | ./gristctl import users
cat ga_grist_pu.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Service-"$3";viewers"}' | ./gristctl import users
cat ga_grist_pa.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Direction-"$2";editors"}' | ./gristctl import users
cat ga_grist_pa.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Service-"$3";editors"}' | ./gristctl import users
cat ga_grist_pu.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Direction-"$2";viewers"}' | gristctl import users
cat ga_grist_pu.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Service-"$3";viewers"}' | gristctl import users
cat ga_grist_pa.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Direction-"$2";editors"}' | gristctl import users
cat ga_grist_pa.csv | awk -F',' 'NR>1 {gsub(/"/, "", $0); print tolower($1)";3;Service-"$3";editors"}' | gristctl import users
```

## Contributing
Expand Down
57 changes: 32 additions & 25 deletions gristapi/gristapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,27 +128,34 @@ func httpRequest(action string, myRequest string, data *bytes.Buffer) (string, i
// Send the HTTP request
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Error sending request %s: %s", url, err)
}
defer resp.Body.Close()

// Read the HTTP response body
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Error reading response %s: %s", url, err)
errMsg := fmt.Sprintf("Error sending request %s: %s", url, err)
return errMsg, -10
} else {
defer resp.Body.Close()
// Read the HTTP response body
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading response %s: %s", url, err)
}
return string(body), resp.StatusCode
}
return string(body), resp.StatusCode
}

// Send an HTTP GET request to Grist's REST API
// Returns the response body
func httpGet(myRequest string, data string) string {
func httpGet(myRequest string, data string) (string, int) {
dataBody := bytes.NewBuffer([]byte(data))
body, status := httpRequest("GET", myRequest, dataBody)
if status != http.StatusOK {
fmt.Printf("Return code from %s : %d (%s)\n", myRequest, status, body)
}
return body
return body, status
}

// Test Grist API connection
func TestConnection() bool {
_, status := httpGet("orgs", "")
return status == http.StatusOK
}

// Sends an HTTP POST request to Grist's REST API with a data load
Expand Down Expand Up @@ -178,15 +185,15 @@ func httpDelete(myRequest string, data string) (string, int) {
// Retrieves the list of organizations
func GetOrgs() []Org {
myOrgs := []Org{}
response := httpGet("orgs", "")
response, _ := httpGet("orgs", "")
json.Unmarshal([]byte(response), &myOrgs)
return myOrgs
}

// Retrieves the organization whose identifier is passed in parameter
func GetOrg(idOrg string) Org {
myOrg := Org{}
response := httpGet("orgs/"+idOrg, "")
response, _ := httpGet("orgs/"+idOrg, "")
json.Unmarshal([]byte(response), &myOrg)
return myOrg
}
Expand All @@ -195,15 +202,15 @@ func GetOrg(idOrg string) Org {
func GetOrgAccess(idOrg string) []User {
var lstUsers EntityAccess
url := fmt.Sprintf("orgs/%s/access", idOrg)
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &lstUsers)
return lstUsers.Users
}

// Retrieves information on a specific organization
func GetOrgWorkspaces(orgId int) []Workspace {
lstWorkspaces := []Workspace{}
response := httpGet("orgs/"+strconv.Itoa(orgId)+"/workspaces", "")
response, _ := httpGet("orgs/"+strconv.Itoa(orgId)+"/workspaces", "")
json.Unmarshal([]byte(response), &lstWorkspaces)
return lstWorkspaces
}
Expand All @@ -212,7 +219,7 @@ func GetOrgWorkspaces(orgId int) []Workspace {
func GetWorkspace(workspaceId int) Workspace {
workspace := Workspace{}
url := fmt.Sprintf("workspaces/%d", workspaceId)
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &workspace)
return workspace
}
Expand Down Expand Up @@ -265,7 +272,7 @@ func DeleteUser(userId int) {
func GetWorkspaceAccess(workspaceId int) EntityAccess {
workspaceAccess := EntityAccess{}
url := fmt.Sprintf("workspaces/%d/access", workspaceId)
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &workspaceAccess)
return workspaceAccess
}
Expand All @@ -274,7 +281,7 @@ func GetWorkspaceAccess(workspaceId int) EntityAccess {
func GetDoc(docId string) Doc {
doc := Doc{}
url := "docs/" + docId
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &doc)
return doc
}
Expand All @@ -283,7 +290,7 @@ func GetDoc(docId string) Doc {
func GetDocTables(docId string) Tables {
tables := Tables{}
url := "docs/" + docId + "/tables"
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &tables)

return tables
Expand All @@ -293,7 +300,7 @@ func GetDocTables(docId string) Tables {
func GetTableColumns(docId string, tableId string) TableColumns {
columns := TableColumns{}
url := "docs/" + docId + "/tables/" + tableId + "/columns"
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &columns)

return columns
Expand All @@ -303,7 +310,7 @@ func GetTableColumns(docId string, tableId string) TableColumns {
func GetTableRows(docId string, tableId string) TableRows {
rows := TableRows{}
url := "docs/" + docId + "/tables/" + tableId + "/data"
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &rows)

return rows
Expand All @@ -313,7 +320,7 @@ func GetTableRows(docId string, tableId string) TableRows {
func GetDocAccess(docId string) EntityAccess {
var lstUsers EntityAccess
url := fmt.Sprintf("docs/%s/access", docId)
response := httpGet(url, "")
response, _ := httpGet(url, "")
json.Unmarshal([]byte(response), &lstUsers)
return lstUsers
}
Expand Down Expand Up @@ -384,20 +391,20 @@ func CreateWorkspace(orgId int, workspaceName string) int {
// Export doc in Grist format (Sqlite)
func ExportDocGrist(docId string) {
url := fmt.Sprintf("docs/%s/download", docId)
file := httpGet(url, "")
file, _ := httpGet(url, "")
fmt.Println(file)
}

// Export doc in Excel format (XLSX)
func ExportDocExcel(docId string) {
url := fmt.Sprintf("docs/%s/download/xlsx", docId)
file := httpGet(url, "")
file, _ := httpGet(url, "")
fmt.Println(file)
}

// Returns table content as Dataframe
func GetTableContent(docId string, tableName string) {
url := fmt.Sprintf("docs/%s/download/csv?tableId=%s", docId, tableName)
csvFile := httpGet(url, "")
csvFile, _ := httpGet(url, "")
fmt.Println(csvFile)
}
Loading
Loading