[mythtv]: Streaming/Download Probleme via MythWeb

Seit Kurzem erhalte ich folgende Fehlermeldung, wenn ich Aufnahmen per MythWeb herunterladen oder streamen möchte:

Internal Server Error
End of script output before headers: mythweb.pl 

Im Apache-Logfile steht es etwas genauer:

[cgi:error] AH01215: Can't locate CGI.pm in @INC (you may need to install the CGI module) (@INC contains: /usr/lib/perl5/site_perl /usr/share/perl5/site_perl /usr/lib/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib/perl5/core_perl /usr/share/perl5/core_perl .) at /srv/http/www/mythweb/mythweb.pl line 8.: /srv/http/www/mythweb/mythweb.pl, referer: https://192.168.X.Y/mythweb/tv/recorded
[cgi:error] AH01215: BEGIN failed--compilation aborted at /srv/http/www/mythweb/mythweb.pl line 8.: /srv/http/www/mythweb/mythweb.pl, referer: https://192.168.X.Y/mythweb/tv/recorded
[cgi:error] End of script output before headers: mythweb.pl, referer: https://192.168.0.4/mythweb/tv/recorded

Des Rätsel Lösung ist: Es fehlt das Paket perl-cgi, welches unter Arch wiefoglt nachinstalliert werden kann:

pacaur -S perl-cgi

Jetzt funktioniert wieder alles.

Posted in Arch | Leave a comment

[GNU R] Ordinale Regression mit R

Zur Bestimmung des Einflusses von Prädiktoren auf ein ordinales Ziel stehen verschiedene Modelle der ordinalen Regression zur Verfügung. Namentlich werden hier vor allem Proportional Odds Modelle und Continuation Ratio Modelle verwendet. Dieser Blogbeitrag beschreibt, wie sich diese Modelle mit Hilfe der freien Statistikumgebung R errechnen lassen.

Vorbereitung

Wir verwenden hier das R-Paket “VGAM”, welches zunächst in R installiert werden muss

install.packages("VGAM", dependencies = T)

Als Beispiel dient der folgende Datensatz:

load(url("http://www.produnis.de/R/OrdinalSample.RData"))
mydata =ordinalSample
head(mydata)
##    Konflikt Zufriedenh Geschlecht Stimmung
## 1       4.2       2.50          1  maessig
## 6       1.8       3.00          1 sehr gut
## 15      3.4       1.75          1  maessig
## 16      4.0       2.50          2  maessig
## 22      2.2       2.50          1      gut
## 23      3.4       2.25          1  maessig

Die Variable “Stimmung” dient hier als ordinales Ziel mit den Ausprägungen “schlecht” < “maessig” < “gut” < “sehr gut”.

Die Variable “Konflikt” dient als Prädiktor. Sie gibt an, wieviele Konflikte derzeit im Arbeitsleben vorliegen.

Die Variable “Zufriedenh” beschreibt, wie zufrieden Probanden mit ihrem Job sind.

Die Variable “Stimmung” soll nun durch “Konflikt” und “Zufriedenh” beschrieben werden.

Proportional Odds Modell

Ein Proportional Odds Modell errechnet sich leicht mit dem VGAM-Paket:

library(VGAM)
pom =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cumulative(parallel = T))
 
# oder abgekürzt
pom =  vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = propodds)
summary(pom)
## 
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = propodds, 
##     data = mydata)
## 
## Pearson Residuals:
##                 Min    1Q Median    3Q Max
## logit(P[Y>=2]) -5.3  0.12   0.20  0.41 1.4
## logit(P[Y>=3]) -3.1 -0.77   0.24  0.76 2.6
## logit(P[Y>=4]) -1.4 -0.46  -0.22 -0.11 7.3
## 
## Coefficients:
##               Estimate Std. Error z value
## (Intercept):1     0.62      0.648    0.96
## (Intercept):2    -1.77      0.654   -2.71
## (Intercept):3    -4.06      0.676   -6.00
## Konflikt         -0.58      0.097   -5.94
## Zufriedenh        1.36      0.202    6.75
## 
## Number of linear predictors:  3 
## 
## Names of linear predictors: 
## logit(P[Y>=2]), logit(P[Y>=3]), logit(P[Y>=4])
## 
## Dispersion Parameter for cumulative family:   1
## 
## Residual deviance: 920.5 on 1240 degrees of freedom
## 
## Log-likelihood: -460.3 on 1240 degrees of freedom
## 
## Number of iterations: 5

Mit dem Modell können nun weitere Parameter errechnet werden:

# Koeffizienten
pom.coef =(coef(summary(pom)))
pom.coef
##               Estimate Std. Error z value
## (Intercept):1   0.6210     0.6482   0.958
## (Intercept):2  -1.7703     0.6540  -2.707
## (Intercept):3  -4.0578     0.6759  -6.004
## Konflikt       -0.5762     0.0970  -5.940
## Zufriedenh      1.3643     0.2021   6.751
# Odds Ratio
pom.odds =exp(coef(pom))
pom.odds
## (Intercept):1 (Intercept):2 (Intercept):3      Konflikt    Zufriedenh 
##       1.86078       0.17029       0.01729       0.56205       3.91293
# Devianz
pom.devi =deviance(pom)
pom.devi
## [1] 920.5
# AIC
pom.aic =AIC(pom)
pom.aic
## [1] 930.5
# logLikelihood
pom.ll =logLik(pom)
pom.ll
## [1] -460.3
# 0-Modell (fuer pseudo R^2)
p0 =vglm(Stimmung ~ 1, data = mydata, family = propodds)
p0.ll =  logLik(p0)
# R^2 McFadden
pom.mcfad =as.vector(1 - (pom.ll/p0.ll))
pom.mcfad
## [1] 0.1241
# R^2 Cox&Snell
N =length(mydata[, 1])  # Anzahl der Fälle
pom.cox =  as.vector(1 - exp((2/N) * (p0.ll - pom.ll)))
pom.cox
## [1] 0.2696
# R^2 Nagelkerke
pom.nagel =as.vector((1 - exp((2/N) * (p0.ll - pom.ll)))/(1 - exp(p0.ll)^(2/N)))
pom.nagel
## [1] 0.2929

Das Proportional Odds Modell geht von der “equal slopes assumption” (auch: “proportional odds assumption”) aus. Diese Annahme muss geprüft werden, bevor das Modell als gültig angesehen werden kann. Dies geht mit dem VGAM-Paket recht einfach. Der Befehl vglm(Stimmung ~ Konflikt+Zufriedenh, data=mydata, family=propodds) ist eine Abkürzung für vglm(Stimmung ~ Konflikt+Zufriedenh, data=mydata, family=cumulative(parallel=T)). Der Parameter parallel=TRUE/FALSE stellt ein, ob das Modell mit equal slopes (=TRUE), oder ohne equal slopes assumption (=FALSE) erstellt werden soll. Zur Überprüfung der “Equal Slopes Assumption” erstellt man jeweils ein TRUE und ein FALSE-Modell, und führt dann einen Likelihood-Test durch. Die Nullhypothese lautet, dass equal slopes vorliegen.

# Modell OHNE equal slopes
npom =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cumulative(parallel = F))
# log-likelihood-Test auf Equal Slopes Assumption
lrtest(pom, npom)  # Test
## Likelihood ratio test
## 
## Model 1: Stimmung ~ Konflikt + Zufriedenh
## Model 2: Stimmung ~ Konflikt + Zufriedenh
##    #Df LogLik Df Chisq Pr(>Chisq)
## 1 1240   -460                    
## 2 1236   -456 -4  7.62       0.11

Der Test ist mit p=0,1065 nicht signifikant. Das heisst, es liegen equal slopes vor. Das Modell darf also verwendet werden.

Alternativ kann dieser Test auch auf die Devianz der Modelle bestimmt werden:

# Devianz-Test auf Equal Slopes Assumption
pom.pdevi = (1 - pchisq(deviance(pom) - deviance(npom), df = df.residual(pom) - 
    df.residual(npom)))
pom.pdevi
## [1] 0.1065

Ist der Test signifikant, liegen keine “equal slopes” vor. Hier kann ein Partial Proportional Odds Modell erstellt werden, welches die “equal slopes” nur für bestimmte Prädiktoren annimmt. Mit dem VGAM-Paket kann recht einfach bestimmt werden, wie ein solches Modell erstellt werden soll. Hierfür erweitertet man den “parallel”-Switch wie folgt:

# Equal Slopes NUR für 'Konflikt'
ppom =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cumulative(parallel = T ~ 
    Konflikt - 1))
ppom
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = cumulative(parallel = T ~ 
##     Konflikt - 1), data = mydata)
## 
## Coefficients:
## (Intercept):1 (Intercept):2 (Intercept):3      Konflikt  Zufriedenh:1 
##        0.6615        1.5374        2.7337        0.5706       -1.9684 
##  Zufriedenh:2  Zufriedenh:3 
##       -1.2805       -0.8865 
## 
## Degrees of Freedom: 1245 Total; 1238 Residual
## Residual deviance: 914.5 
## Log-likelihood: -457.2
# Nochmals EqualSlopes NUR für 'Konflikt'
ppom =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cumulative(parallel = F ~ 
    Zufriedenh))
