-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
817 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
# frozen_string_literal: true | ||
|
||
module Report | ||
module Darwin | ||
# Darwin Core Observations format. | ||
class EolImages < Report::CSV | ||
VOTE_CUTOFF = 2.5 | ||
|
||
attr_accessor :query | ||
|
||
self.separator = "\t" | ||
|
||
def initialize(args) | ||
super(args) | ||
initialize_query | ||
end | ||
|
||
def initialize_query | ||
self.query = tables[:images] | ||
add_joins | ||
add_project | ||
add_conditions | ||
end | ||
|
||
def add_conditions | ||
query.where(tables[:observations][:vote_cache].gteq(VOTE_CUTOFF)) | ||
query.where(tables[:images][:ok_for_export].eq(1)) | ||
add_name_conditions(tables[:names]) | ||
end | ||
|
||
def add_name_conditions(table) | ||
query.where(table[:ok_for_export].eq(1)) | ||
query.where(table[:deprecated].eq(0)) | ||
query.where(table[:text_name].does_not_match('%"%')) | ||
add_rank_condition(table) | ||
end | ||
|
||
def add_rank_condition(table) | ||
query.where(table[:rank].lteq(Name.ranks[:Genus])) | ||
end | ||
|
||
def tables | ||
@tables ||= { | ||
images: Image.arel_table, | ||
images_observations: Arel::Table.new(:images_observations), | ||
licenses: License.arel_table, | ||
names: Name.arel_table, | ||
observations: Observation.arel_table, | ||
users: User.arel_table | ||
} | ||
end | ||
|
||
def add_joins | ||
join_table(:images_observations, :image_id, attribute(:images, :id)) | ||
join_table(:observations, :id, | ||
attribute(:images_observations, :observation_id)) | ||
join_table(:names, :id, attribute(:observations, :name_id)) | ||
join_table(:licenses, :id, attribute(:images, :license_id)) | ||
join_table(:users, :id, attribute(:images, :user_id)) | ||
end | ||
|
||
def join_table(join_name, join_field, attribute) | ||
table = tables[join_name] | ||
join_attribute = table[join_field] | ||
self.query = query.join(table).on(join_attribute.eq(attribute)) | ||
end | ||
|
||
def add_project | ||
query.project(attribute(:images, :id), | ||
attribute(:observations, :name_id), | ||
attribute(:names, :text_name), | ||
attribute(:names, :classification), | ||
attribute(:images, :when), | ||
attribute(:users, :name), | ||
attribute(:users, :login), | ||
attribute(:licenses, :url).as("license_url"), | ||
attribute(:images, :copyright_holder)) | ||
end | ||
|
||
def attribute(table_name, field) | ||
tables[table_name][field] | ||
end | ||
|
||
def formatted_rows | ||
@formatted_rows = sort_after(rows.map { |row| format_image_row(row) }) | ||
end | ||
|
||
def rows | ||
@rows ||= ActiveRecord::Base.connection.exec_query(query.to_sql) | ||
end | ||
|
||
def taxa | ||
return @taxa if @taxa | ||
|
||
@taxa = Set.new | ||
rows.each do |row| | ||
@taxa.add([row["name_id"], row["text_name"], row["classification"]]) | ||
end | ||
@taxa | ||
end | ||
|
||
def labels | ||
%w[ | ||
identifier | ||
type | ||
format | ||
accessURL | ||
furtherInformationURL | ||
taxonID | ||
created | ||
creator | ||
license | ||
rightsHolder | ||
] | ||
end | ||
|
||
def sort_after(rows) | ||
rows.sort_by { |row| row[0].to_i } | ||
end | ||
|
||
private | ||
|
||
def image_url(id) | ||
"https://mushroomobserver.org/images/640/#{id}.jpg" | ||
end | ||
|
||
def show_image_url(id) | ||
"https://mushroomobserver.org/image/show_image/#{id}" | ||
end | ||
|
||
def format_image_row(row) | ||
[row["id"].to_s, | ||
"StillImage", | ||
"image/jpeg", | ||
image_url(row["id"]), | ||
show_image_url(row["id"]), | ||
row["name_id"].to_s, | ||
row["when"].to_s, | ||
row["name"].to_s == "" ? row["login"] : row["name"], | ||
row["license_url"], | ||
row["copyright_holder"]] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# frozen_string_literal: true | ||
|
||
module Report | ||
module Darwin | ||
class EolTaxa < Report::CSV | ||
attr_accessor :taxa, :genus_cache | ||
|
||
self.separator = "\t" | ||
|
||
def initialize(args) | ||
super(args) | ||
self.taxa = args[:taxa] | ||
self.genus_cache = {} | ||
end | ||
|
||
def formatted_rows | ||
results = [] | ||
taxa.each do |row| | ||
results.append([row[0], row[1]] + higher_taxa(row)) | ||
end | ||
results.sort_by { |row| row[1] } | ||
end | ||
|
||
def labels | ||
%w[ | ||
taxonID | ||
scientificName | ||
genus | ||
family | ||
kingdom | ||
] | ||
end | ||
|
||
private | ||
|
||
def parse_genus(name) | ||
name.split(' ')[0] | ||
end | ||
|
||
def higher_taxa(row) | ||
genus = parse_genus(row[1]) | ||
return genus_cache[genus] if genus_cache.key?(genus) | ||
|
||
family_and_kingdom = (parse_classification(row[2]) || | ||
genus_classification(genus)) | ||
result = [genus] + family_and_kingdom | ||
genus_cache[genus] = result | ||
result | ||
end | ||
|
||
def parse_classification(classification) | ||
return nil unless classification | ||
|
||
kingdom = nil | ||
family = nil | ||
classification.split("_\r\n").each do |level| | ||
kingdom = extract_name(level) if level.start_with?("Kingdom") | ||
family = extract_name(level) if level.start_with?("Family") | ||
return [family, kingdom] if family && kingdom | ||
end | ||
return ["", kingdom] if kingdom | ||
nil | ||
end | ||
|
||
def extract_name(level) | ||
level.split(": _")[1].chomp("_") | ||
end | ||
|
||
def genus_classification(genus) | ||
name = Name.find_by(text_name: genus, rank: Name.ranks[:Genus]) | ||
if name | ||
family_and_kingdom = parse_classification(name.classification) | ||
return family_and_kingdom if family_and_kingdom | ||
end | ||
["", ""] | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# frozen_string_literal: true | ||
|
||
module Report | ||
module Darwin | ||
# Darwin Core Observations format. | ||
class GbifImages < Report::CSV | ||
VOTE_CUTOFF = 2.5 | ||
PROJECTION_ATTRIBUTES = [[:images, :id], | ||
[:images, :when], | ||
[:images, :copyright_holder], | ||
[:images_observations, :observation_id], | ||
[:observations, :updated_at], | ||
[:observations, :when, "obs_when"], | ||
[:observations, :lat], | ||
[:observations, :long], | ||
[:observations, :alt], | ||
[:observations, :notes], | ||
[:names, :text_name], | ||
[:names, :author], | ||
[:names, :rank], | ||
[:locations, :name, "location_name"], | ||
[:locations, :north], | ||
[:locations, :south], | ||
[:locations, :east], | ||
[:locations, :west], | ||
[:locations, :high], | ||
[:locations, :low], | ||
[:users, :name], | ||
[:users, :login], | ||
[:licenses, :url, "license_url"]].freeze | ||
|
||
attr_accessor :query | ||
|
||
self.separator = "\t" | ||
|
||
def initialize(args) | ||
super(args) | ||
initialize_query | ||
end | ||
|
||
def initialize_query | ||
self.query = tables[:images] | ||
add_joins | ||
add_project | ||
add_conditions | ||
end | ||
|
||
def add_conditions | ||
add_observation_conditions(tables[:observations]) | ||
query.where(tables[:images][:ok_for_export].eq(1)) | ||
add_name_conditions(tables[:names]) | ||
end | ||
|
||
def add_observation_conditions(table) | ||
query.where(table[:vote_cache].gteq(VOTE_CUTOFF)) | ||
query.where(table[:gps_hidden].eq(0)) | ||
end | ||
|
||
def add_name_conditions(table) | ||
query.where(table[:ok_for_export].eq(1)) | ||
query.where(table[:deprecated].eq(0)) | ||
query.where(table[:text_name].does_not_match('%"%')) | ||
add_rank_condition(table, [:Species, :Genus]) | ||
end | ||
|
||
def add_rank_condition(table, ranks) | ||
query.where(table[:rank].in(ranks.map { |rank| Name.ranks[rank] })) | ||
end | ||
|
||
def tables | ||
@tables ||= { | ||
images: Image.arel_table, | ||
images_observations: Arel::Table.new(:images_observations), | ||
licenses: License.arel_table, | ||
locations: Location.arel_table, | ||
names: Name.arel_table, | ||
observations: Observation.arel_table, | ||
users: User.arel_table | ||
} | ||
end | ||
|
||
def add_joins | ||
join_table(:images_observations, :image_id, attribute(:images, :id)) | ||
join_table(:observations, :id, | ||
attribute(:images_observations, :observation_id)) | ||
join_table(:names, :id, attribute(:observations, :name_id)) | ||
join_table(:locations, :id, attribute(:observations, :location_id)) | ||
join_table(:users, :id, attribute(:images, :user_id)) | ||
join_table(:licenses, :id, attribute(:images, :license_id)) | ||
end | ||
|
||
def join_table(join_name, join_field, attribute) | ||
table = tables[join_name] | ||
join_attribute = table[join_field] | ||
self.query = query.join(table).on(join_attribute.eq(attribute)) | ||
end | ||
|
||
def add_project | ||
query.project(*project_attributes) | ||
end | ||
|
||
def project_attributes | ||
PROJECTION_ATTRIBUTES.map do |spec| | ||
result = attribute(spec[0], spec[1]) | ||
spec.length > 2 ? result.as(spec[2]) : result | ||
end | ||
end | ||
|
||
def attribute(table_name, field) | ||
tables[table_name][field] | ||
end | ||
|
||
def formatted_rows | ||
@formatted_rows = sort_after(rows.map { |row| format_image_row(row) }) | ||
end | ||
|
||
def rows | ||
@rows ||= ActiveRecord::Base.connection.exec_query(query.to_sql) | ||
end | ||
|
||
def observations | ||
return @observations if @taxa | ||
|
||
obs_hash = {} | ||
rows.each { |row| obs_hash[row["observation_id"]] = row } | ||
@observations = obs_hash.values | ||
end | ||
|
||
def labels | ||
%w[ | ||
identifier | ||
type | ||
format | ||
accessURL | ||
furtherInformationURL | ||
created | ||
creator | ||
license | ||
rightsHolder | ||
] | ||
end | ||
|
||
def sort_after(rows) | ||
rows.sort_by { |row| row[0].to_i } | ||
end | ||
|
||
private | ||
|
||
def image_url(id) | ||
"https://mushroomobserver.org/images/640/#{id}.jpg" | ||
end | ||
|
||
def show_image_url(id) | ||
"https://mushroomobserver.org/image/show_image/#{id}" | ||
end | ||
|
||
def format_image_row(row) | ||
[row["observation_id"].to_s, | ||
"StillImage", | ||
"image/jpeg", | ||
image_url(row["id"]), | ||
show_image_url(row["id"]), | ||
row["when"].to_s, | ||
row["name"].to_s == "" ? row["login"] : row["name"], | ||
row["license_url"], | ||
row["copyright_holder"]] | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.