Dawid Cieszyński

.NET/PHP Software Developer

Jeden z moich klientów korzysta z systemu Joomla i dodatku VirtueMart (moduł sklepu internetowego). Żeby uprościć jego obsługę pomyślałem nad napisaniem aplikacji do aktualizacji cen pobieranych z jakiegoś źródła.

Aplikacja korzysta z DB_Linq czyli Linq Provider for MySql, Oracle and PostgreSQL.  Niestety DB_Linq nie ma aktualnie żadnej dokumentacji. Za to znalazłem drobne informacje na stronie Primary Objects. Wykorzystałem wersję 0.18 która jest deprecated ponieważ z 0.19 miałem problem z wygenerowaniem klas linq.

Z wersją 0.18 też był problem…

DbMetal failed:System.ArgumentException: magma string must not be empty

Okazało się, że jest problem jeśli nazwy tabel w bazie zawierają obok siebie dwa znaki podkreślenia.

Oczywiście pogrzebałem trochę w kodzie i to sobie poprawiłem:

//\DbLinq-0.18\src\DbLinq\Language\Implementation\AbstractWords.cs, linia 139
public virtual IList<string> GetWords(string text)
{
    text = text.Replace("__", "_"); //zamienia dwa podkreślenia na jedno

Teraz mogłem już zacząć korzystać z zalet linq połączonego z bazą MySQL.

Dla tych którzy nie znają angielskiego (lub nie lubią czytać po angielsku) napiszę co po koli należy zrobić aby łatwo pogrzebać sobie w bazie MySQL.

  1. Ściągnąć DB_Linq
  2. Wygenerować klasy modelu na podstawie struktury bazy danych. Zostanie utworzony jeden plik o nazwie takiej samej jak nazwa bazy
    dbmetal /server:1.2.3.4 /user:dbuser /password:password /provider:MySql /database:people /language:C#
    
  3. To wszystko :)
    Klasy mamy gotowe więc można operować na bazie.

Odczytywanie danych z bazy (SELECT).

public ObservableCollection GetProducts()
{
    using (var connection = new MySqlConnection("server=server.pl;user id=user; password=haslo; database=baza"))
    {
        connection.Open();
        using (var dataContext = new BazaDataContext(connection))
        {
 
  var items = from s in dataContext.JoSVMProduct
                        join pc in dataContext.JoSVMProductPrice on s.ProductID equals pc.ProductID
                        orderby s.ProductName ascending
                        select new ProduktVm
                                   {
                                       ProductId = s.ProductID,
                                       ProductSku = s.ProductSku,
                                       ProductName = s.ProductName,
                                       ProductPrice = pc.ProductPrice,
                                       ProductFullImage = s.ProductFullImage,
                                   };
 
            var collection = new ObservableCollection();
            foreach (var c in items)
                collection.Add(c);
 
            return collection;
        }
    }
}

W powyższym przykładzie pobieram dane o produktach i cenach i tworzę sobie obserwowalną kolekcję. ProduktVm to moja klasa pośrednia.

Aktualizowanie danych w bazie (UPDATE).

using (var conn = new MySqlConnection("server=server.pl;user id=user; password=haslo; database=baza"))
{
    conn.Open();
    using (var context = new BazaDataContext(conn))
    {
        var items = from pc in context.JoSVMProductPrice
                    where pc.ProductID == 1
                    select pc;
        var i = items.First();
        i.ProductPrice = -1;
        context.SubmitChanges();
    }
}

Dodawanie danych do bazy (INSERT).

using (PeopleDataContext context = new PeopleDataContext(connection))
{
    // Create a LINQ to SQL class to fill the properties.
    Person person = new Person();
    person.FirstName = txtFirstName.Text;
    person.LastName = txtLastName.Text;
    person.Age = Convert.ToInt32(txtAge.Text);
 
    context.Person.InsertOnSubmit(person);
    context.SubmitChanges();
}           

W mojej aplikacji jeszcze insertów nie robię więc podaję przykład z Primary Objects

