MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
it2m.c
Go to the documentation of this file.
1 /*
2  * it2m.c
3  *
4  *
5  * Created by sonique on 28/10/06.
6  * Copyright 2006 Cedric FERRY. All rights reserved.
7  *
8  * contact : sonique_irc(at)yahoo(dot)fr
9  * http://sonique54.free.fr/it2m/
10  * http://sonique54.free.fr/it2m/it2m-0.1.i386.tar.bz2
11  *
12  */
13 
14 #include "iT2M.h"
15 
16 // gcc `xml2-config --cflags --libs` -lmysqlclient -o it2m it2m.c && ./it2m
17 
18 
19 
20 // this file exist ?
21 int is_file (const char *filename) {
22  struct stat buf;
23  if (stat (filename, &buf) == -1)
24  return (0);
25  if (S_ISREG (buf.st_mode))
26  return (1);
27  return (0);
28 }
29 
30 // Usage of it2m
31 void usage(){
32  printf("\n\t*************** it2m: Usage ***************\nit2m itunes.xml dbpassword user databasename port\nit2m ([itunes.xml]|default='iTunes Music Library.xml') dbpassword \n\t[ user [(database|default='mythconverg')] [(port|default=3306)] ]\n* VerySimple Use : YourPassWord\n* Simple : YourItunesMusicLin.xml YourPassWord\n* Custom : YourItunesMusicLin.xml YourPassWord YouUser\n* Default : \"iTunes Music Library.xml\" YourPass root mythconverg 3306\n\ni2tm : writed by Sonique :: Cedric FERRY :: http://sonique54.free.fr.\n");
33  return;
34 }
35 
36 
37 // Update MythTV database
38 int UpdateMythConverg(char * artname, char * albname, char * songname, char * rating, char * count){
39 
40  MYSQL_RES *res;
41  MYSQL_ROW row;
42  int t;
43  int rate = atoi(rating)/10;
44  int numplays = atoi(count);
45  int num_rows = 0;
46  char query [1024] ="";
47  sprintf(query,"UPDATE music_songs SET rating = %d, numplays = %d WHERE music_songs.artist_id IN (SELECT artist_id FROM music_artists WHERE artist_name LIKE \"%s%%\") AND music_songs.album_id IN (SELECT album_id FROM music_albums WHERE album_name LIKE \"%s%%\") AND music_songs.name LIKE \"%s%%\" ",rate, numplays, artname, albname, songname);
48 
49 
50  t=mysql_real_query(mysql, query, strlen(query));
51  if (t) {
52  printf("UpdateMythConverg request error : %s \n", mysql_error(mysql) );
53  } else {
54  if(mysql_affected_rows(mysql) < 1){
55  // music cannot be found in database OR already usage();
56  printf("\t\t%s - %s - %s cannot be found OR already up to date.\n", artname, albname, songname);
57  } else {
58  // Succefully Updated
59  printf("%s - %s - %s Have been UPDATED.\n",artname, albname, songname);
60  }
61  }
62 }
63 
64 
65 // Scan itms XML file to find Play Count and Rating
66 int scan_itms (const char *filename ){
67 
68  // XML Var
69  xmlDocPtr xmlperms_doc = NULL;
70  xmlXPathContextPtr xmlperms_context = NULL;
71  xmlXPathObjectPtr xmlobject;
72 
73  const char path_template[] = "/plist/dict/dict/dict/*";
74 
75  char *path;
76 
77  if (!filename){
78  fprintf (stderr, "%s:%d File not found\n", __FILE__, __LINE__);
79  return (0);
80  }
81 
82  xmlperms_doc = xmlParseFile (filename);
83 
84  if (!xmlperms_doc) {
85  fprintf (stderr, "%s:%d Could not parse the document\n", __FILE__,__LINE__);
86  return (0);
87  }
88 
89  xmlXPathInit();
90 
91  xmlperms_context = xmlXPathNewContext (xmlperms_doc);
92 
93  xmlobject = xmlXPathEval (path_template, xmlperms_context);
94 
95  // Stockage Var
96  char * albname = NULL;
97  char * artname = NULL;
98  char * rating = NULL;
99  char * songname = NULL;
100  char * count = NULL;
101 
102 
103  if ( (xmlobject->type == XPATH_NODESET) &&
104  (xmlobject->nodesetval) ){
105  // Is number of node > 0 ?
106  if (xmlobject->nodesetval->nodeNr){
107  xmlNodePtr node, node2;
108  int i=0;
109  // For each node found value
110  for(i=0; i<xmlobject->nodesetval->nodeNr-1; i++){
111 
112  node = xmlobject->nodesetval->nodeTab[i]; // Key ex: Album
113  node2 = xmlobject->nodesetval->nodeTab[i+1]; // Value ex: Album Name
114  xmlChar *pathact1 = xmlGetNodePath (node);
115 
116  // Is it a node ? Is it a "key"
117  if( node->type == XML_ELEMENT_NODE &&
118  (xmlobject->nodesetval) &&
119  strcmp( node->name, "key" ) == 0 ){
120 
121  // New Track ID = New Songs -> free memory
122  if( strcmp( (char*)node->children->content,"Track ID")==0 ){
123  free(albname);
124  free(artname);
125  free(rating);
126  free(songname);
127  free(count);
128  artname = NULL;
129  albname = NULL;
130  songname = NULL;
131  rating = NULL;
132  count = NULL;
133  }
134  // Balise Name found, get Song Name
135  if( strcmp( (char*)node->children->content,"Name")==0 ){
136  if(strcmp( node2->name,"string") == 0) {
137  songname = strdup(node2->children->content);
138  }
139  }
140  // Balise Album found, get Album Name
141  if(strcmp((char *) node->children->content,"Album")==0 ) {
142  if(strcmp(node2->name,"string") == 0){
143  albname = strdup(node2->children->content);
144  }
145  }
146  // Balise Artist found, get Artist Name
147  if(strcmp((char *) node->children->content,"Artist")==0 ){
148  if(strcmp(node2->name,"string") == 0){
149  artname = strdup(node2->children->content);
150  }
151  }
152  // Balise Play Count found, get Num plays
153  if(strcmp((char *) node->children->content,"Play Count")==0 ){
154  if(strcmp(node2->name,"integer") == 0){
155  count = strdup(node2->children->content);
156  }
157  }
158  // Balise Rating found, get Rate
159  if(strcmp((char *) node->children->content,"Rating")==0 ){
160  if(strcmp(node2->name,"integer") == 0){
161  rating = strdup(node2->children->content);
162  }
163  }
164 
165  // If evry data are there, fill database
166  if(rating != NULL && artname != NULL && albname != NULL && songname != NULL ){
167 
168  if(count == NULL){ count = strdup("0"); }
169  // Go ! Fill database
170  UpdateMythConverg(artname, albname, songname, rating, count);
171  // Free Memory else for each other balise next Rating,
172  free(albname);
173  free(artname);
174  free(rating);
175  free(songname);
176  free(count);
177  artname = NULL;
178  albname = NULL;
179  songname = NULL;
180  rating = NULL;
181  count = NULL;
182  }
183  }
184  }
185  // Free Memory
186  free(albname);
187  free(artname);
188  free(rating);
189  free(songname);
190  free(count);
191  }
192  }
193  // Free XML Memory
194  xmlXPathFreeObject (xmlobject);
195  xmlXPathFreeContext (xmlperms_context);
196  return;
197 }
198 
199 
200 
201 // Order of parameters
202 // it2m ituneslibraryfile.xml password user databasename port
203 // 0 1 2 3 4 5
204 
205 main(int argc, char **argv)
206 {
207  char * file;
208  char * pass;
209  char * user;
210  char * dbname;
211  int port=0;
212  int i = 1;
213 
214  mysql=mysql_init(NULL);
215 
216  // Test Itunes Library File
217  if(!is_file (argv[i]) && !is_file ("iTunes Music Library.xml") ){
218  printf("Error : No such file to analyse, %s or iTunes Music Library.xml not found.\n\n", argv[0]);
219  usage();
220  exit(-1);
221  } else if(is_file (argv[i])){
222  file=strdup(argv[i]);
223  i++;
224  } else {
225  file=strdup("iTunes Music Library.xml");
226  }
227 
228 
229 
230  // Test Password
231  if(argv[i] == NULL){
232  printf("Error : You must specify the MySQL password.\n");
233  usage();
234  exit(-1);
235  } else {
236  pass=strdup(argv[i]);
237  i++;
238  }
239 
240  // Test User
241  if(argv[i]==NULL){
242  printf("* No user given in argument, root will be used.\n");
243  user=strdup("root");
244  } else {
245  user=strdup(argv[i]);
246  i++;
247  }
248 
249  // Test DataBase name
250  if(argv[i]==NULL){
251  printf("* No dbname given in argument, mythconverg will be used.\n");
252  dbname=strdup("mythconverg");
253  } else {
254  dbname=strdup(argv[i]);
255  i++;
256  }
257 
258 
259  // Test DataBase Port
260  if(argv[i]==NULL){
261  printf("* No port given in argument, 3306 will be used.\n");
262  port=3306;
263  } else {
264  port=atoi(argv[i]);
265  }
266 
267  printf(" Itunes Music File: %s \n Password: %s \n User: %s \n dbname: %s \n port: %d \n", file, pass, user, dbname, port);
268 
269 
270 
271  if (!mysql_real_connect(mysql,"localhost",user,pass,dbname,port,NULL,0)) {
272  printf("Connection error : %s \n", mysql_error(mysql) );
273  exit(1) ;
274  } else {
275  printf("MySQL aviable ...\n");
276  }
277 
278 
279  xmlDocPtr xmldoc = NULL;
280  xmldoc = xmlParseFile (file);
281  if (!xmldoc){
282  printf("%s isn't an XML file.\n",file);
283  //fprintf (stderr, "%s:%d: %s n'est pas un fichier XML.\n",argv[0], __FILE__, __LINE__);
284  exit (EXIT_FAILURE);
285  }
286 
287  scan_itms(file);
288 
289  xmlFreeDoc (xmldoc);
290  mysql_close(mysql);
291  exit (EXIT_SUCCESS);
292 }
void usage()
show usage
Definition: it2m.c:31
MYSQL * mysql
Definition: it2m.h:32
main(int argc, char **argv)
Definition: it2m.c:205
const char * filename
Definition: ioapi.h:135
int UpdateMythConverg(char *artname, char *albname, char *songname, char *rating, char *count)
Definition: it2m.c:38
unsigned char t
Definition: ParseText.cpp:339
int is_file(const char *filename)
Definition: it2m.c:21
int scan_itms(const char *filename)
Definition: it2m.c:66