aggregator.module 12.5 KB
Newer Older
1 2
<?php

Dries's avatar
 
Dries committed
3
function import_help() {
4 5 6 7 8
 ?>
  <P>TODO - anyone?</P>
 <?php
}

Dries's avatar
 
Dries committed
9 10 11 12
function import_perm() {
  return array("add and edit news feeds");
}

Dries's avatar
 
Dries committed
13
function import_cron() {
14 15 16
  $result = db_query("SELECT * FROM feed");
  while ($feed = db_fetch_array($result)) {
    // remove expired items:
Dries's avatar
 
Dries committed
17
    db_query("DELETE FROM item WHERE fid = '$feed[fid]' AND timestamp < ". (time() - $feed[uncache]));
18 19

    // update feeds:
Dries's avatar
 
Dries committed
20
    if ($feed[timestamp] + $feed[refresh] < time()) import_update($feed);
21 22 23
  }
}

24 25
function import_bundle($attributes, $limit = 100) {
  if ($attributes) {
26
    // compose query:
27 28
    $keys = explode(",", $attributes);
    foreach ($keys as $key) $where[] = "attributes LIKE '%". trim($key) ."%'";
29

Dries's avatar
 
Dries committed
30
    $result = db_query("SELECT * FROM item WHERE ". implode(" OR ", $where) ." ORDER BY timestamp DESC LIMIT $limit");
31 32 33 34 35

    while ($item = db_fetch_object($result)) {
      $output .= "<LI><A HREF=\"". check_output($item->link) ."\">". check_output($item->title) ."</A></LI>";
    }

Dries's avatar
 
Dries committed
36
    return "$output";
37 38 39
  }
}

Dries's avatar
 
Dries committed
40
function import_view_bundle() {
Dries's avatar
 
Dries committed
41
  $result = db_query("SELECT * FROM bundle ORDER BY title");
42
  while ($bundle = db_fetch_object($result)) {
43
    $output .= "<B>$bundle->title</B><UL>". import_bundle($bundle->attributes) ."</UL>";
44 45 46 47
  }
  return $output;
}

Dries's avatar
 
Dries committed
48 49 50 51 52
function import_block() {
  $result = db_query("SELECT * FROM bundle ORDER BY title");
  while ($bundle = db_fetch_object($result)) {
    $i++;
    $blocks[$i][subject] = $bundle->title;
53
    $blocks[$i][content] = import_bundle($bundle->attributes, 10);
Dries's avatar
 
Dries committed
54 55 56 57 58
    $blocks[$i][info] = "$bundle->title bundle";
  }
  return $blocks;
}

Dries's avatar
 
Dries committed
59 60 61 62 63
function import_remove($feed) {
  db_query("DELETE FROM item WHERE fid = '$feed[fid]'");
  return "feed '$feed[title]' reset.";
}

Dries's avatar
 
Dries committed
64
function import_update($feed) {
65 66 67 68 69 70 71 72 73 74 75 76

  // open socket:
  $url = parse_url($feed[link]);
  $fp = fsockopen($url[host], ($url[port] ? $url[port] : 80), $errno, $errstr, 15);

  if ($fp) {
    // fetch data:
    fputs($fp, "GET $url[path]?$url[query] HTTP/1.0\nUser-Agent: ". variable_get(site_name, "drupal") ."\nHost: $url[host]\nAccept: */*\n\n");
    while(!feof($fp)) $data .= fgets($fp, 128);

    if (strstr($data, "200 OK")) {

Dries's avatar
 
Dries committed
77 78 79
      eregi("<item([^s].*)</item>", $data, $data);

      // print "<PRE>". htmlentities($data[0]) ."</PRE>";
80 81 82

      foreach (explode("</item>", $data[0]) as $item) {
        $t = eregi("<title>(.*)</title>", $item, $title);
Dries's avatar
 
Dries committed
83
        $l = eregi("<link>(.*)</link>", $item, $link);
84 85 86 87
        $a = eregi("<author>(.*)</author>", $item, $author);
        $d = eregi("<description>(.*)</description>", $item, $description);

        if ($l || $t || $a || $d) {
88
          import_save_item(array(fid => $feed[fid], title => $title[0], link => $link[0], author => $author[0], description => $description[0], attributes => $feed[attributes]));
89 90 91 92 93 94 95 96 97
        }
      }

      db_query("UPDATE feed SET timestamp = '". time() ."' WHERE fid = '". $feed[fid] ."'");
    }
    else {
      watchdog("error", "failed to syndicate from '$feed[title]'");
    }
  }
Dries's avatar
 
Dries committed
98 99

  return "feed '$feed[title]' updated.";
100 101
}