Na koniec dodam jeszcze, że VMManager miał pobierać dane z Excela, ale niestety nie znalazłem żadnego działającego sposobu pobrania danych z arkusza. Zapisałem arkusz jako plik tekstowy z danymi rozdzielonymi znakami tabulacji i takie dane to już da się odczytać.

Wszyscy którzy powinni wiedzieć w pierwszej kolejności już wiedzą, więc Wy też już możecie: Zaręczyłem się :D A było to dokładnie 3 stycznia 2010 przed Pałacem Łazienkowskim (Pałac na Wyspie) w Warszawie.

Wczoraj mój kolega opublikował pierwszą wersję projektu Bieduino czyli "Arduino dla biednych". Ja przygotowałem projekt płytki (bo znam się bardzo dobrze na Eagle'u) na podstawie Metaboard'a a Kamil zrobił resztę.

Właśnie jestem w trakcie przygotowywania kolejnej wersji 1.1, więc jeśli macie jakieś opinie lub sugestie zapraszam do komentowania u mnie albo na blogu Kamila.

Dzisiaj kolega Rafał dodał komentarz do mojej poprzedniej próby integracji Joomli z Windows Live Writerem. Podał mi linka do postu który sam też podałem :D Mimo to spróbowałem jeszcze raz i znalazłem inny ciekawy post na blogu MYGUIDE. W tym poście znalazłem informację o Fiddlerze, bardzo fajnej aplikacji do podsłuchiwania informacji przesyłanych przez dowolną aplikację do serwera. Pokazywał ją Krzysiek Sopyła na jednym z OLMUGów, jeszcze nie miałem okazji się nią pobawić więc teraz nadarzyła się okazja.

Podsłuchałem sobie rozmowę WLW z moją Joomlą i zobaczyłem coś takiego:

8b
<br />
<b>Notice<!--b>:  Undefined index:  more_text in <b>/.../www/plugins/xmlrpc/metaweblog.php<!--b> on line <b>213<!--b><br />
 
8e
<br />
<b>Notice<!--b>:  Undefined index:  mt_text_more in <b>/.../www/plugins/xmlrpc/metaweblog.php<!--b> on line <b>217<!--b><br />
 
87
<br />
<b>Notice<!--b>:  Undefined variable: row in <b>/.../www/plugins/xmlrpc/metaweblog.php<!--b> on line <b>261<!--b><br />
 
94
<br />
<b>Notice<!--b>:  Trying to get property of non-object in <b>/.../www/plugins/xmlrpc/metaweblog.php<!--b> on line <b>261<!--b><br />
 
80
xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>341<!--string><!--value>
<!--param>
<!--params>
<!--methodResponse>
0
 

Wszystko było jasne. Metaweblog był trochę “niedopracowany” i tam gdzie na serwerze nie było wyłączone pokazywanie ostrzeżeń tam pojawiały się dodatkowe komunikaty psujące strukturę XML’a. Właściwie to powinienem mieć wyłączone ostrzeżenia (żeby przy jakiejś wpadce użytkownik nie zobaczył jakichś bardziej lub mniej ciekawych komunikatów), ale moją stronę używam często jako poligon doświadczalny i dlatego jest tak jak jest.

Poprawiłem kilka linijek w pliku metaweblog.php i teraz już mogę pisać w WLW. Niestety nie działa automatyczne uploadowanie zdjęć (skonfigurowałem sobie ustawienia FTP w WLW) ani pobieranie motywu, czy wszystkich postów bezpośrednio ze strony. Aby działało trzeba poprawić kolejne naście linijek.

P.S.

Polecam też wtyczkę do WLW zwaną  Dynamic Template. Możemy dzięki niej dodać jakieś własne szablony, np podział artykułu na wstęp i rozwinięcie z rozdzielającym “Więcej…” :) Niestety przy ponownej edycji “Więcej” zamienia się w komentarz i nie pełni już swojej funkcji, ach ta interoperacyjność (a raczej jej brak)…

