Михаиллл
Jan. 19, 2019, 4:08 p.m.

Как документ RTF конвертировать в HTML

Qt, rtf, HTML, CONVERT

Добрый день.
Как документ RTF конвертировать в HTML?
Могу его открыть и прочитать так:

  1. QString file = QFileDialog::getOpenFileName(0, "Выберете резюме hh.ru", "", "*.rtf");
  2. if(!file.isEmpty())
  3. {
  4. QFile sFile(file);
  5. if(sFile.open(QFile::ReadOnly | QFile::Text)){
  6. QTextStream in(&sFile);
  7. //QTextDocument textDocument;
  8. //textDocument = in.readAll().toHtmlEscaped();
  9. QString text = in.readAll();
  10. sFile.close();
  11.  
  12. ui->ResumeHHTextEdit->setHtml(text);
  13. qDebug()<<text;
  14. }
  15. }

Тут Есть подходящая библиотека. Вот , наверно, нужный dll.
Itenso.Rtf.Converter.Html.dll Itenso.Rtf.Converter.Html.dll
Но не могу его дабавить его к проекту как библиотеку, проект требует только формат .lib

Еще тут есть проект. Но не пойму, как еого использовать.
Помогите пожалуйста.

2

Do you like it? Share on social networks!

26
Михаиллл
  • Jan. 19, 2019, 4:41 p.m.