ppom
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = cumulative(parallel = F ~ 
##     Zufriedenh), data = mydata)
## 
## Coefficients:
## (Intercept):1 (Intercept):2 (Intercept):3      Konflikt  Zufriedenh:1 
##        0.6615        1.5374        2.7337        0.5706       -1.9684 
##  Zufriedenh:2  Zufriedenh:3 
##       -1.2805       -0.8865 
## 
## Degrees of Freedom: 1245 Total; 1238 Residual
## Residual deviance: 914.5 
## Log-likelihood: -457.2
  • parallel=T~Konflikt-1 bedeutet, dass equal slopes nur für Konflikt angenommen wird.
  • parallel=F~Zufriedenh bedeutet, dass equal slopes nur für Zufriedenh nicht angenommen wird.

Beide Befehle bedeuten also das selbe. Daher ist die R-Ausgabe bei beiden Befehlen gleich.

Eine Koeffizientenübersicht erhält man per

ppom.ce =coef(summary(ppom))
ppom.ce
##               Estimate Std. Error z value
## (Intercept):1   0.6615    0.85866  0.7704
## (Intercept):2   1.5374    0.71998  2.1353
## (Intercept):3   2.7337    0.98084  2.7871
## Konflikt        0.5706    0.09715  5.8730
## Zufriedenh:1   -1.9684    0.34535 -5.6997
## Zufriedenh:2   -1.2805    0.23585 -5.4294
## Zufriedenh:3   -0.8865    0.32543 -2.7242

Mit einem kleinen Script können Konfidenzintervalle und andere Werte ausgegeben werden:

get.ci =function(x){
  back = cbind( x[1], # estimate
                (x[1] - (1.96 * x[2])), #lCI
                (x[1] + (1.96 * x[2])), #uCI
                x[2], x[3], # SD und z
                (2*(1 -pnorm(abs(x[3]))) ),# p-wert
                exp(x[1])) 
  colnames(back) =  c("Estimate", "lCI", "uCI","SD","z","p-value", "OR")
  return(back)
}

Der Aufruf erfolgt z.B. so:

get.ci(as.numeric(ppom.ce[4, ]))
##      Estimate    lCI   uCI      SD     z  p-value    OR
## [1,]   0.5706 0.3802 0.761 0.09715 5.873 4.28e-09 1.769

Continuation Ratio Model

Um ein Continuation Ratio Modell zu rechnen, muss der Parameter family auf cratio gesetzt werden.

# CR-Modell MIT PO-Assumption (Vorwärts)
crm =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cratio(parallel = T, 
    reverse = F))
summary(crm)
## 
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = cratio(parallel = T, 
##     reverse = F), data = mydata)
## 
## Pearson Residuals:
##                     Min    1Q  Median      3Q  Max
## logit(P[Y>1|Y&gt;=1]) -4.9  0.18 2.6e-01 3.7e-01  1.2
## logit(P[Y>2|Y&gt;=2]) -3.0 -0.86 3.2e-01 7.2e-01  2.4
## logit(P[Y>3|Y&gt;=3]) -1.5 -0.63 1.1e-05 6.2e-05 11.8
## 
## Coefficients:
##               Estimate Std. Error z value
## (Intercept):1     0.93      0.574     1.6
## (Intercept):2    -1.14      0.579    -2.0
## (Intercept):3    -3.02      0.607    -5.0
## Konflikt         -0.54      0.086    -6.2
## Zufriedenh        1.16      0.179     6.5
## 
## Number of linear predictors:  3 
## 
## Names of linear predictors: 
## logit(P[Y>1|Y>=1]), logit(P[Y>2|Y>=2]), logit(P[Y>3|Y>=3])
## 
## Dispersion Parameter for cratio family:   1
## 
## Residual deviance: 924.4 on 1240 degrees of freedom
## 
## Log-likelihood: -462.2 on 1240 degrees of freedom
## 
## Number of iterations: 5

Dies berechnet standardmäßig die Vorwärts-Methode. Möchte man die Rückwärts-Methode rechnen, setzt man den Parameter reverse auf TRUE.

# CR-Modell MIT PO-Assumption (Rückwärts)
crm =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cratio(parallel = T, 
    reverse = TRUE))
