helpers.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import fs from 'fs';
  2. import Sentry from '@sentry/node';
  3. import Config from './config.js';
  4. export function capture_sentry_exception(err) {
  5. if (Config.ENABLE_SENTRY) {
  6. Sentry.captureException(err);
  7. Sentry.configureScope((scope) => scope.clear());
  8. } else {
  9. console.error(err);
  10. }
  11. }
  12. export function gen_url(mode, path) {
  13. const ruleset = ['osu', 'taiko', 'catch', 'mania'][mode || 0];
  14. const scheme = Config.IS_PRODUCTION ? 'https://' : 'http://';
  15. return `${scheme}${ruleset}.${Config.domain_name}${path}`;
  16. }
  17. export function random_from(arr) {
  18. return arr[Math.floor((Math.random() * arr.length))];
  19. }
  20. const base = fs.readFileSync('views/main.eta', 'utf-8');
  21. export const render_error = (error) => {
  22. return base.replace('<%~ it.body %>', error);
  23. };
  24. // Returns the color of a given star rating, matching osu!web's color scheme.
  25. export function stars_to_color(sr) {
  26. if (sr <= 0.1) {
  27. return '#4290FB';
  28. } else if (sr >= 9) {
  29. return '#000000';
  30. }
  31. const star_levels = [0.1, 1.25, 2, 2.5, 3.3, 4.2, 4.9, 5.8, 6.7, 7.7, 9];
  32. const star_colors = ['#4290FB', '#4FC0FF', '#4FFFD5', '#7CFF4F', '#F6F05C', '#FF8068', '#FF4E6F', '#C645B8', '#6563DE', '#18158E', '#000000'];
  33. for (const i in star_levels) {
  34. if (!star_levels.hasOwnProperty(i)) continue;
  35. if (star_levels[i] >= sr && star_levels[i-1] < sr) {
  36. const lower = star_levels[i - 1];
  37. const upper = star_levels[i];
  38. const ratio = (sr - lower) / (upper - lower);
  39. const r = parseInt(star_colors[i-1].substr(1, 2), 16) * (1 - ratio) + parseInt(star_colors[i].substr(1, 2), 16) * ratio;
  40. const g = parseInt(star_colors[i-1].substr(3, 2), 16) * (1 - ratio) + parseInt(star_colors[i].substr(3, 2), 16) * ratio;
  41. const b = parseInt(star_colors[i-1].substr(5, 2), 16) * (1 - ratio) + parseInt(star_colors[i].substr(5, 2), 16) * ratio;
  42. return '#' + Math.round(r).toString(16).padStart(2, '0') + Math.round(g).toString(16).padStart(2, '0') + Math.round(b).toString(16).padStart(2, '0');
  43. }
  44. }
  45. }
  46. export function recover_sql_query_data(filter_query) {
  47. if (!filter_query || filter_query == 1) {
  48. return {
  49. key_counts: [],
  50. filters: [],
  51. };
  52. }
  53. // We never stored the map filters/mania keycounts!
  54. // So, we recover them now from the SQL query ¯\_(ツ)_/¯
  55. const mania_keycounts = [];
  56. const cleaned_filters = [];
  57. const criterion = filter_query.split(' AND ');
  58. criterion.shift(); // SQL query starts with "1 AND "
  59. for (let i = 0; i < criterion.length; i += 2) {
  60. // Map filters are " AND thing >= 0 AND thing <= 9"
  61. // Mania keycounts are " AND (0 OR cs = 4 OR cs = 8)"
  62. if (criterion[i].startsWith('(')) {
  63. const foo = criterion[i].split(' OR cs = ');
  64. foo.shift();
  65. for (const cs of foo) {
  66. mania_keycounts.push(parseInt(cs, 10));
  67. }
  68. continue;
  69. }
  70. const bar = criterion[i].split(' ');
  71. cleaned_filters.push({
  72. name: bar[0],
  73. min: parseFloat(bar[2]),
  74. max: parseFloat(criterion[i+1].split(' ')[2]),
  75. });
  76. }
  77. return {
  78. key_counts: mania_keycounts,
  79. filters: cleaned_filters,
  80. };
  81. }
  82. export function escape_markdown(text) {
  83. text = text.replaceAll('\\', '\\\\');
  84. text = text.replaceAll('_', '\\_');
  85. text = text.replaceAll('~', '\\~');
  86. text = text.replaceAll('`', '\\`');
  87. text = text.replaceAll('|', '\\|');
  88. text = text.replaceAll(/(https?:\/\/\S+)/g, '<$1>');
  89. return text;
  90. }