хотя как динамическая Itenso.Rtf.Converter.Html.dll подключается

    Михаиллл
    • Jan. 19, 2019, 9:41 p.m.

    Нашел тут код конвертации:

    1. var
    2. W: Variant;
    3. begin
    4. W := CreateOleObject('Word.Application');
    5. W.Documents.Open('e:\test.rtf',False,False);
    6. W.ActiveDocument.SaveAs('e:\test.html',wdFormatHTML);
    7. W.ActiveDocument.CLose;
    8. W.Quit;
    9. W := UnAssigned;

    но это видимо синтаксис VS.
    Помогите пожалуйста переписать под QT.
    Наверно это будет примерно так:

    1. QString resumeFileName = QFileDialog::getOpenFileName(0, "Выберете резюме hh.ru", "", "*.rtf");
    2. QString saveFile = "C:/Users/MS/Downloads/Test.html";
    3. if(!resumeFileName.isEmpty())
    4. {
    5. QAxObject wordApplication("Word.Application");
    6. QAxObject *documents = wordApplication.querySubObject("Documents");
    7. //QAxObject *document = documents->querySubObject("Open(const QString&, bool)", resumeFileName, true);
    8. QAxObject *document = documents->querySubObject("Open(const QVariant&, bool)", resumeFileName, true);
    9. QAxObject *words = document->querySubObject("Words");
    10. words->querySubObject("Тут запрос конвертации");
    11.  
    12. document->dynamicCall("Close (boolean)", false);
    13. }
    14.  
      Михаиллл
      • Jan. 19, 2019, 10:23 p.m.

      извиняюсь, код на делфи, но подход наверно правильный.

        Evgenii Legotckoi
        • Jan. 20, 2019, 12:08 a.m.

        Добрый день.

        Я с ActiveX на Вы полностью до незнакомства. Но если поясните кое-какие моменты, то возможно у меня будет идея, которая вас натолкнёт на нужное русло. Поэтому вопрос такой.

        А Вы нашли вообще способ сохранять файлы через QAxObject? Дело в том, что тот код на Дельфи-то конечно отражает алгоритм, но библиотеки-то разные?

        Впрочем, если смотреть на то, что вы имеете, то возможно, для запроса конвертации нужно записать что-то подобное.

        1. words->querySubObject("SaveAs('e:\test.html', wdFormatHTML)");

        Но не знаю, у вас уже есть какие-нибудь примеры сохранение через QAxObject?

          Михаиллл
          • Jan. 20, 2019, 7:33 p.m.

          Так тоже не работает, но наверно что то похожее должно заработать.
          Что то похожее я видел тут и тут .
          Как я понял этот вариант должен работать через библиотеки Word. Запрос querySubObject должен вызвать нужную функцию.

            Михаиллл
            • Jan. 20, 2019, 7:35 p.m.

            Еще я видиле библиотеки на java и C#, которые могут также конывертировать. Не знаете ли вы, можно ли их использовать?

              Evgenii Legotckoi
              • Jan. 21, 2019, 1:40 p.m.

              Бибилотеки Java и С# можно использовать, если они будут добавлены в самостоятельную программу, которая будет работать в консольном режиме. Тогда через QProcess можно будет вызывать данную программу и выполнять конвертирование.

              Я бы попытался по возможности распарсить получаемый текст, если там удаётся извлечь хоть что-то, что походит на сколько-нибудь структурированные данные. Конечно, придётся с регулярками повозиться.

                Михаиллл
                • Jan. 21, 2019, 2:11 p.m.

                Похоже я нашел решение на с++
                Тут автор описывает про магическое превращение через буфер обмена средствами Word.
                Вот
                7925-Rtf2HtmlProj.zip 7925-Rtf2HtmlProj.zip
                Вот код автора:

                1. // Rtf2Html.cpp : Defines the entry point for the console application.
                2. //
                3. #include "stdafx.h"
                4. #include "Rtf2Html2.h"
                5. #include "afxhtml.h"
                6.  
                7. CWinApp theApp; // Win32 App with MFC support
                8.  
                9. CRichEditCtrl g_ctlRichEdit; // the two controls
                10. CHtmlEditCtrl g_ctlEditHtml;
                11.  
                12. // This is needed to load the RichEdit control from a file
                13. static DWORD CALLBACK
                14. MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
                15. {
                16. CFile* pFile = (CFile*) dwCookie;
                17. *pcb = pFile->Read(pbBuff, cb);
                18. return 0;
                19. }
                20.  
                21. void LoadRtfFile( LPCTSTR pszFilename )
                22. {
                23. wchar_t szFilter[] = L"RTF files (*.rtf)|*.rtf;|"
                24. L"All Files (*.*)|*.*||";
                25. CFileDialog dlg(TRUE,0,pszFilename,6,szFilter );
                26. if ( dlg.DoModal()!=IDOK ) {
                27. return;
                28. }
                29. CFile cf( dlg.GetPathName(),CFile::modeRead );
                30.  
                31. // CFile cf( pszFilename,CFile::modeRead );
                32. EDITSTREAM es;
                33. es.dwCookie = (DWORD)&cf;
                34. es.pfnCallback = MyStreamInCallback;
                35. g_ctlRichEdit.StreamIn( SF_RTF, es ); // load from the file
                36. }
                37.  
                38. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
                39. {
                40. AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
                41. AfxInitRichEdit2(); // needed for using CRichEditCtrl
                42.  
                43. CWnd* pWnd = CWnd::GetDesktopWindow();
                44. CRect r(0,0,200,200);
                45.  
                46. g_ctlRichEdit.Create( ES_MULTILINE, r, pWnd, 1111);
                47. g_ctlEditHtml.Create( 0,0, r, pWnd, 2222 );
                48.  
                49. LoadRtfFile( argv[1] ); // read the RTF file into the ctrl
                50. g_ctlRichEdit.SetSel(0,-1); // select all in the RTF ctrl
                51. g_ctlRichEdit.Copy(); // copy to clipboard
                52. g_ctlEditHtml.Paste(); // paste into the Html Edit ctrl
                53. g_ctlEditHtml.SaveAs( L"C:\\temp\\test.html"); // save HTML
                54.  
                55. return 0;
                56. }

                Не могли бы вы мне помочь адаптировать это под QT

                  Evgenii Legotckoi
                  • Jan. 21, 2019, 2:38 p.m.

                  Call back функцию (MyStreamInCallback) можно так и копировать в проект на Qt, также функцию LoadRtfFile можно так и копировать.

                  Думаю, что здесь особо адаптировать-то нечего, просто добавить в проект на Qt все те функции, а код в _tmain вынести в какой-нибудь слот.

                    Михаиллл
                    • Jan. 21, 2019, 5:16 p.m.
                    • (edited)

                    Попробовал, но QT выдает много ошибок, говорит что не знает : LPCTSTR, CFileDialog, CFile, EDITSTREAM и т.д.
                    Для того, чтобы это испраить, видимо нужны какие то файлы из MSVC.

                    Так же нашел библиотеку, скомпилированную на C# .
                    Там же и примеры на C#.
                    Вот документация по этой библиотеке.
                    Подключил эту библиотеку.
                    Пробую воспользоваться этой библиотекой, пока выходит так:

                    1. typedef void (*MyPrototype)(QString);
                    2. MyPrototype OpenDocx = (MyPrototype) rtf2HtmlLib.resolve("OpenDocx");
                    3. MyPrototype ToHtml = (MyPrototype) rtf2HtmlLib.resolve("ToHtml");

                    Помогите пожалуйста разобраться с этим

                      Михаиллл
                      • Jan. 21, 2019, 5:50 p.m.

                      Для решения этой задачи нужно как-то использовать функцию

                      1. public string ConvertFileToString(
                      2. string inputFileName
                      3. )
                      4. Public Function ConvertFileToString ( _
                      5. inputFileName As String _
                      6. ) As String

                      вот только она не статичная и не понятно как создать объект нужного класса

                        Evgenii Legotckoi
                        • Jan. 21, 2019, 6:35 p.m.

                        Ну не цепляются C# библиотеки в C++ коде, обратное возможно.

                          Михаиллл
                          • Jan. 21, 2019, 8:48 p.m.

                          Скажите пожалуйста, что же делать с ошибками незнания: LPCTSTR, CFileDialog, CFile, EDITSTREAM и прочего

                            Evgenii Legotckoi
                            • Jan. 21, 2019, 8:53 p.m.
                            • (edited)

                            Это всё из MFC, нужно заменять на QFileDialog, QFile и т.д. Или подключать соответствующие библиотеки из WinAPI, что априори плохая мысль, если используется Qt. . Не работал с теми библиотеками, только с Qt.

                            Делать это строчка, за строчкой. А не сразу наскоком.

                              Михаиллл
                              • Jan. 21, 2019, 10:24 p.m.

                              Нашел ссылку на древние типы данных , а тут нынешние их аналоги.
                              Но все равно каое что непоня:
                              что такое : LPCTSTR, CALLBACK (наверно QDialig),IDOK, EDITSTREAM, TCHAR
                              Код у меня получился (не доработанный) такой:

                              1. #ifndef RTFTOHTML_H
                              2. #define RTFTOHTML_H
                              3.  
                              4. #include <QFile>
                              5. #include <QDialog>
                              6. // Rtf2Html.cpp : Defines the entry point for the console application.
                              7. //
                              8. //#include "stdafx.h"
                              9. //#include "Rtf2Html2.h"
                              10. //#include "afxhtml.h"
                              11.  
                              12. //CWinApp theApp; // Win32 App with MFC support
                              13.  
                              14. //CRichEditCtrl g_ctlRichEdit; // the two controls
                              15. //CHtmlEditCtrl g_ctlEditHtml;
                              16.  
                              17. // This is needed to load the RichEdit control from a file
                              18. static int CALLBACK
                              19. MyStreamInCallback(int dwCookie, char pbBuff, long long cb, long long *pcb)
                              20. {
                              21. QFile* pFile = (QFile*) dwCookie;
                              22. *pcb = pFile->Read(pbBuff, cb);
                              23. return 0;
                              24. }
                              25.  
                              26. void LoadRtfFile( LPCTSTR pszFilename )
                              27. {
                              28. wchar_t szFilter[] = L"RTF files (*.rtf)|*.rtf;|"
                              29. L"All Files (*.*)|*.*||";
                              30. QFileDialog dlg(true,0,pszFilename,6,szFilter );
                              31. if ( dlg.DoModal()!=IDOK ) {
                              32. return;
                              33. }
                              34. QFile cf( dlg.GetPathName(),QFile::modeRead );
                              35.  
                              36. // QFile cf( pszFilename,QFile::modeRead );
                              37. EDITSTREAM es;
                              38. es.dwCookie = (int)&cf;
                              39. es.pfnCallback = MyStreamInCallback;
                              40. g_ctlRichEdit.StreamIn( SF_RTF, es ); // load from the file
                              41. }
                              42.  
                              43. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
                              44. {
                              45. AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
                              46. AfxInitRichEdit2(); // needed for using CRichEditCtrl
                              47.  
                              48. CWnd* pWnd = CWnd::GetDesktopWindow();
                              49. CRect r(0,0,200,200);
                              50.  
                              51. g_ctlRichEdit.Create( ES_MULTILINE, r, pWnd, 1111);
                              52. g_ctlEditHtml.Create( 0,0, r, pWnd, 2222 );
                              53.  
                              54. LoadRtfFile( argv[1] ); // read the RTF file into the ctrl
                              55. g_ctlRichEdit.SetSel(0,-1); // select all in the RTF ctrl
                              56. g_ctlRichEdit.Copy(); // copy to clipboard
                              57. g_ctlEditHtml.Paste(); // paste into the Html Edit ctrl
                              58. g_ctlEditHtml.SaveAs( L"C:\\temp\\test.html"); // save HTML
                              59.  
                              60. return 0;
                              61. }
                              62.  
                              63. #endif // RTFTOHTML_H
                              64.  

                              помогите пожалуйста до конца разобраться с ним.
                              И скажите пожалуйста , почему не стоит использовать WinAPI, при работе с QT?

                                Михаиллл
                                • Jan. 22, 2019, 2:54 p.m.

                                Тут нашел
                                rtftohtml_win32.zip rtftohtml_win32.zip . Похоже она скомпилированна на С++.
                                Подключил библиотеку как динамическую.
                                Теперь пытаюсь воспользоваться методом

                                1. char * ConvertString(char * rtfBuf, char * htmlBuf, struct convertOptions opt)

                                Пока заготовка такая

                                1. typedef void (*MyPrototype)(QString);
                                2. MyPrototype ConvertRtfFileToString = (MyPrototype) rtf2HtmlLib.resolve("ConvertString");
                                3. QString text;
                                4. text = ConvertRtfFileToString("C:/Users/MS/Desktop/Резюме/резюме/отправила - 3334709 - Дмитрий.rtf");

                                Но выдает ошибку: no viable overloaded '='
                                Помогите пожалуйста воспользоваться этим методом.

                                  Evgenii Legotckoi
                                  • Jan. 22, 2019, 3:06 p.m.
                                  • (edited)

                                  Там в примерах в архиве есть пример определения сигнатуры функции.

                                  1. typedef int (* cfunc)(char * rtffile, char *outfolder, struct convertOptions);
                                  2. cfunc ConvertFile;

                                  То есть сигнатура только так может объявляться. Вам нужно передать имя файла, каталог, где он находится и структуру настроек. Иначе никак. Передача QString туда никак не подойдёт.

                                  Думаю, что в документации там есть информация о параметрах в той структуре настроек.

                                    Михаиллл
                                    • Jan. 22, 2019, 10:02 p.m.

                                    В документации она не описанна, только в примере:

                                    1. struct convertOptions
                                    2. {
                                    3. int htmlType; //0-XHTML, 1- HTML, 2-HTML+CSS
                                    4. char title[120]; //Page title
                                    5. char extension[10]; //for example, ".html"
                                    6. char fontFace[50]; //for example, "Arial" or "Times New Roman"
                                    7. char fontSize[10]; //for example ,"10"
                                    8. int preserveImages; //0-no, 1 - yes
                                    9. int preserveFontFace; //0-no, 1 - yes
                                    10. int preserveFontSize; //0-no, 1 - yes
                                    11. int preserveFontColor; //0-no, 1 - yes
                                    12. int preserveHyperlinks; //0-no, 1 - yes
                                    13. int tableBorders; //0-invisble, 1 - visible
                                    14. int encoding; /* Windows_1250=0, Windows_1251=1, Windows_1252=2, Windows_1253=3,
                                    15. Windows_1254=4, Windows_1255=5, Windows_1256=6, Windows_1257=7,
                                    16. Windows_1258=8, ISO_8859_1=9, ISO_8859_2=10, ISO_8859_3=11,
                                    17. ISO_8859_4=12, ISO_8859_5=13, ISO_8859_6=14, ISO_8859_7=15,
                                    18. ISO_8859_8=16, ISO_8859_9=17, KOI8_R=18, UTF_8=19 */
                                    19. int htmlParts; //0-html Complete, 1 - only between <body>..</body>
                                    20. char imageFolder[500]; //folder where image will be stored
                                    21. char cssStyleName[120]; //style name, for example "ts"
                                    22. int fontSizesType; //0-normal sizes, 1 - medium sizes, 2 - big sizes, 3 - huge sizes
                                    23. char imageSubfolder[120];//will create subfolder for storing images, if ""-empty string then images will be strored in 'image_folder'
                                    24. int hyperlinkTarget; //0 - no target, 1 - target="_blank", 2 - _self, 3 - _parent, 4 - _top
                                    25. int cssStartNumber; //number for style name, like a .tsN (.ts1 or .ts100)
                                    26. char Serial[12];
                                    27. };

                                    На этой строчке

                                    1. ConvertFile=(cfunc)GetProcAddress(rtf2HtmlLib,"ConvertFile");

                                    Выдает ошибку : no matching function for call to 'GetProcAddress'

                                    попробовал сделать так и программа зависла

                                    1. ypedef int (* cfunc)(char * rtffile, char *outfolder, struct convertOptions);
                                    2. cfunc ConvertFile;
                                    3.  
                                    4.  
                                    5. int ret;
                                    6. char rtffile[_MAX_PATH];
                                    7. char outfolder[_MAX_PATH];
                                    8.  
                                    9. //load library
                                    10. //HINSTANCE rtf2HtmlLib=LoadLibrary("Sautinsoft.RTFToHTML.Win32.dll");
                                    11.  
                                    12. /*if(rtf2HtmlLib==NULL)
                                    13. {
                                    14. printf("Unable to load library\n");
                                    15. getchar();
                                    16. //return 0;
                                    17. }*/
                                    18. //ConvertFile=(cfunc)GetProcAddress(rtf2HtmlLib,"ConvertFile");
                                    19.  
                                    20. //typedef void (*MyPrototype)(QString *rtfFile, QString *outFolder, struct convertOptions);
                                    21. //MyPrototype ConvertFile = (MyPrototype) rtf2HtmlLib.resolve("ConvertFile");
                                    22.  
                                    23.  
                                    24. /*if (ConvertFile==NULL)
                                    25. {
                                    26. printf("Can't load function.\n");
                                    27. FreeLibrary((HMODULE)rtf2HtmlLib);
                                    28. getchar();
                                    29. //return 0;
                                    30. }*/
                                    31. //
                                    32. printf("Please enter rtf file (example: d:\\my.rtf):\n");
                                    33. gets(rtffile);
                                    34. printf("Please enter output folder (example : d:\\temp):\n");
                                    35. gets(outfolder);
                                    36.  
                                    37. //set conversion params
                                    38. struct convertOptions ct;
                                    39. ct.cssStartNumber=1;
                                    40. strcpy(ct.cssStyleName,"ts");
                                    41. ct.encoding=9;
                                    42. strcpy(ct.extension,".htm");
                                    43. strcpy(ct.fontFace,"Verdana");
                                    44. strcpy(ct.fontSize,"10");
                                    45. ct.htmlType=1;
                                    46. ct.preserveFontColor=1;
                                    47. ct.preserveFontFace=1;
                                    48. ct.preserveFontSize=1;
                                    49. ct.preserveImages=1;
                                    50. ct.preserveHyperlinks=1;
                                    51. ct.tableBorders=1;
                                    52. ct.htmlParts=0; //only between <body>...</body>
                                    53. strcpy(ct.title,"My Page");
                                    54. strcpy(ct.imageFolder,"D:\\");
                                    55. strcpy(ct.imageSubfolder,"test.files");
                                    56. ct.hyperlinkTarget=0;
                                    57. strcpy(ct.Serial,"Serial number");
                                    58.  
                                    59.  
                                    60. ret=ConvertFile("C:/Users/MS/Desktop/Резюме/резюме/отправила - 3334709 - Дмитрий.rtf","C:/Users/MS/Desktop/Резюме/резюме",ct);
                                    61.  
                                    62. switch(ret)
                                    63. {
                                    64. case -1 : puts("Check your serial number");break;
                                    65. case 0 : puts("Conversion completed");break;
                                    66. case 2 : puts("Not enough memory"); break;
                                    67. case 3 : puts("Can't open output file"); break;
                                    68. case 4 : puts("Can't open input file"); break;
                                    69. case 5 : puts("The input file has zerow length"); break;
                                    70. default: break;
                                    71. }
                                    72. //flushall
                                    73. getchar();

                                    Помогите пожалуйста разобраться с этой библиотекой

                                      Evgenii Legotckoi
                                      • Jan. 23, 2019, 12:19 a.m.

                                      Только если на выходных гляну, у самого своих проектов до кучи, чтобы разбираться в рабочие дни с незнакомой библиотекой.

                                        Михаиллл
                                        • Jan. 23, 2019, 1:54 p.m.
                                        • (edited)

                                        Зарание спасибо.
                                        А еще на эту тему можно будет сделать статью. Это контент будет уникальным.

                                          Evgenii Legotckoi
                                          • Jan. 25, 2019, 6:03 p.m.
                                          • (edited)

                                          А вы случаем ту библиотеку не планируете подключать в приложение на Андроид?

                                          И вообще использовать ActiveX на андроиде?

                                            Михаиллл
                                            • Jan. 25, 2019, 6:25 p.m.

                                            нет, не планирую

                                              Михаиллл
                                              • Jan. 25, 2019, 7:44 p.m.
                                              • The answer was marked as a solution.

                                              вот именно так работает конвертация:

                                              1. QVariant fileFormat(0x0000000A); //Saving as filtered html
                                              2. QString resumeFileName; //= QFileDialog::getOpenFileName(0, "Выберете резюме hh.ru", "", "*.rtf");
                                              3. resumeFileName = "C:\\Users\\MS/Downloads\\Абсент.docx";
                                              4. QString saveFile = "C:\\Users\\MS/Downloads\\Test.html";
                                              5. if(!resumeFileName.isEmpty())
                                              6. {
                                              7. QAxObject wordApplication("Word.Application");
                                              8. QAxObject *documents = wordApplication.querySubObject("Documents");
                                              9.  
                                              10. QAxObject *document = documents->querySubObject("Open(const QVariant&, bool)", resumeFileName, true);
                                              11. document->querySubObject("SaveAs(const QVariant&,const QVariant)", saveFile, fileFormat);
                                              12.  
                                              13.  
                                              14. document->dynamicCall("Close (boolean)", false);
                                              15.  
                                              16.  
                                              17.  
                                              18. qDebug()<<resumeFileName;
                                              19. }

                                              конвертирует через ворд

                                                Evgenii Legotckoi
                                                • Jan. 25, 2019, 7:45 p.m.

                                                Я вас поздравляю. Приятно наблюдать за прогрессом.

                                                  Evgenii Legotckoi
                                                  • Jan. 25, 2019, 7:48 p.m.
                                                  • (edited)

                                                  Пожалуй, я тогда не буду заниматься той библиотекой. Всё равно она какая-то мутная на первый взгляд.

                                                    Михаиллл
                                                    • Jan. 25, 2019, 10:05 p.m.

                                                    и еще в конце нужно дописать для закрытия процесса (иначе будет в памяти висеть):

                                                    1. wordApplication.dynamicCall("Quit()");

                                                      Comments

                                                      Only authorized users can post comments.
                                                      Please, Log in or Sign up
                                                      • Last comments
                                                      • AK
                                                        April 1, 2025, 11:41 a.m.
                                                        Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                                                      • Evgenii Legotckoi
                                                        March 9, 2025, 9:02 p.m.
                                                        К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                                                      • VP
                                                        March 9, 2025, 4:14 p.m.
                                                        Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
                                                      • ИМ
                                                        Nov. 22, 2024, 9:51 p.m.
                                                        Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                                      • Evgenii Legotckoi
                                                        Oct. 31, 2024, 11:37 p.m.
                                                        Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup