Program telewizyjny z powiadamiaczem.
Zadaniem wtyczek źródeł pobierania jest dostarczenie programu telewizyjnego do aplikacji. Polega to na tym, że aplikacja wysyła do wtyczki żądanie pobrania programu telewizyjnego dla określonego kanału i dnia, a następnie wtyczka pobiera kod źródłowy strony internetowej zawierający dany program telewizyjny, z którego to wyciąga potrzebne informacje, poddaje je dodatkowej obróbce i zwraca je do aplikacji.
Wtyczki źródeł pobierania są to biblioteki dll, które znajdują się w podfolderze Źródła w katalogu głównym aplikacji Program TV. Nazwy tych plików składają się z adresu internetowego (z którego pobierany jest program telewizyjny bez przedrostka typu http:// i katalogów podrzędnych, oraz wszystkie kropki zamienia się na podkreślenia) i rozrzerzenia dll. Biblioteki te muszą udostępniać trzy funkcje: Kanaly, Pobierz i Odebrane. Dodatkowo biblioteki mogą również opcjonalnie udostępniać sześć funkcji: OdebraneOpisy, OdebraneKategorie, OdebraneHity, OdebraneObrazki, Opcje i Logo.
Dla wtyczek pobierających program telewizyjny ze stron internetowych oferujących program telewizyjny dla dużej liczby kanałów może istnieć dodatkowy plik znajdujący się obok pliku wtyczki, o takiej samej nazwie ale z rozszerzeniem txt. Plik ten zawiera listę kanałów, co umożliwia dodanie nowych kanałów, które dana wtyczka może obsługiwać, bez konieczności pisania nowej wtyczki.
Wpisy kanałów, w pliku listy kanałów, zaczynają się od czwartego wiersza i zbudowane są z nazw kanałów i adresów internetowych pod którymi znajduje się program telewizyjny dla danego kanału, połączonych znakiem równości w postaci:
Kanał | = | Adres |
---|
Ponieważ nazwy kanałów wykorzystywane są przez aplikację do tworzenia folderów, to nazwy te nie mogą zawierać znaków specjalnych zastrzeżonych przez system Windows.
Pierwszy i trzeci wiersz, w pliku listy kanałów, to komentarze, natomiast drugi wiersz to numer wersji listy kanałów i jest on w postaci:
Wersja: | x |
---|
gdzie x to numer wersji listy kanałów.
Funkcja ta może zwrócić trzy rodzaje informacji jako tablicę char, w zależności od podanej wartości parametru Nr: | ||
dla Nr = -1 | - | funkcja zwraca liczbę obsługiwanych przez wtyczkę kanałów (domyślnie), |
dla Nr > -1 | - | funkcja zwraca nazwy poszczególnych kanałów, |
dla Nr < -1 | - | funkcja zwraca pustą tablicę jeśli wtyczka nie obsługuje listy kanałów lub gdy ją obsługuje to zwraca przykładowy wpis listy kanałów składający się z nazwy kanału połączonego znakiem równości z adresem internetowym pod którym można pobrać program telewizyjny dla podanego kanału. |
Funkcja ta pobiera kod źródłowy strony internetowej zawierającej program telewizyjny do odpowiedniego pliku html, którego nazwa składa się z daty w formacje yyyy-mm-dd (rok-miesiąc-dzień) i rozszerzenia html. Plik ten zapisywany jest do odpowiedniego podfolderu, którym jest nazwa kanału w katalogu głównym aplikacji w folderze Pobrane.
Jeśli parametr Dekoduj ustawiony jest na true (domyślnie), to funkcja ta wydobywa z pobranego pliku wszystkie niezbędne dane na temat programu telewizyjnego i zapisuje je do odpowiednich list globalnych zdefiniowanych we wtyczce, przy czym liczba pozycji we wszystkich listach musi być zgodna, więc jeżeli jakaś dana nie występuje to do danej listy należy dodać pustą wartość, ponieważ aplikacja później będzie łączyć te dane ze wszystkich list w całość odwołując się do nich po numerach indeksów.
Funkcja ta nie zwraca do aplikacji żadnych danych na temat programu telewizyjnego, a jedynie status z przeprowadzonej operacji. Wyniki działania tej funkcji aplikacja odbiera za pomocą funkcji Odebrane oraz funkcji opcjonalnych: OdebraneOpisy, OdebraneKategorie, OdebraneHity i OdebraneObrazki.
Parametry wejściowe to: | ||
char *Kanal | - | nazwa kanału dla którego ma być pobrany program telewizyjny. |
TDateTime Data | - | dzień dla którego ma być pobrany program telewizyjny (format: yyyy-mm-dd). |
bool Dekoduj | - | określa czy po pobraniu pliku kodu źródłowego strony internetowej ma zostać przeprowadzony proces wydobywania programu telewizyjnego (domyślnie jest to robione). |
Funkcja zwraca wartość typu int: | ||
0 | - | gdy operacja zakończyła się sukcesem. |
1 | - | gdy wystąpił błąd. |
2 | - | gdy brak jest listy kanałów lub kanału w liście kanałów. |
Funkcja ta zwraca do aplikacji wyniki z wcześniej uruchomionej funkcji Pobierz.
Funkcja ta może zwrócić dwa rodzaje informacji jako tablicę char, w zależności od podanej wartości parametru Nr: | |||||||||||||||||||||||
dla Nr = -1 | - | funkcja zwraca liczbę pozycji z pobranej ramówki programu telewizyjnego (domyślnie), | |||||||||||||||||||||
dla Nr > -1 | - |
funkcja zwraca dane poszczególnych pozycji z pobranej ramówki programu telewizyjnego. Format tych danych jest następujący:
|
Funkcja ta zwraca do aplikacji opisy dla poszczególnych pozycji z pobranej ramówki programu telewizyjnego z listy utworzonej przez wcześniej uruchomioną funkcję Pobierz.
Funkcja ta zwraca do aplikacji kategorie dla poszczególnych pozycji z pobranej ramówki programu telewizyjnego z listy utworzonej przez wcześniej uruchomioną funkcję Pobierz.
Funkcja ta zwraca do aplikacji oznaczenia hitów (1 - oznacza hit, 0 - oznacza normalną pozycję) dla poszczególnych pozycji z pobranej ramówki programu telewizyjnego z listy utworzonej przez wcześniej uruchomioną funkcję Pobierz.
Funkcja ta zwraca do aplikacji adresy internetowe obrazków dla poszczególnych pozycji z pobranej ramówki programu telewizyjnego z listy utworzonej przez wcześniej uruchomioną funkcję Pobierz.
Funkcja służąca do otwierania okna ustawień wtyczki.
Parametry wejściowe to: | ||
TApplication *Host | - | uchwyt aplikacji wykorzystywany do scalenia okna ustawień wtyczki z aplikacją (aby na pasku zadań nie było dodatkowego przycisku okna ustawień wtyczki). |
Funkcja zwraca wartość typu bool: | ||
true | - | gdy aplikacja ma wyświetlić listę kanałów wtyczki w edytorze list kanałów. |
false | - | gdy brak jest dalszych działań. |
Funkcja ta pobiera loga kanałów.
Parametry wejściowe to: | ||
char *Kanal | - | nazwa kanału dla którego ma być pobrane logo. |
Funkcja zwraca wartość typu bool: | ||
true | - | gdy operacja zakończyła się sukcesem. |
false | - | gdy wystąpił błąd. |
Zgodnie z tym co napisano na wstępie dla fikcyjnej strony "www.informacje.pl/programtv" plik wtyczki powinien się nazywać "www_informacje_pl.dll" a plik listy kanałów (jeśli ma być obsługiwany) "www_informacje_pl.txt".
Wtyczka taka powinna się składać z co najmniej jednego pliku nagłówkowego ".h" i jednego pliku źródłowego ".cpp", przeznaczonych dla funkcji wtyczki (nazwijmy je przykładowo Kod.h i Kod.cpp). Opcionalnie jeśli wtyczka ma zawierać formularz ustawień to powinny istnieć jeszcze dwa takie pliki (nazwijmy je przykładowo Ustawienia.h i Ustawienia.cpp).
Poniżej zostaną przedstawione zawartości tych plików z zaznaczonymi miejscami, które należy odpowiednio zmodyfikować.
Zawartość pliku nagłówkowego Kod.h:
//--------------------------------------------------------------------------- #ifndef KodH #define KodH //--------------------------------------------------------------------------- extern "C" __declspec(dllexport) char* __stdcall Kanaly(int Nr=-1); extern "C" __declspec(dllexport) int __stdcall Pobierz(char *Kanal,TDateTime Data, bool Dekoduj=true); extern "C" __declspec(dllexport) char* __stdcall Odebrane(int Nr=-1); extern "C" __declspec(dllexport) char* __stdcall OdebraneOpisy(int Nr); extern "C" __declspec(dllexport) char* __stdcall OdebraneKategorie(int Nr); extern "C" __declspec(dllexport) char* __stdcall OdebraneHity(int Nr); extern "C" __declspec(dllexport) char* __stdcall OdebraneObrazki(int Nr); extern "C" __declspec(dllexport) bool __stdcall Opcje(TApplication *Host); extern "C" __declspec(dllexport) bool __stdcall Logo(char *Kanal); //--------------------------------------------------------------------------- #endif
Zawartość pliku źródłowego Kod.cpp:
//--------------------------------------------------------------------------- #include <vcl.h> #include <windows.h> #include <urlmon.h> #pragma hdrstop #include "Kod.h" #include "Ustawienia.h" #pragma argsused //--------------------------------------------------------------------------- TStringList *Stacje=NULL; TStringList *Lista=NULL; TStringList *ListaKategori=NULL; TStringList *ListaOpisow=NULL; TStringList *ListaObrazkow=NULL; TStringList *ListaHitow=NULL; char *DaneKanalu=NULL; char *DaneOdebrane=NULL; char *DaneOdebraneKategorie=NULL; char *DaneOdebraneOpisy=NULL; char *DaneOdebraneObrazki=NULL; char *DaneOdebraneHity=NULL; //--------------------------------------------------------------------------- int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { if(reason==DLL_PROCESS_DETACH) { if(DaneKanalu) { delete[] DaneKanalu; DaneKanalu=NULL; } if(DaneOdebrane) { delete[] DaneOdebrane; DaneOdebrane=NULL; } if(DaneOdebraneKategorie) { delete[] DaneOdebraneKategorie; DaneOdebraneKategorie=NULL; } if(DaneOdebraneOpisy) { delete[] DaneOdebraneOpisy; DaneOdebraneOpisy=NULL; } if(DaneOdebraneObrazki) { delete[] DaneOdebraneObrazki; DaneOdebraneObrazki=NULL; } if(DaneOdebraneHity) { delete[] DaneOdebraneHity; DaneOdebraneHity=NULL; } if(Stacje) { delete Stacje; Stacje=NULL; } if(Lista) { delete Lista; Lista=NULL; } if(ListaKategori) { delete ListaKategori; ListaKategori=NULL; } if(ListaOpisow) { delete ListaOpisow; ListaOpisow=NULL; } if(ListaObrazkow) { delete ListaObrazkow; ListaObrazkow=NULL; } if(ListaHitow) { delete ListaHitow; ListaHitow=NULL; } } return 1; } //--------------------------------------------------------------------------- char* __stdcall Kanaly(int Nr) { if(DaneKanalu) { delete[] DaneKanalu; DaneKanalu=NULL; } if(!Stacje) { Stacje=new TStringList; if(FileExists("Źródła\\www_informacje_pl.txt")) // Odczyt listy kanałów jeśli { // wtyczka ją obsługuje. Stacje->LoadFromFile("Źródła\\www_informacje_pl.txt"); Stacje->Delete(2); Stacje->Delete(1); Stacje->Delete(0); } } String Dane; if(Nr<-1) Dane="Nazwa kanału=Adres internetowy kanału"; // Przykładowy kanał i adres dla if(Nr==-1) Dane=IntToStr(Stacje->Count); // edytora, a przy braku obsługi if(Nr>-1) Dane=Stacje->Names[Nr]; // listy kanałów zmienną ustawia DaneKanalu=new char[Dane.Length()+1]; // się pustą (Dane=""). strcpy(DaneKanalu,Dane.c_str()); return DaneKanalu; } //--------------------------------------------------------------------------- int __stdcall Pobierz(char *Kanal,TDateTime Data,bool Dekoduj) { int Status=1; Kanaly(); AnsiString Adres=""; Adres=Stacje->Values[Kanal]; if(Adres=="") { Status=2; } else { Adres=Adres; // Dostosowanie adresu z listy kanałów do rzeczywistego. AnsiString Plik="Pobrane\\"+String(Kanal)+"\\"+Data+".html"; int Stan=URLDownloadToFile(0,Adres.c_str(),Plik.c_str(),0,0); if(Dekoduj==true) { if((Stan==S_OK)&&(FileExists(Plik))) { if(Lista) { Lista->Clear(); } else { Lista=new TStringList; } if(ListaKategori) { ListaKategori->Clear(); } else { ListaKategori=new TStringList; } if(ListaOpisow) { ListaOpisow->Clear(); } else { ListaOpisow=new TStringList; } if(ListaObrazkow) { ListaObrazkow->Clear(); } else { ListaObrazkow=new TStringList; } if(ListaHitow) { ListaHitow->Clear(); } else { ListaHitow=new TStringList; } TStringList *Html=new TStringList; for(;;) { try { Html->LoadFromFile(Plik); break; } catch(...) { Sleep(1000); } } String Szukane="tekst wskazujący na obecność programu telewizyjnego"; for(int i=0;i<Html->Count;i++) { String Dane=Html->Strings[i]; if(Dane.Pos(Szukane)>0) { Status=0; /* Wydobycje poszczególnych danych dla każdej pozycji z ramówki programu telewizyjnego i ich zapis do odpowiednich list: - dla listy "Lista" zapis rzeczywistej daty emisji, godziny emisji i tytułu pozycji w postaci "yyyy-mm-dd hh:nn Tytuł", - dla listy "ListaOpisow" zapis opisu dla danej pozycji a przy braku zapis pustej wartości, - dla listy "ListaKategori" zapis kategorii a przy braku zapis pustej wartości, - dla listy "ListaHitow" zapis stanu czy dana pozycja jest hitem (0 - nie lub 1 - tak), - dla listy "ListaObrazkow" zapis adresu obrazka a przy braku zapis pustej wartości. Uwaga! Listy: "ListaOpisow", "ListaKategori", "ListaHitow" i "ListaObrazkow" są listami opcionalnymi, które występują tylko wtedy, gdy wtyczka obsługuje dane funkcje i muszą być połączone z listą główną "Lista" relacją jeden do jeden za pomocą numerów indeksów list. */ break; } } delete Html; } } else { if((Stan==S_OK)&&(FileExists(Plik))) Status=0; } } return Status; } //--------------------------------------------------------------------------- char* __stdcall Odebrane(int Nr) { if(DaneOdebrane) { delete[] DaneOdebrane; DaneOdebrane=NULL; } String Dane; if(Nr==-1) Dane=IntToStr(Lista->Count); if(Nr>-1) Dane=Lista->Strings[Nr]; DaneOdebrane=new char[Dane.Length()+1]; strcpy(DaneOdebrane,Dane.c_str()); return DaneOdebrane; } //--------------------------------------------------------------------------- char* __stdcall OdebraneKategorie(int Nr) { if(DaneOdebraneKategorie) { delete[] DaneOdebraneKategorie; DaneOdebraneKategorie=NULL; } String Dane; Dane=ListaKategori->Strings[Nr]; DaneOdebraneKategorie=new char[Dane.Length()+1]; strcpy(DaneOdebraneKategorie,Dane.c_str()); return DaneOdebraneKategorie; } //--------------------------------------------------------------------------- char* __stdcall OdebraneOpisy(int Nr) { if(DaneOdebraneOpisy) { delete[] DaneOdebraneOpisy; DaneOdebraneOpisy=NULL; } String Dane; Dane=ListaOpisow->Strings[Nr]; DaneOdebraneOpisy=new char[Dane.Length()+1]; strcpy(DaneOdebraneOpisy,Dane.c_str()); return DaneOdebraneOpisy; } //--------------------------------------------------------------------------- char* __stdcall OdebraneObrazki(int Nr) { if(DaneOdebraneObrazki) { delete[] DaneOdebraneObrazki; DaneOdebraneObrazki=NULL; } String Dane; Dane=ListaObrazkow->Strings[Nr]; DaneOdebraneObrazki=new char[Dane.Length()+1]; strcpy(DaneOdebraneObrazki,Dane.c_str()); return DaneOdebraneObrazki; } //--------------------------------------------------------------------------- char* __stdcall OdebraneHity(int Nr) { if(DaneOdebraneHity) { delete[] DaneOdebraneHity; DaneOdebraneHity=NULL; } String Dane; Dane=ListaHitow->Strings[Nr]; DaneOdebraneHity=new char[Dane.Length()+1]; strcpy(DaneOdebraneHity,Dane.c_str()); return DaneOdebraneHity; } //--------------------------------------------------------------------------- bool __stdcall Opcje(TApplication *Host) { TApplication *Dll=Application; Application=Host; TFormOpcje *Formularz=new TFormOpcje(Application); Formularz->ShowModal(); delete Formularz; Application=Dll; return ::Edytor; // Gdy zwraca true to po zamknięciu okna ustawień wtyczki } // zostanie wyświetlony edytor listy kanałów. //--------------------------------------------------------------------------- bool __stdcall Logo(char *Kanal) { bool Stan=false; String Data=DateToStr(Date()); if(!FileExists("Pobrane\\"+String(Kanal)+"\\"+Data+".html")) Pobierz(Kanal, StrToDate(Data),false); if(FileExists("Pobrane\\"+String(Kanal)+"\\"+Data+".html")) { TStringList *Html=new TStringList; for(;;) { try { Html->LoadFromFile("Pobrane\\"+String(Kanal)+"\\"+Data+".html"); break; } catch(...) { Sleep(1000); } } String Szukane="tekst wskazujący na adres loga kanału"; for(int i=0;i<Html->Count;i++) { String Dane=Html->Strings[i]; if(Dane.Pos(Szukane)>0) { Dane=Dane; // Przypisanie wyciętego adresu loga kanału. int Status=URLDownloadToFile(0,Dane.c_str(),("Ustawienia\\"+String(Kanal)+ "\\Logo.png lub jpg").c_str(),0,0); if((Status==S_OK)&&(FileExists("Ustawienia\\"+String(Kanal)+ "\\Logo.png lub jpg"))) Stan=true; break; } } delete Html; } return Stan; } //---------------------------------------------------------------------------
Zawartość pliku nagłówkowego Ustawienia.h:
//--------------------------------------------------------------------------- #ifndef UstawieniaH #define UstawieniaH //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> //--------------------------------------------------------------------------- class TFormOpcje : public TForm { __published: // IDE-managed Components private: // User declarations public: // User declarations __fastcall TFormOpcje(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TFormOpcje *FormOpcje; extern bool Edytor; //--------------------------------------------------------------------------- #endif
Zawartość pliku źródłowego Ustawienia.cpp:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Ustawienia.h" #pragma package(smart_init) #pragma resource "*.dfm" //--------------------------------------------------------------------------- TFormOpcje *FormOpcje; bool Edytor=false; //--------------------------------------------------------------------------- __fastcall TFormOpcje::TFormOpcje(TComponent* Owner) : TForm(Owner) { } //---------------------------------------------------------------------------
Stronę tę odwiedziło 2000 użytkowników. |