{"id":13558206,"url":"https://github.com/sul-dlss/riiif","last_synced_at":"2025-04-09T21:23:36.965Z","repository":{"id":11842654,"uuid":"14399526","full_name":"sul-dlss/riiif","owner":"sul-dlss","description":"IIIF image server in ruby","archived":false,"fork":false,"pushed_at":"2024-01-17T14:36:39.000Z","size":28094,"stargazers_count":39,"open_issues_count":15,"forks_count":20,"subscribers_count":24,"default_branch":"main","last_synced_at":"2024-04-29T14:21:55.896Z","etag":null,"topics":["access","iiif"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sul-dlss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-14T15:53:57.000Z","updated_at":"2024-06-18T19:48:52.547Z","dependencies_parsed_at":"2024-06-18T20:00:13.670Z","dependency_job_id":null,"html_url":"https://github.com/sul-dlss/riiif","commit_stats":null,"previous_names":["curationexperts/riiif"],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sul-dlss%2Friiif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sul-dlss%2Friiif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sul-dlss%2Friiif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sul-dlss%2Friiif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sul-dlss","download_url":"https://codeload.github.com/sul-dlss/riiif/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248113147,"owners_count":21049791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access","iiif"],"created_at":"2024-08-01T12:04:48.542Z","updated_at":"2025-04-09T21:23:36.940Z","avatar_url":"https://github.com/sul-dlss.png","language":"Ruby","funding_links":[],"categories":["Ruby","others"],"sub_categories":[],"readme":"# Riiif\n[![Gem Version](https://badge.fury.io/rb/riiif.png)](http://badge.fury.io/rb/riiif)\n\nA Ruby IIIF image server as a rails engine. \n\n## Installation\n\nRIIIF depends on Imagemagick so you must install that first. On a mac using Homebrew you can follow these instructions:\n\nImageMagick (7.0.4) may be installed with a few options:\n* `--with-ghostscript` Compile with Ghostscript for Postscript/PDF support\n* `--with-tiff` Compile with libtiff support for TIFF files\n* `--with-openjpeg` Compile with openjpeg2 support for jpeg2000\n\n```bash\nbrew install imagemagick --with-ghostscript --with-tiff --with-openjpeg\n```\n\n## Install the gem\nAdd this line to your application's Gemfile:\n\n    gem 'riiif'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install riiif\n\n## Configure\n\n### Images on the servers file system.\n\nBy default Riiif is set to load images from the filesystem using the Riiif::FileSystemFileResolver.\nYou can configure how this resolver finds the files by setting this property:\n```\n    Riiif::Image.file_resolver.base_path = '/opt/repository/images/'\n```\nWhen the Id passed in is \"foo_image\", then it will look for an image file using this glob:\n```\n/opt/repository/images/foo_image.{png,jpg,tiff,jp,jp2}\n```\n\n### Images retrieved over HTTP\nIt's preferable to use files on the filesystem, because this avoids the overhead of downloading the file.  If this is unavoidable, Riiif can be configured to fetch files from the network.  To enable this behavior, configure Riiif to use an alternative resolver:\n```\n      Riiif::Image.file_resolver = Riiif::HttpFileResolver.new\n```\nThen we configure the resolver with a mechanism for mapping the provided id to a url:\n```\n      Riiif::Image.file_resolver.id_to_uri = lambda do |id|\n        \"http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/#{id}.jpg/600px-#{id}.jpg\"\n      end\n```\nIf you need to use HTTP basic authentication you can enable it like this:\n```\n      Riiif::Image.file_resolver.basic_auth_credentials = ['username', 's0s3kr3t']\n```\n\nThis file resolver caches the network files, so you will want to clear out the old files or the cache will expand until you run out of disk space.\nUsing a script like this would be a good idea: https://github.com/pulibrary/loris/blob/607567b921404a15a2111fbd7123604f4fdec087/bin/loris-cache_clean.sh\nBy default the cache is located in `tmp/network_files`. You can set the cache path like this: `Riiif::Image.file_resolver.cache_path = '/var/cache'`\n### Kakadu (for faster jp2 decoding)\nTo configure Riiif to use Kakadu set:\n\n```ruby\nRiiif::Engine.config.kakadu_enabled = true\n```\n\nSee [benchmark](docs/benchmark.md) for details\n\n### GraphicsMagick\n\nTo use [GraphicsMagick](http://www.graphicsmagick.org/) instead of ImageMagick\n\n    Riiif::ImagemagickCommandFactory.external_command = \"gm convert\"\n    Riiif::ImageMagickInfoExtractor.external_command  = \"gm identify\"\n\nYou will of course need to install GraphicsMagick on your system.\n\n## Usage\n\nAdd the routes to your application by inserting the following line into `config/routes.rb`\n```\n  mount Riiif::Engine =\u003e '/image-service', as: 'riiif'\n```\n\nThen you can make requests like this:\n\n* http://www.example.org/image-service/abcd1234/full/full/0/default.jpg\n* http://www.example.org/image-service/abcd1234/full/100,/0/default.jpg\n* http://www.example.org/image-service/abcd1234/full/,100/0/default.jpg\n* http://www.example.org/image-service/abcd1234/full/pct:50/0/default.jpg\n* http://www.example.org/image-service/abcd1234/full/150,75/0/default.jpg\n* http://www.example.org/image-service/abcd1234/full/!150,75/0/default.jpg\n\n### Route helpers\n\nIt is prefereable that you use the provided route helpers to build these URIs. Here's an example:\n\n```ruby\n  image_tag(Riiif::Engine.routes.url_helpers.image_path(file_id, size: ',600'))\n```\n\n### Using default images for missing and unauthorized requests\n\nIf there is a request for an id that doesn't exist, a 404 will be\nreturned. You can optionally return an image with this 404 by setting\nthis in your initializer:\n\n```ruby\nRiiif.not_found_image = 'path/to/image.png'\n```\n\nIf the request is unauthorized, a 401 will be returned, and a custom\nerror image can also be configured.\n\n```ruby\nRiiif.unauthorized_image = 'path/to/unauthorized_image.png'\n```\n\nYou can do this to create a default Riiif::Image to use (useful for passing \"missing\" images to openseadragon_collection_viewer):\n\n```ruby\nRiiif::Image.new('no_image', Riiif::File.new(Riiif.not_found_image))\n```\n\n## Authorization\n\nThe controller will call an authorization service with the controller context.  This service must have a method `can?(action, image)` which returns a boolean. The default service is the `RIIIF::NilAuthrorizationService` which permits all requests.\n\nIn this example we've dissallowed all requests:\n\n```ruby\nclass NoService\n  def initalize(controller)\n  end\n\n  def can?(action, image)\n    false\n  end\nend\n\nRiiif::Image.authorization_service = NoService\n```\n\n## Integration with Hydra/Fedora\n\nCreate an initializer like this in `config/initializers/riiif_initializer.rb`\n\n```ruby\n# Tell RIIIF to get files via HTTP (not from the local disk)\nRiiif::Image.file_resolver = Riiif::HttpFileResolver.new\n\n# This tells RIIIF how to resolve the identifier to a URI in Fedora\nRiiif::Image.file_resolver.id_to_uri = lambda do |id|\n  ActiveFedora::Base.id_to_uri(CGI.unescape(id)).tap do |url|\n    logger.info \"Riiif resolved #{id} to #{url}\"\n  end\nend\n\n# In order to return the info.json endpoint, we have to have the full height and width of\n# each image. If you are using hydra-file_characterization, you have the height \u0026 width\n# cached in Solr. The following block directs the info_service to return those values:\nRiiif::Image.info_service = lambda do |id, file|\n  # id will look like a path to a pcdm:file\n  # (e.g. rv042t299%2Ffiles%2F6d71677a-4f80-42f1-ae58-ed1063fd79c7)\n  # but we just want the id for the FileSet it's attached to.\n\n  # Capture everything before the first slash\n  fs_id = id.sub(/\\A([^\\/]*)\\/.*/, '\\1')\n  resp = ActiveFedora::SolrService.get(\"id:#{fs_id}\")\n  doc = resp['response']['docs'].first\n  raise \"Unable to find solr document with id:#{fs_id}\" unless doc\n\n  # You’ll want default values if you make thumbnails of PDFs or other\n  # file types that `identify` won’t return dimensions for\n  {\n    height: doc[\"height_is\"] || 100,\n    width: doc[\"width_is\"] || 100,\n    format: doc[\"mime_type_ssi\"],\n  }\nend\n\ndef logger\n  Rails.logger\nend\n\n# Note that this is translated to an `expires` argument to the\n# ActiveSupport::Cache::Store in use, by default the host application's\n# Rails.cache. Some cache stores may not automatically purge expired content,\n# such as the default FileStore.\n# http://guides.rubyonrails.org/caching_with_rails.html#cache-stores\nRiiif::Engine.config.cache_duration = 30.days\n```\n#### Special note for Passenger and Apache users\nIf you are running riiif in Passenger under Apache, you must set the following in your virtual host definition:\n\n```\nAllowEncodedSlashes NoDecode\n```\n\nYou may also need to set the following in your virtual host definition, either at the top level, or within a\nLocation block for a specific path. See the [Passenger configuration reference](https://www.phusionpassenger.com/library/config/apache/reference/#passengerallowencodedslasheshttps://www.phusionpassenger.com/library/config/apache/reference/#passengerallowencodedslashes) for more info.\n\n```\nPassengerAllowEncodedSlashes on\n```\n\nAn alternative approach to `PassengerAllowEncodedSlashes on` is to explicitly decode the url, like this:\n\n```ruby\nrequire \"uri\"\nfs_id = URI.decode(id).sub(/\\A([^\\/]*)\\/.*/, '\\1')\n```\n\n## Running the tests\nFirst, build the engine\n```bash\nrake engine_cart:generate\n```\n\nRun the tests\n```bash\nrake spec\n```\n\n\n## For more information\nsee the IIIF spec:\n\nhttp://www-sul.stanford.edu/iiif/image-api/1.1/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsul-dlss%2Friiif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsul-dlss%2Friiif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsul-dlss%2Friiif/lists"}