批量管理操作

以下是可以从命令行启动的批量操作集合。您需要 SSH 访问权限,因此如果您是托管客户,请联系 Discourse 团队以运行这些命令。

:warning: 在操作控制台之前,极其重要的是您必须拥有最近的备份。错误随时可能发生!

首先要做的是进入您站点的容器:

cd /var/discourse
./launcher enter app

附加指南:

更改主题状态


在运行以下命令之前,请先运行 rails c 进入控制台。

  • 取消列出某个类别下的所有主题(不包括帖子操作)

    您可以将 visible 替换为 closedarchived,并根据需要调整 true/false 值

    cat_id = Category.find_by_slug('admins').id
    Topic.where(category_id: cat_id, visible: true).update_all(visible: false)
    
  • 取消列出某个类别下的所有主题(包括帖子操作)

    cat_id = Category.find_by_slug("admins").id
    Topic.where(category_id: cat_id, visible: true).find_each do |topic| 
      topic.update_status('visible', false, Discourse.system_user)
    end
    
  • 关闭指定日期之前创建的所有主题(包括帖子操作)

    Topic.where(closed: false).where("created_at < '2015-01-01'").find_each do |topic| 
      topic.update_status('closed', true, Discourse.system_user)
    end
    

移动主题


将一组主题从一个类别移动到另一个类别

rails c
topic_ids = [12,16,29]
cat_to = Category.find_by_slug('faq')
Topic.where(id: topic_ids).update_all(category_id: cat_to.id)
Category.update_stats

用户

删除部分用户


删除从未发帖且自指定日期以来未访问过的用户

rails c
User.joins(:user_stat).where("user_stats.post_count = 0 AND previous_visit_at <= '2016-05-20'::timestamp").destroy_all

根据条件暂停一组用户


设置谁将被记录为暂停用户

rails c
logger = StaffActionLogger.new(User.find_by(username_lower: "tshenry"))

创建暂停时间段和原因

suspend_till = DateTime.new(2057,12,31)
reason = 'Completed Course'

在此示例中,我们的用户条件将是组成员资格。

target_group = Group.find_by_name("summer_students")
users = User.joins(:group_users).where(group_users: {group_id: target_group.id})

根据上述设定的值暂停每个用户:

users.find_each do |u|
  u.suspended_till = suspend_till
  u.suspended_at = DateTime.now
  u.save!

  logger.log_user_suspend(u,reason)
  putc '.'
end

更新用户暂停原因


也许您暂停了完成课程的用户(参见上方示例 above),现在您想添加课程年份,因为您已经教授了多年。

UserHistory.where(action: 10, details: "Completed Course").update_all(details: "Completed 2018 Course")

取消暂停用户


如果您需要批量取消暂停用户,例如因为他们属于前一年的 cohort 并将在今年回归,您可以按如下方式操作。在示例中,我们通过用户 ID 查找用户。

user_list = [1, 3, 5, 7, 11]
users = User.where("id in (?)", user_list)

users.each do |user|
    user.suspended_till = nil
    user.suspended_at = nil
    user.save!
    StaffActionLogger.new(User.find(-1)).log_user_unsuspend(user)

    DiscourseEvent.trigger(:user_unsuspended, user: user)
end

导出/导入

导出/导入所有站点设置


要简单地打印出您站点上所有已更改的设置,请运行:

rake site_settings:export

如果您想将设置导出到文件:

rake site_settings:export > saved_settings.yml

如果您想从文件导入设置:

rake site_settings:import < saved_settings.yml

导出/导入类别


导出有两种选项,导入有一种方法。

导出一组完整的类别

首先获取您的类别 ID 列表:

rake categories:list

然后在导出 rake 任务中用空格分隔类别 ID。例如:

rake export:categories["12 6"]

导出您站点的类别结构

这基本上是您 Discourse 站点的“骨架”副本。它包括每个类别以及任何与现有类别权限关联的组。它不包括主题

rake export:category_structure

如果您需要类别结构以及任何与类别权限关联的组这些组的任何成员:

rake export:category_structure[true]

导入类别文件

使用导出文件的名称,如下例所示:

rake import:file["category-export-2019-05-16-052430.json"]

导出/导入组


导出所有用户组

rake export:groups

导出所有用户组(包括用户)

rake export:groups[true]

