~jezra/shnerkel/trunk

« back to all changes in this revision

Viewing changes to src/rssxmlparser.vala

  • Committer: jezra
  • Date: 2010-04-05 20:48:30 UTC
  • Revision ID: jezra@jezra.net-20100405204830-f81oc5v74466y3sv
initial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    rssxmlparser.vala
 
3
    Using libxml2 to get the latest titles, descriptions, release dates, 
 
4
    and files paths from an audcast xml feed file
 
5
*/
 
6
 
 
7
using GLib;
 
8
using Xml;
 
9
 
 
10
public errordomain XmlError
 
11
{
 
12
    FILE_NOT_FOUND,
 
13
    XML_DOCUMENT_EMPTY
 
14
}
 
15
 
 
16
public class rssParser : GLib.Object {
 
17
    //what signals will this class emit?
 
18
    public signal void send_message(string message);
 
19
    public signal void send_episode_info(string[] episode_data);
 
20
    
 
21
    //what variable need to be persistant in scope?
 
22
    List<string> episode_title;
 
23
    List<string> episode_description;
 
24
    List<string> episode_file;
 
25
    List<string> episode_release_date;
 
26
    int episode_count;
 
27
    
 
28
    //what happens when this class is constructed?
 
29
    construct{
 
30
      //init the parser
 
31
      //initialisation, not instantiation since the parser is a static class
 
32
      Parser.init();
 
33
     }
 
34
     
 
35
  //we will have lists to store the data of the various shows
 
36
  public void rssParser(){
 
37
 
 
38
    this.episode_title = new List<string>();
 
39
    this.episode_description = new List<string>();
 
40
    this.episode_file = new List<string>();
 
41
    this.episode_release_date = new List<string>();
 
42
    this.episode_count = 0;
 
43
  }
 
44
  
 
45
    private void parse_item_node( Xml.Node* the_node )
 
46
    {
 
47
        //get the children of the root node as a node
 
48
        Xml.Node* node_children = the_node->children;
 
49
        Xml.Node* iter = node_children->next;
 
50
 
 
51
        string iter_node_name;
 
52
        string title = "";
 
53
        string description = "";
 
54
        string file = "";
 
55
        string release_date = "";
 
56
        //this is an episode, increment the episode count
 
57
        this.episode_count++;
 
58
        while(iter!=null)
 
59
        {  
 
60
          //spaces btw. tags are also nodes, discard them
 
61
          if (iter->type != ElementType.ELEMENT_NODE)
 
62
          {
 
63
            //do nothing
 
64
          }else{
 
65
            iter_node_name = iter->name;
 
66
            
 
67
            switch(iter_node_name)
 
68
            {
 
69
              case "title":
 
70
                title = iter->get_content();
 
71
                break;
 
72
              
 
73
              case "description":
 
74
                description = iter->get_content();
 
75
                break;
 
76
              case "enclosure":
 
77
                file = iter->get_prop("url");
 
78
                break;
 
79
              case "pubDate":
 
80
                release_date = iter->get_content();
 
81
                break;
 
82
              
 
83
            }
 
84
          }
 
85
          iter=iter->next;
 
86
        }
 
87
                //send the data as a signal
 
88
                string[] data = new string[4];
 
89
                data[0] = title;
 
90
                data[1]=description;
 
91
                data[2]=file;
 
92
                data[3]=release_date;
 
93
                send_episode_info(data);
 
94
        this.episode_title.append(title);
 
95
        this.episode_description.append(description);
 
96
        this.episode_file.append(file);
 
97
        this.episode_release_date.append(release_date);
 
98
    }
 
99
    
 
100
    public void print_episode_info()
 
101
    {
 
102
      string title;
 
103
      string description;
 
104
      string file;
 
105
      string release_date;
 
106
      for ( int i = 0; i<this.episode_count;i++)
 
107
      {
 
108
        title = this.episode_title.nth_data(i);
 
109
        description = this.episode_description.nth_data(i);
 
110
        file = this.episode_file.nth_data(i);
 
111
        release_date = this.episode_release_date.nth_data(i);
 
112
        stdout.printf("%s\n",title);
 
113
        stdout.printf("%s\n",file);
 
114
        stdout.printf("%s\n",release_date);
 
115
        
 
116
        //stdout.printf("%s\n\n",description);
 
117
      }
 
118
    
 
119
    }
 
120
    public void parse_file(string file) throws XmlError
 
121
    {
 
122
 
 
123
        send_message("parsing "+file);
 
124
        //parse the XML file 
 
125
        Xml.Doc* xml_doc = Parser.parse_file(file);
 
126
        if (xml_doc == null) {
 
127
            send_message(file+" is not readable");
 
128
            throw new XmlError.FILE_NOT_FOUND (file+" is not readable");
 
129
        }
 
130
 
 
131
        //get the root node. notice the dereferencing operator -> instead of .
 
132
        Xml.Node* root_node = xml_doc->get_root_element();
 
133
        
 
134
        if (root_node == null) {
 
135
            //free the document manually before throwing because the garbage collector can't work on pointers
 
136
            delete xml_doc;
 
137
            send_message(file+" is empty");
 
138
            throw new XmlError.XML_DOCUMENT_EMPTY (file + " is empty");
 
139
        }
 
140
        
 
141
        //get the children of the root node as a node
 
142
        Xml.Node* root_children = root_node->children;
 
143
        Xml.Node* iter = root_children->next;
 
144
 
 
145
        string iter_node_name;
 
146
        //rss should be the top node
 
147
        if(iter->name=="channel")
 
148
        {
 
149
          //get the children of the channel
 
150
          iter = iter->children;
 
151
          //get the first node of the channel children
 
152
          iter = iter->next;
 
153
          //loop through the channel children
 
154
          while(iter!=null)
 
155
          {  
 
156
            //spaces btw. tags are also nodes, discard them
 
157
            if (iter->type != ElementType.ELEMENT_NODE)
 
158
            {
 
159
              //do nothing
 
160
            }else{
 
161
              iter_node_name = iter->name;
 
162
              if(iter_node_name=="item")
 
163
              {
 
164
                  parse_item_node(iter);
 
165
              }
 
166
            }
 
167
            iter=iter->next;
 
168
          }
 
169
        }else{
 
170
          //the first node under root is not the channel, what should I do?
 
171
        }
 
172
        //free the document
 
173
        delete xml_doc;
 
174
    }
 
175
    
 
176
    public void clean_up()
 
177
    {
 
178
            //do the parser cleanup to free the used memory
 
179
            Parser.cleanup ();
 
180
    }
 
181
}