Z okazji Narodzenia Jezusa Chrystusa życzę wszystkim dużo radości z codziennych zajęć, dużo szczęścia przy programowaniu, łask bożych przy rozwiązywaniu problemów algorytmicznych i wiele miłości do bliźniego.

Dnia 15. grudnia 2009 na Wydziale Matematyki i Informatyki UWM w Olsztynie odbędzie się Windows 7 Community Launch. Wydarzenie to organizowane jest przez olsztyńską społeczność skupioną wokół grupy zawodowej OLMUG, oraz akademickiej Eastgroup.pl.Ma ono na celu przybliżenie uczestnikom najnowszej wersji systemu operacyjnego firmy Microsoft - Windows 7.

W trakcie spotkania przedstawione zostaną dwie prezentacje:

Na wydarzenie zapraszamy pasjonatów, ekspertów, pracowników działów IT i nie tylko - wszyscy zainteresowani tematem będą mile widziani.

Spotkanie odbędzie się na ul. Żołnierskiej 14, w sali 49. Zaczynamy o godzinie 17:00!

Lista miejsc jest ograniczona, dlatego już dziś warto zarejestrować się przez portal MS-Groups. Rejestracja oraz udział są bezpłatne! Na aktywnych uczestników czekają nagrody.

Mam kilka monet do sprzedania:

Bolesław II Śmiały 1058 1079
50 ZŁ PRL 1981

Jan Paweł II sprzedane
10000 ZŁ PRL 1987

Solidarność 1980 1990
10000 Zł RP 1990

Dla tego/tej kto kupi wszystkie mam gratis pudełko :)

 

Właśnie powstała nowa firma, właściwie jeszcze nie zarejestrowana, ale niedługo będzie. Nazywa się CrystalCode Studio. Zajmujemy się aktualnie tworzeniem własnego frameworka i własnego CMSa.

Właśnie naprawiłem współpracę JoomFish z standardową obsługą kanałów RSS w Joomla. Od teraz na każdej stronie z listą artykułów dostępny jest kanał RSS z tymi artykułami.

W końcu zrobiłem sobie programator!!!

Ładowanie sterowników w systemie 64-bitowym

Niestety w moim Windows 7 64bit jest wymaganie aby sterowniki były podpisane, a nie są. Doczytałem się, że żeby samodzielnie podpisać sterowniki musiałbym najpierw mieć certyfikat VeriSign za $399/rocznie :D więc sobie darowałem.

2009-12-16: Właśnie się dowiedziałem że certyfikat można mieć za $99/rocznie (czyli 284,65PLN - to i tak za dużo na mały niekomercyjny projekcik), klikając w link na stronie Winqual Help.

W Internecie jest wiele sposobów na umożliwienie ładowania niepodpisanych sterowników, ale prawie żaden u mnie nie działał a nawet trochę mi uszkodziły system (do tego stopnia, że praktycznie żaden sterownik poza microsoftowymi nie chciał się załadować). Zadziałał jedynie program Driver Signature Enforcement Overrider 1.3b.

Aby system załadował sterowniki libusb, po zainstalowaniu musimy podpisać każdy plik sys i dll (opcja Sign a System File w DSEF):

c:\windows\system32\drivers\libusb0.sys
c:\windows\system32\libusb0.dll
c:\windows\syswow64\libusb0.dll


Jednak przy instalacji kolejnych urządzeń te podpisane przez nas sterowniki mogą być nadpisane przez wersje niepodpisane, więc zrobiłem troszkę inaczej. Podpisałem pliki zanim zainstalowałem urządzenie:

bin\win-driver\libusb_0.1.12.1\libusb0.dll
bin\win-driver\libusb_0.1.12.1\libusb0.sys
bin\win-driver\libusb_0.1.12.1\libusb0_x64.dll
bin\win-driver\libusb_0.1.12.1\libusb0_x64.sys