Dries's avatar
 
Dries committed
102
function import_save_item($edit) {
103
  if ($edit[iid] && $edit[title]) {
104
    db_query("UPDATE item SET title = '". check_input($edit[title]) ."', link = '". check_input($edit[link]) ."', author = '". check_input($edit[author]) ."', description = '". check_input($edit[description]) ."', attributes = '". check_input($edit[attributes]) ."' WHERE iid = '$edit[iid]'");
105 106 107 108 109 110
  }
  else if ($edit[iid]) {
    db_query("DELETE FROM item WHERE iid = '". check_input($edit[iid]) ."'");
  }
  else {
    if (!db_fetch_object(db_query("SELECT iid FROM item WHERE link = '". check_input($edit[link]) ."'"))) {
111
      db_query("INSERT INTO item (fid, title, link, author, description, attributes, timestamp) VALUES ('". check_input($edit[fid]) ."', '". check_input($edit[title]) ."', '". check_input($edit[link]) ."', '". check_input($edit[author]) ."', '". check_input($edit[description]) ."', '". check_input($edit[attributes]) ."', '". time() ."')");
112 113 114 115
    }
  }
}

Dries's avatar
 
Dries committed
116
function import_form_bundle($edit = array()) {
117 118 119
  global $REQUEST_URI;

  $form .= form_textfield("Title", "title", $edit[title], 50, 64, "The name of the bundle.");
120
  $form .= form_textfield("Attributes", "attributes", $edit[attributes], 50, 128, "A comma-seperated list of keywords describing the bundle.");
121 122 123 124 125 126 127 128 129 130 131

  $form .= form_submit("Submit");

  if ($edit[bid]) {
    $form .= form_submit(t("Delete"));
    $form .= form_hidden("bid", $edit[bid]);
  }

  return form($REQUEST_URI, $form);
}

Dries's avatar
 
Dries committed
132
function import_save_bundle($edit) {
133
  if ($edit[bid] && $edit[title]) {
134
    db_query("UPDATE bundle SET title = '". check_input($edit[title]) ."', attributes = '". check_input($edit[attributes]) ."' WHERE bid = '". check_input($edit[bid]) ."'");
135 136 137 138 139
  }
  else if ($edit[bid]) {
    db_query("DELETE FROM bundle WHERE bid = '". check_input($edit[bid]) ."'");
  }
  else {
140
    db_query("INSERT INTO bundle (title, attributes) VALUES ('". check_input($edit[title]) ."', '". check_input($edit[attributes]) ."')");
141
  }
Dries's avatar
 
Dries committed
142 143

  module_rehash_blocks("import");
144 145
}

Dries's avatar
 
Dries committed
146
function import_form_feed($edit = array()) {
147 148 149 150 151
  global $REQUEST_URI;

  $period = array(900 => format_interval(900), 1800 => format_interval(1800), 3600 => format_interval(3600), 7200 => format_interval(7200), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 64800 => format_interval(64800), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200));

  $form .= form_textfield("Title", "title", $edit[title], 50, 64, "The name of the feed; typically the name of the website you syndicate content from.");
Dries's avatar
 
Dries committed
152
  $form .= form_textfield("Link", "link", $edit[link], 50, 128, "The fully-qualified URL of the feed.");
153
  $form .= form_textfield("Attributes", "attributes", $edit[attributes], 50, 128, "A comma-seperated list of keywords describing the feed.");
154 155 156 157 158 159 160 161 162 163 164 165 166
  $form .= form_select("Update interval", "refresh", $edit[refresh], $period, "The refresh interval indicating how often you want to update this feed.  Requires crontab.");
  $form .= form_select("Expiration time", "uncache", $edit[uncache], $period, "The time cached items should be kept.  Older items will be automatically discarded.  Requires crontab.");

  $form .= form_submit("Submit");

  if ($edit[fid]) {
    $form .= form_submit(t("Delete"));
    $form .= form_hidden("fid", $edit[fid]);
  }

  return form($REQUEST_URI, $form);
}

Dries's avatar
 
Dries committed
167
function import_save_feed($edit) {
168
  if ($edit[fid] && $edit[title]) {
169
    db_query("UPDATE feed SET title = '". check_input($edit[title]) ."', link = '". check_input($edit[link]) ."', attributes = '". check_input($edit[attributes]) ."', refresh = '". check_input($edit[refresh]) ."', uncache = '". check_input($edit[uncache]) ."' WHERE fid = '". check_input($edit[fid]) ."'");
170 171 172 173 174 175 176
    db_query("DELETE FROM item WHERE fid = '". check_input($edit[fid]) ."'");
  }
  else if ($edit[fid]) {
    db_query("DELETE FROM feed WHERE fid = '". check_input($edit[fid]) ."'");
    db_query("DELETE FROM item WHERE fid = '". check_input($edit[fid]) ."'");
  }
  else {
177
    db_query("INSERT INTO feed (title, link, attributes, refresh, uncache) VALUES ('". check_input($edit[title]) ."', '". check_input($edit[link]) ."', '". check_input($edit[attributes]) ."', '". check_input($edit[refresh]) ."', '". check_input($edit[uncache]) ."')");
178 179 180
  }
}

Dries's avatar
 
Dries committed
181
function import_save_attributes($edit) {
182
  foreach($edit as $iid => $value) {
183
    db_query("UPDATE item SET attributes = '". check_input($value) ."' WHERE iid = '". check_input($iid) ."'");
184 185 186 187
  }
  return "attributes has been saved";
}

Dries's avatar
 
Dries committed
188
function import_get_feed($fid) {
189 190 191
  return db_fetch_array(db_query("SELECT * FROM feed WHERE fid = '". check_input($fid) ."'"));
}

Dries's avatar
 
Dries committed
192
function import_get_bundle($bid) {
193 194 195
  return db_fetch_array(db_query("SELECT * FROM bundle WHERE bid = '". check_input($bid) ."'"));
}

Dries's avatar
 
Dries committed
196
function import_view_feed() {
197 198
  $result = db_query("SELECT f.*, COUNT(i.iid) AS items FROM feed f LEFT JOIN item i ON f.fid = i.fid GROUP BY f.fid ORDER BY f.title");

Dries's avatar
 
Dries committed
199
  $output .= "<H3>Feed overview</H3>";
200
  $output .= "<TABLE BORDER=\"1\" CELLSPADDING=\"2\" CELLSPACING=\"2\">\n";
Dries's avatar
 
Dries committed
201
  $output .= " <TR><TH>title</TH><TH>attributes</TH><TH>items</TH><TH>last update</TH><TH>next update</TH><TH COLSPAN=\"3\">operations</TH></TR>\n";
202
  while ($feed = db_fetch_object($result)) {
203
    $output .= " <TR><TD>". check_output($feed->title) ."</TD><TD>". check_output($feed->attributes) ."</TD><TD>". format_plural($feed->items, "item", "items") ."</TD><TD>". ($feed->timestamp ? format_interval(time() - $feed->timestamp) ." ago" : "never") ."</TD><TD>". ($feed->timestamp ? format_interval($feed->timestamp + $feed->refresh - time()) ." left" : "never") ."</TD><TD><A HREF=\"admin.php?mod=import&type=feed&op=edit&id=$feed->fid\">edit feed</A></TD><TD><A HREF=\"admin.php?mod=import&type=feed&op=remove&id=$feed->fid\">remove items</A></TD><TD><A HREF=\"admin.php?mod=import&type=feed&op=update&id=$feed->fid\">update items</A></TD></TR>\n";
204 205 206 207 208
  }
  $output .= "</TABLE>\n";

  $result = db_query("SELECT * FROM bundle ORDER BY title");

Dries's avatar
 
Dries committed
209
  $output .= "<H3>Bundle overview</H3>";
210 211 212
  $output .= "<TABLE BORDER=\"1\" CELLSPADDING=\"2\" CELLSPACING=\"2\">\n";
  $output .= " <TR><TH>title</TH><TH>attributes</TH><TH>operations</TH></TR>\n";
  while ($bundle = db_fetch_object($result)) {
213
    $output .= " <TR><TD>". check_output($bundle->title) ."</TD><TD>". check_output($bundle->attributes) ."</TD><TD><A HREF=\"admin.php?mod=import&type=bundle&op=edit&id=$bundle->bid\">edit bundle</A></TD></TR>\n";
214 215 216 217 218 219
  }
  $output .= "</TABLE>\n";

  return $output;
}

Dries's avatar
 
Dries committed
220
function import_view_item() {
221 222 223 224 225 226 227 228
  global $REQUEST_URI;

  $result = db_query("SELECT i.*, f.title AS feed FROM item i LEFT JOIN feed f ON i.fid = f.fid ORDER BY i.timestamp DESC LIMIT 50");

  $output .= "<FORM ACTION=\"$REQUEST_URI\" METHOD=\"post\">\n";
  $output .= "<TABLE BORDER=\"1\" CELLSPADDING=\"2\" CELLSPACING=\"2\">\n";
  $output .= " <TR><TH>time</TH><TH>feed</TH><TH>item</TH></TR>\n";
  while ($item = db_fetch_object($result)) {
229
    $output .= " <TR><TD VALIGN=\"top\" NOWRAP>". format_date($item->timestamp, "custom", "m/d/y") ."<BR>".format_date($item->timestamp, "custom", "H:i") ."</TD><TD ALIGN=\"center\" VALIGN=\"top\" NOWRAP><A HREF=\"admin.php?mod=import&type=feed&op=edit&id=$item->fid\">". check_output($item->feed) ."</A></TD><TD><A HREF=\"". check_output($item->link) ."\">". check_output($item->title) ."</A>". ($item->description ? "<BR><SMALL><I>". check_output($item->description) ."</I></SMALL>" : "") ."<BR><INPUT TYPE=\"text\" NAME=\"edit[$item->iid]\" VALUE=\"". check_form($item->attributes) ."\" SIZE=\"50\"></TD></TR>\n";
230 231 232 233 234 235 236 237
  }
  $output .= "</TABLE>\n";
  $output .= "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"Save attributes\">\n";
  $output .= "</FORM>\n";

  return $output;
}

Dries's avatar
 
Dries committed
238
function import_admin() {
Dries's avatar
 
Dries committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
  global $user, $op, $id, $type, $edit;

  if (user_access($user, "add and edit news feeds")) {

    print "<SMALL><A HREF=\"admin.php?mod=import&type=bundle&op=add\">add new bundle</A> | <A HREF=\"admin.php?mod=import&type=feed&op=add\">add new feed</A> | <A HREF=\"admin.php?mod=import&type=bundle&op=view\">available bundles</A> | <A HREF=\"admin.php?mod=import&type=item&op=view\">available items</A> | <A HREF=\"admin.php?mod=import&op=view\">overview</A> | <A HREF=\"admin.php?mod=import&op=help\">help</A></SMALL><HR>";

    switch($op) {
      case "help":
        print import_help();
        break;
      case "add":
        if ($type == "bundle")
          print import_form_bundle();
        else
          print import_form_feed();
        break;
      case "edit":
        if ($type == "bundle")
          print import_form_bundle(import_get_bundle($id));
        else
          print import_form_feed(import_get_feed($id));
        break;
      case "remove":
        print status(import_remove(import_get_feed($id)));
        print import_view_feed();
        break;
      case "update":
        print status(import_update(import_get_feed($id)));
Dries's avatar
 
Dries committed
267
        print import_view_feed();
Dries's avatar
 
Dries committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
        break;
      case "Save attributes":
        print status(import_save_attributes($edit));
        print import_view_item();
        break;
      case "Delete":
        $edit[title] = 0;
        // fall through:
      case "Submit":
        if ($type == "bundle")
          print status(import_save_bundle($edit));
        else
          print status(import_save_feed($edit));
        // fall through:
      default:
        if ($type == "bundle")
          print import_view_bundle();
        else if ($type == "item")
          print import_view_item();
        else
          print import_view_feed();
    }
  }
  else {
    print message_access();
293 294 295 296
  }
}

?>