jekyll-activity-pub 0.1.0rc3 → 0.1.0rc4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/jekyll/activity_pub/create.rb +29 -4
- data/lib/jekyll/activity_pub/delete.rb +7 -0
- data/lib/jekyll/activity_pub/helper.rb +8 -2
- data/lib/jekyll/activity_pub/notifier.rb +56 -22
- data/lib/jekyll/activity_pub/ordered_collection.rb +19 -9
- data/lib/jekyll/activity_pub/update.rb +1 -14
- data/lib/jekyll-activity-pub.rb +20 -4
- metadata +1 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: d66addf28845d3eab9189a74b092bd617d4b82cc96810ad7f22494c5b0a159de
         | 
| 4 | 
            +
              data.tar.gz: 025d2cd2f35f9295219106e87bf63008d782e247f9fbe7d0d61f44091ee8d6aa
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9bbf3bbae9a7499a3d5c981026d75d7f2ab4288d399355dbf98cff5dc49bf23302d578cc3f961867b2e00e80ea88b630203ecc26e8bfafa4690bb99981d3915a
         | 
| 7 | 
            +
              data.tar.gz: c23fb0af3b4ecd6df91fb4f42b121fd52dff0370d11816df272c5e994b53e2608f4cb09a13edf952f8c6cd190f1685bc27526475279766bafc0c22b855ed923b
         | 
| @@ -1,14 +1,19 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'jekyll/page'
         | 
| 3 4 | 
             
            require_relative 'helper'
         | 
| 4 5 |  | 
| 5 6 | 
             
            module Jekyll
         | 
| 6 7 | 
             
              module ActivityPub
         | 
| 7 8 | 
             
                # Represents a Create activity
         | 
| 8 | 
            -
                class Create
         | 
| 9 | 
            +
                class Create < Jekyll::Page
         | 
| 9 10 | 
             
                  include Helper
         | 
| 10 11 |  | 
| 11 | 
            -
                   | 
| 12 | 
            +
                  # @param :object [Jekyll::ActivityPub::Activity]
         | 
| 13 | 
            +
                  attr_reader :object
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  # @param :actor [Jekyll::ActivityPub::Actor]
         | 
| 16 | 
            +
                  attr_reader :actor
         | 
| 12 17 |  | 
| 13 18 | 
             
                  # Initialize with default data
         | 
| 14 19 | 
             
                  #
         | 
| @@ -17,10 +22,26 @@ module Jekyll | |
| 17 22 | 
             
                  # @param :object [Jekyll::ActivityPub::Activity]
         | 
| 18 23 | 
             
                  def initialize(site, actor, object)
         | 
| 19 24 | 
             
                    @context = StubContext.new(registers: { site: site })
         | 
| 25 | 
            +
                    @object = object
         | 
| 26 | 
            +
                    @actor = actor
         | 
| 20 27 |  | 
| 28 | 
            +
                    dest = Pathname.new(object.destination(site.dest)).relative_path_from(site.dest)
         | 
| 29 | 
            +
                    name = "#{type.downcase}.jsonld"
         | 
| 30 | 
            +
                    dir = File.join(
         | 
| 31 | 
            +
                      File.dirname(dest),
         | 
| 32 | 
            +
                      File.basename(dest, '.jsonld')
         | 
| 33 | 
            +
                    )
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    super(site, '', dir, name)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    trigger_hooks :post_init
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  def read_yaml(*)
         | 
| 21 41 | 
             
                    @data = {
         | 
| 22 42 | 
             
                      '@context' => 'https://www.w3.org/ns/activitystreams',
         | 
| 23 | 
            -
                      'type' =>  | 
| 43 | 
            +
                      'type' => type,
         | 
| 44 | 
            +
                      'id' => absolute_url(url),
         | 
| 24 45 | 
             
                      'actor' => absolute_url(actor.url),
         | 
| 25 46 | 
             
                      'published' => object.data['published'],
         | 
| 26 47 | 
             
                      'to' => object.data['to'],
         | 
| @@ -28,8 +49,12 @@ module Jekyll | |
| 28 49 | 
             
                      'object' => absolute_url(object.url),
         | 
| 29 50 | 
             
                      'inReplyTo' => object.data['in_reply_to']
         | 
| 30 51 | 
             
                    }
         | 
| 52 | 
            +
                  end
         | 
| 31 53 |  | 
| 32 | 
            -
             | 
| 54 | 
            +
                  private
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def type
         | 
| 57 | 
            +
                    @type ||= self.class.name.split('::').last
         | 
| 33 58 | 
             
                  end
         | 
| 34 59 | 
             
                end
         | 
| 35 60 | 
             
              end
         | 
| @@ -1,9 +1,15 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require_relative 'helper'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module Jekyll
         | 
| 4 6 | 
             
              module ActivityPub
         | 
| 5 7 | 
             
                # Represents a Delete activity
         | 
| 6 8 | 
             
                class Delete
         | 
| 9 | 
            +
                  include Helper
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  attr_reader :data
         | 
| 12 | 
            +
             | 
| 7 13 | 
             
                  # Initialize with default data
         | 
| 8 14 | 
             
                  #
         | 
| 9 15 | 
             
                  # @param :site [Jekyll::Site]
         | 
| @@ -14,6 +20,7 @@ module Jekyll | |
| 14 20 |  | 
| 15 21 | 
             
                    @data = {
         | 
| 16 22 | 
             
                      '@context' => 'https://www.w3.org/ns/activitystreams',
         | 
| 23 | 
            +
                      'id' => absolute_url(object.url).sub('.jsonld', '/delete.jsonld'),
         | 
| 17 24 | 
             
                      'type' => 'Delete',
         | 
| 18 25 | 
             
                      'actor' => absolute_url(actor.url),
         | 
| 19 26 | 
             
                      'object' => absolute_url(object.url)
         | 
| @@ -15,12 +15,12 @@ module Jekyll | |
| 15 15 | 
             
                  #
         | 
| 16 16 | 
             
                  # @return [String]
         | 
| 17 17 | 
             
                  def content
         | 
| 18 | 
            -
                     | 
| 18 | 
            +
                    pruned_data.to_json
         | 
| 19 19 | 
             
                  end
         | 
| 20 20 |  | 
| 21 21 | 
             
                  # JSONify this object
         | 
| 22 22 | 
             
                  def to_json(*args)
         | 
| 23 | 
            -
                     | 
| 23 | 
            +
                    pruned_data.to_json(*args)
         | 
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| 26 26 | 
             
                  # There's no excerpt to be generated
         | 
| @@ -153,6 +153,12 @@ module Jekyll | |
| 153 153 |  | 
| 154 154 | 
             
                    absolute_url url
         | 
| 155 155 | 
             
                  end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                  def pruned_data
         | 
| 158 | 
            +
                    data.reject do |_, v|
         | 
| 159 | 
            +
                      v.nil? || (v.respond_to?(:empty?) && v.empty?)
         | 
| 160 | 
            +
                    end
         | 
| 161 | 
            +
                  end
         | 
| 156 162 | 
             
                end
         | 
| 157 163 | 
             
              end
         | 
| 158 164 | 
             
            end
         | 
| @@ -108,10 +108,12 @@ module Jekyll | |
| 108 108 | 
             
                      end
         | 
| 109 109 |  | 
| 110 110 | 
             
                      # Remove notifications already performed and notify
         | 
| 111 | 
            -
                      data['notifications'].reject do |object_url,  | 
| 112 | 
            -
                        done? object_url | 
| 111 | 
            +
                      data['notifications'].reject do |object_url, _|
         | 
| 112 | 
            +
                        done? object_url
         | 
| 113 113 | 
             
                      end.each do |object_url, status|
         | 
| 114 | 
            -
                         | 
| 114 | 
            +
                        path = site.in_dest_dir(object_url)
         | 
| 115 | 
            +
                        data = JSON.parse(File.read(path)) if File.exist? path
         | 
| 116 | 
            +
                        object = PseudoObject.new(url: object_url, data: data || {})
         | 
| 115 117 | 
             
                        process_object(outbox_endpoint, actor_object, object, status)
         | 
| 116 118 | 
             
                      end
         | 
| 117 119 |  | 
| @@ -134,34 +136,72 @@ module Jekyll | |
| 134 136 | 
             
                    # Removes an activity if it was previously created
         | 
| 135 137 | 
             
                    #
         | 
| 136 138 | 
             
                    # @param :path [String]
         | 
| 137 | 
            -
                    # @return [ | 
| 139 | 
            +
                    # @return [nil]
         | 
| 138 140 | 
             
                    def delete(path)
         | 
| 139 | 
            -
                      action(path, 'delete') if exist? path
         | 
| 141 | 
            +
                      action(path, 'delete') if exist?(path) && !deleted?(path)
         | 
| 140 142 | 
             
                    end
         | 
| 141 143 |  | 
| 142 144 | 
             
                    # Updates an activity if it was previously created, otherwise
         | 
| 143 145 | 
             
                    # create it
         | 
| 144 146 | 
             
                    #
         | 
| 145 147 | 
             
                    # @param :path [String]
         | 
| 146 | 
            -
                    # @return [ | 
| 148 | 
            +
                    # @return [nil]
         | 
| 147 149 | 
             
                    def update(path)
         | 
| 148 | 
            -
                       | 
| 150 | 
            +
                      if created?(path)
         | 
| 151 | 
            +
                        action(path, 'update')
         | 
| 152 | 
            +
                      else
         | 
| 153 | 
            +
                        create(path)
         | 
| 154 | 
            +
                      end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                      nil
         | 
| 149 157 | 
             
                    end
         | 
| 150 158 |  | 
| 151 | 
            -
                    # Creates an activity
         | 
| 159 | 
            +
                    # Creates an activity unless it has been already created
         | 
| 152 160 | 
             
                    #
         | 
| 153 161 | 
             
                    # @param :path [String]
         | 
| 154 | 
            -
                    # @return [ | 
| 162 | 
            +
                    # @return [nil]
         | 
| 155 163 | 
             
                    def create(path)
         | 
| 156 | 
            -
                      action(path, 'create')
         | 
| 164 | 
            +
                      action(path, 'create') unless created?(path)
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                      nil
         | 
| 157 167 | 
             
                    end
         | 
| 158 168 |  | 
| 159 | 
            -
                    #  | 
| 169 | 
            +
                    # Gets status
         | 
| 170 | 
            +
                    #
         | 
| 171 | 
            +
                    # @param :path [String]
         | 
| 172 | 
            +
                    # @return [Hash]
         | 
| 173 | 
            +
                    def status(path)
         | 
| 174 | 
            +
                      data['notifications'][path_relative_to_dest(path)] || {}
         | 
| 175 | 
            +
                    end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                    # Detects if an action was already done
         | 
| 160 178 | 
             
                    #
         | 
| 161 179 | 
             
                    # @param :path [String]
         | 
| 162 | 
            -
                     | 
| 180 | 
            +
                    def done?(path)
         | 
| 181 | 
            +
                      (status(path)['action'] == 'done').tap do |done|
         | 
| 182 | 
            +
                        Jekyll.logger.debug('ActivityPub:', "Skipping notification for #{path}") if done
         | 
| 183 | 
            +
                      end
         | 
| 184 | 
            +
                    end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                    # Already created
         | 
| 187 | 
            +
                    #
         | 
| 188 | 
            +
                    # @param :path [String]
         | 
| 189 | 
            +
                    def created?(path)
         | 
| 190 | 
            +
                      !(status(path)['created_at'].nil?)
         | 
| 191 | 
            +
                    end
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                    # @param :path [String]
         | 
| 194 | 
            +
                    def updated?(path)
         | 
| 195 | 
            +
                      !(status(path)['updated_at'].nil?)
         | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
                    # @param :path [String]
         | 
| 199 | 
            +
                    def deleted?(path)
         | 
| 200 | 
            +
                      !(status(path)['deleted_at'].nil?)
         | 
| 201 | 
            +
                    end
         | 
| 202 | 
            +
             | 
| 163 203 | 
             
                    def exist?(path)
         | 
| 164 | 
            -
                       | 
| 204 | 
            +
                      !(status(path)['action'].nil?)
         | 
| 165 205 | 
             
                    end
         | 
| 166 206 |  | 
| 167 207 | 
             
                    # Stores data back to a file and optionally commits it
         | 
| @@ -176,7 +216,7 @@ module Jekyll | |
| 176 216 | 
             
                      File.open(path, 'w') do |f|
         | 
| 177 217 | 
             
                        f.flock(File::LOCK_EX)
         | 
| 178 218 | 
             
                        f.rewind
         | 
| 179 | 
            -
                        f.write(YAML.dump(data))
         | 
| 219 | 
            +
                        f.write(YAML.dump(data.reject { |_, v| v.empty? }))
         | 
| 180 220 | 
             
                        f.flush
         | 
| 181 221 | 
             
                        f.truncate(f.pos)
         | 
| 182 222 | 
             
                      end
         | 
| @@ -253,14 +293,8 @@ module Jekyll | |
| 253 293 | 
             
                    # @param :path [String]
         | 
| 254 294 | 
             
                    # @return [String]
         | 
| 255 295 | 
             
                    def path_relative_to_dest(path)
         | 
| 256 | 
            -
                       | 
| 257 | 
            -
             | 
| 258 | 
            -
             | 
| 259 | 
            -
                    # Detects if an action was already done
         | 
| 260 | 
            -
                    def done?(url, status)
         | 
| 261 | 
            -
                      (status['action'] == 'done').tap do |done|
         | 
| 262 | 
            -
                        Jekyll.logger.debug('ActivityPub:', "Skipping notification for #{url}") if done
         | 
| 263 | 
            -
                      end
         | 
| 296 | 
            +
                      @@path_relative_to_dest ||= {}
         | 
| 297 | 
            +
                      @@path_relative_to_dest[path] ||= Pathname.new(site.in_dest_dir(path)).relative_path_from(site.dest).to_s
         | 
| 264 298 | 
             
                    end
         | 
| 265 299 |  | 
| 266 300 | 
             
                    # Turns an object into an activity and notifies outbox
         | 
| @@ -43,19 +43,23 @@ module Jekyll | |
| 43 43 | 
             
                    @content ||=
         | 
| 44 44 | 
             
                      begin
         | 
| 45 45 | 
             
                        order_items!
         | 
| 46 | 
            +
                        items_to_links!
         | 
| 46 47 |  | 
| 47 | 
            -
                         | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
                         | 
| 48 | 
            +
                        if !always_paginate? || !paginable?
         | 
| 49 | 
            +
                          original_content
         | 
| 50 | 
            +
                        elsif data['orderedItems'].empty?
         | 
| 51 | 
            +
                          original_content
         | 
| 52 | 
            +
                        else
         | 
| 53 | 
            +
                          paged_data = data.dup
         | 
| 54 | 
            +
                          pages = paginate(paged_data.delete('orderedItems'))
         | 
| 52 55 |  | 
| 53 | 
            -
             | 
| 56 | 
            +
                          assign_links! pages
         | 
| 54 57 |  | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 58 | 
            +
                          paged_data['first'] = absolute_url(pages.first.url)
         | 
| 59 | 
            +
                          paged_data['last'] = absolute_url(pages.last.url)
         | 
| 57 60 |  | 
| 58 | 
            -
             | 
| 61 | 
            +
                          paged_data.to_json
         | 
| 62 | 
            +
                        end
         | 
| 59 63 | 
             
                      end
         | 
| 60 64 | 
             
                  end
         | 
| 61 65 |  | 
| @@ -132,6 +136,12 @@ module Jekyll | |
| 132 136 | 
             
                      b.data['published'] <=> a.data['published']
         | 
| 133 137 | 
             
                    end
         | 
| 134 138 | 
             
                  end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                  def items_to_links!
         | 
| 141 | 
            +
                    data['orderedItems'] = data['orderedItems'].map do |item|
         | 
| 142 | 
            +
                      item.data['id']
         | 
| 143 | 
            +
                    end
         | 
| 144 | 
            +
                  end
         | 
| 135 145 | 
             
                end
         | 
| 136 146 | 
             
              end
         | 
| 137 147 | 
             
            end
         | 
| @@ -5,19 +5,6 @@ require_relative 'create' | |
| 5 5 | 
             
            module Jekyll
         | 
| 6 6 | 
             
              module ActivityPub
         | 
| 7 7 | 
             
                # Represents an Update activity
         | 
| 8 | 
            -
                class Update < Create
         | 
| 9 | 
            -
                  # Initialize with default data
         | 
| 10 | 
            -
                  #
         | 
| 11 | 
            -
                  # @param :site [Jekyll::Site]
         | 
| 12 | 
            -
                  # @param :actor [Jekyll::ActivityPub::Actor]
         | 
| 13 | 
            -
                  # @param :object [Jekyll::ActivityPub::Activity]
         | 
| 14 | 
            -
                  def initialize(site, actor, object)
         | 
| 15 | 
            -
                    super
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                    data['type'] = 'Update'
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                    trigger_hooks :post_init
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 8 | 
            +
                class Update < Create; end
         | 
| 22 9 | 
             
              end
         | 
| 23 10 | 
             
            end
         | 
    
        data/lib/jekyll-activity-pub.rb
    CHANGED
    
    | @@ -14,9 +14,11 @@ Jekyll::Hooks.register :site, :post_read, priority: :low do |site| | |
| 14 14 | 
             
              begin
         | 
| 15 15 | 
             
                private_key = File.read(site.config['activity_pub_private_key'])
         | 
| 16 16 | 
             
              rescue StandardError
         | 
| 17 | 
            -
                Jekyll.logger.warn 'ActivityPub:', 'There\'s an issue with your private key'
         | 
| 17 | 
            +
                Jekyll.logger.warn 'ActivityPub:', 'There\'s an issue with your private key, skipping generation'
         | 
| 18 18 |  | 
| 19 | 
            -
                 | 
| 19 | 
            +
                site.config['activity_pub_disable'] = true
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                next
         | 
| 20 22 | 
             
              end
         | 
| 21 23 |  | 
| 22 24 | 
             
              # We only need the public key at this point
         | 
| @@ -42,15 +44,24 @@ end | |
| 42 44 | 
             
            # Generate an activity for each document after the content has been
         | 
| 43 45 | 
             
            # rendered as HTML.
         | 
| 44 46 | 
             
            Jekyll::Hooks.register(:documents, :post_convert, priority: :high) do |doc|
         | 
| 47 | 
            +
              next if site.config['activity_pub_disable']
         | 
| 45 48 | 
             
              next unless doc.write?
         | 
| 46 49 | 
             
              next if doc.data['sitemap'] == false
         | 
| 47 50 | 
             
              next if doc.data['activity'] == false
         | 
| 48 51 |  | 
| 49 52 | 
             
              site = doc.site
         | 
| 50 | 
            -
              dir = File.dirname(doc.url)
         | 
| 51 | 
            -
              name = "#{File.basename(doc.url, '.html')}.jsonld"
         | 
| 52 53 | 
             
              actor = site.config['actor']
         | 
| 53 54 | 
             
              outbox = site.config['outbox']
         | 
| 55 | 
            +
              dest = doc.destination(site.dest)
         | 
| 56 | 
            +
              dir = Pathname.new(File.dirname(dest)).relative_path_from(site.dest).to_s
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              # /slug/ => /slug.jsonld
         | 
| 59 | 
            +
              if (n = File.basename(dest, '.html')) == 'index'
         | 
| 60 | 
            +
                name = "#{File.basename(dir)}.jsonld"
         | 
| 61 | 
            +
                dir = File.dirname(dir)
         | 
| 62 | 
            +
              else
         | 
| 63 | 
            +
                name = "#{n}.jsonld"
         | 
| 64 | 
            +
              end
         | 
| 54 65 |  | 
| 55 66 | 
             
              Jekyll::ActivityPub::Activity.new(site, actor, doc, nil, dir, name).tap do |activity|
         | 
| 56 67 | 
             
                doc.data['activity'] = activity
         | 
| @@ -70,6 +81,7 @@ Jekyll::Hooks.register(:documents, :post_convert, priority: :high) do |doc| | |
| 70 81 |  | 
| 71 82 | 
             
                  outbox.data['totalItems'] += 1
         | 
| 72 83 | 
             
                  outbox.data['orderedItems'] << action
         | 
| 84 | 
            +
                  site.pages << action
         | 
| 73 85 | 
             
                end
         | 
| 74 86 |  | 
| 75 87 | 
             
                site.pages << activity
         | 
| @@ -78,6 +90,8 @@ end | |
| 78 90 |  | 
| 79 91 | 
             
            # This hook is shit because we don't have access to the site!
         | 
| 80 92 | 
             
            Jekyll::Hooks.register(:clean, :on_obsolete, priority: :low) do |list|
         | 
| 93 | 
            +
              next if site.config['activity_pub_disable']
         | 
| 94 | 
            +
             | 
| 81 95 | 
             
              list.each do |path|
         | 
| 82 96 | 
             
                Jekyll::ActivityPub::Notifier.delete path
         | 
| 83 97 | 
             
              end
         | 
| @@ -86,5 +100,7 @@ end | |
| 86 100 | 
             
            # Store data generated between builds and commits if
         | 
| 87 101 | 
             
            # jekyll-write-and-commit-changes is enabled.
         | 
| 88 102 | 
             
            Jekyll::Hooks.register(:site, :post_write, priority: :low) do |_|
         | 
| 103 | 
            +
              next if site.config['activity_pub_disable']
         | 
| 104 | 
            +
             | 
| 89 105 | 
             
              Jekyll::ActivityPub::Notifier.save
         | 
| 90 106 | 
             
            end
         |