Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nx10 committed Aug 27, 2022
1 parent 777c1b0 commit e8d4614
Show file tree
Hide file tree
Showing 24 changed files with 1,560 additions and 181 deletions.
1,111 changes: 938 additions & 173 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,26 @@
"devDependencies": {
"@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next",
"@types/luxon": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0",
"autoprefixer": "^10.4.8",
"eslint": "^8.16.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.16",
"prettier": "^2.6.2",
"prettier-plugin-svelte": "^2.7.0",
"svelte": "^3.44.0",
"svelte-check": "^2.7.1",
"svelte-preprocess": "^4.10.6",
"svelte-preprocess": "^4.10.7",
"tailwindcss": "^3.1.8",
"tslib": "^2.3.1",
"typescript": "^4.7.4",
"vite": "^3.0.4"
},
"type": "module"
"type": "module",
"dependencies": {
"luxon": "^3.0.1"
}
}
6 changes: 6 additions & 0 deletions postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
3 changes: 3 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
9 changes: 6 additions & 3 deletions src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
%sveltekit.head%
</head>
<body>
<body class="">
<div>%sveltekit.body%</div>
</body>
</html>
5 changes: 5 additions & 0 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
import '../app.css';
</script>

<slot />
107 changes: 105 additions & 2 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,2 +1,105 @@
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
<script lang="ts">
import { iso2ago } from '../utils';
import { pkg_url_full } from '../server_data';
import { subrepo } from '../stores.js';
const expanded: CranQueue[] = [];
let search = '';
$: subrepo_filtered = $subrepo.then((subrepo) => subrepo.filter(search));
let expand: CranQueue[] = [];
function expand_q(q: CranQueue): () => void {
return () => {
expand.push(q);
expand = expand; // for reactivity
};
}
</script>

<svelte:head>
<title>CRAN sub tracker</title>
</svelte:head>

<main class="my-0 mx-auto max-w-3xl px-2">
<a href="/"
><div class="text-3xl font-bold pr-2 text-slate-600 text-center mb-5 mt-4">
CRAN submission tracker
</div></a
>

<div class="relative mt-3">
<svg
xmlns="http://www.w3.org/2000/svg"
class="absolute top-0 bottom-0 w-6 h-6 my-auto text-gray-400 left-3"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
<input
type="text"
placeholder="Search"
class="w-full py-3 pl-12 pr-4 text-slate-500 border rounded-md outline-none bg-gray-50 focus:text-slate-900 focus:bg-white focus:border-slate-500"
bind:value={search}
/>
</div>