导入组文件
使用导出文件的名称,如下例所示:

rake import:file["group-export-2019-05-16-052430.json"]

为多个类别设置权限


:warning: 请注意,这将删除您为相关类别设置的任何现有访问限制。请确保包含所有相关权限。

  1. 获取类别及其 ID 的列表

    rails c
    Category.all.pluck("name", "id")
    
  2. 创建一个包含您要操作的类别 ID 的数组。

    category_ids = [6,7,8,10]
    
  3. 更改权限。set_permissions 函数可以使用以下参数::full:create_post:readonly

    • 单个权限。例如,将一组类别设置为仅限员工:

      Category.where(id: category_ids).find_each do |category| 
       category.set_permissions(:staff => :full)
       category.save!
      end
      
    • 多个权限。例如,将一组类别设置为对普通用户只读:

      Category.where(id: category_ids).find_each do |category| 
        category.set_permissions(:everyone => :readonly, :staff => :full)
        category.save!
      end
      
    • 用户组权限。例如,为一组类别中的一个组授予完全权限,另一个组授予只读权限:

      artists_group = Group.find_by_name("artists")
      buyers_group = Group.find_by_name("buyers")
      Category.where(id: category_ids).find_each do |category| 
        category.set_permissions(artists_group.id => :full, buyers_group.id => :readonly)
        category.save!
      end
      

基于关键词批量标记所有主题

以下脚本允许您根据主题标题或其帖子中是否存在关键词来标记主题。首先创建一个关键词数组:

rails c
keywords = ['apples','oranges']

接下来我们需要定义一个方法:

def tag_by_keyword(word, tag_name)
  tag = Tag.find_by_name(tag_name) || Tag.create(name: tag_name)
  keyword_topics = Topic.joins(:posts).where("topics.title ~* :keyword or posts.raw ~* :keyword", keyword: "\\y#{word}\\y").distinct

  keyword_topics.each do |topic|
    if topic.tags.exclude?(tag)
      topic.tags << tag
    end
  end
end

最后将每个关键词通过该方法运行。以下示例将每个相关主题标记为“fruit”:

keywords.each { |word| tag_by_keyword(word, 'fruit') }

批量标记某个类别下的所有主题


模板:rake tags:bulk_tag_category["<tag>|<tag>",<category_id>]
这在尝试将类别转换为标签时特别有用。

首先,使用以下 rake 任务查找相关类别 ID。

rake categories:list

标记您指定的类别下的所有主题。在此示例中,您将为 ID 为 6 的类别下的所有主题添加“support”标签。:warning: 这将从每个主题中移除所有其他标签。

rake tags:bulk_tag_category["support",6]

追加您指定的类别下的所有主题。在此示例中,您将为 ID 为 6 的类别下的所有主题添加“support”标签,同时保留现有标签。

rake tags:bulk_tag_category["support",6,true]

将带有特定标签的所有主题移动到单个类别

在尝试重构您的 Discourse 站点时,您可能会发现希望移动一组主题而不触发任何通知。一种方法是创建一个临时标签,将其应用到相关主题,使用以下代码将主题移动到特定类别,最后删除临时标签。

获取标签。

rails c
tag = Tag.find_by_name("tutorial")

获取目标类别。

  • 对于常规类别:
cat_to = Category.find_by_slug('guides')
  • 对于子类别:
cat_to = Category.find_by_slug('child-slug','parent-slug')

将带标签的主题移动到目标类别。

Topic.joins(:topic_tags).where("topic_tags.tag_id = ?", tag.id).update_all(category_id: cat_to.id)

更新受影响类别的主题计数。

Category.update_stats
CategoryTagStat.update_topic_counts

将一个类别中的所有主题移动到另一个类别


使用以下 rake 任务查找类别 ID:

rake categories:list

第一个值应为起始类别 ID。第二个值应为目标类别 ID。

rake categories:move_topics[15,6]
Rails 控制台脚本
cat_from_id = XX # 要移出主题的类别 ID
cat_to_id = XX  # 要移入主题的类别 ID
Topic.where(category_id: cat_from_id).update_all(category_id: cat_to_id)
Category.update_stats
CategoryTagStat.update_topic_counts

更改类别中所有主题的拥有者


使用以下 rake 任务查找类别 ID:

rake categories:list

