[php] van bash- naar een phpscript voor een igooglegadget

Pagina: 1
Acties:
  • 122 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • freyk
  • Registratie: September 2003
  • Laatst online: 18-09 22:46
Hallo,

Na een aantal maanden geleden igoogle ontdekt te hebben, leek het me leuk om eens zelf een paar igoogle-gadgets te schrijven.(Dit is een eitje als je de developer-guide volgt)

Ik kwam op het idee om een gadget te schrijven dat de nieuwste video van een bepaalde youtube-poster in je googlepage weergeeft.
Hiervoor heb ik een aantal dingen nodig:
  • Een plek waar je googlegadget (een xml-bestand) kan laten hosten
  • Een igoogle pagina
  • En een script waarmee je een xml bestand kan laten genereren
De eerste twee dingen heb ik al, maar het laatste wil me nog niet lukken.

Het is me gelukt om een bash-scriptje te schrijven, maar nu lijkt het me verstandig om deze om te zetten naar een php-script zodat iedereen het kan draaien.

Ik heb zitten kloten met readfile(), fopen(), file_get_contents() en fwrite(), maar het lukt me nog niet.
Ik zit dus nu met de volgende vragen:
Hoe download ik met php een profielpagina om daarna daarin te zoeken en de benodigde informatie een xml bestand te zetten.

Code van bashscript:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/bash

# Igoogle Page Generator
# A bashscripts that search the newest video from an user and generates a xml voor igoogle

#Required things
# * Bash
# * cat
# * AWK
# * GREP
# * A location to host the .xml on the internet
# * And a Igoogle page

# *** Preferences
#The username of your favourite poster: 
ytuser="digitalfilmmaker" # Username of your poster like WilliamSledd, DaxFlame, digitalfilmmaker, etc

# == Do nothing with after this line
#-------------------------------------------------------------------------------------


#Display Title of script and status
echo ""
echo " ** Freyk's Newest youtube-video searcher and igoogle-gadget generator ** "
echo ""
echo "== Status =="

# Downloading profilepage
echo " - Downloading movielist from user $ytuser "
wget -q http://www.youtube.com/profile_videos?user=$ytuser
# Renaminging the file tot movielist.txt
mv profile_videos\?user\=$ytuser movielist.txt

# The Search for the newest video from $ytuser
echo " - Searching newest video"
newlink=`cat movielist.txt | grep '<div><a' | head -n1 | awk 'BEGIN { FS = "<" } ; { print $3 }' | awk 'BEGIN { FS = "/" } ; { print $2 }' | awk 'BEGIN { FS = "\"" } ; { print $1 }' | awk 'BEGIN { FS = "=" } ; { print $2 }'`
youtubelink="http://www.youtube.com/watch?v=$newlink"

#Search for movietitle
movietitle=`cat movielist.txt | grep $newlink | grep onclick | awk 'BEGIN { FS = ">" } ; { print $2 }' | awk 'BEGIN { FS = "<" } ; { print $1 }'`

#generating xml for Google Gadget 
echo " - Generating xml for Google Gadget "
echo '<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="Newest Post from '$ytuser' 0.1 (made by Freyk)" />
<Content type="html"><![CDATA[
<center><object type="application/x-shockwave-flash" style="width:250px; height:200px;" data="http://www.youtube.com/v/'$newlink'"><param name="movie" value="http://www.youtube.com/v/'$newlink'"></object><br><b>'$movietitle'</b></center>
]]></Content>
</Module>' > $ytuser.xml

echo " - Remove Used Temporary Files "
rm movielist.txt 

#display link in bash
echo ""
echo "The url of the newest video from $ytuser is: " 
echo "$youtubelink"
echo "$movietitle"
echo ""


-edit-
Om het uiteindelijke resultaat te kunnen zien, ga je naar igoogle, klik op items toevoegen -> toevoegen via url en voeg het volgende adres in: http://fborgerink1.googlepages.com/digitalfilmmaker.xml

[ Voor 5% gewijzigd door freyk op 08-07-2007 19:53 . Reden: voorbeeld van igoogle-gadget ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
freyk schreef op zondag 08 juli 2007 @ 19:41:
Ik heb zitten kloten met readfile(), fopen(), file_get_contents() en fwrite(), maar het lukt me nog niet.
Ik zit dus nu met de volgende vragen:
Hoe download ik met php een profielpagina om daarna daarin te zoeken en de benodigde informatie een xml bestand te zetten.
Dat is al een heel goed begin. Het enige dat je nodig hebt om de data op te halen (ter vervanging van wget) is file_get_contents. Heb je de data eenmaal binnen, kun je met reguliere expressies (of, iets makkelijker voor de beginner, combinaties van strpos en substr) de juiste gegevens uit de pagina krijgen.
Gegevens opslaan in een xml-bestand kan met file_put_contents (of omslachtig via fopen/fwrite). Dat nieuwe commando is alleen onder PHP5 beschikbaar, maar in de comments in de manual staat hoe je dezelfde functie ook onder PHP4 beschikbaar krijgt. Zet die functiedefinitie wel tussen een function_exists conditie, anders krijg je weer problemen onder PHP5 (maar ook dat staat in de comments).
Was je zelf al verdergekomen dan het binnenhalen van de pagina?

[ Voor 24% gewijzigd door GlowMouse op 08-07-2007 19:58 ]


Acties:
  • 0 Henk 'm!

  • freyk
  • Registratie: September 2003
  • Laatst online: 18-09 22:46
Na een format ben ik helaas mijn php-scriptje kwijt geraakt, maar ik kan me nog wel herinneren dat het met niet lukte om met getcontent gegevens te op te halen.
Misschien dat ik het op een knullige manier zo had geschreven dat hij de profielenpagina op youtube's server opende, in plaats van op mijn server?

Acties:
  • 0 Henk 'm!

  • Alex)
  • Registratie: Juni 2003
  • Laatst online: 21-08 11:20
PHP:
1
2
3
<?php
$inhoud = file_get_contents("http://www.youtube.com/profile_videos?user=".$ytuser);
?>


Is min-of-meer-hetzelfde als:
Bash:
1
2
3
wget -q http://www.youtube.com/profile_videos?user=$ytuser
mv profile_videos\?user\=$ytuser movielist.txt
cat movielist.txt

We are shaping the future


Acties:
  • 0 Henk 'm!

  • freyk
  • Registratie: September 2003
  • Laatst online: 18-09 22:46
Ik ben een stukje verder gekomen, door mijn code opnieuw te schrijven in php.
Ik heb ontdekt dat je met pregmatch een string door kan zoeken en dat je het via een array weer kan laten geven.

Nu zit ik met het probleem dat ik niet weet welke recursieve expressies bij searchpatterns moet zetten om het te laten werken.

mijn code tot nu toe (waarvan ik nog de voorbeeldcode nog moet veranderen d.m.v jullie hulp):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php
#Youtube's Newest Post 
# Version: 0.1
# Creator: Freyk

#Description:
# a php script that search the newest post from a youtube user and generates an igoogle gadget

# *** Preferences
# Username of your poster like WilliamSledd, DaxFlame, digitalfilmmaker, etc
$ytuser="digitalfilmmaker"

# == Do nothing with after this line
#-------------------------------------------------------------------------------------

#Get the contents from profilepage
$profilecontents= file_get_contents("http://www.youtube.com/profile_videos?user=".$ytuser); 

# Searching for the newest video from $ytuser

#oude bashcode:
# $newlink=`cat movielist.txt | grep '<div><a' | head -n1 | awk 'BEGIN { FS = "<" } ; { print $3 }' | awk 'BEGIN { FS = "/" } ; { print $2 }' | awk 'BEGIN { FS = "\"" } ; { print $1 }' | awk 'BEGIN { FS = "=" } ; { print $2 }'`

$searchpattern1="/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/"
preg_match_all($searchpattern1, $profilecontents, $matches1, PREG_SET_ORDER);
foreach ($matches1 as $val1) {
    echo "matched: " . $val1[0] . "\n";
    echo "part 1: " . $val1[1] . "\n";
    echo "part 2: " . $val1[3] . "\n";
    echo "part 3: " . $val1[4] . "\n\n";
}
# $Newlink=$val[1]

$youtubelink="http://www.youtube.com/watch?v=".$newlink

#Search for movietitle

#oude bashcode
#$movietitle=`cat movielist.txt | grep $newlink | grep onclick | awk 'BEGIN { FS = ">" } ; { print $2 }' | awk 'BEGIN { FS = "<" } ; { print $1 }'`

$searchpattern2="/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/"
preg_match_all($searchpattern2, $profilecontents, $matches2, PREG_SET_ORDER);
foreach ($matches2 as $val2) {
    echo "matched: " . $val2[0] . "\n";
    echo "part 1: " . $val2[1] . "\n";
    echo "part 2: " . $val2[3] . "\n";
    echo "part 3: " . $val2[4] . "\n\n";
}
# $movietitle=$val2[4]

#generating xml
echo '
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs 
    title="Newest post from a Youtube Poster 0.1 (powered by Freyk)" 
    author="freyk" 
    author_email="emailadres" />
<UserPref name="ytposter" 
    display_name="YT-Username" 
    default_value="'; echo $ytposter; echo '" />
  <Content type="html"><![CDATA[
<center><object type="application/x-shockwave-flash" style="width:250px; height:200px;" data="http://www.youtube.com/v/'; echo $newlink; '"><param name="movie" value="http://www.youtube.com/v/'; echo $newlink; '"></object></center>
]]></Content>
</Module>';

?>

Acties:
  • 0 Henk 'm!

  • freyk
  • Registratie: September 2003
  • Laatst online: 18-09 22:46
Het blijkt dat file_get_contents de data opslaat in plain text en stream_get_contents zijn data bewaard in in code formaat.
Omdat mijn script in code moet zoeken, wijzig ik file_get_contents naar stream_get_contents.

Mijn huidige code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
#Youtube's Newest Post 
# Version: 0.1
# Creator: Freyk

#Description:
# a php script that search the newest post from a youtube user and generates an igoogle gadget

# *** Preferences
# Username of your poster like WilliamSledd, DaxFlame, digitalfilmmaker, etc
$ytuser="digitalfilmmaker";

# == Do nothing with after this line
#-------------------------------------------------------------------------------------

#Get the contents from profilepage

#Save contents (text) in array: 
#$inhoud = file_get_contents("http://www.youtube.com/profile_videos?user=".$ytuser); 
#Save contents (code) in array: 
#$handle = fopen("http://www.youtube.com/profile_videos?user=".$ytuser, "r");
#$inhoud = stream_get_contents($handle);
#fclose($handle);
 
$handle = fopen("http://www.youtube.com/profile_videos?user=".$ytuser, "r");
$inhoud = stream_get_contents($handle);
fclose($handle);


# Searching for the newest video from $ytuser

#oude bashcode:
# $newlink=`cat movielist.txt | grep '<div><a' | head -n1 | awk 'BEGIN { FS = "<" } ; { print $3 }' | awk 'BEGIN { FS = "/" } ; { print $2 }' | awk 'BEGIN { FS = "\"" } ; { print $1 }' | awk 'BEGIN { FS = "=" } ; { print $2 }'`

$searchpattern1="/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/";
preg_match_all($searchpattern1, $inhoud, $matches1, PREG_SET_ORDER);
foreach ($matches1 as $val1) {
    echo "matched: " . $val1[0] . "\n";
    echo "part 1: " . $val1[1] . "\n";
    echo "part 2: " . $val1[3] . "\n";
    echo "part 3: " . $val1[4] . "\n\n";
}
# $Newlink=$val[1];

$youtubelink="http://www.youtube.com/watch?v=".$newlink;

#Search for movietitle

#oude bashcode
#$movietitle=`cat movielist.txt | grep $newlink | grep onclick | awk 'BEGIN { FS = ">" } ; { print $2 }' | awk 'BEGIN { FS = "<" } ; { print $1 }'`

$searchpattern2="/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/";
preg_match_all($searchpattern2, $inhoud, $matches2, PREG_SET_ORDER);
foreach ($matches2 as $val2) {
    echo "matched: " . $val2[0] . "\n";
    echo "part 1: " . $val2[1] . "\n";
    echo "part 2: " . $val2[3] . "\n";
    echo "part 3: " . $val2[4] . "\n\n";
};
# $movietitle=$val2[4];



#generating xml
echo '
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs 
    title="Newest post from a Youtube Poster 0.1 (powered by Freyk)" 
    author="freyk" 
    author_email="emailadres" />
<UserPref name="ytposter" 
    display_name="YT-Username" 
    default_value="'; echo $ytposter; echo '" />
  <Content type="html"><![CDATA[
<center><object type="application/x-shockwave-flash" style="width:250px; height:200px;" data="http://www.youtube.com/v/'; echo $newlink; '"><param name="movie" value="http://www.youtube.com/v/'; echo $newlink; '"></object></center>
]]></Content>
</Module>';

?>

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Tussen file_get_contents en stream_get_contents zit geen verschil in output. Ik weet niet over wat voor code formaat je het hebt, maar er is gewoon geen verschil.
Ik zal je eerste pattern voordoen. Met de huidige pagina lijk je op zoek naar 'Py9lMXen5tM'. In de broncode van de Youtube-pagina komt dit voor in het stukje <a href="/watch?v=Py9lMXen5tM">. Door even te proberen zie je dat het stukje code <a href="/watch?v= als eerste voorkomt vlak voor de string die je wilt hebben, en daarna nog enkele malen. Een preg_match_all is dus niet nodig, een preg_match volstaat want je hebt alleen het eerste resultaat nodig.
PHP:
1
2
3
$searchpattern1 = '/<a href="\\/watch\\?v=([^"]*)/';
preg_match($searchpattern1, $inhoud, $matches1);
print_r($matches1);

En ziedaar:
Array
(
[0] => <a href="/watch?v=Py9lMXen5tM
[1] => Py9lMXen5tM
)

De beschrijving mag je nu zelf proberen.

Wanneer je twee posts doet met daartussen een tijdsverschil van minder dan 24h, kun je beter je oude post aanpassen om te voorkomen dat je het topic onnodig omhoog schopt.

Acties:
  • 0 Henk 'm!

  • freyk
  • Registratie: September 2003
  • Laatst online: 18-09 22:46
Dankje GlowMouse, dat heeft geholpen! :)

De uiteindelijke code ziet er als volgt uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
#Youtube's Newest Post 
# Version: 0.1
# Creator: Freyk

#Description:
# a php script that search the latest post from a youtube user and generates an igoogle gadget

# *** Preferences
# Username of your poster like WilliamSledd, DaxFlame, digitalfilmmaker, etc
$ytuser="digitalfilmmaker";

# == Do nothing with after this line
#-------------------------------------------------------------------------------------

#Get the contents from profilepage
$handle = fopen("http://www.youtube.com/profile_videos?user=".$ytuser, "r");
$contentsprofilepage = stream_get_contents($handle);
fclose($handle);


# Searching for the newest video from $ytuser
$newestvideosearchpattern = '/<a href="\\/watch\\?v=([^"]*)/';
preg_match($newestvideosearchpattern, $contentsprofilepage, $newestvideomatches);
#print_r($matches1);
#echo "$matches1[0]";
#echo "matches 2";
$newlink = $newestvideomatches[1];

#The URL of the newest video
$youtubelink="http://www.youtube.com/watch?v=".$newlink;

#generating xml
echo '<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs 
    title="The Latest '; echo $ytuser; echo' Youtube Video" 
    author="freyk" 
    author_email="fborgerink1@gmail.com" />
  <Content type="html"><![CDATA[
<center><object type="application/x-shockwave-flash" style="width:250px; height:200px;" data="http://www.youtube.com/v/'; echo $newlink; echo'"><param name="movie" value="http://www.youtube.com/v/'; echo $newlink; echo'"></object></center>
]]></Content>
</Module>';

?>

Nu nog ff een optie toevoegen, waarmee je de nieuwste video's van andere yt-gebruikers kan bekijken
Pagina: 1