Unix-Timestamp in JavaScript formatieren

Um ein Unix-Timestamp mit JavaScript zu formatieren, habe ich mir folgendes Objekt geschrieben:

var timeFormat = {
    /**
     * Output format.
     *
     * d - current day
     * m - current month
     * Y - current Year
     *
     * H - current hour (24 hour system)
     * i - current minute
     * s - current second
     */
    displayFormat: 'd.m.Y - H:i:s',

    /**
     * Format given unix-timestamp
     */
    format: function(timestamp) {
        // convert unix timestamp to javascript date object
        var d = new Date(timestamp * 1000);
        var output = this.displayFormat;
        
        output = output.replace(/d/g, this.padZero(d.getDate()))
            .replace(/m/g, this.padZero(d.getMonth()+1))
            .replace(/Y/g, d.getFullYear())
            .replace(/H/g, this.padZero(d.getHours()))
            .replace(/i/g, this.padZero(d.getMinutes()))
            .replace(/s/g, this.padZero(d.getSeconds()));

        
        return output;

    },
   
    /**
     * add zero paddings to numbers smaller than 10
     */
    padZero: function(number) {
        if (number < 10) {
            return "0" + number.toString();
        }
        
        return number;
    }
};

Die Benutzung ist ziemlich einfach:

// schreibt 13.09.2011 - 13:30:23
document.write(timeFormat.format(1318473023));

Man kann das Ausgabeformat über das timeFormat.displayFormat Feld steuern:

timeFormat.displayFormat = 'H:i'; // gibt nur Stunden und Minuten aus
document.write(timeFormat.format(1318473023)); // schreibt 13:30

Wie bereits oben beschrieben sind folgende Zeichen möglich (auch mehrfach)

    /**
     * Ausgabeformat
     *
     * d - aktueller Tag
     * m - aktueller Monat
     * Y - aktuelles Jahr
     *
     * H - aktuelle Stunde
     * i - aktuelle Minute
     * s - aktuelle Sekunde
     */
 

JavaScript Timers mit jQuery

Timer in JavaScript zu realisieren ist eigentlich recht leicht, dazu braucht mal nur die Funktionen window.setTimeout bzw. window.setInterval mit entsprechenden Argumenten zu füttern.

// funktion verzögert aufrufen
function machWas() {
   alert('alert() mit 1000ms verzögerung!');
}
window.setTimeout(machWas, 1000);

// funktion alle X Millisekunden aufruden
function machWasOft() {
   alert('alle 1000ms ein alert()');
}
window.setInterval(machWasOft, 1000);

Doch was ist, wenn ich jetzt einen solchen Timer ändern oder abbrechen möchte? Das ist eigentlich auch nicht schwer – die Funktionen setTimeout/setInterval geben ein Objekt zurück über das sie sich wieder beenden lassen.

var x = 0;
function machWasAbbrechbarOft() {
    x += 1;
    if (x > 200) {
        window.clearInterval(running); // beende das "Interval" nach 201 Ausführungen
    }
}
var running = window.setInterval(machWasAbbrechbarOft, 1000);

Das funktioniert in kleinen JavaScript Codes sicher ohne Probleme, wenn man allerdings an einem großem JavaScript Projekt arbeitet, macht es die Arbeit nicht gerade leichter wenn man immer dieses Rückgabe-Objekt (im Beispiel running) irgendwo speichern muss, vorallem wenn man von überall im Code darauf zugreifen will.

