mirror of
https://github.com/samsonjs/mit-license.git
synced 2026-03-25 09:25:49 +00:00
Complete API
This commit is contained in:
parent
ded72c6140
commit
0b0afb9a83
7 changed files with 85 additions and 207 deletions
|
|
@ -13,7 +13,8 @@
|
|||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
"sourceType": "module",
|
||||
"warnOnUnsupportedTypeScriptVersion": false
|
||||
},
|
||||
"rules": {
|
||||
"indent": ["error", 4],
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -192,15 +192,22 @@ The following types of requests can be made to this project:
|
|||
- <http://rem.mit-license.org/license.html> HTML
|
||||
- <http://rem.mit-license.org/license.txt> Text
|
||||
|
||||
The url also supports including a start year:
|
||||
The URL also supports including a start year:
|
||||
|
||||
- <http://rem.mit-license.org/2009/> will
|
||||
show a license year range of 2009-2016 (2016 being the current year)
|
||||
- [http://rem.mit-license.org/2009-2010](http://rem.mit-license.org/2009-2010/)
|
||||
- <http://rem.mit-license.org/2009-2010>
|
||||
allows me to force the year range
|
||||
- <http://rem.mit-license.org/2009-2010/license.txt> year range of 2009-2010 in plain text
|
||||
|
||||
Finally, the url also supports pinning the year
|
||||
You can also specify either the `MIT` or `ISC` license in the URL:
|
||||
|
||||
- <http://rem.mit-license.org/+MIT> will
|
||||
show the MIT License (default)
|
||||
- <http://rem.mit-license.org/+ISC>
|
||||
shows the ISC license instead
|
||||
|
||||
Finally, the URL also supports pinning the year
|
||||
|
||||
- <http://rem.mit-license.org/@2009>
|
||||
this is useful for when your software copyright should expire ([as discussed here](https://github.com/remy/mit-license/issues/771))
|
||||
|
|
|
|||
165
index.php
165
index.php
|
|
@ -1,165 +0,0 @@
|
|||
<?php
|
||||
|
||||
date_default_timezone_set('Europe/London'); // stop php from whining
|
||||
|
||||
$format = 'html';
|
||||
$theme = 'default';
|
||||
$cname = '';
|
||||
|
||||
// use a match instead of preg_replace to ensure we got the cname
|
||||
preg_match('/^([a-z0-9\-]+)\.mit-license\..*$/', $_SERVER['HTTP_HOST'], $match);
|
||||
|
||||
if (count($match) == 2) {
|
||||
$cname = $match[1];
|
||||
}
|
||||
|
||||
$user_file = 'users/' . $cname . '.json';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $cname) {
|
||||
echo ('>>> curl API has been temporarily disabled. Please send a pull request in the short term. Service will resume as normal again soon ❤');
|
||||
exit;
|
||||
|
||||
try {
|
||||
$data = json_decode(file_get_contents('php://input'));
|
||||
if (!property_exists($data, 'copyright')) {
|
||||
Throw new Exception('>>> JSON requires "copyright" property and value');
|
||||
}
|
||||
|
||||
if (file_exists($user_file)) {
|
||||
Throw new Exception(wordwrap('>>> User already exists - to update values, please send a pull request on https://github.com/remy/mit-license'));
|
||||
}
|
||||
|
||||
if (!file_put_contents($user_file, json_encode($data))) {
|
||||
Throw new Exception(wordwrap('>>> Unable to create new user - please send a pull request on https://github.com/remy/mit-license'));
|
||||
}
|
||||
|
||||
// try to add to github...!
|
||||
exec('cd /WWW/mit-license && /usr/bin/git add ' . $user_file . ' && /usr/bin/git commit -m"automated creation of ' . $user_file . '"', $out, $r);
|
||||
//print_r($out); echo "\n"; print_r($r); echo "\n";
|
||||
$out = array();
|
||||
exec('cd /WWW/mit-license && /usr/bin/git push origin master -v 2>&1', $out, $r);
|
||||
//print_r($out); echo "\n"; print_r($r); echo "\n";
|
||||
|
||||
echo '>>> MIT license page created: https://' . $_SERVER['HTTP_HOST'] . "\n\n";
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo $e->getMessage() . "\n\n";
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load up the user.json file and read properties in
|
||||
**/
|
||||
if ($cname && file_exists($user_file)) {
|
||||
$user = json_decode(file_get_contents($user_file));
|
||||
$holder = htmlentities($user->copyright, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
if (property_exists($user, 'url')) {
|
||||
$holder = '<a href="' . $user->url . '">' . $holder . '</a>';
|
||||
}
|
||||
|
||||
if (property_exists($user, 'email')) {
|
||||
$holder = $holder . ' <<a href="mailto:' . $user->email . '">' . $user->email . '</a>>';
|
||||
|
||||
if (property_exists($user, 'gravatar') && $user->gravatar === true) {
|
||||
$gravatar = '<img id="gravatar" src="https://www.gravatar.com/avatar/' . md5(strtolower(trim($user->email))) . '" />';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (property_exists($user, 'format')) {
|
||||
if (strtolower($user->format) == 'txt') {
|
||||
$format = 'txt';
|
||||
}
|
||||
}
|
||||
|
||||
if (property_exists($user, 'theme')) {
|
||||
if (file_exists('themes/' . $user->theme . '.css')) {
|
||||
$theme = $user->theme;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$holder = "<copyright holders>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Now process the request url. Optional parts of the url are (in order):
|
||||
* [sha]/[year|year-range]/license.[format]
|
||||
* eg. http://rem.mit-license.org/a526bf7ad1/2009-2010/license.txt
|
||||
**/
|
||||
|
||||
// grab sha from request uri
|
||||
$request_uri = explode('/', $_SERVER["REQUEST_URI"]);
|
||||
|
||||
$request = array_pop($request_uri);
|
||||
// in case there's a trailing slash (unlikely)
|
||||
if ($request == '')
|
||||
$request = array_pop($request_uri);
|
||||
|
||||
// url file format overrides user preference
|
||||
if (stripos($request, 'license') === 0) {
|
||||
$format = array_pop(explode('.', strtolower($request))) == 'txt' ? 'txt' : 'html';
|
||||
|
||||
// move down to the next part of the request
|
||||
$request = array_pop($request_uri);
|
||||
}
|
||||
|
||||
// check if we have a year or a year range up front
|
||||
$year = date('Y');
|
||||
preg_match('/^(@?\d{4})(?:(?:\-)(\d{4}))?$/', $request, $match);
|
||||
|
||||
if (count($match) > 1) {
|
||||
if ($match[2] && $match[1][0] != '@') { // 2nd segment
|
||||
$year = $match[2];
|
||||
}
|
||||
if ($match[1]) {
|
||||
if ($match[1][0] == '@') {
|
||||
$year = substr($match[1], 1);
|
||||
} else {
|
||||
$year = $match[1] == $year ? $year : $match[1] . '-' . $year;
|
||||
}
|
||||
}
|
||||
$request = array_pop($request_uri);
|
||||
}
|
||||
|
||||
// check if there's a SHA on the url and read this to switch license versions
|
||||
$sha = '';
|
||||
if ($request != "" && $request != "/" && $request != "/index.php") {
|
||||
$sha = preg_replace('/[^a-f0-9]/', '', $request);
|
||||
} else if (isset($user) && property_exists($user, 'version')) {
|
||||
$sha = preg_replace('/[^a-f0-9]/', '', $user->version);
|
||||
}
|
||||
|
||||
// if sha specified, use that revision of licence
|
||||
$license = '';
|
||||
if ($sha != "") {
|
||||
$out = array();
|
||||
// preg_replace should save us - but: please help me Obi Wan...
|
||||
exec("/usr/local/bin/git show " . $sha . ":LICENSE.html", $out, $r);
|
||||
if ($r == 0) {
|
||||
$license = implode("\n", $out);
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't manage to read one in, use latest
|
||||
if ($license == "") {
|
||||
$license = file_get_contents('LICENSE.html');
|
||||
}
|
||||
|
||||
// replace info tag and display
|
||||
$info = $year . ' ' . $holder;
|
||||
$license = str_replace('{{info}}', $info, $license);
|
||||
$license = str_replace('{{theme}}', $theme, $license);
|
||||
$license = str_replace('{{gravatar}}', $gravatar, $license);
|
||||
|
||||
// if we want text format, strip out the license from the article tag
|
||||
// and then strip any other tags in the license.
|
||||
if ($format == 'txt') {
|
||||
$license = array_shift(explode('</article>', array_pop(explode('<article>', $license))));
|
||||
$license = preg_replace('/<[^>]*>/', '', trim($license));
|
||||
$license = html_entity_decode($license, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
$license .= "\n";
|
||||
header('content-type: text/plain; charset=UTF-8');
|
||||
}
|
||||
|
||||
echo $license;
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
"@types/express": "^4.16.1",
|
||||
"@types/express-minify": "^0.1.34",
|
||||
"@types/md5": "^2.1.33",
|
||||
"@types/node": "^12.0.4",
|
||||
"@types/tmp": "^0.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^1.9.0",
|
||||
"css": "^2.2.4",
|
||||
|
|
|
|||
90
server.ts
90
server.ts
|
|
@ -19,10 +19,11 @@ import postcssMiddleware = require('postcss-middleware')
|
|||
|
||||
// License viewing
|
||||
import * as ejs from 'ejs'
|
||||
import {yearNow, stripTags, trimArray} from './util'
|
||||
import { yearNow, stripTags, trimArray } from './util'
|
||||
import * as HTML from 'node-html-parser'
|
||||
import md5 = require('md5');
|
||||
import humanizeList from 'humanize-list'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
// License creation
|
||||
import btoa = require('btoa')
|
||||
|
|
@ -35,6 +36,26 @@ const github = require('@octokit/rest')({
|
|||
userAgent: `mit-license v${require('./package.json').version}`,
|
||||
})
|
||||
|
||||
// Helpers
|
||||
const yearNow = dayjs().year()
|
||||
const stripTags = (val: any) => val.replace(/<(?:.|\n)*?>/gm, '')
|
||||
function trimArray(arr: any[]) {
|
||||
// Example: trimArray(['', '', 'abc', '', 'abc', 'abc', '', '']) -> ["abc", "", "abc", "abc"]
|
||||
const handleVal = (val: any) => {
|
||||
if (val !== '') {
|
||||
valPassed = true
|
||||
return val
|
||||
}
|
||||
else if (!valPassed) return null
|
||||
else return val
|
||||
}
|
||||
let valPassed = false
|
||||
arr = arr.map(handleVal)
|
||||
valPassed = false
|
||||
arr = arr.reverse().map(handleVal)
|
||||
return arr.reverse().filter((val) => val !== null)
|
||||
}
|
||||
|
||||
// Prepare application
|
||||
const app = express()
|
||||
app.use(compression())
|
||||
|
|
@ -47,7 +68,7 @@ app.set('view engine', 'ejs')
|
|||
app.use('/robots.txt', express.static('robots.txt'))
|
||||
app.use('/users', express.static('users'))
|
||||
app.use('/themes', postcssMiddleware({
|
||||
plugins: [require('postcss-preset-env')({browsers: '>= 0%', stage: 0})],
|
||||
plugins: [require('postcss-preset-env')({ browsers: '>= 0%', stage: 0 })],
|
||||
src: (req) => path.join(__dirname, 'themes', req.path),
|
||||
}))
|
||||
app.use('/themes', express.static('themes'))
|
||||
|
|
@ -61,7 +82,7 @@ app.use((_req, res, next) => {
|
|||
})
|
||||
|
||||
// Parse URL-encoded bodies (as sent by HTML forms)
|
||||
app.use(express.urlencoded({extended: true}))
|
||||
app.use(express.urlencoded({ extended: true }))
|
||||
|
||||
// Parse JSON bodies (as sent by API clients)
|
||||
app.use(express.json())
|
||||
|
|
@ -71,26 +92,59 @@ app.post('/', (req, res) => {
|
|||
// Get differnet parts of hostname (example: remy.mit-license.org -> ['remy', 'mit-license', 'org'])
|
||||
const params = req.hostname.split('.')
|
||||
|
||||
const conf = (() => {
|
||||
// If query parameters provided
|
||||
if (Object.keys(req.query).length > 0) return req.query
|
||||
|
||||
// If the data parsed as {'{data: "value"}': ''}
|
||||
const keys = Object.keys(req.body)
|
||||
if (keys.length === 1 && !Object.values(req.body)[0]) return JSON.parse(keys[0])
|
||||
|
||||
// Fallback
|
||||
return req.body
|
||||
})()
|
||||
|
||||
// If there isn't enough part of the hostname
|
||||
if (params.length < 2) res.status(400).send('Please specify a subdomain in the URL.')
|
||||
|
||||
github.repos.createFile({
|
||||
owner: 'remy',
|
||||
repo: 'mit-license',
|
||||
path: `users/${params[0]}.json`,
|
||||
message: `Automated creation of user ${params[0]}.`,
|
||||
content: btoa(''),
|
||||
committer: {
|
||||
name: 'MIT License Bot',
|
||||
email: 'remy@leftlogic.com',
|
||||
},
|
||||
})
|
||||
// Extract the name from the URL
|
||||
const name = params[0]
|
||||
|
||||
gitpull(__dirname, (err: any, _consoleOutput: any) => {
|
||||
if (err) {
|
||||
res.status(502).end()
|
||||
// Check if the user file exists in the users directory
|
||||
fs.access(path.join('users', `${name}.json`), fs.constants.F_OK, (err) => {
|
||||
if (!err) {
|
||||
// File already exists
|
||||
res.status(409).send('User already exists - to update values, please send a pull request on https://github.com/remy/mit-license')
|
||||
} else {
|
||||
res.status(201).end()
|
||||
try {
|
||||
// File doesn't exist
|
||||
|
||||
// If copyright property and key doesn't exist
|
||||
if (!conf.copyright) res.status(400).send(`JSON requires "copyright" property and value`)
|
||||
else {
|
||||
github.repos.createFile({
|
||||
owner: 'remy',
|
||||
repo: 'mit-license',
|
||||
path: `users/${params[0]}.json`,
|
||||
message: `Automated creation of user ${params[0]}.`,
|
||||
content: btoa(JSON.stringify(conf, null, 4)),
|
||||
committer: {
|
||||
name: 'MIT License Bot',
|
||||
email: 'remy@leftlogic.com',
|
||||
},
|
||||
})
|
||||
|
||||
gitpull(__dirname, (err: any, _consoleOutput: any) => {
|
||||
if (err) {
|
||||
res.status(502).send(`Unable to create new user - please send a pull request on https://github.com/remy/mit-license`)
|
||||
} else {
|
||||
res.status(201).send(`MIT license page created: https://${req.hostname}`)
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(502).send(`Unable to create new user - please send a pull request on https://github.com/remy/mit-license`)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
20
util.ts
20
util.ts
|
|
@ -1,20 +0,0 @@
|
|||
import dayjs = require('dayjs');
|
||||
|
||||
export const yearNow = dayjs().year()
|
||||
export const stripTags = (val: any) => val.replace(/<(?:.|\n)*?>/gm, '')
|
||||
export function trimArray(arr: any[]) {
|
||||
// Example: trimArray(['', '', 'abc', '', 'abc', 'abc', '', '']) -> ["abc", "", "abc", "abc"]
|
||||
const handleVal = (val: any) => {
|
||||
if (val !== '') {
|
||||
valPassed = true
|
||||
return val
|
||||
}
|
||||
else if (!valPassed) return null
|
||||
else return val
|
||||
}
|
||||
let valPassed = false
|
||||
arr = arr.map(handleVal)
|
||||
valPassed = false
|
||||
arr = arr.reverse().map(handleVal)
|
||||
return arr.reverse().filter((val) => val !== null)
|
||||
}
|
||||
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue