Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Domowy sposób na Diodę

Konkurs z diodą to konkurs z diodą, nie tylko wiedza ale i czas udzielenia odpowiedzi się liczy. Wcześniej powstał na blogu wpis o powiadomieniach SMS gdy dioda się uaktywni, działa to różnie i już kilka razy mnie zawiodło, a dziś odrobiło zaległości przysyłając mi 3 smsy z rzędu. Więc postanowiłem coś z tym zrobić...

Dioda od środka

Głównym założeniem mojego projektu było: znaleźć sposób aby określić kiedy dioda jest włączona a kiedy nie, następnie powiadomić o tym.

Jednak zostałem (nie ukrywam - pozytywnie) zaskoczony tym, że klikając najnormalniej w świecie prawym na diodę, następnie "Zbadaj element", nie da się jednoznacznie określić jaki jest aktualnie stan diody, img src zawsze wskazuje na "dioda-off.png". Tak więc wniosek - jakoś to przecież musi być zrobione, że na moim komputerze ta dioda świeci. Spróbowałem zapisać stronę przez Chrome, następnie próbowałem ją otworzyć i dioda nie działała. Przejrzałem dosłownie wszystkie skrypty jakie zapisały się razem z nią, nawet te z xenium, całe style css, wszystkie obrazki zawarte w nich. Próbowałem też zapisać stronę przez IE, ale efekt był podobny (tylko kod poukładany).

Więc zabrałem się za przeglądanie pliku źródłowego samej strony, w IE w narzędziach deweloperskich. Po pewnym czasie znalazłem bardzo fajny odcinek kodu który mnie zaciekawił, mianowicie:

<STYLE type="text/css">.top_3 span ~ a:after { content: " "; background-image:url(/8jgdwkfposl.png); width:35px; height:36px; display:block; }</STYLE>

Stwierdziłem, że wypadało by zobaczyć jaki obrazek kryje się pod tą tajemniczą nazwą. Okazało się, że to dioda, na dodatek włączona :) Nazwa wydawała się losowa więc kilka razy poodświeżałem stronę i za każdym razem plik miał inną nazwę.

Tu Cię mam..

Już wiem gdzie kryje się dioda, więc odpalam Visual Studio 2010 i robię nowy projekt C#, konsolowy, który będzie tą diodę bacznie obserwował. Najpierw trzeba wymyślić w jaki sposób ten biedny podglądacz ma tą diodę śledzić. Na myśl przyszło mi kilka opcji z czego najbardziej mi odpowiadającą było wyszukanie kodu diody we zwracanym przez stronę pliku html i jego odpowiednie przetworzenie.

Jak to zrobić? Moim ulubionym sposobem! Na stringach! Od zawsze lubiłem te użeranie się ze stringami, plikami tekstowymi itp. więc przyszło mi to prościej niż mogło by się zdawać :) Tak więc nasz szpieg pobiera pierw stronę dzięki komponentowi HttpWebResponse, a potem zapisuje ją do StringBuildera. Następnie szuka ciągu znaków

<div id=\"header\"><style type=\"text/css\">.top_3 span ~ a:after { content: \" \"; background-image:url(

i zapisuje położenie ich początku w zmiennej. Następnie wycina powyższy fragment dodając do niego jeszcze z 20 znaków, aby nazwa pliku diody która natychmiast po nim występuje była również zaliczona.
Plik diody zaczyna się od znaku "/" więc szukamy ostatniego wystąpienia tego znaku w wyciętym fragmencie i odcinamy wszystko co jest wcześniej. Plik diody koczy się znakami ");" więc szukamy ich i odcinamy wszystko co jest za nimi. Tym sposobem mamy aktualną nazwę pliku diody :)

Następnie diodę trzeba pobrać. Używamy tego samego elementy HttpWebResponse, tylko jako adres używamy ścieżki do pliku diody, a następnie zapisujemy odpowiedź w pliku png. Taki plik może być mierzony na wiele sposobów, ja wybrałem metodę która określa jaka to dioda za pomocą rozmiaru pliku. Dioda włączona jest o wiele większa od diody wyłączonej - i tu Cię mam :)

Dioda włączona:

Dioda wyłączona:

Domowe sposoby dla wszystkich

Napisałem program, sam nie jestem w tej całej diodzie za dobry, więc podzielę się z Wami. Najpierw kod, aby było grzecznie:

using System; using System.Collections.Generic; using System.Text; using System.Net; namespace busy_dane { class Program { static void Main(string[] args) { while (true) { string URL = "http://www.dobreprogramy.pl/"; System.Uri MainURL = new System.Uri(URL); Console.WriteLine("GATHERING DIODA DATA"); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(MainURL); request.KeepAlive = false; request.Method = "GET"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); StringBuilder dane = new StringBuilder(); System.IO.Stream files = response.GetResponseStream(); int iStrmByte; StringBuilder str = new StringBuilder(); while ((iStrmByte = files.ReadByte()) != -1) { str.Append((char)Convert.ToByte(iStrmByte)); } int index = str.ToString().IndexOf("<div id=\"header\"><style type=\"text/css\">.top_3 span ~ a:after { content: \" \"; background-image:url("); string filename = ""; if (index != -1) { string partof = str.ToString().Substring(index, 135); index = partof.LastIndexOf("/"); partof = partof.Substring(index + 1); index = partof.IndexOf(");"); filename = partof.Substring(0, index); Console.WriteLine("DIODA FILE NAME: " + filename); Console.WriteLine("DIODA FILE NAMELENGTH:" + filename.Length.ToString()); } if (filename.Length > 0) { MainURL = new System.Uri(URL + filename); Console.WriteLine("GATHERING DIODA FILE"); request = (HttpWebRequest)HttpWebRequest.Create(MainURL); request.KeepAlive = false; request.Method = "GET"; response = (HttpWebResponse)request.GetResponse(); files = response.GetResponseStream(); System.IO.FileStream strmFile = System.IO.File.Create("dioda.png"); iStrmByte = 0; int bytes = 0; byte average = 00; while ((iStrmByte = files.ReadByte()) != -1) { bytes++; strmFile.WriteByte(Convert.ToByte(iStrmByte)); average = (byte)(((int)average + (int)Convert.ToByte(iStrmByte)) / 2); } strmFile.Close(); Console.WriteLine("DIODA FILE SIZE :" + bytes + " BYTES"); Console.WriteLine("DIODA AVERAGE BYTE VALUE:" + average); if (bytes > 2300 && bytes < 3000 && average > 105 && average < 120) { Console.WriteLine("\r\n>>>> DIODA IS ACTIVE <<<<\r\n"); System.Diagnostics.Process.Start("http://konkurs.dobreprogramy.pl/Autoryzacja.html"); break; } else Console.WriteLine("\r\nDIODA IS NOT ACTIVE\r\n"); } else { Console.WriteLine("CAN'T FIND DIODA"); } Console.WriteLine("END"); System.Threading.Thread.Sleep(1000); Console.Clear(); } } } }

A teraz link do programu: http://luby.acech24.pl/files/dioda.exe

Program automatycznie co 1 sekundę sprawdza czy dioda się oświeciła, jeśli tak, natychmiast otwiera domyślną przeglądarkę na stronie autoryzacji do pytania, a sam zamyka się :) Idealne po dostaniu Alertu konkursowego :)

Powodzenia! 

windows oprogramowanie internet

Komentarze

0 nowych
djDziadek   17 #1 29.09.2012 07:09

No, no, no, ale żeby tak oddać wszystkim? :D, szkoda, że tak późno - przynajmniej dla niektórych :P.

Autor edytował komentarz.
tfl   8 #2 29.09.2012 07:54

byc moze lepiej by bylo zastosowac wyrazenia regularne ?

swoja droga upublicznienie mojej wersji (w php) chcialem zrealizowac dopiero po konkursie... :)

  #3 29.09.2012 09:36

Pytanie: czy to ma sens gdy są powiadomienia email i różnica w czasie od jego otrzymania do zapalenia jest niewielka?

underface   14 #4 29.09.2012 10:51

@lukasamd
ostatnio coś to powiadomienie od googla nie wyrobiło się (w moim przypadku tylko raz [lub dwa]) raz przyszło bardzo późno, a raz w ogóle - ale być może ze względu na to, że nie miałem zasięgu (chociaż sms powinien pojawić się zaraz po złapaniu sieci)

Eleks   9 #5 29.09.2012 11:26

@underface
Ostatnio, to znaczy w czwartek nie przyszło, a smsy podochodziły w okolicach godzin 0:00 - 1:00 w piątek :) ?
Jeśli tak to Google zaskoczyło niemiło nas wszystkich. Poza tym wszystko działa bez zarzutu.

Ciekawy wpis, aczkolwiek tak jak powiedział @lukasamd - w dobie powiadomień na maila szukanie diody i tak nic nie daje, bo snajperzy strzelają w 5 sekund odpowiedzi, od pojawienia się pytania...

underface   14 #6 29.09.2012 13:23

@Eleks dokładnie tak - prawdopodobnie (tak mi się wydaje) wyczerpali jakiś dzienny limit i być może dlatego rozesłali zaległe smsy w piątek

djfoxer   18 #7 29.09.2012 15:14

Zgadzam się z lukasamd, jeszcze dwa lata temu to miało sens, obecnie, gdy powiadomienia wysyłane są na pocztę, tego typu aplikacja na niewiele się zdaje. Ot taka ciekawostka.

Poza tym dużo dużo dużo prościej byś zrobił używając obiektu klasy WebClient. Zaś samo wykrywanie jest słabe. Wystarczy by Redakcja zmieniła położenie tego stylu lub dodała kolejny, nowy styl, którego obrazek przykrywałby obecny lub zmieniła rozmiar obrazka lub dodawała losowy szum lub ... mase inny rzeczy. Jednak nie robi tego, gdyż nie ma sensu - patrz komentarz lukasamd :)

Dużo ciekawiej było dwa lata temu, gdzie nie było powiadomień: http://www.dobreprogramy.pl/djfoxer/DIODA-wykrywanie-C-i-jej-ewolucja-w-przeciag...

Autor edytował komentarz.
mordzio   15 #8 29.09.2012 15:21

@djfoxer
Jestem w szkoku! To Ty dwa lata temu korzystałeś ze wspomagaczy?!

djfoxer   18 #9 29.09.2012 15:29

@mordzio
Nie, kolega ;)

przemor25   14 #10 29.09.2012 19:08

Mnie mój androidowi Hotmail jeszcze nigdy nie zawiódł ;)

Over   9 #11 29.09.2012 19:18

Zobaczymy jak to działa dzisiaj, fakt faktem pomysł fajny;)
Ale z praktycznością juz inaczej ale żeby nie było doceniam twoje wypociny :)

Songokuu   14 #12 29.09.2012 21:19

Miszczuniu Ty mój :)

Dimatheus   22 #13 30.09.2012 01:19

Hej,

Normalnie aż chce się napisać 2 słowa: "Świetna robota!". Szczerze mówiąc myślałem, że w tej edycji nikomu nie będzie chciało się bawić w śledzenie diody, a tutaj taka niespodzianka. Do tego działa bardzo, ale to bardzo dobrze. Sprawdziłem przy wczorajszym pytaniu. Szkoda tylko, że przy okazji program nie podaje też poprawnej odpowiedzi. :)

Pozdrawiam,
Dimatheus

max1234   10 #14 30.09.2012 08:49

@przemor25, a mnie to już zawiódł kilka razy, przez co dioda mi umknęła...
Sama aplikacja działa, wykrywa zarówno nieaktywną, jak i aktywną diodę :)

  #15 30.09.2012 08:51

"Od zawsze lubiłem te użeranie się ze stringami..." - ja tam wolę użerać się ze stringami mojej Dziewczyny :D

pebal   8 #16 30.09.2012 11:02

Ja wpadłem na to samo rozwiązanie ale zrealizowałem je tak:

private void timer_Tick(object sender, EventArgs e)
{
WebClient client = new WebClient();
String code = client.DownloadString("http://www.dobreprogramy.pl");
int i = code.IndexOf(".top_3 span ~ a:after { content: \" \"; background-image:url(/") + 60;
code = code.Substring(i, code.Length - i);
i = code.IndexOf(".png") + 4;
code = "http://www.dobreprogramy.pl/" + code.Substring(0, i);
byte[] data = client.DownloadData(code);

if (data.Length != 634)
{
// Dioda is on
}

client.Dispose();
}

wujcio   6 #17 30.09.2012 13:47

Ja się dziwię jak można do rozwiązania problemu tak podchodzić. Przecież wystarczy że coś zmienią i będzie płacz że nie działa. Zamieszczałem pod którymś tematem z diodą kod który robi zrzut ekranu i można dowolnie sprawdzać dowolny obszar.

@aeroflyluby
Tak z ciekawości ile czasu z tym męczyłeś się?

pebal   8 #18 30.09.2012 14:51

@wujcio
"Ja się dziwię jak można do rozwiązania problemu tak podchodzić."

Jedni lubią odpowiadać na pytania a inni programować. Można mieć frajdę z wielu rzeczy.

aeroflyluby   15 #19 30.09.2012 15:22

Co do zmieniania czegokolwiek, oni zmienią, ja zmienię :D
A męczyłem się jakoś z pół godziny, później czekanie aż do 0:00 żeby sprawdzić no i napisanie wpisu.

  #20 30.09.2012 20:38

"Zamieszczałem pod którymś tematem z diodą kod który robi zrzut ekranu i można dowolnie sprawdzać dowolny obszar."

co znaczy, że musisz mieć cały czas stronę otwartą żeby zrobić zrzut, albo cały czas renderować ją gdzieś na offscreenie ?

wojtekadams   18 #21 30.09.2012 23:05

ja mam wersje w Pythonie z powiadomieniem na Jabbera Gmaila ;), ale fakt w tym roku tego typu rozwiązania nie są aż tak pomocne jak było za konkursu Intela.

Ufolec   13 #22 30.09.2012 23:20

Jakby ktoś był ciekawy wersji z nakładką graficzną to wygląda to tak:
http://imageshack.us/a/img827/4808/diodaapp2012byufolec.png
też stworzone dla chęci 'poprogramowania' w wolnej chwili :) Można by było dodać powiadomienia dźwiękowe etc. ale to by miało zastosowanie w diodzie Intela, tutaj otrzymujemy powiadomienia mailowe więc nie ma tak dużego parcia by mieć strażnika diody :)

soanvig   10 #23 30.09.2012 23:48

Do kitu podejście do problemu. Trzeba się zastanowić co powoduje to, że znika zgaszona lampka, a pojawia się zapalona. Szybka analiza Dragonfly'em pozwoliła mi stwierdzić, że przy wyłączonym tle dla :after (które również znalazłem od razu, wcale nie sugerując się tym co ty napisałeś :P) zgaszonej lampki też nie ma. A to oznacza, że musi być wyłączona w CSS, skoro nadal jest w kodzie (nie została usunięta z DOM-u). CSS dla zgaszonej diody

#header a[href*="konkurs"] img {
display: none !important;
}

Jeszcze nie wiem jak wygląda ten CSS przy faktycznie zgaszonej diodzie, ale na razie na to patrząc, zgaduję, że pojawia się display: block (!important wskazuje wyraźnie na to, że to jest nadrzędny i główny styl, który nie jest nadpisywany przez inne (a jeśli jest to są nieważne), więc tylko on może włączyć/wyłączyć diodę). A w takim wypadku wystarczy sprawdzić wyrażeniem regularnym czy display ma "none" i wyświetlić komunikat, że jest dostępne pytanie.

soanvig   10 #24 30.09.2012 23:50

Ale tak czy siak to jest ten moment, kiedy webmasterstwo się faktycznie na coś przydaje :D

aeroflyluby   15 #25 01.10.2012 01:00

soanvig - styl zostaje - png diody sie zmienia z zapalonego na niezapalony, styl zawsze jest wyswietlany :D

DonM$   10 #26 01.10.2012 02:57

Heh, a ja rozgryzłem konkurs na tablica.pl...

soanvig   10 #27 01.10.2012 16:01

.@aerufolyluby
No tak, niby masz rację.

Autor edytował komentarz.