├── _config_prod.yml ├── .gitignore ├── .github ├── bin │ └── build_jekyll.sh └── workflows │ ├── master.yml │ └── preview.yml ├── 404.html ├── Bodleian └── bodleian.json ├── Gemfile ├── _includes ├── header.html └── social.html ├── _posts └── 2020-09-30-welcome-to-jekyll.markdown ├── _config.yml ├── Gemfile.lock ├── README.md ├── index.md └── src └── createAS.py /_config_prod.yml: -------------------------------------------------------------------------------- 1 | 2 | url: https://registry.iiif.io 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | output 3 | _site 4 | .sass-cache 5 | .jekyll-cache 6 | .jekyll-metadata 7 | vendor 8 | -------------------------------------------------------------------------------- /.github/bin/build_jekyll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | bundle config path vendor/bundle 4 | if [ $? -eq 1 ];then 5 | echo "Failed adding config path" 6 | exit 1 7 | fi 8 | 9 | bundle install 10 | if [ $? -eq 1 ];then 11 | echo "Failed bundle install" 12 | exit 1 13 | fi 14 | 15 | echo "Running config: $CONFIG" 16 | bundle exec jekyll build --baseurl $BASE_URL $CONFIG 17 | if [ $? -eq 1 ];then 18 | echo "Failed jekyll build" 19 | exit 1 20 | fi 21 | 22 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | --- 2 | permalink: /404.html 3 | layout: default 4 | --- 5 | 6 | 19 | 20 |
21 |

404

22 | 23 |

Page not found :(

24 |

The requested page could not be found.

25 |
26 | -------------------------------------------------------------------------------- /Bodleian/bodleian.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "https://www.bodleian.ox.ac.uk/", 3 | "institution": { "en" : ["Bodleian Libraries, University of Oxford"] }, 4 | "provider": { 5 | "id": "https://digital.bodleian.ox.ac.uk", 6 | "label": { "en": ["Digital Bodleian: Bodleian Libraries and Oxford College Libraries"] } 7 | }, 8 | "streams": [ 9 | { 10 | "id": "https://iiif.bodleian.ox.ac.uk/iiif/activity/all-changes", 11 | "label": {"en": ["All changes"]} 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | # Hello! This is where you manage which Jekyll version is used to run. 3 | # When you want to use a different version, change it below, save the 4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 5 | # 6 | # bundle exec jekyll serve 7 | # 8 | # This will help ensure the proper Jekyll version is running. 9 | # Happy Jekylling! 10 | gem "jekyll", "~> 4.1.1" 11 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 12 | gem "minima", "~> 2.5" 13 | 14 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem 15 | # and associated library. 16 | platforms :mingw, :x64_mingw, :mswin, :jruby do 17 | gem "tzinfo", "~> 1.2" 18 | gem "tzinfo-data" 19 | end 20 | 21 | # Performance-booster for watching directories on Windows 22 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] 23 | 24 | -------------------------------------------------------------------------------- /_includes/header.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /_posts/2020-09-30-welcome-to-jekyll.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Welcome to Jekyll!" 4 | date: 2020-09-30 00:28:44 +0100 5 | categories: jekyll update 6 | --- 7 | You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated. 8 | 9 | Jekyll requires blog post files to be named according to the following format: 10 | 11 | `YEAR-MONTH-DAY-title.MARKUP` 12 | 13 | Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works. 14 | 15 | Jekyll also offers powerful support for code snippets: 16 | 17 | {% highlight ruby %} 18 | def print_hi(name) 19 | puts "Hi, #{name}" 20 | end 21 | print_hi('Tom') 22 | #=> prints 'Hi, Tom' to STDOUT. 23 | {% endhighlight %} 24 | 25 | Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk]. 26 | 27 | [jekyll-docs]: https://jekyllrb.com/docs/home 28 | [jekyll-gh]: https://github.com/jekyll/jekyll 29 | [jekyll-talk]: https://talk.jekyllrb.com/ 30 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Welcome to Jekyll! 2 | # 3 | # This config file is meant for settings that affect your whole blog, values 4 | # which you are expected to set up once and rarely edit after that. If you find 5 | # yourself editing this file very often, consider using Jekyll's data files 6 | # feature for the data you need to update frequently. 7 | # 8 | # For technical reasons, this file is *NOT* reloaded automatically when you use 9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process. 10 | # 11 | # If you need help with YAML syntax, here are some quick references for you: 12 | # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml 13 | # https://learnxinyminutes.com/docs/yaml/ 14 | # 15 | # Site settings 16 | # These are used to personalize your new site. If you look in the HTML files, 17 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. 18 | # You can create any custom variable you would like, and they will be accessible 19 | # in the templates via {{ site.myvariable }}. 20 | 21 | title: IIIF Registry 22 | description: >- # this means to ignore newlines until "baseurl:" 23 | This is the basis of the IIIF Registry of Activity streams. 24 | url: "https://preview.iiif.io" # the base hostname & protocol for your site, e.g. http://example.com 25 | twitter_username: iiif_io 26 | github_username: IIIF/registry 27 | 28 | # Build settings 29 | theme: minima 30 | 31 | kramdown: 32 | input: GFM 33 | parse_block_html: true 34 | toc_levels: 2..4 35 | #syntax_highlighter: rouge 36 | 37 | syntax_highlighter_opts: 38 | wrap: div 39 | css: class 40 | 41 | webrick: 42 | headers: 43 | Access-Control-Allow-Origin: "*" 44 | 45 | exclude: ["scripts", "Gemfile", "Gemfile.lock", "node_modules", "vendor/bundle/", "vendor/cache/", "vendor/gems/", "vendor/ruby/"] 46 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.7.0) 5 | public_suffix (>= 2.0.2, < 5.0) 6 | colorator (1.1.0) 7 | concurrent-ruby (1.1.7) 8 | em-websocket (0.5.2) 9 | eventmachine (>= 0.12.9) 10 | http_parser.rb (~> 0.6.0) 11 | eventmachine (1.2.7) 12 | ffi (1.13.1) 13 | forwardable-extended (2.6.0) 14 | http_parser.rb (0.6.0) 15 | i18n (1.8.5) 16 | concurrent-ruby (~> 1.0) 17 | jekyll (4.1.1) 18 | addressable (~> 2.4) 19 | colorator (~> 1.0) 20 | em-websocket (~> 0.5) 21 | i18n (~> 1.0) 22 | jekyll-sass-converter (~> 2.0) 23 | jekyll-watch (~> 2.0) 24 | kramdown (~> 2.1) 25 | kramdown-parser-gfm (~> 1.0) 26 | liquid (~> 4.0) 27 | mercenary (~> 0.4.0) 28 | pathutil (~> 0.9) 29 | rouge (~> 3.0) 30 | safe_yaml (~> 1.0) 31 | terminal-table (~> 1.8) 32 | jekyll-feed (0.15.0) 33 | jekyll (>= 3.7, < 5.0) 34 | jekyll-sass-converter (2.1.0) 35 | sassc (> 2.0.1, < 3.0) 36 | jekyll-seo-tag (2.6.1) 37 | jekyll (>= 3.3, < 5.0) 38 | jekyll-watch (2.2.1) 39 | listen (~> 3.0) 40 | kramdown (2.3.0) 41 | rexml 42 | kramdown-parser-gfm (1.1.0) 43 | kramdown (~> 2.0) 44 | liquid (4.0.3) 45 | listen (3.2.1) 46 | rb-fsevent (~> 0.10, >= 0.10.3) 47 | rb-inotify (~> 0.9, >= 0.9.10) 48 | mercenary (0.4.0) 49 | minima (2.5.1) 50 | jekyll (>= 3.5, < 5.0) 51 | jekyll-feed (~> 0.9) 52 | jekyll-seo-tag (~> 2.1) 53 | pathutil (0.16.2) 54 | forwardable-extended (~> 2.6) 55 | public_suffix (4.0.6) 56 | rb-fsevent (0.10.4) 57 | rb-inotify (0.10.1) 58 | ffi (~> 1.0) 59 | rexml (3.2.4) 60 | rouge (3.23.0) 61 | safe_yaml (1.0.5) 62 | sassc (2.4.0) 63 | ffi (~> 1.9) 64 | terminal-table (1.8.0) 65 | unicode-display_width (~> 1.1, >= 1.1.1) 66 | unicode-display_width (1.7.0) 67 | 68 | PLATFORMS 69 | ruby 70 | 71 | DEPENDENCIES 72 | jekyll (~> 4.1.1) 73 | kramdown (>= 1.17.0) 74 | minima (~> 2.5) 75 | tzinfo (~> 1.2) 76 | tzinfo-data 77 | wdm (~> 0.1.1) 78 | 79 | BUNDLED WITH 80 | 2.1.4 81 | -------------------------------------------------------------------------------- /.github/workflows/master.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Deploy-live 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | branches: 10 | - master 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "build" 14 | build: 15 | # The type of runner that the job will run on 16 | runs-on: ubuntu-latest 17 | 18 | # Steps represent a sequence of tasks that will be executed as part of the job 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 21 | - uses: actions/checkout@v2 22 | 23 | - name: Setup ruby 24 | uses: actions/setup-ruby@v1 25 | with: 26 | ruby-version: '2.7' 27 | - run: gem install bundler 28 | 29 | - uses: actions/cache@v1 30 | with: 31 | path: vendor/bundle 32 | key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} 33 | restore-keys: | 34 | ${{ runner.os }}-gems- 35 | 36 | # Build jekyll site 37 | - name: Build Jekyll 38 | run: .github/bin/build_jekyll.sh 39 | env: 40 | CONFIG: "--config _config.yml,_config_prod.yml" 41 | BASE_URL: "/" 42 | # build streams 43 | - name: Set up Python 3.x 44 | uses: actions/setup-python@v2 45 | with: 46 | # Semantic version range syntax or exact version of a Python version 47 | python-version: '3.x' 48 | # Optional - x64 or x86 architecture, defaults to x64 49 | architecture: 'x64' 50 | 51 | - name: Create streams 52 | run: src/createAS.py 53 | 54 | 55 | # Deploy to live site 56 | - name: Create GitHub deployment 57 | uses: glenrobson/deployments@v0.4.2 58 | id: deployment 59 | with: 60 | step: start 61 | token: ${{ secrets.GITHUB_TOKEN }} 62 | auto_inactive: 'false' 63 | env: production 64 | - name: Deploy to S3 65 | uses: glenrobson/s3-sync-action@v0.5.1 66 | with: 67 | args: --acl public-read --cache-control max-age=0,public 68 | env: 69 | AWS_S3_BUCKET: "iiif-registry" 70 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 71 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 72 | AWS_REGION: ${{ secrets.AWS_REGION }} 73 | SOURCE_DIR: "_site" 74 | - name: Update deployment status 75 | uses: glenrobson/deployments@v0.4.2 76 | if: always() 77 | with: 78 | step: finish 79 | auto_inactive: 'false' 80 | token: ${{ secrets.GITHUB_TOKEN }} 81 | status: ${{ job.status }} 82 | deployment_id: ${{ steps.deployment.outputs.deployment_id }} 83 | env_url: "https://registry.iiif.io" 84 | -------------------------------------------------------------------------------- /.github/workflows/preview.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Deploy-preview 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | branches: 10 | - '*' 11 | - '!master' 12 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 13 | jobs: 14 | # This workflow contains a single job called "build" 15 | build: 16 | # The type of runner that the job will run on 17 | runs-on: ubuntu-latest 18 | 19 | # Steps represent a sequence of tasks that will be executed as part of the job 20 | steps: 21 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 22 | - uses: actions/checkout@v2 23 | # store branch name in ${BRANCH_NAME} 24 | - uses: nelonoel/branch-name@v1.0.1 25 | 26 | - name: Setup ruby 27 | uses: actions/setup-ruby@v1 28 | with: 29 | ruby-version: '2.7' 30 | - run: gem install bundler 31 | 32 | - uses: actions/cache@v1 33 | with: 34 | path: vendor/bundle 35 | key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} 36 | restore-keys: | 37 | ${{ runner.os }}-gems- 38 | 39 | # Build jekyll site 40 | - name: Build Jekyll 41 | run: .github/bin/build_jekyll.sh 42 | env: 43 | CONFIG: "--config _config.yml" 44 | BASE_URL: "/registry/${{ env.BRANCH_NAME}}" 45 | 46 | # Create streams 47 | - name: Set up Python 3.x 48 | uses: actions/setup-python@v2 49 | with: 50 | # Semantic version range syntax or exact version of a Python version 51 | python-version: '3.x' 52 | # Optional - x64 or x86 architecture, defaults to x64 53 | architecture: 'x64' 54 | 55 | - name: Create streams 56 | run: src/createAS.py 57 | 58 | # Deploy to live site 59 | - name: Create GitHub deployment 60 | uses: glenrobson/deployments@v0.4.2 61 | id: deployment 62 | with: 63 | step: start 64 | token: ${{ secrets.GITHUB_TOKEN }} 65 | auto_inactive: 'false' 66 | env: staging 67 | - name: Deploy to S3 68 | uses: glenrobson/s3-sync-action@v0.5.1 69 | with: 70 | args: --acl public-read 71 | env: 72 | AWS_S3_BUCKET: "preview.iiif.io" 73 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 74 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 75 | AWS_REGION: ${{ secrets.AWS_REGION }} 76 | SOURCE_DIR: "_site" 77 | DEST_DIR: "registry/${BRANCH_NAME}" 78 | - name: Update deployment status 79 | uses: glenrobson/deployments@v0.4.2 80 | if: always() 81 | with: 82 | step: finish 83 | auto_inactive: 'false' 84 | token: ${{ secrets.GITHUB_TOKEN }} 85 | status: ${{ job.status }} 86 | deployment_id: ${{ steps.deployment.outputs.deployment_id }} 87 | env_url: "https://preview.iiif.io/registry/${{ env.BRANCH_NAME}}/index.html" 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IIIF Registry 2 | This is the basis of the IIIF Registry of Activity streams. This project aims to give access to a large amount of IIIF resources and provide a way to keep up to date with changes. The Activity Streams format is defined in the [Change Discovery Specification](https://iiif.io/api/discovery/0.4/). 3 | 4 | We welcome additions to the registry and additions can be made using the following process: 5 | 6 | 1. Create branch for your addition 7 | 2. Create a directory for your institution. This should be a short name without spaces or punctuation 8 | 3. Create a registry JSON file. See details below 9 | 4. Create a pull request with your changes and submit to IIIF/registry 10 | 11 | ## Registry JSON format 12 | 13 | To register a link to your streams we use the following JSON structure: 14 | 15 | ``` 16 | { 17 | "id": "http://www.getty.edu/", 18 | "institution": { 19 | "id": "http://www.getty.edu/", 20 | "label": { 21 | "en": [ "Getty" ] 22 | } 23 | }, 24 | "streams": [ 25 | { 26 | "id": "http://www.getty.edu/museum.json", 27 | "label": { 28 | "en": [ "Museum collections" ] 29 | } 30 | }, 31 | { 32 | "id": "http://www.getty.edu/library.json", 33 | "label": { 34 | "en": [ "Library collections" ] 35 | } 36 | }, 37 | { 38 | "id": "http://www.getty.edu/research.json", 39 | "label": { 40 | "en": [ "Research Center" ] 41 | } 42 | } 43 | ] 44 | } 45 | ``` 46 | 47 | Where: 48 | * `id` is a URI for your institution. This could be an institution website, Wikidata URI or other resolvable link. 49 | * `institution` the name of the institution that could be shown to a user. This is an optional field but encouraged. 50 | * `streams` list of activity streams for this institution 51 | * `id` Activity Stream URL. Must be resolvable 52 | * `label` a description that can be shown to the user so they can tell which stream to monitor for updates. 53 | 54 | The JSON file should be named appropriately so people know what it represents and must have an extension of `.json`. 55 | 56 | ## Aggregators 57 | 58 | For Aggregators or institutions that collect content from other providers and aggregate their content. A slightly different structure can be used. Examples of Aggregators would be Europeana or OCLC with ContentDM. Both hold multiple institutions' data. In this case the Aggregator would have one registry JSON file per institutional client. The Provider can then add the following to the root of the JSON to show who provided the content: 59 | 60 | ``` 61 | "provider": { 62 | "id": "https://www.oclc.org/en/home.html", 63 | "label": { 64 | "en": [ "OCLC" ] 65 | } 66 | }, 67 | ``` 68 | 69 | You can see examples of this in the [OCLC directory](https://github.com/IIIF/registry/tree/deploy/OCLC) where [instx.json](https://github.com/IIIF/registry/blob/deploy/OCLC/instx.json) would be the set of changes from one ContentDM instance and [insty.json](https://github.com/IIIF/registry/blob/deploy/OCLC/insty.json) is a second institution. 70 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: IIIF Registry 3 | layout: default 4 | tags: [tbc] 5 | summary: "tbc" 6 | --- 7 | 8 | # IIIF Registry 9 | This is the basis of the IIIF Registry of Activity streams. This project aims to give access to a large amount of IIIF resources and provide a way to keep up to date with changes. The Activity Streams format is defined in the [Change Discovery Specification](https://iiif.io/api/discovery/0.4/). 10 | 11 | We welcome additions to the registry and additions can be made using the following process: 12 | 13 | 1. Create branch for your addition 14 | 2. Create a directory for your institution. This should be a short name without spaces or punctuation 15 | 3. Create a registry JSON file. See details below 16 | 4. Create a pull request with your changes and submit to IIIF/registry 17 | 18 | ## Registry JSON format 19 | 20 | To register a link to your streams we use the following JSON structure: 21 | 22 | ``` 23 | { 24 | "id": "http://www.getty.edu/", 25 | "institution": { 26 | "id": "http://www.getty.edu/", 27 | "label": { 28 | "en": [ "Getty" ] 29 | } 30 | }, 31 | "streams": [ 32 | { 33 | "id": "http://www.getty.edu/museum.json", 34 | "label": { 35 | "en": [ "Museum collections" ] 36 | } 37 | }, 38 | { 39 | "id": "http://www.getty.edu/library.json", 40 | "label": { 41 | "en": [ "Library collections" ] 42 | } 43 | }, 44 | { 45 | "id": "http://www.getty.edu/research.json", 46 | "label": { 47 | "en": [ "Research Center" ] 48 | } 49 | } 50 | ] 51 | } 52 | ``` 53 | 54 | Where: 55 | * `id` is a URI for your institution. This could be an institution website, Wikidata URI or other resolvable link. 56 | * `institution` the name of the institution that could be shown to a user. This is an optional field but encouraged. 57 | * `streams` list of activity streams for this institution 58 | * `id` Activity Stream URL. Must be resolvable 59 | * `label` a description that can be shown to the user so they can tell which stream to monitor for updates. 60 | 61 | The JSON file should be named appropriately so people know what it represents and must have an extension of `.json`. 62 | 63 | ## Aggregators 64 | 65 | For Aggregators or institutions that collect content from other providers and aggregate their content. A slightly different structure can be used. Examples of Aggregators would be Europeana or OCLC with ContentDM. Both hold multiple institutions' data. In this case the Aggregator would have one registry JSON file per institutional client. The Provider can then add the following to the root of the JSON to show who provided the content: 66 | 67 | ``` 68 | "provider": { 69 | "id": "https://www.oclc.org/en/home.html", 70 | "label": { 71 | "en": [ "OCLC" ] 72 | } 73 | }, 74 | ``` 75 | 76 | You can see examples of this in the [OCLC directory](https://github.com/IIIF/registry/tree/deploy/OCLC) where [instx.json](https://github.com/IIIF/registry/blob/deploy/OCLC/instx.json) would be the set of changes from one ContentDM instance and [insty.json](https://github.com/IIIF/registry/blob/deploy/OCLC/insty.json) is a second institution. 77 | -------------------------------------------------------------------------------- /_includes/social.html: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/createAS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import json 4 | import math 5 | 6 | from os import listdir 7 | from os.path import isfile, join, isdir, exists 8 | import os 9 | import re 10 | 11 | ignore_list = ['[.]+.*', 'src', '_site'] 12 | 13 | def processDir(path): 14 | files = [] 15 | for fileName in listdir(path): 16 | ignore=False 17 | for ignoreStr in ignore_list: 18 | if re.match(ignoreStr, fileName): 19 | #print ('Ignoring {} with {}'.format(fileName, ignoreStr)) 20 | ignore=True 21 | break 22 | if not ignore: 23 | if isdir(fileName): 24 | files.extend(processDir(fileName)) 25 | elif fileName[-5:] == '.json': 26 | #print ('Adding {}'.format(fileName)) 27 | files.append('{}/{}'.format(path, fileName)) 28 | #else: 29 | # print ('Ignoring {} as its not json'.format(fileName)) 30 | 31 | return files 32 | 33 | 34 | 35 | files = processDir('.') 36 | print ('Found files {}'.format(files)) 37 | pageLimit = 10 38 | asStreams = [] 39 | for jsonFile in files: 40 | print ('Opening: {}'.format(jsonFile)) 41 | with open(jsonFile) as json_file: 42 | data = json.load(json_file) 43 | for stream in data['streams']: 44 | asStream = { 45 | 'id': stream['id'], 46 | 'label': stream['label'] 47 | } 48 | if 'provider' in data: 49 | asStream['provider'] = data['provider'] 50 | if 'institution' in data: 51 | asStream['source'] = data['institution'] 52 | asStreams.append(asStream) 53 | 54 | # should now sort asStream in some way to ensure the newest are first. 55 | 56 | # Now write out streams to pages 57 | startIndex = 0 58 | if len(asStreams) > pageLimit: 59 | endIndex = pageLimit 60 | else: 61 | endIndex = len(asStreams) 62 | 63 | pageCount = 0 64 | maxPages = math.ceil(len(asStreams) / pageLimit) 65 | pageJson = [] 66 | baseURL = "https://registry.iiif.io" 67 | firstRun = True 68 | while endIndex < len(asStreams) or firstRun==True: 69 | print ('endIndex {} asStreams length {}'.format(endIndex, len(asStreams))) 70 | currentPage = { 71 | "@context": "http://iiif.io/api/discovery/1/context.json", 72 | "id": "{}/page-{}.json".format(baseURL, pageCount), 73 | "type": "OrderedCollectionPage", 74 | "partOf": { 75 | "id": "{}/index.json".format(baseURL), 76 | "type": "OrderedCollection" 77 | } 78 | } 79 | if pageCount != 0: 80 | currentPage["prev"] = { 81 | "id": "{}/page-{}".format(baseURL, pageCount - 1), 82 | "type": "OrderedCollectionPage" 83 | } 84 | print ('Page count {}, maxPages {}'.format(pageCount, maxPages)) 85 | if pageCount < (maxPages - 1): 86 | currentPage["next"] = { 87 | "id": "{}/page-{}".format(baseURL, pageCount + 1), 88 | "type": "OrderedCollectionPage" 89 | } 90 | currentPage['orderedItems'] = [] 91 | for i in range(startIndex, endIndex): 92 | activity = { 93 | 'type': 'Update', 94 | 'object': { 95 | 'id': asStreams[i]['id'], 96 | 'type': 'OrderedCollection', 97 | 'nameMap': asStreams[i]['label'] 98 | } 99 | } 100 | if 'source' in asStreams[i] or 'provider' in asStreams[i]: 101 | activity['actor'] = [] 102 | if 'source' in asStreams[i]: 103 | actor = asStreams[i]['source'] 104 | if 'type' not in actor: 105 | actor['type'] = "Organization" 106 | 107 | activity['actor'].append(actor) 108 | 109 | if 'provider' in asStreams[i]: 110 | actor = asStreams[i]['provider'] 111 | if 'type' not in actor: 112 | actor['type'] = "Organization" 113 | 114 | activity['actor'].append(actor) 115 | 116 | 117 | currentPage['orderedItems'].append(activity) 118 | 119 | 120 | pageJson.append(currentPage) 121 | 122 | firstRun = False 123 | startIndex = endIndex 124 | pageCount += 1 125 | if len(asStreams) - endIndex > pageLimit: 126 | endIndex += pageLimit 127 | else: 128 | endIndex = len(asStreams) 129 | 130 | pageCount = 1 131 | outputDir = '_site' 132 | if not exists(outputDir): 133 | os.mkdir(outputDir) 134 | 135 | for page in pageJson: 136 | print ('Page: {}'.format(pageCount)) 137 | print (json.dumps(page, indent=4)) 138 | filename = page['id'].split('/')[-1] 139 | with open('{}/{}'.format(outputDir, filename), 'w') as outfile: 140 | json.dump(page, outfile, indent=4) 141 | pageCount += 1 142 | 143 | # Now create index.json 144 | 145 | index = { 146 | "@context": "http://iiif.io/api/discovery/1/context.json", 147 | "id": "https://registry.iiif.io/index.json", 148 | "type": "OrderedCollection", 149 | "summary": "The IIIF registry of Activity Streams", 150 | "first": { 151 | "id": "https://registry.iiif.io/page-0.json", 152 | "type": "OrderedCollectionPage" 153 | }, 154 | "last": { 155 | "id": "https://registry.iiif.io/page-{}.json".format(pageCount - 2), 156 | "type": "OrderedCollectionPage" 157 | } 158 | } 159 | 160 | with open('{}/index.json'.format(outputDir), 'w') as outfile: 161 | json.dump(index, outfile, indent=4) 162 | --------------------------------------------------------------------------------