Skip to content

Commit

Permalink
✨ feat: Export as CSV
Browse files Browse the repository at this point in the history
Fix #2
  • Loading branch information
remileblond67076 committed Dec 27, 2024
1 parent 093dd68 commit 0ee3d58
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 94 deletions.
1 change: 1 addition & 0 deletions common/common.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Common tools
package common

import (
Expand Down
119 changes: 48 additions & 71 deletions gristapi/gristapi.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Grist API operation
package gristapi

import (
Expand All @@ -12,10 +13,10 @@ import (
"strconv"
"strings"

"github.com/go-gota/gota/dataframe"
"github.com/joho/godotenv"
)

// Grist's user
type User struct {
Id int `json:"id"`
Name string `json:"name"`
Expand All @@ -24,13 +25,15 @@ type User struct {
ParentAccess string `json:"parentAccess"`
}

// Grist's Organization
type Org struct {
Id int `json:"id"`
Name string `json:"name"`
Domain string `json:"domain"`
CreatedAt string `json:"createdAt"`
}

// Grist'a workspace
type Workspace struct {
Id int `json:"id"`
Name string `json:"name"`
Expand All @@ -47,40 +50,47 @@ type EntityAccess struct {
Users []User `json:"users"`
}

// Grist's document
type Doc struct {
Id string `json:"id"`
Name string `json:"name"`
IsPinned bool `json:"isPinned"`
Workspace Workspace `json:"workspace"`
}

// Grist's table
type Table struct {
Id string `json:"id"`
}

// List of Grist's tables
type Tables struct {
Tables []Table `json:"tables"`
}

// Grist's table column
type TableColumn struct {
Id string `json:"id"`
}

// List of Grist's table columns
type TableColumns struct {
Columns []TableColumn `json:"columns"`
}

// Grist's table row
type TableRows struct {
Id []uint `json:"id"`
}

// Grist's user role
type UserRole struct {
Email string
Role string
}

// Apply config and return the config file path
func GetConfig() string {
// Apply config and return the config file path
home := os.Getenv("HOME")
configFile := filepath.Join(home, ".gristctl")
if os.Getenv("GRIST_TOKEN") == "" || os.Getenv("GRIST_URL") == "" {
Expand All @@ -96,10 +106,10 @@ func init() {
GetConfig()
}

// Sending an HTTP request to Grist's REST API
// Action: GET, POST, PATCH, DELETE
// Returns response body
func httpRequest(action string, myRequest string, data *bytes.Buffer) (string, int) {
// Sending an HTTP request to Grist's REST API
// Returns response body

client := &http.Client{}
url := fmt.Sprintf("%s/api/%s", os.Getenv("GRIST_URL"), myRequest)
bearer := "Bearer " + os.Getenv("GRIST_TOKEN")
Expand All @@ -126,9 +136,9 @@ func httpRequest(action string, myRequest string, data *bytes.Buffer) (string, i
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 {
// Send an HTTP GET request to Grist's REST API
// Returns the response body
dataBody := bytes.NewBuffer([]byte(data))
body, status := httpRequest("GET", myRequest, dataBody)
if status != http.StatusOK {
Expand All @@ -137,81 +147,74 @@ func httpGet(myRequest string, data string) string {
return body
}

// Sends an HTTP POST request to Grist's REST API with a data load
// Return the response body
func httpPost(myRequest string, data string) (string, int) {
// Sends an HTTP POST request to Grist's REST API with a data load
// Return the response body

dataBody := bytes.NewBuffer([]byte(data))
body, status := httpRequest("POST", myRequest, dataBody)
return body, status
}

// Sends an HTTP POST request to Grist's REST API with a data load
// Return the response body
func httpPatch(myRequest string, data string) (string, int) {
// Sends an HTTP POST request to Grist's REST API with a data load
// Return the response body

dataBody := bytes.NewBuffer([]byte(data))
body, status := httpRequest("PATCH", myRequest, dataBody)
return body, status
}

// Send an HTTP DELETE request to Grist's REST API with a data load
// Return the response body
func httpDelete(myRequest string, data string) (string, int) {
// Send an HTTP DELETE request to Grist's REST API with a data load
// Return the response body

dataBody := bytes.NewBuffer([]byte(data))
body, status := httpRequest("DELETE", myRequest, dataBody)
return body, status
}

// Retrieves the list of organizations
func GetOrgs() []Org {
// Retrieves the list of organizations

myOrgs := []Org{}
response := httpGet("orgs", "")
json.Unmarshal([]byte(response), &myOrgs)
return myOrgs
}

// Retrieves the organization whose identifier is passed in parameter
func GetOrg(idOrg string) Org {
// Retrieves the organization whose identifier is passed in parameter

myOrg := Org{}
response := httpGet("orgs/"+idOrg, "")
json.Unmarshal([]byte(response), &myOrg)
return myOrg
}

// Retrieves the list of users in the organization whose ID is passed in parameter
func GetOrgAccess(idOrg string) []User {
// Retrieves the list of users in the organization whose ID is passed in parameter

var lstUsers EntityAccess
url := fmt.Sprintf("orgs/%s/access", idOrg)
response := httpGet(url, "")
json.Unmarshal([]byte(response), &lstUsers)
return lstUsers.Users
}

// Retrieves information on a specific organization
func GetOrgWorkspaces(orgId int) []Workspace {
// Retrieves information on a specific organization
lstWorkspaces := []Workspace{}
response := httpGet("orgs/"+strconv.Itoa(orgId)+"/workspaces", "")
json.Unmarshal([]byte(response), &lstWorkspaces)
return lstWorkspaces
}

// Recovers a workspace
func GetWorkspace(workspaceId int) Workspace {
// Recovers a workspace
workspace := Workspace{}
url := fmt.Sprintf("workspaces/%d", workspaceId)
response := httpGet(url, "")
json.Unmarshal([]byte(response), &workspace)
return workspace
}

// Delete a workspace
func DeleteWorkspace(workspaceId int) {
// Delete a workspace

url := fmt.Sprintf("workspaces/%d", workspaceId)
response, status := httpDelete(url, "")
if status == http.StatusOK {
Expand All @@ -221,9 +224,8 @@ func DeleteWorkspace(workspaceId int) {
}
}

// Delete a document
func DeleteDoc(docId string) {
// Delete a document

url := fmt.Sprintf("docs/%s", docId)
response, status := httpDelete(url, "")
if status == http.StatusOK {
Expand All @@ -233,9 +235,8 @@ func DeleteDoc(docId string) {
}
}

// Delete a user
func DeleteUser(userId int) {
// Delete a user

url := fmt.Sprintf("users/%d", userId)
response, status := httpDelete(url, `{"name": ""}`)

Expand All @@ -256,28 +257,26 @@ func DeleteUser(userId int) {
}
}

// Workspace access rights query
func GetWorkspaceAccess(workspaceId int) EntityAccess {
// Workspace access rights query

workspaceAccess := EntityAccess{}
url := fmt.Sprintf("workspaces/%d/access", workspaceId)
response := httpGet(url, "")
json.Unmarshal([]byte(response), &workspaceAccess)
return workspaceAccess
}

// Retrieves information about a specific document
func GetDoc(docId string) Doc {
// Retrieves information about a specific document

doc := Doc{}
url := "docs/" + docId
response := httpGet(url, "")
json.Unmarshal([]byte(response), &doc)
return doc
}

// Retrieves the list of tables contained in a document
func GetDocTables(docId string) Tables {
// Retrieves the list of tables contained in a document
tables := Tables{}
url := "docs/" + docId + "/tables"
response := httpGet(url, "")
Expand All @@ -286,9 +285,8 @@ func GetDocTables(docId string) Tables {
return tables
}

// Retrieves a list of table columns
func GetTableColumns(docId string, tableId string) TableColumns {
// Retrieves a list of table columns

columns := TableColumns{}
url := "docs/" + docId + "/tables/" + tableId + "/columns"
response := httpGet(url, "")
Expand All @@ -297,9 +295,8 @@ func GetTableColumns(docId string, tableId string) TableColumns {
return columns
}

// Retrieves records from a table
func GetTableRows(docId string, tableId string) TableRows {
// Retrieves records from a table

rows := TableRows{}
url := "docs/" + docId + "/tables/" + tableId + "/data"
response := httpGet(url, "")
Expand All @@ -308,19 +305,17 @@ func GetTableRows(docId string, tableId string) TableRows {
return rows
}

// Returns the list of users with access to the document
func GetDocAccess(docId string) EntityAccess {
// Returns the list of users with access to the document

var lstUsers EntityAccess
url := fmt.Sprintf("docs/%s/access", docId)
response := httpGet(url, "")
json.Unmarshal([]byte(response), &lstUsers)
return lstUsers
}

// Purge a document's history, to retain only the last modifications
func PurgeDoc(docId string, nbHisto int) {
// Purge a document's history, to retain only the last modifications

url := "docs/" + docId + "/states/remove"
data := fmt.Sprintf(`{"keep": "%d"}`, nbHisto)
_, status := httpPost(url, data)
Expand All @@ -329,10 +324,9 @@ func PurgeDoc(docId string, nbHisto int) {
}
}

// Import a list of user & role into a workspace
// Search workspace by name in org
func ImportUsers(orgId int, workspaceName string, users []UserRole) {
// Import a list of user & role into a workspace

// Search workspace by name in org
lstWorkspaces := GetOrgWorkspaces(orgId)
idWorkspace := 0
for _, ws := range lstWorkspaces {
Expand Down Expand Up @@ -368,9 +362,8 @@ func ImportUsers(orgId int, workspaceName string, users []UserRole) {

}

// Create a workspace in an organization
func CreateWorkspace(orgId int, workspaceName string) int {
// Create a workspace in an organization

url := fmt.Sprintf("orgs/%d/workspaces", orgId)
data := fmt.Sprintf(`{"name":"%s"}`, workspaceName)
body, status := httpPost(url, data)
Expand All @@ -384,39 +377,23 @@ func CreateWorkspace(orgId int, workspaceName string) int {
return idWorkspace
}

// Export doc in Grist format (Sqlite)
func ExportDocGrist(docId string) {
// Export doc in Grist format (Sqlite)
url := fmt.Sprintf("docs/%s/download", docId)
file := httpGet(url, "")
fmt.Println(file)
}

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

func GetTableContent(docId string, tableName string) dataframe.DataFrame {
// Returns table content as Dataframe
url := fmt.Sprintf("docs/%s/tables/%s/records", docId, tableName)
response := httpGet(url, "")
type GristRecord struct {
ID int `json:"id"`
Fields map[string]any `json:"fields"`
}

type GristResponse struct {
Records []GristRecord `json:"records"`
}

var gristResponse GristResponse
err := json.Unmarshal([]byte(response), &gristResponse)
if err != nil {
log.Fatalf("Erreur lors du décodage du JSON: %v", err)
}

df := dataframe.LoadStructs(gristResponse.Records)
return df
// 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, "")
fmt.Println(csvFile)
}
Loading

0 comments on commit 0ee3d58

Please sign in to comment.