Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
# help_file = "#{ArchiveConfig.HELP_DIRECTORY}/#{Locale.active.language.code}/#{help_entry}.html"
#end

unless !help_file.blank? && File.exists?("#{Rails.root}/public/#{help_file}")
unless help_file.present? && File.exist?("#{Rails.root}/public/#{help_file}")

Check warning on line 163 in app/helpers/application_helper.rb

View workflow job for this annotation

GitHub Actions / Rubocop

[rubocop] reported by reviewdog 🐶 Favor modifier `unless` usage when having a single-line body. Another good alternative is the usage of control flow `&&`/`||`. Raw Output: app/helpers/application_helper.rb:163:5: C: Style/IfUnlessModifier: Favor modifier `unless` usage when having a single-line body. Another good alternative is the usage of control flow `&&`/`||`.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't part of the issue, but I thought fixing the broken File.exists? here too would be helpful.

help_file = "#{ArchiveConfig.HELP_DIRECTORY}/#{help_entry}.html"
end

Expand Down
203 changes: 108 additions & 95 deletions lib/tasks/skin_tasks.rake
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
namespace :skins do
def masters_dir
Rails.public_path.join("stylesheets/masters/")
end

def ask(message)
print message
STDIN.gets.chomp.strip
def top_level_skins
dir = File.join(masters_dir, "top_level")
Dir["#{dir}/*/*.css"]
end

def replace_or_new(skin_content)
skin = Skin.new
if skin_content.match(/REPLACE:\s*(\d+)/)
id = $1.to_i
skin = Skin.where(:id => id).first
unless skin
puts "Couldn't find skin with id #{id} to replace"
return nil
end
end
skin
def skin_previews_path
File.join(masters_dir, "previews")
end

def parent_only_skins
dir = File.join(masters_dir, "parent_only")
Dir["#{dir}/*/*.css"]
end

def default_skin_preview_path
File.join(skin_previews_path, "default_preview.png")
end

def ask(message)
print message
$stdin.gets.chomp.strip
end

def set_parents(skin, parent_names)
Expand All @@ -31,17 +39,21 @@ namespace :skins do
puts "Empty parent name for #{skin.title}"
next
else
parent_skin = Skin.where(:title => parent_name).first
parent_skin = Skin.where(title: parent_name).first
end
unless parent_skin
puts "Couldn't find parent #{parent_name} to add, skipping"
next
end
if (parent_skin.role == "site" || parent_skin.role == "override") && skin.role != "override"
skin.role = "override"
skin.save or puts "Problem updating skin #{skin.title} to be replacement skin: #{skin.errors.full_messages.join(', ')}"
next

unless skin.save
puts "Problem updating skin #{skin.title} to be replacement skin: #{skin.errors.full_messages.join(', ')}"
next
end
end

p = skin.skin_parents.build(:parent_skin => parent_skin, :position => parent_position)
if p.save
parent_position += 1
Expand All @@ -51,99 +63,101 @@ namespace :skins do
end
end

def get_user_skins
dir = Skin.site_skins_dir + 'user_skins_to_load'
default_preview_filename = "#{dir}/previews/default_preview.png"
user_skin_files = Dir.entries(dir).select {|f| f.match(/css$/)}
skins = []
user_skin_files.each do |skin_file|
skins << File.read("#{dir}/#{skin_file}").split(/\/\*\s*END SKIN\s*\*\//)
def load_parent_only_skins(replace:)
parent_only_skins.each do |skin_file|
load_official_css(
filename: skin_file,
replace: replace,
parent_only: true
)
end
skins.flatten!
end

desc "Purge user skins parents"
task(:purge_user_skins_parents => :environment) do
get_user_skins.each do |skin_content|
skin = replace_or_new(skin_content)
if skin.new_record? && skin_content.match(/SKIN:\s*(.*)\s*\*\//)
skin = Skin.find_by_title($1.strip)
desc "Purge parents of official skins"
task(purge_official_skin_parents: :environment) do
top_level_skins.each do |skin_file|
skin_content = File.read(skin_file)

unless skin_content.match(%r{SKIN:\s*(.*)\s*\*/})
puts "No skin title found for skin #{skin_content}"
next
end
skin.skin_parents.delete_all

skin = Skin.find_by(title: Regexp.last_match(1).strip)
skin&.skin_parents&.delete_all
end
end

desc "Load user skins"
task(:load_user_skins => :environment) do
desc "Load official skins"
task(load_official_skins: :environment) do
replace = ask("Replace existing skins with same titles? (y/n) ") == "y"
Rake::Task['skins:purge_user_skins_parents'].invoke if replace

author = User.find_by_login("lim")
dir = Skin.site_skins_dir + 'user_skins_to_load'

skins = get_user_skins
skins.each do |skin_content|
next if skin_content.blank?

# Determine if we're replacing or creating new
next unless (skin = replace_or_new(skin_content))

# set the title and preview
if skin_content.match(/SKIN:\s*(.*)\s*\*\//)
title = $1.strip
if (oldskin = Skin.find_by_title(title)) && oldskin.id != skin.id
if replace
skin = oldskin
else
puts "Existing skin with title #{title} - did you mean to replace? Skipping."
next
end
end
skin.title = title
preview_filename = "#{dir}/previews/#{title.gsub(/[^\w\s]+/, '')}.png"
unless File.exists?(preview_filename)
puts "No preview filename #{preview_filename} found for #{title}"
preview_filename = "#{dir}/previews/default_preview.png"
end
File.open(preview_filename, 'rb') {|preview_file| skin.icon = preview_file}
else
puts "No skin title found for skin #{skin_content}"
next
end

# set the css and make public
skin.css = skin_content
skin.public = true
skin.official = true
skin.author = author unless skin.author
Rake::Task["skins:purge_official_skin_parents"].invoke if replace
load_parent_only_skins(replace: replace)

if skin_content.match(/DESCRIPTION:\s*(.*?)\*\//m)
skin.description = "<pre>#{$1}</pre>"
end
if skin_content.match(/PARENT_ONLY/)
skin.unusable = true
end
top_level_skins.each do |skin_file|
load_official_css(
filename: skin_file,
replace: replace,
preview_path: File.join(File.dirname(skin_file), "preview.png")
)
end

# make sure we have valid skin now
if skin.save
puts "Saved skin #{skin.title}"
else
puts "Problem with skin #{skin.title}: #{skin.errors.full_messages.join(', ')}"
next
end
# Create Basic Formatting as an official work skin
WorkSkin.basic_formatting
end

# recache any cached skins
if skin.cached?
skin.cache!
end
def load_official_css(filename:, replace: false, parent_only: false, preview_path: default_skin_preview_path)
skin_content = File.read(filename)
return if skin_content.blank?

unless skin_content.match(%r{SKIN:\s*(.*)\s*\*/})
puts "No skin title found for skin #{skin_content}"
return
end
title = Regexp.last_match(1).strip

# set parents
if skin_content.match(/PARENTS:\s*(.*)\s*\*\//)
parent_string = $1
skin = Skin.find_by(title: title)
if skin && !replace
puts "Existing skin with title #{title} - did you mean to replace? Skipping."
return
end
skin ||= Skin.new

unless File.exist?(preview_path)
puts "No preview filename #{preview_path} found for #{title}"
preview_path = default_skin_preview_path
end

case skin_content
when /MEDIA: (.*?) ENDMEDIA/
skin.media = Regexp.last_match(1).split(/,\s?/)
when /MEDIA: (\w+)/
skin.media = [Regexp.last_match(1)]
end

skin.title ||= title
skin.author ||= User.find_by(login: "lim")
skin.description = "<pre>#{Regexp.last_match(1)}</pre>" if skin_content.match(%r{DESCRIPTION:\s*(.*?)\*/}m)
skin.filename = filename
skin.css = nil # get_css should load from filename
skin.public = true
skin.role = "user"
skin.unusable = parent_only
skin.official = true
skin.in_chooser = true unless parent_only
skin.icon.attach(io: File.open(preview_path, "rb"), content_type: "image/png", filename: "preview.png")
if skin.save
puts "Saved skin #{skin.title}"

skin.cache! if skin.cached?
if skin_content.match(%r{PARENTS:\s*(.*)\s*\*/})
parent_string = Regexp.last_match(1)
set_parents(skin, parent_string)
end
else
puts "Problem with skin #{skin.title}: #{skin.errors.full_messages.join(', ')}"
end

end

desc "Load site skins"
Expand Down Expand Up @@ -189,5 +203,4 @@ namespace :skins do
default_id = AdminSetting.default_skin_id
Skin.where("id != ?", default_id).update_all(:official => false)
end

end
54 changes: 54 additions & 0 deletions public/stylesheets/masters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Guide

This folder contains CSS files for user skins that are loaded into the development database using the provided rake tasks. The skins can be organized into two categories:
- **Top-Level Skins**: Located in the `top_level/` subdirectory. Skins that are added to the skin chooser and subsequently cached.
- Preview images for skins should be placed in the `previews/` subdirectory. If no preview is provided, the default preview image will be used.
- **Parent-Only Skins**: Located in the `parent_only/` subdirectory. Skins that are used as parent components for top-level skins.

## Rake tasks

### Load user skins
```bash
rake skins:load_official_skins
```
This task will:
- Prompt you whether to replace existing skins (`y/n`).
- Load top-level skins from the main directory and adds them to the skin chooser.
- Load parent-only skins from the `parent_only/` directory.

### Cache skins in skin chooser
```bash
rake skins:cache_chooser_skins
```
This task caches all skins marked as `in_chooser` and the default skin.

## Syntax for skin files

Each CSS file represents a single skin. The title of the skin should be specified at the top of the file:
```css
/* SKIN: My Awesome Skin */
```

### Parent Relationships
Skins can specify parent relationships using the `/* PARENTS: */` comment. Parents can be listed by title or by ID for default site skin components:

```css
/* PARENTS: Dark Mode - Midsize, Dark Mode - Screen */
```
or
```css
/* PARENTS: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 */
```

### Additional Metadata
Skins can include optional metadata:
- **Description**: Add a description using the `/* DESCRIPTION: */` comment.
- **Media Queries**: Specify media queries using the `/* MEDIA: ... */` or `/* MEDIA: ... ENDMEDIA */`comment.

Example:
```css
/* SKIN: Lorem Ipsum */
/* DESCRIPTION: This skin serves an important purpose. */
/* PARENTS: Snow */
/* MEDIA: only screen and (max-width: 62em) ENDMEDIA */
```
1 change: 1 addition & 0 deletions public/stylesheets/masters/parent_only/dark_mode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This directory contains the parents of the Dark Mode skin. Please refer to [`public/stylesheets/masters/top_level/dark_mode/README.md`](https://github.com/otwcode/otwarchive/tree/master/public/stylesheets/masters/top_level/dark_mode/README.md) for a full overview.
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* SKIN: Dark Mode - Midsize */
/* MEDIA: only screen and (max-width: 62em) ENDMEDIA */

/* 25-MEDIA-MIDSIZE, 24-MEDIA-NARROW */

#header .user .open a:focus {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* SKIN: Dark Mode - Screen */
/* MEDIA: screen */

/* 01-CORE, 02-ELEMENTS: Very basics */

body,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* SKIN: Snow */
/* MEDIA: screen */

body,
th,
tr:hover,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/stylesheets/masters/top_level/dark_mode/dark_mode.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* SKIN: Dark Mode */
/* PARENTS: Dark Mode - Midsize, Dark Mode - Screen */
/* MEDIA: screen */

#unused-selector { content: none; }
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* SKIN: Low Vision Default */
/* PARENTS: 1, 2, 4, 5, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32 */

#outer * {
box-shadow: none;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/* SKIN: Reversi */
/* MEDIA: screen */

#outer .region,
#footer .group,
.post fieldset fieldset,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/* SKIN: Snow Blue */
/* PARENTS: Snow */
/* MEDIA: screen */

#header ul.primary,
#footer,
.autocomplete .dropdown ul li:hover,
Expand Down
26 changes: 0 additions & 26 deletions public/stylesheets/site/user_skins_to_load/README.txt

This file was deleted.

Loading
Loading