Friday, July 31, 2009

Seam ve Hata Mesajlari

Seam ile validasyon (veri dogruluk kontrolu), hata bulunca hata mesajlari yazma / gosterme mekanizmasi soyle kurulabilir.

Hata kontrolu yapan her aksiyon,
  @Out
private transient List errors = new ArrayList();
ile bir hata listesi tanimlar. Validasiyon sirasinda tum hatalar errors.add("mesaj") ibaresi ile bu listeye yazilir. Bu hatalar aksiyon sonrasi ustteki @Out ile de-enjekte edilecektir ve uygulamanin geri kalani artik bu listeye erisebilir. Bu noktada eger hatalarin olup olmadigina bagli olarak bir navigasyon yapmak istiyorsak, rule-if ile bunu yapmak artik cok basittir.
  <page view-id="/page.xhtml" conversation-required="false"
login-required="true">
<navigation from-action="#{userHandler.someAction}">
<rule if="#{errors.size() == 0}">
<redirect view-id="/home.xhtml"/>
</rule>
</navigation>
</page>
Dikkat edelim: Hata olmadigi durumda hangi sayfaya gidilecegini tanimlamadik, cunku bunu tanimlamadiysak, Seam otomatik olarak bizi ayni sayfaya yonlendirir. Bu bizim icin uygun, zaten hata varsa o sayfayi terk etmek istemiyorduk. Simdi, bu ayni sayfada hatalari basmak icin bir JSF kodu soyle yazilabilir.
  <font color="#FF0000">
<s:div rendered="#{errors.size() > 0}">
#{errors}
</s:div>
</font>
Bu sayfayi bir errors.xhtml diye tanimladik ve gereken her sayfadan include ile dahil ediyoruz.

Tabii bu kodu surekli kullanabilmek icin hata verebilecek her aksiyonumuzun errors adli ayni degisken ismini kullanmasi gerekiyor.

Sayfa Oncesi Aksiyon

Seam'in kullandigi sayfa -> aksiyon -> sayfa modelinden bahsettik. pages.xml adli bir dosyada tum navigasyon kurallari tanimlanmaktadir, ve X sayfasinda iken 'a' aksiyonu alinca Y sayfasina yonlendir gibi kurallar burada tanimlanabilir.

Yanliz bazi durumlarda sayfa yuklenmeden once bir aksiyon isletmek gerekebilir. Bu durum icin view-id tanimladigimiz ayni satirda bir aksiyon tanimlamamiz mumkundur.
<page view-id="/main.xhtml" conversation-required="false"
login-required="false" action="#{userHandler.someAction}">
<rule if="#{user == null}">
<redirect view-id="/home.xhtml"/>
</rule>
...
</page>
Bu ornekte main.xhtml sayfasi icin (aslinda boyle bir sayfanin mevcut olmasi bile gerekli degil, tarayiciya main.seam girince ustteki navigasyon kurallari isler) userHandler.someAction komutu isletilsin istiyorsak, tanim yukaridaki gibidir... Ayrica, diger her tur navigasyon kurali icin de, bu isletimden sonraki yonlendirmeyi "eger kuralina" baglayabiliriz. Mesela, bir aksiyondan @Out ile de-enjekte edilmis bir user objesinin olup olmadigina bagli bir karar almak istiyorsak, rule-if ile bunu yapariz. Ustte, eger user null ise, "home.xhtml adli bir sayfaya yonlendir" diye bir tanim yapmisiz.

Tuesday, July 28, 2009

Facebook Import

Bir kullanicinin arkadas listesini, onlarin bilgisini kendi uygulamaniza yuklemek istiyorsaniz, alttaki kodlar yardimci olabilir. Once temel kodlar:
  public Collection<String> getFriendIds() throws FacebookException, IOException {
Collection<String> userIds = new LinkedList<String>();

JSONArray friends = _client.friends_get();
if (friends == null || friends.length() == 0) {
return userIds;
}

/* Walk the list of result elements; each one's contents is a user ID. */
for (int i = 0; i < friends.length(); i++) {
try {
userIds.add(friends.getString(i));
}
catch (JSONException e) {
throw new IOException("friend list can't be extracted");
}
}

return userIds;
}