指定新拥有者和要操作的类别。类别应为类别 ID 数组,示例中的类别 123

rails c
user = User.find_by(username_lower: "lowercase-username")
categories = [1, 2, 3]

获取给定类别的所有主题 ID,并更改所有匹配主题中第一个帖子的拥有者。

topics = Topic.where(category_id: categories).pluck(:id)

topics.each do |topic|
  PostOwnerChanger.new(
    post_ids: Post.where(topic_id: topic).where(post_number: 1).pluck(:id),
    topic_id: topic,
    new_owner: user,
    acting_user: Discourse.system_user,
    skip_revision: true
  ).change_owner!
end

向所有组成员授予徽章


向属于特定组的所有用户授予徽章。第一个值是组 ID,第二个值是徽章 ID。

rails c
Group.find_by_name("event_participants").id
Badge.find_by_name("event_badge").id
exit
rake groups:grant_badge[42,102]

:warning: 请注意,上述 rake 任务仅授予徽章,如果用户不再属于指定组,它不会撤销之前授予的徽章。如果您需要批量撤销不再属于某个组的所有用户的徽章,可以运行以下命令:

rails c

badge_id = Badge.find_by_name("Some Group Member").id

group = Group.find_by_name("Some_Group")

group_user_id = group.users.pluck("id")

userBadge = UserBadge.where.not(user_id: group_user_id).where(badge_id: badge_id)

userBadge.each do |ub|
  BadgeGranter.revoke(ub, revoked_by: Discourse.system_user)
end

exit

确保所有用户处于其自动信任级别


假设您将新用户或受邀用户的默认信任级别设置为一个不太符合预期的值(例如 TL4)。现在您想更改它,使您的用户处于根据其当前统计信息自动获得的信任级别。以下命令将确保所有用户都处于其应有的信任级别,详见 https://blog.discourse.org/2018/06/understanding-discourse-trust-levels/。**注意**:具有锁定信任级别的用户不会受到影响。

确保所有用户都设置为正确的信任级别:

rails c
User.all.find_each do |user|
  Promotion.recalculate(user)
end

刷新组统计信息以反映更改:

Group.ensure_consistency!

主题维护脚本

以下 Ruby 脚本演示了如何根据活动日期和其他条件对主题执行自动化维护。这些脚本结合了 SQL 查询以识别主题,以及 Ruby 代码以对其执行操作,必须通过您站点的 Rails 控制台运行。

每个脚本都遵循类似的模式:

  1. 识别相关主题的 SQL 查询
  2. 处理每个主题并应用所需操作的 Ruby 代码
  3. 基本的错误处理和日志记录

这些脚本可以通过以下方式自定义:

  • 调整时间段(例如,‘6 MONTH’、‘1 YEAR’、‘2 YEAR’)
  • 更改类别选择以匹配您的论坛结构
  • 修改要执行的操作(关闭、取消列出或移动)
  • 添加其他条件,如帖子数量或查看阈值

关闭、取消列出并移动不活跃的主题

此脚本识别符合以下条件的主题:

  • 在特定类别中
  • 开放
  • 未解决(使用 Discourse Solved 插件)
  • 在特定时间段内无近期活动

然后执行多个操作:

  • 关闭它们,
  • 取消列出它们,
  • 将它们移动到指定类别以存放过时内容
SQL 查询
WITH topic_list AS (
    SELECT ua.target_topic_id, MAX(ua.created_at) "created_at"  
    FROM user_actions ua
    INNER JOIN topics t ON t.id = ua.target_topic_id
    INNER JOIN categories c ON c.id = t.category_id
    LEFT JOIN discourse_solved_solved_topics solved ON solved.topic_id = t.id
    WHERE t.closed = false
        AND t.category_id = [CATEGORY_ID]
        AND solved.topic_id IS NULL
        AND t.deleted_at IS NULL
    GROUP BY ua.target_topic_id
    HAVING MAX(ua.created_at) <= (CURRENT_DATE - (INTERVAL '[TIME_PERIOD]'))
    ORDER BY "created_at" DESC
)
    
