Gab Social. All are welcome.
This commit is contained in:
20
lib/tasks/assets.rake
Normal file
20
lib/tasks/assets.rake
Normal file
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
def render_static_page(action, dest:, **opts)
|
||||
html = ApplicationController.render(action, opts)
|
||||
File.write(dest, html)
|
||||
end
|
||||
|
||||
namespace :assets do
|
||||
desc 'Generate static pages'
|
||||
task generate_static_pages: :environment do
|
||||
render_static_page 'errors/500', layout: 'error', dest: Rails.root.join('public', 'assets', '500.html')
|
||||
end
|
||||
end
|
||||
|
||||
if Rake::Task.task_defined?('assets:precompile')
|
||||
Rake::Task['assets:precompile'].enhance do
|
||||
Webpacker.manifest.refresh
|
||||
Rake::Task['assets:generate_static_pages'].invoke
|
||||
end
|
||||
end
|
||||
45
lib/tasks/auto_annotate_models.rake
Normal file
45
lib/tasks/auto_annotate_models.rake
Normal file
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
if Rails.env.development?
|
||||
task :set_annotation_options do
|
||||
Annotate.set_defaults(
|
||||
'routes' => 'false',
|
||||
'position_in_routes' => 'before',
|
||||
'position_in_class' => 'before',
|
||||
'position_in_test' => 'before',
|
||||
'position_in_fixture' => 'before',
|
||||
'position_in_factory' => 'before',
|
||||
'position_in_serializer' => 'before',
|
||||
'show_foreign_keys' => 'false',
|
||||
'show_indexes' => 'false',
|
||||
'simple_indexes' => 'false',
|
||||
'model_dir' => 'app/models',
|
||||
'root_dir' => '',
|
||||
'include_version' => 'false',
|
||||
'require' => '',
|
||||
'exclude_tests' => 'true',
|
||||
'exclude_fixtures' => 'true',
|
||||
'exclude_factories' => 'true',
|
||||
'exclude_serializers' => 'true',
|
||||
'exclude_scaffolds' => 'true',
|
||||
'exclude_controllers' => 'true',
|
||||
'exclude_helpers' => 'true',
|
||||
'ignore_model_sub_dir' => 'false',
|
||||
'ignore_columns' => nil,
|
||||
'ignore_routes' => nil,
|
||||
'ignore_unknown_models' => 'false',
|
||||
'hide_limit_column_types' => 'integer,boolean',
|
||||
'skip_on_db_migrate' => 'false',
|
||||
'format_bare' => 'true',
|
||||
'format_rdoc' => 'false',
|
||||
'format_markdown' => 'false',
|
||||
'sort' => 'false',
|
||||
'force' => 'false',
|
||||
'trace' => 'false',
|
||||
'wrapper_open' => nil,
|
||||
'wrapper_close' => nil
|
||||
)
|
||||
end
|
||||
|
||||
Annotate.load_tasks
|
||||
end
|
||||
75
lib/tasks/db.rake
Normal file
75
lib/tasks/db.rake
Normal file
@@ -0,0 +1,75 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../gabsocial/snowflake'
|
||||
|
||||
def each_schema_load_environment
|
||||
# If we're in development, also run this for the test environment.
|
||||
# This is a somewhat hacky way to do this, so here's why:
|
||||
# 1. We have to define this before we load the schema, or we won't
|
||||
# have a timestamp_id function when we get to it in the schema.
|
||||
# 2. db:setup calls db:schema:load_if_ruby, which calls
|
||||
# db:schema:load, which we define above as having a prerequisite
|
||||
# of this task.
|
||||
# 3. db:schema:load ends up running
|
||||
# ActiveRecord::Tasks::DatabaseTasks.load_schema_current, which
|
||||
# calls a private method `each_current_configuration`, which
|
||||
# explicitly also does the loading for the `test` environment
|
||||
# if the current environment is `development`, so we end up
|
||||
# needing to do the same, and we can't even use the same method
|
||||
# to do it.
|
||||
|
||||
if Rails.env.development?
|
||||
test_conf = ActiveRecord::Base.configurations['test']
|
||||
|
||||
if test_conf['database']&.present?
|
||||
ActiveRecord::Base.establish_connection(:test)
|
||||
yield
|
||||
ActiveRecord::Base.establish_connection(Rails.env.to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
yield
|
||||
end
|
||||
|
||||
namespace :db do
|
||||
namespace :migrate do
|
||||
desc 'Setup the db or migrate depending on state of db'
|
||||
task setup: :environment do
|
||||
begin
|
||||
if ActiveRecord::Migrator.current_version.zero?
|
||||
Rake::Task['db:migrate'].invoke
|
||||
Rake::Task['db:seed'].invoke
|
||||
end
|
||||
rescue ActiveRecord::NoDatabaseError
|
||||
Rake::Task['db:setup'].invoke
|
||||
else
|
||||
Rake::Task['db:migrate'].invoke
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Before we load the schema, define the timestamp_id function.
|
||||
# Idiomatically, we might do this in a migration, but then it
|
||||
# wouldn't end up in schema.rb, so we'd need to figure out a way to
|
||||
# get it in before doing db:setup as well. This is simpler, and
|
||||
# ensures it's always in place.
|
||||
Rake::Task['db:schema:load'].enhance ['db:define_timestamp_id']
|
||||
|
||||
# After we load the schema, make sure we have sequences for each
|
||||
# table using timestamp IDs.
|
||||
Rake::Task['db:schema:load'].enhance do
|
||||
Rake::Task['db:ensure_id_sequences_exist'].invoke
|
||||
end
|
||||
|
||||
task :define_timestamp_id do
|
||||
each_schema_load_environment do
|
||||
GabSocial::Snowflake.define_timestamp_id
|
||||
end
|
||||
end
|
||||
|
||||
task :ensure_id_sequences_exist do
|
||||
each_schema_load_environment do
|
||||
GabSocial::Snowflake.ensure_id_sequences_exist
|
||||
end
|
||||
end
|
||||
end
|
||||
58
lib/tasks/emojis.rake
Normal file
58
lib/tasks/emojis.rake
Normal file
@@ -0,0 +1,58 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
def codepoints_to_filename(codepoints)
|
||||
codepoints.downcase.gsub(/\A[0]+/, '').tr(' ', '-')
|
||||
end
|
||||
|
||||
def codepoints_to_unicode(codepoints)
|
||||
if codepoints.include?(' ')
|
||||
codepoints.split(' ').map(&:hex).pack('U*')
|
||||
else
|
||||
[codepoints.hex].pack('U')
|
||||
end
|
||||
end
|
||||
|
||||
namespace :emojis do
|
||||
desc 'Generate a unicode to filename mapping'
|
||||
task :generate do
|
||||
source = 'http://www.unicode.org/Public/emoji/11.0/emoji-test.txt'
|
||||
codes = []
|
||||
dest = Rails.root.join('app', 'javascript', 'gabsocial', 'features', 'emoji', 'emoji_map.json')
|
||||
|
||||
puts "Downloading emojos from source... (#{source})"
|
||||
|
||||
HTTP.get(source).to_s.split("\n").each do |line|
|
||||
next if line.start_with? '#'
|
||||
parts = line.split(';').map(&:strip)
|
||||
next if parts.size < 2
|
||||
codes << [parts[0], parts[1].start_with?('fully-qualified')]
|
||||
end
|
||||
|
||||
grouped_codes = codes.reduce([]) do |agg, current|
|
||||
if current[1]
|
||||
agg << [current[0]]
|
||||
else
|
||||
agg.last << current[0]
|
||||
agg
|
||||
end
|
||||
end
|
||||
|
||||
existence_maps = grouped_codes.map { |c| c.map { |cc| [cc, File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg'))] }.to_h }
|
||||
map = {}
|
||||
|
||||
existence_maps.each do |group|
|
||||
existing_one = group.key(true)
|
||||
|
||||
next if existing_one.nil?
|
||||
|
||||
group.each_key do |key|
|
||||
map[codepoints_to_unicode(key)] = codepoints_to_filename(existing_one)
|
||||
end
|
||||
end
|
||||
|
||||
map = map.sort { |a, b| a[0].size <=> b[0].size }.to_h
|
||||
|
||||
File.write(dest, Oj.dump(map))
|
||||
puts "Wrote emojo to destination! (#{dest})"
|
||||
end
|
||||
end
|
||||
408
lib/tasks/gabsocial.rake
Normal file
408
lib/tasks/gabsocial.rake
Normal file
@@ -0,0 +1,408 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'tty-command'
|
||||
require 'tty-prompt'
|
||||
|
||||
namespace :gabsocial do
|
||||
desc 'Configure the instance for production use'
|
||||
task :setup do
|
||||
prompt = TTY::Prompt.new
|
||||
env = {}
|
||||
|
||||
begin
|
||||
prompt.say('Your instance is identified by its domain name. Changing it afterward will break things.')
|
||||
env['LOCAL_DOMAIN'] = prompt.ask('Domain name:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
q.validate(/\A[a-z0-9\.\-]+\z/i)
|
||||
q.messages[:valid?] = 'Invalid domain. If you intend to use unicode characters, enter punycode here'
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
prompt.say('Single user mode disables registrations and redirects the landing page to your public profile.')
|
||||
env['SINGLE_USER_MODE'] = prompt.yes?('Do you want to enable single user mode?', default: false)
|
||||
|
||||
%w(SECRET_KEY_BASE OTP_SECRET).each do |key|
|
||||
env[key] = SecureRandom.hex(64)
|
||||
end
|
||||
|
||||
vapid_key = Webpush.generate_key
|
||||
|
||||
env['VAPID_PRIVATE_KEY'] = vapid_key.private_key
|
||||
env['VAPID_PUBLIC_KEY'] = vapid_key.public_key
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
using_docker = prompt.yes?('Are you using Docker to run Gab Social?')
|
||||
db_connection_works = false
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
loop do
|
||||
env['DB_HOST'] = prompt.ask('PostgreSQL host:') do |q|
|
||||
q.required true
|
||||
q.default using_docker ? 'db' : '/var/run/postgresql'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['DB_PORT'] = prompt.ask('PostgreSQL port:') do |q|
|
||||
q.required true
|
||||
q.default 5432
|
||||
q.convert :int
|
||||
end
|
||||
|
||||
env['DB_NAME'] = prompt.ask('Name of PostgreSQL database:') do |q|
|
||||
q.required true
|
||||
q.default using_docker ? 'postgres' : 'gabsocial_production'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['DB_USER'] = prompt.ask('Name of PostgreSQL user:') do |q|
|
||||
q.required true
|
||||
q.default using_docker ? 'postgres' : 'gabsocial'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['DB_PASS'] = prompt.ask('Password of PostgreSQL user:') do |q|
|
||||
q.echo false
|
||||
end
|
||||
|
||||
# The chosen database may not exist yet. Connect to default database
|
||||
# to avoid "database does not exist" error.
|
||||
db_options = {
|
||||
adapter: :postgresql,
|
||||
database: 'postgres',
|
||||
host: env['DB_HOST'],
|
||||
port: env['DB_PORT'],
|
||||
user: env['DB_USER'],
|
||||
password: env['DB_PASS'],
|
||||
}
|
||||
|
||||
begin
|
||||
ActiveRecord::Base.establish_connection(db_options)
|
||||
ActiveRecord::Base.connection
|
||||
prompt.ok 'Database configuration works! 🎆'
|
||||
db_connection_works = true
|
||||
break
|
||||
rescue StandardError => e
|
||||
prompt.error 'Database connection could not be established with this configuration, try again.'
|
||||
prompt.error e.message
|
||||
break unless prompt.yes?('Try again?')
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
loop do
|
||||
env['REDIS_HOST'] = prompt.ask('Redis host:') do |q|
|
||||
q.required true
|
||||
q.default using_docker ? 'redis' : 'localhost'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['REDIS_PORT'] = prompt.ask('Redis port:') do |q|
|
||||
q.required true
|
||||
q.default 6379
|
||||
q.convert :int
|
||||
end
|
||||
|
||||
env['REDIS_PASSWORD'] = prompt.ask('Redis password:') do |q|
|
||||
q.required false
|
||||
q.default nil
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
redis_options = {
|
||||
host: env['REDIS_HOST'],
|
||||
port: env['REDIS_PORT'],
|
||||
password: env['REDIS_PASSWORD'],
|
||||
driver: :hiredis,
|
||||
}
|
||||
|
||||
begin
|
||||
redis = Redis.new(redis_options)
|
||||
redis.ping
|
||||
prompt.ok 'Redis configuration works! 🎆'
|
||||
break
|
||||
rescue StandardError => e
|
||||
prompt.error 'Redis connection could not be established with this configuration, try again.'
|
||||
prompt.error e.message
|
||||
break unless prompt.yes?('Try again?')
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
if prompt.yes?('Do you want to store uploaded files on the cloud?', default: false)
|
||||
case prompt.select('Provider', ['Amazon S3', 'Wasabi', 'Minio'])
|
||||
when 'Amazon S3'
|
||||
env['S3_ENABLED'] = 'true'
|
||||
env['S3_PROTOCOL'] = 'https'
|
||||
|
||||
env['S3_BUCKET'] = prompt.ask('S3 bucket name:') do |q|
|
||||
q.required true
|
||||
q.default "files.#{env['LOCAL_DOMAIN']}"
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['S3_REGION'] = prompt.ask('S3 region:') do |q|
|
||||
q.required true
|
||||
q.default 'us-east-1'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['S3_HOSTNAME'] = prompt.ask('S3 hostname:') do |q|
|
||||
q.required true
|
||||
q.default 's3-us-east-1.amazonaws.com'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_ACCESS_KEY_ID'] = prompt.ask('S3 access key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_SECRET_ACCESS_KEY'] = prompt.ask('S3 secret key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
when 'Wasabi'
|
||||
env['S3_ENABLED'] = 'true'
|
||||
env['S3_PROTOCOL'] = 'https'
|
||||
env['S3_REGION'] = 'us-east-1'
|
||||
env['S3_HOSTNAME'] = 's3.wasabisys.com'
|
||||
env['S3_ENDPOINT'] = 'https://s3.wasabisys.com/'
|
||||
|
||||
env['S3_BUCKET'] = prompt.ask('Wasabi bucket name:') do |q|
|
||||
q.required true
|
||||
q.default "files.#{env['LOCAL_DOMAIN']}"
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_ACCESS_KEY_ID'] = prompt.ask('Wasabi access key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_SECRET_ACCESS_KEY'] = prompt.ask('Wasabi secret key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
when 'Minio'
|
||||
env['S3_ENABLED'] = 'true'
|
||||
env['S3_PROTOCOL'] = 'https'
|
||||
env['S3_REGION'] = 'us-east-1'
|
||||
|
||||
env['S3_ENDPOINT'] = prompt.ask('Minio endpoint URL:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['S3_PROTOCOL'] = env['S3_ENDPOINT'].start_with?('https') ? 'https' : 'http'
|
||||
env['S3_HOSTNAME'] = env['S3_ENDPOINT'].gsub(/\Ahttps?:\/\//, '')
|
||||
|
||||
env['S3_BUCKET'] = prompt.ask('Minio bucket name:') do |q|
|
||||
q.required true
|
||||
q.default "files.#{env['LOCAL_DOMAIN']}"
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_ACCESS_KEY_ID'] = prompt.ask('Minio access key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['AWS_SECRET_ACCESS_KEY'] = prompt.ask('Minio secret key:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
end
|
||||
|
||||
if prompt.yes?('Do you want to access the uploaded files from your own domain?')
|
||||
env['S3_ALIAS_HOST'] = prompt.ask('Domain for uploaded files:') do |q|
|
||||
q.required true
|
||||
q.default "files.#{env['LOCAL_DOMAIN']}"
|
||||
q.modify :strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
|
||||
loop do
|
||||
if prompt.yes?('Do you want to send e-mails from localhost?', default: false)
|
||||
env['SMTP_SERVER'] = 'localhost'
|
||||
env['SMTP_PORT'] = 25
|
||||
env['SMTP_AUTH_METHOD'] = 'none'
|
||||
env['SMTP_OPENSSL_VERIFY_MODE'] = 'none'
|
||||
else
|
||||
env['SMTP_SERVER'] = prompt.ask('SMTP server:') do |q|
|
||||
q.required true
|
||||
q.default 'smtp.mailgun.org'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['SMTP_PORT'] = prompt.ask('SMTP port:') do |q|
|
||||
q.required true
|
||||
q.default 587
|
||||
q.convert :int
|
||||
end
|
||||
|
||||
env['SMTP_LOGIN'] = prompt.ask('SMTP username:') do |q|
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['SMTP_PASSWORD'] = prompt.ask('SMTP password:') do |q|
|
||||
q.echo false
|
||||
end
|
||||
|
||||
env['SMTP_AUTH_METHOD'] = prompt.ask('SMTP authentication:') do |q|
|
||||
q.required
|
||||
q.default 'plain'
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
env['SMTP_OPENSSL_VERIFY_MODE'] = prompt.select('SMTP OpenSSL verify mode:', %w(none peer client_once fail_if_no_peer_cert))
|
||||
end
|
||||
|
||||
env['SMTP_FROM_ADDRESS'] = prompt.ask('E-mail address to send e-mails "from":') do |q|
|
||||
q.required true
|
||||
q.default "Gab Social <noreply@#{env['LOCAL_DOMAIN']}>"
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
break unless prompt.yes?('Send a test e-mail with this configuration right now?')
|
||||
|
||||
send_to = prompt.ask('Send test e-mail to:', required: true)
|
||||
|
||||
begin
|
||||
ActionMailer::Base.smtp_settings = {
|
||||
port: env['SMTP_PORT'],
|
||||
address: env['SMTP_SERVER'],
|
||||
user_name: env['SMTP_LOGIN'].presence,
|
||||
password: env['SMTP_PASSWORD'].presence,
|
||||
domain: env['LOCAL_DOMAIN'],
|
||||
authentication: env['SMTP_AUTH_METHOD'] == 'none' ? nil : env['SMTP_AUTH_METHOD'] || :plain,
|
||||
openssl_verify_mode: env['SMTP_OPENSSL_VERIFY_MODE'],
|
||||
enable_starttls_auto: true,
|
||||
}
|
||||
|
||||
ActionMailer::Base.default_options = {
|
||||
from: env['SMTP_FROM_ADDRESS'],
|
||||
}
|
||||
|
||||
mail = ActionMailer::Base.new.mail to: send_to, subject: 'Test', body: 'Gab Social SMTP configuration works!'
|
||||
mail.deliver
|
||||
break
|
||||
rescue StandardError => e
|
||||
prompt.error 'E-mail could not be sent with this configuration, try again.'
|
||||
prompt.error e.message
|
||||
break unless prompt.yes?('Try again?')
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
prompt.say 'This configuration will be written to .env.production'
|
||||
|
||||
if prompt.yes?('Save configuration?')
|
||||
cmd = TTY::Command.new(printer: :quiet)
|
||||
|
||||
File.write(Rails.root.join('.env.production'), "# Generated with gabsocial:setup on #{Time.now.utc}\n\n" + env.each_pair.map { |key, value| "#{key}=#{value}" }.join("\n") + "\n")
|
||||
|
||||
if using_docker
|
||||
prompt.ok 'Below is your configuration, save it to an .env.production file outside Docker:'
|
||||
prompt.say "\n"
|
||||
prompt.say File.read(Rails.root.join('.env.production'))
|
||||
prompt.say "\n"
|
||||
prompt.ok 'It is also saved within this container so you can proceed with this wizard.'
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
prompt.say 'Now that configuration is saved, the database schema must be loaded.'
|
||||
prompt.warn 'If the database already exists, this will erase its contents.'
|
||||
|
||||
if prompt.yes?('Prepare the database now?')
|
||||
prompt.say 'Running `RAILS_ENV=production rails db:setup` ...'
|
||||
prompt.say "\n\n"
|
||||
|
||||
if cmd.run!({ RAILS_ENV: 'production', SAFETY_ASSURED: 1 }, :rails, 'db:setup').failure?
|
||||
prompt.error 'That failed! Perhaps your configuration is not right'
|
||||
else
|
||||
prompt.ok 'Done!'
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
prompt.say 'The final step is compiling CSS/JS assets.'
|
||||
prompt.say 'This may take a while and consume a lot of RAM.'
|
||||
|
||||
if prompt.yes?('Compile the assets now?')
|
||||
prompt.say 'Running `RAILS_ENV=production rails assets:precompile` ...'
|
||||
prompt.say "\n\n"
|
||||
|
||||
if cmd.run!({ RAILS_ENV: 'production' }, :rails, 'assets:precompile').failure?
|
||||
prompt.error 'That failed! Maybe you need swap space?'
|
||||
else
|
||||
prompt.say 'Done!'
|
||||
end
|
||||
end
|
||||
|
||||
prompt.say "\n"
|
||||
prompt.ok 'All done! You can now power on the Gab Social server.'
|
||||
prompt.say "\n"
|
||||
|
||||
if db_connection_works && prompt.yes?('Do you want to create an admin user straight away?')
|
||||
env.each_pair do |key, value|
|
||||
ENV[key] = value.to_s
|
||||
end
|
||||
|
||||
require_relative '../../config/environment'
|
||||
disable_log_stdout!
|
||||
|
||||
username = prompt.ask('Username:') do |q|
|
||||
q.required true
|
||||
q.default 'admin'
|
||||
q.validate(/\A[a-z0-9_]+\z/i)
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
email = prompt.ask('E-mail:') do |q|
|
||||
q.required true
|
||||
q.modify :strip
|
||||
end
|
||||
|
||||
password = SecureRandom.hex(16)
|
||||
|
||||
user = User.new(admin: true, email: email, password: password, confirmed_at: Time.now.utc, account_attributes: { username: username })
|
||||
user.save(validate: false)
|
||||
|
||||
prompt.ok "You can login with the password: #{password}"
|
||||
prompt.warn 'You can change your password once you login.'
|
||||
end
|
||||
else
|
||||
prompt.warn 'Nothing saved. Bye!'
|
||||
end
|
||||
rescue TTY::Reader::InputInterrupt
|
||||
prompt.ok 'Aborting. Bye!'
|
||||
end
|
||||
end
|
||||
|
||||
namespace :webpush do
|
||||
desc 'Generate VAPID key'
|
||||
task generate_vapid_key: :environment do
|
||||
vapid_key = Webpush.generate_key
|
||||
puts "VAPID_PRIVATE_KEY=#{vapid_key.private_key}"
|
||||
puts "VAPID_PUBLIC_KEY=#{vapid_key.public_key}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def disable_log_stdout!
|
||||
dev_null = Logger.new('/dev/null')
|
||||
|
||||
Rails.logger = dev_null
|
||||
ActiveRecord::Base.logger = dev_null
|
||||
HttpLog.configuration.logger = dev_null
|
||||
Paperclip.options[:log] = false
|
||||
end
|
||||
57
lib/tasks/repo.rake
Normal file
57
lib/tasks/repo.rake
Normal file
@@ -0,0 +1,57 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :repo do
|
||||
desc 'Generate the AUTHORS.md file'
|
||||
task :authors do
|
||||
# Gab AI, Inc., does not disclose information about contributors to the Gab
|
||||
# Social project in this way. Please refer to our public git repository or
|
||||
# contact us directly at legal@gab.com with any questions about the
|
||||
# contributors to Gab Social.
|
||||
end
|
||||
|
||||
desc 'Replace pull requests with authors in the CHANGELOG.md file'
|
||||
task :changelog do
|
||||
path = Rails.root.join('CHANGELOG.md')
|
||||
tmp = Tempfile.new
|
||||
|
||||
HttpLog.config.compact_log = true
|
||||
|
||||
begin
|
||||
File.open(path, 'r') do |file|
|
||||
file.each_line do |line|
|
||||
if line.start_with?('-')
|
||||
new_line = line.gsub(/#([[:digit:]]+)*/) do |pull_request_reference|
|
||||
pull_request_number = pull_request_reference[1..-1]
|
||||
response = nil
|
||||
|
||||
loop do
|
||||
response = HTTP.headers('Authorization' => "token #{ENV['GITHUB_API_TOKEN']}").get("https://api.github.com/repos/gab-ai-inc/gab-social/pulls/#{pull_request_number}")
|
||||
|
||||
if response.code == 403
|
||||
sleep_for = (response.headers['X-RateLimit-Reset'].to_i - Time.now.to_i).abs
|
||||
puts "Sleeping for #{sleep_for} seconds to get over rate limit"
|
||||
sleep sleep_for
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
pull_request = Oj.load(response.to_s)
|
||||
"[#{pull_request['user']['login']}](#{pull_request['html_url']})"
|
||||
end
|
||||
|
||||
tmp.puts new_line
|
||||
else
|
||||
tmp.puts line
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tmp.close
|
||||
FileUtils.mv(tmp.path, path)
|
||||
ensure
|
||||
tmp.close
|
||||
tmp.unlink
|
||||
end
|
||||
end
|
||||
end
|
||||
19
lib/tasks/statistics.rake
Normal file
19
lib/tasks/statistics.rake
Normal file
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
task stats: 'gabsocial:stats'
|
||||
|
||||
namespace :gabsocial do
|
||||
desc 'Report code statistics (KLOCs, etc)'
|
||||
task :stats do
|
||||
require 'rails/code_statistics'
|
||||
[
|
||||
%w(App\ Libraries app/lib),
|
||||
%w(Presenters app/presenters),
|
||||
%w(Services app/services),
|
||||
%w(Validators app/validators),
|
||||
%w(Workers app/workers),
|
||||
].each do |name, dir|
|
||||
::STATS_DIRECTORIES << [name, Rails.root.join(dir)]
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user