Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
253ab26520 | |||
b640f35621 | |||
e14b76c7cb | |||
7e53efae31 | |||
f4ad2fb35a | |||
2b116131d7 | |||
e2b846f630 | |||
5d72b92271 | |||
71ae4dd3d2 | |||
c349200761 | |||
d4892ace62 | |||
66a2107527 | |||
111f2a1d48 | |||
f97fc9744f | |||
47d1cb4e21 | |||
071f64d317 | |||
580b91c387 | |||
48aeacd5f9 | |||
7837afbb5f | |||
94eb142ab8 | |||
9a7485d034 | |||
15476d505d | |||
323474c97e | |||
af7ae348d7 | |||
e239fc3050 | |||
d022975444 | |||
086d487145 | |||
9cb690c706 | |||
786397e15d | |||
55ca59a66c | |||
48d66a2055 | |||
2c374cd97c | |||
8767a98fbb | |||
a9db42a956 |
@ -1,5 +1,23 @@
|
||||
# Service dependencies
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
DB_HOST=db
|
||||
DB_USER=postgres
|
||||
DB_NAME=postgres
|
||||
DB_PASS=
|
||||
DB_PORT=5432
|
||||
|
||||
# Federation
|
||||
LOCAL_DOMAIN=example.com
|
||||
LOCAL_HTTPS=true
|
||||
|
||||
# Application secrets
|
||||
PAPERCLIP_SECRET=
|
||||
SECRET_KEY_BASE=
|
||||
|
||||
# E-mail configuration
|
||||
SMTP_SERVER=smtp.mailgun.org
|
||||
SMTP_PORT=587
|
||||
SMTP_LOGIN=
|
||||
SMTP_PASSWORD=
|
||||
SMTP_FROM_ADDRESS=notifications@example.com
|
||||
|
23
.travis.yml
Normal file
23
.travis.yml
Normal file
@ -0,0 +1,23 @@
|
||||
language: ruby
|
||||
cache: bundler
|
||||
|
||||
env:
|
||||
global:
|
||||
- LOCAL_DOMAIN=example.com
|
||||
- LOCAL_HTTPS=false
|
||||
|
||||
addons:
|
||||
postgresql: 9.4
|
||||
|
||||
rvm:
|
||||
- 2.2.4
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
|
||||
bundler_args: --without development --retry=3 --jobs=3
|
||||
|
||||
before_script:
|
||||
- bundle exec rake db:create db:migrate
|
||||
|
||||
script: bundle exec rspec
|
@ -2,7 +2,7 @@ FROM ruby:2.2.4
|
||||
|
||||
ENV RAILS_ENV=production
|
||||
|
||||
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
|
||||
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev && rm -rf /var/lib/apt/lists/*
|
||||
RUN mkdir /mastodon
|
||||
|
||||
WORKDIR /mastodon
|
||||
@ -13,3 +13,5 @@ ADD Gemfile.lock /mastodon/Gemfile.lock
|
||||
RUN bundle install --deployment --without test --without development
|
||||
|
||||
ADD . /mastodon
|
||||
|
||||
VOLUME ["/mastodon/public/system", "/mastodon/public/assets"]
|
||||
|
5
Gemfile
5
Gemfile
@ -1,7 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '4.2.5.1'
|
||||
gem 'sqlite3'
|
||||
gem 'sass-rails', '~> 5.0'
|
||||
gem 'uglifier', '>= 1.3.0'
|
||||
gem 'coffee-rails', '~> 4.1.0'
|
||||
@ -18,7 +17,6 @@ gem 'font-awesome-rails'
|
||||
|
||||
gem 'paranoia', '~> 2.0'
|
||||
gem 'paperclip', '~> 4.3'
|
||||
gem 'backport_new_renderer'
|
||||
|
||||
gem 'http'
|
||||
gem 'addressable'
|
||||
@ -36,6 +34,8 @@ gem 'fast_blank'
|
||||
gem 'htmlentities'
|
||||
gem 'onebox'
|
||||
gem 'simple_form'
|
||||
gem 'will_paginate', '~> 3.0.6'
|
||||
gem 'rack-attack'
|
||||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails'
|
||||
@ -56,6 +56,7 @@ group :development do
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'rack-mini-profiler'
|
||||
gem 'letter_opener'
|
||||
end
|
||||
|
||||
group :production do
|
||||
|
15
Gemfile.lock
15
Gemfile.lock
@ -39,8 +39,6 @@ GEM
|
||||
addressable (2.4.0)
|
||||
arel (6.0.3)
|
||||
ast (2.2.0)
|
||||
backport_new_renderer (1.0.0)
|
||||
rails
|
||||
bcrypt (3.1.11)
|
||||
better_errors (2.1.1)
|
||||
coderay (>= 1.0.0)
|
||||
@ -131,6 +129,10 @@ GEM
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.4.1)
|
||||
launchy (~> 2.2)
|
||||
libv8 (3.16.14.13)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
@ -182,6 +184,8 @@ GEM
|
||||
rabl (0.12.0)
|
||||
activesupport (>= 2.3.14)
|
||||
rack (1.6.4)
|
||||
rack-attack (4.4.1)
|
||||
rack
|
||||
rack-mini-profiler (0.9.9.2)
|
||||
rack (>= 1.2.0)
|
||||
rack-test (0.6.3)
|
||||
@ -283,7 +287,6 @@ GEM
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.11)
|
||||
therubyracer (0.12.2)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
@ -310,13 +313,13 @@ GEM
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
will_paginate (3.0.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
addressable
|
||||
backport_new_renderer
|
||||
better_errors
|
||||
binding_of_caller
|
||||
coffee-rails (~> 4.1.0)
|
||||
@ -334,6 +337,7 @@ DEPENDENCIES
|
||||
http
|
||||
jbuilder (~> 2.0)
|
||||
jquery-rails
|
||||
letter_opener
|
||||
nokogiri
|
||||
oj
|
||||
onebox
|
||||
@ -345,6 +349,7 @@ DEPENDENCIES
|
||||
puma
|
||||
quiet_assets
|
||||
rabl
|
||||
rack-attack
|
||||
rack-mini-profiler
|
||||
rails (= 4.2.5.1)
|
||||
rails_12factor
|
||||
@ -356,11 +361,11 @@ DEPENDENCIES
|
||||
sdoc (~> 0.4.0)
|
||||
simple_form
|
||||
simplecov
|
||||
sqlite3
|
||||
therubyracer
|
||||
uglifier (>= 1.3.0)
|
||||
web-console (~> 2.0)
|
||||
webmock
|
||||
will_paginate (~> 3.0.6)
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
|
36
README.md
36
README.md
@ -1,6 +1,8 @@
|
||||
Mastodon
|
||||
========
|
||||
|
||||
[](https://travis-ci.org/Gargron/mastodon)
|
||||
|
||||
Mastodon is a federated microblogging engine. An alternative implementation of the GNU Social project. Based on ActivityStreams, Webfinger, PubsubHubbub and Salmon.
|
||||
|
||||
**Current status of the project is early development. Documentation &co will be added later**
|
||||
@ -18,18 +20,14 @@ Mastodon is a federated microblogging engine. An alternative implementation of t
|
||||
- Upload header image for profile page
|
||||
- Deleting statuses, deletion propagation
|
||||
|
||||
Missing:
|
||||
|
||||
- Media attachments (photos, videos)
|
||||
- UI to post, reblog, favourite, follow and unfollow
|
||||
- Streaming API
|
||||
|
||||
## Configuration
|
||||
|
||||
- `LOCAL_DOMAIN` should be the domain/hostname of your instance. This is **absolutely required** as it is used for generating unique IDs for everything federation-related
|
||||
- `LOCAL_HTTPS` set it to `true` if HTTPS works on your website. This is used to generate canonical URLs, which is also important when generating and parsing federation-related IDs
|
||||
- `HUB_URL` should be the URL of the PubsubHubbub service that your instance is going to use. By default it is the open service of Superfeedr
|
||||
|
||||
Consult the example configuration file, `.env.production.sample` for the full list.
|
||||
|
||||
## Requirements
|
||||
|
||||
- PostgreSQL
|
||||
@ -37,14 +35,36 @@ Missing:
|
||||
|
||||
## Running with Docker and Docker-Compose
|
||||
|
||||
The project now includes a Dockerfile and a docker-compose.yml. You need to turn .env.production sample into .env.production with all the variables set before you can:
|
||||
The project now includes a `Dockerfile` and a `docker-compose.yml`. You need to turn `.env.production.sample` into `.env.production` with all the variables set before you can:
|
||||
|
||||
docker-compose build
|
||||
|
||||
And finally
|
||||
|
||||
docker-compose up
|
||||
docker-compose up -d
|
||||
|
||||
As usual, the first thing you would need to do would be to run migrations:
|
||||
|
||||
docker-compose run web rake db:migrate
|
||||
|
||||
And since the instance running in the container will be running in production mode, you need to pre-compile assets:
|
||||
|
||||
docker-compose run web rake assets:precompile
|
||||
|
||||
The container has two volumes, for the assets and for user uploads. The default docker-compose.yml maps them to the repository's `public/assets` and `public/system` directories, you may wish to put them somewhere else. Likewise, the PostgreSQL and Redis images have data containers that you may wish to map somewhere where you know how to find them and back them up.
|
||||
|
||||
### Updating
|
||||
|
||||
This approach makes updating to the latest version a real breeze.
|
||||
|
||||
git pull
|
||||
|
||||
To pull down the updates, re-run
|
||||
|
||||
docker-compose build
|
||||
|
||||
And finally,
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
Which will re-create the updated containers, leaving databases and data as is. Depending on what files have been updated, you might need to re-run migrations and asset compilation.
|
||||
|
@ -2,7 +2,7 @@
|
||||
background: #282c37;
|
||||
background-size: cover;
|
||||
padding: 60px 0;
|
||||
padding-bottom: 10px;
|
||||
padding-bottom: 0;
|
||||
border-radius: 4px 4px 0 0;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
overflow: hidden;
|
||||
@ -64,8 +64,45 @@
|
||||
width: 80px;
|
||||
color: #9baec8;
|
||||
padding: 0 10px;
|
||||
margin-bottom: 10px;
|
||||
border-right: 1px solid #9baec8;
|
||||
cursor: default;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:after {
|
||||
display: block;
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
border-bottom: 4px solid #9baec8;
|
||||
opacity: 0.5;
|
||||
transition: all 0.8s ease;
|
||||
}
|
||||
|
||||
&.active {
|
||||
&:after {
|
||||
border-bottom: 4px solid #2b90d9;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:after {
|
||||
opacity: 1;
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.counter-label {
|
||||
font-size: 12px;
|
||||
@ -89,3 +126,146 @@
|
||||
color: #d9e1e8;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
|
||||
a, .current, .next_page, .previous_page, .gap {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
display: inline-block;
|
||||
padding: 6px 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.current {
|
||||
background: #fff;
|
||||
border-radius: 100px;
|
||||
color: #282c37;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.gap {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.previous_page, .next_page {
|
||||
text-transform: uppercase;
|
||||
color: #d9e1e8;
|
||||
}
|
||||
|
||||
.previous_page {
|
||||
float: left;
|
||||
padding-left: 0;
|
||||
|
||||
.fa {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.next_page {
|
||||
float: right;
|
||||
padding-right: 0;
|
||||
|
||||
.fa {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
cursor: default;
|
||||
color: lighten(#282c37, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.accounts-grid {
|
||||
clear: both;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
background: #fff;
|
||||
border-radius: 0 0 4px 4px;
|
||||
padding: 20px 10px;
|
||||
padding-bottom: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
.account-grid-card {
|
||||
box-sizing: border-box;
|
||||
width: 335px;
|
||||
float: left;
|
||||
border: 1px solid #d9e1e8;
|
||||
border-radius: 4px;
|
||||
color: #282c37;
|
||||
height: 160px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:nth-child(odd) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.account-grid-card__header {
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #d9e1e8;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 333-20-60-15px;
|
||||
float: left;
|
||||
padding-top: 10px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
color: #282c37;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
.display_name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.display_name {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.username {
|
||||
color: #2b90d9;
|
||||
}
|
||||
|
||||
.note {
|
||||
padding: 10px;
|
||||
padding-top: 15px;
|
||||
color: #9baec8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nothing-here {
|
||||
color: #9baec8;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
padding: 15px 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the Api::Accounts controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the API::Follows controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the API::Salmon controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the API::Statuses controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the API::Subscriptions controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -1,12 +1,3 @@
|
||||
$primary-color: #ff7473;
|
||||
$secondary-color: #ffc952;
|
||||
$tertiary-color: #47b8e0;
|
||||
$quaternary-color: #34314c;
|
||||
$background-color: #fff;
|
||||
$darker-background-color: #e3dede;
|
||||
$text-color: #333030;
|
||||
$lighter-text-color: #8b8687;
|
||||
|
||||
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic);
|
||||
@import url(https://fonts.googleapis.com/css?family=Roboto+Mono:400,500);
|
||||
@import "font-awesome";
|
||||
|
@ -214,6 +214,12 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.error_notification {
|
||||
color: #df405a;
|
||||
font-weight: 500;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.input {
|
||||
margin-bottom: 15px;
|
||||
|
||||
@ -238,7 +244,7 @@
|
||||
font-size: 14px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
|
||||
&:focus {
|
||||
&:focus, &:active {
|
||||
border-bottom: 2px solid #2b90d9;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
@ -253,6 +259,24 @@
|
||||
margin-top: 5px;
|
||||
color: lighten(#282c37, 25%);
|
||||
}
|
||||
|
||||
&.field_with_errors {
|
||||
input[type=text], input[type=email], input[type=password], textarea {
|
||||
border-bottom: 2px solid #df405a;
|
||||
padding-bottom: 5px;
|
||||
|
||||
&:focus, &:active {
|
||||
border-bottom: 2px solid #2b90d9;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
color: #df405a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
// Place all the styles related to the oauth::applications controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
@ -8,11 +8,19 @@ class AccountsController < ApplicationController
|
||||
@statuses = @account.statuses.order('id desc').with_includes.with_counters
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.html { @statuses = @statuses.paginate(page: params[:page], per_page: 10)}
|
||||
format.atom
|
||||
end
|
||||
end
|
||||
|
||||
def followers
|
||||
@followers = @account.followers.order('follows.created_at desc').paginate(page: params[:page], per_page: 6)
|
||||
end
|
||||
|
||||
def following
|
||||
@following = @account.following.order('follows.created_at desc').paginate(page: params[:page], per_page: 6)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
|
@ -15,16 +15,21 @@ class Api::AccountsController < ApiController
|
||||
end
|
||||
|
||||
def statuses
|
||||
@statuses = @account.statuses.with_includes.with_counts.order('created_at desc')
|
||||
@statuses = @account.statuses.with_includes.with_counters.order('created_at desc')
|
||||
end
|
||||
|
||||
def follow
|
||||
@follow = current_user.account.follow!(@account)
|
||||
if @account.local?
|
||||
@follow = current_user.account.follow!(@account)
|
||||
else
|
||||
@follow = FollowService.new.(current_user.account, @account.acct)
|
||||
end
|
||||
|
||||
render action: :show
|
||||
end
|
||||
|
||||
def unfollow
|
||||
@unfollow = current_user.account.unfollow!(@account)
|
||||
@unfollow = UnfollowService.new.(current_user.account, @account)
|
||||
render action: :show
|
||||
end
|
||||
|
||||
|
@ -12,7 +12,7 @@ class Api::SubscriptionsController < ApiController
|
||||
def update
|
||||
body = request.body.read
|
||||
|
||||
if @account.subscription(api_subscription_url(@account.id)).verify(body, env['HTTP_X_HUB_SIGNATURE'])
|
||||
if @account.subscription(api_subscription_url(@account.id)).verify(body, request.headers['HTTP_X_HUB_SIGNATURE'])
|
||||
ProcessFeedService.new.(body, @account)
|
||||
render nothing: true, status: 201
|
||||
else
|
||||
|
@ -1,5 +1,6 @@
|
||||
class ApiController < ApplicationController
|
||||
protect_from_forgery with: :null_session
|
||||
skip_before_filter :verify_authenticity_token
|
||||
|
||||
protected
|
||||
|
||||
|
@ -6,7 +6,7 @@ class XrdController < ApplicationController
|
||||
end
|
||||
|
||||
def webfinger
|
||||
@account = Account.find_by!(username: username_from_resource, domain: nil)
|
||||
@account = Account.find_local!(username_from_resource)
|
||||
@canonical_account_uri = "acct:#{@account.username}@#{Rails.configuration.x.local_domain}"
|
||||
@magic_key = pem_to_magic_key(@account.keypair.public_key)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@ -21,10 +21,10 @@ class XrdController < ApplicationController
|
||||
end
|
||||
|
||||
def username_from_resource
|
||||
if params[:resource].start_with?('acct:')
|
||||
params[:resource].split('@').first.gsub('acct:', '')
|
||||
if resource_param.start_with?('acct:')
|
||||
resource_param.split('@').first.gsub('acct:', '')
|
||||
else
|
||||
url = Addressable::URI.parse(params[:resource])
|
||||
url = Addressable::URI.parse(resource_param)
|
||||
url.path.gsub('/users/', '')
|
||||
end
|
||||
end
|
||||
@ -43,4 +43,8 @@ class XrdController < ApplicationController
|
||||
|
||||
(["RSA"] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
|
||||
end
|
||||
|
||||
def resource_param
|
||||
params.require(:resource)
|
||||
end
|
||||
end
|
||||
|
@ -1,3 +1,5 @@
|
||||
module AccountsHelper
|
||||
|
||||
def pagination_options
|
||||
{ previous_label: "#{fa_icon('chevron-left')} Prev".html_safe, next_label: "Next #{fa_icon('chevron-right')}".html_safe, inner_window: 2 }
|
||||
end
|
||||
end
|
||||
|
@ -12,6 +12,17 @@ module ApplicationHelper
|
||||
id.start_with?("tag:#{Rails.configuration.x.local_domain}")
|
||||
end
|
||||
|
||||
def linkify(status)
|
||||
mention_hash = {}
|
||||
status.mentions.each { |m| mention_hash[m.acct] = m }
|
||||
coder = HTMLEntities.new
|
||||
|
||||
auto_link(coder.encode(status.text), link: :urls, html: { rel: 'nofollow noopener' }).gsub(Account::MENTION_RE) do |m|
|
||||
account = mention_hash[Account::MENTION_RE.match(m)[1]]
|
||||
"#{m.split('@').first}<a href=\"#{url_for_target(account)}\" class=\"mention\">@<span>#{account.acct}</span></a>"
|
||||
end.html_safe
|
||||
end
|
||||
|
||||
def active_nav_class(path)
|
||||
current_page?(path) ? 'active' : ''
|
||||
end
|
||||
|
@ -3,7 +3,7 @@ module AtomBuilderHelper
|
||||
@account.stream_entries.last ? (@account.updated_at > @account.stream_entries.last.created_at ? @account.updated_at : @account.stream_entries.last.created_at) : @account.updated_at
|
||||
end
|
||||
|
||||
def entry(xml, is_root, &block)
|
||||
def entry(xml, is_root = false, &block)
|
||||
if is_root
|
||||
root_tag(xml, :entry, &block)
|
||||
else
|
||||
@ -135,6 +135,22 @@ module AtomBuilderHelper
|
||||
xml.logo url
|
||||
end
|
||||
|
||||
def conditionally_formatted(activity)
|
||||
if activity.is_a?(Status)
|
||||
if activity.reblog? && activity.reblog.local?
|
||||
linkify(activity.reblog)
|
||||
elsif activity.local?
|
||||
linkify(activity)
|
||||
else
|
||||
activity.content
|
||||
end
|
||||
elsif activity.nil?
|
||||
''
|
||||
else
|
||||
activity.content
|
||||
end
|
||||
end
|
||||
|
||||
def include_author(xml, account)
|
||||
object_type xml, :person
|
||||
uri xml, url_for_target(account)
|
||||
@ -150,7 +166,7 @@ module AtomBuilderHelper
|
||||
published_at xml, stream_entry.created_at
|
||||
updated_at xml, stream_entry.updated_at
|
||||
title xml, stream_entry.title
|
||||
content xml, stream_entry.content
|
||||
content xml, conditionally_formatted(stream_entry.activity)
|
||||
verb xml, stream_entry.verb
|
||||
link_self xml, account_stream_entry_url(stream_entry.account, stream_entry, format: 'atom')
|
||||
object_type xml, stream_entry.object_type
|
||||
@ -176,7 +192,7 @@ module AtomBuilderHelper
|
||||
|
||||
# Statuses have content
|
||||
if [:note, :comment].include? stream_entry.target.object_type
|
||||
content xml, stream_entry.target.content
|
||||
content xml, conditionally_formatted(stream_entry.target)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -20,17 +20,6 @@ module StreamEntriesHelper
|
||||
date < 5.days.ago ? date.strftime("%d.%m.%Y") : "#{time_ago_in_words(date)} ago"
|
||||
end
|
||||
|
||||
def linkify(status)
|
||||
mention_hash = {}
|
||||
status.mentions.each { |m| mention_hash[m.acct] = m }
|
||||
coder = HTMLEntities.new
|
||||
|
||||
auto_link(coder.encode(status.text), link: :urls, html: { target: '_blank', rel: 'nofollow' }).gsub(Account::MENTION_RE) do |m|
|
||||
account = mention_hash[Account::MENTION_RE.match(m)[1]]
|
||||
"#{m.split('@').first}<a href=\"#{url_for_target(account)}\" class=\"mention\">@<span>#{account.acct}</span></a>"
|
||||
end.html_safe
|
||||
end
|
||||
|
||||
def reblogged_by_me_class(status)
|
||||
user_signed_in? && current_user.account.reblogged?(status) ? 'reblogged' : ''
|
||||
end
|
||||
|
4
app/mailers/application_mailer.rb
Normal file
4
app/mailers/application_mailer.rb
Normal file
@ -0,0 +1,4 @@
|
||||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: (ENV['SMTP_FROM_ADDRESS'] || 'notifications@localhost')
|
||||
layout 'mailer'
|
||||
end
|
34
app/mailers/notification_mailer.rb
Normal file
34
app/mailers/notification_mailer.rb
Normal file
@ -0,0 +1,34 @@
|
||||
class NotificationMailer < ApplicationMailer
|
||||
helper StreamEntriesHelper
|
||||
helper AtomBuilderHelper
|
||||
|
||||
def mention(mentioned_account, status)
|
||||
@me = mentioned_account
|
||||
@status = status
|
||||
|
||||
mail to: @me.user.email, subject: "You were mentioned by #{@status.account.acct}"
|
||||
end
|
||||
|
||||
def follow(followed_account, follower)
|
||||
@me = followed_account
|
||||
@account = follower
|
||||
|
||||
mail to: @me.user.email, subject: "#{@account.acct} is now following you"
|
||||
end
|
||||
|
||||
def favourite(target_status, from_account)
|
||||
@me = target_status.account
|
||||
@account = from_account
|
||||
@status = target_status
|
||||
|
||||
mail to: @me.user.email, subject: "#{@account.acct} favourited your status"
|
||||
end
|
||||
|
||||
def reblog(target_status, from_account)
|
||||
@me = target_status.account
|
||||
@account = from_account
|
||||
@status = target_status
|
||||
|
||||
mail to: @me.user.email, subject: "#{@account.acct} reblogged your status"
|
||||
end
|
||||
end
|
@ -1,7 +1,8 @@
|
||||
class Account < ActiveRecord::Base
|
||||
# Local users
|
||||
has_one :user, inverse_of: :account
|
||||
validates :username, uniqueness: { scope: :domain }
|
||||
validates :username, uniqueness: { scope: :domain, case_sensitive: false }, if: 'local?'
|
||||
validates :username, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
|
||||
|
||||
# Avatar upload
|
||||
attr_reader :avatar_remote_url
|
||||
@ -12,6 +13,10 @@ class Account < ActiveRecord::Base
|
||||
has_attached_file :header, styles: { medium: '700x335#' }
|
||||
validates_attachment_content_type :header, content_type: /\Aimage\/.*\Z/
|
||||
|
||||
# Local user profile validations
|
||||
validates :display_name, length: { maximum: 30 }, if: 'local?'
|
||||
validates :note, length: { maximum: 124 }, if: 'local?'
|
||||
|
||||
# Timelines
|
||||
has_many :stream_entries, inverse_of: :account
|
||||
has_many :statuses, inverse_of: :account
|
||||
@ -32,7 +37,8 @@ class Account < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def unfollow!(other_account)
|
||||
self.active_relationships.find_by(target_account: other_account).destroy
|
||||
follow = self.active_relationships.find_by(target_account: other_account)
|
||||
follow.destroy unless follow.nil?
|
||||
end
|
||||
|
||||
def following?(other_account)
|
||||
@ -93,6 +99,17 @@ class Account < ActiveRecord::Base
|
||||
self.username
|
||||
end
|
||||
|
||||
def self.find_local!(username)
|
||||
table = self.arel_table
|
||||
self.where(table[:username].matches(username)).where(domain: nil).take!
|
||||
end
|
||||
|
||||
def self.find_local(username)
|
||||
self.find_local!(username)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
nil
|
||||
end
|
||||
|
||||
before_create do
|
||||
if local?
|
||||
keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 1024 : 2048)
|
||||
|
@ -2,7 +2,7 @@ class Favourite < ActiveRecord::Base
|
||||
belongs_to :account, inverse_of: :favourites
|
||||
belongs_to :status, inverse_of: :favourites
|
||||
|
||||
has_one :stream_entry, as: :activity, dependent: :destroy
|
||||
has_one :stream_entry, as: :activity
|
||||
|
||||
def verb
|
||||
:favorite
|
||||
|
@ -2,7 +2,7 @@ class Follow < ActiveRecord::Base
|
||||
belongs_to :account
|
||||
belongs_to :target_account, class_name: 'Account'
|
||||
|
||||
has_one :stream_entry, as: :activity, dependent: :destroy
|
||||
has_one :stream_entry, as: :activity
|
||||
|
||||
validates :account, :target_account, presence: true
|
||||
validates :account_id, uniqueness: { scope: :target_account_id }
|
||||
|
@ -78,6 +78,5 @@ class Status < ActiveRecord::Base
|
||||
|
||||
after_create do
|
||||
self.account.stream_entries.create!(activity: self)
|
||||
FanOutOnWriteService.new.(self)
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,6 @@
|
||||
class BaseService
|
||||
include RoutingHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ApplicationHelper
|
||||
include AtomBuilderHelper
|
||||
end
|
||||
|
@ -16,7 +16,8 @@ class FanOutOnWriteService < BaseService
|
||||
end
|
||||
|
||||
# Deliver to local mentioned
|
||||
status.mentions.each do |mentioned_account|
|
||||
status.mentioned_accounts.each do |mention|
|
||||
mentioned_account = mention.account
|
||||
next unless mentioned_account.local?
|
||||
push(:mentions, mentioned_account.id, status)
|
||||
end
|
||||
|
@ -6,8 +6,13 @@ class FavouriteService < BaseService
|
||||
def call(account, status)
|
||||
favourite = Favourite.create!(account: account, status: status)
|
||||
account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
|
||||
return favourite if status.local?
|
||||
send_interaction_service.(favourite.stream_entry, status.account)
|
||||
|
||||
if status.local?
|
||||
NotificationMailer.favourite(status, account).deliver_later
|
||||
else
|
||||
send_interaction_service.(favourite.stream_entry, status.account)
|
||||
end
|
||||
|
||||
favourite
|
||||
end
|
||||
|
||||
|
@ -7,6 +7,7 @@ class PostStatusService < BaseService
|
||||
def call(account, text, in_reply_to = nil)
|
||||
status = account.statuses.create!(text: text, thread: in_reply_to)
|
||||
process_mentions_service.(status)
|
||||
fan_out_on_write_service.(status)
|
||||
account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
|
||||
status
|
||||
end
|
||||
@ -16,4 +17,8 @@ class PostStatusService < BaseService
|
||||
def process_mentions_service
|
||||
@process_mentions_service ||= ProcessMentionsService.new
|
||||
end
|
||||
|
||||
def fan_out_on_write_service
|
||||
@fan_out_on_write_service ||= FanOutOnWriteService.new
|
||||
end
|
||||
end
|
||||
|
@ -17,7 +17,7 @@ class ProcessFeedService < BaseService
|
||||
status = Status.find_by(uri: activity_id(entry))
|
||||
|
||||
# If we already have a post and the verb is now "delete", we gotta delete it and move on!
|
||||
if verb(entry) == :delete
|
||||
if !status.nil? && verb(entry) == :delete
|
||||
delete_post!(status)
|
||||
next
|
||||
end
|
||||
@ -26,12 +26,14 @@ class ProcessFeedService < BaseService
|
||||
|
||||
status = Status.new(uri: activity_id(entry), url: activity_link(entry), account: account, text: content(entry), created_at: published(entry), updated_at: updated(entry))
|
||||
|
||||
if object_type(entry) == :comment && verb(entry) == :post
|
||||
add_reply!(entry, status)
|
||||
elsif verb(entry) == :share
|
||||
if verb(entry) == :share
|
||||
add_reblog!(entry, status)
|
||||
elsif verb(entry) == :post
|
||||
add_post!(entry, status)
|
||||
if thread_id(entry).nil?
|
||||
add_post!(entry, status)
|
||||
else
|
||||
add_reply!(entry, status)
|
||||
end
|
||||
end
|
||||
|
||||
# If we added a status, go through accounts it mentions and create respective relations
|
||||
@ -45,13 +47,16 @@ class ProcessFeedService < BaseService
|
||||
href = Addressable::URI.parse(mention_link.attribute('href').value)
|
||||
|
||||
if href.host == Rails.configuration.x.local_domain
|
||||
mentioned_account = Account.find_by(username: href.path.gsub('/users/', ''), domain: nil)
|
||||
mentioned_account = Account.find_local(href.path.gsub('/users/', ''))
|
||||
|
||||
unless mentioned_account.nil?
|
||||
mentioned_account.mentions.first_or_create(status: status)
|
||||
mentioned_account.mentions.where(status: status).first_or_create(status: status)
|
||||
NotificationMailer.mention(mentioned_account, status).deliver_later
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
fan_out_on_write_service.(status)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -69,7 +74,10 @@ class ProcessFeedService < BaseService
|
||||
status.reblog = fetch_remote_status(entry)
|
||||
end
|
||||
|
||||
status.save! unless status.reblog.nil?
|
||||
if !status.reblog.nil?
|
||||
status.save!
|
||||
NotificationMailer.reblog(status.reblog, status.account).deliver_later
|
||||
end
|
||||
end
|
||||
|
||||
def add_reply!(entry, status)
|
||||
@ -98,7 +106,7 @@ class ProcessFeedService < BaseService
|
||||
account = Account.find_by(username: username, domain: domain)
|
||||
|
||||
if account.nil?
|
||||
account = follow_remote_account_service.("acct:#{username}@#{domain}", false)
|
||||
account = follow_remote_account_service.("#{username}@#{domain}", false)
|
||||
return nil if account.nil?
|
||||
end
|
||||
|
||||
@ -166,4 +174,8 @@ class ProcessFeedService < BaseService
|
||||
def update_remote_profile_service
|
||||
@update_remote_profile_service ||= UpdateRemoteProfileService.new
|
||||
end
|
||||
|
||||
def fan_out_on_write_service
|
||||
@fan_out_on_write_service ||= FanOutOnWriteService.new
|
||||
end
|
||||
end
|
||||
|
@ -14,7 +14,7 @@ class ProcessInteractionService < BaseService
|
||||
account = Account.find_by(username: username, domain: domain)
|
||||
|
||||
if account.nil?
|
||||
account = follow_remote_account_service.("acct:#{username}@#{domain}", false)
|
||||
account = follow_remote_account_service.("#{username}@#{domain}", false)
|
||||
return if account.nil?
|
||||
end
|
||||
|
||||
@ -48,13 +48,14 @@ class ProcessInteractionService < BaseService
|
||||
end
|
||||
|
||||
def verb(xml)
|
||||
xml.at_xpath('//activity:verb').content.gsub('http://activitystrea.ms/schema/1.0/', '').to_sym
|
||||
xml.at_xpath('//activity:verb').content.gsub('http://activitystrea.ms/schema/1.0/', '').gsub('http://ostatus.org/schema/1.0/', '').to_sym
|
||||
rescue
|
||||
:post
|
||||
end
|
||||
|
||||
def follow!(account, target_account)
|
||||
account.follow!(target_account)
|
||||
NotificationMailer.follow(target_account, account).deliver_later
|
||||
end
|
||||
|
||||
def unfollow!(account, target_account)
|
||||
@ -62,7 +63,9 @@ class ProcessInteractionService < BaseService
|
||||
end
|
||||
|
||||
def favourite!(xml, from_account)
|
||||
status(xml).favourites.first_or_create!(account: from_account)
|
||||
current_status = status(xml)
|
||||
current_status.favourites.where(account: from_account).first_or_create!(account: from_account)
|
||||
NotificationMailer.favourite(current_status, from_account).deliver_later
|
||||
end
|
||||
|
||||
def add_post!(body, account)
|
||||
@ -74,7 +77,7 @@ class ProcessInteractionService < BaseService
|
||||
end
|
||||
|
||||
def activity_id(xml)
|
||||
xml.at_xpath('/xmlns:entry/xmlns:id').content
|
||||
xml.at_xpath('./activity:object/xmlns:id').content
|
||||
end
|
||||
|
||||
def salmon
|
||||
|
@ -10,16 +10,22 @@ class ProcessMentionsService < BaseService
|
||||
username, domain = match.first.split('@')
|
||||
mentioned_account = Account.find_by(username: username, domain: domain)
|
||||
|
||||
if mentioned_account.nil?
|
||||
mentioned_account = follow_remote_account_service.("acct:#{match.first}")
|
||||
if mentioned_account.nil? && !domain.nil?
|
||||
mentioned_account = follow_remote_account_service.("#{match.first}")
|
||||
next if mentioned_account.nil?
|
||||
end
|
||||
|
||||
mentioned_account.mentions.first_or_create(status: status)
|
||||
mentioned_account.mentions.where(status: status).first_or_create(status: status)
|
||||
end
|
||||
|
||||
status.mentions.each do |mentioned_account|
|
||||
next if mentioned_account.local?
|
||||
send_interaction_service.(status.stream_entry, mentioned_account)
|
||||
status.mentioned_accounts.each do |mention|
|
||||
mentioned_account = mention.account
|
||||
|
||||
if mentioned_account.local?
|
||||
NotificationMailer.mention(mentioned_account, status).deliver_later
|
||||
else
|
||||
send_interaction_service.(status.stream_entry, mentioned_account)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,9 +5,15 @@ class ReblogService < BaseService
|
||||
# @return [Status]
|
||||
def call(account, reblogged_status)
|
||||
reblog = account.statuses.create!(reblog: reblogged_status, text: '')
|
||||
fan_out_on_write_service.(reblog)
|
||||
account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
|
||||
return reblog if reblogged_status.local?
|
||||
send_interaction_service.(reblog.stream_entry, reblogged_status.account)
|
||||
|
||||
if reblogged_status.local?
|
||||
NotificationMailer.reblog(reblogged_status, account).deliver_later
|
||||
else
|
||||
send_interaction_service.(reblog.stream_entry, reblogged_status.account)
|
||||
end
|
||||
|
||||
reblog
|
||||
end
|
||||
|
||||
@ -16,4 +22,8 @@ class ReblogService < BaseService
|
||||
def send_interaction_service
|
||||
@send_interaction_service ||= SendInteractionService.new
|
||||
end
|
||||
|
||||
def fan_out_on_write_service
|
||||
@fan_out_on_write_service ||= FanOutOnWriteService.new
|
||||
end
|
||||
end
|
||||
|
@ -1,14 +0,0 @@
|
||||
class SetupLocalAccountService < BaseService
|
||||
# Setup an account for a new user instance by generating
|
||||
# an RSA key pair and a profile
|
||||
# @param [User] user Unsaved user instance
|
||||
# @param [String] username
|
||||
def call(user, username)
|
||||
user.build_account
|
||||
|
||||
user.account.username = username
|
||||
user.account.domain = nil
|
||||
|
||||
user.save!
|
||||
end
|
||||
end
|
8
app/views/accounts/_grid_card.html.haml
Normal file
8
app/views/accounts/_grid_card.html.haml
Normal file
@ -0,0 +1,8 @@
|
||||
.account-grid-card
|
||||
.account-grid-card__header
|
||||
.avatar= image_tag account.avatar.url(:medium)
|
||||
.name
|
||||
= link_to url_for_target(account) do
|
||||
%span.display_name= display_name(account)
|
||||
%span.username= "@#{account.acct}"
|
||||
%p.note= truncate(account.note, length: 124)
|
20
app/views/accounts/_header.html.haml
Normal file
20
app/views/accounts/_header.html.haml
Normal file
@ -0,0 +1,20 @@
|
||||
.card{ style: "background-image: url(#{@account.header.url(:medium)})" }
|
||||
.avatar= image_tag @account.avatar.url(:large)
|
||||
%h1.name
|
||||
= display_name(@account)
|
||||
%small= "@#{@account.username}"
|
||||
.details
|
||||
.counter{ class: active_nav_class(account_url(@account)) }
|
||||
= link_to account_url(@account) do
|
||||
%span.counter-label Posts
|
||||
%span.counter-number= @account.statuses.count
|
||||
.counter{ class: active_nav_class(following_account_url(@account)) }
|
||||
= link_to following_account_url(@account) do
|
||||
%span.counter-label Following
|
||||
%span.counter-number= @account.following.count
|
||||
.counter{ class: active_nav_class(followers_account_url(@account)) }
|
||||
= link_to followers_account_url(@account) do
|
||||
%span.counter-label Followers
|
||||
%span.counter-number= @account.followers.count
|
||||
.bio
|
||||
%p= @account.note
|
1
app/views/accounts/_nothing_here.html.haml
Normal file
1
app/views/accounts/_nothing_here.html.haml
Normal file
@ -0,0 +1 @@
|
||||
%p.nothing-here There is nothing here!
|
14
app/views/accounts/followers.html.haml
Normal file
14
app/views/accounts/followers.html.haml
Normal file
@ -0,0 +1,14 @@
|
||||
- content_for :page_title do
|
||||
People who follow
|
||||
= display_name(@account)
|
||||
|
||||
= render partial: 'header'
|
||||
|
||||
.accounts-grid
|
||||
- @followers.each do |f|
|
||||
= render partial: 'grid_card', locals: { account: f }
|
||||
|
||||
- if @followers.empty?
|
||||
= render partial: 'nothing_here'
|
||||
|
||||
= will_paginate @followers, pagination_options
|
15
app/views/accounts/following.html.haml
Normal file
15
app/views/accounts/following.html.haml
Normal file
@ -0,0 +1,15 @@
|
||||
- content_for :page_title do
|
||||
People whom
|
||||
= display_name(@account)
|
||||
follows
|
||||
|
||||
= render partial: 'header'
|
||||
|
||||
.accounts-grid
|
||||
- @following.each do |f|
|
||||
= render partial: 'grid_card', locals: { account: f }
|
||||
|
||||
- if @following.empty?
|
||||
= render partial: 'nothing_here'
|
||||
|
||||
= will_paginate @following, pagination_options
|
@ -1,24 +1,14 @@
|
||||
- content_for :page_title do
|
||||
= display_name(@account)
|
||||
|
||||
- content_for :header_tags do
|
||||
%link{ rel: 'salmon', href: api_salmon_url(@account.id) }/
|
||||
%link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/
|
||||
|
||||
.card{ style: "background-image: url(#{@account.header.url(:medium)})" }
|
||||
.avatar= image_tag @account.avatar.url(:large)
|
||||
%h1.name
|
||||
= @account.display_name.blank? ? @account.username : @account.display_name
|
||||
%small= "@#{@account.username}"
|
||||
.details
|
||||
.counter
|
||||
%span.counter-label Posts
|
||||
%span.counter-number= @account.statuses.count
|
||||
.counter
|
||||
%span.counter-label Following
|
||||
%span.counter-number= @account.following.count
|
||||
.counter
|
||||
%span.counter-label Followers
|
||||
%span.counter-number= @account.followers.count
|
||||
.bio
|
||||
%p= @account.note
|
||||
= render partial: 'header'
|
||||
|
||||
.activity-stream
|
||||
- @statuses.each do |status|
|
||||
= render partial: 'stream_entries/status', locals: { status: status, include_threads: false, is_successor: false, is_predecessor: false }
|
||||
|
||||
= will_paginate @statuses, pagination_options
|
||||
|
@ -2,7 +2,9 @@
|
||||
%html
|
||||
%head
|
||||
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
|
||||
%title Mastodon
|
||||
%title
|
||||
= "#{yield(:page_title)} - " if content_for?(:page_title)
|
||||
Mastodon
|
||||
= stylesheet_link_tag 'application', media: 'all'
|
||||
= javascript_include_tag 'application'
|
||||
= csrf_meta_tags
|
||||
|
@ -6,7 +6,7 @@
|
||||
.dashboard__current-user
|
||||
= link_to account_path(current_user.account) do
|
||||
= image_tag current_user.account.avatar.url(:medium), class: 'dashboard__current-user__avatar'
|
||||
%strong.dashboard__current-user__display-name= current_user.account.display_name.blank? ? current_user.account.username : current_user.account.display_name
|
||||
%strong.dashboard__current-user__display-name= display_name(current_user.account)
|
||||
%span.dashboard__current-user__username= "@#{current_user.account.username}"
|
||||
%ul
|
||||
%li{ class: active_nav_class(root_path) }
|
||||
|
5
app/views/layouts/mailer.text.erb
Normal file
5
app/views/layouts/mailer.text.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<%= yield %>
|
||||
|
||||
---
|
||||
|
||||
Mastodon notifications from <%= Rails.configuration.x.local_domain %>
|
5
app/views/notification_mailer/favourite.text.erb
Normal file
5
app/views/notification_mailer/favourite.text.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<%= display_name(@me) %>,
|
||||
|
||||
Your status was favourited by <%= @account.acct %>:
|
||||
|
||||
<%= account_stream_entry_url(@me, @status.stream_entry) %>
|
5
app/views/notification_mailer/follow.text.erb
Normal file
5
app/views/notification_mailer/follow.text.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<%= display_name(@me) %>,
|
||||
|
||||
<%= @account.acct %> is now following you!
|
||||
|
||||
<%= url_for_target(@account) %>
|
7
app/views/notification_mailer/mention.text.erb
Normal file
7
app/views/notification_mailer/mention.text.erb
Normal file
@ -0,0 +1,7 @@
|
||||
<%= display_name(@me) %>,
|
||||
|
||||
You were mentioned by <%= @status.account.acct %> in:
|
||||
|
||||
<%= strip_tags(@status.content) %>
|
||||
|
||||
<%= url_for_target(@status) %>
|
5
app/views/notification_mailer/reblog.text.erb
Normal file
5
app/views/notification_mailer/reblog.text.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<%= display_name(@me) %>,
|
||||
|
||||
Your status was reblogged by <%= @account.acct %>:
|
||||
|
||||
<%= account_stream_entry_url(@me, @status.stream_entry) %>
|
@ -33,5 +33,7 @@ module Mastodon
|
||||
Doorkeeper::AuthorizedApplicationsController.layout 'dashboard'
|
||||
Doorkeeper::AuthorizationsController.layout 'auth'
|
||||
end
|
||||
|
||||
config.middleware.use Rack::Attack
|
||||
end
|
||||
end
|
||||
|
@ -17,7 +17,8 @@ test:
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
database: postgres
|
||||
username: postgres
|
||||
password:
|
||||
host: db
|
||||
database: <%= ENV['DB_NAME'] || 'mastodon_production' %>
|
||||
username: <%= ENV['DB_USER'] || 'mastodon' %>
|
||||
password: <%= ENV['DB_PASS'] || '' %>
|
||||
host: <%= ENV['DB_HOST'] || 'localhost' %>
|
||||
port: <%= ENV['DB_PORT'] || 5432 %>
|
||||
|
@ -38,4 +38,6 @@ Rails.application.configure do
|
||||
|
||||
# Raises error for missing translations
|
||||
# config.action_view.raise_on_missing_translations = true
|
||||
|
||||
config.action_mailer.delivery_method = :letter_opener
|
||||
end
|
||||
|
@ -22,7 +22,7 @@ Rails.application.configure do
|
||||
|
||||
# Disable serving static files from the `/public` folder by default since
|
||||
# Apache or NGINX already handles this.
|
||||
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
||||
config.serve_static_files = true
|
||||
|
||||
# Compress JavaScripts and CSS.
|
||||
config.assets.js_compressor = :uglifier
|
||||
@ -42,7 +42,7 @@ Rails.application.configure do
|
||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
# config.force_ssl = true
|
||||
config.force_ssl = ENV['LOCAL_HTTPS'] == 'true'
|
||||
|
||||
# Use the lowest log level to ensure availability of diagnostic information
|
||||
# when problems arise.
|
||||
@ -76,4 +76,16 @@ Rails.application.configure do
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
||||
# E-mails
|
||||
config.action_mailer.smtp_settings = {
|
||||
:port => ENV['SMTP_PORT'],
|
||||
:address => ENV['SMTP_SERVER'],
|
||||
:user_name => ENV['SMTP_LOGIN'],
|
||||
:password => ENV['SMTP_PASSWORD'],
|
||||
:domain => config.x.local_domain,
|
||||
:authentication => :plain,
|
||||
}
|
||||
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
end
|
||||
|
@ -15,6 +15,7 @@ Rails.application.configure do
|
||||
# Configure static file server for tests with Cache-Control for performance.
|
||||
config.serve_static_files = true
|
||||
config.static_cache_control = 'public, max-age=3600'
|
||||
config.assets.digest = false
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
|
@ -12,7 +12,7 @@ Devise.setup do |config|
|
||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||
# note that it will be overwritten if you use your own mailer class
|
||||
# with default "from" parameter.
|
||||
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
|
||||
config.mailer_sender = ENV['SMTP_FROM_ADDRESS'] || 'notifications@localhost'
|
||||
|
||||
# Configure the class responsible to send e-mails.
|
||||
# config.mailer = 'Devise::Mailer'
|
||||
|
@ -23,7 +23,7 @@ Doorkeeper.configure do
|
||||
|
||||
# Access token expiration time (default 2 hours).
|
||||
# If you want to disable expiration, set this to nil.
|
||||
# access_token_expires_in nil
|
||||
access_token_expires_in nil
|
||||
|
||||
# Assign a custom TTL for implicit grants.
|
||||
# custom_access_token_expires_in do |oauth_client|
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [:password]
|
||||
Rails.application.config.filter_parameters += [:password, :private_key, :public_key]
|
||||
|
3
config/initializers/rack-attack.rb
Normal file
3
config/initializers/rack-attack.rb
Normal file
@ -0,0 +1,3 @@
|
||||
class Rack::Attack
|
||||
# TODO
|
||||
end
|
@ -14,6 +14,11 @@ Rails.application.routes.draw do
|
||||
|
||||
resources :accounts, path: 'users', only: [:show], param: :username do
|
||||
resources :stream_entries, path: 'updates', only: [:show]
|
||||
|
||||
member do
|
||||
get :followers
|
||||
get :following
|
||||
end
|
||||
end
|
||||
|
||||
resource :settings, only: [:show, :update]
|
||||
|
10
db/migrate/20160316103650_add_missing_indices.rb
Normal file
10
db/migrate/20160316103650_add_missing_indices.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class AddMissingIndices < ActiveRecord::Migration
|
||||
def change
|
||||
add_index :users, :account_id
|
||||
add_index :statuses, :account_id
|
||||
add_index :statuses, :in_reply_to_id
|
||||
add_index :statuses, :reblog_of_id
|
||||
add_index :stream_entries, :account_id
|
||||
add_index :stream_entries, [:activity_id, :activity_type]
|
||||
end
|
||||
end
|
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160314164231) do
|
||||
ActiveRecord::Schema.define(version: 20160316103650) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@ -125,6 +125,9 @@ ActiveRecord::Schema.define(version: 20160314164231) do
|
||||
t.string "url"
|
||||
end
|
||||
|
||||
add_index "statuses", ["account_id"], name: "index_statuses_on_account_id", using: :btree
|
||||
add_index "statuses", ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id", using: :btree
|
||||
add_index "statuses", ["reblog_of_id"], name: "index_statuses_on_reblog_of_id", using: :btree
|
||||
add_index "statuses", ["uri"], name: "index_statuses_on_uri", unique: true, using: :btree
|
||||
|
||||
create_table "stream_entries", force: :cascade do |t|
|
||||
@ -135,6 +138,9 @@ ActiveRecord::Schema.define(version: 20160314164231) do
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
add_index "stream_entries", ["account_id"], name: "index_stream_entries_on_account_id", using: :btree
|
||||
add_index "stream_entries", ["activity_id", "activity_type"], name: "index_stream_entries_on_activity_id_and_activity_type", using: :btree
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.integer "account_id", null: false
|
||||
@ -151,6 +157,7 @@ ActiveRecord::Schema.define(version: 20160314164231) do
|
||||
t.inet "last_sign_in_ip"
|
||||
end
|
||||
|
||||
add_index "users", ["account_id"], name: "index_users_on_account_id", using: :btree
|
||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
|
||||
|
||||
|
@ -12,4 +12,7 @@ services:
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
volumes:
|
||||
- ./public/assets:/mastodon/public/assets
|
||||
- ./public/system:/mastodon/public/system
|
||||
env_file: .env.production
|
||||
|
13
lib/tasks/subscriptions.rake
Normal file
13
lib/tasks/subscriptions.rake
Normal file
@ -0,0 +1,13 @@
|
||||
namespace :subscriptions do
|
||||
|
||||
desc "For all remote accounts that have no local followers, unsubscribe from PuSH"
|
||||
task clear: :environment do
|
||||
accounts = Account.where('(select count(f.id) from follows as f where f.target_account_id = accounts.id) = 0').where.not(domain: nil)
|
||||
|
||||
accounts.each do |a|
|
||||
a.subscription(api_subscription_url(a.id)).unsubscribe
|
||||
a.update!(verify_token: '', secret: '')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Binary file not shown.
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 2.3 KiB |
@ -4,14 +4,28 @@ RSpec.describe AccountsController, type: :controller do
|
||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns 200' do
|
||||
it 'returns http success' do
|
||||
get :show, username: alice.username
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns 200 with Atom' do
|
||||
it 'returns http success with Atom' do
|
||||
get :show, username: alice.username, format: 'atom'
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #followers' do
|
||||
it 'returns http success' do
|
||||
get :followers, username: alice.username
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #following' do
|
||||
it 'returns http success' do
|
||||
get :following, username: alice.username
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,71 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::AccountsController, type: :controller do
|
||||
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
|
||||
let(:token) { double acceptable?: true, resource_owner_id: user.id }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :show, id: user.account.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #statuses' do
|
||||
it 'returns http success' do
|
||||
get :statuses, id: user.account.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #followers' do
|
||||
it 'returns http success' do
|
||||
get :followers, id: user.account.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #following' do
|
||||
it 'returns http success' do
|
||||
get :following, id: user.account.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #follow' do
|
||||
let(:other_account) { Fabricate(:account, username: 'bob') }
|
||||
|
||||
before do
|
||||
post :follow, id: other_account.id
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'creates a following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #unfollow' do
|
||||
let(:other_account) { Fabricate(:account, username: 'bob') }
|
||||
|
||||
before do
|
||||
user.account.follow!(other_account)
|
||||
post :unfollow, id: other_account.id
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'removes the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,48 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::FollowsController, type: :controller do
|
||||
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
|
||||
let(:token) { double acceptable?: true, resource_owner_id: user.id }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
before do
|
||||
stub_request(:get, "https://quitter.no/.well-known/host-meta").to_return(request_fixture('.host-meta.txt'))
|
||||
stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no").to_return(request_fixture('webfinger.txt'))
|
||||
stub_request(:get, "https://quitter.no/api/statuses/user_timeline/7477.atom").to_return(request_fixture('feed.txt'))
|
||||
stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt'))
|
||||
stub_request(:post, "https://quitter.no/main/push/hub").to_return(:status => 200, :body => "", :headers => {})
|
||||
stub_request(:post, "https://quitter.no/main/salmon/user/7477").to_return(:status => 200, :body => "", :headers => {})
|
||||
stub_request(:post, "https://pubsubhubbub.superfeedr.com/").to_return(:status => 200, :body => "", :headers => {})
|
||||
|
||||
post :create, uri: 'gargron@quitter.no'
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'creates account for remote user' do
|
||||
expect(Account.find_by(username: 'gargron', domain: 'quitter.no')).to_not be_nil
|
||||
end
|
||||
|
||||
it 'creates a follow relation between user and remote user' do
|
||||
expect(user.account.following?(Account.find_by(username: 'gargron', domain: 'quitter.no'))).to be true
|
||||
end
|
||||
|
||||
it 'sends a salmon slap to the remote user' do
|
||||
expect(a_request(:post, "https://quitter.no/main/salmon/user/7477")).to have_been_made
|
||||
end
|
||||
|
||||
it 'notifies own hub' do
|
||||
expect(a_request(:post, "https://pubsubhubbub.superfeedr.com/")).to have_been_made
|
||||
end
|
||||
|
||||
it 'subscribes to remote hub' do
|
||||
expect(a_request(:post, "https://quitter.no/main/push/hub")).to have_been_made
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,7 +1,35 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::SalmonController, type: :controller do
|
||||
let(:account) { Fabricate(:account, username: 'catsrgr8', user: Fabricate(:user)) }
|
||||
|
||||
before do
|
||||
stub_request(:get, "https://quitter.no/.well-known/host-meta").to_return(request_fixture('.host-meta.txt'))
|
||||
stub_request(:get, "https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no").to_return(request_fixture('webfinger.txt'))
|
||||
stub_request(:get, "https://quitter.no/api/statuses/user_timeline/7477.atom").to_return(request_fixture('feed.txt'))
|
||||
stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt'))
|
||||
end
|
||||
|
||||
describe 'POST #update' do
|
||||
pending
|
||||
before do
|
||||
request.env['RAW_POST_DATA'] = File.read(File.join(Rails.root, 'spec', 'fixtures', 'salmon', 'mention.xml'))
|
||||
post :update, id: account.id
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'creates remote account' do
|
||||
expect(Account.find_by(username: 'gargron', domain: 'quitter.no')).to_not be_nil
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
expect(Status.find_by(uri: 'tag:quitter.no,2016-03-20:noticeId=1276923:objectType=note')).to_not be_nil
|
||||
end
|
||||
|
||||
it 'creates mention for target account' do
|
||||
expect(account.mentions.count).to eq 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,5 +1,39 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::StatusesController, type: :controller do
|
||||
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
|
||||
let(:token) { double acceptable?: true, resource_owner_id: user.id }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
let(:status) { Fabricate(:status, account: user.account) }
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, id: status.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #home' do
|
||||
it 'returns http success'
|
||||
end
|
||||
|
||||
describe 'GET #mentions' do
|
||||
it 'returns http success'
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'returns http success'
|
||||
end
|
||||
|
||||
describe 'POST #reblog' do
|
||||
it 'returns http success'
|
||||
end
|
||||
|
||||
describe 'POST #favourite' do
|
||||
it 'returns http success'
|
||||
end
|
||||
end
|
||||
|
@ -1,11 +1,40 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::SubscriptionsController, type: :controller do
|
||||
let(:account) { Fabricate(:account, username: 'gargron', domain: 'quitter.no', verify_token: '123', remote_url: 'topic_url', secret: 'abc') }
|
||||
|
||||
describe 'GET #show' do
|
||||
pending
|
||||
before do
|
||||
get :show, id: account.id, 'hub.topic': 'topic_url', 'hub.verify_token': 123, 'hub.challenge': '456'
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'echoes back the challenge' do
|
||||
expect(response.body).to match '456'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #update' do
|
||||
pending
|
||||
let(:feed) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'push', 'feed.atom')) }
|
||||
|
||||
before do
|
||||
stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt'))
|
||||
|
||||
request.env['HTTP_X_HUB_SIGNATURE'] = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', 'abc', feed)}"
|
||||
request.env['RAW_POST_DATA'] = feed
|
||||
|
||||
post :update, id: account.id
|
||||
end
|
||||
|
||||
it 'returns http created' do
|
||||
expect(response).to have_http_status(:created)
|
||||
end
|
||||
|
||||
it 'creates statuses for feed' do
|
||||
expect(account.statuses.count).to_not eq 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe HomeController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
it 'returns 200' do
|
||||
it 'redirects to login page' do
|
||||
get :index
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
|
@ -1,5 +1,11 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Oauth::ApplicationsController, type: :controller do
|
||||
describe 'GET #index' do
|
||||
it 'returns http success'
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
it 'redirects to the application page'
|
||||
end
|
||||
end
|
||||
|
@ -5,12 +5,12 @@ RSpec.describe StreamEntriesController, type: :controller do
|
||||
let(:status) { Fabricate(:status, account: alice) }
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns 200 with HTML' do
|
||||
it 'returns http success with HTML' do
|
||||
get :show, account_username: alice.username, id: status.stream_entry.id
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns 200 with Atom' do
|
||||
it 'returns http success with Atom' do
|
||||
get :show, account_username: alice.username, id: status.stream_entry.id, format: 'atom'
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe XrdController, type: :controller do
|
||||
describe 'GET #host_meta' do
|
||||
it 'returns 200' do
|
||||
it 'returns http success' do
|
||||
get :host_meta
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
@ -11,12 +11,12 @@ RSpec.describe XrdController, type: :controller do
|
||||
describe 'GET #webfinger' do
|
||||
let(:alice) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it 'returns 200 when account can be found' do
|
||||
it 'returns http success when account can be found' do
|
||||
get :webfinger, resource: "acct:#{alice.username}@anything.com"
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns 404 when account cannot be found' do
|
||||
it 'returns http not found when account cannot be found' do
|
||||
get :webfinger, resource: 'acct:not@existing.com'
|
||||
expect(response).to have_http_status(:not_found)
|
||||
end
|
||||
|
424
spec/fixtures/push/feed.atom
vendored
Normal file
424
spec/fixtures/push/feed.atom
vendored
Normal file
@ -0,0 +1,424 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
|
||||
<generator uri="https://gnu.io/social" version="1.2.0-beta4">GNU social</generator>
|
||||
<id>https://quitter.no/api/statuses/user_timeline/7477.atom</id>
|
||||
<title>gargron timeline</title>
|
||||
<subtitle>Updates from gargron on Quitter.no!</subtitle>
|
||||
<logo>https://quitter.no/avatar/7477-96-20160211190340.png</logo>
|
||||
<updated>2016-03-20T12:42:58+01:00</updated>
|
||||
<author>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<uri>https://quitter.no/user/7477</uri>
|
||||
<name>gargron</name>
|
||||
<summary>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</summary>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/gargron"/>
|
||||
<link rel="avatar" type="image/png" media:width="300" media:height="300" href="https://quitter.no/avatar/7477-300-20160211190340.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="96" media:height="96" href="https://quitter.no/avatar/7477-96-20160211190340.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="48" media:height="48" href="https://quitter.no/avatar/7477-48-20160211190449.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="24" media:height="24" href="https://quitter.no/avatar/7477-24-20160211190517.png"/>
|
||||
<poco:preferredUsername>gargron</poco:preferredUsername>
|
||||
<poco:displayName>DIGITAL CAT</poco:displayName>
|
||||
<poco:note>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</poco:note>
|
||||
<poco:address>
|
||||
<poco:formatted>Germany</poco:formatted>
|
||||
</poco:address>
|
||||
<poco:urls>
|
||||
<poco:type>homepage</poco:type>
|
||||
<poco:value>https://zeonfederated.com</poco:value>
|
||||
<poco:primary>true</poco:primary>
|
||||
</poco:urls>
|
||||
<followers url="https://quitter.no/gargron/subscribers"></followers>
|
||||
<statusnet:profile_info local_id="7477"></statusnet:profile_info>
|
||||
</author>
|
||||
<link href="https://quitter.no/gargron" rel="alternate" type="text/html"/>
|
||||
<link href="https://quitter.no/main/sup" rel="http://api.friendfeed.com/2008/03#sup" type="application/json"/>
|
||||
<link href="https://quitter.no/api/statuses/user_timeline/7477.atom?max_id=1243309" rel="next" type="application/atom+xml"/>
|
||||
<link href="https://quitter.no/main/push/hub" rel="hub"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="salmon"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="http://salmon-protocol.org/ns/salmon-replies"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="http://salmon-protocol.org/ns/salmon-mention"/>
|
||||
<link href="https://quitter.no/api/statuses/user_timeline/7477.atom" rel="self" type="application/atom+xml"/>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-20:noticeId=1276923:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">@<a href="https://cb6e6126.ngrok.io/users/catsrgr8" class="h-card mention">catsrgr8</a> this is a mention</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1276923"/>
|
||||
<status_net notice_id="1276923"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-20T11:05:31+00:00</published>
|
||||
<updated>2016-03-20T11:05:31+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-20:objectType=thread:nonce=7c998112e39a6685"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-20:objectType=thread:nonce=7c998112e39a6685</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://cb6e6126.ngrok.io/users/catsrgr8"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1276923.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1276923.atom"/>
|
||||
<statusnet:notice_info local_id="1276923" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1273635:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">Just testing a thing.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1273635"/>
|
||||
<status_net notice_id="1273635"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-19T20:35:53+00:00</published>
|
||||
<updated>2016-03-19T20:35:53+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-19:objectType=thread:nonce=c4a61886d5cad4c2"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-19:objectType=thread:nonce=c4a61886d5cad4c2</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273635.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273635.atom"/>
|
||||
<statusnet:notice_info local_id="1273635" source="web"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
<title>Delete</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> deleted notice <a href="https://quitter.no/notice/1272988">{{tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note}}</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1273012"/>
|
||||
<activity:verb>delete</activity:verb>
|
||||
<published>2016-03-19T18:16:58+00:00</published>
|
||||
<updated>2016-03-19T18:16:58+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-19:objectType=thread:nonce=7913e6b6256b6d0b"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-19:objectType=thread:nonce=7913e6b6256b6d0b</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<activity:target>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
</activity:target>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273012.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273012.atom"/>
|
||||
<statusnet:notice_info local_id="1273012" source="unknown"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1269381:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://mastodon.social/users/Gargron" class="h-card mention" title="Eugen">gargron</a> I have to wonder if this will appear as a reply to the right status, and not just a mention.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1269381"/>
|
||||
<status_net notice_id="1269381"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-19T00:10:14+00:00</published>
|
||||
<updated>2016-03-19T00:10:14+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:mastodon.social,2016-03-18:objectId=60:objectType=Status" href="https://quitter.no/notice/1269244"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1269244"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-18:objectType=thread:nonce=d05c6330fbe23fb9"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-18:objectType=thread:nonce=d05c6330fbe23fb9</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1269381.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1269381.atom"/>
|
||||
<statusnet:notice_info local_id="1269381" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-18:noticeId=1265337:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> Plus, Android can hardly be considered free software given how many proprietary blobs are used. I'm speaking as a disappointed Android user.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1265337"/>
|
||||
<status_net notice_id="1265337"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-18T10:01:50+00:00</published>
|
||||
<updated>2016-03-18T10:01:50+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:quitter.no,2016-03-18:noticeId=1265331:objectType=comment" href="https://quitter.no/notice/1265331"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1265331"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://quitter.no/user/7477"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265337.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265337.atom"/>
|
||||
<statusnet:notice_info local_id="1265337" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-18:noticeId=1265331:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> Well as it turns out, Apple software is better than Android in terms of security, and Apple is fighting FBI while Google promised to build a messaging app that facilitates wire tapping. The whole free software thing should imo be considered a bonus and not overshadow other factors.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1265331"/>
|
||||
<status_net notice_id="1265331"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-18T10:01:01+00:00</published>
|
||||
<updated>2016-03-18T10:01:01+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-18:noticeId=54411:objectType=note" href="https://community.highlandarrow.com/notice/54411"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/54411"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265331.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265331.atom"/>
|
||||
<statusnet:notice_info local_id="1265331" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-17:noticeId=1261358:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> @<a href="https://gs.kawa-kun.com/user/2" class="h-card mention" title="&#x7AF9;&#x4E0B;&#x61B2;&#x4E8C;">takeshitakenji</a> There is a reason that was deprecated and we don't use tables to design websites anymore. HTML needs to be semantic, i.e. tags need to describe the *kind* of content, not how it should *look*, which is a responsibility delegated to CSS. There are so many upsides to this separation of concerns, should I start listing?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1261358"/>
|
||||
<status_net notice_id="1261358"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-17T17:00:26+00:00</published>
|
||||
<updated>2016-03-17T17:00:26+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-17:noticeId=53857:objectType=comment" href="https://community.highlandarrow.com/notice/53857"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/53857"/>
|
||||
<link rel="ostatus:conversation" href="tag:gs.kawa-kun.com,2016-03-17:objectType=thread:nonce=a83963573a0520f1"/>
|
||||
<ostatus:conversation>tag:gs.kawa-kun.com,2016-03-17:objectType=thread:nonce=a83963573a0520f1</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://gs.kawa-kun.com/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1261358.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1261358.atom"/>
|
||||
<statusnet:notice_info local_id="1261358" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:24:13+01:00</id>
|
||||
<title>DIGITAL CAT (gargron)'s status on Wednesday, 16-Mar-2016 21:24:13 CET</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256972"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:24:13+00:00</published>
|
||||
<updated>2016-03-16T20:24:13+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>https://mastodon.social/users/Gargron</id>
|
||||
<title>Eugen</title>
|
||||
<summary>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</summary>
|
||||
<link rel="alternate" type="text/html" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="avatar" type="image/gif" media:width="96" media:height="96" href="https://quitter.no/avatar/15743-original-20160316180410.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="96" media:height="96" href="https://quitter.no/avatar/15743-original-20160316180410.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="48" media:height="48" href="https://quitter.no/avatar/15743-48-20160316180416.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="24" media:height="24" href="https://quitter.no/avatar/15743-24-20160316180416.gif"/>
|
||||
<poco:preferredUsername>gargron</poco:preferredUsername>
|
||||
<poco:displayName>Eugen</poco:displayName>
|
||||
<poco:note>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</poco:note>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=073bda8223dfcaa7"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=073bda8223dfcaa7</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256972.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256972.atom"/>
|
||||
<statusnet:notice_info local_id="1256972" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:22:38+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256966"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:22:38+00:00</published>
|
||||
<updated>2016-03-16T20:22:38+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:22:38+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256966"/>
|
||||
<status_net notice_id="1256966"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=b157f676181e0ecd"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=b157f676181e0ecd</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256966.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256966.atom"/>
|
||||
<statusnet:notice_info local_id="1256966" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:16:14+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256939"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:16:15+00:00</published>
|
||||
<updated>2016-03-16T20:16:15+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:16:14+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256939"/>
|
||||
<status_net notice_id="1256939"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=6a6ebd1ed6504a11"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=6a6ebd1ed6504a11</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256939.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256939.atom"/>
|
||||
<statusnet:notice_info local_id="1256939" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:13:06+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256929"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:13:06+00:00</published>
|
||||
<updated>2016-03-16T20:13:06+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:13:06+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256929"/>
|
||||
<status_net notice_id="1256929"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=8f5f92443584e8f0"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=8f5f92443584e8f0</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256929.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256929.atom"/>
|
||||
<statusnet:notice_info local_id="1256929" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:05:02+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256888"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:05:03+00:00</published>
|
||||
<updated>2016-03-16T20:05:03+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:05:02+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256888"/>
|
||||
<status_net notice_id="1256888"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=b630d235232fcff5"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=b630d235232fcff5</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256888.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256888.atom"/>
|
||||
<statusnet:notice_info local_id="1256888" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T19:04:16+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256253"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T18:04:16+00:00</published>
|
||||
<updated>2016-03-16T18:04:16+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T19:04:16+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256253"/>
|
||||
<status_net notice_id="1256253"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=40eb98e5f85c9908"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=40eb98e5f85c9908</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256253.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256253.atom"/>
|
||||
<statusnet:notice_info local_id="1256253" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1251422:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> LGB, not LGBT?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1251422"/>
|
||||
<status_net notice_id="1251422"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T20:28:13+00:00</published>
|
||||
<updated>2016-03-15T20:28:13+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-15:noticeId=51852:objectType=note" href="https://community.highlandarrow.com/notice/51852"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/51852"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-15:objectType=thread:nonce=70ff6886d69e5225"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-15:objectType=thread:nonce=70ff6886d69e5225</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1251422.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1251422.atom"/>
|
||||
<statusnet:notice_info local_id="1251422" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1250742:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://social.umeahackerspace.se/user/2" class="h-card mention" title="&lt;Mikael &amp; Nordfeldth&gt;">mmn</a> I'm like reeeeally close to actually deploying the first production instance of Mastodon, but it bugs me that there's gonna be that issue with avatars and profiles not updating :(</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1250742"/>
|
||||
<status_net notice_id="1250742"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T18:44:54+00:00</published>
|
||||
<updated>2016-03-15T18:44:54+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:social.umeahackerspace.se,2016-03-15:noticeId=424348:objectType=comment" href="https://social.umeahackerspace.se/notice/424348"></thr:in-reply-to>
|
||||
<link rel="related" href="https://social.umeahackerspace.se/notice/424348"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://social.umeahackerspace.se/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250742.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250742.atom"/>
|
||||
<statusnet:notice_info local_id="1250742" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1250653:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">@<a href="https://social.umeahackerspace.se/user/2" class="h-card mention" title="&lt;Mikael &amp; Nordfeldth&gt;">mmn</a> Any progress on the issues I created?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1250653"/>
|
||||
<status_net notice_id="1250653"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T18:27:00+00:00</published>
|
||||
<updated>2016-03-15T18:27:00+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://social.umeahackerspace.se/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250653.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250653.atom"/>
|
||||
<statusnet:notice_info local_id="1250653" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-14:noticeId=1243566:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> I heard Piwik is also good.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1243566"/>
|
||||
<status_net notice_id="1243566"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-14T15:35:23+00:00</published>
|
||||
<updated>2016-03-14T15:35:23+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-14:noticeId=50467:objectType=note" href="https://community.highlandarrow.com/notice/50467"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/50467"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-14:objectType=thread:nonce=8fbf00e7f76866d3"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-14:objectType=thread:nonce=8fbf00e7f76866d3</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243566.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243566.atom"/>
|
||||
<statusnet:notice_info local_id="1243566" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-14:noticeId=1243331:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">I do wish I had somebody else partake in the development process if only to give me feedback on my decisions</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1243331"/>
|
||||
<status_net notice_id="1243331"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-14T14:52:03+00:00</published>
|
||||
<updated>2016-03-14T14:52:03+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:quitter.no,2016-03-14:noticeId=1243309:objectType=comment" href="https://quitter.no/notice/1243309"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1243309"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-14:objectType=thread:nonce=46e8a2abc1839d01"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-14:objectType=thread:nonce=46e8a2abc1839d01</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://quitter.no/user/7477"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243331.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243331.atom"/>
|
||||
<statusnet:notice_info local_id="1243331" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
</feed>
|
19
spec/fixtures/requests/.host-meta.txt
vendored
Normal file
19
spec/fixtures/requests/.host-meta.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.6.2
|
||||
Date: Sun, 20 Mar 2016 11:11:00 GMT
|
||||
Content-Type: application/xrd+xml
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Access-Control-Allow-Origin: *
|
||||
Vary: Accept-Encoding,Cookie
|
||||
Strict-Transport-Security: max-age=31536000; includeSubdomains;
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<Link rel="lrdd" type="application/jrd+json" template="https://quitter.no/.well-known/webfinger?resource={uri}"/>
|
||||
<Link rel="lrdd" type="application/json" template="https://quitter.no/.well-known/webfinger?resource={uri}"/>
|
||||
<Link rel="lrdd" type="application/xrd+xml" template="https://quitter.no/.well-known/webfinger?resource={uri}"/>
|
||||
<Link rel="http://apinamespace.org/oauth/access_token" href="https://quitter.no/api/oauth/access_token"/>
|
||||
<Link rel="http://apinamespace.org/oauth/request_token" href="https://quitter.no/api/oauth/request_token"/>
|
||||
<Link rel="http://apinamespace.org/oauth/authorize" href="https://quitter.no/api/oauth/authorize"/>
|
||||
</XRD>
|
BIN
spec/fixtures/requests/avatar.txt
vendored
Normal file
BIN
spec/fixtures/requests/avatar.txt
vendored
Normal file
Binary file not shown.
440
spec/fixtures/requests/feed.txt
vendored
Normal file
440
spec/fixtures/requests/feed.txt
vendored
Normal file
@ -0,0 +1,440 @@
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.6.2
|
||||
Date: Sun, 20 Mar 2016 11:15:03 GMT
|
||||
Content-Type: application/atom+xml; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Access-Control-Allow-Origin: *
|
||||
Vary: Accept-Encoding,Cookie
|
||||
ETag: "ApiTimelineUser:0:en:7477:1458471931:1457967123"
|
||||
Last-Modified: Sun, 20 Mar 2016 11:05:31 +0000
|
||||
Expires: Thu, 01 Jan 1970 00:00:00 GMT
|
||||
Cache-Control: private, must-revalidate, max-age=0
|
||||
Pragma:
|
||||
X-SUP-ID: https://quitter.no/main/sup
|
||||
Strict-Transport-Security: max-age=31536000; includeSubdomains;
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
|
||||
<generator uri="https://gnu.io/social" version="1.2.0-beta4">GNU social</generator>
|
||||
<id>https://quitter.no/api/statuses/user_timeline/7477.atom</id>
|
||||
<title>gargron timeline</title>
|
||||
<subtitle>Updates from gargron on Quitter.no!</subtitle>
|
||||
<logo>https://quitter.no/avatar/7477-96-20160211190340.png</logo>
|
||||
<updated>2016-03-20T12:15:03+01:00</updated>
|
||||
<author>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<uri>https://quitter.no/user/7477</uri>
|
||||
<name>gargron</name>
|
||||
<summary>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</summary>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/gargron"/>
|
||||
<link rel="avatar" type="image/png" media:width="300" media:height="300" href="https://quitter.no/avatar/7477-300-20160211190340.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="96" media:height="96" href="https://quitter.no/avatar/7477-96-20160211190340.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="48" media:height="48" href="https://quitter.no/avatar/7477-48-20160211190449.png"/>
|
||||
<link rel="avatar" type="image/png" media:width="24" media:height="24" href="https://quitter.no/avatar/7477-24-20160211190517.png"/>
|
||||
<poco:preferredUsername>gargron</poco:preferredUsername>
|
||||
<poco:displayName>DIGITAL CAT</poco:displayName>
|
||||
<poco:note>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</poco:note>
|
||||
<poco:address>
|
||||
<poco:formatted>Germany</poco:formatted>
|
||||
</poco:address>
|
||||
<poco:urls>
|
||||
<poco:type>homepage</poco:type>
|
||||
<poco:value>https://zeonfederated.com</poco:value>
|
||||
<poco:primary>true</poco:primary>
|
||||
</poco:urls>
|
||||
<followers url="https://quitter.no/gargron/subscribers"></followers>
|
||||
<statusnet:profile_info local_id="7477"></statusnet:profile_info>
|
||||
</author>
|
||||
<link href="https://quitter.no/gargron" rel="alternate" type="text/html"/>
|
||||
<link href="https://quitter.no/main/sup" rel="http://api.friendfeed.com/2008/03#sup" type="application/json"/>
|
||||
<link href="https://quitter.no/api/statuses/user_timeline/7477.atom?max_id=1243309" rel="next" type="application/atom+xml"/>
|
||||
<link href="https://quitter.no/main/push/hub" rel="hub"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="salmon"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="http://salmon-protocol.org/ns/salmon-replies"/>
|
||||
<link href="https://quitter.no/main/salmon/user/7477" rel="http://salmon-protocol.org/ns/salmon-mention"/>
|
||||
<link href="https://quitter.no/api/statuses/user_timeline/7477.atom" rel="self" type="application/atom+xml"/>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-20:noticeId=1276923:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">@<a href="https://cb6e6126.ngrok.io/users/catsrgr8" class="h-card mention">catsrgr8</a> this is a mention</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1276923"/>
|
||||
<status_net notice_id="1276923"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-20T11:05:31+00:00</published>
|
||||
<updated>2016-03-20T11:05:31+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-20:objectType=thread:nonce=7c998112e39a6685"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-20:objectType=thread:nonce=7c998112e39a6685</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://cb6e6126.ngrok.io/users/catsrgr8"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1276923.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1276923.atom"/>
|
||||
<statusnet:notice_info local_id="1276923" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1273635:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">Just testing a thing.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1273635"/>
|
||||
<status_net notice_id="1273635"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-19T20:35:53+00:00</published>
|
||||
<updated>2016-03-19T20:35:53+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-19:objectType=thread:nonce=c4a61886d5cad4c2"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-19:objectType=thread:nonce=c4a61886d5cad4c2</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273635.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273635.atom"/>
|
||||
<statusnet:notice_info local_id="1273635" source="web"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
<title>Delete</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> deleted notice <a href="https://quitter.no/notice/1272988">{{tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note}}</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1273012"/>
|
||||
<activity:verb>delete</activity:verb>
|
||||
<published>2016-03-19T18:16:58+00:00</published>
|
||||
<updated>2016-03-19T18:16:58+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-19:objectType=thread:nonce=7913e6b6256b6d0b"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-19:objectType=thread:nonce=7913e6b6256b6d0b</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<activity:target>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1272988:objectType=note</id>
|
||||
</activity:target>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273012.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1273012.atom"/>
|
||||
<statusnet:notice_info local_id="1273012" source="unknown"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-19:noticeId=1269381:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://mastodon.social/users/Gargron" class="h-card mention" title="Eugen">gargron</a> I have to wonder if this will appear as a reply to the right status, and not just a mention.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1269381"/>
|
||||
<status_net notice_id="1269381"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-19T00:10:14+00:00</published>
|
||||
<updated>2016-03-19T00:10:14+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:mastodon.social,2016-03-18:objectId=60:objectType=Status" href="https://quitter.no/notice/1269244"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1269244"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-18:objectType=thread:nonce=d05c6330fbe23fb9"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-18:objectType=thread:nonce=d05c6330fbe23fb9</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1269381.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1269381.atom"/>
|
||||
<statusnet:notice_info local_id="1269381" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-18:noticeId=1265337:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> Plus, Android can hardly be considered free software given how many proprietary blobs are used. I'm speaking as a disappointed Android user.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1265337"/>
|
||||
<status_net notice_id="1265337"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-18T10:01:50+00:00</published>
|
||||
<updated>2016-03-18T10:01:50+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:quitter.no,2016-03-18:noticeId=1265331:objectType=comment" href="https://quitter.no/notice/1265331"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1265331"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://quitter.no/user/7477"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265337.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265337.atom"/>
|
||||
<statusnet:notice_info local_id="1265337" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-18:noticeId=1265331:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> Well as it turns out, Apple software is better than Android in terms of security, and Apple is fighting FBI while Google promised to build a messaging app that facilitates wire tapping. The whole free software thing should imo be considered a bonus and not overshadow other factors.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1265331"/>
|
||||
<status_net notice_id="1265331"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-18T10:01:01+00:00</published>
|
||||
<updated>2016-03-18T10:01:01+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-18:noticeId=54411:objectType=note" href="https://community.highlandarrow.com/notice/54411"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/54411"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-18:objectType=thread:nonce=d61438407b882959</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265331.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1265331.atom"/>
|
||||
<statusnet:notice_info local_id="1265331" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-17:noticeId=1261358:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> @<a href="https://gs.kawa-kun.com/user/2" class="h-card mention" title="&#x7AF9;&#x4E0B;&#x61B2;&#x4E8C;">takeshitakenji</a> There is a reason that was deprecated and we don't use tables to design websites anymore. HTML needs to be semantic, i.e. tags need to describe the *kind* of content, not how it should *look*, which is a responsibility delegated to CSS. There are so many upsides to this separation of concerns, should I start listing?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1261358"/>
|
||||
<status_net notice_id="1261358"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-17T17:00:26+00:00</published>
|
||||
<updated>2016-03-17T17:00:26+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-17:noticeId=53857:objectType=comment" href="https://community.highlandarrow.com/notice/53857"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/53857"/>
|
||||
<link rel="ostatus:conversation" href="tag:gs.kawa-kun.com,2016-03-17:objectType=thread:nonce=a83963573a0520f1"/>
|
||||
<ostatus:conversation>tag:gs.kawa-kun.com,2016-03-17:objectType=thread:nonce=a83963573a0520f1</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://gs.kawa-kun.com/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1261358.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1261358.atom"/>
|
||||
<statusnet:notice_info local_id="1261358" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:24:13+01:00</id>
|
||||
<title>DIGITAL CAT (gargron)'s status on Wednesday, 16-Mar-2016 21:24:13 CET</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256972"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:24:13+00:00</published>
|
||||
<updated>2016-03-16T20:24:13+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>https://mastodon.social/users/Gargron</id>
|
||||
<title>Eugen</title>
|
||||
<summary>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</summary>
|
||||
<link rel="alternate" type="text/html" href="https://mastodon.social/users/Gargron"/>
|
||||
<link rel="avatar" type="image/gif" media:width="96" media:height="96" href="https://quitter.no/avatar/15743-original-20160316180410.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="96" media:height="96" href="https://quitter.no/avatar/15743-original-20160316180410.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="48" media:height="48" href="https://quitter.no/avatar/15743-48-20160316180416.gif"/>
|
||||
<link rel="avatar" type="image/gif" media:width="24" media:height="24" href="https://quitter.no/avatar/15743-24-20160316180416.gif"/>
|
||||
<poco:preferredUsername>gargron</poco:preferredUsername>
|
||||
<poco:displayName>Eugen</poco:displayName>
|
||||
<poco:note>Software engineer, free time musician and DIGITAL SPORTS enthusiast. Likes cats. Warning: May contain memes</poco:note>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=073bda8223dfcaa7"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=073bda8223dfcaa7</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256972.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256972.atom"/>
|
||||
<statusnet:notice_info local_id="1256972" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:22:38+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256966"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:22:38+00:00</published>
|
||||
<updated>2016-03-16T20:22:38+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:22:38+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256966"/>
|
||||
<status_net notice_id="1256966"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=b157f676181e0ecd"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=b157f676181e0ecd</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256966.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256966.atom"/>
|
||||
<statusnet:notice_info local_id="1256966" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:16:14+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256939"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:16:15+00:00</published>
|
||||
<updated>2016-03-16T20:16:15+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T21:16:14+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256939"/>
|
||||
<status_net notice_id="1256939"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=6a6ebd1ed6504a11"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=6a6ebd1ed6504a11</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256939.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256939.atom"/>
|
||||
<statusnet:notice_info local_id="1256939" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:13:06+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256929"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:13:06+00:00</published>
|
||||
<updated>2016-03-16T20:13:06+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:13:06+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256929"/>
|
||||
<status_net notice_id="1256929"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=8f5f92443584e8f0"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=8f5f92443584e8f0</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256929.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256929.atom"/>
|
||||
<statusnet:notice_info local_id="1256929" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:05:02+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256888"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T20:05:03+00:00</published>
|
||||
<updated>2016-03-16T20:05:03+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15750:2016-03-16T21:05:02+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://acda7931.ngrok.io/users/catsrgr8">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256888"/>
|
||||
<status_net notice_id="1256888"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=b630d235232fcff5"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=b630d235232fcff5</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256888.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256888.atom"/>
|
||||
<statusnet:notice_info local_id="1256888" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T19:04:16+01:00</id>
|
||||
<title></title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256253"/>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/follow</activity:verb>
|
||||
<published>2016-03-16T18:04:16+00:00</published>
|
||||
<updated>2016-03-16T18:04:16+00:00</updated>
|
||||
<activity:object>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-16:subscription:7477:person:15743:2016-03-16T19:04:16+01:00</id>
|
||||
<title>New person by gargron</title>
|
||||
<content type="html"><a href="https://quitter.no/gargron">DIGITAL CAT</a> started following <a href="https://mastodon.social/users/Gargron">Eugen</a>.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1256253"/>
|
||||
<status_net notice_id="1256253"></status_net>
|
||||
</activity:object>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-16:objectType=thread:nonce=40eb98e5f85c9908"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-16:objectType=thread:nonce=40eb98e5f85c9908</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256253.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1256253.atom"/>
|
||||
<statusnet:notice_info local_id="1256253" source="activity"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1251422:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> LGB, not LGBT?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1251422"/>
|
||||
<status_net notice_id="1251422"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T20:28:13+00:00</published>
|
||||
<updated>2016-03-15T20:28:13+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-15:noticeId=51852:objectType=note" href="https://community.highlandarrow.com/notice/51852"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/51852"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-15:objectType=thread:nonce=70ff6886d69e5225"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-15:objectType=thread:nonce=70ff6886d69e5225</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1251422.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1251422.atom"/>
|
||||
<statusnet:notice_info local_id="1251422" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1250742:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://social.umeahackerspace.se/user/2" class="h-card mention" title="&lt;Mikael &amp; Nordfeldth&gt;">mmn</a> I'm like reeeeally close to actually deploying the first production instance of Mastodon, but it bugs me that there's gonna be that issue with avatars and profiles not updating :(</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1250742"/>
|
||||
<status_net notice_id="1250742"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T18:44:54+00:00</published>
|
||||
<updated>2016-03-15T18:44:54+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:social.umeahackerspace.se,2016-03-15:noticeId=424348:objectType=comment" href="https://social.umeahackerspace.se/notice/424348"></thr:in-reply-to>
|
||||
<link rel="related" href="https://social.umeahackerspace.se/notice/424348"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://social.umeahackerspace.se/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250742.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250742.atom"/>
|
||||
<statusnet:notice_info local_id="1250742" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-15:noticeId=1250653:objectType=note</id>
|
||||
<title>New note by gargron</title>
|
||||
<content type="html">@<a href="https://social.umeahackerspace.se/user/2" class="h-card mention" title="&lt;Mikael &amp; Nordfeldth&gt;">mmn</a> Any progress on the issues I created?</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1250653"/>
|
||||
<status_net notice_id="1250653"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-15T18:27:00+00:00</published>
|
||||
<updated>2016-03-15T18:27:00+00:00</updated>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-15:objectType=thread:nonce=2fbd771270b5da80</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://social.umeahackerspace.se/user/2"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250653.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1250653.atom"/>
|
||||
<statusnet:notice_info local_id="1250653" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-14:noticeId=1243566:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">@<a href="https://community.highlandarrow.com/user/1" class="h-card mention" title="Maiyannah Bishop">maiyannah</a> I heard Piwik is also good.</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1243566"/>
|
||||
<status_net notice_id="1243566"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-14T15:35:23+00:00</published>
|
||||
<updated>2016-03-14T15:35:23+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:community.highlandarrow.com,2016-03-14:noticeId=50467:objectType=note" href="https://community.highlandarrow.com/notice/50467"></thr:in-reply-to>
|
||||
<link rel="related" href="https://community.highlandarrow.com/notice/50467"/>
|
||||
<link rel="ostatus:conversation" href="tag:community.highlandarrow.com,2016-03-14:objectType=thread:nonce=8fbf00e7f76866d3"/>
|
||||
<ostatus:conversation>tag:community.highlandarrow.com,2016-03-14:objectType=thread:nonce=8fbf00e7f76866d3</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://community.highlandarrow.com/user/1"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243566.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243566.atom"/>
|
||||
<statusnet:notice_info local_id="1243566" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
<entry>
|
||||
<activity:object-type>http://activitystrea.ms/schema/1.0/comment</activity:object-type>
|
||||
<id>tag:quitter.no,2016-03-14:noticeId=1243331:objectType=comment</id>
|
||||
<title>New comment by gargron</title>
|
||||
<content type="html">I do wish I had somebody else partake in the development process if only to give me feedback on my decisions</content>
|
||||
<link rel="alternate" type="text/html" href="https://quitter.no/notice/1243331"/>
|
||||
<status_net notice_id="1243331"></status_net>
|
||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||
<published>2016-03-14T14:52:03+00:00</published>
|
||||
<updated>2016-03-14T14:52:03+00:00</updated>
|
||||
<thr:in-reply-to ref="tag:quitter.no,2016-03-14:noticeId=1243309:objectType=comment" href="https://quitter.no/notice/1243309"></thr:in-reply-to>
|
||||
<link rel="related" href="https://quitter.no/notice/1243309"/>
|
||||
<link rel="ostatus:conversation" href="tag:quitter.no,2016-03-14:objectType=thread:nonce=46e8a2abc1839d01"/>
|
||||
<ostatus:conversation>tag:quitter.no,2016-03-14:objectType=thread:nonce=46e8a2abc1839d01</ostatus:conversation>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/person" href="https://quitter.no/user/7477"/>
|
||||
<link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
|
||||
<link rel="self" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243331.atom"/>
|
||||
<link rel="edit" type="application/atom+xml" href="https://quitter.no/api/statuses/show/1243331.atom"/>
|
||||
<statusnet:notice_info local_id="1243331" source="Qvitter"></statusnet:notice_info>
|
||||
</entry>
|
||||
</feed>
|
11
spec/fixtures/requests/webfinger.txt
vendored
Normal file
11
spec/fixtures/requests/webfinger.txt
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx/1.6.2
|
||||
Date: Sun, 20 Mar 2016 11:13:16 GMT
|
||||
Content-Type: application/jrd+json
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Access-Control-Allow-Origin: *
|
||||
Vary: Accept-Encoding,Cookie
|
||||
Strict-Transport-Security: max-age=31536000; includeSubdomains;
|
||||
|
||||
{"subject":"acct:gargron@quitter.no","aliases":["https:\/\/quitter.no\/user\/7477","https:\/\/quitter.no\/gargron","https:\/\/quitter.no\/index.php\/user\/7477","https:\/\/quitter.no\/index.php\/gargron"],"links":[{"rel":"http:\/\/webfinger.net\/rel\/profile-page","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/gmpg.org\/xfn\/11","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"describedby","type":"application\/rdf+xml","href":"https:\/\/quitter.no\/gargron\/foaf"},{"rel":"http:\/\/apinamespace.org\/atom","type":"application\/atomsvc+xml","href":"https:\/\/quitter.no\/api\/statusnet\/app\/service\/gargron.xml"},{"rel":"http:\/\/apinamespace.org\/twitter","href":"https:\/\/quitter.no\/api\/"},{"rel":"http:\/\/specs.openid.net\/auth\/2.0\/provider","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/schemas.google.com\/g\/2010#updates-from","type":"application\/atom+xml","href":"https:\/\/quitter.no\/api\/statuses\/user_timeline\/7477.atom"},{"rel":"magic-public-key","href":"data:application\/magic-public-key,RSA.1ZBkHTavLvxH3FzlKv4O6WtlILKRFfNami3_Rcu8EuogtXSYiS-bB6hElZfUCSHbC4uLemOA34PEhz__CDMozax1iI_t8dzjDnh1x0iFSup7pSfW9iXk_WU3Dm74yWWW2jildY41vWgrEstuQ1dJ8vVFfSJ9T_tO4c-T9y8vDI8=.AQAB"},{"rel":"salmon","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-replies","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-mention","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/ostatus.org\/schema\/1.0\/subscribe","template":"https:\/\/quitter.no\/main\/ostatussub?profile={uri}"}]}
|
2
spec/fixtures/salmon/mention.xml
vendored
Normal file
2
spec/fixtures/salmon/mention.xml
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the AccountsHelper. For example:
|
||||
#
|
||||
# describe AccountsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe AccountsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Api::AccountsHelper. For example:
|
||||
#
|
||||
# describe Api::AccountsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Api::AccountsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Api::FollowsHelper. For example:
|
||||
#
|
||||
# describe Api::FollowsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Api::FollowsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Api::SalmonHelper. For example:
|
||||
#
|
||||
# describe Api::SalmonHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Api::SalmonHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Api::StatusesHelper. For example:
|
||||
#
|
||||
# describe Api::StatusesHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Api::StatusesHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Api::SubscriptionsHelper. For example:
|
||||
#
|
||||
# describe Api::SubscriptionsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Api::SubscriptionsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -28,4 +28,8 @@ RSpec.describe ApplicationHelper, type: :helper do
|
||||
expect(helper.local_id?('tag:foreign.tld;objectId=12:objectType=Status')).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#linkify' do
|
||||
pending
|
||||
end
|
||||
end
|
||||
|
@ -6,95 +6,148 @@ RSpec.describe AtomBuilderHelper, type: :helper do
|
||||
end
|
||||
|
||||
describe '#entry' do
|
||||
pending
|
||||
it 'creates an entry' do
|
||||
expect(used_in_builder { |xml| helper.entry(xml) }).to match '<entry/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#feed' do
|
||||
pending
|
||||
it 'creates a feed' do
|
||||
expect(used_in_builder { |xml| helper.feed(xml) }).to match '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:media="http://purl.org/syndication/atommedia"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#unique_id' do
|
||||
pending
|
||||
it 'creates an id' do
|
||||
time = Time.now
|
||||
expect(used_in_builder { |xml| helper.unique_id(xml, time, 1, 'Status') }).to match "<id>#{helper.unique_tag(time, 1, 'Status')}</id>"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#simple_id' do
|
||||
pending
|
||||
it 'creates an id' do
|
||||
expect(used_in_builder { |xml| helper.simple_id(xml, 1) }).to match '<id>1</id>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#published_at' do
|
||||
pending
|
||||
it 'creates a published tag' do
|
||||
time = Time.now
|
||||
expect(used_in_builder { |xml| helper.published_at(xml, time) }).to match "<published>#{time.iso8601}</published>"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#updated_at' do
|
||||
pending
|
||||
it 'creates an updated tag' do
|
||||
time = Time.now
|
||||
expect(used_in_builder { |xml| helper.updated_at(xml, time) }).to match "<updated>#{time.iso8601}</updated>"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#verb' do
|
||||
pending
|
||||
it 'creates an entry' do
|
||||
expect(used_with_namespaces { |xml| helper.verb(xml, 'verb') }).to match '<activity:verb>http://activitystrea.ms/schema/1.0/verb</activity:verb>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#content' do
|
||||
pending
|
||||
it 'creates a content' do
|
||||
expect(used_in_builder { |xml| helper.content(xml, 'foo') }).to match '<content type="html">foo</content>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#title' do
|
||||
pending
|
||||
it 'creates a title' do
|
||||
expect(used_in_builder { |xml| helper.title(xml, 'foo') }).to match '<title>foo</title>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#author' do
|
||||
pending
|
||||
it 'creates an author' do
|
||||
expect(used_in_builder { |xml| helper.author(xml) }).to match '<author/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#target' do
|
||||
pending
|
||||
it 'creates a target' do
|
||||
expect(used_with_namespaces { |xml| helper.target(xml) }).to match '<activity:object/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#object_type' do
|
||||
pending
|
||||
it 'creates an object type' do
|
||||
expect(used_with_namespaces { |xml| helper.object_type(xml, 'test') }).to match '<activity:object-type>http://activitystrea.ms/schema/1.0/test</activity:object-type>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uri' do
|
||||
pending
|
||||
it 'creates a uri' do
|
||||
expect(used_in_builder { |xml| helper.uri(xml, 1) }).to match '<uri>1</uri>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#name' do
|
||||
pending
|
||||
it 'creates a name' do
|
||||
expect(used_in_builder { |xml| helper.name(xml, 1) }).to match '<name>1</name>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#summary' do
|
||||
pending
|
||||
it 'creates a summary' do
|
||||
expect(used_in_builder { |xml| helper.summary(xml, 1) }).to match '<summary>1</summary>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#subtitle' do
|
||||
pending
|
||||
it 'creates a subtitle' do
|
||||
expect(used_in_builder { |xml| helper.subtitle(xml, 1) }).to match '<subtitle>1</subtitle>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link_alternate' do
|
||||
pending
|
||||
it 'creates a link' do
|
||||
expect(used_in_builder { |xml| helper.link_alternate(xml, 1) }).to match '<link rel="alternate" type="text/html" href="1"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link_self' do
|
||||
pending
|
||||
it 'creates a link' do
|
||||
expect(used_in_builder { |xml| helper.link_self(xml, 1) }).to match '<link rel="self" type="application/atom+xml" href="1"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link_hub' do
|
||||
pending
|
||||
it 'creates a link' do
|
||||
expect(used_in_builder { |xml| helper.link_hub(xml, 1) }).to match '<link rel="hub" href="1"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link_salmon' do
|
||||
pending
|
||||
it 'creates a link' do
|
||||
expect(used_in_builder { |xml| helper.link_salmon(xml, 1) }).to match '<link rel="salmon" href="1"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#portable_contact' do
|
||||
pending
|
||||
let(:account) { Fabricate(:account, username: 'alice', display_name: 'Alice in Wonderland') }
|
||||
|
||||
it 'creates portable contacts entries' do
|
||||
expect(used_with_namespaces { |xml| helper.portable_contact(xml, account) }).to match '<poco:displayName>Alice in Wonderland</poco:displayName>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#in_reply_to' do
|
||||
pending
|
||||
it 'creates a thread' do
|
||||
expect(used_with_namespaces { |xml| helper.in_reply_to(xml, 'uri', 'url') }).to match '<thr:in-reply-to ref="uri" href="url" type="text/html"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link_mention' do
|
||||
pending
|
||||
let(:account) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it 'creates a link' do
|
||||
expect(used_in_builder { |xml| helper.link_mention(xml, account) }).to match '<link rel="mentioned" href="http://test.host/users/alice"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#disambiguate_uri' do
|
||||
@ -114,10 +167,25 @@ RSpec.describe AtomBuilderHelper, type: :helper do
|
||||
end
|
||||
|
||||
describe '#link_avatar' do
|
||||
pending
|
||||
let(:account) { Fabricate(:account, username: 'alice') }
|
||||
|
||||
it 'creates a link' do
|
||||
expect(used_with_namespaces { |xml| helper.link_avatar(xml, account) }).to match '<link rel="avatar" type="" media:width="300" media:height="300" href="http://test.host/assets/avatars/missing.png"/>'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#logo' do
|
||||
pending
|
||||
it 'creates a logo' do
|
||||
expect(used_in_builder { |xml| helper.logo(xml, 1) }).to match '<logo>1</logo>'
|
||||
end
|
||||
end
|
||||
|
||||
def used_in_builder(&block)
|
||||
builder = Nokogiri::XML::Builder.new(&block)
|
||||
builder.doc.root.to_xml
|
||||
end
|
||||
|
||||
def used_with_namespaces(&block)
|
||||
used_in_builder { |xml| helper.entry(xml, true, &block) }
|
||||
end
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the Oauth::ApplicationsHelper. For example:
|
||||
#
|
||||
# describe Oauth::ApplicationsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe Oauth::ApplicationsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -1,15 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the SettingsHelper. For example:
|
||||
#
|
||||
# describe SettingsHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
RSpec.describe SettingsHelper, type: :helper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
|
||||
end
|
||||
|
@ -16,4 +16,12 @@ RSpec.describe StreamEntriesHelper, type: :helper do
|
||||
describe '#relative_time' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#reblogged_by_me_class' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#favourited_by_me_class' do
|
||||
pending
|
||||
end
|
||||
end
|
||||
|
61
spec/mailers/notification_mailer_spec.rb
Normal file
61
spec/mailers/notification_mailer_spec.rb
Normal file
@ -0,0 +1,61 @@
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe NotificationMailer, type: :mailer do
|
||||
let(:receiver) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
|
||||
let(:sender) { Fabricate(:account, username: 'bob') }
|
||||
let(:foreign_status) { Fabricate(:status, account: sender) }
|
||||
let(:own_status) { Fabricate(:status, account: receiver.account) }
|
||||
|
||||
describe "mention" do
|
||||
let(:mail) { NotificationMailer.mention(receiver.account, foreign_status) }
|
||||
|
||||
it "renders the headers" do
|
||||
expect(mail.subject).to eq("You were mentioned by bob")
|
||||
expect(mail.to).to eq([receiver.email])
|
||||
end
|
||||
|
||||
it "renders the body" do
|
||||
expect(mail.body.encoded).to match("You were mentioned by bob")
|
||||
end
|
||||
end
|
||||
|
||||
describe "follow" do
|
||||
let(:mail) { NotificationMailer.follow(receiver.account, sender) }
|
||||
|
||||
it "renders the headers" do
|
||||
expect(mail.subject).to eq("bob is now following you")
|
||||
expect(mail.to).to eq([receiver.email])
|
||||
end
|
||||
|
||||
it "renders the body" do
|
||||
expect(mail.body.encoded).to match("bob is now following you")
|
||||
end
|
||||
end
|
||||
|
||||
describe "favourite" do
|
||||
let(:mail) { NotificationMailer.favourite(own_status, sender) }
|
||||
|
||||
it "renders the headers" do
|
||||
expect(mail.subject).to eq("bob favourited your status")
|
||||
expect(mail.to).to eq([receiver.email])
|
||||
end
|
||||
|
||||
it "renders the body" do
|
||||
expect(mail.body.encoded).to match("Your status was favourited by bob")
|
||||
end
|
||||
end
|
||||
|
||||
describe "reblog" do
|
||||
let(:mail) { NotificationMailer.reblog(own_status, sender) }
|
||||
|
||||
it "renders the headers" do
|
||||
expect(mail.subject).to eq("bob reblogged your status")
|
||||
expect(mail.to).to eq([receiver.email])
|
||||
end
|
||||
|
||||
it "renders the body" do
|
||||
expect(mail.body.encoded).to match("Your status was reblogged by bob")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
24
spec/mailers/previews/notification_mailer_preview.rb
Normal file
24
spec/mailers/previews/notification_mailer_preview.rb
Normal file
@ -0,0 +1,24 @@
|
||||
# Preview all emails at http://localhost:3000/rails/mailers/notification_mailer
|
||||
class NotificationMailerPreview < ActionMailer::Preview
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/notification_mailer/mention
|
||||
def mention
|
||||
# NotificationMailer.mention
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/notification_mailer/follow
|
||||
def follow
|
||||
# NotificationMailer.follow
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/notification_mailer/favourite
|
||||
def favourite
|
||||
# NotificationMailer.favourite
|
||||
end
|
||||
|
||||
# Preview this email at http://localhost:3000/rails/mailers/notification_mailer/reblog
|
||||
def reblog
|
||||
# NotificationMailer.reblog
|
||||
end
|
||||
|
||||
end
|
@ -111,4 +111,16 @@ RSpec.describe Account, type: :model do
|
||||
describe '#ping!' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#favourited?' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#reblogged?' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '.find_local' do
|
||||
pending
|
||||
end
|
||||
end
|
||||
|
7
spec/models/feed_spec.rb
Normal file
7
spec/models/feed_spec.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Feed, type: :model do
|
||||
describe '#get' do
|
||||
pending
|
||||
end
|
||||
end
|
@ -114,4 +114,12 @@ RSpec.describe Status, type: :model do
|
||||
expect(subject.target).to eq other
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reblogs_count' do
|
||||
pending
|
||||
end
|
||||
|
||||
describe '#favourites_count' do
|
||||
pending
|
||||
end
|
||||
end
|
||||
|
@ -19,3 +19,7 @@ RSpec.configure do |config|
|
||||
config.include Devise::TestHelpers, type: :controller
|
||||
config.include Devise::TestHelpers, type: :view
|
||||
end
|
||||
|
||||
def request_fixture(name)
|
||||
File.read(File.join(Rails.root, 'spec', 'fixtures', 'requests', name))
|
||||
end
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user