post '/create' do # TODO protected! request.body.rewind # in case someone already read it to = [] inReplyTo = '' content = [] tag = [] attachment = [] url_regexp = %r{\Ahttps?://\S+\Z} mention_regexp = /\A@\w+@\S+\Z/ hashtag_regexp = /\A#\w+\Z/ lines = request.body.read.each_line.to_a lines.each.with_index do |line, i| line.chomp! if i == 0 to = line.split(/\s+/).collect do |word| case word when 'public' ['https://www.w3.org/ns/activitystreams#Public', FOLLOWERS_URL] when mention_regexp actor word when url_regexp word end end.flatten elsif i == 1 and line.match url_regexp inReplyTo = line elsif line == '' content << '
' elsif line.match(/\A==\Z/) attachment = lines[i + 1..-1].collect do |url| url.chomp! { 'type' => 'Document', 'mediaType' => media_type(url), 'url' => url } end break else # create links # single quotes in html invalidate digest, reason unknown line.split(/\s+/).grep(url_regexp).each { |u| line.gsub!(u, "#{u}") } line.split(/\s+/).grep(URI::MailTo::EMAIL_REGEXP).each { |m| line.gsub!(m, "#{m}") } tags = line.split(/\s+/).grep(hashtag_regexp) tags.each do |name| tag_url = File.join(TAGS[:url], name.sub('#', '')) tag << { 'type' => 'Hashtag', 'href' => tag_url, 'name' => name } # single quotes in html invalidate digest, reason unknown line.gsub!(name, "#{name}") end mentions = line.split(/\s+/).grep(mention_regexp) mentions.each do |mention| actor = actor(mention) tag << { 'type' => 'Mention', 'href' => actor, 'name' => mention } # single quotes in html invalidate digest, reason unknown line.gsub!(mention, "#{mention}") end content << line end end object = { 'to' => to, 'type' => 'Note', 'attributedTo' => ACTOR, 'content' => "#{content.join("\n")}" } object['inReplyTo'] = inReplyTo unless inReplyTo.empty? object['attachment'] = attachment unless attachment.empty? object['tag'] = tag unless tag.empty? activity = outbox 'Create', object, to if activity['object']['tag'] activity['object']['tag'].each do |tag| next unless tag['type'] == 'Hashtag' tag_path = File.join(TAGS[:dir], tag['name'].sub('#', '')) + '.json' tag_collection = if File.exist? tag_path JSON.parse(File.read(tag_path)) else { '@context' => 'https://www.w3.org/ns/activitystreams', 'id' => tag['href'], 'type' => 'OrderedCollection', 'totalItems' => 0, 'orderedItems' => [] } end tag_collection['orderedItems'] << activity['object']['id'] tag_collection['totalItems'] = tag_collection['orderedItems'].size File.open(tag_path, 'w+') do |f| f.puts tag_collection.to_json end end end 200 end