SELECT '' AS total, target_topic_id AS topic_id, created_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY created_at DESC
组合 SQL + 脚本
sql = "WITH topic_list AS (
    SELECT ua.target_topic_id, MAX(ua.created_at) \"created_at\"  
    FROM user_actions ua
    INNER JOIN topics t ON t.id = ua.target_topic_id
    INNER JOIN categories c ON c.id = t.category_id
    LEFT JOIN discourse_solved_solved_topics solved ON solved.topic_id = t.id
    WHERE t.closed = false
        AND t.category_id = [CATEGORY_ID]
        AND solved.topic_id IS NULL
        AND t.deleted_at IS NULL
    GROUP BY ua.target_topic_id
    HAVING MAX(ua.created_at) <= (CURRENT_DATE - (INTERVAL '[TIME_PERIOD]'))
    ORDER BY \"created_at\" DESC
)
    
SELECT '' AS total, target_topic_id AS topic_id, created_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY created_at DESC"

results = ActiveRecord::Base.connection.execute(sql)
user = Discourse.system_user
destination_category = Category.find([DESTINATION_CATEGORY_ID])

puts "Found #{results.count} topics to process"

results.each do |row|
    begin
    topic = Topic.find(row["topic_id"])
    
    # 1. 移动到目标类别
    topic.update!(category_id: destination_category.id)
    puts "#{topic.id} moved to destination category"
    
    # 2. 关闭主题
    topic.update_status('closed', true, user, until: nil)
    puts "#{topic.id} is closed"
    
    # 3. 取消列出主题
    topic.update_status('visible', false, user, until: nil)
    puts "#{topic.id} is unlisted"

    # 错误处理
    rescue => e
      puts "Error processing topic #{row["topic_id"]}: #{e.message}"
    end
end

puts "Process completed"

关闭无近期活动的已解决主题

此脚本关闭已解决但已闲置一段时间的主题。这有助于保持论坛整洁,同时保留有价值的已解决主题。

此脚本识别符合以下条件的主题:

  • 在特定类别中
  • 开放
  • 已解决(使用 Discourse Solved 插件)
  • 在特定时间段内无近期活动
SQL 查询
WITH topic_list AS (
    SELECT ua.target_topic_id, MAX(ua.created_at) "created_at"  
    FROM user_actions ua
    INNER JOIN topics t ON t.id = ua.target_topic_id
    INNER JOIN categories c ON c.id = t.category_id
    INNER JOIN discourse_solved_solved_topics solved ON solved.topic_id = t.id
    WHERE t.closed = false
        AND t.category_id IN ([CATEGORY_IDS])
        AND t.deleted_at IS NULL
    GROUP BY ua.target_topic_id
    HAVING MAX(ua.created_at) <= (CURRENT_DATE - (INTERVAL '[TIME_PERIOD]'))
    ORDER BY "created_at" DESC
)
    
SELECT '' AS total, target_topic_id AS topic_id, created_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY created_at DESC
组合 SQL + 脚本
sql = "WITH topic_list AS (
    SELECT ua.target_topic_id, MAX(ua.created_at) \"created_at\"  
    FROM user_actions ua
    INNER JOIN topics t ON t.id = ua.target_topic_id
    INNER JOIN categories c ON c.id = t.category_id
    INNER JOIN discourse_solved_solved_topics solved ON solved.topic_id = t.id
    WHERE t.closed = false
        AND t.category_id IN ([CATEGORY_IDS])
        AND t.deleted_at IS NULL
    GROUP BY ua.target_topic_id
    HAVING MAX(ua.created_at) <= (CURRENT_DATE - (INTERVAL '[TIME_PERIOD]'))
    ORDER BY \"created_at\" DESC
)
    
SELECT '' AS total, target_topic_id AS topic_id, created_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY created_at DESC"

results = ActiveRecord::Base.connection.execute(sql)
user = Discourse.system_user

puts "Found #{results.count} topics to process"

results.each do |row|
    begin
    topic = Topic.find(row["topic_id"])
     
    # 关闭主题
    topic.update_status('closed', true, user, until: nil)
    puts "#{topic.id} is closed"

    # 错误处理
    rescue => e
      puts "Error processing topic #{row["topic_id"]}: #{e.message}"
    end
end

puts "Process completed"

归档之前已关闭的主题

此脚本识别在特定日期之前已关闭的主题,并将它们移动到归档类别,同时取消列出它们。

