1
1
use std:: sync:: Arc ;
2
2
3
+ use futures:: future:: try_join;
3
4
use google_drive3:: {
4
5
api:: Scope ,
5
6
yup_oauth2:: { read_service_account_key, ServiceAccountAuthenticator } ,
6
7
DriveHub ,
7
8
} ;
9
+ use http_body_util:: BodyExt ;
8
10
use hyper_rustls:: HttpsConnector ;
9
11
use hyper_util:: client:: legacy:: connect:: HttpConnector ;
12
+ use log:: debug;
10
13
11
14
use crate :: ops:: sdk:: * ;
12
15
@@ -37,7 +40,7 @@ impl Executor {
37
40
hyper_rustls:: HttpsConnectorBuilder :: new ( )
38
41
. with_provider_and_native_roots ( rustls:: crypto:: ring:: default_provider ( ) ) ?
39
42
. https_only ( )
40
- . enable_http1 ( )
43
+ . enable_http2 ( )
41
44
. build ( ) ,
42
45
) ;
43
46
let drive_hub = DriveHub :: new ( client, auth) ;
@@ -72,16 +75,17 @@ impl SourceExecutor for Executor {
72
75
. drive_hub
73
76
. files ( )
74
77
. list ( )
75
- . q ( & query )
76
- . add_scope ( Scope :: Readonly ) ;
78
+ . add_scope ( Scope :: Readonly )
79
+ . q ( & query ) ;
77
80
if let Some ( next_page_token) = & next_page_token {
78
81
list_call = list_call. page_token ( next_page_token) ;
79
82
}
80
- let ( resp , files) = list_call. doit ( ) . await ?;
83
+ let ( _ , files) = list_call. doit ( ) . await ?;
81
84
if let Some ( files) = files. files {
82
85
for file in files {
83
- if let Some ( name) = file. name {
84
- result. push ( KeyValue :: Str ( Arc :: from ( name) ) ) ;
86
+ debug ! ( "file: {:?}" , file) ;
87
+ if let Some ( id) = file. id {
88
+ result. push ( KeyValue :: Str ( Arc :: from ( id) ) ) ;
85
89
}
86
90
}
87
91
}
@@ -94,7 +98,45 @@ impl SourceExecutor for Executor {
94
98
}
95
99
96
100
async fn get_value ( & self , key : & KeyValue ) -> Result < Option < FieldValues > > {
97
- unimplemented ! ( )
101
+ let file_id = key. str_value ( ) ?;
102
+
103
+ let filename = async {
104
+ let ( _, file) = self
105
+ . drive_hub
106
+ . files ( )
107
+ . get ( file_id)
108
+ . add_scope ( Scope :: Readonly )
109
+ . doit ( )
110
+ . await ?;
111
+ anyhow:: Ok ( file. name . unwrap_or_default ( ) )
112
+ } ;
113
+ let body = async {
114
+ let ( resp, _) = self
115
+ . drive_hub
116
+ . files ( )
117
+ . get ( file_id)
118
+ . add_scope ( Scope :: Readonly )
119
+ . param ( "alt" , "media" )
120
+ . doit ( )
121
+ . await ?;
122
+ let content = resp. into_body ( ) . collect ( ) . await ?;
123
+ anyhow:: Ok ( content)
124
+ } ;
125
+ let ( filename, content) = try_join ( filename, body) . await ?;
126
+
127
+ let mut fields = Vec :: with_capacity ( 2 ) ;
128
+ fields. push ( filename. into ( ) ) ;
129
+ if self . binary {
130
+ fields. push ( content. to_bytes ( ) . to_vec ( ) . into ( ) ) ;
131
+ } else {
132
+ fields. push (
133
+ String :: from_utf8_lossy ( & content. to_bytes ( ) )
134
+ . to_string ( )
135
+ . into ( ) ,
136
+ ) ;
137
+ }
138
+
139
+ Ok ( Some ( FieldValues { fields } ) )
98
140
}
99
141
}
100
142
@@ -116,6 +158,7 @@ impl SourceFactoryBase for Factory {
116
158
Ok ( make_output_type ( CollectionSchema :: new (
117
159
CollectionKind :: Table ,
118
160
vec ! [
161
+ FieldSchema :: new( "file_id" , make_output_type( BasicValueType :: Str ) ) ,
119
162
FieldSchema :: new( "filename" , make_output_type( BasicValueType :: Str ) ) ,
120
163
FieldSchema :: new(
121
164
"content" ,
0 commit comments