Merge branch 'insularity-score' into 'develop'

add Insularity score

See merge request taobojlen/fediverse.space!54
This commit is contained in:
Tao Bojlén 2019-07-18 15:20:09 +00:00
commit b145ac7160
8 changed files with 73 additions and 23 deletions

View file

@ -1,9 +1,13 @@
# fediverse.space 🌐 # fediverse.space 🌐
The map of the fediverse that you always wanted. The map of the fediverse that you always wanted.
Read the latest updates on Mastodon: [@fediversespace](https://cursed.technology/@fediversespace)
![A screenshot of fediverse.space](screenshot.png) ![A screenshot of fediverse.space](screenshot.png)
## Requirements ## Requirements
- For the scraper + API: - For the scraper + API:
- Elixir - Elixir
- Postgres - Postgres
@ -16,24 +20,31 @@ The map of the fediverse that you always wanted.
All of the above can also be run through Docker with `docker-compose`. All of the above can also be run through Docker with `docker-compose`.
## Running it ## Running it
### Backend ### Backend
- `cp example.env .env` and modify environment variables as required - `cp example.env .env` and modify environment variables as required
- `docker-compose build` - `docker-compose build`
- `docker-compose up -d phoenix` - `docker-compose up -d phoenix`
- if you don't specify `phoenix`, it'll also start `gephi` which should only be run as a regular one-off job - if you don't specify `phoenix`, it'll also start `gephi` which should only be run as a regular one-off job
### Frontend ### Frontend
- `cd frontend && yarn install` - `cd frontend && yarn install`
- `yarn start` - `yarn start`
## Commands ## Commands
### Backend ### Backend
After running the backend in Docker: After running the backend in Docker:
- `docker-compose run gephi java -Xmx1g -jar build/libs/graphBuilder.jar` lays out the graph - `docker-compose run gephi java -Xmx1g -jar build/libs/graphBuilder.jar` lays out the graph
`./gradlew shadowJar` compiles the graph layout program. `java -Xmx1g -jar build/libs/graphBuilder.jar` runs it. `./gradlew shadowJar` compiles the graph layout program. `java -Xmx1g -jar build/libs/graphBuilder.jar` runs it.
### Frontend ### Frontend
- `yarn build` to create an optimized build for deployment - `yarn build` to create an optimized build for deployment
### Acknowledgements ### Acknowledgements

View file

@ -44,7 +44,9 @@ config :backend, Backend.Scheduler,
# At midnight every day # At midnight every day
{"@daily", {Backend.Scheduler, :prune_crawls, [1, "month"]}}, {"@daily", {Backend.Scheduler, :prune_crawls, [1, "month"]}},
# 00.15 daily # 00.15 daily
{"15 0 * * *", {Backend.Scheduler, :generate_edges, []}} {"15 0 * * *", {Backend.Scheduler, :generate_edges, []}},
# 00.30 every night
{"30 0 * * *", {Backend.Scheduler, :generate_insularity_scores, []}}
] ]
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom

View file

@ -35,6 +35,7 @@ defmodule BackendWeb.InstanceView do
description: instance.description, description: instance.description,
version: instance.version, version: instance.version,
userCount: instance.user_count, userCount: instance.user_count,
insularity: instance.insularity,
statusCount: instance.status_count, statusCount: instance.status_count,
domainCount: length(instance.peers), domainCount: length(instance.peers),
peers: render_many(instance.peers, InstanceView, "instance.json"), peers: render_many(instance.peers, InstanceView, "instance.json"),

View file

@ -38,6 +38,7 @@
"lodash": "^4.17.14", "lodash": "^4.17.14",
"moment": "^2.22.2", "moment": "^2.22.2",
"normalize.css": "^8.0.0", "normalize.css": "^8.0.0",
"numeral": "^2.0.6",
"react": "^16.4.2", "react": "^16.4.2",
"react-dom": "^16.4.2", "react-dom": "^16.4.2",
"react-redux": "^7.1.0", "react-redux": "^7.1.0",
@ -57,6 +58,7 @@
"@types/jest": "^24.0.15", "@types/jest": "^24.0.15",
"@types/lodash": "^4.14.136", "@types/lodash": "^4.14.136",
"@types/node": "^12.6.2", "@types/node": "^12.6.2",
"@types/numeral": "^0.0.25",
"@types/react": "^16.8.23", "@types/react": "^16.8.23",
"@types/react-dom": "^16.8.4", "@types/react-dom": "^16.8.4",
"@types/react-redux": "^7.1.1", "@types/react-redux": "^7.1.1",

View file

@ -1,5 +1,6 @@
import { orderBy } from "lodash"; import { orderBy } from "lodash";
import moment from "moment"; import moment from "moment";
import * as numeral from "numeral";
import * as React from "react"; import * as React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Dispatch } from "redux"; import { Dispatch } from "redux";
@ -16,6 +17,7 @@ import {
H2, H2,
H4, H4,
HTMLTable, HTMLTable,
Icon,
NonIdealState, NonIdealState,
Position, Position,
Tab, Tab,
@ -138,11 +140,10 @@ class SidebarImpl extends React.Component<ISidebarProps, ISidebarState> {
}; };
private renderVersionAndCounts = () => { private renderVersionAndCounts = () => {
const version = this.props.instanceDetails!.version; if (!this.props.instanceDetails) {
const userCount = this.props.instanceDetails!.userCount; throw new Error("Did not receive instance details as expected!");
const statusCount = this.props.instanceDetails!.statusCount; }
const domainCount = this.props.instanceDetails!.domainCount; const { version, userCount, statusCount, domainCount, lastUpdated, insularity } = this.props.instanceDetails;
const lastUpdated = this.props.instanceDetails!.lastUpdated;
return ( return (
<div> <div>
<HTMLTable small={true} striped={true} className="fediverse-sidebar-table"> <HTMLTable small={true} striped={true} className="fediverse-sidebar-table">
@ -153,15 +154,34 @@ class SidebarImpl extends React.Component<ISidebarProps, ISidebarState> {
</tr> </tr>
<tr> <tr>
<td>Users</td> <td>Users</td>
<td>{userCount || "Unknown"}</td> <td>{(userCount && numeral.default(userCount).format("0,0")) || "Unknown"}</td>
</tr> </tr>
<tr> <tr>
<td>Statuses</td> <td>Statuses</td>
<td>{statusCount || "Unknown"}</td> <td>{(statusCount && numeral.default(statusCount).format("0,0")) || "Unknown"}</td>
</tr>
<tr>
<td>
Insularity{" "}
<Tooltip
content={
<span>
The percentage of mentions that are directed
<br />
toward users on the same instance.
</span>
}
position={Position.TOP}
className={Classes.DARK}
>
<Icon icon={IconNames.HELP} iconSize={Icon.SIZE_STANDARD} />
</Tooltip>
</td>
<td>{(insularity && numeral.default(insularity).format("0.0%")) || "Unknown"}</td>
</tr> </tr>
<tr> <tr>
<td>Known peers</td> <td>Known peers</td>
<td>{domainCount || "Unknown"}</td> <td>{(domainCount && numeral.default(domainCount).format("0,0")) || "Unknown"}</td>
</tr> </tr>
<tr> <tr>
<td>Last updated</td> <td>Last updated</td>

View file

@ -7,7 +7,7 @@ export const AboutScreen: React.FC = () => (
<H1>About</H1> <H1>About</H1>
<p className={Classes.RUNNING_TEXT}> <p className={Classes.RUNNING_TEXT}>
fediverse.space is a tool to visualize networks and communities on the{" "} fediverse.space is a tool to visualize networks and communities on the{" "}
<a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank"> <a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank" rel="noopener noreferrer">
fediverse fediverse
</a> </a>
. It works by crawling every instance it can find and aggregating statistics on communication between these. . It works by crawling every instance it can find and aggregating statistics on communication between these.
@ -26,7 +26,7 @@ export const AboutScreen: React.FC = () => (
</H4> </H4>
<p className={Classes.RUNNING_TEXT}> <p className={Classes.RUNNING_TEXT}>
Check out{" "} Check out{" "}
<a href="https://gitlab.com/taobojlen/fediverse.space/issues/24" target="_blank"> <a href="https://gitlab.com/taobojlen/fediverse.space/issues/24" target="_blank" rel="noopener noreferrer">
this GitLab issue this GitLab issue
</a> </a>
. .
@ -35,7 +35,7 @@ export const AboutScreen: React.FC = () => (
<H4>How do I add my personal instance?</H4> <H4>How do I add my personal instance?</H4>
<p className={Classes.RUNNING_TEXT}> <p className={Classes.RUNNING_TEXT}>
Send a DM to{" "} Send a DM to{" "}
<a href="https://cursed.technology/@fediversespace" target="_blank"> <a href="https://cursed.technology/@fediversespace" target="_blank" rel="noopener noreferrer">
@fediversespace @fediversespace
</a>{" "} </a>{" "}
on Mastodon. Make sure to send it from the account that's listed as the instance admin. on Mastodon. Make sure to send it from the account that's listed as the instance admin.
@ -54,27 +54,31 @@ export const AboutScreen: React.FC = () => (
This site is inspired by several other sites in the same vein: This site is inspired by several other sites in the same vein:
<ul className={Classes.LIST}> <ul className={Classes.LIST}>
<li> <li>
<a href="https://the-federation.info/" target="_blank"> <a href="https://the-federation.info/" target="_blank" rel="noopener noreferrer">
the-federation.info the-federation.info
</a> </a>
</li> </li>
<li> <li>
<a href="http://fediverse.network/" target="_blank"> <a href="http://fediverse.network/" target="_blank" rel="noopener noreferrer">
fediverse.network fediverse.network
</a> </a>
</li> </li>
<li> <li>
<a href="https://lucahammer.at/vis/fediverse/2018-08-30-mastoverse_hashtags/" target="_blank"> <a
href="https://lucahammer.at/vis/fediverse/2018-08-30-mastoverse_hashtags/"
target="_blank"
rel="noopener noreferrer"
>
Mastodon hashtag network Mastodon hashtag network
</a> </a>
{" by "} {" by "}
<a href="https://vis.social/web/statuses/100634284168959187" target="_blank"> <a href="https://vis.social/web/statuses/100634284168959187" target="_blank" rel="noopener noreferrer">
@Luca@vis.social @Luca@vis.social
</a> </a>
</li> </li>
</ul> </ul>
The source code for fediverse.space is available on{" "} The source code for fediverse.space is available on{" "}
<a href="https://gitlab.com/taobojlen/fediverse.space" target="_blank"> <a href="https://gitlab.com/taobojlen/fediverse.space" target="_blank" rel="noopener noreferrer">
GitLab GitLab
</a> </a>
; issues and pull requests are welcome! ; issues and pull requests are welcome!

View file

@ -17,17 +17,17 @@ export interface IAction {
export interface IInstance { export interface IInstance {
name: string; name: string;
numUsers?: number;
} }
export interface IInstanceDetails { export interface IInstanceDetails {
name: string; name: string;
peers?: IInstance[];
description?: string; description?: string;
domainCount?: number;
statusCount?: number;
userCount?: number;
version?: string; version?: string;
userCount?: number;
insularity?: number;
statusCount?: number;
domainCount?: number;
peers?: IInstance[];
lastUpdated?: string; lastUpdated?: string;
status: string; status: string;
} }

View file

@ -1433,6 +1433,11 @@
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/numeral@^0.0.25":
version "0.0.25"
resolved "https://registry.yarnpkg.com/@types/numeral/-/numeral-0.0.25.tgz#b6f55062827a4787fe4ab151cf3412a468e65271"
integrity sha512-ShHzHkYD+Ldw3eyttptCpUhF1/mkInWwasQkCNXZHOsJMJ/UMa8wXrxSrTJaVk0r4pLK/VnESVM0wFsfQzNEKQ==
"@types/prop-types@*": "@types/prop-types@*":
version "15.7.0" version "15.7.0"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.0.tgz#4c48fed958d6dcf9487195a0ef6456d5f6e0163a" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.0.tgz#4c48fed958d6dcf9487195a0ef6456d5f6e0163a"
@ -7336,6 +7341,11 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
numeral@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506"
integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY=
nwsapi@^2.0.7: nwsapi@^2.0.7:
version "2.1.3" version "2.1.3"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558"