Skip to content

Commit f27e372

Browse files
svartkaninvitalif
authored andcommitted
Implement progressbar (by @svartkanin adjusted by @vitalif)
1 parent 11a3d78 commit f27e372

16 files changed

Lines changed: 211 additions & 20 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Grive2 0.5.1-dev
22

3-
14 Jan 2016, Vitaliy Filippov
3+
28 Sep 2016, Vitaliy Filippov
44

55
http://yourcmc.ru/wiki/Grive2
66

@@ -91,6 +91,7 @@ Grive uses cmake to build. Basic install sequence is
9191
- added options to limit upload and download speed
9292
- faster upload of new and changed files. now Grive uploads files without first calculating
9393
md5 checksum when file is created locally or when its size changes.
94+
- added -P/--progress-bar option to print ASCII progress bar for each processed file (pull request by @svartkanin)
9495

9596
### Grive2 v0.5
9697

grive/doc/grive.1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ subdirectory. Internally converted to an ignore regexp, remembered for next runs
7575
\fB\-v\fR, \fB\-\-version\fR
7676
Displays program version
7777
.TP
78+
\fB\-P\fR, \fB\-\-progress-bar\fR
79+
Print ASCII progress bar for each downloaded/uploaded file.
80+
.TP
7881
\fB\-V\fR, \fB\-\-verbose\fR
7982
Verbose mode. Enables more messages than usual.
8083

grive/src/main.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include "util/Config.hh"
21+
#include "util/ProgressBar.hh"
2122

2223
#include "base/Drive.hh"
2324
#include "drive2/Syncer2.hh"
@@ -126,6 +127,7 @@ int Main( int argc, char **argv )
126127
( "ignore", po::value<std::string>(), "Perl RegExp to ignore files (matched against relative paths)." )
127128
( "upload-speed,U", po::value<unsigned>(), "Limit upload speed in kbytes per second" )
128129
( "download-speed,D", po::value<unsigned>(), "Limit download speed in kbytes per second" )
130+
( "progress-bar,P", "Enable progress bar for upload/download of files")
129131
;
130132

131133
po::variables_map vm;
@@ -156,6 +158,13 @@ int Main( int argc, char **argv )
156158
if ( vm.count( "log-http" ) )
157159
http->SetLog( new http::ResponseLog( vm["log-http"].as<std::string>(), ".txt" ) );
158160

161+
std::unique_ptr<ProgressBar> pb;
162+
if ( vm.count( "progress-bar" ) )
163+
{
164+
pb.reset( new ProgressBar() );
165+
http->SetProgressReporter( pb.get() );
166+
}
167+
159168
if ( vm.count( "auth" ) )
160169
{
161170
OAuth2 token( http.get(), client_id, client_secret ) ;
@@ -208,7 +217,13 @@ int Main( int argc, char **argv )
208217

209218
if ( vm.count( "dry-run" ) == 0 )
210219
{
220+
// The progress bar should just be enabled when actual file transfers take place
221+
if ( pb )
222+
pb->setShowProgressBar( true ) ;
211223
drive.Update() ;
224+
if ( pb )
225+
pb->setShowProgressBar( false ) ;
226+
212227
drive.SaveState() ;
213228
}
214229
else

libgrive/src/base/Resource.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ void Resource::FromRemoteFile( const Entry& remote )
187187
{
188188
Log( "file %1% is created in remote (change %2%)", path,
189189
remote.ChangeStamp(), log::verbose ) ;
190-
190+
m_size = remote.Size();
191191
m_state = remote_new ;
192192
}
193193
else
@@ -214,6 +214,7 @@ void Resource::FromRemoteFile( const Entry& remote )
214214
if ( remote.MTime().Sec() > m_mtime.Sec() )
215215
{
216216
Log( "file %1% is changed in remote", path, log::verbose ) ;
217+
m_size = remote.Size();
217218
m_state = remote_changed ;
218219
}
219220

libgrive/src/base/Syncer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ http::Agent* Syncer::Agent() const
4141
void Syncer::Download( Resource *res, const fs::path& file )
4242
{
4343
http::Download dl( file.string(), http::Download::NoChecksum() ) ;
44-
long r = m_http->Get( res->ContentSrc(), &dl, http::Header() ) ;
44+
long r = m_http->Get( res->ContentSrc(), &dl, http::Header(), res->Size() ) ;
4545
if ( r <= 400 )
4646
{
4747
if ( res->ServerTime() != DateTime() )

libgrive/src/drive2/Feed2.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ bool Feed2::GetNext( http::Agent *http )
4242
return false ;
4343

4444
http::ValResponse out ;
45-
http->Get( m_next, &out, http::Header() ) ;
45+
http->Get( m_next, &out, http::Header(), 0 ) ;
4646
Val m_content = out.Response() ;
4747

4848
Val::Array items = m_content["items"].AsArray() ;

libgrive/src/drive2/Syncer2.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ std::unique_ptr<Feed> Syncer2::GetChanges( long min_cstamp )
235235
long Syncer2::GetChangeStamp( long min_cstamp )
236236
{
237237
http::ValResponse res ;
238-
m_http->Get( ChangesFeed( min_cstamp, 1 ), &res, http::Header() ) ;
238+
m_http->Get( ChangesFeed( min_cstamp, 1 ), &res, http::Header(), 0 ) ;
239239

240240
return std::atoi( res.Response()["largestChangeId"].Str().c_str() );
241241
}

libgrive/src/http/Agent.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ long Agent::Put(
5252
long Agent::Get(
5353
const std::string& url,
5454
DataStream *dest,
55-
const Header& hdr )
55+
const Header& hdr,
56+
u64_t downloadFileBytes )
5657
{
57-
return Request( "GET", url, NULL, dest, hdr );
58+
return Request( "GET", url, NULL, dest, hdr, downloadFileBytes );
5859
}
5960

6061
long Agent::Post(

libgrive/src/http/Agent.hh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <string>
2323
#include "ResponseLog.hh"
2424
#include "util/Types.hh"
25+
#include "util/Progress.hh"
2526

2627
namespace gr {
2728

@@ -59,7 +60,8 @@ public :
5960
virtual long Get(
6061
const std::string& url,
6162
DataStream *dest,
62-
const Header& hdr ) ;
63+
const Header& hdr,
64+
u64_t downloadFileBytes = 0 ) ;
6365

6466
virtual long Post(
6567
const std::string& url,
@@ -72,7 +74,8 @@ public :
7274
const std::string& url,
7375
SeekStream *in,
7476
DataStream *dest,
75-
const Header& hdr ) = 0 ;
77+
const Header& hdr,
78+
u64_t downloadFileBytes = 0 ) = 0 ;
7679

7780
virtual void SetUploadSpeed( unsigned kbytes ) ;
7881
virtual void SetDownloadSpeed( unsigned kbytes ) ;
@@ -84,6 +87,8 @@ public :
8487

8588
virtual std::string Escape( const std::string& str ) = 0 ;
8689
virtual std::string Unescape( const std::string& str ) = 0 ;
90+
91+
virtual void SetProgressReporter( Progress* ) = 0;
8792
} ;
8893

8994
} } // end of namespace

libgrive/src/http/CurlAgent.cc

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@
2828

2929
#include <boost/throw_exception.hpp>
3030

31-
// dependent libraries
32-
#include <curl/curl.h>
33-
3431
#include <algorithm>
3532
#include <cassert>
3633
#include <cstring>
@@ -68,6 +65,7 @@ struct CurlAgent::Impl
6865
std::string error_headers ;
6966
std::string error_data ;
7067
DataStream *dest ;
68+
u64_t total_download, total_upload ;
7169
} ;
7270