{#await subrepo_filtered}
<p>Fetching snapshot...</p>
{:then subrepo}
{#each subrepo.queues as queue}
<div class="flex flex-row space-x-1 items-end pt-3 mb-1">
<div class="flex-auto text-2xl font-bold ">{queue.info.name}</div>
<div class="text-slate-500">{queue.queue.length} packages</div>
</div>
<p class="italic text-sm text-slate-600">{queue.info.description}</p>
<div class="flex flex-col border border-slate-300 rounded-md mt-2">
{#each queue.queue as sub, idx_sub}
{#if expand.indexOf(queue) !== -1 || idx_sub < 5 || idx_sub > queue.queue.length - 6}
<a
href={pkg_url_full(sub)}
class="flex flex-row space-x-1 items-center hover:bg-slate-200 odd:bg-white even:bg-slate-50 px-2 py-1 first:rounded-t-md last:rounded-b-md"
>
<div class="font-light text-sm w-14 text-slate-500">#{idx_sub + 1}</div>
<div class="text-slate-900">
{sub.pkg_name}
</div>
<div class="text-sm text-slate-500 flex-auto">{sub.pkg_version}</div>
<div class="text-sm font-light">{iso2ago(sub.file_time)}</div>
</a>
{:else if idx_sub == 5}
<div
on:click|once={expand_q(queue)}
class="flex flex-row space-x-1 items-center justify-center hover:bg-slate-200 odd:bg-white even:bg-slate-50 cursor-pointer"
>
<div class="text-slate-600 py-1">Show {queue.queue.length - 10} more...</div>
</div>
{/if}
{/each}
</div>
{:else}
<p class="text-slate-800">No submissions match the search query.</p>
{/each}

<div class="text-slate-500 my-4 ">
<span class="hover:underline text-slate-600"
><a href="/about" class="my-4">About this page</a></span
>

<span class="float-right text-sm font-light"
>Updated {iso2ago(subrepo.capture_time)} in {subrepo.capture_duration / 1000} seconds. Updating
every {subrepo.update_interval / 60} minutes.</span
>
</div>
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
</main>
72 changes: 72 additions & 0 deletions src/routes/about/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<svelte:head>
<title>CRAN sub tracker: About</title>
</svelte:head>

<main class="my-0 mx-auto max-w-3xl px-2">
<a href="/"
><div class="text-3xl font-bold pr-2 text-slate-600 text-center mb-5 mt-4">
CRAN submission tracker
</div></a
>
<p>Please report issues with this site via the GitHub issue tracker or contact me directly.</p>
<h3 class="font-bold text-xl my-4">About</h3>
<ul class="list-disc">
<li>This tracker is inofficial and in no way affiliated with CRAN or the R Project.</li>
<li>The primary goal of this site is to make tracking package submissions more accessible.</li>
<li>Both backend and frontend are fully open source and available on GitHub.</li>
<li>
To minimize traffic to the CRAN network, the backend lazily fetches data from the CRAN
incoming FTP server (<a
href="ftp://cran.r-project.org/incoming/"
class="no-underline hover:underline">ftp://cran.r-project.org/incoming/</a
>) and caches it in memory. (This means when nobody is looking at this page, there will be no
traffic to CRAN and there is no increased traffic for concurrent users.)
</li>
<li>A big shout-out to the CRAN members reviewing many packages every week.</li>
</ul>
<h3 class="font-bold text-xl my-4">Alternatives</h3>
<ul class="list-disc">
<li>
<a class="hover:underline" href="https://r-hub.github.io/cransays/articles/dashboard.html"
>r-hub/cransays CRAN incoming dashbord (website)</a
>
</li>
<li>
<a class="hover:underline" href="https://cran.r-project.org/incoming/"
>CRAN incoming FTP (website)</a
>
</li>
<li>
<a class="hover:underline" href="https://cran.r-project.org/web/packages/foghorn/index.html"
>foghorn (R package)</a
>
</li>
</ul>

<h3 class="font-bold text-xl my-4">References</h3>
<ul class="list-disc">
<li>
<a class="hover:underline" href="https://journal.r-project.org/archive/2018-1/cran.pdf"
>R journal (2017): Changes on CRAN (Kurt Hornik, Uwe Ligges and Achim Zeileis)</a
>
</li>
<li>
<a
class="hover:underline"
href="https://stat.ethz.ch/pipermail/r-package-devel/2019q1/003631.html"
>[R-pkg-devel] Meaning and consequences of action pending in the submission pipeline</a
>
</li>
<li>
<a class="hover:underline" href="https://github.com/edgararuiz-zz/cran-stages"
>CRAN Analysis: Edgar Ruiz (2018)</a
>
</li>
</ul>

<div class="mt-3 ">
<a href="/" class="text-l text-slate-500 hover:underline hover:text-slate-800"
>&larr; Back to browse</a
>
</div>
</main>
113 changes: 113 additions & 0 deletions src/routes/pkg/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<script lang="ts">
import { subrepo } from '../../stores.js';
import { page } from '$app/stores';
import { humanRedableMemoryUnits, iso2ago } from '../../utils.js';
import { pkg_url_full, pkg_url_name } from '../../server_data.js';
const pkgid = decodeURIComponent($page.url.hash.substring(1));
$: pkg = $subrepo.then((subrepo) => {
const uc = pkgid.split('_');
return (uc.length > 1) ? subrepo.find_pkg(uc[0], uc[1]) : subrepo.find_pkg(uc[0]);
});
</script>

<svelte:head>
<title>CRAN sub tracker</title>
</svelte:head>

<main class="my-0 mx-auto max-w-3xl px-2">
<a href="/"
><div class="text-3xl font-bold pr-2 text-slate-600 text-center mb-5 mt-4">
CRAN submission tracker
</div></a
>

{#await pkg}
<p>Fetching snapshot...</p>
{:then pkg}
{#if pkg}
<h1>
<span class="text-5xl font-bold pr-2 text-slate-800">{pkg[0].pkg_name}</span>
<span class="text-4xl font-bold text-slate-600">{pkg[0].pkg_version}</span>
</h1>

<div class="flex border border-slate-300 rounded-md my-4 divide-x divide-y text-center">
<div class="p-3 text-slate-900 grow">
<h4 class="text-xl text-slate-600 font-bold rounded-l-md">Submitted</h4>
<p class="text-3xl">{iso2ago(pkg[0].file_time)}</p>
<p class="text-slate-500 font-light mt-1">Oldest: {iso2ago(pkg[1].queue[0].file_time)}</p>
</div>
<div class="p-3 text-slate-900 grow">
<h4 class="text-xl text-slate-600 font-bold rounded-l-md ">Status</h4>
<p class="text-3xl">{pkg[1].info.name}</p>
<p class="text-slate-500 font-light mt-1">
#{pkg[1].queue.indexOf(pkg[0]) + 1} of {pkg[1].queue.length}
</p>
</div>
<div class="p-3 text-slate-900 grow">
<h4 class="text-xl text-slate-600 font-bold rounded-l-md">Size</h4>
<span class="text-3xl">{humanRedableMemoryUnits(pkg[0].file_bytes)}</span>
<p class="text-slate-500 font-light mt-1">.tar.gz</p>
</div>
</div>

<div class="px-10 my-3 text-slate-700">
{pkg[1].info.longdescription}
<span class="text-sm font-light text-slate-500">
<a href={pkg[1].info.reference} class="my-4">({pkg[1].info.reference_label})</a>
</span>
</div>

<p class="font-bold text-slate-800">Track this submission:</p>
<input
type="text"
readonly
value={'nx10.github.io/cransubs' + pkg_url_full(pkg[0])}
class="w-full my-1 py-1 px-3 text-slate-900 border rounded-md outline-none bg-gray-50 focus:text-slate-900 focus:bg-white focus:border-slate-500"
/>
<p class="font-bold text-slate-800">Track the newest submission with this name:</p>
<input
type="text"
readonly
value={'nx10.github.io/cransubs' + pkg_url_name(pkg[0])}
class="w-full my-1 py-1 px-3 text-slate-900 border rounded-md outline-none bg-gray-50 focus:text-slate-900 focus:bg-white focus:border-slate-500"
/>

<div class="mt-1 text-blue-800">
{#if pkg[0].folder !== 'newbies'}
<p>
<a
class="hover:underline hover:text-blue-900"
href={'https://CRAN.R-project.org/package=' + pkg[0].pkg_name}
>Find on CRAN (previous version)</a
>
</p>
{/if}
<p>
<a
class="hover:underline hover:text-blue-900"
href={'https://cran.r-project.org/incoming/' + pkg[0].folder}>Find on CRAN_incoming</a
>
</p>
</div>

<div class="float-right text-sm font-light text-slate-500">
<span class="">Updated {iso2ago(pkg[0].request_time)}.</span>
<span class="hover:underline text-slate-600"
><a href="/about" class="my-4"> About this page</a></span
>
</div>
{:else}
Package does not exist (anymore?)
{/if}
{:catch error}
<p style="color: red">{error.message}</p>
{/await}

<div class="mt-3 ">
<a href="/" class="text-l text-slate-500 hover:underline hover:text-slate-800"
>&larr; Back to browse</a
>
</div>
</main>
Loading

0 comments on commit e8d4614

Please sign in to comment.