Все расширения написаны под Tampermonkey поэтому его необходимо установить, тык. LZTHideCopyButton Реализация предложения копирования хайда из темы: https://zelenka.guru/threads/5095343/ Скрин После нажатия хайд выделяется и содержимое попадает в буфер обмена Установить LZTHideCopyButton Изменения: v2.0 -Изменена иконка -Добавлена анимация копирования -Добавлено всплывающее уведомление при копировании (Всё как при копировании ВВ-кода "Код") v2.1 - Исправлено дублирование кнопки - Изменён @namespace у расширения, старое придётся удалить и поставить новое. v2.2 Изменил способ копирования. Некоторые bb-коды внутри хайда могут заменяться некорректно, но текст и картинки сохраняются. вложенные хайды заменяются на цитату(такая механика editor/to-bb-code) v2.3 фикс дублирования кнопки у хайдов к которым нет доступа LZTConversationsMute Временное решение https://zelenka.guru/threads/5353072/ Позволяет отключить уведомления у конкретного диалога(группы) Скрин Установить LZTConversationsMute Изменения: v1.4 Спасибо @zoto_ff за помощь. -при нажатии на иконку отключения уведомлений диалог не будет открываться (для ПК, с телефона откроется ) -небольшой рефакторинг -исправлено появление нескольких иконок у одного чата -отключение расширения на странице диалогов, чтобы не ломать работу чата (иногда не приходили новые сообщения) -ПОМЕНАЛ ЗНАЧЕНИЯ ИКОНОК МУТА МЕСТАМИ -смена namespace скрипта (обновление с 1.3 до 1.4 придется установить вручную) v1.5 Исправлен баг из-за которого чаты в муте и чаты без мута менялись местами после обновления страницы v1.6 Исправлено обновление счетчика сообщений в меню в шапке сайта v1.7 Рефакторинг кода v2.0 Изменён интерфейс, добавлена синхронизация между вкладками. LZTUserCounterOpacityDisable Отключаем скрытие симпатий пользователя в темах (по дефолту показывает при наведении на сообщение) Установить LZTUserCounterOpacityDisable П.с. просто мне так удобнее, мб кому пригодится LZTMobileFollowersShow Расширение отображает скрытый блок подписок и подписчиков (в мобильной версии скрыт) При клике по блоку он раскрывается/закрывается. Установить LZTMobileFollowersShow Демонстрация Немного костыльно, т.к. не нашёл где в коде проверяется ресайз окна браузера. Изменения: v1.1 -Добавил поддержку других доменов форума -Анимация раскрытия/скрытия списка LZTCopyUniqButton Если понравился чей-то уник, просто кликни чтобы скопировать. Установить LZTCopyUniqButton LZTHideStickyThreads Расширение частично реализует задуманное из предложения https://zelenka.guru/threads/5372145/ Видео Установить LZTHideStickyThreads Изменения v1.0 - Добавлено скрытие тем на лету во время загрузки темы - Добавлена галочка и анимация при скрытии/показе закрепленных тем как в менюшках сайта v1.2 - Исправлен баг, при переключении страниц закрепы не скрывались - Теперь разделе розыгрышей закрепы нельзя скрыть (чтобы не пропустить выгодные Zelenify Увидел похожую тему, решил поделиться своим скриптом. Скрипт в цикле проверяет наличие новых уведомлений на форуме и отображает его в уведомлениях windows/android. Пример уведомлений: На ПК: На телефоне: У каждого типа уведомления своя иконка (не все виды отснифал, можете предлагать ещё) Нажатие на уведомление открывает его в браузере. Код на python [CENTER]import requests from time import sleep import json from bs4 import BeautifulSoup import sys import os VERSION = "1.1" print("""\u001b[32m %(( (( (((( \u001b[0m\u001b[42mZelenify\u001b[0m\u001b[32m ( &(((& #(((((% #((& ((((((((((((( ((% ((((##((((((((((((((& (# (((((%((((((((((((((((& &(((( (((((((((((((((((# ((((((((((((((((((# &((((% #(((((((((((((# &((((((( ((((((((( &(((((( #(((((((( ((((( &( %(( &((((((( %(((((# (((((( ((((((((((((((( \u001b[45m\u001b[34;1mby MeloniuM\u001b[0m""") is_android: bool = hasattr(sys, 'getandroidapilevel') PATH = os.path.dirname(os.path.realpath(__file__)) WIN_ICON = os.path.join(PATH, "favicon.png") class LolzApi: def __init__(self, token: str, baseUrl="https://api.zelenka.guru/"): self.token = token self.baseUrl = baseUrl self.session = requests.session() self.session.headers = {'Authorization': f'Bearer {self.token}'} def get(self, url, params={}): return self.session.get(self.baseUrl + url, params=params) def post(self, url, data={}): return self.session.post(self.baseUrl + url, data=data) class Zelenify: def __init__(self, api, config, is_android): self.api = api self.config = config self.is_android = is_android icon=WIN_ICON url="https://zelenify.t.me" if is_android: icon = "notifications" url = "termux-open " + url self.send_notify(title='Уведомление', content='Скрипт запущен. Контакты: [URL]https://zelenify.t.me',[/URL] url=url, icon=icon) def send_notify(self, title: str, content: str, url: str, icon=WIN_ICON): if self.is_android: termux.Notification.notify(title=("Zelenify " + title), content=content, kwargs={"icon": icon, "action": url}) #execute(["termux-notification", "-t", title, "-c", content, "-i", "Zelenify", "--action", "termux-open " + url, "--icon", icon]) else: notify(title, content, on_click=url, icon=icon, app_id="Zelenify") def run(self): #global **** """ todo: - добавить конфиг с выбором типа уведомлений которые отслеживать """ last = [] dots = 1 connectError = False while True: response = None; try: response = api.get("notifications") if('error' in response.json()): if(response.json()['error'] == 'invalid_token'): print('> Неверный токен, измените его в config.json') else: print('[' + response.json()['error'] +']', response.json()['error_description']) break notifys = response.json()['notifications'] except requests.exceptions.ConnectionError as e: print('[Error] Пропал интернет, ожидаю подключение' + '.'*dots + ' ', end="\r") dots += 1 if dots >= 3: dots = 1 connectError = True sleep(3) continue except Exception as e: if response != None: if response.status_code == 429:#флуд sleep(5) continue print('[Error]', e, end="\r") continue else: if connectError: print('\n[info] Соединение восстановлено ') connectError = False if response.status_code != 200: print('status', response) sleep(5) continue for notify in notifys: soup = BeautifulSoup(notify['notification_html'], 'html.parser') if notify['notification_is_unread'] == True and not notify['notification_id'] in last: if notify['creator_username'] != 'Реклама' or self.config['hide_ads'] != 'true': #log = notify['content_type'] + ":" + notify['content_action'] #if not log in ****.keys(): # ****[log] = soup.text.strip() url = soup.find("a", {"class": "PopupItemLink"}) if url: url = url.get('href') else: url = False icon=WIN_ICON if is_android: icon = self.get_termux_icon(notify['content_type'], notify['content_action']) #print(icon) if url: url = "termux-open " + str(url) #print(url) self.send_notify(title="Уведомление", content=soup.text.strip(), url=url, icon=icon) last.append(notify['notification_id']) print('\u001b[35;1m>\u001b[32;1m ' + soup.text.strip() + '\u001b[0m') mark = True if notify['notification_is_unread'] == False and notify['notification_id'] in last: last.remove(notify['notification_id']) sleep(1) def get_termux_icon(self, content_type: str, content_action: str): alerts1 = { 'thread': 'format_list_bulleted', #type: icon 'profile_post_comment': 'chat' } if content_type in alerts1.keys(): return alerts1[content_type] alerts2 = { 'conversation': {#type 'insert': 'insert_comment', #action: icon 'join': 'person_add', 'reply' : 'reply' }, 'post': { 'insert': 'speaker_notes' }, 'post_comment': { 'like': 'favorite' }, 'profile_post': { 'like': 'thumb_up' }, 'user': { 'post_copy': 'content_copy', 'post_move': 'low_priority', 'thread_merge': 'merge_type', 'thread_move': 'wrap_text', 'from_admin': 'verified_user' } } if content_type in alerts2.keys(): if content_action in alerts2[content_type].keys(): return alerts2[content_type][content_action] return 'notification' if __name__ == '__main__': if is_android: try: import termux except: print("Установите Termux:API - pip install termux") exit(1) else: try: from win11toast import notify except: print("Установите win11toast - pip install win11toast") exit(1) """ 1.Заходим на [URL]https://zelenka.guru/account/api[/URL] и создаём приложение 2.Теперь перехожим на [URL]https://api.zelenka.guru/oauth/authorize?response_type=token&client_id=CLIENT_ID&scope=read+post+market[/URL] заменив CLIENT_ID на айди приложения из пункта [1] 3.Выдаём приложению права все кроме маркета(они ему не нужны) 4.Копируем токен из адресной строки со страницы на которую нас перенаправило и вставляем в код """ if not os.path.exists(os.path.join(PATH, "config.json")): with open(os.path.join(PATH, 'config.json'), 'w') as configfile: data = { 'token': input('Введите токен lolzapi: '), 'hide_ads': 'true' } configfile.write(json.dumps(data)) configfile.close() with open(os.path.join(PATH, 'config.json'), "r") as jsonfile: config = json.load(jsonfile) api = LolzApi(config['token']) if not os.path.exists(WIN_ICON): print('\u001b[33;1mНе найден favicon.png, качаю с форума\u001b[0m') favicon = open(WIN_ICON, 'wb') favicon.write(requests.get("https://zelenka.guru/styles/brand/download/logos/LolzTeam-Logo-Green.png", allow_redirects=True).content) favicon.close() print('\u001b[33;1mГотово!\u001b[0m') print('Жду новые уведомления на форуме') try: zel = Zelenify(api, config, is_android) zel.run() except KeyboardInterrupt: print(' '*50, end="\r") print('До новых встреч <3') Python [CENTER]import requests from time import sleep import json from bs4 import BeautifulSoup import sys import os VERSION = "1.1" print("""\u001b[32m %(( (( (((( \u001b[0m\u001b[42mZelenify\u001b[0m\u001b[32m ( &(((& #(((((% #((& ((((((((((((( ((% ((((##((((((((((((((& (# (((((%((((((((((((((((& &(((( (((((((((((((((((# ((((((((((((((((((# &((((% #(((((((((((((# &((((((( ((((((((( &(((((( #(((((((( ((((( &( %(( &((((((( %(((((# (((((( ((((((((((((((( \u001b[45m\u001b[34;1mby MeloniuM\u001b[0m""") is_android: bool = hasattr(sys, 'getandroidapilevel') PATH = os.path.dirname(os.path.realpath(__file__)) WIN_ICON = os.path.join(PATH, "favicon.png") class LolzApi: def __init__(self, token: str, baseUrl="https://api.zelenka.guru/"): self.token = token self.baseUrl = baseUrl self.session = requests.session() self.session.headers = {'Authorization': f'Bearer {self.token}'} def get(self, url, params={}): return self.session.get(self.baseUrl + url, params=params) def post(self, url, data={}): return self.session.post(self.baseUrl + url, data=data) class Zelenify: def __init__(self, api, config, is_android): self.api = api self.config = config self.is_android = is_android icon=WIN_ICON url="https://zelenify.t.me" if is_android: icon = "notifications" url = "termux-open " + url self.send_notify(title='Уведомление', content='Скрипт запущен. Контакты: [URL]https://zelenify.t.me',[/URL] url=url, icon=icon) def send_notify(self, title: str, content: str, url: str, icon=WIN_ICON): if self.is_android: termux.Notification.notify(title=("Zelenify " + title), content=content, kwargs={"icon": icon, "action": url}) #execute(["termux-notification", "-t", title, "-c", content, "-i", "Zelenify", "--action", "termux-open " + url, "--icon", icon]) else: notify(title, content, on_click=url, icon=icon, app_id="Zelenify") def run(self): #global **** """ todo: - добавить конфиг с выбором типа уведомлений которые отслеживать """ last = [] dots = 1 connectError = False while True: response = None; try: response = api.get("notifications") if('error' in response.json()): if(response.json()['error'] == 'invalid_token'): print('> Неверный токен, измените его в config.json') else: print('[' + response.json()['error'] +']', response.json()['error_description']) break notifys = response.json()['notifications'] except requests.exceptions.ConnectionError as e: print('[Error] Пропал интернет, ожидаю подключение' + '.'*dots + ' ', end="\r") dots += 1 if dots >= 3: dots = 1 connectError = True sleep(3) continue except Exception as e: if response != None: if response.status_code == 429:#флуд sleep(5) continue print('[Error]', e, end="\r") continue else: if connectError: print('\n[info] Соединение восстановлено ') connectError = False if response.status_code != 200: print('status', response) sleep(5) continue for notify in notifys: soup = BeautifulSoup(notify['notification_html'], 'html.parser') if notify['notification_is_unread'] == True and not notify['notification_id'] in last: if notify['creator_username'] != 'Реклама' or self.config['hide_ads'] != 'true': #log = notify['content_type'] + ":" + notify['content_action'] #if not log in ****.keys(): # ****[log] = soup.text.strip() url = soup.find("a", {"class": "PopupItemLink"}) if url: url = url.get('href') else: url = False icon=WIN_ICON if is_android: icon = self.get_termux_icon(notify['content_type'], notify['content_action']) #print(icon) if url: url = "termux-open " + str(url) #print(url) self.send_notify(title="Уведомление", content=soup.text.strip(), url=url, icon=icon) last.append(notify['notification_id']) print('\u001b[35;1m>\u001b[32;1m ' + soup.text.strip() + '\u001b[0m') mark = True if notify['notification_is_unread'] == False and notify['notification_id'] in last: last.remove(notify['notification_id']) sleep(1) def get_termux_icon(self, content_type: str, content_action: str): alerts1 = { 'thread': 'format_list_bulleted', #type: icon 'profile_post_comment': 'chat' } if content_type in alerts1.keys(): return alerts1[content_type] alerts2 = { 'conversation': {#type 'insert': 'insert_comment', #action: icon 'join': 'person_add', 'reply' : 'reply' }, 'post': { 'insert': 'speaker_notes' }, 'post_comment': { 'like': 'favorite' }, 'profile_post': { 'like': 'thumb_up' }, 'user': { 'post_copy': 'content_copy', 'post_move': 'low_priority', 'thread_merge': 'merge_type', 'thread_move': 'wrap_text', 'from_admin': 'verified_user' } } if content_type in alerts2.keys(): if content_action in alerts2[content_type].keys(): return alerts2[content_type][content_action] return 'notification' if __name__ == '__main__': if is_android: try: import termux except: print("Установите Termux:API - pip install termux") exit(1) else: try: from win11toast import notify except: print("Установите win11toast - pip install win11toast") exit(1) """ 1.Заходим на [URL]https://zelenka.guru/account/api[/URL] и создаём приложение 2.Теперь перехожим на [URL]https://api.zelenka.guru/oauth/authorize?response_type=token&client_id=CLIENT_ID&scope=read+post+market[/URL] заменив CLIENT_ID на айди приложения из пункта [1] 3.Выдаём приложению права все кроме маркета(они ему не нужны) 4.Копируем токен из адресной строки со страницы на которую нас перенаправило и вставляем в код """ if not os.path.exists(os.path.join(PATH, "config.json")): with open(os.path.join(PATH, 'config.json'), 'w') as configfile: data = { 'token': input('Введите токен lolzapi: '), 'hide_ads': 'true' } configfile.write(json.dumps(data)) configfile.close() with open(os.path.join(PATH, 'config.json'), "r") as jsonfile: config = json.load(jsonfile) api = LolzApi(config['token']) if not os.path.exists(WIN_ICON): print('\u001b[33;1mНе найден favicon.png, качаю с форума\u001b[0m') favicon = open(WIN_ICON, 'wb') favicon.write(requests.get("https://zelenka.guru/styles/brand/download/logos/LolzTeam-Logo-Green.png", allow_redirects=True).content) favicon.close() print('\u001b[33;1mГотово!\u001b[0m') print('Жду новые уведомления на форуме') try: zel = Zelenify(api, config, is_android) zel.run() except KeyboardInterrupt: print(' '*50, end="\r") print('До новых встреч <3') [/CENTER] Зависимости Для windows: pip install bs4 requests win11toast Для андроид нужен Termux и Termux:API (советую ставить версии с гитхаба) pip install termux-api pkg install bs4 requests termux-api Code pip install termux-api pkg install bs4 requests termux-api Бонус для android Для андроид можно установить Termux:Boot, либо Termux:Widget для быстрого запуска скрипта. Первый для запуска при включении телефона, второй для запуска с виджета на рабочем столе. Для владельцев браслета Mi Band: Можно через приложение Notify сменить иконку у Termux:API на логотип форума. Инструкция Установить Notify Выбираем - Приложения Добавляем в список приложение Termux:API нажав на плюсик и выбрав его в списке приложений. А теперь изменим иконку приложения. Жмём шестерёнку: Настроить значок уведомлений Выбираем в списке то приложение, которым не будем пользоваться. Я например не использую Mi чат, его иконку заменю лого форума. Выбрать значок с телефона. Предварительно скачайте логотип форума. Теперь сменим иконку у приложения Termux:API выбрав в настройках изменённую в предыдущем шаге иконку. В комментариях рад видеть предложения по улучшению скрипта. LZTLinkPreview Многие хотели эту возможность, а я вот Вам реализовал Вы все знаете, что когда в любом разделе навести мышку на тему появится окошко предпросмотра. Все же хотели, чтобы этот предпросмотр работал ещё и в других местах?) Так вот, данное расширение это позволяет. А именно в: диалогах, постах и комментариях под темой и даже в профиле. Скриншотики: Установить LZTLinkPreview Изменения v1.1 - Исправлено отсутствие превью у ссылок при открытии нового диалога. LZTCommentLink У сообщений в теме есть ссылка, которую можно получить нажав на его дату, у комментариев данного функционала нет, хотя ссылки имеются. Данное расширение позволит скопировать ссылку на комментарий кликнув по его дате. Бонусом, при открытии таких ссылок страница автоматически прокрутится до нужного комментария и подсветит его. Установить LZTCommentLink Изменения v1.1 Добавлено отображение даты на мобильной версии сайта v1.2 Убран отступ слева у даты v1.3 - Добавлены ссылки к комментариям на странице профиля - Добавлено окно копирования ссылки, bb-кода, html-кода в темах. В профилях копирование ссылки сразу в буфер обмена. - Если при открытии профиля комментария нет на первой странице, он перенаправит на нужную страницу v1.3.1 - Фикс недобавления ссылки к комментариям при листании страниц профиля LZTManageNotifyButton Настройка подписки на пользователя прямо из карточки. Подписались на человека и вдруг начинается спам в уведомлениях о его темах? Хочется отключить уведомления, но не хочется отписываться от пользователя. Чтобы не лезть в https://zelenka.guru/account/following искать там и убирать галочки, а некоторые и не знают об этой ссылке и просто переподписываются чтобы увидеть заветное меню. Теперь всё просто: нажал на ник, в карточке нажал на шестерёнку, снял нужные галочки! Установить LZTManageNotifyButton Изменения v1.1 Подправил css шестерёнки. Спасибо Extremum LZTClicableUserThreadsUsername Как просил Копировать в предложениях. Установить LZTClicableUserThreadsUsername LZT_ContestPro Переписал и дополнил расширение: https://zelenka.guru/threads/5145175/ С разрешения автора конечно. Что умеет моя версия: - Автолайк, с учётом оставшихся лайков. - участие по кнопке Tab - пролистывание розыгрыша до кнопки участвовать. Установить LZT_ContestPro LZTSuetaFavicon Ну, раз пошла такая пляска, внесу свой вклад в суету. Установить LZTSuetaFavicon LZTMobileInfinityScroll Включаем бесконечное листание ленты в мобильной версии форума. Всё. Установить LZTMobileInfinityScroll Реализация предложения: https://zelenka.guru/threads/5951452/ LZTThreadsURLCopy Копирование ссылки на тему простым нажатием. Просто потому, что меня напрягает лонгтап в мобильной версии для вызова контекстного меню и копирования ссылки. Мне так удобней Установить LZTThreadsURLCopy LZTConversOnlineMembers Реализация предложения: https://zelenka.guru/threads/6060117/ Количество участников беседы находящихся в данный момент в чате (может не совпадать с кол-вом участников из списка, при открытии чата с одного акк на нескольких устройствах). Обновляется каждые 10 сек и при тайпинге/отправке сообщений. Установить LZTConversOnlineMembers v1.1 LZTStackAlertsScrollable Уменьшит высоту блока уведомлений (StackAlerts) и позволит их листать. Установить LZTStackAlertsScrollable LZT_MemberCardReportButton Кнопка "Пожаловаться" в карточке профиля. Из предложения https://zelenka.guru/threads/6577053/ Установить LZT_MemberCardReportButton LZTlastPostPreview [LZTlastPostPreview v1.0] Предпросмотр последнего поста в теме Установить
Отключаем скрытие симпатий пользователя в темах (по дефолту показывает при наведении на сообщение) Установить расширение Tampermonkey П.с. просто мне так удобнее, мб кому пригодится
workingkilla, тут не об этом. Помимо симпатий так скрывается статус. С расширением он будет виден статически
НЕАКТУАЛЬНО. На форуме добавили эту кнопку. Вчера случайно нашёл это фичу. На форуме разрешили создание бесед, но кнопку не добавили, расширение исправит это дело Скрины: Установка Расширение LZTConversationsAddBotton
Так же можно сделать без расширения. Только надо зайти в переписки и добавить к https://zelenka.guru/conversations/ + add https://zelenka.guru/conversations/add - чтобы создать беседу с несколькими пользователями
Временное решение https://zelenka.guru/threads/5353072/ Позволяет отключить уведомления у конкретного диалога(группы) Скрин Установить Изменения: v1.4 Спасибо @zoto_ff за помощь. -при нажатии на иконку отключения уведомлений диалог не будет открываться (для ПК, с телефона откроется ) -небольшой рефакторинг -исправлено появление нескольких иконок у одного чата -отключение расширения на странице диалогов, чтобы не ломать работу чата (иногда не приходили новые сообщения) -ПОМЕНАЛ ЗНАЧЕНИЯ ИКОНОК МУТА МЕСТАМИ -смена namespace скрипта (обновление с 1.3 до 1.4 придется установить вручную) v1.5 Исправлен баг из-за которого чаты в муте и чаты без мута менялись местами после обновления страницы v1.6 Исправлено обновление счетчика сообщений в меню в шапке сайта v1.7 Рефакторинг кода v2.0 Изменён интерфейс, добавлена синхронизация между вкладками.