diff --git a/README.md b/README.md
index 21682e8bf..3600f2890 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ TorrentPier II - движок торрент-трекера, написанны
Исходя из настроек вашего сервера, устанавливаем рекомендуемые права доступа (chmod) на указанные папки **777**, а на файлы внутри этих папок (кроме файлов **.htaccess** и **.keep**) **666**:
- ajax/html
+- atom
- cache
- cache/filecache
- images
diff --git a/install/sql/mysql.sql b/install/sql/mysql.sql
index 8aed473d3..3a168aefa 100644
--- a/install/sql/mysql.sql
+++ b/install/sql/mysql.sql
@@ -645,6 +645,7 @@ INSERT INTO `bb_cron` VALUES (19, 1, 'Captcha', 'captcha_gen_gc.php', 'daily', N
INSERT INTO `bb_cron` VALUES (20, 1, 'Tracker dl-complete count', 'tr_complete_count.php', 'interval', NULL, NULL, 255, '', '', '06:00:00', 0, '', 0, 0, 0);
INSERT INTO `bb_cron` VALUES (21, 1, 'Cache garbage collector', 'cache_gc.php', 'interval', NULL, NULL, 255, '', '', '00:05:00', 0, '', 0, 0, 0);
INSERT INTO `bb_cron` VALUES (22, 1, 'Sitemap update', 'sitemap.php', 'daily', NULL, '06:00:00', 30, '', '', NULL, 0, '', 0, 0, 0);
+INSERT INTO `bb_cron` VALUES (23, 1, 'Update forums atom', 'update_forums_atom.php', 'interval', NULL, NULL, 255, '', '', '00:20:00', 0, '', 0, 0, 0);
-- --------------------------------------------------------
diff --git a/upload/ajax/posts.php b/upload/ajax/posts.php
index 86ad38dbe..7c6397144 100644
--- a/upload/ajax/posts.php
+++ b/upload/ajax/posts.php
@@ -57,6 +57,10 @@ switch($this->request['type'])
$this->prompt_for_confirm($lang['CONFIRM_DELETE']);
}
post_delete($post_id);
+
+ // Update atom feed
+ update_atom('topic', (int) $this->request['topic_id']);
+
$this->response['hide'] = true;
$this->response['post_id'] = $post_id;
}
@@ -158,6 +162,9 @@ switch($this->request['type'])
}
else $this->ajax_die($lang['EMPTY_MESSAGE']);
+ // Update atom feed
+ update_atom('topic', (int) $this->request['topic_id']);
+
$this->response['html'] = bbcode2html($text);
}
else
@@ -309,6 +316,9 @@ switch($this->request['type'])
user_notification('reply', $post, $post['topic_title'], $post['forum_id'], $topic_id, $notify);
}
+ // Update atom feed
+ update_atom('topic', (int) $this->request['topic_id']);
+
$this->response['redirect'] = make_url(POST_URL . "$post_id#$post_id");
break;
diff --git a/upload/atom/.keep b/upload/atom/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/upload/config.php b/upload/config.php
index 9371b61bd..254f3b42b 100644
--- a/upload/config.php
+++ b/upload/config.php
@@ -56,6 +56,7 @@
* Avatars
* Misc
* Captcha
+ * Atom feed
**/
if (!defined('BB_ROOT')) die(basename(__FILE__));
@@ -68,8 +69,8 @@ $domain_name = (!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : $do
// Version info
$bb_cfg['tp_version'] = '2.0.9 (RC)';
-$bb_cfg['tp_release_date'] = '07-08-2014';
-$bb_cfg['tp_release_state'] = 'R594b';
+$bb_cfg['tp_release_date'] = '14-08-2014';
+$bb_cfg['tp_release_state'] = 'R595';
// Database
$charset = 'utf8';
@@ -590,10 +591,16 @@ $bb_cfg['advert_url'] = 'misc.php?do=info&show=advert';
// Captcha
$bb_cfg['captcha'] = array(
- 'disabled' => false,
+ 'disabled' => false,
'secret_key' => 'secret_key',
- 'img_url' => './images/captcha/', # without '/'
- 'img_path' => BB_PATH .'/images/captcha/', # without '/'
+ 'img_url' => './images/captcha/',
+ 'img_path' => BB_PATH .'/images/captcha/',
+);
+
+// Atom feed
+$bb_cfg['atom'] = array(
+ 'path' => BB_PATH .'/atom',
+ 'url' => './atom',
);
define('BB_CFG_LOADED', true);
\ No newline at end of file
diff --git a/upload/feed.php b/upload/feed.php
new file mode 100644
index 000000000..87b981957
--- /dev/null
+++ b/upload/feed.php
@@ -0,0 +1,68 @@
+session_start(array('req_login' => true));
+
+$mode = (string) @$_REQUEST['mode'];
+$type = (string) @$_POST['type'];
+$id = (int) @$_POST['id'];
+$timecheck = TIMENOW - 600;
+
+if (!$mode) bb_simple_die($lang['ATOM_NO_MODE']);
+
+if ($mode == 'get_feed_url' && ($type == 'f' || $type == 'u') && $id >= 0)
+{
+ if ($type == 'f')
+ {
+ // Check if the user has actually sent a forum ID
+ $sql = "SELECT allow_reg_tracker, forum_name FROM ". BB_FORUMS ." WHERE forum_id = $id LIMIT 1";
+ if (!$forum_data = DB()->fetch_row($sql))
+ {
+ if ($id == 0)
+ {
+ $forum_data = array();
+ }
+ else bb_simple_die($lang['ATOM_ERROR'].' #1');
+ }
+ if (file_exists($bb_cfg['atom']['path'] .'/f/'. $id .'.atom') && filemtime($bb_cfg['atom']['path'] .'/f/'. $id .'.atom') > $timecheck)
+ {
+ redirect($bb_cfg['atom']['url'] .'/f/'. $id .'.atom');
+ }
+ else
+ {
+ require_once(INC_DIR .'functions_atom.php');
+ if (update_forum_feed($id, $forum_data)) redirect($bb_cfg['atom']['url'] .'/f/'. $id .'.atom');
+ else bb_simple_die($lang['ATOM_NO_FORUM']);
+ }
+ }
+ if ($type == 'u')
+ {
+ // Check if the user has actually sent a user ID
+ if ($id < 1)
+ {
+ bb_simple_die($lang['ATOM_ERROR'].' #2');
+ }
+ if (!$username = get_username($id))
+ {
+ bb_simple_die($lang['ATOM_ERROR'].' #3');
+ }
+ if (file_exists($bb_cfg['atom']['path'] .'/u/'. floor($id/5000) .'/'. ($id % 100) .'/'. $id .'.atom') && filemtime($bb_cfg['atom']['path'] .'/u/'. floor($id/5000) .'/'. ($id % 100) .'/'. $id .'.atom') > $timecheck)
+ {
+ redirect($bb_cfg['atom']['url'] .'/u/'. floor($id/5000) .'/'. ($id % 100) .'/'. $id .'.atom');
+ }
+ else
+ {
+ require_once(INC_DIR .'functions_atom.php');
+ if (update_user_feed($id, $username)) redirect($bb_cfg['atom']['url'] .'/u/'. floor($id/5000) .'/'. ($id % 100) .'/'. $id .'.atom');
+ else bb_simple_die($lang['ATOM_NO_USER']);
+ }
+ }
+}
+else
+{
+ bb_simple_die($lang['ATOM_ERROR'].' #4');
+}
\ No newline at end of file
diff --git a/upload/includes/captcha/captcha.php b/upload/includes/captcha/captcha.php
index 61fe023d3..4ecfcdc34 100644
--- a/upload/includes/captcha/captcha.php
+++ b/upload/includes/captcha/captcha.php
@@ -131,7 +131,7 @@ class captcha_common
CACHE('bb_cap_sid')->set('c_sid_'. $this->new_cap_sid, $this->new_cap_code, $this->key_ttl*2);
}
- function get_img_url ($id)
+ function get_img_url ($id)
{
return $this->get_path($id, $this->cfg['img_url']);
}
@@ -215,8 +215,6 @@ class captcha_kcaptcha extends captcha_common
$credits = $bb_cfg['server_name']; # if empty, HTTP_HOST will be shown
# CAPTCHA image colors (RGB, 0-255)
- //$foreground_color = array(0, 0, 0);
- //$background_color = array(220, 230, 255);
$foreground_color = array(mt_rand(0,100), mt_rand(0,100), mt_rand(0,100));
$background_color = array(mt_rand(200,255), mt_rand(200,255), mt_rand(200,255));
@@ -316,7 +314,7 @@ class captcha_kcaptcha extends captcha_common
$center=$x/2;
- // credits. To remove, see configuration file
+ // credits
$img2=imagecreatetruecolor($width, $height+($show_credits?12:0));
$foreground=imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]);
$background=imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]);
@@ -390,8 +388,6 @@ class captcha_kcaptcha extends captcha_common
file_write('', $img_path, null, true, true);
imagejpeg($img2, $img_path, $jpeg_quality);
-# imagegif($img2, $img_path);
-# imagepng($img2, $img_path);
imagedestroy($img2);
diff --git a/upload/includes/cron/jobs/update_forums_atom.php b/upload/includes/cron/jobs/update_forums_atom.php
new file mode 100644
index 000000000..eaf6bc73e
--- /dev/null
+++ b/upload/includes/cron/jobs/update_forums_atom.php
@@ -0,0 +1,23 @@
+fetch_rowset("SELECT forum_id, allow_reg_tracker, forum_name FROM ". BB_FORUMS);
+
+if (!file_exists($bb_cfg['atom']['path'] .'/f/0.atom') && filemtime($bb_cfg['atom']['path'] .'/f/0.atom') <= $timecheck)
+{
+ update_forum_feed(0, $forums_data);
+}
+
+foreach ($forums_data as $forum_data)
+{
+ if (!file_exists($bb_cfg['atom']['path'] .'/f/'. $forum_data['forum_id'] .'.atom') && filemtime($bb_cfg['atom']['path'] .'/f/'. $forum_data['forum_id'] .'.atom') <= $timecheck)
+ {
+ update_forum_feed($forum_data['forum_id'], $forum_data);
+ }
+}
\ No newline at end of file
diff --git a/upload/includes/functions.php b/upload/includes/functions.php
index c8c7db0a6..b92c29b34 100644
--- a/upload/includes/functions.php
+++ b/upload/includes/functions.php
@@ -11,7 +11,7 @@ function get_path_from_id ($id, $ext_id, $base_path, $first_div, $sec_div)
function get_avatar_path ($id, $ext_id, $base_path = '')
{
- return get_path_from_id($id, $ext_id, $base_path, 5000000, 100);
+ return get_path_from_id($id, $ext_id, $base_path, 5000, 100);
}
function delete_avatar ($user_id, $avatar_ext_id)
@@ -24,7 +24,7 @@ function delete_avatar ($user_id, $avatar_ext_id)
function get_attach_path ($id)
{
global $bb_cfg;
- return get_path_from_id($id, '', $bb_cfg['attach']['upload_path'], 1000000, 100);
+ return get_path_from_id($id, '', $bb_cfg['attach']['upload_path'], 1000, 100);
}
function get_tracks ($type)
@@ -2836,4 +2836,21 @@ function is_gold ($type)
}
return $is_gold;
+}
+
+function update_atom ($type, $id)
+{
+ require_once(INC_DIR .'functions_atom.php');
+
+ switch ($type)
+ {
+ case 'user':
+ update_user_feed($id, get_username($id));
+ break;
+
+ case 'topic':
+ $topic_poster = (int) DB()->fetch_row("SELECT topic_poster FROM ". BB_TOPICS ." WHERE topic_id = $id LIMIT 1", 'topic_poster');
+ update_user_feed($topic_poster, get_username($topic_poster));
+ break;
+ }
}
\ No newline at end of file
diff --git a/upload/includes/functions_admin.php b/upload/includes/functions_admin.php
index 32ce428f8..1c4319d32 100644
--- a/upload/includes/functions_admin.php
+++ b/upload/includes/functions_admin.php
@@ -277,6 +277,13 @@ function topic_delete ($mode_or_topic_id, $forum_id = null, $prune_time = 0, $pr
GROUP BY p.poster_id
");
+ // Get array for atom update
+ $atom_csv = array();
+ foreach (DB()->fetch_rowset('SELECT user_id FROM '.$tmp_user_posts) as $at)
+ {
+ $atom_csv[] = $at['user_id'];
+ }
+
DB()->query("
UPDATE
$tmp_user_posts tmp, ". BB_USERS ." u
@@ -384,6 +391,12 @@ function topic_delete ($mode_or_topic_id, $forum_id = null, $prune_time = 0, $pr
// Sync
sync('forum', array_keys($sync_forums));
+ // Update atom feed
+ foreach ($atom_csv as $atom)
+ {
+ update_atom('user', $atom);
+ }
+
DB()->query("DROP TEMPORARY TABLE $tmp_delete_topics");
return $deleted_topics_count;
@@ -663,6 +676,16 @@ function post_delete ($mode_or_post_id, $user_id = null, $exclude_first = true)
sync('forum', array_keys($sync_forums));
sync('user_posts', $sync_users);
+ // Update atom feed
+ foreach ($sync_topics as $atom_topic)
+ {
+ update_atom('topic', $atom_topic);
+ }
+ foreach ($sync_users as $atom_user)
+ {
+ update_atom('user', $atom_user);
+ }
+
DB()->query("DROP TEMPORARY TABLE $tmp_delete_posts");
return $deleted_posts_count;
@@ -670,7 +693,7 @@ function post_delete ($mode_or_post_id, $user_id = null, $exclude_first = true)
function user_delete ($user_id, $delete_posts = false)
{
- global $log_action;
+ global $bb_cfg, $log_action;
if (!$user_csv = get_id_csv($user_id))
{
@@ -755,6 +778,13 @@ function user_delete ($user_id, $delete_posts = false)
DB()->query("UPDATE ". BB_PRIVMSGS ." SET privmsgs_from_userid = ". DELETED ." WHERE privmsgs_from_userid IN($user_csv)");
DB()->query("UPDATE ". BB_PRIVMSGS ." SET privmsgs_to_userid = ". DELETED ." WHERE privmsgs_to_userid IN($user_csv)");
+
+ // Delete user feed
+ foreach (explode(',', $user_csv) as $user_id)
+ {
+ $file_path = $bb_cfg['atom']['path'] .'/u/'. floor($user_id/5000) .'/'. ($user_id % 100) .'/'. $user_id .'.atom';
+ @unlink($file_path);
+ }
}
function get_usernames_for_log ($user_id)
diff --git a/upload/includes/functions_atom.php b/upload/includes/functions_atom.php
new file mode 100644
index 000000000..0c3c4f2e2
--- /dev/null
+++ b/upload/includes/functions_atom.php
@@ -0,0 +1,186 @@
+ 0 && $forum_data['allow_reg_tracker'])
+ {
+ $select_tor_sql = ', tor.size AS tor_size, tor.tor_status';
+ $join_tor_sql = "LEFT JOIN ". BB_BT_TORRENTS ." tor ON(t.topic_id = tor.topic_id)";
+ }
+ if ($forum_id == 0)
+ {
+ $sql = "
+ SELECT
+ t.topic_id, t.topic_title, t.topic_status,
+ u1.username AS first_username,
+ p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
+ p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time,
+ tor.size AS tor_size, tor.tor_status
+ FROM ". BB_BT_TORRENTS ." tor
+ LEFT JOIN ". BB_TOPICS ." t ON(tor.topic_id = t.topic_id)
+ LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
+ LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
+ LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
+ ORDER BY t.topic_last_post_time DESC
+ LIMIT 100
+ ";
+ }
+ else if ($forum_id > 0)
+ {
+ $sql = "
+ SELECT
+ t.topic_id, t.topic_title, t.topic_status,
+ u1.username AS first_username,
+ p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
+ p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time
+ $select_tor_sql
+ FROM ". BB_TOPICS ." t
+ LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
+ LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
+ LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
+ $join_tor_sql
+ WHERE t.forum_id = $forum_id
+ ORDER BY t.topic_last_post_time DESC
+ LIMIT 50
+ ";
+ }
+ $topics_tmp = DB()->fetch_rowset($sql);
+ $topics = array();
+ foreach ($topics_tmp as $topic)
+ {
+ if (isset($topic['topic_status']))
+ {
+ if ($topic['topic_status'] == TOPIC_MOVED) continue;
+ }
+ if (isset($topic['tor_status']))
+ {
+ if (isset($bb_cfg['tor_frozen'][$topic['tor_status']])) continue;
+ }
+ $topics[] = $topic;
+ }
+ if (!count($topics))
+ {
+ @unlink($file_path);
+ return false;
+ }
+ if (create_atom($file_path, 'f', $forum_id, htmlCHR($forum_data['forum_name']), $topics)) return true;
+ else return false;
+}
+
+function update_user_feed ($user_id, $username)
+{
+ global $bb_cfg;
+ $file_path = $bb_cfg['atom']['path'] .'/u/'. floor($user_id/5000) .'/'. ($user_id % 100) .'/'. $user_id .'.atom';
+ $sql = "
+ SELECT
+ t.topic_id, t.topic_title, t.topic_status,
+ u1.username AS first_username,
+ p1.post_time AS topic_first_post_time, p1.post_edit_time AS topic_first_post_edit_time,
+ p2.post_time AS topic_last_post_time, p2.post_edit_time AS topic_last_post_edit_time,
+ tor.size AS tor_size, tor.tor_status
+ FROM ". BB_TOPICS ." t
+ LEFT JOIN ". BB_USERS ." u1 ON(t.topic_poster = u1.user_id)
+ LEFT JOIN ". BB_POSTS ." p1 ON(t.topic_first_post_id = p1.post_id)
+ LEFT JOIN ". BB_POSTS ." p2 ON(t.topic_last_post_id = p2.post_id)
+ LEFT JOIN ". BB_BT_TORRENTS ." tor ON(t.topic_id = tor.topic_id)
+ WHERE t.topic_poster = $user_id
+ ORDER BY t.topic_last_post_time DESC
+ LIMIT 50
+ ";
+ $topics_tmp = DB()->fetch_rowset($sql);
+ $topics = array();
+ foreach ($topics_tmp as $topic)
+ {
+ if (isset($topic['topic_status']))
+ {
+ if ($topic['topic_status'] == TOPIC_MOVED) continue;
+ }
+ if (isset($topic['tor_status']))
+ {
+ if (isset($bb_cfg['tor_frozen'][$topic['tor_status']])) continue;
+ }
+ $topics[] = $topic;
+ }
+ if (!count($topics))
+ {
+ @unlink($file_path);
+ return false;
+ }
+ if (create_atom($file_path, 'u', $user_id, wbr($username), $topics)) return true;
+ else return false;
+}
+
+function create_atom ($file_path, $mode, $id, $title, $topics)
+{
+ global $bb_cfg;
+ $dir = dirname($file_path);
+ if (!file_exists($dir))
+ {
+ if (!bb_mkdir($dir)) return false;
+ }
+ foreach ($topics as $topic)
+ {
+ $last_time = $topic['topic_last_post_time'];
+ if ($topic['topic_last_post_edit_time']) $last_time = $topic['topic_last_post_edit_time'];
+ $date = bb_date($last_time, 'Y-m-d', 0);
+ $time = bb_date($last_time, 'H:i:s', 0);
+ break;
+ }
+ $atom = "";
+ $atom .= "\n";
+ $atom .= "