7371
static struct curl_slist* SetHeader( CURL* handle, const Header& hdr );
@@ -94,6 +92,7 @@ void CurlAgent::Init()
9492
m_pimpl->error_headers = "";
9593
m_pimpl->error_data = "";
9694
m_pimpl->dest = NULL;
95+
m_pimpl->total_download = m_pimpl->total_upload = 0;
9796
}
9897

9998
CurlAgent::~CurlAgent()
@@ -111,6 +110,11 @@ void CurlAgent::SetLog(ResponseLog *log)
111110
m_log.reset( log );
112111
}
113112

113+
void CurlAgent::SetProgressReporter(Progress *progress)
114+
{
115+
m_pb = progress;
116+
}
117+
114118
std::size_t CurlAgent::HeaderCallback( void *ptr, size_t size, size_t nmemb, CurlAgent *pthis )
115119
{
116120
char *str = static_cast<char*>(ptr) ;
@@ -131,7 +135,7 @@ std::size_t CurlAgent::HeaderCallback( void *ptr, size_t size, size_t nmemb, Cur
131135
if ( pos != line.npos )
132136
{
133137
std::size_t end_pos = line.find( "\r\n", pos ) ;
134-
pthis->m_pimpl->location = line.substr( loc.size(), end_pos - loc.size() ) ;
138+
pthis->m_pimpl->location = line.substr( pos+loc.size(), end_pos - loc.size() ) ;
135139
}
136140

137141
return size*nmemb ;
@@ -142,6 +146,7 @@ std::size_t CurlAgent::Receive( void* ptr, size_t size, size_t nmemb, CurlAgent
142146
assert( pthis != 0 ) ;
143147
if ( pthis->m_log.get() )
144148
pthis->m_log->Write( (const char*)ptr, size*nmemb );
149+
145150
if ( pthis->m_pimpl->error && pthis->m_pimpl->error_data.size() < 65536 )
146151
{
147152
// Do not feed error responses to destination stream
@@ -151,6 +156,19 @@ std::size_t CurlAgent::Receive( void* ptr, size_t size, size_t nmemb, CurlAgent
151156
return pthis->m_pimpl->dest->Write( static_cast<char*>(ptr), size * nmemb ) ;
152157
}
153158

159+
int CurlAgent::progress_callback( CurlAgent *pthis, curl_off_t totalDownload, curl_off_t finishedDownload, curl_off_t totalUpload, curl_off_t finishedUpload )
160+
{
161+
// Only report download progress when set explicitly
162+
totalDownload = pthis->m_pimpl->total_download;
163+
if ( !totalUpload )
164+
totalUpload = pthis->m_pimpl->total_upload;
165+
pthis->m_pb->reportProgress(
166+
totalDownload > 0 ? totalDownload : totalUpload,
167+
totalDownload > 0 ? finishedDownload : finishedUpload
168+
);
169+
return 0;
170+
}
171+
154172
long CurlAgent::ExecCurl(
155173
const std::string& url,
156174
DataStream *dest,
@@ -168,6 +186,10 @@ long CurlAgent::ExecCurl(
168186

169187
struct curl_slist *slist = SetHeader( m_pimpl->curl, hdr ) ;
170188

189+
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
190+
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
191+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this);
192+
171193
CURLcode curl_code = ::curl_easy_perform(curl);
172194

173195
curl_slist_free_all(slist);
@@ -202,11 +224,13 @@ long CurlAgent::Request(
202224
const std::string& url,
203225
SeekStream *in,
204226
DataStream *dest,
205-
const Header& hdr )
227+
const Header& hdr,
228+
u64_t downloadFileBytes )
206229
{
207230
Trace("HTTP %1% \"%2%\"", method, url ) ;
208231

209232
Init() ;
233+
m_pimpl->total_download = downloadFileBytes ;
210234
CURL *curl = m_pimpl->curl ;
211235

212236
// set common options

0 commit comments

Comments
 (0)