Dzięki temu sterowniki są ładowane :D (ps. piszą że trzeba wyłączyć UAC, ja wyłączyłem przed użyciem i jak już wszystko działało to włączyłem UAC - i działa nadal)

Własny USB PID

Jeszcze jedna sprawa. Dowiedziałem się, że firma FTDI dla swoich klientów wydziela unikalne identyfikatory PID w ramach swojego VID'a. Myślałem, że będę sprytny i zrobię sobie własny programator i własne sterowniki. Napisałem do nich maila. Wystarczyło, że podałem

  • nazwisko
  • nazwę firmy
  • kraj
  • email

i dostałem bezpłatnie własne 8 PIDów. :D Jeden z nich chciałem użyć do programatora, ale zatrzymała mnie kwestia certyfikacji sterowników (i przy okazji zauważyłem, że avrdude nie zobaczy mojego programatora)

USBasp

Zdjęć programatora na razie nie będzie bo nie mam aparatu, ale wygląda mniej więcej jak ten modelowany w poprzednim poście.

Użyłem softu w wersji usbasp.2009-02-28 z strony autora USBasp. Do programowania używam avrdude. Programy piszę w Code::Blocks (w post-build steps dodałem 

avrdude -q -p m8 -c usbasp -e -U flash:w:$(TARGET_OUTPUT_FILE).hex

dzięki czemu od razu po kompilacji soft ląduje w mikrokontrolerze) + WinAVR-20090313.

Nie będę powtarzał instrukcji składania bo wszystko jest na stronie autora oraz po polsku na stronie Mirleya

Jeśli ktoś ma jakieś pytania to zapraszam do kontaktowania się ze mną :)

Debugowanie po RXD/TXD

Autor programatora przewidział możliwość przesyłania danych wykorzystując UART w mikrokontrolerze w programatorze ale do tej pory ta funkcja nie jest obsługiwana. Właśnie jestem w trakcie modyfikowania firmware i pisania odpowiedniej aplikacji korzystającej z tej możliwości.

Aktualnie potrafię już za pomocą aplikacji na PC zapalić/gasić diody :D Teraz się muszę nauczyć obsługi UARTa

AVRUSBBoot vs BootloadHID

Żeby łatwo modyfikować soft w programatorze postanowiłem wgrać do niego bootloader.

Z AVRUSBBoot jest problem taki, że wymaga sterowników (libusb - problem z podpisem) oraz używa VID i PID tych samych co USBasp więc Windows od razu instaluje sterowniki dla USBasp i program ładujący nie widzi urządzenia (bo sprawdza nie tylko VID i PID ale i nazwę i dostawcę urządzenia)

Dużo lepiej sprawuje się BootloadHID. Nie wymaga żadnych sterowników (używa sterowników Windows).

W obu przypadkach zasada działania jest taka sama. Program bootloadera jest ładowany pod koniec pamięci flash i ustawiane są fusebity tak by stamtąd rozpoczynało się wykonywanie rozkazów po resecie mikrokontrolera. Jeśli po resecie odpowiednie piny będą w odpowiednim stanie (tzw. bootLoaderCondition), nastąpi wykonanie kodu bootloadera i komputer zobaczy urządzenie jako (odpowiednio) AVRUSBBoot lub Urządzenie wejściowe USB. Wtedy programem ładującym wczytujemy do mikrokontrolera właściwy firmware.

Trzeba pamiętać żeby przy zmianach bootLoaderCondition poprawić też ustawienie pinów w stany wysokie (jeśli warunkiem jest zwarcie pinu do masy). Ja wykorzystałem zworkę Slow SCK z USBasp jako warunek włączenia bootloadera.

static inline void  bootLoaderInit(void)
{
    PORTC = (1 << PC2); /* activate pull-up for key */
    _delay_us(10);  /* wait for levels to stabilize */
}

#define bootLoaderCondition()   ((PINC & (1 << PC2)) == 0)

2009-11-22:

Niestety użycie bootloadera w programatorze się nie sprawdziło. Sam programator nie chce poprawnie działać.