Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Grégoire Locqueville
haskell-gargantext
Commits
c38dec2f
Commit
c38dec2f
authored
Mar 04, 2024
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/312-dev-export-json-as-zip' into dev
parents
63ca3e92
7294697a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
191 additions
and
82 deletions
+191
-82
gargantext.cabal
gargantext.cabal
+1
-0
List.hs
src/Gargantext/API/Ngrams/List.hs
+22
-8
Prelude.hs
src/Gargantext/API/Ngrams/Prelude.hs
+3
-4
Types.hs
src/Gargantext/API/Ngrams/Types.hs
+50
-12
Export.hs
src/Gargantext/API/Node/Document/Export.hs
+26
-12
Types.hs
src/Gargantext/API/Node/Document/Export/Types.hs
+39
-10
Servant.hs
src/Gargantext/Utils/Servant.hs
+22
-28
Zip.hs
src/Gargantext/Utils/Zip.hs
+28
-8
No files found.
gargantext.cabal
View file @
c38dec2f
...
@@ -630,6 +630,7 @@ library
...
@@ -630,6 +630,7 @@ library
, xml-types ^>= 0.3.8
, xml-types ^>= 0.3.8
, yaml ^>= 0.11.8.0
, yaml ^>= 0.11.8.0
, zip ^>= 1.7.2
, zip ^>= 1.7.2
, zip-archive ^>= 0.4.3
, zlib ^>= 0.6.2.3
, zlib ^>= 0.6.2.3
executable gargantext-admin
executable gargantext-admin
...
...
src/Gargantext/API/Ngrams/List.hs
View file @
c38dec2f
...
@@ -55,16 +55,18 @@ import Servant
...
@@ -55,16 +55,18 @@ import Servant
------------------------------------------------------------------------
------------------------------------------------------------------------
type
GETAPI
=
Summary
"Get List"
type
GETAPI
=
Summary
"Get List"
:>
"lists"
:>
"lists"
:>
Capture
"listId"
ListId
:>
"json"
:>
Get
'[
J
SON
,
HTML
]
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsList
)
:<|>
"lists"
:>
Capture
"listId"
ListId
:>
Capture
"listId"
ListId
:>
"csv"
:>
(
"json"
:>
Get
'[
G
US
.
CSV
]
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsTableMap
)
:>
Get
'[
J
SON
,
HTML
]
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsList
)
:<|>
"json.zip"
:>
Get
'[
G
US
.
ZIP
]
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsListZIP
)
:<|>
"csv"
:>
Get
'[
G
US
.
CSV
]
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsTableMap
)
)
getApi
::
GargServer
GETAPI
getApi
::
GargServer
GETAPI
getApi
=
getJson
:<|>
getCsv
getApi
listId
=
getJson
listId
:<|>
getJsonZip
listId
:<|>
getCsv
listId
--
--
-- JSON API
-- JSON API
...
@@ -94,6 +96,18 @@ getJson lId = do
...
@@ -94,6 +96,18 @@ getJson lId = do
]
]
)
lst
)
lst
getJsonZip
::
HasNodeStory
env
err
m
=>
ListId
->
m
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsListZIP
)
getJsonZip
lId
=
do
lst
<-
getNgramsList
lId
let
nlz
=
NgramsListZIP
{
_nlz_nl
=
lst
,
_nlz_list_id
=
lId
}
pure
$
addHeader
(
concat
[
"attachment; filename="
,
nlzFileName
nlz
,
".zip"
]
)
nlz
getCsv
::
HasNodeStory
env
err
m
getCsv
::
HasNodeStory
env
err
m
=>
ListId
=>
ListId
->
m
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsTableMap
)
->
m
(
Headers
'[
H
eader
"Content-Disposition"
Text
]
NgramsTableMap
)
...
...
src/Gargantext/API/Ngrams/Prelude.hs
View file @
c38dec2f
...
@@ -20,13 +20,12 @@ import Data.List qualified as List
...
@@ -20,13 +20,12 @@ import Data.List qualified as List
import
Data.Map.Strict
(
fromList
)
import
Data.Map.Strict
(
fromList
)
import
Data.Map.Strict
qualified
as
Map
import
Data.Map.Strict
qualified
as
Map
import
Data.Text
qualified
as
Text
import
Data.Text
qualified
as
Text
import
Data.Validity
import
Gargantext.API.Ngrams
(
getNgramsTableMap
)
import
Gargantext.API.Ngrams
(
getNgramsTableMap
)
import
Gargantext.API.Ngrams.Types
import
Gargantext.API.Ngrams.Types
import
Gargantext.Core.NodeStory
(
HasNodeStory
)
import
Gargantext.Core.NodeStory
.Types
(
HasNodeStory
)
import
Gargantext.Core.Text.Context
(
TermList
)
import
Gargantext.Core.Text.Context
(
TermList
)
import
Gargantext.Core.Text.List.Social.Prelude
import
Gargantext.Core.Text.List.Social.Prelude
(
unPatchMapToHashMap
)
import
Gargantext.Core.Types
(
ListType
)
import
Gargantext.Core.Types
.Main
(
ListType
)
import
Gargantext.Database.Admin.Types.Node
(
ListId
)
import
Gargantext.Database.Admin.Types.Node
(
ListId
)
import
Gargantext.Database.Schema.Ngrams
(
NgramsType
,
ngramsTypes
)
import
Gargantext.Database.Schema.Ngrams
(
NgramsType
,
ngramsTypes
)
import
Gargantext.Prelude
import
Gargantext.Prelude
...
...
src/Gargantext/API/Ngrams/Types.hs
View file @
c38dec2f
...
@@ -20,20 +20,19 @@ module Gargantext.API.Ngrams.Types where
...
@@ -20,20 +20,19 @@ module Gargantext.API.Ngrams.Types where
import
Codec.Serialise
(
Serialise
())
import
Codec.Serialise
(
Serialise
())
import
Control.Category
((
>>>
))
import
Control.Category
((
>>>
))
import
Control.Lens
(
makeLenses
,
makePrisms
,
Iso
'
,
iso
,
from
,
(
.~
),
(
.=
),
(
?=
),
(
#
),
to
,
folded
,
{-withIndex, ifolded,-}
view
,
use
,
(
^.
),
(
^?
),
(
%~
),
(
.~
),
(
%=
),
at
,
_Just
,
Each
(
..
),
itraverse_
,
both
,
forOf_
,
(
?~
),
over
)
import
Control.Lens
(
makeLenses
,
makePrisms
,
Iso
'
,
iso
,
from
,
(
.~
),
(
.=
),
(
?=
),
(
#
),
to
,
folded
,
{-withIndex, ifolded,-}
view
,
use
,
(
^.
),
(
^?
),
(
%~
),
(
.~
),
(
%=
),
at
,
_Just
,
Each
(
..
),
itraverse_
,
both
,
forOf_
,
(
?~
),
over
)
import
Control.Monad.State
import
Data.Aeson
hiding
((
.=
))
import
Data.Aeson
hiding
((
.=
))
import
Data.Aeson.TH
(
deriveJSON
)
import
Data.Aeson.TH
(
deriveJSON
)
import
Data.Foldable
import
Data.Csv
(
defaultEncodeOptions
,
encodeByNameWith
,
header
,
namedRecord
,
EncodeOptions
(
..
),
NamedRecord
,
Quoting
(
QuoteNone
))
import
Data.Csv
qualified
as
Csv
import
Data.HashMap.Strict.InsOrd
qualified
as
InsOrdHashMap
import
Data.HashMap.Strict.InsOrd
qualified
as
InsOrdHashMap
import
Data.Map.Strict
qualified
as
Map
import
Data.Map.Strict
qualified
as
Map
import
Data.Map.Strict.Patch
qualified
as
PM
import
Data.Map.Strict.Patch
qualified
as
PM
import
Data.Monoid
import
Data.Patch.Class
(
Replace
,
replace
,
Action
(
act
),
Group
,
Applicable
(
..
),
Composable
(
..
),
Transformable
(
..
),
PairPatch
(
..
),
Patched
,
ConflictResolution
,
ConflictResolutionReplace
,
MaybePatch
(
Mod
),
unMod
,
old
,
new
)
import
Data.Patch.Class
(
Replace
,
replace
,
Action
(
act
),
Group
,
Applicable
(
..
),
Composable
(
..
),
Transformable
(
..
),
PairPatch
(
..
),
Patched
,
ConflictResolution
,
ConflictResolutionReplace
,
MaybePatch
(
Mod
),
unMod
,
old
,
new
)
import
Data.Set
qualified
as
Set
import
Data.Set
qualified
as
Set
import
Data.String
(
IsString
(
..
))
import
Data.String
(
IsString
(
..
))
import
Data.Swagger
hiding
(
version
,
patch
)
import
Data.Swagger
(
NamedSchema
(
NamedSchema
),
declareSchemaRef
,
genericDeclareNamedSchema
,
SwaggerType
(
SwaggerObject
),
ToParamSchema
,
ToSchema
(
..
),
HasProperties
(
properties
),
HasRequired
(
required
),
HasType
(
type_
)
)
import
Data.Text
(
pack
,
strip
)
import
Data.Text
qualified
as
T
import
Data.Validity
import
Data.Validity
(
Validity
(
..
)
)
import
Database.PostgreSQL.Simple.FromField
(
FromField
,
fromField
,
fromJSONField
)
import
Database.PostgreSQL.Simple.FromField
(
FromField
,
fromField
,
fromJSONField
)
import
Database.PostgreSQL.Simple.ToField
(
ToField
,
toJSONField
,
toField
)
import
Database.PostgreSQL.Simple.ToField
(
ToField
,
toJSONField
,
toField
)
import
Gargantext.Core.Text
(
size
)
import
Gargantext.Core.Text
(
size
)
...
@@ -42,10 +41,12 @@ import Gargantext.Core.Types.Query (Limit, Offset, MaxSize, MinSize)
...
@@ -42,10 +41,12 @@ import Gargantext.Core.Types.Query (Limit, Offset, MaxSize, MinSize)
import
Gargantext.Core.Utils.Prefix
(
unPrefix
,
unPrefixUntagged
,
unPrefixSwagger
,
wellNamedSchema
)
import
Gargantext.Core.Utils.Prefix
(
unPrefix
,
unPrefixUntagged
,
unPrefixSwagger
,
wellNamedSchema
)
import
Gargantext.Database.Admin.Types.Node
(
ContextId
)
import
Gargantext.Database.Admin.Types.Node
(
ContextId
)
import
Gargantext.Database.Prelude
(
fromField'
,
HasConnectionPool
,
HasConfig
,
CmdM
'
)
import
Gargantext.Database.Prelude
(
fromField'
,
HasConnectionPool
,
HasConfig
,
CmdM
'
)
import
Gargantext.Database.
Query.Table
.Ngrams
qualified
as
TableNgrams
import
Gargantext.Database.
Schema
.Ngrams
qualified
as
TableNgrams
import
Gargantext.Prelude
hiding
(
IsString
,
hash
,
from
,
replace
,
to
)
import
Gargantext.Prelude
hiding
(
IsString
,
hash
,
from
,
replace
,
to
)
import
Gargantext.Prelude.Crypto.Hash
(
IsHashable
(
..
))
import
Gargantext.Prelude.Crypto.Hash
(
IsHashable
(
..
))
import
Servant
hiding
(
Patch
)
import
Gargantext.Utils.Servant
(
CSV
,
ZIP
)
import
Gargantext.Utils.Zip
(
zipContentsPure
)
import
Servant
(
FromHttpApiData
(
parseUrlPiece
),
ToHttpApiData
(
toUrlPiece
),
Required
,
Strict
,
QueryParam
'
,
MimeRender
(
..
))
import
Servant.Job.Utils
(
jsonOptions
)
import
Servant.Job.Utils
(
jsonOptions
)
import
Test.QuickCheck
(
elements
,
frequency
)
import
Test.QuickCheck
(
elements
,
frequency
)
import
Test.QuickCheck.Arbitrary
(
Arbitrary
,
arbitrary
)
import
Test.QuickCheck.Arbitrary
(
Arbitrary
,
arbitrary
)
...
@@ -79,7 +80,7 @@ instance FromHttpApiData TabType where
...
@@ -79,7 +80,7 @@ instance FromHttpApiData TabType where
parseUrlPiece
_
=
Left
"Unexpected value of TabType"
parseUrlPiece
_
=
Left
"Unexpected value of TabType"
instance
ToHttpApiData
TabType
where
instance
ToHttpApiData
TabType
where
toUrlPiece
=
pack
.
show
toUrlPiece
=
T
.
pack
.
show
instance
ToParamSchema
TabType
instance
ToParamSchema
TabType
instance
ToJSON
TabType
instance
ToJSON
TabType
instance
FromJSON
TabType
instance
FromJSON
TabType
...
@@ -128,9 +129,9 @@ instance IsHashable NgramsTerm where
...
@@ -128,9 +129,9 @@ instance IsHashable NgramsTerm where
instance
Monoid
NgramsTerm
where
instance
Monoid
NgramsTerm
where
mempty
=
NgramsTerm
""
mempty
=
NgramsTerm
""
instance
FromJSONKey
NgramsTerm
where
instance
FromJSONKey
NgramsTerm
where
fromJSONKey
=
FromJSONKeyTextParser
$
\
t
->
pure
$
NgramsTerm
$
strip
t
fromJSONKey
=
FromJSONKeyTextParser
$
\
t
->
pure
$
NgramsTerm
$
T
.
strip
t
instance
IsString
NgramsTerm
where
instance
IsString
NgramsTerm
where
fromString
s
=
NgramsTerm
$
pack
s
fromString
s
=
NgramsTerm
$
T
.
pack
s
data
RootParent
=
RootParent
data
RootParent
=
RootParent
...
@@ -266,7 +267,7 @@ instance FromHttpApiData OrderBy
...
@@ -266,7 +267,7 @@ instance FromHttpApiData OrderBy
parseUrlPiece
_
=
Left
"Unexpected value of OrderBy"
parseUrlPiece
_
=
Left
"Unexpected value of OrderBy"
instance
ToHttpApiData
OrderBy
where
instance
ToHttpApiData
OrderBy
where
toUrlPiece
=
pack
.
show
toUrlPiece
=
T
.
pack
.
show
instance
ToParamSchema
OrderBy
instance
ToParamSchema
OrderBy
instance
FromJSON
OrderBy
instance
FromJSON
OrderBy
...
@@ -286,6 +287,27 @@ data NgramsSearchQuery = NgramsSearchQuery
...
@@ -286,6 +287,27 @@ data NgramsSearchQuery = NgramsSearchQuery
------------------------------------------------------------------------
------------------------------------------------------------------------
type
NgramsTableMap
=
Map
NgramsTerm
NgramsRepoElement
type
NgramsTableMap
=
Map
NgramsTerm
NgramsRepoElement
-- CSV:
-- header: status\tlabel\tforms
-- item: map\taccountability\taccounting|&|accoutns|&|account
instance
MimeRender
CSV
NgramsTableMap
where
-- mimeRender _ _val = encode ([] :: [(Text, Text)])
mimeRender
_
val
=
encodeByNameWith
encOptions
(
header
[
"status"
,
"label"
,
"forms"
])
$
fn
<$>
Map
.
toList
val
where
encOptions
=
defaultEncodeOptions
{
encDelimiter
=
fromIntegral
(
ord
'
\t
'
)
,
encQuoting
=
QuoteNone
}
fn
::
(
NgramsTerm
,
NgramsRepoElement
)
->
NamedRecord
fn
(
NgramsTerm
term
,
NgramsRepoElement
{
_nre_list
,
_nre_children
})
=
namedRecord
[
"status"
Csv
..=
toText
_nre_list
,
"label"
Csv
..=
term
,
"forms"
Csv
..=
T
.
intercalate
"|&|"
(
unNgramsTerm
<$>
mSetToList
_nre_children
)]
toText
::
ListType
->
Text
toText
CandidateTerm
=
"candidate"
toText
MapTerm
=
"map"
toText
StopTerm
=
"stop"
------------------------------------------------------------------------
------------------------------------------------------------------------
-- On the Client side:
-- On the Client side:
--data Action = InGroup NgramsId NgramsId
--data Action = InGroup NgramsId NgramsId
...
@@ -763,6 +785,22 @@ instance ToSchema UpdateTableNgramsCharts where
...
@@ -763,6 +785,22 @@ instance ToSchema UpdateTableNgramsCharts where
------------------------------------------------------------------------
------------------------------------------------------------------------
type
NgramsList
=
(
Map
TableNgrams
.
NgramsType
(
Versioned
NgramsTableMap
))
type
NgramsList
=
(
Map
TableNgrams
.
NgramsType
(
Versioned
NgramsTableMap
))
-- | Same as NgramsList, but wraps node_id so that the inner .json file can have proper name
data
NgramsListZIP
=
NgramsListZIP
{
_nlz_nl
::
NgramsList
,
_nlz_list_id
::
ListId
}
deriving
(
Generic
)
instance
ToSchema
NgramsListZIP
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_nlz_"
)
nlzFileName
::
NgramsListZIP
->
Text
nlzFileName
(
NgramsListZIP
{
..
})
=
"GarganText_NgramsList-"
<>
show
_nlz_list_id
<>
".json"
instance
MimeRender
ZIP
NgramsListZIP
where
mimeRender
_
nlz
@
(
NgramsListZIP
{
..
})
=
zipContentsPure
(
T
.
unpack
$
nlzFileName
nlz
)
(
encode
_nlz_nl
)
--
--
-- Serialise instances
-- Serialise instances
--
--
...
...
src/Gargantext/API/Node/Document/Export.hs
View file @
c38dec2f
...
@@ -12,28 +12,29 @@ module Gargantext.API.Node.Document.Export
...
@@ -12,28 +12,29 @@ module Gargantext.API.Node.Document.Export
where
where
import
Control.Lens
(
view
)
import
Control.Lens
(
view
)
import
Data.ByteString.Lazy.Char8
qualified
as
BSC
import
Data.Csv
(
encodeDefaultOrderedByName
)
import
Data.Csv
(
encodeDefaultOrderedByName
)
import
Data.Text
qualified
as
T
import
Data.Text.Encoding
qualified
as
TE
import
Data.Version
(
showVersion
)
import
Data.Version
(
showVersion
)
import
Gargantext.API.Node.Document.Export.Types
import
Gargantext.API.Node.Document.Export.Types
import
Gargantext.API.Prelude
(
GargNoServer
,
GargServer
)
import
Gargantext.API.Prelude
(
GargNoServer
,
GargServer
)
import
Gargantext.Core
(
toDBid
)
import
Gargantext.Core
(
toDBid
)
import
Gargantext.
Core.Types
import
Gargantext.
Database.Admin.Types.Node
(
DocId
,
NodeId
,
NodeType
(
..
))
import
Gargantext.Database.Query.Facet
(
runViewDocuments
,
Facet
(
..
))
import
Gargantext.Database.Query.Facet
(
runViewDocuments
,
Facet
(
..
))
import
Gargantext.Database.Query.Table.Node
(
getClosestParentIdByType
)
import
Gargantext.Database.Query.Table.Node
(
getClosestParentIdByType
)
import
Gargantext.Database.Query.Table.Node.User
import
Gargantext.Database.Query.Table.Node.User
(
getNodeUser
)
import
Gargantext.Database.Schema.Node
(
NodePoly
(
..
),
node_user_id
)
import
Gargantext.Database.Schema.Node
(
NodePoly
(
..
),
node_user_id
)
import
Gargantext.Prelude
import
Gargantext.Prelude
import
Servant
import
Paths_gargantext
qualified
as
PG
-- cabal magic build module
import
qualified
Data.ByteString.Lazy.Char8
as
BSC
import
Servant
(
addHeader
,
(
:<|>
)((
:<|>
)),
Header
,
Headers
(
getResponse
)
)
import
qualified
Data.Text
as
T
import
qualified
Data.Text.Encoding
as
TE
import
qualified
Paths_gargantext
as
PG
-- cabal magic build module
api
::
NodeId
api
::
NodeId
-- ^ The ID of the target user
-- ^ The ID of the target user
->
DocId
->
DocId
->
GargServer
API
->
GargServer
API
api
userNodeId
dId
=
getDocumentsJSON
userNodeId
dId
api
userNodeId
dId
=
getDocumentsJSON
userNodeId
dId
:<|>
getDocumentsJSONZip
userNodeId
dId
:<|>
getDocumentsCSV
userNodeId
dId
:<|>
getDocumentsCSV
userNodeId
dId
--------------------------------------------------
--------------------------------------------------
...
@@ -47,11 +48,12 @@ getDocumentsJSON nodeUserId pId = do
...
@@ -47,11 +48,12 @@ getDocumentsJSON nodeUserId pId = do
mcId
<-
getClosestParentIdByType
pId
NodeCorpus
mcId
<-
getClosestParentIdByType
pId
NodeCorpus
let
cId
=
maybe
(
panicTrace
"[G.A.N.D.Export] Node has no parent"
)
identity
mcId
let
cId
=
maybe
(
panicTrace
"[G.A.N.D.Export] Node has no parent"
)
identity
mcId
docs
<-
runViewDocuments
cId
False
Nothing
Nothing
Nothing
Nothing
Nothing
docs
<-
runViewDocuments
cId
False
Nothing
Nothing
Nothing
Nothing
Nothing
pure
$
addHeader
(
T
.
concat
[
"attachment; filename=GarganText_DocsList-"
let
dexp
=
DocumentExport
{
_de_documents
=
mapFacetDoc
uId
<$>
docs
,
T
.
pack
$
show
pId
,
_de_garg_version
=
T
.
pack
$
showVersion
PG
.
version
}
,
".json"
])
pure
$
addHeader
(
T
.
concat
[
"attachment; filename="
DocumentExport
{
_de_documents
=
mapFacetDoc
uId
<$>
docs
,
"GarganText_DocsList-"
,
_de_garg_version
=
T
.
pack
$
showVersion
PG
.
version
}
,
T
.
pack
(
show
pId
)
,
".json"
])
dexp
where
where
mapFacetDoc
uId
(
FacetDoc
{
..
})
=
mapFacetDoc
uId
(
FacetDoc
{
..
})
=
Document
{
_d_document
=
Document
{
_d_document
=
...
@@ -71,6 +73,18 @@ getDocumentsJSON nodeUserId pId = do
...
@@ -71,6 +73,18 @@ getDocumentsJSON nodeUserId pId = do
,
_ng_hash
=
""
}
,
_ng_hash
=
""
}
,
_d_hash
=
""
}
,
_d_hash
=
""
}
getDocumentsJSONZip
::
NodeId
-- ^ The Node ID of the target user
->
DocId
->
GargNoServer
(
Headers
'[
H
eader
"Content-Disposition"
T
.
Text
]
DocumentExportZIP
)
-- [Document]
getDocumentsJSONZip
userNodeId
pId
=
do
dJSON
<-
getDocumentsJSON
userNodeId
pId
let
dexp
=
getResponse
dJSON
let
dexpz
=
DocumentExportZIP
{
_dez_dexp
=
dexp
,
_dez_doc_id
=
pId
}
pure
$
addHeader
(
T
.
concat
[
"attachment; filename="
,
dezFileName
dexpz
,
".zip"
])
dexpz
getDocumentsCSV
::
NodeId
getDocumentsCSV
::
NodeId
-- ^ The Node ID of the target user
-- ^ The Node ID of the target user
->
DocId
->
DocId
...
...
src/Gargantext/API/Node/Document/Export/Types.hs
View file @
c38dec2f
...
@@ -13,19 +13,21 @@ Portability : POSIX
...
@@ -13,19 +13,21 @@ Portability : POSIX
module
Gargantext.API.Node.Document.Export.Types
where
module
Gargantext.API.Node.Document.Export.Types
where
import
Data.Aeson
(
encode
)
import
Data.Aeson.TH
(
deriveJSON
)
import
Data.Aeson.TH
(
deriveJSON
)
import
Data.Csv
(
DefaultOrdered
(
..
),
ToNamedRecord
(
..
),
(
.=
),
header
,
namedRecord
)
import
Data.Csv
(
DefaultOrdered
(
..
),
ToNamedRecord
(
..
),
(
.=
),
header
,
namedRecord
)
import
Data.Swagger
import
Data.Swagger
(
genericDeclareNamedSchema
,
ToParamSchema
(
..
),
ToSchema
(
..
)
)
--import qualified Data.Text
as T
import
Data.Text
qualified
as
T
import
qualified
Data.Text.Encoding
as
TE
import
Data.Text.Encoding
qualified
as
TE
import
Gargantext.Core.Types
import
Gargantext.Core.Types
(
Node
,
TODO
)
import
Gargantext.Core.Utils.Prefix
(
unPrefix
,
unPrefixSwagger
)
import
Gargantext.Core.Utils.Prefix
(
unPrefix
,
unPrefixSwagger
)
import
Gargantext.Database.Admin.Types.Hyperdata
(
HyperdataDocument
(
..
))
import
Gargantext.Database.Admin.Types.Hyperdata.Document
(
HyperdataDocument
(
..
)
)
import
Gargantext.Database.Admin.Types.Node
(
DocId
)
import
Gargantext.Database.Schema.Node
(
NodePoly
(
..
))
import
Gargantext.Database.Schema.Node
(
NodePoly
(
..
))
--import Gargantext.Utils.Servant (CSV)
import
Gargantext.Utils.Servant
(
ZIP
)
import
Gargantext.Utils.Zip
(
zipContentsPure
)
import
Protolude
import
Protolude
--import Protolude.Partial (read)
import
Servant
((
:>
),
(
:<|>
),
Get
,
Header
,
Headers
(
..
),
JSON
,
MimeRender
(
..
),
PlainText
,
Summary
)
import
Servant
-- | Document Export
-- | Document Export
...
@@ -34,6 +36,12 @@ data DocumentExport =
...
@@ -34,6 +36,12 @@ data DocumentExport =
,
_de_garg_version
::
Text
,
_de_garg_version
::
Text
}
deriving
(
Generic
)
}
deriving
(
Generic
)
-- | This is to represent a zipped document export. We want to have doc_id in zipped file name.
data
DocumentExportZIP
=
DocumentExportZIP
{
_dez_dexp
::
DocumentExport
,
_dez_doc_id
::
DocId
}
deriving
(
Generic
)
data
Document
=
data
Document
=
Document
{
_d_document
::
Node
HyperdataDocument
Document
{
_d_document
::
Node
HyperdataDocument
,
_d_ngrams
::
Ngrams
,
_d_ngrams
::
Ngrams
...
@@ -71,6 +79,9 @@ type Hash = Text
...
@@ -71,6 +79,9 @@ type Hash = Text
instance
ToSchema
DocumentExport
where
instance
ToSchema
DocumentExport
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_de_"
)
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_de_"
)
instance
ToSchema
DocumentExportZIP
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_dez_"
)
instance
ToSchema
Document
where
instance
ToSchema
Document
where
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_d_"
)
declareNamedSchema
=
genericDeclareNamedSchema
(
unPrefixSwagger
"_d_"
)
...
@@ -81,6 +92,9 @@ instance ToSchema Ngrams where
...
@@ -81,6 +92,9 @@ instance ToSchema Ngrams where
instance
ToParamSchema
DocumentExport
where
instance
ToParamSchema
DocumentExport
where
toParamSchema
_
=
toParamSchema
(
Proxy
::
Proxy
TODO
)
toParamSchema
_
=
toParamSchema
(
Proxy
::
Proxy
TODO
)
instance
ToParamSchema
DocumentExportZIP
where
toParamSchema
_
=
toParamSchema
(
Proxy
::
Proxy
TODO
)
instance
ToParamSchema
Document
where
instance
ToParamSchema
Document
where
toParamSchema
_
=
toParamSchema
(
Proxy
::
Proxy
TODO
)
toParamSchema
_
=
toParamSchema
(
Proxy
::
Proxy
TODO
)
...
@@ -90,10 +104,25 @@ instance ToParamSchema Ngrams where
...
@@ -90,10 +104,25 @@ instance ToParamSchema Ngrams where
type
API
=
Summary
"Document Export"
type
API
=
Summary
"Document Export"
:>
"export"
:>
"export"
:>
(
"json"
:>
(
"json"
:>
Get
'[
J
SON
]
(
Headers
'[
S
ervant
.
Header
"Content-Disposition"
Text
]
DocumentExport
)
:>
Get
'[
J
SON
]
(
Headers
'[
S
ervant
.
Header
"Content-Disposition"
Text
]
DocumentExport
)
:<|>
"json.zip"
:>
Get
'[
Z
IP
]
(
Headers
'[
S
ervant
.
Header
"Content-Disposition"
Text
]
DocumentExportZIP
)
:<|>
"csv"
:<|>
"csv"
:>
Get
'[
P
lainText
]
(
Headers
'[
S
ervant
.
Header
"Content-Disposition"
Text
]
Text
))
-- [Document]
)
:>
Get
'[
P
lainText
]
(
Headers
'[
S
ervant
.
Header
"Content-Disposition"
Text
]
Text
)
)
$
(
deriveJSON
(
unPrefix
"_ng_"
)
''
N
grams
)
$
(
deriveJSON
(
unPrefix
"_ng_"
)
''
N
grams
)
$
(
deriveJSON
(
unPrefix
"_d_"
)
''
D
ocument
)
$
(
deriveJSON
(
unPrefix
"_d_"
)
''
D
ocument
)
$
(
deriveJSON
(
unPrefix
"_de_"
)
''
D
ocumentExport
)
$
(
deriveJSON
(
unPrefix
"_de_"
)
''
D
ocumentExport
)
------
-- Needs to be here because of deriveJSON TH above
dezFileName
::
DocumentExportZIP
->
Text
dezFileName
(
DocumentExportZIP
{
..
})
=
"GarganText_DocsList-"
<>
show
_dez_doc_id
<>
".json"
instance
MimeRender
ZIP
DocumentExportZIP
where
mimeRender
_
dexpz
@
(
DocumentExportZIP
{
..
})
=
zipContentsPure
(
T
.
unpack
$
dezFileName
dexpz
)
(
encode
_dez_dexp
)
src/Gargantext/Utils/Servant.hs
View file @
c38dec2f
...
@@ -10,18 +10,16 @@ Portability : POSIX
...
@@ -10,18 +10,16 @@ Portability : POSIX
module
Gargantext.Utils.Servant
where
module
Gargantext.Utils.Servant
where
import
qualified
Data.ByteString.Lazy.Char8
as
BSC
import
Data.ByteString.Lazy.Char8
qualified
as
BSC
import
Data.Csv
(
defaultEncodeOptions
,
encodeByNameWith
,
encodeDefaultOrderedByName
,
header
,
namedRecord
,
(
.=
),
DefaultOrdered
,
EncodeOptions
(
..
),
NamedRecord
,
Quoting
(
QuoteNone
),
ToNamedRecord
)
import
Data.Csv
(
encodeDefaultOrderedByName
,
DefaultOrdered
,
ToNamedRecord
)
import
qualified
Data.Map.Strict
as
Map
import
Data.Text
qualified
as
T
import
qualified
Data.Text
as
T
import
Data.Text.Encoding
qualified
as
TE
import
qualified
Data.Text.Encoding
as
TE
import
Gargantext.API.Ngrams.Types
(
mSetToList
,
NgramsRepoElement
(
..
),
NgramsTableMap
,
NgramsTerm
(
..
),
unNgramsTerm
)
import
Gargantext.Core.Types.Main
(
ListType
(
..
))
import
Network.HTTP.Media
((
//
),
(
/:
))
import
Network.HTTP.Media
((
//
),
(
/:
))
import
qualified
Prelude
import
Prelude
qualified
import
Protolude
import
Protolude
import
Protolude.Partial
(
read
)
import
Protolude.Partial
(
read
)
import
Servant
import
Servant
(
Accept
(
contentType
),
MimeRender
(
..
),
MimeUnrender
(
mimeUnrender
)
)
data
CSV
=
CSV
data
CSV
=
CSV
...
@@ -34,25 +32,6 @@ instance (DefaultOrdered a, ToNamedRecord a) => MimeRender CSV [a] where
...
@@ -34,25 +32,6 @@ instance (DefaultOrdered a, ToNamedRecord a) => MimeRender CSV [a] where
instance
MimeRender
CSV
T
.
Text
where
instance
MimeRender
CSV
T
.
Text
where
mimeRender
_
=
BSC
.
fromStrict
.
TE
.
encodeUtf8
mimeRender
_
=
BSC
.
fromStrict
.
TE
.
encodeUtf8
-- CSV:
-- header: status\tlabel\tforms
-- item: map\taccountability\taccounting|&|accoutns|&|account
instance
MimeRender
CSV
NgramsTableMap
where
-- mimeRender _ _val = encode ([] :: [(Text, Text)])
mimeRender
_
val
=
encodeByNameWith
encOptions
(
header
[
"status"
,
"label"
,
"forms"
])
$
fn
<$>
Map
.
toList
val
where
encOptions
=
defaultEncodeOptions
{
encDelimiter
=
fromIntegral
(
ord
'
\t
'
)
,
encQuoting
=
QuoteNone
}
fn
::
(
NgramsTerm
,
NgramsRepoElement
)
->
NamedRecord
fn
(
NgramsTerm
term
,
NgramsRepoElement
{
_nre_list
,
_nre_children
})
=
namedRecord
[
"status"
.=
toText
_nre_list
,
"label"
.=
term
,
"forms"
.=
(
T
.
intercalate
"|&|"
$
unNgramsTerm
<$>
mSetToList
_nre_children
)]
toText
::
ListType
->
Text
toText
CandidateTerm
=
"candidate"
toText
MapTerm
=
"map"
toText
StopTerm
=
"stop"
instance
Read
a
=>
MimeUnrender
CSV
a
where
instance
Read
a
=>
MimeUnrender
CSV
a
where
mimeUnrender
_
bs
=
case
BSC
.
take
len
bs
of
mimeUnrender
_
bs
=
case
BSC
.
take
len
bs
of
"text/csv"
->
pure
.
read
.
BSC
.
unpack
$
BSC
.
drop
len
bs
"text/csv"
->
pure
.
read
.
BSC
.
unpack
$
BSC
.
drop
len
bs
...
@@ -76,3 +55,18 @@ instance MimeRender Markdown T.Text where
...
@@ -76,3 +55,18 @@ instance MimeRender Markdown T.Text where
instance
MimeUnrender
Markdown
T
.
Text
where
instance
MimeUnrender
Markdown
T
.
Text
where
mimeUnrender
_
=
Right
.
TE
.
decodeUtf8
.
BSC
.
toStrict
mimeUnrender
_
=
Right
.
TE
.
decodeUtf8
.
BSC
.
toStrict
---------------------------
data
ZIP
=
ZIP
instance
Accept
ZIP
where
contentType
_
=
"application"
//
"zip"
instance
MimeRender
ZIP
BSC
.
ByteString
where
mimeRender
_
=
identity
instance
MimeUnrender
ZIP
BSC
.
ByteString
where
mimeUnrender
_
=
Right
.
identity
src/Gargantext/Utils/Zip.hs
View file @
c38dec2f
...
@@ -15,18 +15,38 @@ Utilities for handling zip files
...
@@ -15,18 +15,38 @@ Utilities for handling zip files
module
Gargantext.Utils.Zip
where
module
Gargantext.Utils.Zip
where
import
"zip"
Codec.Archive.Zip
(
withArchive
,
ZipArchive
)
import
"zip"
Codec.Archive.Zip
(
addEntry
,
createArchive
,
mkEntrySelector
,
withArchive
,
CompressionMethod
(
BZip2
),
ZipArchive
)
-- import Control.Monad.Base (liftBase)
import
"zip-archive"
Codec.Archive.Zip
qualified
as
ZArch
import
Control.Monad.Base
(
MonadBase
,
liftBase
)
import
Data.ByteString
qualified
as
BS
import
Data.ByteString
qualified
as
BS
import
Data.ByteString.Lazy.Char8
qualified
as
BSC
import
Protolude
import
Protolude
import
System.Directory
(
removeFile
)
import
System.Directory
(
removeFile
)
import
System.IO.Temp
(
emptySystemTempFile
)
import
System.IO.Temp
(
emptySystemTempFile
)
-- | Take a zip file (in for of a ByteString) and work on its contents (using the ZipArchive monad)
withZipFileBS
::
MonadIO
m
=>
BS
.
ByteString
->
ZipArchive
a
->
m
a
withZipFileBS
::
MonadIO
m
=>
BS
.
ByteString
->
ZipArchive
a
->
m
a
withZipFileBS
bs
actions
=
withZipFileBS
bs
actions
=
liftIO
$
liftIO
$
bracket
(
emptySystemTempFile
"parsed-zip"
)
bracket
(
emptySystemTempFile
"parsed-zip"
)
(
\
path
->
removeFile
path
)
$
removeFile
\
path
->
do
(
\
path
->
do
BS
.
writeFile
path
bs
BS
.
writeFile
path
bs
withArchive
path
actions
withArchive
path
actions
)
-- | Zip ByteString contents and return the ZIP file as ByteString
zipContents
::
MonadBase
IO
m
=>
FilePath
->
BS
.
ByteString
->
m
BS
.
ByteString
zipContents
fpath
bsContents
=
liftBase
$
bracket
(
emptySystemTempFile
"zip-contents"
)
removeFile
(
\
path
->
do
s
<-
mkEntrySelector
fpath
createArchive
path
(
addEntry
BZip2
bsContents
s
)
BS
.
readFile
path
)
-- | Same as zipContents above, but pure (in-memory)
zipContentsPure
::
FilePath
->
BSC
.
ByteString
->
BSC
.
ByteString
zipContentsPure
fpath
bscContents
=
ZArch
.
fromArchive
(
ZArch
.
addEntryToArchive
e
ZArch
.
emptyArchive
)
where
e
=
ZArch
.
toEntry
fpath
0
bscContents
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment