Skip to content

Instantly share code, notes, and snippets.

@zdennis
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zdennis/f1ee525797b2fe3c6c1b to your computer and use it in GitHub Desktop.
Save zdennis/f1ee525797b2fe3c6c1b to your computer and use it in GitHub Desktop.
Zenodo file export

Option A

In this approach ZenodoFileExport is a class intended to be consumed and customized via constructor arguments. The goal of this approach is to make it easy for task runners like Rake to be able to construct new kinds of Zenodo file exports without having to modify code.

The downside here is that the export_type has meaning and is subject to whatever the caller passes in which is subject to typo's, etc. I see this risk as low.

This also introduces the concept of generating a README file by telling it what file to use as a README. The README contents are stored outside of code, but within the overall code-base, so it can be re-used if Lagotto adds additional 3rd party data stores later.

class ZenodoFileExport
# +export_type+ represents the kind of file this is. Must be set in
# a subclass (or NotImplementedError will be raised).
#
# It is also used to determine the relationships between this and other
# ZenodoFileExports.
#
# * the first report of its kind will become the parent DOI for all the ones that follow
# * the latest uploaded report of its kind will become the newer version of the previous report
# * the previously uploaded report of its kind will become marked as a previous version of the latest
#
cattr_accessor :export_type
# If not supplied then there would be no README added to the uploaded Zenodo deposition.
# THIS WOULD ONLY EXIST IF YOU WANTED A README TO BE A PROMINENT PART OF A ZENODO EXPORT.
# OTHERWISE, the readme_file would just be added as another generic file to the export.
cattr_accessor :readme_file
def export!
# Default implementation for Zenodo file exports
# * look for the earliest Zenodo file export that has this export_type
# * If found, use that as the parent DOI for the IsPartOf relation
# * If not found, do not set the parent DOI for IsPartOf, as this will be the parent
# * look for the previous Zenodo file export that has the same export_type
# * If found, use that as the DOI for the IsNewerVersionOf relation.
# * If not found, do not set the IsNewerVersionOf relation
# * after export to Zenodo, if we had a previous version then update it to set its IsPreviousOf relation to this DOI
#
end
end
################################### USAGE EXAMPLE
# with prominent readme
export_1 = ZenodoFileExport.new(
files: ["path/to/alm_report.zip"],
export_type: "AlmStatsZenodoFileExport",
readme_file: "path/to/Readme.md" #
).export!
# with readme as just another file
export_2 = ZenodoFileExport.new(
files: ["path/to/alm_report.zip", "path/to/readme.zip"],
export_type: "AlmStatsZenodoFileExport",
readme_file: "path/to/Readme.md"
).export!
# At this point in time export_2 will have the following settings:
# * IsPreviousVersionOf relation will not be set
# * IsPartOf relation will be export_1's DOI
# * IsNewerVersionOf relation will be set to export_1's DOI
# export_1 will have the following settings:
# * IsPreviousVersionOf relation will be set to export_2's DOi
# * IsPartOf relation will not be set
# * IsNewerVersionOf relation will not be set
export_3 = ZenodoFileExport.new(
files: ["path/to/alm_report.zip"],
export_type: "AlmStatsZenodoFileExport"
).export!
# At this point in time export_3 will have the following settings:
# * IsPreviousVersionOf relation will not be set
# * IsPartOf relation will be export_1's DOI
# * IsNewerVersionOf relation will be set to export_2's DOI
# export_2 will have the following settings:
# * IsPreviousVersionOf relation will be set to export_3's DOi
# * IsPartOf relation will be set to export_1's DOI
# * IsNewerVersionOf relation will be set to export_1's DOI
# export_1 will have the following settings:
# * IsPreviousVersionOf relation will be set to export_2's DOi
# * IsPartOf relation will not be set
# * IsNewerVersionOf relation will not be set
# export_2 will have the following settings:
# * IsPartOf relation will be export_1's DOI
# * IsNewerVersionOf relation will be set to export_1's DOI

Option B

In this approach ZenodoFileExport is more of an abstract base class (or could become a mixin). The primary goal here would be to encapsulate export differences in a concrete (subclass) implementation. This would reduce the risk that exported files had the wrong export type and would possibly get incorrect relations set up. It also would promote the discoverability of this functionality because there woudl be a dedicated place in the code-base where you could find and explore the different kinds of exports.

The downside here is that in order to re-use zenodo file exports you'd be encouraged to implement a new base class for the specific type of file(s) you wanted to export to Zenodo. It makes it a little bit more work. Another downside is that you end up with more code than what may be necessary. Until Lagotto actually needs to have truly custom behavior for a particular kind of report you could get away with ZenodoFileExport and avoid unnecessary class proliferation at the expense of being slightly less discoverable.

# Pretty much the same implementation as Option A
class ZenodoFileExport
cattr_accessor :export_type
cattr_accessor :readme_file
def export!
end
end
class AlmStatsZenodoFileExport < ZenodoFileExport
self.report_type = "AlmStats"
self.readme_file = "path/to/README.markdown"
end
class SomeFutureZenodoFileExport < ZenodoFileExport
self.report_type = "A Different Kind of Report"
self.readme_file = "path/to/SOME_OTHER_README.txt"
end
################################### USAGE EXAMPLE
export = AlmStatsZenodoFileExport.create(
:files => ["path/to/alm_report.zip"]
).export!

Option C

This approach is a combination of OptionA and OptionB. It would be have ZenodoFileExport be a generic base-class that worked out of the box (e.g. you'd be required to pass in the export_type or it'd raise an exception). Additionally, you can still subclass it to override specific values as needed.

# Pretty much the same implementation as Option A
class ZenodoFileExport
cattr_accessor :export_type
cattr_accessor :readme_file
def export!
end
end
class AlmStatsZenodoFileExport < ZenodoFileExport
# This could be the default.
self.report_type = "AlmStats"
end
################################### USAGE EXAMPLE
# Both of the following would work
export_1 = ZenodoFileExport.new(
files: ["path/to/alm_report.zip"],
export_type: "AlmStats",
self.readme_file = "path/to/some/README.txt"
).export!
export_2 = AlmStatsZenodoZenodoFileExport.new(
files: ["path/to/alm_report.zip"]
).export!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment