Dev

Alles was man so „Developen“ kann…

Facebook RSS-App die Zweite…

Nachdem Facebook im Mai die Permanenten Tokens abgeschafft hat, musste ich meine RSS-Ping-Applikation gezwungenermaßen aktualisieren.

Der neue Authentication-Flow sieht es leider nicht mehr vor, dass eine Applikation ohne eingeloggten Benutzer agiert.

Daher ein kleines Update. Das neue Skript funktioniert nur noch mit einem Server im Hintergrund, während es bei dem alten Skript noch möglich war lokal zu testen ist man nun leider dazu gezwungen scharf zu schießen. (Macht es halt etwas umständlicher, imho.)

Zum Anmelden der neuen Applikation benötigt man nun nur noch folgende Rechte:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=manage_pages,create_note&response_type=token

# manage_pages für Seitenverwaltung
# create_note um Notizen posten zu dürfen

Und der zugehörige Code der Applikation in Perl:

#!/usr/bin/perl
use strict;
use LWP::Simple;            # Für Get-Anfragen an Facebook
use CGI;                    # Zum Auswerten der Parameter
use JSON;                   # Zum Auswerten der Antworten
use URI::Escape;            # Zum Escapen der Nachrichten

my $q = CGI->new();	    # Neuer Query

# Anwendungs-ID
my $client_id = '123456789012345';

# Anwendungs-Secret
my $client_secret = '1234a56b789012cde345678a90123b45';

# Fan-Page ID
my $page_id = '123456789012';

# Ort des Skripts 
# Muss mit Redirect_URI übereinstimmen und im
# App-Domain Raum liegen.
my $script_location = $q->url();

# Solange, wie der Parameter "Code" nicht angegeben ist.
unless($q->param('code')) {
	my $code_query = "https://www.facebook.com/dialog/oauth?" .
    "client_id=" . $client_id .
   "&redirect_uri=" . $script_location .
   "&response_type=code";

	print $q->redirect($code_query);
	exit;
}
else {
	if($q->param('code') eq "") {
		print $q->header(-status=>406),
		$q->start_html('Problems'),
		$q->h2('No Coffee for you.'),
		$q->strong('Code was empty... User not logged in?');
		exit 0;
	}
	
	my $token_query = "https://graph.facebook.com/oauth/access_token?" .
    "client_id=" . $client_id . 
   "&redirect_uri=" . $script_location .
   "&client_secret=" . $client_secret .
   "&code=" . $q->param('code');

	my $app_token = get($token_query);
	&post_news($app_token);
	exit;
}
exit; 

   
sub post_news($) {   
	# Application Token
	my $token = shift;
	
	# Betreff
	# Achtung! Lazy auf UTF8 konvertieren, sonst
	# werden Umlaute nicht richtig dargestellt.
	my $subject = uri_escape_utf8('Nur ein Test');

	# Nachricht
	my $message = uri_escape_utf8('Testnachricht...<br>Hallo Welt!');

	# Liste der Accounts (der verwalteten Seiten / Apps ...) holen
	# und Token für die Seite suchen.
	my $accounts = get('https://graph.facebook.com/me/accounts?' . $token);

	unless($accounts)
	{
		print $q->header(-status=>407),
		$q->start_html('Problems'),
		$q->h2('This should (hopefully) never happen...'),
		$q->strong('Accounts was undefined - Maybe wrong token?');
		exit 0;
	}

	my %data = %{decode_json($accounts)};
	my $page_access_token = "";

	foreach my $access_page (@{$data{'data'}})
	{
		my %item = %{$access_page};
		if($item{'id'} eq $page_id) {
			$page_access_token = $item{'access_token'};
		}
	}

	if(!defined $page_access_token || $page_access_token eq "")
	{
		print $q->header(-status=>408),
		$q->start_html('Problems'),
		$q->h2('No access token...'),
		$q->strong('manage_pages privilege removed? Try granting it again!');
		exit 0;
	}

	# Nachricht posten
	my $news_id = get('https://graph.facebook.com/' . $page_id .
               '/notes?message='. $message .
               '&subject=' . $subject .
               '&method=post&access_token=' . $page_access_token);

	print $q->header(-status=>200),
	$q->start_html('Great Success'),
	$q->h2($news_id . " posted!");
	exit;
}

Sollte man ausgeloggt werden, reicht ein einfaches:

https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=ALTES_TOKEN

für den Relogin. (natürlich muss dann das alte pseudo perma Token durch das Neue ersetzt werden.)

Firefox – Probleme mit Unicodedarstellung

Firefox kennt plötzlich keine Dingbats mehr (quick-and-dirty)

Heute meinte mein Firefox plötzlich kein UTF-8 mehr zu können. Okay, ganz stimmt das nicht, UTF-8 konnte er noch – jedoch wurden Sonderzeichen aus bestimmten Bereichen (u+2700 Dingbats) nicht mehr dargestellt.

Anstelle den normalen Zeichen erhielt ich nur noch gesperrte Leerzeichen als Ausgabe.

Nach etwas Recherche erhärtete sich der Verdacht, dass eine defekte Schriftart dafür der Grund ist. Diese muss irgendwie zusammen mit der letzten Office 2007 Installation und entsprechenden Updates auf mein System geraten sein, denn davor ging alles noch ohne Probleme.

Die Besonderheit beim Firefox ist, dass er sich die – für ihn am besten aussehende – Repräsentation aus den Schriftarten aussucht, die die Zeichen darstellen kann. Für UTF-8 gibt es keine bevorzugten Schriftarten, wie zum Beispiel bei Kyrillisch, Griechisch oder Ähnlichem. (about:config font.name-list… oder im Schriftarten-Dialog unter Darstellung)

Für UTF-8 benutzt der Firefox, genau wie Thunderbird und andere Mozilla-Produkte die Einstellungen aus „Andere Sprachen“. Enthält die dort eingestellte Schriftart (z.B. für Serif – Times New Roman) keine Darstellung für die gesuchten Zeichen wird aus der Liste der installierten Schriftarten die nächst Beste genommen, die die Zeichen „vermutlich“ (wo der darzustellende Bereich nicht gesperrt ist) darstellen kann.

In meinem Fall scheint genau diese Schriftart aber an den besagten Stellen nur gesperrte Leerzeichen (also nix) zu enthalten, der Bereich selber ist jedoch nicht gesperrt.

Beheben lässt sich dies, in dem man für Serif zum Beispiel eine Schriftart auswählt, welche an besagten Stellen keine Leerzeichen aufweist. (Wie zum Beispiel die wundervolle kostenlose Schriftart DejaVu Sans)

Quick-And-Dirty
Der „Fix“ ist natürlich sehr sehr quick-and-dirty (schnell-und-unsauber), da er das eigentliche Problem, die „defekte“ Schriftart, bzw. die Firefox Auswahl Dieser als bessere Repräsentation, nicht behebt, jedoch kann man so wenigstens wieder sicher sein alle Zeichen zu sehen, die auch wirklich da seien sollten.

Eine sauberere Lösung wäre die besagte Schriftart, wenn nicht benötigt, zu entfernen oder durch eine vollständige Unicode Schriftart zu ersetzen.

Update: Die besagte Schriftart ist jpn_boot (oder eine der anderen _boot-Schriftarten), welche wohl durch die unbeaufsichtigte Installation von Windows Vista oder 7 auf die Festplatte kommt. Zu sehr geringer Wahrscheinlichkeit fällt die Firefox Auswahl genau auf diese. Festzustellen mit dem Addon „Font Info[1].

Bisher gibts diesbezüglich 2 offene Bugpostings[2][3] bei Mozilla. Mal schaun, was sich da noch tut. 🙂


[1] https://addons.mozilla.org/en-US/firefox/addon/fontinfo/
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=91190
[3] https://bugzilla.mozilla.org/show_bug.cgi?id=713595

Mystique und die Probleme mit dem M�rz

Irgendwie hat Mystique (das Theme was ich hier einsetze) manchmal Probleme mit den Monatsnamen. Keine Ahnung ob es an irgendeiner Fehlkonfiguration von mir liegt oder so, jedoch hat bei mir beim Monat März in der Standardinstallation einen kleinen Schönheitsmakel (Remember that „Schei� Encoding“ shirt?!).

Beheben lässt sich dieser durch 2 kleine Änderungen.

Einer Extended „archive.php“ die den selben Inhalt trägt, wie die normale archive.php, mit dieser Zeile anstelle des alten Datumsstrings:

<h1><?php atom()->te('Archive for %s', sprintf('%s', $wp_locale->get_month(get_the_time('n')) . " " . get_the_time('Y'))); ?>

und einer kleinen Änderung der Funktion getDate() in der atom-core.php

 /*
 * Return the post date
 *
 * @since 1.0
 * @param string $mode
 * @return string
 */
 public function getDate($mode = ''){

 // 'relative' or a date string like 'd-M-Y'
 $mode = empty($mode) ? atom()->options('post_date_mode') : $mode;

 if($mode === 'absolute')
 $mode = get_option('date_format');
 // date_i18n($mode, strtotime(get_the_time('Y-m-d', $this->data->ID)))
 // was get_the_time($mode, $this->data->ID)
 return ($mode !== 'relative') ? date_i18n($mode, strtotime(get_the_time('Y-m-d', $this->data->ID))) : atom()->getTimeSince(abs(strtotime("{$this->data->post_date} GMT")));
 }

und schon wird aus M�rz wieder der gute alte März. 😉

Btw. � ist &#xFFFD; (in case anyone is wondering)