figshare_api_v2 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/History.txt +58 -0
- data/Manifest.txt +18 -0
- data/README.md +74 -0
- data/Rakefile +31 -0
- data/lib/authors.rb +41 -0
- data/lib/base.rb +262 -0
- data/lib/figshare_api_v2.rb +121 -0
- data/lib/institutions.rb +238 -0
- data/lib/oai_pmh.rb +6 -0
- data/lib/other.rb +51 -0
- data/lib/private_articles.rb +354 -0
- data/lib/private_collections.rb +324 -0
- data/lib/private_projects.rb +308 -0
- data/lib/public_articles.rb +125 -0
- data/lib/public_collections.rb +105 -0
- data/lib/public_projects.rb +66 -0
- data/lib/stats.rb +16 -0
- data/lib/upload.rb +215 -0
- metadata +140 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
module Figshare
|
2
|
+
|
3
|
+
# Figshare Public Articles API
|
4
|
+
#
|
5
|
+
class PublicArticles < Base
|
6
|
+
|
7
|
+
# Requests a list of public articles
|
8
|
+
#
|
9
|
+
# @param institution [Boolean] Just our institution
|
10
|
+
# @param group_id [Integer] Only return this group's collections
|
11
|
+
# @param published_since [Time] Return results if published after this time
|
12
|
+
# @param modified_since [Time] Return results if modified after this time
|
13
|
+
# @param resource_doi [String] Matches this resource doi
|
14
|
+
# @param item_type [String] Matches this item_type. See Figshare API docs for list (https://docs.figshare.com/#articles_list)
|
15
|
+
# @param doi [String] Matches this doi
|
16
|
+
# @param handle [String] Matches this handle
|
17
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
18
|
+
# @param order_direction [String] "desc" Default, "asc"
|
19
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
20
|
+
def list(institute: false, group_id: nil,
|
21
|
+
published_since: nil, modified_since: nil,
|
22
|
+
item_type: nil, resource_doi: nil, doi: nil, handle: nil,
|
23
|
+
order: 'published_date', order_direction: 'desc',
|
24
|
+
&block
|
25
|
+
)
|
26
|
+
args = {}
|
27
|
+
args['institution'] = @institute_id if ! institute.nil?
|
28
|
+
args['group_id'] = group_id if ! group_id.nil?
|
29
|
+
args['item_type'] = item_type if ! item_type.nil?
|
30
|
+
args['resource_doi'] = resource_doi if ! resource_doi.nil?
|
31
|
+
args['doi'] = doi if ! doi.nil?
|
32
|
+
args['handle'] = handle if ! handle.nil?
|
33
|
+
args['published_since'] = published_since if ! published_since.nil?
|
34
|
+
args['modified_since'] = modified_since if ! modified_since.nil?
|
35
|
+
args['order'] = order if ! order.nil?
|
36
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
37
|
+
get_paginate(api_query: 'articles', args: args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Search within the public articles
|
41
|
+
#
|
42
|
+
# @param institution [Boolean] Just our institution
|
43
|
+
# @param group_id [Integer] Only return this group's collections
|
44
|
+
# @param published_since [Time] Return results if published after this time
|
45
|
+
# @param modified_since [Time] Return results if modified after this time
|
46
|
+
# @param resource_doi [String] Matches this resource doi
|
47
|
+
# @param item_type [String] Matches this item_type. See Figshare API docs for list (https://docs.figshare.com/#articles_list)
|
48
|
+
# @param doi [String] Matches this doi
|
49
|
+
# @param handle [String] Matches this handle
|
50
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
51
|
+
# @param order_direction [String] "desc" Default, "asc"
|
52
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
53
|
+
def search(institute: false, group_id: nil,
|
54
|
+
published_since: nil, modified_since: nil,
|
55
|
+
item_type: nil, resource_doi: nil, doi: nil, handle: nil,
|
56
|
+
order: 'published_date', order_direction: 'desc',
|
57
|
+
search_for:,
|
58
|
+
&block
|
59
|
+
)
|
60
|
+
args = { 'search_for' => search_for }
|
61
|
+
args['institution'] = @institute_id if ! institute.nil?
|
62
|
+
args['group_id'] = group_id if ! group_id.nil?
|
63
|
+
args['item_type'] = item_type if ! item_type.nil?
|
64
|
+
args['resource_doi'] = resource_doi if ! resource_doi.nil?
|
65
|
+
args['doi'] = doi if ! doi.nil?
|
66
|
+
args['handle'] = handle if ! handle.nil?
|
67
|
+
args['published_since'] = published_since if ! published_since.nil?
|
68
|
+
args['modified_since'] = modified_since if ! modified_since.nil?
|
69
|
+
args['order'] = order if ! order.nil?
|
70
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
71
|
+
post(api_query: 'articles/search', args: args, &block)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Return details of specific article (default version)
|
75
|
+
#
|
76
|
+
# @param article_id [Integer] Figshare id of the article
|
77
|
+
# @yield [Hash] See figshare api docs
|
78
|
+
def detail(article_id:, &block)
|
79
|
+
get(api_query: "articles/#{article_id}", &block)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Return details of list of versions for a specific article
|
83
|
+
#
|
84
|
+
# @param article_id [Integer] Figshare id of the artcle
|
85
|
+
# @yield [Hash] See figshare api docs
|
86
|
+
def versions(article_id:, &block)
|
87
|
+
get(api_query: "articles/#{article_id}/versions", &block)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return details of specific article version
|
91
|
+
#
|
92
|
+
# @param article_id [Integer] Figshare id of the article
|
93
|
+
# @param version_id [Integer] Figshare id of the article's version
|
94
|
+
# @param embargo [Boolean] Include only embargoed items
|
95
|
+
# @param confidentiality [Boolean] Include only confidential items
|
96
|
+
# @yield [Hash] See figshare api docs
|
97
|
+
def version_detail(article_id:, version_id: , embargo: false, confidentiality: false, &block)
|
98
|
+
if embargo
|
99
|
+
get(api_query: "articles/#{article_id}/versions/#{version_id}/embargo", &block)
|
100
|
+
elsif confidentiality
|
101
|
+
get(api_query: "articles/#{article_id}/versions/#{version_id}/confidentiality", &block)
|
102
|
+
else
|
103
|
+
get(api_query: "articles/#{article_id}/versions/#{version_id}", &block)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return details of list of files for a specific articles
|
108
|
+
#
|
109
|
+
# @param article_id [Integer] Figshare id of the article
|
110
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
111
|
+
def files(article_id:)
|
112
|
+
get(api_query: "articles/#{article_id}/files", &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return details of a specific file for a specific articles
|
116
|
+
#
|
117
|
+
# @param article_id [Integer] Figshare id of the article
|
118
|
+
# @param file_id [Integer] Figshare id of the file
|
119
|
+
# @yield [Hash] See figshare api docs
|
120
|
+
def file_detail(article_id:, file_id:)
|
121
|
+
get(api_query: "articles/#{article_id}/files/#{file_id}", &block)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Figshare
|
2
|
+
|
3
|
+
# Figshare public colections api calls
|
4
|
+
#
|
5
|
+
class PublicCollections < Base
|
6
|
+
|
7
|
+
# Requests a list of public collections
|
8
|
+
#
|
9
|
+
# @param institution [Boolean] Just our institution
|
10
|
+
# @param group_id [Integer] Only return this group's collections
|
11
|
+
# @param published_since [Time] Return results if published after this time
|
12
|
+
# @param modified_since [Time] Return results if modified after this time
|
13
|
+
# @param resource_doi [String] Matches this resource doi
|
14
|
+
# @param doi [String] Matches this doi
|
15
|
+
# @param handle [String] Matches this handle
|
16
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
17
|
+
# @param order_direction [String] "desc" Default, "asc"
|
18
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
19
|
+
def list(institution: false, group_id: nil,
|
20
|
+
published_since: nil, modified_since: nil,
|
21
|
+
resource_doi: nil, doi: nil, handle: nil,
|
22
|
+
order: 'published_date', order_direction: 'desc',
|
23
|
+
&block
|
24
|
+
)
|
25
|
+
args = {}
|
26
|
+
args['institution'] = @institute_id if ! institution.nil?
|
27
|
+
args['group'] = group_id if ! group_id.nil?
|
28
|
+
args['resource_doi'] = resource_doi if ! resource_doi.nil?
|
29
|
+
args['doi'] = doi if ! doi.nil?
|
30
|
+
args['handle'] = handle if ! handle.nil?
|
31
|
+
args['published_since'] = published_since if ! published_since.nil?
|
32
|
+
args['modified_since'] = modified_since if ! modified_since.nil?
|
33
|
+
args['order'] = order if ! order.nil?
|
34
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
35
|
+
get_paginate(api_query: 'collections', args: args, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Search within the public collections
|
39
|
+
#
|
40
|
+
# @param institution [Boolean] Just our institution
|
41
|
+
# @param group_id [Integer] Only return this group's collections
|
42
|
+
# @param published_since [Time] Return results if published after this time
|
43
|
+
# @param modified_since [Time] Return results if modified after this time
|
44
|
+
# @param resource_doi [String] Matches this resource doi
|
45
|
+
# @param doi [String] Matches this doi
|
46
|
+
# @param handle [String] Matches this handle
|
47
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
48
|
+
# @param order_direction [String] "desc" Default, "asc"
|
49
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
50
|
+
def search( institute: false, group_id: nil,
|
51
|
+
published_since: nil, modified_since: nil,
|
52
|
+
item_type: nil, resource_doi: nil, doi: nil, handle: nil,
|
53
|
+
order: 'published_date', order_direction: 'desc',
|
54
|
+
search_for:,
|
55
|
+
&block
|
56
|
+
)
|
57
|
+
args = { 'search_for' => search_for }
|
58
|
+
args['institution'] = @institute_id if ! institute.nil?
|
59
|
+
args['group_id'] = group_id if ! group_id.nil?
|
60
|
+
args['item_type'] = item_type if ! item_type.nil?
|
61
|
+
args['resource_doi'] = resource_doi if ! resource_doi.nil?
|
62
|
+
args['doi'] = doi if ! doi.nil?
|
63
|
+
args['handle'] = handle if ! handle.nil?
|
64
|
+
args['published_since'] = published_since if ! published_since.nil?
|
65
|
+
args['modified_since'] = modified_since if ! modified_since.nil?
|
66
|
+
args['order'] = order if ! order.nil?
|
67
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
68
|
+
post(api_query: 'account/articles/search', args: args, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get details of specific collection (default version)
|
72
|
+
#
|
73
|
+
# @param collection_id [Integer] Figshare id of the collection
|
74
|
+
# @yield [Hash] See figshare api docs
|
75
|
+
def detail(collection_id:, &block)
|
76
|
+
get(api_query: "collections/#{collection_id}", &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return details of a list of public collection Versions
|
80
|
+
#
|
81
|
+
# @param collection_id [Integer] Figshare id of the collection
|
82
|
+
# @yield [Hash] See figshare api docs
|
83
|
+
def versions(collection_id:, &block)
|
84
|
+
get(api_query: "collections/#{collection_id}/versions", &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Get details of specific collection version
|
88
|
+
#
|
89
|
+
# @param collection_id [Integer] Figshare id of the collection
|
90
|
+
# @param version_id [Integer] Figshare id of the collection's version
|
91
|
+
# @yield [Hash] See figshare api docs
|
92
|
+
def version_detail(collection_id:, version_id:, &block)
|
93
|
+
get(api_query: "collections/#{collection_id}/versions/#{version_id}", &block)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Get details of list of articles for a specific collection
|
97
|
+
#
|
98
|
+
# @param collection_id [Integer] Figshare id of the collection
|
99
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
100
|
+
def articles(collection_id:, &block)
|
101
|
+
get_paginate(api_query: "collections/#{collection_id}/articles", &block)
|
102
|
+
end
|
103
|
+
end #of class
|
104
|
+
|
105
|
+
end #of module
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Figshare
|
2
|
+
|
3
|
+
# Figshare public projects api
|
4
|
+
#
|
5
|
+
class PublicProjects < Base
|
6
|
+
# Requests a list projects
|
7
|
+
#
|
8
|
+
# @param institution [Boolean] Just our institution
|
9
|
+
# @param group_id [Integer] Only return this group's project
|
10
|
+
# @param published_since [Time] Return results if published after this time
|
11
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
12
|
+
# @param order_direction [String] "desc" Default, "asc"
|
13
|
+
# @yield [Hash] {url, published_date, id, title}
|
14
|
+
def list(institute: false,group_id: nil, published_since: nil, order: 'published_date', order_direction: 'desc', &block)
|
15
|
+
args = {}
|
16
|
+
args['institution'] = @institute_id if ! institute.nil?
|
17
|
+
args['group'] = group_id if ! group_id.nil?
|
18
|
+
args['published_since'] = published_since if ! published_since.nil?
|
19
|
+
args['order'] = order if ! order.nil?
|
20
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
21
|
+
get_paginate(api_query: 'projects', args: args, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Search within all projects
|
25
|
+
#
|
26
|
+
# @param institution [Boolean] Just our institution
|
27
|
+
# @param group_id [Integer] Only return this group's project
|
28
|
+
# @param published_since [Time] Return results if published after this time
|
29
|
+
# @param modified_since [Time] Return results if modified after this time
|
30
|
+
# @param order [String] "published_date" Default, "modified_date", "views", "cites", "shares"
|
31
|
+
# @param order_direction [String] "desc" Default, "asc"
|
32
|
+
# @yield [Hash] {id, title, doi, handle, url, published_date}
|
33
|
+
def search(institute: false, group_id: nil,
|
34
|
+
published_since: nil, modified_since: nil,
|
35
|
+
order: 'published_date', order_direction: 'desc',
|
36
|
+
search_for:,
|
37
|
+
&block
|
38
|
+
)
|
39
|
+
args = { 'search_for' => search_for }
|
40
|
+
args['institution'] = @institute_id if ! institute.nil?
|
41
|
+
args['group'] = group_id if ! group_id.nil?
|
42
|
+
args['published_since'] = published_since if ! published_since.nil?
|
43
|
+
args['modified_since'] = modified_since if ! modified_since.nil?
|
44
|
+
args['order'] = order if ! order.nil?
|
45
|
+
args['order_direction'] = order_direction if ! order_direction.nil?
|
46
|
+
post(api_query: 'account/projects/search', args: args, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return details of specific project_id
|
50
|
+
#
|
51
|
+
# @param project_id [Integer] Figshare id of the project_id
|
52
|
+
# @yield [Hash] See figshare api docs
|
53
|
+
def detail(project_id:, &block)
|
54
|
+
get(api_query: "projects/#{project_id}", &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get list of articles for a specific project
|
58
|
+
#
|
59
|
+
# @param project_id [Integer] Figshare id of the project
|
60
|
+
# @yield [Hash] See Figshare API Doc
|
61
|
+
def articles(project_id:, &block)
|
62
|
+
get_paginate(api_query: "projects/#{project_id}/articles", &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
end # of class
|
66
|
+
end # of module
|
data/lib/stats.rb
ADDED
data/lib/upload.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
module Figshare
|
2
|
+
require 'digest'
|
3
|
+
require 'dir_r'
|
4
|
+
|
5
|
+
# Upload files to figshare
|
6
|
+
# Nb. This can sometimes fail, so you need to check the md5 to ensure the file got there
|
7
|
+
# It can take a short while for the md5 to be calculated, so upload, wait, then check for a computed_md5.
|
8
|
+
# The status will show as "ic_checking", "moving_to_final" then to "available",
|
9
|
+
# I have seen it stuck at "moving_to_final", but with the right computed_md5.
|
10
|
+
#
|
11
|
+
class Upload < PrivateArticles
|
12
|
+
CHUNK_SIZE = 1048576
|
13
|
+
attr_accessor :file_info, :upload_query, :upload_host, :upload_parts_detail , :file_id, :article_id, :file_name
|
14
|
+
attr_accessor :new_count, :bad_count
|
15
|
+
|
16
|
+
# Calculate a local files MD5.
|
17
|
+
#
|
18
|
+
# @param filename [String] Path/name of local file to MD5
|
19
|
+
# @return [String,Integer] MD5 as a Hex String, Size of the file in bytes.
|
20
|
+
def self.get_file_check_data(filename)
|
21
|
+
stat_record = File.stat(filename)
|
22
|
+
md5 = Digest::MD5.new
|
23
|
+
File.open(filename, 'rb') do |fd|
|
24
|
+
while(buffer = fd.read(CHUNK_SIZE))
|
25
|
+
md5.update(buffer)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return md5.hexdigest, stat_record.size
|
29
|
+
end
|
30
|
+
|
31
|
+
# Upload the file, to the Figshare article
|
32
|
+
#
|
33
|
+
# @param article_id [Integer] Figshare article id
|
34
|
+
# @param file_name [String] path/file_name to upload
|
35
|
+
# @param trace [Integer] 0: no output, 1: per file upload message, 2: fuller trace
|
36
|
+
def upload(article_id:, file_name:, trace: 0)
|
37
|
+
@article_id = article_id
|
38
|
+
@file_name = file_name
|
39
|
+
@trace = trace
|
40
|
+
|
41
|
+
@file_id = nil
|
42
|
+
@file_info = nil
|
43
|
+
@upload_query = nil
|
44
|
+
@upload_host = nil
|
45
|
+
@upload_parts_detail = nil
|
46
|
+
|
47
|
+
initiate_new_upload()
|
48
|
+
puts "New File_id: #{@file_id}\n\n" if @trace > 1
|
49
|
+
|
50
|
+
get_file_info()
|
51
|
+
puts "@file_info: #{@file_info.to_j}\n\n" if @trace > 1
|
52
|
+
|
53
|
+
get_upload_parts_details()
|
54
|
+
puts "@upload_parts_detail: #{@upload_parts_detail.to_j}\n\n" if @trace > 1
|
55
|
+
|
56
|
+
upload_the_parts()
|
57
|
+
|
58
|
+
complete_upload()
|
59
|
+
if @trace > 1
|
60
|
+
status
|
61
|
+
puts "Final Status: #{@file_info.to_j}\n\n"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Upload all files in a directory, into one article.
|
66
|
+
# Check checksums, and only upload changed or new files
|
67
|
+
# Does not recurse through sub-directories, as figshare has a flat file structure.
|
68
|
+
#
|
69
|
+
# @param article_id [Integer] Figshare article id
|
70
|
+
# @param directory [String] path
|
71
|
+
# @param delete_extras [Boolean] delete any files in the figshare end, that aren't in the local directory.
|
72
|
+
# @param trace [Integer] 0: no output, 1: per file upload message, 2: fuller trace
|
73
|
+
def upload_dir(article_id:, directory:, delete_extras: false, exclude_dot_files: true, trace: 0)
|
74
|
+
@new_count = 0
|
75
|
+
@bad_count = 0
|
76
|
+
|
77
|
+
files = {}
|
78
|
+
cache_article_file_md5(article_id: article_id)
|
79
|
+
|
80
|
+
DirR.walk_dir(directory: directory, walk_sub_directories: false) do |d,f|
|
81
|
+
next if exclude_dot_files && f =~ /^\..*/
|
82
|
+
files[f] = true #note that we have seen this filename
|
83
|
+
if @md5_cache[f] #check to see if it has already been uploaded
|
84
|
+
md5, size = Upload.get_file_check_data("#{d}/#{f}")
|
85
|
+
if @md5_cache[f][:md5] != md5 #file is there, but has changed, or previously failed to upload.
|
86
|
+
puts "Deleting: #{article_id} << #{d}/#{f} #{@md5_cache[f][:id]} MISMATCH '#{@md5_cache[f]}' != '#{md5}'" if trace > 0
|
87
|
+
file_delete(article_id: article_id, file_id: @md5_cache[f][:id])
|
88
|
+
@bad_count += 1
|
89
|
+
puts "Re-ADDING: #{article_id} << #{d}/#{f}" if trace > 0
|
90
|
+
upload(article_id: article_id, file_name: "#{d}/#{f}", trace: trace)
|
91
|
+
@new_count += 1
|
92
|
+
elsif trace > 1
|
93
|
+
puts "EXISTS: #{article_id} #{d}/#{f}"
|
94
|
+
end
|
95
|
+
else
|
96
|
+
puts "ADDING: #{article_id} << #{d}/#{f}" if trace > 0
|
97
|
+
upload(article_id: article_id, file_name: "#{d}/#{f}", trace: trace)
|
98
|
+
@new_count += 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Print out filename of files in the Figshare article, that weren't in the directory.
|
103
|
+
@md5_cache.each do |fn,v|
|
104
|
+
if ! files[fn]
|
105
|
+
#File exists on Figshare, but not on the local disk
|
106
|
+
if delete_extras
|
107
|
+
puts "Deleteing EXTRA: #{article_id} << #{fn} #{v[:id]}" if trace > 0
|
108
|
+
file_delete(article_id: article_id, file_id: @md5_cache[f][:id])
|
109
|
+
elsif trace > 0
|
110
|
+
puts "EXTRA: #{article_id} << #{fn} #{v[:id]}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Retrieve md5 sums of the existing files in the figshare article
|
117
|
+
# Sets @md5_cache[filename] => figshare.computed_md5
|
118
|
+
#
|
119
|
+
# @param article_id [Integer] Figshare article ID
|
120
|
+
private def cache_article_file_md5(article_id:)
|
121
|
+
@md5_cache = {}
|
122
|
+
files(article_id: article_id) do |f|
|
123
|
+
@md5_cache[f['name']] = {:article_id => article_id, :id => f['id'], :md5 => f[ 'computed_md5']}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get status of the current upload.
|
128
|
+
# Just fetches the file record from figshare.
|
129
|
+
# Of interest is the status field, and the computed_md5 field
|
130
|
+
#
|
131
|
+
# @return [Hash] Figshare file record, or nil, if the call fails
|
132
|
+
def status
|
133
|
+
@file_info = nil
|
134
|
+
file_detail(article_id: @article_id, file_id: @file_id) do |f|
|
135
|
+
@file_info = f
|
136
|
+
end
|
137
|
+
raise "Upload::status(): Failed to get figshare file record" if @file_info.nil?
|
138
|
+
end
|
139
|
+
|
140
|
+
# Creates a new Figshare file record, in the figshare article, and we get the file_id from the upload URL
|
141
|
+
# file status == 'created'
|
142
|
+
#
|
143
|
+
private def initiate_new_upload
|
144
|
+
md5, size = Upload.get_file_check_data(@file_name)
|
145
|
+
args = {'name' => File.basename(@file_name),
|
146
|
+
'md5' => md5,
|
147
|
+
'size'=> size
|
148
|
+
}
|
149
|
+
post( api_query: "account/articles/#{@article_id}/files", args: args ) do |f|
|
150
|
+
@file_id = f['location'].gsub(/^.*\/([0-9]+)$/, '\1')
|
151
|
+
end
|
152
|
+
raise "Upload::initiate_new_upload(): failed to create Figshare file record" if @file_id.nil?
|
153
|
+
end
|
154
|
+
|
155
|
+
# Gets the Figshare file info
|
156
|
+
# We need the upload URLs to continue
|
157
|
+
#
|
158
|
+
private def get_file_info
|
159
|
+
status
|
160
|
+
@upload_host = @file_info['upload_url'].gsub(/^http.*\/\/(.*)\/upload.*$/, '\1')
|
161
|
+
@upload_query = @file_info['upload_url'].gsub(/^http.*\/\/(.*)\/(upload.*)$/, '\2')
|
162
|
+
puts "Upload_host: #{@upload_host} URL: #{@upload_query}" if @trace > 1
|
163
|
+
end
|
164
|
+
|
165
|
+
# Completes the upload.
|
166
|
+
# Figshare then calculates the md5 in the background, which may take a while to complete
|
167
|
+
# And sometimes the checksum never gets calculated, and is left blank.
|
168
|
+
#
|
169
|
+
private def complete_upload
|
170
|
+
post( api_query: "account/articles/#{@article_id}/files/#{@file_id}" )
|
171
|
+
puts "complete_upload" if trace > 1
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get the upload settings
|
175
|
+
#
|
176
|
+
private def get_upload_parts_details
|
177
|
+
@upload_parts_detail = nil
|
178
|
+
result = nil
|
179
|
+
WIKK::WebBrowser.https_session( host: @upload_host, verify_cert: false ) do |ws|
|
180
|
+
result = ws.get_page( query: @upload_query,
|
181
|
+
authorization: "token #{@auth_token}",
|
182
|
+
)
|
183
|
+
end
|
184
|
+
raise "get_upload_parts_detail(#{@article_id}) failed to get upload URL" if result.nil?
|
185
|
+
@upload_parts_detail = JSON.parse(result)
|
186
|
+
|
187
|
+
puts "Part URL #{@upload_parts_detail['parts']}" if @trace > 1
|
188
|
+
end
|
189
|
+
|
190
|
+
# Upload the file in parts
|
191
|
+
#
|
192
|
+
private def upload_the_parts
|
193
|
+
parts = @upload_parts_detail['parts']
|
194
|
+
File.open(@file_name, 'rb') do |fin|
|
195
|
+
parts.each do |part|
|
196
|
+
data = fin.read(part['endOffset'] - part['startOffset'] + 1)
|
197
|
+
upload_part(buffer: data, part: part['partNo'])
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Upload just one part
|
203
|
+
#
|
204
|
+
private def upload_part(buffer:, part:)
|
205
|
+
puts "upload_part(#{part})" if @trace > 1
|
206
|
+
WIKK::WebBrowser.https_session( host: @upload_host, verify_cert: false ) do |ws|
|
207
|
+
ws.put_req( query: "#{@upload_query}/#{part}",
|
208
|
+
authorization: "token #{@auth_token}",
|
209
|
+
data: buffer
|
210
|
+
)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
end
|