SQL 查询
WITH topic_list AS (
    SELECT 
        t.id AS topic_id, 
        tt.execute_at AS closed_at
    FROM topics t
    INNER JOIN categories c ON c.id = t.category_id
    LEFT JOIN topic_timers tt ON tt.topic_id = t.id AND tt.status_type IN (1, 8)
    WHERE t.closed = true
        AND t.category_id IN ([CATEGORY_IDS])
        AND t.deleted_at IS NULL
        AND tt.execute_at IS NOT NULL
        AND tt.execute_at <= (CURRENT_DATE - INTERVAL '[TIME_PERIOD]')
    ORDER BY tt.execute_at DESC
)
    
SELECT '' AS total, topic_id, closed_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY closed_at DESC
组合 SQL + 脚本
sql = "WITH topic_list AS (
    SELECT 
        t.id AS topic_id, 
        tt.execute_at AS closed_at
    FROM topics t
    INNER JOIN categories c ON c.id = t.category_id
    LEFT JOIN topic_timers tt ON tt.topic_id = t.id AND tt.status_type IN (1, 8)
    WHERE t.closed = true
        AND t.category_id IN ([CATEGORY_IDS])
        AND t.deleted_at IS NULL
        AND tt.execute_at IS NOT NULL
        AND tt.execute_at <= (CURRENT_DATE - INTERVAL '[TIME_PERIOD]')
    ORDER BY tt.execute_at DESC
)
    
SELECT '' AS total, topic_id, closed_at 
FROM topic_list
UNION
SELECT ''||COUNT(*), 0, CURRENT_DATE
FROM topic_list
ORDER BY closed_at DESC"

results = ActiveRecord::Base.connection.execute(sql)
user = Discourse.system_user
archive_category = Category.find([ARCHIVE_CATEGORY_ID])

puts "Found #{results.count} topics to process"

results.each do |row|
    begin
    topic = Topic.find(row["topic_id"])
    
    # 1. 移动到归档类别
    topic.update!(category_id: archive_category.id)
    puts "#{topic.id} moved to archive category"
    
    # 2. 取消列出主题
    topic.update_status('visible', false, user, until: nil)
    puts "#{topic.id} is unlisted"

    # 错误处理
    rescue => e
      puts "Error processing topic #{row["topic_id"]}: #{e.message}"
    end
end

puts "Process completed"

破坏性 rake 任务


删除整个类别

以下命令允许您销毁多个类别,以及属于这些类别的任何子类别和主题。

打印类别 ID 列表

rake categories:list

根据 ID 销毁一组类别

rake destroy:categories[10,11,12,18,30]

删除某个类别中的所有主题

移除所有私人消息

rake destroy:private_messages

销毁所有组

rake destroy:groups

销毁所有非管理员用户

rake destroy:users

销毁站点统计信息

rake destroy:stats

匿名化所有非员工用户

rake users:anonymize_all

永久删除一组帖子

以下 rake 任务将根据 ID 硬删除帖子列表。**如果帖子是主题中的第一个帖子,则该主题中的所有帖子都将被硬删除。**在成功运行任务之前,必须启用 can_permanently_delete 站点设置 启用

:warning: 一旦帖子被此任务删除,它将不再存在于数据库中,且无法恢复。

有两种可能的方法:

  • 选项 1 – 将逗号分隔的帖子 ID 列表作为参数传递

    rake destroy:posts[4,8,15,16,23,42]
    
  • 选项 2 – 指定一个包含逗号分隔的帖子 ID 列表的文本文件(适用于大量帖子)。

    cat post_ids.txt | rake destroy:posts
    

我尝试在此主题中包含最有用的 rake 任务,但 Discourse 还打包了许多其他任务。如果您想查看完整列表,可以使用以下命令:

所有带有描述的任务

rake --tasks

所有任务,包括没有描述的任务

rake -AT
70 个赞
Performing bulk actions as a moderator
Ruby on rails console command
Backup only Site Settings
How to move all topics of 1 category to new tag
Error Message when editing large number of topics
Delete/Remove All Tags in Bulk
How To Apply signature to every user?
How can I directly edit Discourse database from a GUI?
Bulk open closed topics
Suggest favorite YouTube tutorials for Discourse Admins and Moderators
Error Message when editing large number of topics
How to truncate bounced email log
Is there a way to grant badge to a group of user?
What makes a successful volunteer Discourse sysadmin?
How to extend time of all suspended users by one command?
Is there a bulk administrative command to aprove users?
DiscoTOC mobile view does not work with Docs
How might we better structure #howto?
Moving from sub-categories to tags?
Moving from sub-categories to tags?
Automatic Admin settings backups
How to get rid of thousands of topics that have no value?
Setting the api key via console
Bulk Action on Users
Mass-edit (or review) category parameters
How to activate and unstage accounts for imported users
Moving a group to TL3
Bulk Category Creation via CSV
Adding bulk categories
Can I/how to convert a tag to a category?
Rake post without confirmation
A few questions about batch moving or deleting topics
Restoring Deleted Messages?
Bulk Ownership Change of First Posts by Tag – Script Review and Suggestions
What makes a successful volunteer Discourse sysadmin?
Understanding and using badges
How to recalculate all trust_levels?
Adding many categories
How to Delete Active Users whose Readtime is less or not logged in since long or not visited since long?
How to Reset Site Statistics or Recalculate?
A community template emphasizing place and intent
Docker attach gives empty new line
Change notification settings for all users per topic
Why is there a category that I can't modify
How to sort topics in Latest by creation date?
"Period" in tag
Bulk move many topics from one category to another
Can I disable choosing a default homepage in users' Interface settings?
Bulk delete all topics in a category
Update all users email watchlist with a (newly created) category
How to change owner of invite links?
Trust level names in spanish
Admin guide to tags in Discourse
Assign users a random digest time?
How to change language of all users?
Requesting help demoting users with invalid email addresses
Rake import category doesn't respect parent category
Is there a non-query way to remove a bulk of users from groups?
Set up file and image uploads to S3
Hide Muted Categories
Modify trust level for all users
Create user without sending invite
Removing specific staff action logs using the console
Is it possible to make database changes using postgres rather than rake?
Applying Watched Words to existing posts
Bulk changing subcategories doesn't select all topics?
How to update and unlock all groups?
CLI Command for Deleting Category
Apply preferences settings for all normal users globally
Switch all users to TL2
How to add multiple tags up front
Creating and configuring custom user fields
How to delete EVERYTHING from my forum and just leave the users?
Back up only the settings
Bulk mark messages and posters as spam
Bulk mark messages and posters as spam
Staff category permission change
Convert all existing topics in category to wikis
Migrate a phpBB3 forum to Discourse
Manage multiple Discourse instances from one place only
Merge categories
Bulk Importing Groups Fails
Automatically replacing some tags with categories on existing forum
Mass closing topics
User monetization with group access?
A way to trigger auto-tagging across all topics for a new watched word
Convert a category to private and add users to a specific group with access
How to mass remove PMs?
RSS Polling
Mass Revoking Badges
How to turn off forum except for staff
Cannot delete tag with 2k topics
Is it possible to limit TL0 to posting in one category?
Mass close existing topics older than x?
Mass close existing topics older than x?
How to import category with category permissions?
Bulk open closed topics
Get Error Oops The software powering this discussion forum encountered an unexpected problem after upgrade
How do I back up only forum configuration information?
Question about category populating with certain tags
How extensible can I make my installation in terms of sub domains and restricting membership to them?
Automatically re-categorize topics from an imported forum by targeting keywords in titles?
How to clear all historical statistics from dashboard
Create a category that's private to one group, but open to other groups
自定义表情符号能否支持批量删除?
Unable to Bulk Suspend/Deactivate Users in Rails Console on Discourse 3.5.0.beta5-dev
How to Disable ALL User-to-User DMs/Chat without breaking Other Features?
Move Some topics to New Instance
Structure and duplication of category contents intra discourse and between discourse sites
Is there a way to convert categories into tags?
Structuring an active support community migrating from Facebook
How to delete thousands of Personal Messages?
Multilingual Plugin :globe_with_meridians:
Moving from sub-categories to tags?
How to change topic date after import
Emoji Fluff
Export/import theme components in bulk?
Need To Reopen All Topics!
How to bulk delete old whispers
Add a tag to all topics in a category
How to Create a Script to "Bulk Remove" from a Group?
How to delete all warnings?
Marking multiple account as Suspended account
How can I directly edit Discourse database from a GUI?
Are conditions to get new Trust level cumulative?
Bulk Remove Members from a Group
Can't reverse silencing a category for a group
Assigning mod status to multiple users
Preserving site settings through migration
Limit volume of forum emails via admin
Is it possible to import a Discourse backup as a category inside an alredy existing discourse isntance?
Site rearrangement scripting: What's the best venue?
Recover deleted categories

