diff --git a/default.nix b/default.nix index d6fd300..ee5d21f 100644 --- a/default.nix +++ b/default.nix @@ -35,4 +35,5 @@ in { dhmd-veranstaltungen = wrapScript "dhmd-veranstaltungen" ./dhmd-veranstaltungen/scrape.rb; mkz-programm = wrapScript "mkz-programm" ./mkz-programm/scrape.rb; drk-impfaktionen = wrapScript "drk-impfaktionen" ./drk-impfaktionen/scrape.rb; + zuendstoffe = wrapScript "zuendstoffe" ./zuendstoffe/scrape.rb; } diff --git a/zuendstoffe/scrape.rb b/zuendstoffe/scrape.rb new file mode 100644 index 0000000..3475d53 --- /dev/null +++ b/zuendstoffe/scrape.rb @@ -0,0 +1,167 @@ +#!/usr/bin/env ruby +# coding: utf-8 + +require 'uri' +require 'net/http' +require 'json' +require 'time' +require 'erb' + +url = "https://zuendstoffe.materialvermittlung.org/graphql" +uri = URI.parse(url) +http = Net::HTTP.new(uri.host, uri.port) +http.use_ssl = uri.is_a?(URI::HTTPS) + +req = Net::HTTP::Post.new(uri.request_uri, + 'Content-Type' => 'application/json' +) +req.body = { + "operationName" => "MaterialQuery", + "variables" => { + "hasAvailableQuantity" => true, + "first" => 9000, + }, + "query" => <<-EOF + query MaterialsQuery($first: Int, $hasAvailableQuantity: Boolean) { + materials(first: $first hasAvailableQuantity: $hasAvailableQuantity) { + edges { + node { + id + _id + title + description + isNew + isDraft + isFinished + quantityUnit + availableQuantity + inflowQuantity + pickedUpQuantity + reservedQuantity + publishAt + updatedAt + visibleUntil + validationResults + color + dimensions + isDraft + visibleUntil + disallowPartialReservations + images { + id + thumbnailUrl + previewUrl + detailsUrl + __typename + } + storage { + id + _id + title + isPublic + notes + addressStreet + addressPostalCode + addressCity + contact + __typename + } + __typename + } + } + } + } + EOF +}.to_json + +res = http.request(req) +if res.code != "200" + raise "HTTP #{res.code}" +end + + +class Material + attr_accessor :link + attr_accessor :title + attr_accessor :descriptions + attr_accessor :updated + attr_accessor :published + attr_accessor :images + attr_accessor :storages +end + +json = JSON.parse(res.body) +materials = json["data"]["materials"]["edges"].collect do |edge| + edge["node"] +end.collect do |node| + begin + m = Material.new + m.link = URI.join(uri, "/material/#{node["_id"]}") + m.title = node["title"] + if node["availableQuantity"] and node["quantityUnit"] + m.title = "#{node["availableQuantity"]} #{node["quantityUnit"]} #{m.title}" + end + m.descriptions = [node["color"], node["dimensions"], node["description"]] + .filter { |s| s.to_s.size > 1 } + m.published = Time.parse(node["publishAt"]) + m.updated = Time.parse(node["publishAt"]) + m.images = node["images"].collect do |img| + img["detailsUrl"] ? URI.join(uri, img["detailsUrl"]) : nil + end.compact + s = node["storage"] + m.storages = [ + s["notes"], + s["contact"], + s["title"], + s["addressStreet"], + "#{s["addressPostalCode"]} #{s["addressCity"]}", + ].collect { |s| s.strip } + .filter { |s| s.to_s.size > 1 } + m + rescue + STDERR.puts $!.inspect + nil + end +end.compact + +def escape_xml s + s.to_s + .gsub(/&/, "&") + .gsub(//, ">") + .gsub(/"/, """) +end + +atom = ERB::new <<~EOF + + + Zuendstoffe Materialvermittlung + + <%= Time.now.iso8601 %> + + <% materials.each do |m| %> + + <%= escape_xml m.title %> + <%= m.published.iso8601 %> + <%= m.updated.iso8601 %> + + <%= escape_xml m.link %> + + +
+ <% m.descriptions.each do |d| %> +

<%= escape_xml d %>

+ <% end %> + <% m.images.each do |i| %> + + <% end %> + <% m.storages.each do |s| %> +

<%= escape_xml s %>

+ <% end %> +
+
+
+ <% end %> +
+EOF +puts atom.result