public JSONArray getInfo(Collection <String> userIds) {
Object result = null;
try {
// two fields
Set<ProfileField> fields = new HashSet<ProfileField>(2);
fields.add(ProfileField.UID);
fields.add(ProfileField.BIRTHDAY);
fields.add(ProfileField.FIRST_NAME);
fields.add(ProfileField.LAST_NAME);
fields.add(ProfileField.PIC_SMALL);
fields.add(ProfileField.SEX);
fields.add(ProfileField.RELATIONSHIP_STATUS);
fields.add(ProfileField.SIGNIFICANT_OTHER_ID);
fields.add(ProfileField.ACTIVITIES);
fields.add(ProfileField.INTERESTS);
fields.add(ProfileField.MUSIC);
fields.add(ProfileField.TV);
fields.add(ProfileField.MOVIES);

Collection<Long> longUserIds = new ArrayList<Long>(userIds.size());
for (String uid : userIds) {
longUserIds.add(Long.valueOf(uid));
}
result = _client.users_getInfo(longUserIds, fields);

} catch (Exception e) {
Util.log(e);
}

return (JSONArray)result;

}
Bu kodlari su sekilde cagirabiliriz (uid degiskeni kullanicinin facebook kimligini tasiyor olsun):
  public void importUsers() {
try {
Collection<String> plist = new LinkedList<String>();
plist.add(uid);
JSONArray parr = getInfo(plist);
importUsers(parr);

Collection<String> list = getFriendIds();
JSONArray arr = getInfo(list);
importUsers(arr);
} catch (Exception e) {
Util.log(e);
}
}

public void importUsers(JSONArray arr) {
..
for (int i = 0; i < arr.length(); i++) {
JSONObject obj = (JSONObject)arr.get(i);
...
value = ""+obj.get(ProfileField.BIRTHDAY.toString());
...
}
}
Session id uzerinden facebook kimliginin nasil alinacagini bir onceki yazida islemistik.

Thursday, July 23, 2009

Google Aramasi ve Urllib

Google aramalarina scriptlemek istiyorsak, wget, hatta urllib ile ilk denememiz basarisiz olabilir. Anlasiliyor ki wget ve urllib baglantilari, kullanicilari Google'in izin verdigi robotlardan degil. O zaman baglananin 'kim oldugunu' degistirerek, yani Google'i yaniltarak, izin verilen bir robot ortaya cikartabiliriz. Alttaki 'version' tanimi bunu yapiyor. Sanki bir Windows makinasindan baglanan Firefox tarayicisi gibi gozukuyoruz.
from urllib import FancyURLopener

class MyOpener(FancyURLopener):
version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; ' + \
'rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'

myopener = MyOpener()
page = myopener.open('http://www.google.com.tr/search?q=tomatoes')
content = page.read()
print content
Bu kadar!

Detexify

Bazen bir Latex sembolunun komutunu hatirlayamiyor olabiliriz; boyle durumlar icin Detefixy web programi faydali oluyor. Elle cizdiginiz sembol oruntu eslestirme algoritmasi ile arka planda size bir Latex sembolu bulup gosteriyor. Altta bizim theta icin yaptigimiz arama..

Wednesday, July 22, 2009

HTML Toplamak (Scraping)

Baska bir sitenin icerigini otomize olarak (bir script yardimiyla) alip diskte saklamak istiyorsak, bu tekrar yayin amacli, baglantisiz bakma amacli vs. olabilir, o zaman HTML toplama tekniklerini bilmek gerekli. Bu gibi isler icin biz Unix wget komutunu kullaniriz; fakat eger wget herhangi bir sebeple ise yaramazsa, bir alternatifi bilmekte yarar var. Python kutuphanelerinden urllib. Alttaki ornekte Google Insights for Search sayfalarindan Google'da son 7 gun icinde en cok aranan kelimelerin listesini almak icin kullandigimiz kodlar bulunabilir. Ayni sayfalar uzerinde wget ise yaramadi, urllib FancyURLopener calisti.
from urllib import FancyURLopener

myopener = FancyURLopener()
insightsURL = 'http://www.google.com/insights/search/overviewReport'
page = myopener.open(insightsURL + '?q=&date=today+7-d&cmpt=q')
print page.read()

Saturday, July 18, 2009

Lineer Cebir Karikaturu