refact: moved storage behind interface
also better read and write methods
This commit is contained in:
parent
b09e7c2db4
commit
2963dac8a6
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
document "textualize/core/Document"
|
||||
session "textualize/core/Session"
|
||||
storage "textualize/storage/Local"
|
||||
storage "textualize/storage"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
@ -24,7 +24,7 @@ func GetInstance() *App {
|
||||
|
||||
func (a *App) Startup(ctx context.Context) {
|
||||
a.Context = ctx
|
||||
localUserData := storage.ReadLocalUserData()
|
||||
localUserData := storage.GetDriver().ReadUserData()
|
||||
session.InitializeModule(session.Session{
|
||||
User: session.User(localUserData),
|
||||
})
|
||||
|
||||
@ -6,7 +6,8 @@ import (
|
||||
consts "textualize/core/Consts"
|
||||
document "textualize/core/Document"
|
||||
session "textualize/core/Session"
|
||||
storage "textualize/storage/Local"
|
||||
storage "textualize/storage"
|
||||
storageEntity "textualize/storage/Entities"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@ -408,40 +409,40 @@ func (c *Channel) RequestSaveDocumentCollection() bool {
|
||||
documentCollection := document.GetDocumentCollection()
|
||||
projectName := c.GetCurrentSession().Project.Name
|
||||
|
||||
fullProject := storage.ReadLocalProjectByName(projectName)
|
||||
fullProject := storage.GetDriver().ReadProjectDataByName(projectName)
|
||||
|
||||
if fullProject.Id == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
var documentsToWrite []storage.LocalDocument
|
||||
var documentsToWrite []storageEntity.Document
|
||||
for _, d := range documentCollection.Documents {
|
||||
var areasToWrite []storage.LocalArea
|
||||
var areasToWrite []storageEntity.Area
|
||||
for _, a := range d.Areas {
|
||||
areasToWrite = append(areasToWrite, storage.LocalArea{
|
||||
areasToWrite = append(areasToWrite, storageEntity.Area{
|
||||
Id: a.Id,
|
||||
Name: a.Name,
|
||||
StartX: a.StartX,
|
||||
StartY: a.StartY,
|
||||
EndX: a.EndX,
|
||||
EndY: a.EndY,
|
||||
Language: storage.Language(a.Language),
|
||||
Language: storageEntity.Language(a.Language),
|
||||
Order: a.Order,
|
||||
})
|
||||
}
|
||||
|
||||
documentsToWrite = append(documentsToWrite, storage.LocalDocument{
|
||||
documentsToWrite = append(documentsToWrite, storageEntity.Document{
|
||||
Id: d.Id,
|
||||
GroupId: d.GroupId,
|
||||
Name: d.Name,
|
||||
Path: d.Path,
|
||||
ProjectId: d.ProjectId,
|
||||
Areas: areasToWrite,
|
||||
DefaultLanguage: storage.Language(d.DefaultLanguage),
|
||||
DefaultLanguage: storageEntity.Language(d.DefaultLanguage),
|
||||
})
|
||||
}
|
||||
|
||||
successfulWrite := storage.WriteLocalDocumentCollection(storage.LocalDocumentCollection{
|
||||
successfulWrite := storage.GetDriver().WriteDocumentCollection(storageEntity.DocumentCollection{
|
||||
Documents: documentsToWrite,
|
||||
ProjectId: fullProject.Id,
|
||||
}, projectName)
|
||||
@ -453,18 +454,18 @@ func (c *Channel) RequestSaveGroupCollection() bool {
|
||||
groupCollection := document.GetGroupCollection()
|
||||
projectName := c.GetCurrentSession().Project.Name
|
||||
|
||||
fullProject := storage.ReadLocalProjectByName(projectName)
|
||||
fullProject := storage.GetDriver().ReadProjectDataByName(projectName)
|
||||
|
||||
if fullProject.Id == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
var groupsToWrite []storage.LocalGroup
|
||||
var groupsToWrite []storageEntity.Group
|
||||
for _, g := range groupCollection.Groups {
|
||||
groupsToWrite = append(groupsToWrite, storage.LocalGroup(g))
|
||||
groupsToWrite = append(groupsToWrite, storageEntity.Group(g))
|
||||
}
|
||||
|
||||
successfulWrite := storage.WriteLocalGroupCollection(storage.LocalGroupCollection{
|
||||
successfulWrite := storage.GetDriver().WriteGroupCollection(storageEntity.GroupCollection{
|
||||
Id: groupCollection.Id,
|
||||
ProjectId: groupCollection.ProjectId,
|
||||
Groups: groupsToWrite,
|
||||
@ -477,39 +478,39 @@ func (c *Channel) RequestSaveProcessedTextCollection() bool {
|
||||
processedAreaCollection := document.GetProcessedAreaCollection()
|
||||
projectName := c.GetCurrentSession().Project.Name
|
||||
|
||||
areasToWrite := make([]storage.LocalProcessedArea, 0)
|
||||
areasToWrite := make([]storageEntity.ProcessedArea, 0)
|
||||
for _, a := range processedAreaCollection.Areas {
|
||||
linesOfAreaToWrite := make([]storage.LocalProcessedLine, 0)
|
||||
linesOfAreaToWrite := make([]storageEntity.ProcessedLine, 0)
|
||||
for _, l := range a.Lines {
|
||||
wordsOfLineToWrite := make([]storage.LocalProcessedWord, 0)
|
||||
wordsOfLineToWrite := make([]storageEntity.ProcessedWord, 0)
|
||||
|
||||
for _, w := range l.Words {
|
||||
symbolsOfWordToWrite := make([]storage.LocalProcessedSymbol, 0)
|
||||
symbolsOfWordToWrite := make([]storageEntity.ProcessedSymbol, 0)
|
||||
|
||||
for _, s := range w.Symbols {
|
||||
symbolsOfWordToWrite = append(symbolsOfWordToWrite, storage.LocalProcessedSymbol{
|
||||
symbolsOfWordToWrite = append(symbolsOfWordToWrite, storageEntity.ProcessedSymbol{
|
||||
Text: s.Text,
|
||||
Confidence: s.Confidence,
|
||||
BoundingBox: storage.LocalProcessedBoundingBox(s.BoundingBox),
|
||||
BoundingBox: storageEntity.ProcessedBoundingBox(s.BoundingBox),
|
||||
})
|
||||
}
|
||||
|
||||
wordsOfLineToWrite = append(wordsOfLineToWrite, storage.LocalProcessedWord{
|
||||
wordsOfLineToWrite = append(wordsOfLineToWrite, storageEntity.ProcessedWord{
|
||||
FullText: w.FullText,
|
||||
Confidence: w.Confidence,
|
||||
Direction: w.Direction,
|
||||
BoundingBox: storage.LocalProcessedBoundingBox(w.BoundingBox),
|
||||
BoundingBox: storageEntity.ProcessedBoundingBox(w.BoundingBox),
|
||||
Symbols: symbolsOfWordToWrite,
|
||||
})
|
||||
}
|
||||
|
||||
linesOfAreaToWrite = append(linesOfAreaToWrite, storage.LocalProcessedLine{
|
||||
linesOfAreaToWrite = append(linesOfAreaToWrite, storageEntity.ProcessedLine{
|
||||
FullText: l.FullText,
|
||||
Words: wordsOfLineToWrite,
|
||||
})
|
||||
}
|
||||
|
||||
areasToWrite = append(areasToWrite, storage.LocalProcessedArea{
|
||||
areasToWrite = append(areasToWrite, storageEntity.ProcessedArea{
|
||||
Id: a.Id,
|
||||
DocumentId: a.DocumentId,
|
||||
FullText: a.FullText,
|
||||
@ -518,11 +519,11 @@ func (c *Channel) RequestSaveProcessedTextCollection() bool {
|
||||
})
|
||||
}
|
||||
|
||||
processedAreaCollectionToWrite := storage.LocalProcessedAreaCollection{
|
||||
processedAreaCollectionToWrite := storageEntity.ProcessedTextCollection{
|
||||
Areas: areasToWrite,
|
||||
}
|
||||
|
||||
successfulWrite := storage.WriteLocalProcessedAreaCollection(processedAreaCollectionToWrite, projectName)
|
||||
successfulWrite := storage.GetDriver().WriteProcessedTextCollection(processedAreaCollectionToWrite, projectName)
|
||||
return successfulWrite
|
||||
}
|
||||
|
||||
@ -530,22 +531,20 @@ func (c *Channel) RequestSaveLocalUserProcessedMarkdownCollection() bool {
|
||||
userProcessedMarkdownCollection := document.GetUserMarkdownCollection()
|
||||
projectName := c.GetCurrentSession().Project.Name
|
||||
|
||||
fullProject := storage.ReadLocalProjectByName(projectName)
|
||||
fullProject := storage.GetDriver().ReadProjectDataByName(projectName)
|
||||
|
||||
if fullProject.Id == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
var valuesToWrite []storage.LocalUserMarkdown
|
||||
var valuesToWrite []storageEntity.ProcessedUserMarkdown
|
||||
for _, v := range userProcessedMarkdownCollection.Values {
|
||||
valuesToWrite = append(valuesToWrite, storage.LocalUserMarkdown(v))
|
||||
valuesToWrite = append(valuesToWrite, storageEntity.ProcessedUserMarkdown(v))
|
||||
}
|
||||
|
||||
successfulWrite := storage.WriteLocalUserProcessedMarkdownCollection(storage.LocalUserMarkdownCollection{
|
||||
successfulWrite := storage.GetDriver().WriteProcessedUserMarkdownCollection(storageEntity.ProcessedUserMarkdownCollection{
|
||||
Values: valuesToWrite,
|
||||
}, projectName)
|
||||
|
||||
return successfulWrite
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,8 @@ import (
|
||||
consts "textualize/core/Consts"
|
||||
document "textualize/core/Document"
|
||||
session "textualize/core/Session"
|
||||
storage "textualize/storage/Local"
|
||||
storage "textualize/storage"
|
||||
storageEntity "textualize/storage/Entities"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
|
||||
@ -55,7 +56,7 @@ func (c *Channel) CreateNewProject(name string) Session {
|
||||
Name: name,
|
||||
}
|
||||
|
||||
successfulProjectWrite := storage.WriteLocalProjectData(storage.LocalProject{
|
||||
successfulProjectWrite := storage.GetDriver().WriteProjectData(storageEntity.Project{
|
||||
Id: newProject.Id,
|
||||
OrganizationId: newProject.OrganizationId,
|
||||
Name: newProject.Name,
|
||||
@ -94,7 +95,7 @@ func (c *Channel) RequestUpdateCurrentUser(updatedUserRequest User) User {
|
||||
|
||||
sessionUser.AvatarPath = updatedUserRequest.AvatarPath
|
||||
|
||||
successfulUserWrite := storage.WriteLocalUserData(storage.LocalUser(sessionUser))
|
||||
successfulUserWrite := storage.GetDriver().WriteUserData(storageEntity.User(sessionUser))
|
||||
if !successfulUserWrite {
|
||||
return User{}
|
||||
}
|
||||
@ -124,7 +125,7 @@ func (c *Channel) RequestChooseUserAvatar() string {
|
||||
}
|
||||
|
||||
func (c *Channel) GetAllLocalProjects() []Project {
|
||||
readLocalProjects := storage.ReadAllLocalProjects()
|
||||
readLocalProjects := storage.GetDriver().ReadAllProjects()
|
||||
response := make([]Project, 0)
|
||||
|
||||
for _, p := range readLocalProjects {
|
||||
@ -144,7 +145,7 @@ func (c *Channel) GetAllLocalProjects() []Project {
|
||||
}
|
||||
|
||||
func (c *Channel) GetProjectByName(projectName string) Project {
|
||||
foundProject := storage.ReadLocalProjectByName(projectName)
|
||||
foundProject := storage.GetDriver().ReadProjectDataByName(projectName)
|
||||
|
||||
if foundProject.Id == "" {
|
||||
return Project{}
|
||||
@ -163,6 +164,7 @@ func (c *Channel) GetProjectByName(projectName string) Project {
|
||||
}
|
||||
|
||||
func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
|
||||
storageDriver := storage.GetDriver()
|
||||
foundProject := c.GetProjectByName(projectName)
|
||||
|
||||
if foundProject.Id == "" {
|
||||
@ -180,7 +182,7 @@ func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
|
||||
},
|
||||
}
|
||||
|
||||
localDocumentCollection := storage.ReadLocalDocumentCollection(projectName)
|
||||
localDocumentCollection := storageDriver.ReadDocumentCollection(projectName)
|
||||
newDocuments := make([]document.Entity, 0)
|
||||
for _, d := range localDocumentCollection.Documents {
|
||||
newAreas := make([]document.Area, 0)
|
||||
@ -212,7 +214,7 @@ func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
|
||||
}
|
||||
document.SetDocumentCollection(newDocumentColllection)
|
||||
|
||||
localGroupsCollection := storage.ReadLocalGroupCollection(projectName)
|
||||
localGroupsCollection := storageDriver.ReadGroupCollection(projectName)
|
||||
newGroups := make([]document.Group, 0)
|
||||
for _, g := range localGroupsCollection.Groups {
|
||||
newGroups = append(newGroups, document.Group(g))
|
||||
@ -226,7 +228,7 @@ func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
|
||||
|
||||
// Processed Texts
|
||||
|
||||
localProcessedAreaCollection := storage.ReadLocalProcessedAreaCollection(projectName)
|
||||
localProcessedAreaCollection := storageDriver.ReadProcessedTextCollection(projectName)
|
||||
newAreas := make([]document.ProcessedArea, 0)
|
||||
for _, a := range localProcessedAreaCollection.Areas {
|
||||
linesOfArea := make([]document.ProcessedLine, 0)
|
||||
@ -274,7 +276,7 @@ func (c *Channel) RequestChangeSessionProjectByName(projectName string) bool {
|
||||
|
||||
// UserProcessedMarkdown
|
||||
|
||||
localUserProcessedMarkdown := storage.ReadLocalUserProcessedMarkdownCollection(projectName)
|
||||
localUserProcessedMarkdown := storageDriver.ReadProcessedUserMarkdownCollection(projectName)
|
||||
|
||||
newUserProcessedMarkdown := make([]document.UserMarkdown, 0)
|
||||
for _, v := range localUserProcessedMarkdown.Values {
|
||||
|
||||
27
storage/Entities/Document.go
Normal file
27
storage/Entities/Document.go
Normal file
@ -0,0 +1,27 @@
|
||||
package storage
|
||||
|
||||
type DocumentCollection struct {
|
||||
Documents []Document `json:"documents"`
|
||||
ProjectId string `json:"projectId"`
|
||||
}
|
||||
|
||||
type Document struct {
|
||||
Id string `json:"id"`
|
||||
GroupId string `json:"groupId"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
ProjectId string `json:"projectId"`
|
||||
Areas []Area `json:"areas"`
|
||||
DefaultLanguage Language `json:"defaultLanguage"`
|
||||
}
|
||||
|
||||
type Area struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
StartX int `json:"startX"`
|
||||
StartY int `json:"startY"`
|
||||
EndX int `json:"endX"`
|
||||
EndY int `json:"endY"`
|
||||
Language Language `json:"language"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
15
storage/Entities/Group.go
Normal file
15
storage/Entities/Group.go
Normal file
@ -0,0 +1,15 @@
|
||||
package storage
|
||||
|
||||
type Group struct {
|
||||
Id string `json:"id"`
|
||||
ParentId string `json:"parentId"`
|
||||
ProjectId string `json:"projectId"`
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type GroupCollection struct {
|
||||
Id string `json:"id"`
|
||||
Groups []Group `json:"groups"`
|
||||
ProjectId string `json:"projectId"`
|
||||
}
|
||||
7
storage/Entities/Language.go
Normal file
7
storage/Entities/Language.go
Normal file
@ -0,0 +1,7 @@
|
||||
package storage
|
||||
|
||||
type Language struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
ProcessCode string `json:"processCode"`
|
||||
TranslateCode string `json:"translateCode"`
|
||||
}
|
||||
49
storage/Entities/ProcessedText.go
Normal file
49
storage/Entities/ProcessedText.go
Normal file
@ -0,0 +1,49 @@
|
||||
package storage
|
||||
|
||||
type ProcessedBoundingBox struct {
|
||||
X0 int32 `json:"x0"`
|
||||
Y0 int32 `json:"y0"`
|
||||
X1 int32 `json:"x1"`
|
||||
Y1 int32 `json:"y1"`
|
||||
}
|
||||
|
||||
type ProcessedSymbol struct {
|
||||
Text string `json:"text"`
|
||||
Confidence float32 `json:"confidence"`
|
||||
BoundingBox ProcessedBoundingBox `json:"boundingBox"`
|
||||
}
|
||||
|
||||
type ProcessedWord struct {
|
||||
FullText string `json:"fullText"`
|
||||
Symbols []ProcessedSymbol `json:"symbols"`
|
||||
Confidence float32 `json:"confidence"`
|
||||
Direction string `json:"direction"`
|
||||
BoundingBox ProcessedBoundingBox `json:"boundingBox"`
|
||||
}
|
||||
|
||||
type ProcessedLine struct {
|
||||
FullText string `json:"fullText"`
|
||||
Words []ProcessedWord `json:"words"`
|
||||
}
|
||||
|
||||
type ProcessedArea struct {
|
||||
Id string `json:"id"`
|
||||
DocumentId string `json:"documentId"`
|
||||
FullText string `json:"fullText"`
|
||||
Order int `json:"order"`
|
||||
Lines []ProcessedLine `json:"lines"`
|
||||
}
|
||||
|
||||
type ProcessedTextCollection struct {
|
||||
Areas []ProcessedArea
|
||||
}
|
||||
|
||||
type ProcessedUserMarkdown struct {
|
||||
Id string `json:"id"`
|
||||
DocumentId string `json:"documentId"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ProcessedUserMarkdownCollection struct {
|
||||
Values []ProcessedUserMarkdown `json:"values"`
|
||||
}
|
||||
14
storage/Entities/Project.go
Normal file
14
storage/Entities/Project.go
Normal file
@ -0,0 +1,14 @@
|
||||
package storage
|
||||
|
||||
type Project struct {
|
||||
Id string `json:"id"`
|
||||
OrganizationId string `json:"organizationId"`
|
||||
Name string `json:"name"`
|
||||
Settings ProjectSettings `json:"settings"`
|
||||
}
|
||||
|
||||
type ProjectSettings struct {
|
||||
DefaultProcessLanguage Language `json:"defaultProcessLanguage"`
|
||||
DefaultTranslateTargetLanguage Language `json:"defaultTranslateTargetLanguage"`
|
||||
IsHosted bool `json:"isHosted"`
|
||||
}
|
||||
11
storage/Entities/User.go
Normal file
11
storage/Entities/User.go
Normal file
@ -0,0 +1,11 @@
|
||||
package storage
|
||||
|
||||
type User struct {
|
||||
Id string `json:"id"`
|
||||
LocalId string `json:"localId"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
AvatarPath string `json:"avatarPath"`
|
||||
AuthToken string `json:"authToken"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
22
storage/Local/DocumentDriver.go
Normal file
22
storage/Local/DocumentDriver.go
Normal file
@ -0,0 +1,22 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
entity "textualize/storage/Entities"
|
||||
)
|
||||
|
||||
func (d LocalDriver) WriteDocumentCollection(documentCollection entity.DocumentCollection, projectName string) bool {
|
||||
jsonData, _ := json.MarshalIndent(documentCollection, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/projects/"+projectName+"/", "Documents.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadDocumentCollection(projectName string) entity.DocumentCollection {
|
||||
documentCollectionData := entity.DocumentCollection{}
|
||||
readError := AssignFileDataToStruct("/projects/"+projectName+"/Documents.json", &documentCollectionData)
|
||||
if readError != nil {
|
||||
return entity.DocumentCollection{}
|
||||
}
|
||||
|
||||
return documentCollectionData
|
||||
}
|
||||
96
storage/Local/Driver.go
Normal file
96
storage/Local/Driver.go
Normal file
@ -0,0 +1,96 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type LocalDriver struct{}
|
||||
|
||||
func getLocalStoragePath() string {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
applicationName := "/Textualize"
|
||||
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return homeDir + applicationName
|
||||
}
|
||||
|
||||
// `relativeSubdirectoryPath` should start and end with a `/`.
|
||||
//
|
||||
// Use empty string if you wish to just use the Application directory
|
||||
func createLocalStorageSubDirIfNeeded(relativeSubdirectoryPath string) bool {
|
||||
localStoragePath := getLocalStoragePath()
|
||||
if localStoragePath == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
fullLocalStoragePath := localStoragePath + relativeSubdirectoryPath
|
||||
|
||||
_, directoryError := os.Stat(fullLocalStoragePath)
|
||||
directoryDoesNotExist := os.IsNotExist(directoryError)
|
||||
if !directoryDoesNotExist {
|
||||
return true
|
||||
}
|
||||
|
||||
errorCreatingDir := os.MkdirAll(fullLocalStoragePath, os.ModePerm)
|
||||
return errorCreatingDir == nil
|
||||
}
|
||||
|
||||
// `relativePathInAppDir` should both start and end with a `/`
|
||||
//
|
||||
// `fileName` should not start with a `/` to avoid bad pathing
|
||||
func WriteDataToAppDir(data []byte, relativePathInAppDir string, fileName string) error {
|
||||
localStoragePath := getLocalStoragePath()
|
||||
|
||||
if localStoragePath == "" {
|
||||
return errors.New("could not find application directory")
|
||||
}
|
||||
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(relativePathInAppDir)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return errors.New("could not create subdirectory '" + localStoragePath + "' in application directory")
|
||||
}
|
||||
|
||||
err := os.WriteFile(localStoragePath+relativePathInAppDir+fileName, data, 0644)
|
||||
return err
|
||||
}
|
||||
|
||||
// `relativePathInAppDir` should both start with a `/` and end with the file name
|
||||
func ReadDataFromAppDir(relativePathInAppDir string) ([]byte, error) {
|
||||
localStoragePath := getLocalStoragePath()
|
||||
|
||||
if localStoragePath == "" {
|
||||
return make([]byte, 0), errors.New("could not find application directory")
|
||||
}
|
||||
|
||||
data, err := os.ReadFile((localStoragePath + relativePathInAppDir))
|
||||
if err != nil {
|
||||
return make([]byte, 0), err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// `relativePathInAppDir` should both start with a `/` and end with the file name
|
||||
func AssignFileDataToStruct(relativePathInAppDir string, structPointer interface{}) error {
|
||||
fileData, err := ReadDataFromAppDir(relativePathInAppDir)
|
||||
if err != nil {
|
||||
fmt.Println("ReadDataFromAppDir err: " + err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// response := structInterface
|
||||
errorUnmarshaling := json.Unmarshal([]byte(fileData), structPointer)
|
||||
if errorUnmarshaling != nil {
|
||||
fmt.Println("errorUnmarshaling err: " + errorUnmarshaling.Error())
|
||||
|
||||
return errorUnmarshaling
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
22
storage/Local/GroupDriver.go
Normal file
22
storage/Local/GroupDriver.go
Normal file
@ -0,0 +1,22 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
entity "textualize/storage/Entities"
|
||||
)
|
||||
|
||||
func (d LocalDriver) WriteGroupCollection(collection entity.GroupCollection, projectName string) bool {
|
||||
jsonData, _ := json.MarshalIndent(collection, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/projects/"+projectName+"/", "Groups.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadGroupCollection(projectName string) entity.GroupCollection {
|
||||
collectionData := entity.GroupCollection{}
|
||||
readError := AssignFileDataToStruct("/projects/"+projectName+"/Groups.json", &collectionData)
|
||||
if readError != nil {
|
||||
return entity.GroupCollection{}
|
||||
}
|
||||
|
||||
return collectionData
|
||||
}
|
||||
@ -1,222 +0,0 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func GetLocalStoragePath() string {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
applicationName := "/Textualize"
|
||||
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return homeDir + applicationName
|
||||
}
|
||||
|
||||
func createLocalStorageDirIfNeeded() bool {
|
||||
localStoragePath := GetLocalStoragePath()
|
||||
if localStoragePath == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
_, directoryError := os.Stat(GetLocalStoragePath())
|
||||
directoryDoesNotExist := os.IsNotExist(directoryError)
|
||||
if !directoryDoesNotExist {
|
||||
return true
|
||||
}
|
||||
|
||||
errorCreatingDir := os.Mkdir(localStoragePath, os.ModePerm)
|
||||
return errorCreatingDir == nil
|
||||
}
|
||||
|
||||
func createLocalStorageSubDirIfNeeded(relativeSubdirectoryPath string) bool {
|
||||
localStoragePath := GetLocalStoragePath()
|
||||
if localStoragePath == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
fullLocalStoragePath := GetLocalStoragePath() + relativeSubdirectoryPath
|
||||
|
||||
_, directoryError := os.Stat(fullLocalStoragePath)
|
||||
directoryDoesNotExist := os.IsNotExist(directoryError)
|
||||
if !directoryDoesNotExist {
|
||||
return true
|
||||
}
|
||||
|
||||
errorCreatingDir := os.MkdirAll(fullLocalStoragePath, os.ModePerm)
|
||||
return errorCreatingDir == nil
|
||||
}
|
||||
|
||||
func WriteLocalUserData(user LocalUser) bool {
|
||||
file, _ := json.MarshalIndent(user, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
isLocalStorageDirectoryCreated := createLocalStorageDirIfNeeded()
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+"/User.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadLocalUserData() LocalUser {
|
||||
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/User.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalUser{}
|
||||
}
|
||||
|
||||
response := LocalUser{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalUser{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func ReadLocalProjectByName(name string) LocalProject {
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + name + "/Project.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalProject{}
|
||||
}
|
||||
|
||||
response := LocalProject{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalProject{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func WriteLocalProjectData(project LocalProject) bool {
|
||||
file, _ := json.MarshalIndent(project, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
fmt.Println(project)
|
||||
|
||||
subdirectory := "/projects/" + project.Name + "/"
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+subdirectory+"Project.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadAllLocalProjects() []LocalProject {
|
||||
localProjects := make([]LocalProject, 0)
|
||||
|
||||
subdirectory := "/projects/"
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return localProjects
|
||||
}
|
||||
|
||||
localProjectFileEntries, readDirError := os.ReadDir(GetLocalStoragePath() + subdirectory)
|
||||
if readDirError != nil {
|
||||
fmt.Println(localProjectFileEntries)
|
||||
return localProjects
|
||||
}
|
||||
|
||||
localProjectNames := make([]string, 0)
|
||||
for _, fileEntry := range localProjectFileEntries {
|
||||
localProjectNames = append(localProjectNames, fileEntry.Name())
|
||||
// localProjectNames = append(localProjectNames, strings.ReplaceAll(fileName.Name(), ".json", ""))
|
||||
}
|
||||
|
||||
for _, projectName := range localProjectNames {
|
||||
localProjects = append(localProjects, ReadLocalProjectByName(projectName))
|
||||
}
|
||||
|
||||
return localProjects
|
||||
}
|
||||
|
||||
func WriteLocalDocumentCollection(documentCollection LocalDocumentCollection, projectName string) bool {
|
||||
file, _ := json.MarshalIndent(documentCollection, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
subdirectory := "/projects/" + projectName
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+subdirectory+"/Documents.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadLocalDocumentCollection(projectName string) LocalDocumentCollection {
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + projectName + "/Documents.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalDocumentCollection{}
|
||||
}
|
||||
|
||||
response := LocalDocumentCollection{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalDocumentCollection{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func WriteLocalGroupCollection(groupCollection LocalGroupCollection, projectName string) bool {
|
||||
file, _ := json.MarshalIndent(groupCollection, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
subdirectory := "/projects/" + projectName
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+subdirectory+"/Groups.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadLocalGroupCollection(projectName string) LocalGroupCollection {
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + projectName + "/Groups.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalGroupCollection{}
|
||||
}
|
||||
|
||||
response := LocalGroupCollection{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalGroupCollection{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
@ -1,118 +0,0 @@
|
||||
package storage
|
||||
|
||||
type LocalProject struct {
|
||||
Id string `json:"id"`
|
||||
OrganizationId string `json:"organizationId"`
|
||||
Name string `json:"name"`
|
||||
Settings LocalProjectSettings `json:"settings"`
|
||||
}
|
||||
|
||||
type LocalProjectSettings struct {
|
||||
DefaultProcessLanguage Language `json:"defaultProcessLanguage"`
|
||||
DefaultTranslateTargetLanguage Language `json:"defaultTranslateTargetLanguage"`
|
||||
IsHosted bool `json:"isHosted"`
|
||||
}
|
||||
|
||||
type Language struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
ProcessCode string `json:"processCode"`
|
||||
TranslateCode string `json:"translateCode"`
|
||||
}
|
||||
|
||||
type LocalUser struct {
|
||||
Id string `json:"id"`
|
||||
LocalId string `json:"localId"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
AvatarPath string `json:"avatarPath"`
|
||||
AuthToken string `json:"authToken"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type LocalDocument struct {
|
||||
Id string `json:"id"`
|
||||
GroupId string `json:"groupId"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
ProjectId string `json:"projectId"`
|
||||
Areas []LocalArea `json:"areas"`
|
||||
DefaultLanguage Language `json:"defaultLanguage"`
|
||||
}
|
||||
|
||||
type LocalDocumentCollection struct {
|
||||
Documents []LocalDocument `json:"documents"`
|
||||
ProjectId string `json:"projectId"`
|
||||
}
|
||||
|
||||
type LocalArea struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
StartX int `json:"startX"`
|
||||
StartY int `json:"startY"`
|
||||
EndX int `json:"endX"`
|
||||
EndY int `json:"endY"`
|
||||
Language Language `json:"language"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type LocalGroup struct {
|
||||
Id string `json:"id"`
|
||||
ParentId string `json:"parentId"`
|
||||
ProjectId string `json:"projectId"`
|
||||
Name string `json:"name"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type LocalGroupCollection struct {
|
||||
Id string `json:"id"`
|
||||
Groups []LocalGroup `json:"groups"`
|
||||
ProjectId string `json:"projectId"`
|
||||
}
|
||||
|
||||
type LocalProcessedBoundingBox struct {
|
||||
X0 int32 `json:"x0"`
|
||||
Y0 int32 `json:"y0"`
|
||||
X1 int32 `json:"x1"`
|
||||
Y1 int32 `json:"y1"`
|
||||
}
|
||||
|
||||
type LocalProcessedSymbol struct {
|
||||
Text string `json:"text"`
|
||||
Confidence float32 `json:"confidence"`
|
||||
BoundingBox LocalProcessedBoundingBox `json:"boundingBox"`
|
||||
}
|
||||
|
||||
type LocalProcessedWord struct {
|
||||
FullText string `json:"fullText"`
|
||||
Symbols []LocalProcessedSymbol `json:"symbols"`
|
||||
Confidence float32 `json:"confidence"`
|
||||
Direction string `json:"direction"`
|
||||
BoundingBox LocalProcessedBoundingBox `json:"boundingBox"`
|
||||
}
|
||||
|
||||
type LocalProcessedLine struct {
|
||||
FullText string `json:"fullText"`
|
||||
Words []LocalProcessedWord `json:"words"`
|
||||
}
|
||||
|
||||
type LocalProcessedArea struct {
|
||||
Id string `json:"id"`
|
||||
DocumentId string `json:"documentId"`
|
||||
FullText string `json:"fullText"`
|
||||
Order int `json:"order"`
|
||||
Lines []LocalProcessedLine `json:"lines"`
|
||||
}
|
||||
|
||||
type LocalProcessedAreaCollection struct {
|
||||
Areas []LocalProcessedArea
|
||||
}
|
||||
|
||||
type LocalUserMarkdown struct {
|
||||
Id string `json:"id"`
|
||||
DocumentId string `json:"documentId"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type LocalUserMarkdownCollection struct {
|
||||
Values []LocalUserMarkdown `json:"values"`
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
func WriteLocalProcessedAreaCollection(processedTextCollection LocalProcessedAreaCollection, projectName string) bool {
|
||||
file, _ := json.MarshalIndent(processedTextCollection, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
subdirectory := "/projects/" + projectName
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+subdirectory+"/ProcessedTexts.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadLocalProcessedAreaCollection(projectName string) LocalProcessedAreaCollection {
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + projectName + "/ProcessedTexts.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalProcessedAreaCollection{}
|
||||
}
|
||||
|
||||
response := LocalProcessedAreaCollection{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalProcessedAreaCollection{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
func WriteLocalUserProcessedMarkdownCollection(userMarkdownCollection LocalUserMarkdownCollection, projectName string) bool {
|
||||
file, _ := json.MarshalIndent(userMarkdownCollection, "", " ")
|
||||
path := GetLocalStoragePath()
|
||||
|
||||
if path == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
subdirectory := "/projects/" + projectName
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return false
|
||||
}
|
||||
|
||||
err := os.WriteFile(GetLocalStoragePath()+subdirectory+"/UserProcessedMarkdown.json", file, 0644)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ReadLocalUserProcessedMarkdownCollection(projectName string) LocalUserMarkdownCollection {
|
||||
file, err := os.ReadFile(GetLocalStoragePath() + "/projects/" + projectName + "/UserProcessedMarkdown.json")
|
||||
|
||||
if err != nil {
|
||||
return LocalUserMarkdownCollection{}
|
||||
}
|
||||
|
||||
response := LocalUserMarkdownCollection{}
|
||||
errorUnmarshaling := json.Unmarshal([]byte(file), &response)
|
||||
if errorUnmarshaling != nil {
|
||||
return LocalUserMarkdownCollection{}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
38
storage/Local/ProcessedTextDriver.go
Normal file
38
storage/Local/ProcessedTextDriver.go
Normal file
@ -0,0 +1,38 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
entity "textualize/storage/Entities"
|
||||
)
|
||||
|
||||
func (d LocalDriver) WriteProcessedTextCollection(collection entity.ProcessedTextCollection, projectName string) bool {
|
||||
jsonData, _ := json.MarshalIndent(collection, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/projects/"+projectName+"/", "ProcessedTexts.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadProcessedTextCollection(projectName string) entity.ProcessedTextCollection {
|
||||
collectionData := entity.ProcessedTextCollection{}
|
||||
readError := AssignFileDataToStruct("/projects/"+projectName+"/ProcessedTexts.json", &collectionData)
|
||||
if readError != nil {
|
||||
return entity.ProcessedTextCollection{}
|
||||
}
|
||||
|
||||
return collectionData
|
||||
}
|
||||
|
||||
func (d LocalDriver) WriteProcessedUserMarkdownCollection(collection entity.ProcessedUserMarkdownCollection, projectName string) bool {
|
||||
jsonData, _ := json.MarshalIndent(collection, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/projects/"+projectName+"/", "UserProcessedMarkdown.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadProcessedUserMarkdownCollection(projectName string) entity.ProcessedUserMarkdownCollection {
|
||||
collectionData := entity.ProcessedUserMarkdownCollection{}
|
||||
readError := AssignFileDataToStruct("/projects/"+projectName+"/UserProcessedMarkdown.json", &collectionData)
|
||||
if readError != nil {
|
||||
return entity.ProcessedUserMarkdownCollection{}
|
||||
}
|
||||
|
||||
return collectionData
|
||||
}
|
||||
49
storage/Local/ProjectDriver.go
Normal file
49
storage/Local/ProjectDriver.go
Normal file
@ -0,0 +1,49 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
storage "textualize/storage/Entities"
|
||||
)
|
||||
|
||||
func (d LocalDriver) WriteProjectData(project storage.Project) bool {
|
||||
jsonData, _ := json.MarshalIndent(project, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/projects/"+project.Name+"/", "Project.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadProjectDataByName(projectName string) storage.Project {
|
||||
projectData := storage.Project{}
|
||||
readError := AssignFileDataToStruct("/projects/"+projectName+"/Project.json", &projectData)
|
||||
if readError != nil {
|
||||
return storage.Project{}
|
||||
}
|
||||
|
||||
return projectData
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadAllProjects() []storage.Project {
|
||||
localProjects := make([]storage.Project, 0)
|
||||
|
||||
subdirectory := "/projects/"
|
||||
isLocalStorageDirectoryCreated := createLocalStorageSubDirIfNeeded(subdirectory)
|
||||
if !isLocalStorageDirectoryCreated {
|
||||
return localProjects
|
||||
}
|
||||
|
||||
localProjectDirEntries, readDirError := os.ReadDir(getLocalStoragePath() + subdirectory)
|
||||
if readDirError != nil {
|
||||
return localProjects
|
||||
}
|
||||
|
||||
localProjectDirNames := make([]string, 0)
|
||||
for _, fileEntry := range localProjectDirEntries {
|
||||
localProjectDirNames = append(localProjectDirNames, fileEntry.Name())
|
||||
}
|
||||
|
||||
for _, projectName := range localProjectDirNames {
|
||||
localProjects = append(localProjects, d.ReadProjectDataByName(projectName))
|
||||
}
|
||||
|
||||
return localProjects
|
||||
}
|
||||
22
storage/Local/UserDriver.go
Normal file
22
storage/Local/UserDriver.go
Normal file
@ -0,0 +1,22 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
storage "textualize/storage/Entities"
|
||||
)
|
||||
|
||||
func (d LocalDriver) WriteUserData(user storage.User) bool {
|
||||
jsonData, _ := json.MarshalIndent(user, "", " ")
|
||||
writeError := WriteDataToAppDir(jsonData, "/", "User.json")
|
||||
return writeError == nil
|
||||
}
|
||||
|
||||
func (d LocalDriver) ReadUserData() storage.User {
|
||||
userData := storage.User{}
|
||||
readError := AssignFileDataToStruct("/User.json", &userData)
|
||||
if readError != nil {
|
||||
return storage.User{}
|
||||
}
|
||||
|
||||
return userData
|
||||
}
|
||||
31
storage/Storage.go
Normal file
31
storage/Storage.go
Normal file
@ -0,0 +1,31 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
entity "textualize/storage/Entities"
|
||||
local "textualize/storage/Local"
|
||||
)
|
||||
|
||||
type Driver interface {
|
||||
WriteUserData(entity.User) bool
|
||||
ReadUserData() entity.User
|
||||
WriteProjectData(entity.Project) bool
|
||||
ReadProjectDataByName(string) entity.Project
|
||||
ReadAllProjects() []entity.Project
|
||||
WriteDocumentCollection(entity.DocumentCollection, string) bool
|
||||
ReadDocumentCollection(string) entity.DocumentCollection
|
||||
WriteGroupCollection(entity.GroupCollection, string) bool
|
||||
ReadGroupCollection(string) entity.GroupCollection
|
||||
WriteProcessedTextCollection(entity.ProcessedTextCollection, string) bool
|
||||
ReadProcessedTextCollection(string) entity.ProcessedTextCollection
|
||||
WriteProcessedUserMarkdownCollection(entity.ProcessedUserMarkdownCollection, string) bool
|
||||
ReadProcessedUserMarkdownCollection(string) entity.ProcessedUserMarkdownCollection
|
||||
}
|
||||
|
||||
var driverInstance Driver
|
||||
|
||||
func GetDriver() Driver {
|
||||
if driverInstance == nil {
|
||||
driverInstance = local.LocalDriver{}
|
||||
}
|
||||
return driverInstance
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user