Added export as CSV

This commit is contained in:
Simon Brooke 2018-08-24 23:28:32 +01:00
parent a824691282
commit 5d286f85c2
3 changed files with 109 additions and 11 deletions

5
.gitignore vendored
View file

@ -10,4 +10,7 @@ pom.xml.asc
.hgignore
.hg/
/resources/*
*~
*~
*.ods
*.csv

View file

@ -5,6 +5,7 @@
:url "https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html"}
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/data.json "0.2.6"]
[org.clojure/tools.cli "0.3.7"]
[clj-http "3.9.1"]
[clj-time "0.14.4"]]
:aot [mastodonusers.core]

View file

@ -1,25 +1,65 @@
(ns mastodonusers.core
(:require [clojure.data.json :as json]
[clojure.pprint :refer :all]
[clojure.string :as s]
[clojure.tools.cli :refer [parse-opts]]
[clojure.walk :refer [keywordize-keys]]
[clj-http.client :as h]
[clj-time.core :as t]
[clj-time.format :as f])
(:gen-class))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
;;;; mastodonusers.core
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
;;;; as published by the Free Software Foundation; either version 2
;;;; of the License, or (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;;; GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public License
;;;; along with this program; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
;;;; USA.
;;;;
;;;; Copyright (C) 2018 Simon Brooke
;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; (def application-id "431276798")
;; (def application-name "mastodonusers")
(def cli-options
[["-h" "--help" "Show this message"
:default false]
["-o" "--csv" "output data as comma-separated values"]
["-s" "--bearer-secret [SECRET]" "The secret which identifies us to instances.social"]
["-v" "--verbosity [LEVEL]" nil "Verbosity level - integer value required"
:parse-fn #(Integer/parseInt %)
:default 0]
])
(defn usage
"Show a usage message. `options` should be options as
parsed by [clojure.tools.cli](https://github.com/clojure/tools.cli)"
[options]
(println (:summary options)))
(defn fetch-data
"Fetch current data from instances.social with our key"
[]
"Fetch current data from instances.social with this `secret` key"
[secret]
(h/get
"https://instances.social/api/1.0/instances/list"
{:headers {:authorization (str
"Bearer "
(slurp "resources/secret.txt"))}
(or
secret
(slurp "resources/secret.txt")))}
:query-params {:count 0}
:accept :json}))
@ -61,14 +101,68 @@
c)))))
(defn -main [& args]
(defn ->csv
"Return the contents of this EDN `file`, assumed to contain a map with
date/time keys and count values, in CSV format."
[file]
(let [data (read-string (slurp file))]
(s/join
"\n"
(map
#(str % ", " (data %))
(sort
#(compare
(f/parse
;; (f/formatters :basic-date-time)
%1)
(f/parse
;; (f/formatters :basic-date-time)
%2))
(keys data))))))
(defn process
"Process these parsed `options`."
[options]
(let [c (count-users
(fetch-data
(-> options :options :bearer-secret)))
args (:arguments options)]
(if-not
(empty? args)
(update-file (first args) c))
(if-not
(zero? (-> options :options :verbosity))
(println "Total #fediverse user accounts: " c))
(if
(and
(not (empty? args))
(-> options :options :csv))
(println (->csv (first args))))
c))
(defn -main
"Print a count of the current number of user accounts in the fediverse.
If an argument is present, it is presumed to be the pathname of
an EDN formatted file containing a map mapping times to counts, which will
be updated with the current count."
(let [c (count-users (fetch-data))]
(if-not (empty? args) (update-file (first args) c))
(println "Total #fediverse user accounts: " c)
c))
[& args]
(let [options (parse-opts args cli-options)]
(cond
(empty? args)
(usage options)
(seq (:errors options))
(do
(doall
(map
println
(:errors options)))
(usage options))
(-> options :options :help)
(usage options)
true
(process options))))