summary(crm)
## 
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = cratio(parallel = T, 
##     reverse = TRUE), data = mydata)
## 
## Pearson Residuals:
##                     Min    1Q  Median      3Q Max
## logit(P[Y&lt;2|Y< =2]) -1.6 -0.57 1.5e-05 4.1e-05 7.0
## logit(P[Y&lt;3|Y&lt;=3]) -2.5 -0.88 7.3e-05 7.2e-01 3.1
## logit(P[Y&lt;4|Y&lt;=4]) -6.3  0.18 3.0e-01 4.4e-01 1.1
## 
## Coefficients:
##               Estimate Std. Error z value
## (Intercept):1     0.13      0.573    0.22
## (Intercept):2     2.09      0.581    3.59
## (Intercept):3     4.04      0.606    6.67
## Konflikt          0.45      0.085    5.33
## Zufriedenh       -1.26      0.181   -6.94
## 
## Number of linear predictors:  3 
## 
## Names of linear predictors: 
## logit(P[Y&lt;2|Y&lt;=2]), logit(P[Y&lt;3|Y&lt;=3]), logit(P[Y&lt;4|Y&lt;=4])
## 
## Dispersion Parameter for cratio family:   1
## 
## Residual deviance: 920.5 on 1240 degrees of freedom
## 
## Log-likelihood: -460.2 on 1240 degrees of freedom
## 
## Number of iterations: 5

Hat man die passende Methode gewählt, folgen die selben Befehle wie beim Proportional Odds Modell. Zunächst muss überprüft werden, ob “equal slopes” vorliegen:

# CR-Modell OHNE PO-Assumption (Rückwärts)
ncrm =vglm(Stimmung ~ Konflikt + Zufriedenh, data = mydata, family = cratio(parallel = F, 
    reverse = T))
summary(ncrm)
## 
## Call:
## vglm(formula = Stimmung ~ Konflikt + Zufriedenh, family = cratio(parallel = F, 
##     reverse = T), data = mydata)
## 
## Pearson Residuals:
##                     Min    1Q   Median      3Q Max
## logit(P[Y&lt;2|Y< =2]) -1.8 -0.57 -1.6e-05 0.00015 8.5
## logit(P[Y&lt;3|Y&lt;=3]) -2.5 -0.87  5.3e-07 0.72073 3.1
## logit(P[Y&lt;4|Y&lt;=4]) -5.4  0.18  2.9e-01 0.43071 1.0
## 
## Coefficients:
##               Estimate Std. Error z value
## (Intercept):1     2.36       1.17    2.01
## (Intercept):2     2.00       0.81    2.46
## (Intercept):3     2.47       1.12    2.20
## Konflikt:1        0.15       0.18    0.81
## Konflikt:2        0.49       0.12    4.07
## Konflikt:3        0.63       0.17    3.74
## Zufriedenh:1     -1.80       0.39   -4.60
## Zufriedenh:2     -1.26       0.26   -4.89
## Zufriedenh:3     -0.84       0.34   -2.47
## 
## Number of linear predictors:  3 
## 
## Names of linear predictors: 
## logit(P[Y&lt;2|Y&lt;=2]), logit(P[Y&lt;3|Y&lt;=3]), logit(P[Y&lt;4|Y&lt;=4])
## 
## Dispersion Parameter for cratio family:   1
## 
## Residual deviance: 914.8 on 1236 degrees of freedom
## 
## Log-likelihood: -457.4 on 1236 degrees of freedom
## 
## Number of iterations: 5
# loglikelihood test auf equal slopes assumption
lrtest(ncrm, crm)  # Test
## Likelihood ratio test
## 
## Model 1: Stimmung ~ Konflikt + Zufriedenh
## Model 2: Stimmung ~ Konflikt + Zufriedenh
##    #Df LogLik Df Chisq Pr(>Chisq)
## 1 1236   -457                    
## 2 1240   -460  4  5.67       0.23

Der Test ist nicht signifikant (p=0,23). Das bedeutet, dass die Annahme der equal slopes für die hier getesteten Rückwärts-Modelle beibehalten werden kann.

Nun können weitere Modellparameter bestimmt werden:

# 0-Modell (fuer pseudo R^2) Vorbereitungen
c0 =vglm(Stimmung ~ 1, data = mydata, family = cratio(parallel = T))
c0.ll =  logLik(c0)
crm.ll =  logLik(crm)
N =  length(mydata[, 1])  # Anzahl der Fälle
# R^2 McFadden
crm.mcfad =as.vector(1 - (crm.ll/c0.ll))
crm.mcfad
## [1] 0.1241
# R^2 Cox&Snell
crm.cox =as.vector(1 - exp((2/N) * (c0.ll - crm.ll)))
crm.cox
## [1] 0.2698
# R^2 Nagelkerke
crm.nagel =as.vector((1 - exp((2/N) * (c0.ll - crm.ll)))/(1 - exp(c0.ll)^(2/N)))
crm.nagel
## [1] 0.293
# Devianz
crm.devi =deviance(crm)
crm.devi
## [1] 920.5
# AIC
crm.aic =AIC(crm)
crm.aic
## [1] 930.5

Mit unserer Funktion von oben können wir uns die Modellparameter der Koeffizienten ausgeben lassen

# Konfidenzinztervalle
crm.ce =coef(summary(crm))
crm.ce
##               Estimate Std. Error z value
## (Intercept):1   0.1282    0.57259  0.2239
## (Intercept):2   2.0875    0.58094  3.5933
## (Intercept):3   4.0425    0.60636  6.6668
## Konflikt        0.4523    0.08488  5.3289
## Zufriedenh     -1.2563    0.18108 -6.9378
get.ci(as.numeric(crm.ce[4, ]))
##      Estimate   lCI    uCI      SD     z   p-value    OR
## [1,]   0.4523 0.286 0.6187 0.08488 5.329 9.881e-08 1.572
get.ci(as.numeric(crm.ce[5, ]))
##      Estimate    lCI     uCI     SD      z   p-value     OR
## [1,]   -1.256 -1.611 -0.9014 0.1811 -6.938 3.982e-12 0.2847

Links

Literatur

  • große Schlarmann, J.; Galatsch, M. (2014): “Regressionsmodelle für ordinale Zielvariablen”. GMS Medizinische Informatik, Biometrie und Epidemiologie, 10(1):2-10
  • Harrell, Frank: Regression Modeling Strategies: With Applications to Linear Models, Logistic Regression, and Survival Analysis. New York: Springer 2001.
  • Agresti, A: Analysis of Ordinal Categorical Data. New York: Wiley & Sons, 2nd edition 2010.
Posted in Professor Hastig | Leave a comment

[kile] Sweave-Werkzeug erstellen

Ich nutze den Kile-Editor für meine LaTeX Dokumente.
Innerhalb von LaTeX möchte ich gerne meinen R-Code bzw. dessen Ausgabe integrieren. Ich schreibe daher meine Latex- und R-Code in so genannte .Rnw-Dateien, welche ich (sofern alle R-Daten parat sind) in .tex übersetze und per pdflatex als PDF-Datei ausdrucke.
Für diesen Vorgang kann man in Kile einfach ein neues „Werkzeug“ erstellen. Naja,… eigentlich sind es 3 Werkezuge:

  1. ein Werkzeug, welches den Rnw-Code in tex übersetzt
  2. ein Werkzeug, welches die tex-Datei als PDF schreibt
  3. ein Built-Werkzeug, welches die ersten zwei Werkzeuge aufruft

Später brauch man dann „nur“ das Built-Werkzeug auf eine .Rnw-Datei anwenden.

Werkzeug „sweave“

  • Klicke auf „Einstellungen“ -> „Kile einrichten“ -> „Werkzeuge“ -> „Erstellen“ -> „Neu..“
  • gib ihm den Namen „Sweave“ und ändere „benutzerdefiniert“ in „PDFLatex“ um.
  • Schreibe in das Feld „Befehl“:
    R
  • Schreibe in das Feld „Optionen“:
    CMD Sweave '%source'
  • Die drei Häkchen müssen gesetzt sein.
    Auswahl_003
  • wechsle auf den Reiter „Erweitert“
  • „Typ“ = „Außerhalb von Kile ausführen“
  • „Klasse“ = „LaTeX“
  • Schreibe in das Feld „Erweiterung der Quelldatei“:
    Rnw
  • Schreibe in das Feld „Erweiterung der Zieldatei“:
    tex
  • lasse die anderen Felder leer
  • Auswahl_002
  • speichere das neue Werkzeug mit „Ok“

Werkzeug „PDFlatexFromSweave“

  • Klicke auf „Einstellungen“ -> „Kile einrichten“ -> „Werkzeuge“ -> „Erstellen“ -> „Neu..“
  • gib ihm den Namen „PDFlatexFromSweave“ und ändere „benutzerdefiniert“ in „PDFLatex“ um.
  • Schreibe in das Feld „Befehl“:
    pdflatex
  • Schreibe in das Feld „Optionen“:
    -interaction=nonstopmode -synctex=1 '%S.tex'
  • Die drei Häkchen müssen gesetzt sein.
  • wechsle auf den Reiter „Erweitert“
  • „Typ“ = „Außerhalb von Kile ausführen“
  • „Klasse“ = „LaTeX“
  • Schreibe in das Feld „Erweiterung der Quelldatei“:
    tex
  • Schreibe in das Feld „Erweiterung der Zieldatei“:
    pdf
  • lasse die anderen Felder leer
  • speichere das neue Werkzeug mit „Ok“

Built-Werkzeug

  • Klicke auf „Einstellungen“ -> „Kile einrichten“ -> „Werkzeuge“ -> „Erstellen“ -> „Neu..“
  • gib ihm den Namen „QuickSweave“ und ändere „benutzerdefiniert“ in „Quickbuilt“ um.
  • Auswahl_004
  • Wähle nun aus dem „Werkzeug“-Dropmenü die neuen Werkzeuge „sweave“ und „PDFlatexFromSweave“ aus, und klicke jeweils auf „Hinzufügen“.
  • Auswahl_006
  • Klicke auf „OK“ um das Built-Werkzeug zu speichern.

Jetzt kann man das neue Built-Werkzeug „QuickSweave“ anwenden, um .Rnw-Dateien in PDF umzuwandeln.

Weblinks

Quelle: http://danielfischer.name/index.php?id=382

Posted in Arch, LaTeX, Ubuntu, ubuntuusers | Leave a comment

MediaWiki: alle Seiten einer Kategorie plus Unterkategorien als PDF exportieren

Ich habe ein kleines php-Script geschrieben, mit welchem man alle Seiten einer Kategorie inklusive der Seiten aller Sub-Kategorien von einer beliebigen MediaWiki-Instanz als PDF exportieren kann.
Benötigt werden PHP>5.5, wkhtmltopdf und pdftk (müssen evtl. erst installiert werden).

https://github.com/produnis/myscripts/blob/master/PHP/mwc2pdf.php

Ihr müsst am Anfang des Scripts die drei Variablen euren Bedürfnissen entsprechend anpassen, und dann das Script aufrufen per:

$ php /Pfad/zu/mwc2pdf.php

Das Script nutzt nun die „api.php“ der MediaWiki-Instanz und erstellt damit einen „Pagetree“. Von diesem Pagetree wird jede einzelne Seite mittels wkhtmltopdf in eine PDF-Datei exportiert.
Anschließend werden alle erzeugten PDF-Dateien mittels pdftk zu einer einzelnen Datei namens „MWC2PDF.pdf“ zusammengeführt.

$ nano mwc2pdf.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
< ?php
## Welcome to mwc2pdf
## ----------------------------------------------
## Media Wiki Category To PDF (MWC2PDF)
## is a php script that exports a Category from MediaWiki
## into PDF, including all Pages of that category as well as
## all pages from subcategories.
## mwc2pdf uses MediaWiki's "api.php" to collect
## all data and create a "pagetree".
## mwc2pdf prints out every item of that pagetree
## into a single pdf-file using "wkhtmltopdf".
## It than combines all single pdf-files into
## one single pdf-file called "MWC2PDF.pdf" using "pdftk".
##
## -----------------------------------------------
## Requires:
## - PHP >= 5.4
## - wkhtmltopdf
## - pdftk
## -------------------------
## Written by Joe Slam 2015
## Licence: GPL
## -------------------------
##
## Usage:
## 1) Change the three lines to fit your situation
## 2) open terminal
## 3) $ php /PATH/TO/mwc2pdf.php #
##
## All files are generated in the directory you call mwc2pdf from
##
####################################################################
# + + + + + + + + + + + + + + + + + + + + + + +
## Change this vars to fit your system
$mywiki = "http://192.168.0.2/produniswiki/"; // URL to index.php
$kategorie = "Kategorie:Hauptkategorie"; // Which Category to grab?
$kategorie_word = "Kategorie:"; // What is "Category:" in your wiki's language?
# + + + + + + + + + + + + + + + + + + + + + + +
# ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
## Dont change after here...
# ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
##----------------------------------------------
## API -Commands
#------------------
# List all Subcategories
$cmd_subcat = "api.php?action=query&format=xml&list=categorymembers&cmlimit=5000&cmtitle=";
# List all Pages of Category
$cmd_catinfo = "api.php?action=query&format=xml&prop=categoryinfo&titles=";
# Get URL from pageid
$cmd_geturlfromID = "api.php?action=query&format=xml&inprop=url&prop=info&pageids=";
# Functions
#-------------------
#-----------------------------------------------------------------------
function getCategoryID($xml){
# this function returns the pageid of a category
$arr=$xml->query[0]->pages[0]->page->attributes();
#echo $arr["pageid"] . ": ";
#echo $arr["title"] . "\n";
return($arr["pageid"]);
}
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
function startsWith($haystack, $needle)
{ # this function checks if the string
# "$hayshack" starts with the letters "$neddle"
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
#-----------------------------------------------------------------------
function wikiHTMLprint($command){
# This function takes a pageid and
# returns the "printable"-URL of that
# page/category
$xml = simplexml_load_file($command);
$arr = $xml->query[0]->pages[0]->page->attributes();
$output= str_replace("&action=edit", "&printable=yes", $arr['editurl']);
return($output);
}
#---- end of functions --------------
#### M A I N S C R I P T
#-------------------------
echo "\n\nCollecting data for " . $kategorie ."\n\n";
# Get pageid of start-category
$xml = simplexml_load_file($mywiki . $cmd_catinfo . $kategorie);
$current_parent = getCategoryID($xml);
# Setting up all important vars() and arrays()
#---------------------------------------------
$x = 0;
$y = 0;
$done = FALSE;
$the_pageids = NULL;
$the_names = NULL;
$loop_list = NULL;
$next_level = 0;
$current_level = 0;
$the_pageids[0] = $current_parent;
$the_names[0] = $kategorie;
$the_prefix[0] = "p0_";
$the_parentid[0] = 0;
$the_level[0] = 0;
$is_category[0] = "C";
$loop_list[0] = $kategorie;
$loop_id[0] = $current_parent;
$loop_prefix[0] = "p0_";
//---------------------------------
$x++;
# MAIN LOOP
#----------------------
while ($done == FALSE){
// get pageid of current category
$current_parent = $loop_id[$y];
# getting members of this category
//-------------------------------------------------------------
$xml = simplexml_load_file($mywiki . $cmd_subcat . $loop_list[$y]);
foreach($xml->query[0]->categorymembers[0]->cm as $child){
$arr = $child->attributes();
#echo $arr["pageid"] . ": ";
#echo $arr["title"] . "\n";
// is this a Page?
//---------------------------------------------------
if(startsWith($arr["title"], $kategorie_word) == FALSE){
if(
(startsWith($arr["title"], "Datei:") == FALSE) AND
(startsWith($arr["title"], "File:") == FALSE) AND
(startsWith($arr["title"], "Media:") == FALSE) AND
(startsWith($arr["title"], "Bild:") == FALSE)
){
// is page already in list?
if(in_array("" . $arr["title"] . "", $the_names)){
#echo "page " . $arr["title"] . " already in list \n";
}else{
#echo "new Page";
$the_pageids[$x] = $arr["pageid"];
$the_names[$x] = $arr["title"];
$the_parentid[$x] = $current_parent;
$the_level[$x] = $current_level;
$the_prefix[$x] = $loop_prefix[$y] . sprintf('%05d',$x);
$is_category[$x] = "P";
}
}else{ $x--; }
//----------------------------------------------------
// is this a Category?
//----------------------------------------------------
}elseif(startsWith($arr["title"], $kategorie_word) == TRUE){
// is Category already in list?
if(in_array("" . $arr["title"] . "", $the_names)){
#echo "cat " . $arr["title"] . " already in list \n";
}else{
#echo "new Category";
$loop_list[] = $arr["title"];
$loop_id[] = $arr["pageid"];
$loop_prefix[] = $loop_prefix[$y] . sprintf('%05d',$x) . "_";
$the_pageids[$x] = $arr["pageid"];
$the_names[$x] = $arr["title"];
$the_prefix[$x] = $loop_prefix[$y] . sprintf('%05d',$x) . "_";
$the_parentid[$x] = $current_parent;
$the_level[$x] = $current_level+1;
$is_category[$x] = "C";
}
}
//----------------------------------------------------
$x++;
} // END foreach
$y++;
$current_level++;
if($y == sizeof($loop_list)+2){
$done=TRUE;
}
//--------------------------------------------------------------
} // End WHILE false
// END Main Loop
#############################################################################
# # # # S O R T D A T A # # # # # # #
#--------------------------------------------
array_multisort($the_prefix, $the_pageids, $the_names, $the_parentid, $the_level,$is_category);
#--------------------------------------------
# # # # # # # # # # # # # # # # # # # # #
#--- output final array ---
echo "\nThis is what I got:\n";
$i = count($the_prefix);
echo $i;
for ($x =0;$x < $i; $x++){
echo $the_prefix[$x] . "|" . $is_category[$x] . "| ". $the_pageids[$x] . ": " . $the_names[$x] . " | Lev=" . $the_level[$x] . " (P=" . $the_parentid[$x] . ")\n";
}
#--------------------------------------------
## print PDF of Cats and Pages
## depends: wkhtmltopdf
#---------------------------------------------
echo "\nPrinting single Pages to PDF (wkhtmltopdf)\n";
$i = count($the_prefix);
echo "\n";
for ($x =0;$x < $i; $x++){
$command = $mywiki . "" . $cmd_geturlfromID . "" . $the_pageids[$x];
$this_pdf = wikiHTMLprint($command);
echo "Printing pageid " . $the_pageids[$x] . " | (" . $x . "/" . $i . ")\n";
$command = "wkhtmltopdf '" . $this_pdf . "' " . sprintf('%06d',$x) . "-" . $the_prefix[$x] . "-" . $is_category[$x] . "_" . $the_pageids[$x] . ".mwc2pdf.pdf";
$out = shell_exec($command);
echo "\n";
}
#---------------------------------------------
## cats the PDFs into a single one
## depends: pdftk
#---------------------------------------------
# $dummy = shell_exec("wkhtmltopdf http://google.com google.pdf");
echo "\nGenerating single PDF-file (pdftk)\n";
$command = "pdftk *.mwc2pdf.pdf cat output MWC2PDF.pdf";
$out = shell_exec($command);
## -------------------------------------------------------
echo "\nDone.\n";
?>
Posted in Jean Pütz, Professor Hastig, ubuntuusers | Leave a comment

cairo-dock hat unter xfce4.12 einen Schatten

Seit dem Update auf xfce4 wirft das Cairo-Dock einen komischen Strich auf meinen Desktop.
cairoschatteen

Das Ganze ist eine Einstellungssache von xfce4.

Gehe in den Einstellungen zu xfce4-settings | Window Manager Tweaks | compositor und entferne den Haken bei „Schatten unter Leisten anzeigen
Feineinstellungen der Fensterverwaltung_001

Posted in Arch, ubuntuusers | 1 Comment

Vectrex-Emulator „parajve“

Der Vectrex-Emulator „parajve“ kommt mit einem Haufen Spielen vorinstalliert daher!

Vectrex

Ein Hoch auf die 80er!

Installation

Arch:

pacaur -S parajve

Weblinks

Posted in Arch, Jean Pütz | Leave a comment

[arch] Day of Install

Um unter Arch herauszufinden, wann genau das System erstmals installiert wurde, kann man wie folgt vorgehen:

  • head /var/log/pacman.log
Posted in Arch, Jean Pütz, Professor Hastig | Leave a comment

[Arch]: top auf alte Default-Einstellung zurücksetzen

Seit dem letzten Arch-Update sieht die top-Ausgabe nicht mehr wie gewohnt aus.
scaled_full_099441bc0fee28ef73e1
Um den Status quo wieder herzustellen geht man wie folgt vor:

  • lösche (falls vorhanden) die Datei ~/.toprc
  • starte „top
  • drücke z (kleines z!)
  • drücke V (großes V!)
  • drücke 1 (die Zahl Eins)
  • drücke y
  • drücke m m
  • drücke t t t
  • drücke W (großes W! …dies schreibt eine neue Config-Datei ~/.toprc).

Danke an procps-ng-sucks

Weblinks

Posted in Arch, Ubuntu, ubuntuusers | Leave a comment

[gthumb] Bilder nach exif-Datum umbenennen

Mittels gthumb wähle ich die entsprechenden Bilder aus, drücke F2 und gebe folgenden Code ein:
%M{%Y-%m-%d, %T}_%F.%E

So werden die Bilder entsprechend ihres EXIF-Datums umbenannt, aus „DSC_0252.jpg“ wird „2014-10-18, 16:16:14_DSC_0252.jpg

Posted in Arch, Professor Hastig, Ubuntu | Leave a comment

[Ubuntu] Boot-Repair

Habe mir heute nach einem Festplattenwechsel den Bootloader zerschossen.

Musste aber nur per Livestick booten und dann „boot-repair“ installieren:

sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair
boot-repair

bootrepair
Das Programm erkennt automatisch was wo installiert ist, und repariert die Bootloader entsprechend.
Ich fans das ungemein hilfreich…

via

Posted in dev/null, Ubuntu, ubuntuusers | Tagged , , | 2 Comments
« Older