Um dieses Problem zu lösen habe ich ein jQuery Timer Plugin gefunden. (Siehe http://plugins.jquery.com/project/timers) Wer an einem größerem JavaScript Projekt arbeitet, sollte meiner Meinung nach aufjedenfall auf ein Framework setzen – jQuery ist hier meine Wahl von daher bietet sich dieses Plugin an.

Mit diesem Plugin geht das „Interval“ setzen dann wie folgt:

$(document).everyTime(1000, "machWasOftAbbrechbar", function(i) { // alle 1000ms
  alert('Hallo ich bin der ' + i + 'te Aufruf!'); // machWasOftAbbrechbar, hier die funktion die aufgerufen werden soll
}, 200); // 200 mal ausführen

Der zweite Parameter, machWasOftAbbrechbar, stellt hierbei ein sogenanntes „label“ dar, über das man den gestarten Timer dann wieder abbrechen kann:

$(document).stopTime("machWasOftAbbrechbar"); // stoppe machWasOftAbbrechbar

Viel mehr gibt’s eigentlich nicht dazu zu sagen – die Dokumentation dazu findet man, genau wie das Plugin selbst, unter http://plugins.jquery.com/project/timers.

 

JavaScript und Geolocation

Seit Firefox 3.5, Opera 10.60 bzw. Safari/Webkit 5 ist es möglich per JavaScript mit Einverständniss des Benutzers seine Position zu ermitteln. Die Position wird dann entweder über eine angeschlossene GPS-Antenne oder über die verfügbaren WLans ermittelt. Die API dafür ist sehr leicht zu benutzen.

Zunächst sollte geprüft werden ob der benutzte Browser Geolocation unterstützt. Das geht wie folgt:

if (!navigator.geolocation) {
	alert('Sorry, dein Browser unterstützt keine Geolocation-API');
}

Jetzt ist es möglich die aktuelle Position abzufragen:

navigator.geolocation.getCurrentPosition(function(position) {  
	alert('Deine aktuelle Position ist: Lat: ' + position.coords.latitude + ' Long: ' + position.coords.longitude);  
}, function(error) { alert('Fehler beim finden der Position. Fehler: ' + error.message); });

und bei jeder Änderung der Position erneut ein Event auszulösen:

var = locationHandler = navigator.geolocation.watchPosition(function(position) {  
	alert('Deine neue Position ist: Lat: ' + position.coords.latitude + ' Long: ' + position.coords.longitude); 
}, function (e) {}, {enableHighAccuracy:true, maximumAge:120 * 1000, timeout:27000});

Hierbei kann man angeben

  • enableHighAccuray: ob man auf hohe Genauigkeit setzen möchte (sofern diese vom Gerät unterstützt wird)
  • maximumAge: (in ms) wie alt die letzte Position maximal sein darf – je kleiner dieser Wert, desto öfterst wird auf dem Gerät die aktuelle Position abgefragt.
  • timeout: (in ms) wann die Positionsbestimmung abgebrochen werden soll wenn sie nicht erfolgreich ist

Wenn man die Positionsüberwachung wieder abbrechen will, hilft folgender API-Call weiter:

navigator.geolocation.clearWatch(locationHandler);

Sehr nützlich, vorallem wenn man eine Webseite für Smartphones bastelt 😉

 

Zippyshare Downloads Automatisieren *update*

Kurz nachdem ich den letzten Beitrag über zippyshare veröffentlicht habe, hat die Seite wieder umgestellt auf einen anderen „Schutz“ der Downloadlinks. Diesmal ist es aber ziemlich einfach an diese zu geraten, man muss nur nach documents.getElementById(‚dlbutton‘).href = „…“ suchen. Dort findet sich in Klammern ein einfacher mathematischer Ausdruck, der in fasst jeder Programmiersprache mit einem Einzeiler ausgeführt werden kann.

 

Zippyshare Downloads automatisieren

Zur Zeit arbeite ich an einem Downloadmanager, der alle gängigen Download-Seiten unterstützen soll. Neulich hat zippyshare.com etwas eingebaut um genau diesen „automatischen“ Downloads einen Riegel vorzuschieben: Der Download-Link wird jetzt per JavaScript „verschlüsselt“. Ich werde jetzt hier keinen Beispiel-Zippyshare-Downloadlink posten, das findet man mit etwas googlen schnell selbst 😉

Nun möchte ich erläutern, wie ich den Download-Link automatisch auslese:
Zuerst entnehme ich der Seite per Regulärem Ausdruck die benötigten JavaScript Variablen:
xHTML-Code der Stelle

var zipdata = eval(eval(eval(((function() {var parzDiXdet= (((function() {var hutByDojpZ= eval(379);var BvLCmMYDEQB= ((function() {var qefrKDjxbJ= eval(51);var DKbCbnceoJN= ((((18+(3*3)))+((function() {var kzCDpmQUwq= eval(eval(43));var UoRHKeZvyaH= 23;return (kzCDpmQUwq+UoRHKeZvyaH)})())));return (qefrKDjxbJ+DKbCbnceoJN)})());return (hutByDojpZ+BvLCmMYDEQB)})())*eval((19*eval(29)+((eval((eval(3)*3))+(((function() {var fhYCresaSD= 0;var XRIVTZgfbzF= eval(2);return (fhYCresaSD+XRIVTZgfbzF)})())*eval(3)+1)))))+468);var MpIWcCCkdZo= (((function() {var ciqbBKFBYW= eval(80);var aAZRNKwkocE= 242;return (ciqbBKFBYW+aAZRNKwkocE)})())*(3*(8*eval(32)+(1*((function() {var yMgeUqevwX= ((function() {var CIechCiWBN= 0;var GoKsZmkLAMw= ((function() {var JYpKjwyxxu= 0;var YfDpdwhpscp= 2;return (JYpKjwyxxu+YfDpdwhpscp)})());return (CIechCiWBN+GoKsZmkLAMw)})());var FklyvoQTPho= eval(eval(2));return (yMgeUqevwX+FklyvoQTPho)})())))+eval(eval((1*((0+eval(2)))))))+261);return (parzDiXdet+MpIWcCCkdZo)})()))));
var fulllink = 'http://www123.zippyshare.com/d/123456789/'+zipdata+'/Alarmclock.mp3';
document.getElementById('dlbutton').href = fulllink;

Regexp zum auslesen

$aFind = StringRegExp($ZippySrc, "s*(var zipdata = .*;)s*var fulllink = '(.*)';s*document", 1)

Nun muss die Variable „zipdata“ evaluiert werden. Dies mache ich wie folgt:

;
;
; Evaluate zippyshare.com JavaScript
;
; Coded by www.agrafix.net
;
;
Func _JSParse_Parse($sJavaScript)
	For $_x = 0 To 50

		If StringRegExp($sJavaScript, "var zipdata = ([0-9]*);") Then
			ExitLoop
		EndIf

		$sJavaScript = _JSParse_NumericVariableDeclarations($sJavaScript)
		$sJavaScript = _JSParse_EvaluateEasyMath($sJavaScript)
		$sJavaScript = _JSParse_SimpleEvals($sJavaScript)
		$sJavaScript = _JSParse_SimpleFunctions($sJavaScript)
	Next

	$m = StringRegExp($sJavaScript, "var zipdata = ([0-9]*);", 1)

	Return $m[0]

EndFunc

Func _JSParse_SourceReplace($aArray, $sJavaScript)
	For $i = 0 To UBound($aArray) - 1 Step 2
		$sJavaScript = StringReplace($sJavaScript, $aArray[$i], $aArray[$i+1])
	Next

	Return $sJavaScript
EndFunc

Func _JSParse_NumericVariableDeclarations($sJavaScript)
	$aNumDeclarations = StringRegExp($sJavaScript, "var ([a-zA-Z0-9_-]*) ?= ([0-9]*);", 3)

	$sJavaScript = StringRegExpReplace($sJavaScript, "var ([a-zA-Z0-9_-]*) ?= ([0-9]*);", "")

	$sJavaScript = _JSParse_SourceReplace($aNumDeclarations, $sJavaScript)

	Return $sJavaScript
EndFunc

Func _JSParse_EvaluateEasyMath($sJavaScript)

	While StringRegExp($sJavaScript, "(([0-9]*?[+-*/]?[0-9]*[+-*/][0-9]*))")

		$aMatches = StringRegExp($sJavaScript, "(([0-9]*?[+-*/]?[0-9]*[+-*/][0-9]*))", 3)

		For $i = 0 To UBound($aMatches) - 1
			$Result = Execute($aMatches[$i])

			$sJavaScript = StringReplace($sJavaScript, "(" & $aMatches[$i] & ")", $Result)
		Next

	WEnd

	Return $sJavaScript

EndFunc

Func _JSParse_SimpleEvals($sJavaScript)

	While StringRegExp($sJavaScript, "eval(([0-9]*))")

		$aMatches = StringRegExp($sJavaScript, "eval(([0-9]*))", 3)

		For $i = 0 To UBound($aMatches) - 1
			$sJavaScript = StringReplace($sJavaScript, "eval(" & $aMatches[$i] & ")", $aMatches[$i])
		Next

	WEnd

	$sJavaScript = StringRegExpReplace($sJavaScript, "(([0-9]{1,11}))", "$1")

	Return $sJavaScript
EndFunc

Func _JSParse_SimpleFunctions($sJavaScript)

	$sJavaScript = StringRegExpReplace($sJavaScript, "(function() {return ([0-9]*)})()", "$1")

	Return $sJavaScript
EndFunc

Nun muss ich die Funktion nur noch mit den obigen Werten aus meiner RegExp aufrufen, die JavaScript Variable „fulllink“ anpassen und aufrufen:

$url = StringReplace($aFind[1], "'+zipdata+'", _JSParse_Parse($aFind[0]))
INetGet($url, "Alarm.mp3")

Das war’s auch schon. Alle Source-Codes sind in AutoIT. Natürlich ist _JSParse kein funktionierender JavaScript Parser, sondern einfach nur eine Funktionssammlung die eben diesen Zippyshare-JavaScript-Haufen evaluieren kann 😉

Der obige Source-Code darf natürlich verwendet, verändert und verteilt werden, ich bitte legendlich um einen kleinen Hinweis auf den Ursprung (http://www.agrafix.net).

 

jQuery in Greasemonkey

Wer kennt das nicht? Man möchte ein Greasemonkey-Script schreiben und würde dabei gerne auf jQuery zurückgreifen. Außerdem verwendet die betreffende Seite bereits jQuery, das heißt man müsste dieses Script eigentlich gar nicht mehr nachladen. Doch wie kann man auf die bereits vorhandene jQuery-Instanz zugreifen? Ganz einfach:

var $ = unsafeWindow.jQuery;

Das steht zu beginn des Scripts und nun kann man wie immer per $ auf alle jQuery Funktionen und Elemente der Seite zugreifen.

In diesem Zuge möchte ich gleich noch zwei neue UserScripts für das Browserspiel Die-Stämme vorstellen, die ich heute veröffentlicht habe und welche ebenfalls auf die genannte Technik zurückgreifen:

[DS] Save Attack

Ermöglicht es im Versammlungsplatz die gewählen Einheiten zu speichern um bei einem weiteren Angriff mit gleichen Truppen anzugreifen

Download & Install

[DS] Menu Resort

Dieses Script sortiert die ingame Die-Stämme Menüleiste so um wie sie früher war (vor Version 7.x)

Download & Install

 

Visitor-Stats.de Update

Heute habe ich endlich mal wieder ein Update für visitor-stats.de fertiggestellt. Große optische Änderungen sind wohl nicht zu erkennen, dennoch wurde hinter den Kulissen einiges verändert. Die JavaScripts basieren jetzt auf jquery und die AJAX-API gibt json-formatierte Antworten. Außerdem habe ich einen „loadscreen“ eingebaut, der bei gesendeten AJAX-Requests erscheint.

Das Projekt ist unter http://www.visitor-stats.de zu finden.

Für die Realisierung der AJAX-API mit json Antworten habe ich json_encode() benutzt.

 

in_array() für Javascript

Da in_array() eine nützliche Funktion in PHP ist, habe ich sie für JavaScript umgeschrieben:

Array.prototype.in_array = function(search) {
	for(var i=0; i < this.length; i++) {
		if (this[ i] === search) {
			return true;
		}
	}

	return false;
}

Die Funktion wird wie folgt angewendet:

var arr = new Array("rock", "and", "roll");
alert(arr.in_array("rock")); // -> true
alert(arr.in_array("pop")); // -> false
alert(arr.in_array("nd")); // -> false

Viel Vergnügen damit 😉