pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
added a cleanup function to autogen.sh which gets called on SIGINT to cleanup our temp files (autogen-??????)
2009-10-27, Gary Kramlich
f8733e54f6fe
added a cleanup function to autogen.sh which gets called on SIGINT to cleanup our temp files (autogen-??????)
/*--------------------------------------------------------------------------*
* AUTOPROFILE *
* *
* A Purple away message and profile manager that supports dynamic text *
* *
* AutoProfile is the legal property of its developers. Please refer to *
* the COPYRIGHT file distributed with this source distribution. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
*--------------------------------------------------------------------------*/
#include
"autoprofile.h"
#include
"comp_rss.h"
#include
"utility.h"
#include
<string.h>
static
gboolean
parsing_rss
=
FALSE
;
static
gboolean
parsing_item
=
FALSE
;
static
gboolean
item_title
=
FALSE
;
static
gboolean
item_link
=
FALSE
;
static
gboolean
item_description
=
FALSE
;
static
gboolean
item_comments
=
FALSE
;
static
gboolean
item_pubdate
=
FALSE
;
/* Get URL of RSS feed */
static
char
*
get_url
(
struct
widget
*
w
)
{
int
type
;
char
*
ret
;
const
char
*
username
;
GString
*
s
;
type
=
ap_prefs_get_int
(
w
,
"type"
);
s
=
g_string_new
(
""
);
switch
(
type
)
{
case
RSS_LIVEJOURNAL
:
username
=
ap_prefs_get_string
(
w
,
"username"
);
g_string_append_printf
(
s
,
"http://www.livejournal.com/users/%s/data/rss"
,
username
);
break
;
case
RSS_XANGA
:
username
=
ap_prefs_get_string
(
w
,
"username"
);
g_string_append_printf
(
s
,
"http://www.xanga.com/%s/rss"
,
username
);
break
;
case
RSS_2
:
g_string_append_printf
(
s
,
"%s"
,
ap_prefs_get_string
(
w
,
"location"
));
break
;
default
:
break
;
}
ret
=
s
->
str
;
g_string_free
(
s
,
FALSE
);
return
ret
;
}
/* Utility functions */
static
void
free_entries
(
struct
widget
*
w
)
{
GList
*
tmp
,
*
entries
;
struct
rss_entry
*
e
;
entries
=
(
GList
*
)
g_hash_table_lookup
(
rss_entries
,
w
);
while
(
entries
)
{
e
=
(
struct
rss_entry
*
)
entries
->
data
;
if
(
e
->
title
)
free
(
e
->
title
);
if
(
e
->
entry
)
free
(
e
->
entry
);
if
(
e
->
url
)
free
(
e
->
url
);
if
(
e
->
comments
)
free
(
e
->
comments
);
if
(
e
->
t
)
free
(
e
->
t
);
free
(
e
);
tmp
=
entries
;
entries
=
entries
->
next
;
g_list_free_1
(
tmp
);
}
g_hash_table_replace
(
rss_entries
,
w
,
NULL
);
}
/* Date parsing functions */
static
struct
tm
*
parse_date_rfc822
(
const
char
*
date_string
)
{
time_t
t
,
gmt_time
,
local_time
;
struct
tm
*
ret
,
*
result
;
local_time
=
time
(
NULL
);
gmt_time
=
time
(
NULL
);
gmt_time
=
mktime
(
gmtime
(
&
gmt_time
));
// TODO: Change this to GDate
t
=
rfc_parse_date_time
(
date_string
);
// if (rfc_parse_was_gmt ()) {
// FIXME: Handle time zones
// } else {
ret
=
(
struct
tm
*
)
malloc
(
sizeof
(
struct
tm
));
result
=
localtime
(
&
t
);
ret
->
tm_sec
=
result
->
tm_sec
;
ret
->
tm_min
=
result
->
tm_min
;
ret
->
tm_hour
=
result
->
tm_hour
;
ret
->
tm_mday
=
result
->
tm_mday
;
ret
->
tm_mon
=
result
->
tm_mon
;
ret
->
tm_year
=
result
->
tm_year
;
//}
return
ret
;
}
/* XML Parser Callbacks */
static
void
start_element_handler
(
GMarkupParseContext
*
context
,
const
gchar
*
element_name
,
const
gchar
**
attribuate_names
,
const
gchar
**
attribute_values
,
gpointer
data
,
GError
**
error
)
{
struct
rss_entry
*
e
;
GList
*
entries
;
struct
widget
*
w
=
(
struct
widget
*
)
data
;
//printf ("start:%s\n", element_name);
if
(
!
parsing_rss
&&
!
strcmp
(
element_name
,
"rss"
))
parsing_rss
=
TRUE
;
else
if
(
parsing_rss
&&
!
parsing_item
&&
!
strcmp
(
element_name
,
"item"
))
{
parsing_item
=
TRUE
;
e
=
(
struct
rss_entry
*
)
malloc
(
sizeof
(
struct
rss_entry
));
entries
=
(
GList
*
)
g_hash_table_lookup
(
rss_entries
,
w
);
entries
=
g_list_prepend
(
entries
,
e
);
g_hash_table_replace
(
rss_entries
,
w
,
entries
);
e
->
t
=
NULL
;
e
->
title
=
NULL
;
e
->
entry
=
NULL
;
e
->
url
=
NULL
;
e
->
comments
=
NULL
;
}
else
if
(
parsing_item
&&
!
strcmp
(
element_name
,
"title"
))
item_title
=
TRUE
;
else
if
(
parsing_item
&&
!
strcmp
(
element_name
,
"link"
))
item_link
=
TRUE
;
else
if
(
parsing_item
&&
!
strcmp
(
element_name
,
"description"
))
item_description
=
TRUE
;
else
if
(
parsing_item
&&
!
strcmp
(
element_name
,
"comments"
))
item_comments
=
TRUE
;
else
if
(
parsing_item
&&
!
strcmp
(
element_name
,
"pubDate"
))
item_pubdate
=
TRUE
;
}
static
void
end_element_handler
(
GMarkupParseContext
*
context
,
const
gchar
*
element_name
,
gpointer
data
,
GError
**
error
)
{
struct
widget
*
w
=
(
struct
widget
*
)
w
;
//printf ("end:%s\n", element_name);
if
(
!
strcmp
(
element_name
,
"rss"
))
parsing_rss
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"item"
))
parsing_item
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"title"
))
item_title
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"link"
))
item_link
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"description"
))
item_description
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"comments"
))
item_comments
=
FALSE
;
else
if
(
!
strcmp
(
element_name
,
"pubDate"
))
item_pubdate
=
FALSE
;
}
static
void
text_handler
(
GMarkupParseContext
*
context
,
const
gchar
*
text
,
gsize
text_len
,
gpointer
data
,
GError
**
error
)
{
struct
rss_entry
*
e
;
GList
*
entries
;
struct
widget
*
w
=
(
struct
widget
*
)
data
;
entries
=
(
GList
*
)
g_hash_table_lookup
(
rss_entries
,
w
);
if
(
entries
==
NULL
)
{
return
;
}
e
=
(
struct
rss_entry
*
)
entries
->
data
;
if
(
item_link
)
{
if
(
e
->
url
)
{
free
(
e
->
url
);
}
e
->
url
=
g_strdup
(
text
);
}
else
if
(
item_description
)
{
if
(
e
->
entry
)
{
free
(
e
->
entry
);
}
e
->
entry
=
purple_unescape_html
(
text
);
// If there is a standard format for Xanga titles (there really isn't)
// it will probably be devised from the actual content. Will be placed
// here if there is proven demand.
}
else
if
(
item_comments
)
{
if
(
e
->
comments
)
{
free
(
e
->
comments
);
}
e
->
comments
=
g_strdup
(
text
);
}
else
if
(
item_title
)
{
if
(
e
->
title
)
{
free
(
e
->
title
);
}
e
->
title
=
g_strdup
(
text
);
}
else
if
(
item_pubdate
)
{
if
(
e
->
t
)
{
free
(
e
->
t
);
}
e
->
t
=
parse_date_rfc822
(
text
);
}
}
/* Final parser variable */
GMarkupParser
rss_parser
=
{
start_element_handler
,
end_element_handler
,
text_handler
,
NULL
,
NULL
};
/* Callback for HTTP data fetcher */
static
void
url_callback
(
PurpleUtilFetchUrlData
*
url_data
,
gpointer
data
,
const
char
*
text
,
size_t
size
,
const
gchar
*
error_message
)
{
GMarkupParseContext
*
context
;
gchar
*
filtered_text
;
GError
*
err
=
NULL
;
GList
*
entries
;
struct
widget
*
w
=
(
struct
widget
*
)
data
;
/* Make sure URL exists/connected to Internet */
if
(
text
==
NULL
)
{
ap_debug
(
"rss"
,
"error, unable to fetch page via internet"
);
return
;
}
parsing_rss
=
FALSE
;
parsing_item
=
FALSE
;
item_title
=
FALSE
;
item_link
=
FALSE
;
item_description
=
FALSE
;
item_comments
=
FALSE
;
item_pubdate
=
FALSE
;
g_static_mutex_lock
(
&
rss_mutex
);
free_entries
(
w
);
// Sanity checking
filtered_text
=
purple_utf8_salvage
(
text
);
gchar
*
convert
=
purple_utf8_try_convert
(
"<"
);
gchar
*
next
=
g_utf8_strchr
(
filtered_text
,
10
,
g_utf8_get_char
(
convert
));
free
(
convert
);
if
(
next
==
NULL
)
{
free
(
filtered_text
);
// TODO: error out
g_static_mutex_unlock
(
&
rss_mutex
);
return
;
}
if
(
ap_prefs_get_int
(
w
,
"type"
)
==
RSS_XANGA
)
{
parse_xanga_rss
(
w
,
filtered_text
);
entries
=
(
GList
*
)
g_hash_table_lookup
(
rss_entries
,
w
);
entries
=
g_list_reverse
(
entries
);
g_hash_table_replace
(
rss_entries
,
w
,
entries
);
g_static_mutex_unlock
(
&
rss_mutex
);
free
(
filtered_text
);
return
;
}
context
=
g_markup_parse_context_new
(
&
rss_parser
,
0
,
w
,
NULL
);
if
(
!
g_markup_parse_context_parse
(
context
,
next
,
size
,
&
err
))
{
g_markup_parse_context_free
(
context
);
ap_debug
(
"rss"
,
"error, unable to start parser"
);
ap_debug
(
"rss"
,
err
->
message
);
free
(
filtered_text
);
return
;
}
if
(
!
g_markup_parse_context_end_parse
(
context
,
&
err
))
{
g_markup_parse_context_free
(
context
);
ap_debug
(
"rss"
,
"error, unable to end parser"
);
free
(
filtered_text
);
return
;
}
g_markup_parse_context_free
(
context
);
entries
=
(
GList
*
)
g_hash_table_lookup
(
rss_entries
,
w
);
entries
=
g_list_reverse
(
entries
);
g_hash_table_replace
(
rss_entries
,
w
,
entries
);
g_static_mutex_unlock
(
&
rss_mutex
);
free
(
filtered_text
);
}
void
parse_rss
(
struct
widget
*
w
)
{
char
*
url
;
url
=
get_url
(
w
);
if
(
strcmp
(
url
,
""
)
!=
0
)
{
purple_util_fetch_url
(
url
,
TRUE
,
NULL
,
FALSE
,
url_callback
,
w
);
}
free
(
url
);
}