@Taylor 批量更新所有主题并使用不同的时间戳,这有什么办法吗?

假如我想让我的 discourse 实例上的所有主题都立即显示为今天创建的时间戳,该怎么做?

可能是对此查询的修改:

(假设它们在同一个类别中)

1 个赞

4 篇帖子已拆分为新主题:如何导入具有类别权限的类别?

考虑到此命令需要在 Docker 容器内运行,并且运行 ./launcher enter app 时容器内的默认 pwd 似乎是 /var/www/discourse,这里描述的命令似乎有些奇怪,原因如下:

  • site_settings 包含用于 S3 和其他 API 的秘密访问密钥,感觉不应该将这些密钥存储在 /var/www 下的文件中,因为传统上该位置用于提供给 Web 的文件。
  • 由于我们位于容器内的此默认 pwd,我预计保存在此处的文件的容器停止后会丢失?

从容器内部,我使用了命令 mount | grep ^/dev/ | grep -v /etc/ 来确定容器内的 /shared 位置似乎映射回主机系统上的 /var/discourse/shared/standalone。所以命令似乎应该是这样的?

cd /var/discourse
./launcher enter app
rake site_settings:export | grep -v key | grep -v secret > /shared/site_settings_$(date "%Y-%m-%d-%H-%M-%S").yml

这将把文件保留在主机系统上的 /var/discourse/shared/standalone/site_settings_2024-08-14-15-53-11.yml 等位置。

请注意,这里通过管道传输的额外 grep 命令将删除包含“key”或“secret”一词的任何行,以删除 API 密钥,但也会删除包含这些词语但出于非敏感原因的行。

这听起来对吗?

确实如此,但我很确定 Discourse 不会提供这些设置。你可以从任何目录运行命令,而且人们普遍认为,如果你在做这类事情,你就会明白你在做什么。

所以你只需要在运行 rake 任务之前执行以下操作:

cd /shared/
mkdir -p my-settings
cd my-settings
rake ...

当然,转储文件中包含了密钥,但很多内容已经在很多地方以明文形式存在了(例如,如果你遵循推荐的步骤,你的 S3 密钥就在 app.yml 中)。

是的。

2 个赞

哦,我不知道 rake 任务在应用程序的 pwd 之外仍然有效,这样说就说得通了,是的,谢谢。

1 个赞

这仍然让我感到惊讶!

另外,您可以在管道输出到文件时指定转储的完整路径。

根据这些说明,我可以使用

rake export:groups

来导出“群组”(Groups)集合并使用相同的格式导入新的“群组”。但是,当我按照导出的格式创建一个新的“群组”时,–trace 会报错:

ActiveRecord::RecordInvalid: Validation failed: You cannot allow membership requests for a group without any owners. (ActiveRecord::RecordInvalid)

(如果我不包含 user_ids 也会出现同样的错误。)

这是我的导入文件:

{“groups”:[{“id”:352,“name”:“NewGroup1”,“created_at”:“2026-02-18T17:56:01.807Z”,“automatic_membership_email_domains”:“”,“primary_group”:false,“title”:null,“grant_trust_level”:null,“incoming_email”:null,“bio_raw”:“This is a NewGroup.”,“allow_membership_requests”:true,“full_name”:“NewGroup1”,“default_notification_level”:3,“visibility_level”:2,“public_exit”:true,“public_admission”:false,“membership_request_template”:null,“messageable_level”:3,“mentionable_level”:3,“members_visibility_level”:2,“publish_read_state”:false,“user_ids”:[1,2]}]}

我看不出如何指定哪个用户是“所有者”(owner)。

我甚至添加了另一个 {“group_users”:[…} 记录来指定“所有者”,但仍然收到相同的错误。

这能用吗?有人成功导入过新的“群组”吗?如果是,秘诀是什么?

1 个赞

抱歉有点晚了,但这就是你的问题。如果你通过在导出前编辑群组或修改 .json 文件将该值设为 false,问题就解决了。

问题在于,开启该设置要求必须有所有者来处理请求。

迁移后,你可以按自己的需求进行修补。