├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── build-all.yml ├── .gitignore ├── COPYING.LESSER ├── README.md ├── Sync-my-L2P.icns ├── Sync-my-L2P.pro ├── gui ├── autoclosedialog.ui ├── browser.ui ├── dateidownloader.ui ├── info.ui.template ├── logger.ui ├── logindialog.ui ├── message.ui ├── mymainwindow.ui └── options.ui ├── icon.rc ├── icons ├── Sync-my-L2P.png ├── about.png ├── archive.png ├── audio.png ├── block.png ├── browser.png ├── check.png ├── contact.png ├── contributors.png ├── course.png ├── directory.png ├── document.png ├── download.png ├── downloadDirectory.png ├── icons.qrc ├── license.png ├── login.png ├── logout.png ├── logs.png ├── magnifier.png ├── mail.png ├── otherFile.png ├── pdf.png ├── picture.png ├── refresh.png ├── semester.png ├── settings.png ├── sheet.png ├── slideshow.png ├── tutorial.png └── video.png ├── include ├── autoclosedialog.h ├── browser.h ├── clientId.h ├── filedownloader.h ├── info.h ├── l2pitemmodel.h ├── logger.h ├── login.h ├── logindialog.h ├── mymainwindow.h ├── mysortfilterproxymodel.h ├── options.h ├── parser.h ├── structureelement.h ├── urls.h ├── utils.h └── version.h.template ├── lang ├── sync-my-l2p_de.qm ├── sync-my-l2p_de.ts ├── sync-my-l2p_en.qm ├── sync-my-l2p_en.ts ├── sync-my-l2p_lb.qm ├── sync-my-l2p_lb.ts ├── sync-my-l2p_sq.qm ├── sync-my-l2p_sq.ts └── translation.qrc ├── linux ├── Dockerfile ├── Sync-my-L2P.desktop ├── create_appimage.sh ├── hicolor │ ├── 128x128 │ │ └── apps │ │ │ └── sync-my-L2P.png │ ├── 16x16 │ │ └── apps │ │ │ └── sync-my-L2P.png │ ├── 32x32 │ │ └── apps │ │ │ └── sync-my-L2P.png │ └── 48x48 │ │ └── apps │ │ └── sync-my-L2P.png ├── lib │ ├── LICENSE │ ├── Readme.md │ ├── libicudata.so.56 │ ├── libicui18n.so.56 │ └── libicuuc.so.56 ├── run.bat ├── run.sh └── sync-my-L2P.png ├── magnifier.ico ├── qslog ├── .gitignore ├── LICENSE.txt ├── QsLog.cpp ├── QsLog.h ├── QsLog.pri ├── QsLogChanges.txt ├── QsLogDest.cpp ├── QsLogDest.h ├── QsLogDestConsole.cpp ├── QsLogDestConsole.h ├── QsLogDestFile.cpp ├── QsLogDestFile.h ├── QsLogDestFunctor.cpp ├── QsLogDestFunctor.h ├── QsLogDisableForThisFile.h ├── QsLogLevel.h ├── QsLogReadme.txt ├── QsLogSharedLibrary.pro ├── example │ ├── log_example.pro │ ├── log_example_main.cpp │ ├── log_example_main.pro │ ├── log_example_shared.cpp │ ├── log_example_shared.h │ └── log_example_shared.pro └── unittest │ ├── QtTestUtil │ ├── QtTestUtil.h │ ├── SimpleChecker.cpp │ ├── TestRegistration.h │ ├── TestRegistry.cpp │ └── TestRegistry.h │ ├── TestLog.cpp │ └── unittest.pro ├── src ├── autoclosedialog.cpp ├── browser.cpp ├── filedownloader.cpp ├── info.cpp ├── l2pitemmodel.cpp ├── logger.cpp ├── login.cpp ├── logindialog.cpp ├── main.cpp ├── mymainwindow.cpp ├── mysortfilterproxymodel.cpp ├── options.cpp ├── parser.cpp ├── structureelement.cpp └── utils.cpp └── windows ├── SyncMyL2P.xml.template ├── lib ├── LICENSE ├── Readme.md ├── libcrypto-1_1-x64.dll ├── libcrypto-1_1.dll ├── libssl-1_1-x64.dll └── libssl-1_1.dll └── license.xml.template /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. Windows] 28 | - Version [e.g. v2.2.0] 29 | 30 | **Additional context** 31 | Please post or add as a file the "extended" log showing the events before and after the error occurs. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | // Builds 2 | bin 3 | *.o 4 | *.pro.user 5 | moc_*.cpp 6 | qrc_*.cpp 7 | ui_*.h 8 | Makefile* 9 | *.exe 10 | *.obj 11 | icon.res 12 | compile_commands.json 13 | moc_predefs.h 14 | .qmake.stash 15 | 16 | // Files generated from templates 17 | gui/info.ui 18 | include/version.h 19 | windows/SyncMyL2P.xml 20 | 21 | // Automated builds 22 | qt5 23 | qtcreator 24 | installbuilder 25 | -------------------------------------------------------------------------------- /COPYING.LESSER: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 

2 | 3 |

4 | 5 | Sync-my-L2P is a program created by students of the RWTH Aachen University for the comfortable download of all available files in RWTH Moodle (formerly L²P). It allows you to easily mirror all files from the learning rooms to your hard disk, so that they are available without internet. 6 | 7 | **Please note: After more than 9 years, I resign as maintainer. However, a team at the RWTH ITC and Moodle will continue to maintain and improve Sync-my-L2P. The new repository will be: https://github.com/rwthmoodle/Sync-my-L2P** 8 | 9 | # Download and Installation 10 | 11 | You can download Sync-my-L2P either from the [official Website](http://www.syncmyl2p.de) oder [here](https://github.com/Sync-my-L2P/Sync-my-L2P/releases/tag/latest) for Windows, Linux and macOS. While on Windows an installer is provided, on macOS a .dmg or homebrew package, and on Linux an AppImage is distributed. 12 | 13 | ## Installation on Windows 14 | Just use the provided installer. 15 | 16 | ## Installation on Linux Distributions (tested on Ubuntu 18.04) 17 | Make the AppImage executable and open it with a double click. 18 | 19 | ## Installation on OSX (.dmg) 20 | Open the .dmg and drag&drop Sync-my-L2P to your apps. 21 | 22 | ## Installation on OSX (Cask) 23 | Users with home-brew installed can now install Sync-my-L2P with the following commands: 24 | `brew tap caskroom/cask` followed by `brew cask install sync-my-l2p`. Updating the program will work with the command `brew update` to update the program formula, followed by `brew upgrade` to upgrade the program itself. 25 | 26 | # Compile 27 | For compilation we recommend C++11, Qt (5.15 or higher) and OpenSSL 1.1.1. 28 | The easiest way is to load the .pro file into Qt Creator and compile Sync-my-L2P there. From the console you can also run qmake (with appropriate arguments) instead and then the preferred C++ compiler. 29 | 30 | Note: A ClientID is required for the program to connect to the API of RWTH Moodle. The RWTH does not allow the publication of such a client ID. However, an individual ClientID can easily be requested. 31 | 32 | # Distribute 33 | For distributing Sync-my-L2P on Linux, two options are available: 34 | 1. Create an AppImage using the `run.sh` script provided in the `linux` subdirectory. 35 | 2. Create an deb package: https://github.com/justin-time/Sync-my-L2P-Linux 36 | 37 | # Crashes? Feedback? Questions? 38 | https://github.com/RobertKrajewski/Sync-my-L2P/issues 39 | -------------------------------------------------------------------------------- /Sync-my-L2P.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/Sync-my-L2P.icns -------------------------------------------------------------------------------- /Sync-my-L2P.pro: -------------------------------------------------------------------------------- 1 | QT += core gui network widgets xml 2 | CONFIG += c++11 3 | 4 | VERSION = "2.5.1" 5 | VERSION_CODE = "20501" 6 | 7 | TEMPLATE_FILES = include/version.h.template \ 8 | gui/info.ui.template \ 9 | windows/SyncMyL2P.xml.template 10 | 11 | template_compiler.input = TEMPLATE_FILES 12 | template_compiler.output = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_IN_BASE} 13 | template_compiler.depends = ${QMAKE_FILE_IN} Sync-my-L2P.pro 14 | win32 { 15 | template_compiler.commands = powershell -Command \"(Get-Content -Encoding utf8 \\\"${QMAKE_FILE_IN}\\\").Replace(\\\"__PRODUCT_VERSION_CODE\\\",\\\"$$VERSION_CODE\\\").Replace(\\\"__PRODUCT_VERSION\\\",\\\"$$VERSION\\\") | Set-Content -Encoding utf8 -Path ${QMAKE_FILE_OUT}\" 16 | } 17 | unix { 18 | template_compiler.commands = sed 's/__PRODUCT_VERSION_CODE/$$VERSION_CODE/g' ${QMAKE_FILE_IN} | sed 's/__PRODUCT_VERSION/$$VERSION/g' > ${QMAKE_FILE_OUT} 19 | } 20 | template_compiler.CONFIG = target_predeps no_link 21 | QMAKE_EXTRA_COMPILERS += template_compiler 22 | 23 | macx { 24 | plistupdate.commands = /usr/libexec/PlistBuddy -c \"Add :CFBundleVersion string $$VERSION\" -c \"Add :CFBundleShortVersionString string $$VERSION\" -c \"Add :CFBundleName string Sync-my-L2P\" -c \"Set :CFBundleIdentifier de.rwth-aachen.Sync-my-L2P\" bin/Sync-my-L2P.app/Contents/Info.plist 25 | QMAKE_EXTRA_TARGETS += plistupdate 26 | PRE_TARGETDEPS += plistupdate 27 | } 28 | 29 | TARGET = Sync-my-L2P 30 | TEMPLATE = app 31 | DESTDIR = bin 32 | 33 | SOURCES += \ 34 | src/main.cpp \ 35 | src/autoclosedialog.cpp \ 36 | src/browser.cpp \ 37 | src/filedownloader.cpp \ 38 | src/info.cpp \ 39 | src/l2pitemmodel.cpp \ 40 | src/logger.cpp \ 41 | src/login.cpp \ 42 | src/logindialog.cpp \ 43 | src/mymainwindow.cpp \ 44 | src/mysortfilterproxymodel.cpp \ 45 | src/options.cpp \ 46 | src/parser.cpp \ 47 | src/structureelement.cpp \ 48 | src/utils.cpp 49 | 50 | INCLUDEPATH += include/ 51 | HEADERS += \ 52 | include/clientId.h \ 53 | include/autoclosedialog.h \ 54 | include/browser.h \ 55 | include/clientId.h \ 56 | include/filedownloader.h \ 57 | include/info.h \ 58 | include/l2pitemmodel.h \ 59 | include/logger.h \ 60 | include/login.h \ 61 | include/logindialog.h \ 62 | include/mymainwindow.h \ 63 | include/mysortfilterproxymodel.h \ 64 | include/options.h \ 65 | include/parser.h \ 66 | include/structureelement.h \ 67 | include/urls.h \ 68 | include/utils.h \ 69 | include/version.h 70 | 71 | FORMS += \ 72 | gui/autoclosedialog.ui \ 73 | gui/browser.ui \ 74 | gui/dateidownloader.ui \ 75 | gui/info.ui \ 76 | gui/logger.ui \ 77 | gui/logindialog.ui \ 78 | gui/message.ui \ 79 | gui/mymainwindow.ui \ 80 | gui/options.ui 81 | 82 | TRANSLATIONS = lang/sync-my-l2p_de.ts \ 83 | lang/sync-my-l2p_en.ts \ 84 | lang/sync-my-l2p_lb.ts \ 85 | lang/sync-my-l2p_sq.ts 86 | 87 | RESOURCES += \ 88 | icons/icons.qrc \ 89 | lang/translation.qrc 90 | 91 | RC_FILE = icon.rc 92 | 93 | OTHER_FILES += \ 94 | Sync-my-L2P.icns \ 95 | README.md \ 96 | magnifier.ico \ 97 | LICENSE \ 98 | .gitignore 99 | 100 | include(qslog/QsLog.pri) 101 | -------------------------------------------------------------------------------- /gui/autoclosedialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AutoCloseDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 250 10 | 50 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Automatisch beenden 21 | 22 | 23 | 24 | :/icons/magnifier.png:/icons/magnifier.png 25 | 26 | 27 | 28 | 29 | 30 | 31 | 0 32 | 0 33 | 34 | 35 | 36 | Automatisches Beenden abbrechen 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /gui/dateidownloader.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DateiDownloader 4 | 5 | 6 | 7 | 0 8 | 0 9 | 680 10 | 180 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 680 22 | 180 23 | 24 | 25 | 26 | 27 | 680 28 | 180 29 | 30 | 31 | 32 | Qt::NoContextMenu 33 | 34 | 35 | 36 | 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 10 44 | 110 45 | 660 46 | 60 47 | 48 | 49 | 50 | 51 | 0 52 | 0 53 | 54 | 55 | 56 | 57 | 660 58 | 60 59 | 60 | 61 | 62 | 63 | 660 64 | 60 65 | 66 | 67 | 68 | Qt::ActionsContextMenu 69 | 70 | 71 | 72 | 73 | 74 | 0 75 | 76 | 77 | 0 78 | 79 | 80 | -1 81 | 82 | 83 | Qt::AlignCenter 84 | 85 | 86 | true 87 | 88 | 89 | Qt::Horizontal 90 | 91 | 92 | false 93 | 94 | 95 | QProgressBar::TopToBottom 96 | 97 | 98 | %v/%m KBs 99 | 100 | 101 | 102 | 103 | 104 | 10 105 | 10 106 | 660 107 | 30 108 | 109 | 110 | 111 | 112 | 0 113 | 0 114 | 115 | 116 | 117 | 118 | 660 119 | 30 120 | 121 | 122 | 123 | 124 | 660 125 | 30 126 | 127 | 128 | 129 | 130 | 12 131 | 75 132 | false 133 | true 134 | 135 | 136 | 137 | Qt::NoContextMenu 138 | 139 | 140 | font: bold 12pt; 141 | 142 | 143 | QFrame::NoFrame 144 | 145 | 146 | QFrame::Plain 147 | 148 | 149 | Warte auf Download 150 | 151 | 152 | Qt::AlignCenter 153 | 154 | 155 | Qt::NoTextInteraction 156 | 157 | 158 | 159 | 160 | 161 | 10 162 | 40 163 | 660 164 | 30 165 | 166 | 167 | 168 | 169 | 0 170 | 0 171 | 172 | 173 | 174 | 175 | 660 176 | 30 177 | 178 | 179 | 180 | 181 | 660 182 | 30 183 | 184 | 185 | 186 | 187 | 11 188 | 50 189 | false 190 | 191 | 192 | 193 | Qt::NoContextMenu 194 | 195 | 196 | QFrame::NoFrame 197 | 198 | 199 | QFrame::Plain 200 | 201 | 202 | Warten ... 203 | 204 | 205 | Qt::AlignCenter 206 | 207 | 208 | Qt::NoTextInteraction 209 | 210 | 211 | 212 | 213 | 214 | 10 215 | 60 216 | 660 217 | 30 218 | 219 | 220 | 221 | 222 | 0 223 | 0 224 | 225 | 226 | 227 | 228 | 660 229 | 30 230 | 231 | 232 | 233 | 234 | 660 235 | 30 236 | 237 | 238 | 239 | 240 | 10 241 | 50 242 | false 243 | 244 | 245 | 246 | Qt::NoContextMenu 247 | 248 | 249 | QFrame::NoFrame 250 | 251 | 252 | QFrame::Plain 253 | 254 | 255 | Datei.pdf 256 | 257 | 258 | Qt::AlignCenter 259 | 260 | 261 | Qt::NoTextInteraction 262 | 263 | 264 | 265 | 266 | 267 | 564 268 | 10 269 | 101 270 | 23 271 | 272 | 273 | 274 | Abbrechen 275 | 276 | 277 | 278 | 279 | 280 | 536 281 | 90 282 | 131 283 | 20 284 | 285 | 286 | 287 | 1321 kB/s 288 | 289 | 290 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 291 | 292 | 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /gui/logger.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Logger 4 | 5 | 6 | 7 | 0 8 | 0 9 | 619 10 | 378 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Qt::ScrollBarAlwaysOn 21 | 22 | 23 | Qt::ScrollBarAlwaysOff 24 | 25 | 26 | QAbstractItemView::NoEditTriggers 27 | 28 | 29 | false 30 | 31 | 32 | QAbstractItemView::ExtendedSelection 33 | 34 | 35 | Qt::ElideRight 36 | 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Qt::Vertical 48 | 49 | 50 | 51 | 20 52 | 40 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Log-Umfang: 61 | 62 | 63 | 64 | 65 | 66 | 67 | <html><head/><body><p><span style=" font-weight:600;">Standard</span>: Alle wichtigen Ereignisse werden geloggt.</p><p><span style=" font-weight:600;">Erweitert</span>: Neben den wichtigen Ereignissen werden auch solche geloggt, die zur Fehlerbehebung dienen.</p></body></html> 68 | 69 | 70 | 71 | 72 | 73 | 74 | <html><head/><body><p>Kopiert den gesamten Text in die Zwischenablage.</p><p>Um einzelne Elemente zu kopieren, müssen diese ausgewählt und mit der plattformtypischen Tastenkombination (Windows: Strg + C) kopiert werden</p></body></html> 75 | 76 | 77 | Kopieren 78 | 79 | 80 | 81 | 82 | 83 | 84 | <html><head/><body><p>Speichert den gesamten Text in eine separate Datei.</p></body></html> 85 | 86 | 87 | Speichern 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /gui/logindialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | LoginDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 352 10 | 87 11 | 12 | 13 | 14 | Qt::NoContextMenu 15 | 16 | 17 | Login 18 | 19 | 20 | 21 | :/icons/login.png:/icons/login.png 22 | 23 | 24 | true 25 | 26 | 27 | 28 | 29 | 30 | Überprüfe Erreichbarkeit von RWTHmoodle... 31 | 32 | 33 | Qt::AlignHCenter|Qt::AlignTop 34 | 35 | 36 | 37 | 38 | 39 | 40 | 3 41 | 42 | 43 | 0 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | 53 | Qt::NoContextMenu 54 | 55 | 56 | Qt::Horizontal 57 | 58 | 59 | QDialogButtonBox::Cancel 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | buttonBox 71 | accepted() 72 | LoginDialog 73 | accept() 74 | 75 | 76 | 248 77 | 254 78 | 79 | 80 | 157 81 | 274 82 | 83 | 84 | 85 | 86 | buttonBox 87 | rejected() 88 | LoginDialog 89 | reject() 90 | 91 | 92 | 316 93 | 260 94 | 95 | 96 | 286 97 | 274 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /gui/message.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | message 4 | 5 | 6 | 7 | 0 8 | 0 9 | 466 10 | 612 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 466 22 | 612 23 | 24 | 25 | 26 | 27 | 466 28 | 612 29 | 30 | 31 | 32 | Nachricht 33 | 34 | 35 | 36 | 37 | 360 38 | 570 39 | 91 40 | 32 41 | 42 | 43 | 44 | Qt::Horizontal 45 | 46 | 47 | QDialogButtonBox::Close 48 | 49 | 50 | 51 | 52 | 53 | 10 54 | 10 55 | 441 56 | 551 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | QFormLayout::AllNonFixedFieldsGrow 66 | 67 | 68 | 69 | 70 | 71 | 75 72 | true 73 | 74 | 75 | 76 | Von: 77 | 78 | 79 | 80 | 81 | 82 | 83 | Mustermann 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 75 92 | true 93 | 94 | 95 | 96 | Datum: 97 | 98 | 99 | 100 | 101 | 102 | 103 | 01.01.2000 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 75 112 | true 113 | 114 | 115 | 116 | Thema: 117 | 118 | 119 | 120 | 121 | 122 | 123 | Musterthema 124 | 125 | 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 139 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 140 | p, li { white-space: pre-wrap; } 141 | </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:7.8pt; font-weight:400; font-style:normal;"> 142 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:12pt;">Musterinhalt</span></p></body></html> 143 | 144 | 145 | 146 | 147 | 148 | true 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | buttonBox 161 | accepted() 162 | message 163 | accept() 164 | 165 | 166 | 248 167 | 254 168 | 169 | 170 | 157 171 | 274 172 | 173 | 174 | 175 | 176 | buttonBox 177 | rejected() 178 | message 179 | reject() 180 | 181 | 182 | 316 183 | 260 184 | 185 | 186 | 286 187 | 274 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /gui/mymainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MyMainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 700 10 | 663 11 | 12 | 13 | 14 | 15 | 700 16 | 0 17 | 18 | 19 | 20 | 21 | 1300 22 | 16777215 23 | 24 | 25 | 26 | Sync-my-L2P 27 | 28 | 29 | 30 | :/icons/magnifier.png:/icons/magnifier.png 31 | 32 | 33 | 34 | 35 | 36 | 37 | 1 38 | 39 | 40 | 41 | 42 | :/icons/browser.png:/icons/browser.png 43 | 44 | 45 | Dateibrowser 46 | 47 | 48 | 49 | 50 | 51 | :/icons/settings.png:/icons/settings.png 52 | 53 | 54 | Einstellungen 55 | 56 | 57 | 58 | 59 | true 60 | 61 | 62 | 63 | :/icons/logs.png:/icons/logs.png 64 | 65 | 66 | Log 67 | 68 | 69 | 70 | 71 | 72 | :/icons/tutorial.png:/icons/tutorial.png 73 | 74 | 75 | Anleitung 76 | 77 | 78 | 79 | 80 | 81 | <html><head/><body><p><span style=" font-size:10pt; font-weight:600;">Willkommen bei Sync-my-L²P!</span></p><p><span style=" font-size:10pt;">In diesem Tab findet sich eine kurze Anleitung für Erstbenutzer dieses Programms.</span></p><p><span style=" font-size:10pt; font-weight:600;">Schnellstart</span></p><p><span style=" font-size:10pt;">Wenn du sofort loslegen willst, führe einfach folgende drei Schritte durch:</span></p><p><span style=" font-size:10pt; text-decoration: underline;">1. Einloggen</span></p><p><span style=" font-size:10pt;">Klicke im Tab &quot;Einstellungen&quot; auf den Knopf auf den Knopf &quot;Einloggen&quot;. Kurz darauf wird sich dein Browser einloggen und du wirst aufgefordert, dich mit deiner Tim-Kennung zu authentifizieren. Danach musst du Sync-my-L²P authorisieren, damit das Programm auf deine Daten im L²P zugreifen kann. Sobald du auch dies erledigt hast, kannst du den Browser schließen und zum Programm zurückkehren.</span></p><p><span style=" font-size:10pt; text-decoration: underline;">2. Daten aktualisieren und auswählen</span></p><p><span style=" font-size:10pt;">Nach dem erfolgreichen Login werden automatisch die Daten aller deiner Kurse im L²P abgerufen. Dies kann einen Moment dauern. Sobald die Aktualisierung fertig ist, kannst du die abgerufenen Daten ansehen und einzelne Dateien/Verzeichnisse/Kurse/Semester von dem Download ausschließen. Auch kannst du Filter für Größe und Änderungsdatum setzen.</span></p><p><span style=" font-size:10pt; text-decoration: underline;">3. Download</span></p><p><span style=" font-size:10pt;">Um nun deine Dateien runterzuladen musst du noch ein Downloadverzeichnis setzen. Hierfür klickst du im Tab &quot;Einstellungen&quot; auf den Knopf &quot;Durchsuchen&quot; und wählst ein Ordner aus. Nun musst du nur noch im Tab &quot;Dateibrowser&quot; auf den Knopf &quot;downloaden&quot; drücken und Sync-my-L²P lädt alle ausgewählten Dateien für dich herrunter.</span></p><p><span style=" font-size:10pt; font-weight:600;">Tips und Tricks</span></p><p><span style=" font-size:10pt;">Die </span><span style=" font-size:10pt; text-decoration: underline;">Farbe der Dateien</span><span style=" font-size:10pt;"> gibt dir Auskunft über den aktuellen Status der Dateien. Rot bedeutet &quot;nicht downloaden&quot;, Schwarz sind neue, nicht runtergeladene Dateien und Grün wird für bereits auf deiner Festplatte vorhandene Dateien benutzt.</span></p><p><span style=" font-size:10pt;">Du kannst durch einen </span><span style=" font-size:10pt; text-decoration: underline;">Doppelklick</span><span style=" font-size:10pt;"> auf Dateien diese einfach öffnen.</span></p><p><span style=" font-size:10pt;">Im Tab </span><span style=" font-size:10pt; text-decoration: underline;">Einstellungen</span><span style=" font-size:10pt;"> finden sich einige Optionen, mit denen du Sync-my-L²P noch komfortabler machen kannst.</span></p></body></html> 82 | 83 | 84 | Qt::AlignJustify|Qt::AlignTop 85 | 86 | 87 | true 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | Browser 102 | QWidget 103 |
browser.h
104 | 1 105 |
106 | 107 | Options 108 | QWidget 109 |
options.h
110 | 1 111 |
112 | 113 | Logger 114 | QWidget 115 |
logger.h
116 | 1 117 |
118 |
119 | 120 | 121 | 122 | 123 |
124 | -------------------------------------------------------------------------------- /icon.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "magnifier.ico" 2 | -------------------------------------------------------------------------------- /icons/Sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/Sync-my-L2P.png -------------------------------------------------------------------------------- /icons/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/about.png -------------------------------------------------------------------------------- /icons/archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/archive.png -------------------------------------------------------------------------------- /icons/audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/audio.png -------------------------------------------------------------------------------- /icons/block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/block.png -------------------------------------------------------------------------------- /icons/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/browser.png -------------------------------------------------------------------------------- /icons/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/check.png -------------------------------------------------------------------------------- /icons/contact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/contact.png -------------------------------------------------------------------------------- /icons/contributors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/contributors.png -------------------------------------------------------------------------------- /icons/course.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/course.png -------------------------------------------------------------------------------- /icons/directory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/directory.png -------------------------------------------------------------------------------- /icons/document.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/document.png -------------------------------------------------------------------------------- /icons/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/download.png -------------------------------------------------------------------------------- /icons/downloadDirectory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/downloadDirectory.png -------------------------------------------------------------------------------- /icons/icons.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | download.png 4 | login.png 5 | magnifier.png 6 | refresh.png 7 | otherFile.png 8 | downloadDirectory.png 9 | logs.png 10 | semester.png 11 | course.png 12 | directory.png 13 | pdf.png 14 | browser.png 15 | settings.png 16 | Sync-my-L2P.png 17 | video.png 18 | slideshow.png 19 | sheet.png 20 | document.png 21 | audio.png 22 | picture.png 23 | archive.png 24 | mail.png 25 | tutorial.png 26 | logout.png 27 | about.png 28 | contact.png 29 | contributors.png 30 | license.png 31 | 32 | 33 | -------------------------------------------------------------------------------- /icons/license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/license.png -------------------------------------------------------------------------------- /icons/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/login.png -------------------------------------------------------------------------------- /icons/logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/logout.png -------------------------------------------------------------------------------- /icons/logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/logs.png -------------------------------------------------------------------------------- /icons/magnifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/magnifier.png -------------------------------------------------------------------------------- /icons/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/mail.png -------------------------------------------------------------------------------- /icons/otherFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/otherFile.png -------------------------------------------------------------------------------- /icons/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/pdf.png -------------------------------------------------------------------------------- /icons/picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/picture.png -------------------------------------------------------------------------------- /icons/refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/refresh.png -------------------------------------------------------------------------------- /icons/semester.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/semester.png -------------------------------------------------------------------------------- /icons/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/settings.png -------------------------------------------------------------------------------- /icons/sheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/sheet.png -------------------------------------------------------------------------------- /icons/slideshow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/slideshow.png -------------------------------------------------------------------------------- /icons/tutorial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/tutorial.png -------------------------------------------------------------------------------- /icons/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/icons/video.png -------------------------------------------------------------------------------- /include/autoclosedialog.h: -------------------------------------------------------------------------------- 1 | #ifndef AUTOCLOSEDIALOG_H 2 | #define AUTOCLOSEDIALOG_H 3 | 4 | #include 5 | #include 6 | 7 | namespace Ui { 8 | class AutoCloseDialog; 9 | } 10 | 11 | class AutoCloseDialog : public QDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit AutoCloseDialog(QWidget *parent = nullptr); 17 | ~AutoCloseDialog(); 18 | 19 | private: 20 | Ui::AutoCloseDialog *ui; 21 | 22 | private slots: 23 | void on_autoClosePushButton_clicked(); 24 | }; 25 | 26 | #endif // AUTOCLOSEDIALOG_H 27 | -------------------------------------------------------------------------------- /include/browser.h: -------------------------------------------------------------------------------- 1 | #ifndef BROWSER_H 2 | #define BROWSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "filedownloader.h" 33 | #include "mysortfilterproxymodel.h" 34 | 35 | #include "autoclosedialog.h" 36 | 37 | #include "parser.h" 38 | #include "utils.h" 39 | 40 | class Options; 41 | class L2pItemModel; 42 | 43 | namespace Ui { 44 | class Browser; 45 | } 46 | 47 | class Browser : public QWidget 48 | { 49 | Q_OBJECT 50 | 51 | public: 52 | explicit Browser(QWidget *parent = nullptr); 53 | ~Browser(); 54 | void init(Options *options); 55 | void loadSettings(); 56 | void saveSettings(); 57 | 58 | public slots: 59 | void on_refreshPushButton_clicked(); 60 | void downloadDirectoryLineEditChangedSlot(QString downloadDirectory); 61 | void clearItemModel(); 62 | void retranslate(); 63 | 64 | signals: 65 | void enableSignal(bool); 66 | void switchTab(int); 67 | void showStatusMessage(QString); 68 | 69 | private: 70 | void removeSelection(Structureelement*); 71 | void addSelection(Structureelement*); 72 | 73 | void getStructureelementsList(Structureelement*, QList&, bool); 74 | void getStructureelementsList(QStandardItem *topElement, QList &list); 75 | 76 | int getFileCount(QList& items); 77 | 78 | void updateButtons(); 79 | void setupSignalsSlots(); 80 | int overrideFilesDialog(QString filename); 81 | QUrl getFileURL(Structureelement* item); 82 | #ifdef _WIN32 83 | static int pathTooLongDialog(QString filename); 84 | #endif 85 | 86 | Ui::Browser *ui; 87 | QNetworkAccessManager *manager; 88 | MySortFilterProxyModel *proxy; 89 | Structureelement *iter; 90 | QFile output; 91 | 92 | Structureelement* lastRightClickItem; 93 | 94 | 95 | 96 | Options *options; 97 | 98 | int refreshCounter = 0; 99 | 100 | L2pItemModel *l2pItemModel; 101 | 102 | private slots: 103 | void openFile(); 104 | void openFile(Structureelement* item); 105 | void openCourse(); 106 | void openCourse(Structureelement* item); 107 | void on_searchPushButton_clicked(); 108 | void on_removeSelectionPushButton_clicked(); 109 | void on_addSelectionPushButton_clicked(); 110 | void on_syncPushButton_clicked(); 111 | void on_openDownloadfolderPushButton_clicked(); 112 | void on_dataTreeView_doubleClicked(const QModelIndex &index); 113 | void on_dataTreeView_customContextMenuRequested(const QPoint &pos); 114 | void on_showNewDataPushButton_clicked(); 115 | void copyUrlToClipboardSlot(); 116 | void copyUrlToClipboardSlot(Structureelement* item); 117 | void successfulLoginSlot(); 118 | void itemModelReloadedSlot(); 119 | }; 120 | 121 | #endif // BROWSER_H 122 | -------------------------------------------------------------------------------- /include/clientId.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENTID_H 2 | #define CLIENTID_H 3 | 4 | 5 | // Achtung: Hier muss eine gültige ClientID für den Zugriff 6 | // auf die API eingetragen werden. 7 | // Eine Veröffentlichung ist ID ist seitens des 8 | // Rechenzentrums untersagt. 9 | #define CLIENTID "INSERT YOUR CLIENT ID HERE" 10 | 11 | // Remove this line after insertion of the client ID 12 | #error ERROR: NO CLIENTID IN CLIENTID.H DEFINED 13 | 14 | #endif // CLIENTID_H 15 | -------------------------------------------------------------------------------- /include/filedownloader.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #ifndef DATEIDOWNLOADER_H 19 | #define DATEIDOWNLOADER_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "utils.h" 34 | #include 35 | 36 | #ifdef _WIN32 37 | #include 38 | #else 39 | #include 40 | #endif 41 | 42 | namespace Ui { 43 | class DateiDownloader; 44 | } 45 | 46 | class FileDownloader : public QDialog 47 | { 48 | Q_OBJECT 49 | 50 | public: 51 | explicit FileDownloader(int itemNumber, 52 | QWidget *parent= nullptr); 53 | ~FileDownloader(); 54 | int startNextDownload(QString, QString, QString, QUrl, int, int, int time); 55 | 56 | private: 57 | void keyPressEvent(QKeyEvent *); 58 | Ui::DateiDownloader *ui; 59 | QNetworkAccessManager* manager; 60 | QNetworkReply* reply; 61 | 62 | QEventLoop loop; 63 | 64 | int itemNumber; 65 | bool originalModifiedDate; 66 | 67 | QFile output; 68 | utimbuf times; 69 | 70 | QString correctUnit(qint64 bytes); 71 | double correctSize(qint64 bytes); 72 | 73 | QElapsedTimer downloadTime; 74 | 75 | bool showedError; 76 | 77 | private slots: 78 | void downloadProgressSlot(qint64,qint64); 79 | void readyReadSlot(); 80 | void finishedSlot(); 81 | void on_abortPushButton_clicked(); 82 | }; 83 | 84 | #endif // DATEIDOWNLOADER_H 85 | -------------------------------------------------------------------------------- /include/info.h: -------------------------------------------------------------------------------- 1 | #ifndef INFO_H 2 | #define INFO_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class Info; 8 | } 9 | 10 | class Info : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit Info(QWidget *parent = nullptr); 16 | ~Info(); 17 | 18 | private: 19 | Ui::Info *ui; 20 | 21 | }; 22 | 23 | #endif // LOGINDIALOG_H 24 | -------------------------------------------------------------------------------- /include/l2pitemmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef L2PITEMMODEL_H 2 | #define L2PITEMMODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "parser.h" 26 | #include "utils.h" 27 | #include "options.h" 28 | 29 | #define DATAFILENAME "data.xml" 30 | 31 | class L2pItemModel : public QObject 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | L2pItemModel(); 37 | ~L2pItemModel(); 38 | 39 | const QStandardItemModel *getData() const { return data; } 40 | MySortFilterProxyModel *getProxy() { return &proxy; } 41 | 42 | void setOptions(Options* options) { this->options = options; } 43 | void loadDataFromFile(); 44 | void saveDataToFile(); 45 | 46 | public slots: 47 | void loadDataFromServer(); 48 | 49 | signals: 50 | void loadingFinished(bool successful); 51 | void showStatusMessage(QString); 52 | 53 | protected: 54 | void parseDataFromXml(QDomElement input, QStandardItem *parentItem); 55 | void parseDataToXml(QDomDocument &output, QStandardItem *item, QDomElement *parentItem); 56 | void addMoodleCoursesFromReply(QNetworkReply* reply); 57 | void addMoodleFilesFromReply(QNetworkReply* reply, Structureelement *course); 58 | void getItemList(QStandardItem *topElement, QList &list); 59 | void requestMoodleCourses(); 60 | void requestMoodleFiles(); 61 | void startNextRequests(); 62 | 63 | QStandardItemModel *data = new QStandardItemModel(); 64 | QStandardItemModel *oldData = nullptr; 65 | 66 | MySortFilterProxyModel proxy; 67 | 68 | enum Type 69 | { 70 | moodleCourses, 71 | moodleFiles 72 | }; 73 | 74 | struct ReplyInfo 75 | { 76 | Structureelement *item; 77 | 78 | Type type; 79 | 80 | QTime timeStart; 81 | }; 82 | 83 | struct OpenRequest 84 | { 85 | Structureelement *item; 86 | 87 | Type type; 88 | 89 | QTime timeStart; 90 | 91 | QNetworkRequest request; 92 | }; 93 | 94 | QNetworkAccessManager manager; 95 | QMap replies; 96 | QList requestQueue; 97 | Options *options = nullptr; 98 | int numRequests = 0; 99 | 100 | protected slots: 101 | void serverDataRecievedSlot(QNetworkReply *reply); 102 | }; 103 | 104 | #endif // L2PITEMMODEL_H 105 | -------------------------------------------------------------------------------- /include/logger.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGER_H 2 | #define LOGGER_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class Logger; 8 | } 9 | 10 | class Logger : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit Logger(QWidget *parent = nullptr); 16 | ~Logger(); 17 | 18 | void saveSettings(); 19 | 20 | void loadSettings(); 21 | 22 | public slots: 23 | void retranslate(); 24 | 25 | private slots: 26 | void logSlot(QString message, int level); 27 | 28 | void on_logLevelCB_currentIndexChanged(const QString &logLevel); 29 | 30 | void on_savePB_clicked(); 31 | 32 | void on_copyPB_clicked(); 33 | 34 | private: 35 | QString getLogText(); 36 | 37 | Ui::Logger *ui; 38 | }; 39 | 40 | #endif // LOGGER_H 41 | -------------------------------------------------------------------------------- /include/login.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGIN_H 2 | #define LOGIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class Login: public QObject 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit Login(QWidget *parent = nullptr); 17 | 18 | bool isRefreshTokenAvailable() { return !refreshToken.isEmpty(); } 19 | void init(); 20 | void saveAccessToken(); 21 | 22 | signals: 23 | void newAccessToken(QString accessToken); 24 | void loginFailed(); 25 | 26 | public slots: 27 | void getAccess(); 28 | void stopLoginSlot(); 29 | void deleteAccess(); 30 | void getTokenInfo(); 31 | 32 | private: 33 | void postRequest(QUrlQuery &query, QUrl url); 34 | 35 | 36 | QNetworkAccessManager manager; 37 | 38 | QJsonObject verification; 39 | 40 | QString refreshToken; 41 | QString accessToken; 42 | 43 | bool stopLogin; 44 | QTimer stopLoginTimer; 45 | 46 | bool settingsLoaded; 47 | 48 | private slots: 49 | void finishedSlot(QNetworkReply *reply); 50 | void checkForVerification(); 51 | void refreshAccess(); 52 | void getUserCode(); 53 | }; 54 | 55 | #endif // LOGIN_H 56 | -------------------------------------------------------------------------------- /include/logindialog.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGINDIALOG_H 2 | #define LOGINDIALOG_H 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "login.h" 9 | 10 | enum Availability { 11 | NOTTESTED, 12 | AVAILABLE, 13 | NOTAVAILABLE 14 | }; 15 | 16 | namespace Ui { 17 | class LoginDialog; 18 | } 19 | 20 | class LoginDialog : public QDialog 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit LoginDialog(QWidget *parent = nullptr); 26 | ~LoginDialog(); 27 | 28 | public slots: 29 | void run(Login *login); 30 | 31 | private slots: 32 | //void checkL2PAvailability(); /// deprecated 33 | void checkMoodleAvailability(); 34 | //void availabilityL2PSlot(QNetworkReply*); /// deprecated 35 | void availabilityMoodleSlot(QNetworkReply*); 36 | void failedSlot(); 37 | void succededSlot(); 38 | 39 | private: 40 | void checkForAuthentification(); 41 | 42 | Ui::LoginDialog *ui; 43 | QNetworkAccessManager manager; 44 | 45 | // Pointer to Class responsible for the login 46 | Login *login; 47 | Availability moodleAvailable; 48 | }; 49 | 50 | #endif // LOGINDIALOG_H 51 | -------------------------------------------------------------------------------- /include/mymainwindow.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #ifndef HAUPTFENSTER_H 19 | #define HAUPTFENSTER_H 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "browser.h" 28 | 29 | namespace Ui { 30 | class MyMainWindow; 31 | } 32 | 33 | class MyMainWindow : public QMainWindow 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | explicit MyMainWindow(QWidget *parent = nullptr); 39 | void closeEvent(QCloseEvent * event); 40 | 41 | private slots: 42 | void trayClickedSlot(QSystemTrayIcon::ActivationReason); 43 | void on_langCB_currentIndexChanged(const int &lang); 44 | void showStatusMessage(QString msg); 45 | void retranslate(); 46 | void closeTask(); 47 | 48 | private: 49 | void init(); 50 | 51 | void changeEvent(QEvent *); 52 | 53 | void createTrayIcon(); 54 | 55 | void loadSettings(); 56 | void saveSettings(); 57 | void removeOldSettings(); 58 | 59 | void centerOnDesktop(); 60 | 61 | void checkForUpdate(); 62 | 63 | QSystemTrayIcon *trayIcon; 64 | Ui::MyMainWindow* ui; 65 | 66 | QTranslator m_translator; 67 | }; 68 | 69 | #endif // HAUPTFENSTER_H 70 | -------------------------------------------------------------------------------- /include/mysortfilterproxymodel.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #ifndef MYSORTFILTERPROXYMODEL_H 19 | #define MYSORTFILTERPROXYMODEL_H 20 | 21 | #include 22 | #include 23 | #include "structureelement.h" 24 | 25 | class MySortFilterProxyModel : public QSortFilterProxyModel 26 | { 27 | Q_OBJECT 28 | 29 | public: 30 | MySortFilterProxyModel(QObject *parent = nullptr); 31 | 32 | public slots: 33 | QDate filterMinimumDate() const { return minDate; } 34 | void setFilterMinimumDate(const QDate &date); 35 | 36 | QDate filterMaximumDate() const { return maxDate; } 37 | void setFilterMaximumDate(const QDate &date); 38 | 39 | void setInRangeDateFilter(const bool filter); 40 | 41 | qint32 filterMaximumSize() const { return maxSize; } 42 | void setMaximumSize(const int size); 43 | 44 | void setMaximumSizeFilter(const bool filter); 45 | 46 | protected: 47 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; 48 | // bool lessThan(const QModelIndex &left, const QModelIndex &right) const; 49 | 50 | private: 51 | bool dateInRange(const QDate &date) const; 52 | bool sizeInRange(const qint32 size) const; 53 | 54 | qint32 maxSize; 55 | bool maxSizeFilter; 56 | 57 | QDate minDate; 58 | QDate maxDate; 59 | bool dateFilter; 60 | }; 61 | 62 | #endif // MYSORTFILTERPROXYMODEL_H 63 | -------------------------------------------------------------------------------- /include/options.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTIONS_H 2 | #define OPTIONS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "login.h" 12 | 13 | // macro for converting enum to int 14 | #define ETOI(e) (static_cast(e)) 15 | 16 | class Browser; 17 | 18 | namespace Ui { 19 | class Options; 20 | } 21 | 22 | class Options : public QWidget 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | explicit Options(QWidget *parent = nullptr); 28 | ~Options(); 29 | void loadSettings(); 30 | void saveSettings(); 31 | 32 | // Setting enums 33 | enum class language {sys=0,de,en,lb,sq}; 34 | enum class longPaths {ask=0,download,skip}; 35 | enum class overrideFiles {ask=0,override,skip}; 36 | 37 | // Getter 38 | bool isUserDataSaveCheckBoxChecked(); 39 | bool isAutoLoginOnStartCheckBoxChecked(); 40 | bool isAutoSyncOnStartCheckBoxChecked(); 41 | bool isMinimizeInTrayCheckBoxChecked(); 42 | bool isAutoCloseAfterSyncCheckBoxChecked(); 43 | bool isAutoBackgroundSyncCheckBoxChecked(); 44 | bool isOverrideFilesCheckBoxChecked(); 45 | bool isCheckForUpdateCheckBoxChecked(); 46 | bool isCurrentSemesterCheckBoxChecked(); 47 | bool isTutorDomainCheckBoxChecked(); 48 | longPaths getLongPathsSetting(); 49 | overrideFiles getOverrideFilesSetting(); 50 | 51 | QString getAccessToken() const; 52 | 53 | int getLoginCounter(); 54 | 55 | QString downloadFolderLineEditText(); 56 | 57 | void init(Browser *browser); 58 | 59 | signals: 60 | void enableSignal(bool); 61 | void switchTab(int); 62 | void downloadFolderLineEditTextChanged(const QString text); 63 | void successfulLogin(); 64 | 65 | public slots: 66 | void on_loginPushButton_clicked(); 67 | void retranslate(); 68 | void on_aboutButton_clicked(); 69 | 70 | private: 71 | Ui::Options *ui; 72 | 73 | Browser *browser; 74 | 75 | // Zählvariable für jeden Loginversuch 76 | int loginCounter; 77 | 78 | Login login; 79 | 80 | QString accessToken; 81 | 82 | private slots: 83 | void on_userDataSaveCheckBox_stateChanged(int); 84 | void on_downloadFolderPushButton_clicked(); 85 | void on_autoLoginOnStartCheckBox_stateChanged(int arg1); 86 | void on_downloadFolderlineEdit_textChanged(const QString); 87 | void on_loginErasePushButton_clicked(); 88 | void loginResultSlot(int result); 89 | void accessTokenChanged(QString newAccessToken); 90 | }; 91 | 92 | #endif // OPTIONS_H 93 | -------------------------------------------------------------------------------- /include/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef PARSER_H 2 | #define PARSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "structureelement.h" 8 | #include 9 | #include 10 | #include 11 | #include "mymainwindow.h" 12 | #include "utils.h" 13 | 14 | class Parser : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | static void parseMoodleCourses(QNetworkReply *reply, QStandardItemModel *itemModel); 20 | static void parseMoodleFiles(QNetworkReply *reply, Structureelement *course); 21 | static QString escapeString(QString title); 22 | }; 23 | 24 | #endif // PARSER_H 25 | -------------------------------------------------------------------------------- /include/structureelement.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #ifndef STRUKTURELEMENT_H 19 | #define STRUKTURELEMENT_H 20 | #include 21 | #include 22 | #include 23 | 24 | enum MyItemSystem 25 | { 26 | l2p = 100, 27 | moodle = 101 28 | }; 29 | 30 | enum MyItemType 31 | { 32 | semesterItem = 1000, 33 | courseItem = 1001, 34 | directoryItem = 1002, 35 | fileItem = 1003, 36 | messageItem = 1004 37 | }; 38 | 39 | enum MyItemDataRole 40 | { 41 | sizeRole = 32, 42 | urlRole = 33, 43 | dateRole = 34, 44 | includeRole = 35, 45 | synchronisedRole = 36, 46 | cidRole = 37, 47 | bodyRole = 38, 48 | topicRole = 39, 49 | authorRole = 40, 50 | typeEXRole = 41, 51 | systemEXRole = 42 52 | }; 53 | 54 | enum synchroniseStatus 55 | { 56 | NOT_SYNCHRONISED = 0, 57 | SYNCHRONISED = 1, 58 | NOW_SYNCHRONISED = 2 59 | 60 | }; 61 | 62 | class Structureelement : public QStandardItem 63 | { 64 | public: 65 | Structureelement(QString name, QUrl url = QUrl(), int time = 0, qint32 size = 0, QString cid = "", MyItemType typeEX = fileItem, MyItemSystem systemEX = l2p); 66 | 67 | Structureelement(QString body, QString topic, QString author, int time = 0, QString cid = "", MyItemType typeEX = messageItem, MyItemSystem systemEX = l2p); 68 | 69 | int type() const { return typeEX; } 70 | 71 | bool operator< (const QStandardItem& other) const; 72 | 73 | void setData(const QVariant &value, int role = Qt::UserRole + 1 ); 74 | QVariant data(int role = Qt::UserRole + 1) const; 75 | 76 | protected: 77 | /// Größe des Elements in Bytes 78 | qint32 size; 79 | 80 | /// Ob die Datei in den Download eingebunden wird 81 | bool included; 82 | 83 | /// Url für die API 84 | QUrl url; 85 | 86 | /// Veranstaltungs ID 87 | QString cid; 88 | 89 | /// Änderungsdatum 90 | QDateTime time; 91 | 92 | /// Inhalt der Nachricht 93 | QString body; 94 | 95 | /// Thema der Nachricht 96 | QString topic; 97 | 98 | /// Autor der Nachricht 99 | QString author; 100 | 101 | /// Type des Elements 102 | MyItemType typeEX; 103 | 104 | /// System des Elements 105 | MyItemSystem systemEX; 106 | 107 | /// Status der Synchronisation 108 | enum synchroniseStatus synchronised; 109 | 110 | // Neuer Bereich für die Nachrichten 111 | 112 | private: 113 | void chooseIcon(); 114 | }; 115 | 116 | #endif // STRUKTURELEMENT_H 117 | -------------------------------------------------------------------------------- /include/urls.h: -------------------------------------------------------------------------------- 1 | #ifndef URLS 2 | #define URLS 3 | 4 | #include 5 | 6 | const QString releaseUrl = "https://github.com/rwthmoodle/Sync-my-L2P/releases"; 7 | const QString appUpdateUrl = "https://app.rwth-aachen.de/syncmyl2p/version.txt"; 8 | const QString moodleApiDomain = "https://moped.ecampus.rwth-aachen.de/"; 9 | const QString moodleApiUrlBase = moodleApiDomain + "proxy/api/v2/"; 10 | const QString moodleApiDocs = moodleApiUrlBase + "Documentation"; 11 | const QString moodleApiUrl = moodleApiUrlBase + "eLearning/Moodle/"; 12 | const QString moodleGetMyEnrolledCoursesUrl = moodleApiUrl + "getmyenrolledcourses"; 13 | const QString moodleGetFilesUrl = moodleApiUrl + "getfiles"; 14 | const QString moodleDownloadFileUrl = moodleApiUrl + "downloadfile"; 15 | 16 | #endif // URLS 17 | 18 | -------------------------------------------------------------------------------- /include/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | 4 | #include 5 | #include "structureelement.h" 6 | 7 | class Utils : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | 12 | static Structureelement *getParentCourse(Structureelement *item); 13 | static QString getElementLocalPath(Structureelement* item, QString path, bool includeFilname = true, bool includePrefix = true); 14 | static QString getElementRemotePath(Structureelement* item); 15 | static void copyTextToClipboard(QString text); 16 | static void errorMessageBox(QString message, QString detailMessage); 17 | 18 | static QList getAllCourseItems(QStandardItemModel* itemModel); 19 | static Structureelement *getSemesterItem(QStandardItemModel *itemModel, QString semester); 20 | 21 | static Structureelement *getDirectoryItem(Structureelement *courseItem, QStringList path); 22 | 23 | static void centerWidgetOnDesktop(QWidget* widget); 24 | 25 | static void checkAllFilesIfSynchronised(QList items, QString downloadDirectory); 26 | 27 | static bool longPathsSupported(); 28 | private: 29 | explicit Utils(QObject *parent = nullptr); 30 | 31 | }; 32 | 33 | #endif // UTILS_H 34 | -------------------------------------------------------------------------------- /include/version.h.template: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | #define PRODUCT_VERSION_CODE __PRODUCT_VERSION_CODE 5 | #define PRODUCT_VERSION "__PRODUCT_VERSION" 6 | 7 | #endif // VERSION_H 8 | -------------------------------------------------------------------------------- /lang/sync-my-l2p_de.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/lang/sync-my-l2p_de.qm -------------------------------------------------------------------------------- /lang/sync-my-l2p_en.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/lang/sync-my-l2p_en.qm -------------------------------------------------------------------------------- /lang/sync-my-l2p_lb.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/lang/sync-my-l2p_lb.qm -------------------------------------------------------------------------------- /lang/sync-my-l2p_sq.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/lang/sync-my-l2p_sq.qm -------------------------------------------------------------------------------- /lang/translation.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | sync-my-l2p_de.qm 4 | sync-my-l2p_en.qm 5 | sync-my-l2p_lb.qm 6 | sync-my-l2p_sq.qm 7 | 8 | 9 | -------------------------------------------------------------------------------- /linux/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get update && apt-get install -y libssl-dev git build-essential wget file software-properties-common libgl1-mesa-dev 4 | RUN add-apt-repository ppa:beineri/opt-qt-5.11.1-xenial && apt-get update && apt-get install -y qt511-meta-full 5 | RUN echo "/opt/qt511/bin\n/opt/qt511/lib" > /etc/xdg/qtchooser/default.conf 6 | RUN mkdir /work 7 | WORKDIR /work 8 | COPY . /work 9 | RUN mkdir /res 10 | ENV PATH="${PATH}:/opt/qt511/bin" 11 | RUN qmake DESTDIR=/res -o syncmyl2p.mk 12 | RUN make -j4 -f syncmyl2p.mk 13 | RUN bash linux/create_appimage.sh -------------------------------------------------------------------------------- /linux/Sync-my-L2P.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Sync-my-L2P 3 | Comment=Sync-my-L2P — L2P synchronisation tool 4 | Comment[de]=Sync-my-L2P – Synchronsiert deine Dokumente aus dem L2P mit deinem Rechner 5 | Exec=Sync-my-L2P 6 | Icon=sync-my-L2P 7 | Terminal=false 8 | Type=Application 9 | Categories=Qt;FileTransfer;Network; 10 | -------------------------------------------------------------------------------- /linux/create_appimage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd linux 3 | wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage 4 | wget http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu52_52.1-3ubuntu0.8_amd64.deb 5 | dpkg -i libicu52_52.1-3ubuntu0.8_amd64.deb 6 | dos2unix Sync-my-L2P.desktop 7 | chmod a+x ./linuxdeployqt-continuous-x86_64.AppImage 8 | ./linuxdeployqt-continuous-x86_64.AppImage --appimage-extract 9 | export PATH=/work/linux/squashfs-root/usr/bin/:$PATH 10 | mkdir -p usr/bin 11 | cp ../bin/Sync-my-L2P ./usr/bin/Sync-my-L2P 12 | squashfs-root/AppRun ./usr/bin/Sync-my-L2P -verbose=1 -appimage 13 | 14 | -------------------------------------------------------------------------------- /linux/hicolor/128x128/apps/sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/hicolor/128x128/apps/sync-my-L2P.png -------------------------------------------------------------------------------- /linux/hicolor/16x16/apps/sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/hicolor/16x16/apps/sync-my-L2P.png -------------------------------------------------------------------------------- /linux/hicolor/32x32/apps/sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/hicolor/32x32/apps/sync-my-L2P.png -------------------------------------------------------------------------------- /linux/hicolor/48x48/apps/sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/hicolor/48x48/apps/sync-my-L2P.png -------------------------------------------------------------------------------- /linux/lib/Readme.md: -------------------------------------------------------------------------------- 1 | These files are needed for building with qt5.15 on Ubuntu 18.04. Since they are not there on GitHub Actions buildservers, we built them manually and checked them in. 2 | 3 | ## Build 4 | Here's how to build these libraries: 5 | ```bash 6 | sudo apt install gcc g++ build-essential 7 | cd /tmp 8 | wget https://github.com/unicode-org/icu/releases/download/release-56-2/icu4c-56_2-src.tgz 9 | tar xzf ./icu4c-56_2-src.tgz 10 | cd icu/source 11 | ./configure 12 | make 13 | ``` 14 | -------------------------------------------------------------------------------- /linux/lib/libicudata.so.56: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/lib/libicudata.so.56 -------------------------------------------------------------------------------- /linux/lib/libicui18n.so.56: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/lib/libicui18n.so.56 -------------------------------------------------------------------------------- /linux/lib/libicuuc.so.56: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/lib/libicuuc.so.56 -------------------------------------------------------------------------------- /linux/run.bat: -------------------------------------------------------------------------------- 1 | docker build -t syncmyl2p -f linux/Dockerfile . 2 | docker run -it --rm -v %cd%:/trans syncmyl2p sh -c "mv /work/linux/Sync*.AppImage /trans/" -------------------------------------------------------------------------------- /linux/run.sh: -------------------------------------------------------------------------------- 1 | docker build -t syncmyl2p -f linux/Dockerfile . 2 | docker run -it --rm -v %cd%:/trans syncmyl2p bash -------------------------------------------------------------------------------- /linux/sync-my-L2P.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/linux/sync-my-L2P.png -------------------------------------------------------------------------------- /magnifier.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/magnifier.ico -------------------------------------------------------------------------------- /qslog/.gitignore: -------------------------------------------------------------------------------- 1 | *.pro.user 2 | build-* 3 | -------------------------------------------------------------------------------- /qslog/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Razvan Petru 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, this 10 | list of conditions and the following disclaimer in the documentation and/or other 11 | materials provided with the distribution. 12 | * The name of the contributors may not be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /qslog/QsLog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "QsLog.h" 27 | #include "QsLogDest.h" 28 | #ifdef QS_LOG_SEPARATE_THREAD 29 | #include 30 | #include 31 | #endif 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | namespace QsLogging 41 | { 42 | typedef QVector DestinationList; 43 | 44 | static const char TraceString[] = "TRACE"; 45 | static const char DebugString[] = "DEBUG"; 46 | static const char InfoString[] = "INFO "; 47 | static const char WarnString[] = "WARN "; 48 | static const char ErrorString[] = "ERROR"; 49 | static const char FatalString[] = "FATAL"; 50 | 51 | // not using Qt::ISODate because we need the milliseconds too 52 | static const QString fmtDateTime("hh:mm:ss.zzz"); 53 | 54 | static Logger* sInstance = 0; 55 | 56 | static const char* LevelToText(Level theLevel) 57 | { 58 | switch (theLevel) { 59 | case TraceLevel: 60 | return TraceString; 61 | case DebugLevel: 62 | return DebugString; 63 | case InfoLevel: 64 | return InfoString; 65 | case WarnLevel: 66 | return WarnString; 67 | case ErrorLevel: 68 | return ErrorString; 69 | case FatalLevel: 70 | return FatalString; 71 | case OffLevel: 72 | return ""; 73 | default: { 74 | assert(!"bad log level"); 75 | return InfoString; 76 | } 77 | } 78 | } 79 | 80 | #ifdef QS_LOG_SEPARATE_THREAD 81 | class LogWriterRunnable : public QRunnable 82 | { 83 | public: 84 | LogWriterRunnable(QString message, Level level); 85 | virtual void run(); 86 | 87 | private: 88 | QString mMessage; 89 | Level mLevel; 90 | }; 91 | #endif 92 | 93 | class LoggerImpl 94 | { 95 | public: 96 | LoggerImpl(); 97 | 98 | #ifdef QS_LOG_SEPARATE_THREAD 99 | QThreadPool threadPool; 100 | #endif 101 | QMutex logMutex; 102 | Level level; 103 | DestinationList destList; 104 | }; 105 | 106 | #ifdef QS_LOG_SEPARATE_THREAD 107 | LogWriterRunnable::LogWriterRunnable(QString message, Level level) 108 | : QRunnable() 109 | , mMessage(message) 110 | , mLevel(level) 111 | { 112 | } 113 | 114 | void LogWriterRunnable::run() 115 | { 116 | Logger::instance().write(mMessage, mLevel); 117 | } 118 | #endif 119 | 120 | 121 | LoggerImpl::LoggerImpl() 122 | : level(InfoLevel) 123 | { 124 | // assume at least file + console 125 | destList.reserve(2); 126 | #ifdef QS_LOG_SEPARATE_THREAD 127 | threadPool.setMaxThreadCount(1); 128 | threadPool.setExpiryTimeout(-1); 129 | #endif 130 | } 131 | 132 | 133 | Logger::Logger() 134 | : d(new LoggerImpl) 135 | { 136 | } 137 | 138 | Logger& Logger::instance() 139 | { 140 | if (!sInstance) 141 | sInstance = new Logger; 142 | 143 | return *sInstance; 144 | } 145 | 146 | void Logger::destroyInstance() 147 | { 148 | delete sInstance; 149 | sInstance = 0; 150 | } 151 | 152 | // tries to extract the level from a string log message. If available, conversionSucceeded will 153 | // contain the conversion result. 154 | Level Logger::levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded) 155 | { 156 | if (conversionSucceeded) 157 | *conversionSucceeded = true; 158 | 159 | if (logMessage.startsWith(QLatin1String(TraceString))) 160 | return TraceLevel; 161 | if (logMessage.startsWith(QLatin1String(DebugString))) 162 | return DebugLevel; 163 | if (logMessage.startsWith(QLatin1String(InfoString))) 164 | return InfoLevel; 165 | if (logMessage.startsWith(QLatin1String(WarnString))) 166 | return WarnLevel; 167 | if (logMessage.startsWith(QLatin1String(ErrorString))) 168 | return ErrorLevel; 169 | if (logMessage.startsWith(QLatin1String(FatalString))) 170 | return FatalLevel; 171 | 172 | if (conversionSucceeded) 173 | *conversionSucceeded = false; 174 | return OffLevel; 175 | } 176 | 177 | Logger::~Logger() 178 | { 179 | #ifdef QS_LOG_SEPARATE_THREAD 180 | d->threadPool.waitForDone(); 181 | #endif 182 | delete d; 183 | d = 0; 184 | } 185 | 186 | void Logger::addDestination(DestinationPtr destination) 187 | { 188 | assert(destination.data()); 189 | d->destList.push_back(destination); 190 | } 191 | 192 | void Logger::setLoggingLevel(Level newLevel) 193 | { 194 | d->level = newLevel; 195 | } 196 | 197 | Level Logger::loggingLevel() const 198 | { 199 | return d->level; 200 | } 201 | 202 | //! creates the complete log message and passes it to the logger 203 | void Logger::Helper::writeToLog() 204 | { 205 | const char* const levelName = LevelToText(level); 206 | const QString completeMessage(QString("%1 %2 %3") 207 | .arg(levelName) 208 | .arg(QDateTime::currentDateTime().toString(fmtDateTime)) 209 | .arg(buffer) 210 | ); 211 | 212 | Logger::instance().enqueueWrite(completeMessage, level); 213 | } 214 | 215 | Logger::Helper::~Helper() 216 | { 217 | try { 218 | writeToLog(); 219 | } 220 | catch(std::exception&) { 221 | // you shouldn't throw exceptions from a sink 222 | assert(!"exception in logger helper destructor"); 223 | throw; 224 | } 225 | } 226 | 227 | //! directs the message to the task queue or writes it directly 228 | void Logger::enqueueWrite(const QString& message, Level level) 229 | { 230 | #ifdef QS_LOG_SEPARATE_THREAD 231 | LogWriterRunnable *r = new LogWriterRunnable(message, level); 232 | d->threadPool.start(r); 233 | #else 234 | write(message, level); 235 | #endif 236 | } 237 | 238 | //! Sends the message to all the destinations. The level for this message is passed in case 239 | //! it's useful for processing in the destination. 240 | void Logger::write(const QString& message, Level level) 241 | { 242 | QMutexLocker lock(&d->logMutex); 243 | for (DestinationList::iterator it = d->destList.begin(), 244 | endIt = d->destList.end();it != endIt;++it) { 245 | (*it)->write(message, level); 246 | } 247 | } 248 | 249 | } // end namespace 250 | -------------------------------------------------------------------------------- /qslog/QsLog.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef QSLOG_H 27 | #define QSLOG_H 28 | 29 | #include "QsLogLevel.h" 30 | #include "QsLogDest.h" 31 | #include 32 | #include 33 | 34 | #define QS_LOG_VERSION "2.0b3" 35 | 36 | namespace QsLogging 37 | { 38 | class Destination; 39 | class LoggerImpl; // d pointer 40 | 41 | class QSLOG_SHARED_OBJECT Logger 42 | { 43 | public: 44 | static Logger& instance(); 45 | static void destroyInstance(); 46 | static Level levelFromLogMessage(const QString& logMessage, bool* conversionSucceeded = 0); 47 | 48 | ~Logger(); 49 | 50 | //! Adds a log message destination. Don't add null destinations. 51 | void addDestination(DestinationPtr destination); 52 | //! Logging at a level < 'newLevel' will be ignored 53 | void setLoggingLevel(Level newLevel); 54 | //! The default level is INFO 55 | Level loggingLevel() const; 56 | 57 | //! The helper forwards the streaming to QDebug and builds the final 58 | //! log message. 59 | class QSLOG_SHARED_OBJECT Helper 60 | { 61 | public: 62 | explicit Helper(Level logLevel) : 63 | level(logLevel), 64 | qtDebug(&buffer) {} 65 | ~Helper(); 66 | #if QT_VERSION >= 0x050400 67 | QDebug& stream(){ return qtDebug.noquote(); } 68 | #else 69 | QDebug& stream(){ return qtDebug; } 70 | #endif 71 | 72 | private: 73 | void writeToLog(); 74 | 75 | Level level; 76 | QString buffer; 77 | QDebug qtDebug; 78 | }; 79 | 80 | private: 81 | Logger(); 82 | Logger(const Logger&); // not available 83 | Logger& operator=(const Logger&); // not available 84 | 85 | void enqueueWrite(const QString& message, Level level); 86 | void write(const QString& message, Level level); 87 | 88 | LoggerImpl* d; 89 | 90 | friend class LogWriterRunnable; 91 | }; 92 | 93 | } // end namespace 94 | 95 | //! Logging macros: define QS_LOG_LINE_NUMBERS to get the file and line number 96 | //! in the log output. 97 | #ifndef QS_LOG_LINE_NUMBERS 98 | #define QLOG_TRACE() \ 99 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::TraceLevel) {} \ 100 | else QsLogging::Logger::Helper(QsLogging::TraceLevel).stream() 101 | #define QLOG_DEBUG() \ 102 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::DebugLevel) {} \ 103 | else QsLogging::Logger::Helper(QsLogging::DebugLevel).stream() 104 | #define QLOG_INFO() \ 105 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::InfoLevel) {} \ 106 | else QsLogging::Logger::Helper(QsLogging::InfoLevel).stream() 107 | #define QLOG_WARN() \ 108 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::WarnLevel) {} \ 109 | else QsLogging::Logger::Helper(QsLogging::WarnLevel).stream() 110 | #define QLOG_ERROR() \ 111 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::ErrorLevel) {} \ 112 | else QsLogging::Logger::Helper(QsLogging::ErrorLevel).stream() 113 | #define QLOG_FATAL() \ 114 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::FatalLevel) {} \ 115 | else QsLogging::Logger::Helper(QsLogging::FatalLevel).stream() 116 | #else 117 | #define QLOG_TRACE() \ 118 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::TraceLevel) {} \ 119 | else QsLogging::Logger::Helper(QsLogging::TraceLevel).stream() << __FILE__ << '@' << __LINE__ 120 | #define QLOG_DEBUG() \ 121 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::DebugLevel) {} \ 122 | else QsLogging::Logger::Helper(QsLogging::DebugLevel).stream() << __FILE__ << '@' << __LINE__ 123 | #define QLOG_INFO() \ 124 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::InfoLevel) {} \ 125 | else QsLogging::Logger::Helper(QsLogging::InfoLevel).stream() << __FILE__ << '@' << __LINE__ 126 | #define QLOG_WARN() \ 127 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::WarnLevel) {} \ 128 | else QsLogging::Logger::Helper(QsLogging::WarnLevel).stream() << __FILE__ << '@' << __LINE__ 129 | #define QLOG_ERROR() \ 130 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::ErrorLevel) {} \ 131 | else QsLogging::Logger::Helper(QsLogging::ErrorLevel).stream() << __FILE__ << '@' << __LINE__ 132 | #define QLOG_FATAL() \ 133 | if (QsLogging::Logger::instance().loggingLevel() > QsLogging::FatalLevel) {} \ 134 | else QsLogging::Logger::Helper(QsLogging::FatalLevel).stream() << __FILE__ << '@' << __LINE__ 135 | #endif 136 | 137 | #ifdef QS_LOG_DISABLE 138 | #include "QsLogDisableForThisFile.h" 139 | #endif 140 | 141 | #endif // QSLOG_H 142 | -------------------------------------------------------------------------------- /qslog/QsLog.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | #DEFINES += QS_LOG_LINE_NUMBERS # automatically writes the file and line for each log message 3 | #DEFINES += QS_LOG_DISABLE # logging code is replaced with a no-op 4 | #DEFINES += QS_LOG_SEPARATE_THREAD # messages are queued and written from a separate thread 5 | SOURCES += $$PWD/QsLogDest.cpp \ 6 | $$PWD/QsLog.cpp \ 7 | $$PWD/QsLogDestConsole.cpp \ 8 | $$PWD/QsLogDestFile.cpp \ 9 | $$PWD/QsLogDestFunctor.cpp 10 | 11 | HEADERS += $$PWD/QsLogDest.h \ 12 | $$PWD/QsLog.h \ 13 | $$PWD/QsLogDestConsole.h \ 14 | $$PWD/QsLogLevel.h \ 15 | $$PWD/QsLogDestFile.h \ 16 | $$PWD/QsLogDisableForThisFile.h \ 17 | $$PWD/QsLogDestFunctor.h 18 | 19 | OTHER_FILES += \ 20 | $$PWD/QsLogChanges.txt \ 21 | $$PWD/QsLogReadme.txt \ 22 | $$PWD/LICENSE.txt 23 | -------------------------------------------------------------------------------- /qslog/QsLogChanges.txt: -------------------------------------------------------------------------------- 1 | ------------------- 2 | QsLog version 2.0b4 3 | Fixes: 4 | Fixed file name case error for Linux. 5 | 6 | Misc: 7 | * Moved to separate git repository. 8 | 9 | ------------------- 10 | QsLog version 2.0b3 11 | 12 | Changes: 13 | * added functor logging destination (thanks to Omar Carey for providing a patch) 14 | 15 | ------------------- 16 | QsLog version 2.0b2 17 | 18 | Changes: 19 | * function signature redefinition for file destination creation 20 | * added shared library build configuration. Credit goes to Xavier Lamien 21 | for the Linux-specific config. 22 | * removed Symbian support 23 | * this version does not guarantee support for Nokia N9 devices, although it should in theory still 24 | work with them 25 | * workaround for Issue 8 - when used from an executable and a plugin QsLog only logs from the 26 | executable. 27 | * utility function to parse the level from an existing log message 28 | 29 | Known issues: 30 | * The current version will crash at program exit when using QS_LOG_SEPARATE_THREAD and linking 31 | with QsLog dynamically. 32 | 33 | ------------------- 34 | QsLog version 2.0b1 35 | 36 | Changes: 37 | * destination pointers use shared pointer semantics 38 | * the file destination supports log rotation. As a consequence, log files are encoded as UTF-8 and 39 | the log appends rather than truncating on every startup when rotation is enabled. 40 | * added the posibility of disabling logging either at run time or compile time. 41 | * added the possibility of using a separate thread for writing to the log destinations. 42 | 43 | Fixes: 44 | * renamed the main.cpp example to avoid QtCreator confusion 45 | * offer a way to check if the destination creation has failed (for e.g files) 46 | -------------------------------------------------------------------------------- /qslog/QsLogDest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "QsLogDest.h" 27 | #include "QsLogDestConsole.h" 28 | #include "QsLogDestFile.h" 29 | #include "QsLogDestFunctor.h" 30 | #include 31 | 32 | namespace QsLogging 33 | { 34 | 35 | Destination::~Destination() 36 | { 37 | } 38 | 39 | //! destination factory 40 | DestinationPtr DestinationFactory::MakeFileDestination(const QString& filePath, 41 | LogRotationOption rotation, const MaxSizeBytes &sizeInBytesToRotateAfter, 42 | const MaxOldLogCount &oldLogsToKeep) 43 | { 44 | if (EnableLogRotation == rotation) { 45 | QScopedPointer logRotation(new SizeRotationStrategy); 46 | logRotation->setMaximumSizeInBytes(sizeInBytesToRotateAfter.size); 47 | logRotation->setBackupCount(oldLogsToKeep.count); 48 | 49 | return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(logRotation.take()))); 50 | } 51 | 52 | return DestinationPtr(new FileDestination(filePath, RotationStrategyPtr(new NullRotationStrategy))); 53 | } 54 | 55 | DestinationPtr DestinationFactory::MakeDebugOutputDestination() 56 | { 57 | return DestinationPtr(new DebugOutputDestination); 58 | } 59 | 60 | DestinationPtr DestinationFactory::MakeFunctorDestination(QsLogging::Destination::LogFunction f) 61 | { 62 | return DestinationPtr(new FunctorDestination(f)); 63 | } 64 | 65 | DestinationPtr DestinationFactory::MakeFunctorDestination(QObject *receiver, const char *member) 66 | { 67 | return DestinationPtr(new FunctorDestination(receiver, member)); 68 | } 69 | 70 | } // end namespace 71 | -------------------------------------------------------------------------------- /qslog/QsLogDest.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef QSLOGDEST_H 27 | #define QSLOGDEST_H 28 | 29 | #include "QsLogLevel.h" 30 | #include 31 | #include 32 | class QString; 33 | class QObject; 34 | 35 | #ifdef QSLOG_IS_SHARED_LIBRARY 36 | #define QSLOG_SHARED_OBJECT Q_DECL_EXPORT 37 | #elif QSLOG_IS_SHARED_LIBRARY_IMPORT 38 | #define QSLOG_SHARED_OBJECT Q_DECL_IMPORT 39 | #else 40 | #define QSLOG_SHARED_OBJECT 41 | #endif 42 | 43 | namespace QsLogging 44 | { 45 | 46 | class QSLOG_SHARED_OBJECT Destination 47 | { 48 | public: 49 | typedef void (*LogFunction)(const QString &message, Level level); 50 | 51 | public: 52 | virtual ~Destination(); 53 | virtual void write(const QString& message, Level level) = 0; 54 | virtual bool isValid() = 0; // returns whether the destination was created correctly 55 | }; 56 | typedef QSharedPointer DestinationPtr; 57 | 58 | 59 | // a series of "named" paramaters, to make the file destination creation more readable 60 | enum LogRotationOption 61 | { 62 | DisableLogRotation = 0, 63 | EnableLogRotation = 1 64 | }; 65 | 66 | struct QSLOG_SHARED_OBJECT MaxSizeBytes 67 | { 68 | MaxSizeBytes() : size(0) {} 69 | explicit MaxSizeBytes(qint64 size_) : size(size_) {} 70 | qint64 size; 71 | }; 72 | 73 | struct QSLOG_SHARED_OBJECT MaxOldLogCount 74 | { 75 | MaxOldLogCount() : count(0) {} 76 | explicit MaxOldLogCount(int count_) : count(count_) {} 77 | int count; 78 | }; 79 | 80 | 81 | //! Creates logging destinations/sinks. The caller shares ownership of the destinations with the logger. 82 | //! After being added to a logger, the caller can discard the pointers. 83 | class QSLOG_SHARED_OBJECT DestinationFactory 84 | { 85 | public: 86 | static DestinationPtr MakeFileDestination(const QString& filePath, 87 | LogRotationOption rotation = DisableLogRotation, 88 | const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(), 89 | const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount()); 90 | static DestinationPtr MakeDebugOutputDestination(); 91 | // takes a pointer to a function 92 | static DestinationPtr MakeFunctorDestination(Destination::LogFunction f); 93 | // takes a QObject + signal/slot 94 | static DestinationPtr MakeFunctorDestination(QObject *receiver, const char *member); 95 | }; 96 | 97 | } // end namespace 98 | 99 | #endif // QSLOGDEST_H 100 | -------------------------------------------------------------------------------- /qslog/QsLogDestConsole.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "QsLogDestConsole.h" 27 | #include 28 | #include 29 | 30 | #if defined(Q_OS_WIN) 31 | #define WIN32_LEAN_AND_MEAN 32 | #include 33 | void QsDebugOutput::output( const QString& message ) 34 | { 35 | OutputDebugStringW(reinterpret_cast(message.utf16())); 36 | OutputDebugStringW(L"\n"); 37 | } 38 | #elif defined(Q_OS_UNIX) 39 | #include 40 | void QsDebugOutput::output( const QString& message ) 41 | { 42 | fprintf(stderr, "%s\n", qPrintable(message)); 43 | fflush(stderr); 44 | } 45 | #endif 46 | 47 | void QsLogging::DebugOutputDestination::write(const QString& message, Level) 48 | { 49 | QsDebugOutput::output(message); 50 | } 51 | 52 | bool QsLogging::DebugOutputDestination::isValid() 53 | { 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /qslog/QsLogDestConsole.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef QSLOGDESTCONSOLE_H 27 | #define QSLOGDESTCONSOLE_H 28 | 29 | #include "QsLogDest.h" 30 | 31 | class QString; 32 | 33 | class QsDebugOutput 34 | { 35 | public: 36 | static void output(const QString& a_message); 37 | }; 38 | 39 | namespace QsLogging 40 | { 41 | 42 | // debugger sink 43 | class DebugOutputDestination : public Destination 44 | { 45 | public: 46 | virtual void write(const QString& message, Level level); 47 | virtual bool isValid(); 48 | }; 49 | 50 | } 51 | 52 | #endif // QSLOGDESTCONSOLE_H 53 | -------------------------------------------------------------------------------- /qslog/QsLogDestFile.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "QsLogDestFile.h" 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | const int QsLogging::SizeRotationStrategy::MaxBackupCount = 10; 33 | 34 | QsLogging::RotationStrategy::~RotationStrategy() 35 | { 36 | } 37 | 38 | QsLogging::SizeRotationStrategy::SizeRotationStrategy() 39 | : mCurrentSizeInBytes(0) 40 | , mMaxSizeInBytes(0) 41 | , mBackupsCount(0) 42 | { 43 | } 44 | 45 | void QsLogging::SizeRotationStrategy::setInitialInfo(const QFile &file) 46 | { 47 | mFileName = file.fileName(); 48 | mCurrentSizeInBytes = file.size(); 49 | } 50 | 51 | void QsLogging::SizeRotationStrategy::includeMessageInCalculation(const QString &message) 52 | { 53 | mCurrentSizeInBytes += message.toUtf8().size(); 54 | } 55 | 56 | bool QsLogging::SizeRotationStrategy::shouldRotate() 57 | { 58 | return mCurrentSizeInBytes > mMaxSizeInBytes; 59 | } 60 | 61 | // Algorithm assumes backups will be named filename.X, where 1 <= X <= mBackupsCount. 62 | // All X's will be shifted up. 63 | void QsLogging::SizeRotationStrategy::rotate() 64 | { 65 | if (!mBackupsCount) { 66 | if (!QFile::remove(mFileName)) 67 | std::cerr << "QsLog: backup delete failed " << qPrintable(mFileName); 68 | return; 69 | } 70 | 71 | // 1. find the last existing backup than can be shifted up 72 | const QString logNamePattern = mFileName + QString::fromUtf8(".%1"); 73 | int lastExistingBackupIndex = 0; 74 | for (int i = 1;i <= mBackupsCount;++i) { 75 | const QString backupFileName = logNamePattern.arg(i); 76 | if (QFile::exists(backupFileName)) 77 | lastExistingBackupIndex = qMin(i, mBackupsCount - 1); 78 | else 79 | break; 80 | } 81 | 82 | // 2. shift up 83 | for (int i = lastExistingBackupIndex;i >= 1;--i) { 84 | const QString oldName = logNamePattern.arg(i); 85 | const QString newName = logNamePattern.arg(i + 1); 86 | QFile::remove(newName); 87 | const bool renamed = QFile::rename(oldName, newName); 88 | if (!renamed) { 89 | std::cerr << "QsLog: could not rename backup " << qPrintable(oldName) 90 | << " to " << qPrintable(newName); 91 | } 92 | } 93 | 94 | // 3. rename current log file 95 | const QString newName = logNamePattern.arg(1); 96 | if (QFile::exists(newName)) 97 | QFile::remove(newName); 98 | if (!QFile::rename(mFileName, newName)) { 99 | std::cerr << "QsLog: could not rename log " << qPrintable(mFileName) 100 | << " to " << qPrintable(newName); 101 | } 102 | } 103 | 104 | QIODevice::OpenMode QsLogging::SizeRotationStrategy::recommendedOpenModeFlag() 105 | { 106 | return QIODevice::Append; 107 | } 108 | 109 | void QsLogging::SizeRotationStrategy::setMaximumSizeInBytes(qint64 size) 110 | { 111 | Q_ASSERT(size >= 0); 112 | mMaxSizeInBytes = size; 113 | } 114 | 115 | void QsLogging::SizeRotationStrategy::setBackupCount(int backups) 116 | { 117 | Q_ASSERT(backups >= 0); 118 | mBackupsCount = qMin(backups, SizeRotationStrategy::MaxBackupCount); 119 | } 120 | 121 | 122 | QsLogging::FileDestination::FileDestination(const QString& filePath, RotationStrategyPtr rotationStrategy) 123 | : mRotationStrategy(rotationStrategy) 124 | { 125 | mFile.setFileName(filePath); 126 | if (!mFile.open(QFile::WriteOnly | QFile::Text | mRotationStrategy->recommendedOpenModeFlag())) 127 | std::cerr << "QsLog: could not open log file " << qPrintable(filePath); 128 | mOutputStream.setDevice(&mFile); 129 | mOutputStream.setCodec(QTextCodec::codecForName("UTF-8")); 130 | 131 | mRotationStrategy->setInitialInfo(mFile); 132 | } 133 | 134 | void QsLogging::FileDestination::write(const QString& message, Level) 135 | { 136 | mRotationStrategy->includeMessageInCalculation(message); 137 | if (mRotationStrategy->shouldRotate()) { 138 | mOutputStream.setDevice(NULL); 139 | mFile.close(); 140 | mRotationStrategy->rotate(); 141 | if (!mFile.open(QFile::WriteOnly | QFile::Text | mRotationStrategy->recommendedOpenModeFlag())) 142 | std::cerr << "QsLog: could not reopen log file " << qPrintable(mFile.fileName()); 143 | mRotationStrategy->setInitialInfo(mFile); 144 | mOutputStream.setDevice(&mFile); 145 | } 146 | 147 | mOutputStream << message << endl; 148 | mOutputStream.flush(); 149 | } 150 | 151 | bool QsLogging::FileDestination::isValid() 152 | { 153 | return mFile.isOpen(); 154 | } 155 | 156 | -------------------------------------------------------------------------------- /qslog/QsLogDestFile.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef QSLOGDESTFILE_H 27 | #define QSLOGDESTFILE_H 28 | 29 | #include "QsLogDest.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace QsLogging 36 | { 37 | class RotationStrategy 38 | { 39 | public: 40 | virtual ~RotationStrategy(); 41 | 42 | virtual void setInitialInfo(const QFile &file) = 0; 43 | virtual void includeMessageInCalculation(const QString &message) = 0; 44 | virtual bool shouldRotate() = 0; 45 | virtual void rotate() = 0; 46 | virtual QIODevice::OpenMode recommendedOpenModeFlag() = 0; 47 | }; 48 | 49 | // Never rotates file, overwrites existing file. 50 | class NullRotationStrategy : public RotationStrategy 51 | { 52 | public: 53 | virtual void setInitialInfo(const QFile &) {} 54 | virtual void includeMessageInCalculation(const QString &) {} 55 | virtual bool shouldRotate() { return false; } 56 | virtual void rotate() {} 57 | virtual QIODevice::OpenMode recommendedOpenModeFlag() { return QIODevice::Truncate; } 58 | }; 59 | 60 | // Rotates after a size is reached, keeps a number of <= 10 backups, appends to existing file. 61 | class SizeRotationStrategy : public RotationStrategy 62 | { 63 | public: 64 | SizeRotationStrategy(); 65 | static const int MaxBackupCount; 66 | 67 | virtual void setInitialInfo(const QFile &file); 68 | virtual void includeMessageInCalculation(const QString &message); 69 | virtual bool shouldRotate(); 70 | virtual void rotate(); 71 | virtual QIODevice::OpenMode recommendedOpenModeFlag(); 72 | 73 | void setMaximumSizeInBytes(qint64 size); 74 | void setBackupCount(int backups); 75 | 76 | private: 77 | QString mFileName; 78 | qint64 mCurrentSizeInBytes; 79 | qint64 mMaxSizeInBytes; 80 | int mBackupsCount; 81 | }; 82 | 83 | typedef QSharedPointer RotationStrategyPtr; 84 | 85 | // file message sink 86 | class FileDestination : public Destination 87 | { 88 | public: 89 | FileDestination(const QString& filePath, RotationStrategyPtr rotationStrategy); 90 | virtual void write(const QString& message, Level level); 91 | virtual bool isValid(); 92 | 93 | private: 94 | QFile mFile; 95 | QTextStream mOutputStream; 96 | QSharedPointer mRotationStrategy; 97 | }; 98 | 99 | } 100 | 101 | #endif // QSLOGDESTFILE_H 102 | -------------------------------------------------------------------------------- /qslog/QsLogDestFunctor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Razvan Petru 2 | // Copyright (c) 2014, Omar Carey 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, 6 | // are permitted provided that the following conditions are met: 7 | 8 | // * Redistributions of source code must retain the above copyright notice, this 9 | // list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this 11 | // list of conditions and the following disclaimer in the documentation and/or other 12 | // materials provided with the distribution. 13 | // * The name of the contributors may not be used to endorse or promote products 14 | // derived from this software without specific prior written permission. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 25 | // OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #include "QsLogDestFunctor.h" 28 | #include 29 | #include 30 | 31 | QsLogging::FunctorDestination::FunctorDestination(LogFunction f) 32 | : QObject(NULL) 33 | , mLogFunction(f) 34 | { 35 | } 36 | 37 | QsLogging::FunctorDestination::FunctorDestination(QObject *receiver, const char *member) 38 | : QObject(NULL) 39 | , mLogFunction(NULL) 40 | { 41 | connect(this, SIGNAL(logMessageReady(QString,int)), receiver, member, Qt::QueuedConnection); 42 | } 43 | 44 | 45 | void QsLogging::FunctorDestination::write(const QString &message, QsLogging::Level level) 46 | { 47 | if (mLogFunction) 48 | mLogFunction(message, level); 49 | 50 | emit logMessageReady(message, static_cast(level)); 51 | } 52 | 53 | bool QsLogging::FunctorDestination::isValid() 54 | { 55 | return true; 56 | } 57 | -------------------------------------------------------------------------------- /qslog/QsLogDestFunctor.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Razvan Petru 2 | // Copyright (c) 2014, Omar Carey 3 | // All rights reserved. 4 | 5 | // Redistribution and use in source and binary forms, with or without modification, 6 | // are permitted provided that the following conditions are met: 7 | 8 | // * Redistributions of source code must retain the above copyright notice, this 9 | // list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above copyright notice, this 11 | // list of conditions and the following disclaimer in the documentation and/or other 12 | // materials provided with the distribution. 13 | // * The name of the contributors may not be used to endorse or promote products 14 | // derived from this software without specific prior written permission. 15 | 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 25 | // OF THE POSSIBILITY OF SUCH DAMAGE. 26 | 27 | #ifndef QSLOGDESTFUNCTOR_H 28 | #define QSLOGDESTFUNCTOR_H 29 | 30 | #include "QsLogDest.h" 31 | #include 32 | 33 | namespace QsLogging 34 | { 35 | // Offers various types of function-like sinks. 36 | // This is an advanced destination type. Depending on your configuration, LogFunction might be 37 | // called from a different thread or even a different binary. You should not access QsLog from 38 | // inside LogFunction and should not perform any time-consuming operations. 39 | // logMessageReady is connected through a queued connection and trace messages are not included 40 | class FunctorDestination : public QObject, public Destination 41 | { 42 | Q_OBJECT 43 | public: 44 | explicit FunctorDestination(LogFunction f); 45 | FunctorDestination(QObject *receiver, const char *member); 46 | 47 | virtual void write(const QString &message, Level level); 48 | virtual bool isValid(); 49 | 50 | protected: 51 | // int used to avoid registering a new enum type 52 | Q_SIGNAL void logMessageReady(const QString &message, int level); 53 | 54 | private: 55 | LogFunction mLogFunction; 56 | }; 57 | } 58 | 59 | #endif // QSLOGDESTFUNCTOR_H 60 | -------------------------------------------------------------------------------- /qslog/QsLogDisableForThisFile.h: -------------------------------------------------------------------------------- 1 | #ifndef QSLOGDISABLEFORTHISFILE_H 2 | #define QSLOGDISABLEFORTHISFILE_H 3 | 4 | #include 5 | // When included AFTER QsLog.h, this file will disable logging in that C++ file. When included 6 | // before, it will lead to compiler warnings or errors about macro redefinitions. 7 | 8 | #undef QLOG_TRACE 9 | #undef QLOG_DEBUG 10 | #undef QLOG_INFO 11 | #undef QLOG_WARN 12 | #undef QLOG_ERROR 13 | #undef QLOG_FATAL 14 | 15 | #define QLOG_TRACE() if (1) {} else qDebug() 16 | #define QLOG_DEBUG() if (1) {} else qDebug() 17 | #define QLOG_INFO() if (1) {} else qDebug() 18 | #define QLOG_WARN() if (1) {} else qDebug() 19 | #define QLOG_ERROR() if (1) {} else qDebug() 20 | #define QLOG_FATAL() if (1) {} else qDebug() 21 | 22 | #endif // QSLOGDISABLEFORTHISFILE_H 23 | -------------------------------------------------------------------------------- /qslog/QsLogLevel.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef QSLOGLEVEL_H 27 | #define QSLOGLEVEL_H 28 | 29 | namespace QsLogging 30 | { 31 | 32 | enum Level 33 | { 34 | TraceLevel = 0, 35 | DebugLevel, 36 | InfoLevel, 37 | WarnLevel, 38 | ErrorLevel, 39 | FatalLevel, 40 | OffLevel 41 | }; 42 | 43 | } 44 | 45 | #endif // QSLOGLEVEL_H 46 | -------------------------------------------------------------------------------- /qslog/QsLogReadme.txt: -------------------------------------------------------------------------------- 1 | QsLog - the simple Qt logger 2 | ------------------------------------------------------------------------------- 3 | QsLog is an easy to use logger that is based on Qt's QDebug class. 4 | 5 | Features 6 | ------------------------------------------------------------------------------- 7 | * Six logging levels (from trace to fatal) 8 | * Logging level threshold configurable at runtime. 9 | * Minimum overhead when logging is turned off. 10 | * Multiple destinations, comes with file and debug destinations. 11 | * Thread-safe 12 | * Logging of common Qt types out of the box. 13 | * Immediate logging or queueing messages in a separate thread. 14 | * Small dependency: just drop it in your project directly. 15 | 16 | Usage 17 | ------------------------------------------------------------------------------- 18 | By directly including QsLog in your project: 19 | 1. Include QsLog.pri in your pro file 20 | 2. Include QsLog.h in your C++ files. Include QsLogDest.h only where you create/add destinations. 21 | 3. Get the instance of the logger by calling QsLogging::Logger::instance(); 22 | 4. Optionally set the logging level. Info is default. 23 | 5. Create as many destinations as you want by using the QsLogging::DestinationFactory. 24 | 6. Add the destinations to the logger instance by calling addDestination. 25 | 7. Start logging! 26 | Note: when you want to use QsLog both from an executable and a shared library you have to 27 | link dynamically with QsLog due to a limitation with static variables. 28 | 29 | By linking to QsLog dynamically: 30 | 1. Build QsLog using the QsLogSharedLibrary.pro. 31 | 2. Add the QsLog shared library to your LIBS project dependencies. 32 | 3. Follow the steps in "directly including QsLog in your project" starting with step 2. 33 | 34 | Configuration 35 | ------------------------------------------------------------------------------- 36 | QsLog has several configurable parameters: 37 | * defining QS_LOG_LINE_NUMBERS in the .pri file enables writing the file and line number 38 | automatically for each logging call 39 | * defining QS_LOG_SEPARATE_THREAD will route all log messages to a separate thread. 40 | 41 | Sometimes it's necessary to turn off logging. This can be done in several ways: 42 | * globally, at compile time, by enabling the QS_LOG_DISABLE macro in the .pri file. 43 | * globally, at run time, by setting the log level to "OffLevel". 44 | * per file, at compile time, by including QsLogDisableForThisFile.h in the target file. 45 | 46 | Thread safety 47 | ------------------------------------------------------------------------------- 48 | The Qt docs say: A thread-safe function can be called simultaneously from multiple threads, 49 | even when the invocations use shared data, because all references to the shared data are serialized. 50 | A reentrant function can also be called simultaneously from multiple threads, but only if each 51 | invocation uses its own data. 52 | 53 | Since sending the log message to the destinations is protected by a mutex, the logging macros are 54 | thread-safe provided that the log has been initialized - i.e: instance() has been called. 55 | The instance function and the setup functions (e.g: setLoggingLevel, addDestination) are NOT 56 | thread-safe and are NOT reentrant. 57 | 58 | IMPORTANT: when using a separate thread for logging, your program might crash at exit time on some 59 | operating systems if you won't call Logger::destroyInstance() before your program exits. 60 | This function can be called either before returning from main in a console app or 61 | inside QCoreApplication::aboutToQuit in a Qt GUI app. 62 | The reason is that the logging thread is still running as some objects are destroyed by 63 | the OS. Calling destroyInstance will wait for the thread to finish. 64 | Nothing will happen if you forget to call the function when not using a separate thread 65 | for logging. 66 | -------------------------------------------------------------------------------- /qslog/QsLogSharedLibrary.pro: -------------------------------------------------------------------------------- 1 | # This pro file will build QsLog as a shared library 2 | include(QsLog.pri) 3 | 4 | TARGET = QsLog 5 | VERSION = "2.0.0" 6 | QT -= gui 7 | CONFIG -= console 8 | CONFIG -= app_bundle 9 | CONFIG += shared 10 | TEMPLATE = lib 11 | 12 | DESTDIR = $$PWD/build-QsLogShared 13 | OBJECTS_DIR = $$DESTDIR/obj 14 | MOC_DIR = $$DESTDIR/moc 15 | 16 | win32 { 17 | DEFINES += QSLOG_IS_SHARED_LIBRARY 18 | } 19 | 20 | unix:!macx { 21 | # make install will install the shared object in the appropriate folders 22 | headers.files = QsLog.h QsLogDest.h QsLogLevel.h 23 | headers.path = /usr/include/$(QMAKE_TARGET) 24 | 25 | other_files.files = *.txt 26 | other_files.path = /usr/local/share/$(QMAKE_TARGET) 27 | 28 | contains(QT_ARCH, x86_64) { 29 | target.path = /usr/lib64 30 | } else { 31 | target.path = /usr/lib 32 | } 33 | 34 | INSTALLS += headers target other_files 35 | } 36 | -------------------------------------------------------------------------------- /qslog/example/log_example.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | CONFIG += ordered 3 | 4 | SUBDIRS = ../QsLogSharedLibrary.pro \ 5 | log_example_shared.pro \ 6 | log_example_main.pro 7 | -------------------------------------------------------------------------------- /qslog/example/log_example_main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "QsLog.h" 27 | #include "QsLogDest.h" 28 | #include "log_example_shared.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | void logFunction(const QString &message, QsLogging::Level level) 35 | { 36 | std::cout << "From log function: " << qPrintable(message) << " " << static_cast(level) 37 | << std::endl; 38 | } 39 | 40 | // This small example shows how QsLog can be used inside a project. 41 | int main(int argc, char *argv[]) 42 | { 43 | QCoreApplication a(argc, argv); 44 | 45 | using namespace QsLogging; 46 | 47 | // 1. init the logging mechanism 48 | Logger& logger = Logger::instance(); 49 | logger.setLoggingLevel(QsLogging::TraceLevel); 50 | const QString sLogPath(QDir(a.applicationDirPath()).filePath("log.txt")); 51 | 52 | // 2. add two destinations 53 | DestinationPtr fileDestination(DestinationFactory::MakeFileDestination( 54 | sLogPath, EnableLogRotation, MaxSizeBytes(512), MaxOldLogCount(2))); 55 | DestinationPtr debugDestination(DestinationFactory::MakeDebugOutputDestination()); 56 | DestinationPtr functorDestination(DestinationFactory::MakeFunctorDestination(&logFunction)); 57 | logger.addDestination(debugDestination); 58 | logger.addDestination(fileDestination); 59 | logger.addDestination(functorDestination); 60 | 61 | // 3. start logging 62 | QLOG_INFO() << "Program started"; 63 | QLOG_INFO() << "Built with Qt" << QT_VERSION_STR << "running on" << qVersion(); 64 | 65 | QLOG_TRACE() << "Here's a" << QString::fromUtf8("trace") << "message"; 66 | QLOG_DEBUG() << "Here's a" << static_cast(QsLogging::DebugLevel) << "message"; 67 | QLOG_WARN() << "Uh-oh!"; 68 | qDebug() << "This message won't be picked up by the logger"; 69 | QLOG_ERROR() << "An error has occurred"; 70 | qWarning() << "Neither will this one"; 71 | QLOG_FATAL() << "Fatal error!"; 72 | 73 | logger.setLoggingLevel(QsLogging::OffLevel); 74 | for (int i = 0;i < 10000000;++i) { 75 | QLOG_ERROR() << QString::fromUtf8("this message should not be visible"); 76 | } 77 | logger.setLoggingLevel(QsLogging::TraceLevel); 78 | 79 | // 4. log from a shared library - should automatically share the same log instance as above 80 | QLibrary myLib("log_example_shared"); 81 | typedef LogExampleShared* (*LogExampleGetter)(); 82 | typedef void(*LogExampleDeleter)(LogExampleShared*); 83 | LogExampleGetter fLogCreator = (LogExampleGetter) myLib.resolve("createExample"); 84 | LogExampleDeleter fLogDeleter = (LogExampleDeleter)myLib.resolve("destroyExample"); 85 | LogExampleShared *logFromShared = 0; 86 | if (fLogCreator && fLogDeleter) { 87 | logFromShared = fLogCreator(); 88 | logFromShared->logSomething(); 89 | fLogDeleter(logFromShared); 90 | } else if (!fLogCreator || !fLogDeleter) { 91 | QLOG_ERROR() << "could not resolve shared library function(s)"; 92 | } 93 | 94 | QLOG_DEBUG() << "Program ending"; 95 | 96 | QsLogging::Logger::destroyInstance(); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /qslog/example/log_example_main.pro: -------------------------------------------------------------------------------- 1 | #This project links with QsLog dynamically and outputs an executable file. 2 | 3 | QT -= gui 4 | TARGET = log_example 5 | CONFIG += console 6 | CONFIG -= app_bundle 7 | TEMPLATE = app 8 | SOURCES += log_example_main.cpp 9 | INCLUDEPATH += $$PWD/../ 10 | DEFINES += QSLOG_IS_SHARED_LIBRARY_IMPORT 11 | 12 | LIBS += -L$$PWD/../build-QsLogShared 13 | win32 { 14 | LIBS += -lQsLog2 15 | } else { 16 | LIBS += -lQsLog 17 | } 18 | LIBS += -L$$PWD/../build-QsLogExample -llog_example_shared 19 | 20 | DESTDIR = $$PWD/../build-QsLogExample 21 | OBJECTS_DIR = $$DESTDIR/obj 22 | -------------------------------------------------------------------------------- /qslog/example/log_example_shared.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #include "log_example_shared.h" 27 | #include "QsLog.h" 28 | 29 | void LogExampleShared::logSomething() 30 | { 31 | QLOG_INFO() << "this message is comming from a shared library"; 32 | } 33 | 34 | LogExampleShared* createExample() 35 | { 36 | return new LogExampleShared(); 37 | } 38 | 39 | 40 | void destroyExample(LogExampleShared *example) 41 | { 42 | delete example; 43 | } 44 | -------------------------------------------------------------------------------- /qslog/example/log_example_shared.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Razvan Petru 2 | // All rights reserved. 3 | 4 | // Redistribution and use in source and binary forms, with or without modification, 5 | // are permitted provided that the following conditions are met: 6 | 7 | // * Redistributions of source code must retain the above copyright notice, this 8 | // list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above copyright notice, this 10 | // list of conditions and the following disclaimer in the documentation and/or other 11 | // materials provided with the distribution. 12 | // * The name of the contributors may not be used to endorse or promote products 13 | // derived from this software without specific prior written permission. 14 | 15 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 19 | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 | // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 22 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 23 | // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 | // OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | #ifndef LOGEXAMPLESHARED_H 27 | #define LOGEXAMPLESHARED_H 28 | 29 | #include 30 | 31 | #ifdef EXAMPLE_IS_SHARED_LIBRARY 32 | #define EXAMPLE_SHARED_OBJECT Q_DECL_IMPORT 33 | #else 34 | #define EXAMPLE_SHARED_OBJECT Q_DECL_EXPORT 35 | #endif 36 | 37 | class EXAMPLE_SHARED_OBJECT LogExampleShared 38 | { 39 | public: 40 | void logSomething(); 41 | }; 42 | 43 | extern "C" { 44 | LogExampleShared *createExample(); 45 | void destroyExample(LogExampleShared *example); 46 | } 47 | 48 | #endif // LOGEXAMPLESHARED_H 49 | -------------------------------------------------------------------------------- /qslog/example/log_example_shared.pro: -------------------------------------------------------------------------------- 1 | #This project file links with QsLog dynamically and outputs a shared object. 2 | 3 | QT -= gui 4 | 5 | TARGET = log_example_shared 6 | TEMPLATE = lib 7 | 8 | DEFINES += EXAMPLE_IS_SHARED_LIBRARY QSLOG_IS_SHARED_LIBRARY_IMPORT 9 | SOURCES += log_example_shared.cpp 10 | HEADERS += log_example_shared.h 11 | INCLUDEPATH += $$PWD/../ 12 | DESTDIR = $$PWD/../build-QsLogExample 13 | OBJECTS_DIR = $$DESTDIR/obj 14 | 15 | LIBS += -L$$PWD/../build-QsLogShared 16 | win32 { 17 | LIBS += -lQsLog2 18 | } else { 19 | LIBS += -lQsLog 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /qslog/unittest/QtTestUtil/QtTestUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Remko Troncon 3 | * Licensed under the MIT license. 4 | * See COPYING for license details. 5 | */ 6 | 7 | #ifndef QtTestUtil_H 8 | #define QtTestUtil_H 9 | 10 | #include 11 | #include 12 | #include "QtTestUtil/TestRegistration.h" 13 | 14 | /** 15 | * A macro to register a test class. 16 | * 17 | * This macro will create a static variable which registers the 18 | * testclass with the TestRegistry, and creates an instance of the 19 | * test class. 20 | * 21 | * Execute this macro in the body of your unit test's .cpp file, e.g. 22 | * class MyTest { 23 | * ... 24 | * }; 25 | * 26 | * QTTESTUTIL_REGISTER_TEST(MyTest) 27 | */ 28 | #define QTTESTUTIL_REGISTER_TEST(TestClass) \ 29 | static QtTestUtil::TestRegistration TestClass##Registration 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /qslog/unittest/QtTestUtil/SimpleChecker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Remko Troncon 3 | * Licensed under the MIT license. 4 | * See COPYING for license details. 5 | */ 6 | 7 | #include 8 | 9 | #include "QtTestUtil/TestRegistry.h" 10 | 11 | /** 12 | * Runs all tests registered with the QtTestUtil registry. 13 | */ 14 | int main(int argc, char* argv[]) { 15 | QCoreApplication application(argc, argv); 16 | return QtTestUtil::TestRegistry::getInstance()->runTests(argc, argv); 17 | } 18 | -------------------------------------------------------------------------------- /qslog/unittest/QtTestUtil/TestRegistration.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Remko Troncon 3 | * Licensed under the MIT license. 4 | * See COPYING for license details. 5 | */ 6 | 7 | #ifndef QtTestUtil_TestRegistration_H 8 | #define QtTestUtil_TestRegistration_H 9 | 10 | #include "QtTestUtil/TestRegistry.h" 11 | 12 | namespace QtTestUtil { 13 | 14 | /** 15 | * A wrapper class around a test to manage registration and static 16 | * creation of an instance of the test class. 17 | * This class is used by QTTESTUTIL_REGISTER_TEST(), and you should not 18 | * use this class directly. 19 | */ 20 | template 21 | class TestRegistration { 22 | public: 23 | TestRegistration() { 24 | test_ = new TestClass(); 25 | TestRegistry::getInstance()->registerTest(test_); 26 | } 27 | 28 | ~TestRegistration() { 29 | delete test_; 30 | } 31 | 32 | private: 33 | TestClass* test_; 34 | }; 35 | 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /qslog/unittest/QtTestUtil/TestRegistry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Remko Troncon 3 | * Licensed under the MIT license. 4 | * See COPYING for license details. 5 | */ 6 | 7 | #include "QtTestUtil/TestRegistry.h" 8 | 9 | #include 10 | 11 | namespace QtTestUtil { 12 | 13 | TestRegistry* TestRegistry::getInstance() { 14 | static TestRegistry registry; 15 | return ®istry; 16 | } 17 | 18 | void TestRegistry::registerTest(QObject* test) { 19 | tests_ += test; 20 | } 21 | 22 | int TestRegistry::runTests(int argc, char* argv[]) { 23 | int result = 0; 24 | foreach(QObject* test, tests_) { 25 | result |= QTest::qExec(test, argc, argv); 26 | } 27 | return result; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /qslog/unittest/QtTestUtil/TestRegistry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2008 Remko Troncon 3 | * Licensed under the MIT license. 4 | * See COPYING for license details. 5 | */ 6 | 7 | #ifndef QtTestUtil_TestRegistry_H 8 | #define QtTestUtil_TestRegistry_H 9 | 10 | #include 11 | 12 | class QObject; 13 | 14 | namespace QtTestUtil { 15 | 16 | /** 17 | * A registry of QtTest test classes. 18 | * All test classes registered with QTTESTUTIL_REGISTER_TEST add 19 | * themselves to this registry. All registered tests can then be run at 20 | * once using runTests(). 21 | */ 22 | class TestRegistry { 23 | public: 24 | /** 25 | * Retrieve the single instance of the registry. 26 | */ 27 | static TestRegistry* getInstance(); 28 | 29 | /** 30 | * Register a QtTest test. 31 | * This method is called by QTTESTUTIL_REGISTER_TEST, and you should 32 | * not use this method directly. 33 | */ 34 | void registerTest(QObject*); 35 | 36 | /** 37 | * Run all registered tests using QTest::qExec() 38 | */ 39 | int runTests(int argc, char* argv[]); 40 | 41 | private: 42 | TestRegistry() {} 43 | 44 | private: 45 | QList tests_; 46 | }; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /qslog/unittest/TestLog.cpp: -------------------------------------------------------------------------------- 1 | #include "QtTestUtil/QtTestUtil.h" 2 | #include "QsLog.h" 3 | #include "QsLogDest.h" 4 | #include 5 | #include 6 | #include 7 | 8 | // A destination that tracks log messages 9 | class MockDestination : public QsLogging::Destination 10 | { 11 | public: 12 | virtual void write(const QString &message, QsLogging::Level level) 13 | { 14 | Message m; 15 | m.text = message; 16 | m.level = level; 17 | mMessages.push_back(m); 18 | ++mCountByLevel[level]; 19 | } 20 | 21 | virtual bool isValid() 22 | { 23 | return true; 24 | } 25 | 26 | struct Message 27 | { 28 | Message() : level(QsLogging::TraceLevel) {} 29 | QString text; 30 | QsLogging::Level level; 31 | }; 32 | 33 | void clear() 34 | { 35 | mMessages.clear(); 36 | mCountByLevel.clear(); 37 | } 38 | 39 | int messageCount() const 40 | { 41 | return mMessages.count(); 42 | } 43 | 44 | int messageCountForLevel(QsLogging::Level level) const 45 | { 46 | return mCountByLevel.value(level); 47 | } 48 | 49 | bool hasMessage(const QString &messageContent, QsLogging::Level level) const 50 | { 51 | Q_FOREACH (const Message &m, mMessages) { 52 | if (m.level == level && m.text.contains(messageContent)) 53 | return true; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | const Message& messageAt(int index) 60 | { 61 | Q_ASSERT(index >= 0 && index < messageCount()); 62 | return mMessages.at(index); 63 | } 64 | 65 | private: 66 | QHash mCountByLevel; 67 | QList mMessages; 68 | }; 69 | 70 | // Autotests for QsLog 71 | class TestLog : public QObject 72 | { 73 | Q_OBJECT 74 | public: 75 | TestLog() 76 | : mockDest1(new MockDestination) 77 | , mockDest2(new MockDestination) 78 | { 79 | } 80 | 81 | private slots: 82 | void initTestCase(); 83 | void testAllLevels(); 84 | void testMessageText(); 85 | void testLevelChanges(); 86 | void testLevelParsing(); 87 | void cleanupTestCase(); 88 | 89 | private: 90 | QSharedPointer mockDest1; 91 | QSharedPointer mockDest2; 92 | }; 93 | 94 | void TestLog::initTestCase() 95 | { 96 | using namespace QsLogging; 97 | QCOMPARE(Logger::instance().loggingLevel(), InfoLevel); 98 | Logger::instance().setLoggingLevel(TraceLevel); 99 | QCOMPARE(Logger::instance().loggingLevel(), TraceLevel); 100 | Logger::instance().addDestination(mockDest1); 101 | Logger::instance().addDestination(mockDest2); 102 | } 103 | 104 | void TestLog::testAllLevels() 105 | { 106 | mockDest1->clear(); 107 | mockDest2->clear(); 108 | 109 | QLOG_TRACE() << "trace level"; 110 | QLOG_DEBUG() << "debug level"; 111 | QLOG_INFO() << "info level"; 112 | QLOG_WARN() << "warn level"; 113 | QLOG_ERROR() << "error level"; 114 | QLOG_FATAL() << "fatal level"; 115 | 116 | using namespace QsLogging; 117 | QCOMPARE(mockDest1->messageCount(), 6); 118 | QCOMPARE(mockDest1->messageCountForLevel(TraceLevel), 1); 119 | QCOMPARE(mockDest1->messageCountForLevel(DebugLevel), 1); 120 | QCOMPARE(mockDest1->messageCountForLevel(InfoLevel), 1); 121 | QCOMPARE(mockDest1->messageCountForLevel(WarnLevel), 1); 122 | QCOMPARE(mockDest1->messageCountForLevel(ErrorLevel), 1); 123 | QCOMPARE(mockDest1->messageCountForLevel(FatalLevel), 1); 124 | QCOMPARE(mockDest2->messageCount(), 6); 125 | QCOMPARE(mockDest2->messageCountForLevel(TraceLevel), 1); 126 | QCOMPARE(mockDest2->messageCountForLevel(DebugLevel), 1); 127 | QCOMPARE(mockDest2->messageCountForLevel(InfoLevel), 1); 128 | QCOMPARE(mockDest2->messageCountForLevel(WarnLevel), 1); 129 | QCOMPARE(mockDest2->messageCountForLevel(ErrorLevel), 1); 130 | QCOMPARE(mockDest2->messageCountForLevel(FatalLevel), 1); 131 | } 132 | 133 | void TestLog::testMessageText() 134 | { 135 | mockDest1->clear(); 136 | 137 | QLOG_DEBUG() << "foobar"; 138 | QLOG_WARN() << "eiszeit"; 139 | QLOG_FATAL() << "ruh-roh!"; 140 | using namespace QsLogging; 141 | QVERIFY(mockDest1->hasMessage("foobar", DebugLevel)); 142 | QVERIFY(mockDest1->hasMessage("eiszeit", WarnLevel)); 143 | QVERIFY(mockDest1->hasMessage("ruh-roh!", FatalLevel)); 144 | QCOMPARE(mockDest1->messageCount(), 3); 145 | } 146 | 147 | void TestLog::testLevelChanges() 148 | { 149 | mockDest1->clear(); 150 | mockDest2->clear(); 151 | 152 | using namespace QsLogging; 153 | Logger::instance().setLoggingLevel(WarnLevel); 154 | QCOMPARE(Logger::instance().loggingLevel(), WarnLevel); 155 | 156 | QLOG_TRACE() << "one"; 157 | QLOG_DEBUG() << "two"; 158 | QLOG_INFO() << "three"; 159 | QCOMPARE(mockDest1->messageCount(), 0); 160 | QCOMPARE(mockDest2->messageCount(), 0); 161 | 162 | QLOG_WARN() << "warning"; 163 | QLOG_ERROR() << "error"; 164 | QLOG_FATAL() << "fatal"; 165 | QCOMPARE(mockDest1->messageCountForLevel(WarnLevel), 1); 166 | QCOMPARE(mockDest1->messageCountForLevel(ErrorLevel), 1); 167 | QCOMPARE(mockDest1->messageCountForLevel(FatalLevel), 1); 168 | QCOMPARE(mockDest1->messageCount(), 3); 169 | QCOMPARE(mockDest2->messageCountForLevel(WarnLevel), 1); 170 | QCOMPARE(mockDest2->messageCountForLevel(ErrorLevel), 1); 171 | QCOMPARE(mockDest2->messageCountForLevel(FatalLevel), 1); 172 | QCOMPARE(mockDest2->messageCount(), 3); 173 | } 174 | 175 | void TestLog::testLevelParsing() 176 | { 177 | mockDest1->clear(); 178 | 179 | QLOG_TRACE() << "one"; 180 | QLOG_DEBUG() << "two"; 181 | QLOG_INFO() << "three"; 182 | QLOG_WARN() << "warning"; 183 | QLOG_ERROR() << "error"; 184 | QLOG_FATAL() << "fatal"; 185 | 186 | using namespace QsLogging; 187 | for(int i = 0;i < mockDest1->messageCount();++i) { 188 | bool conversionOk = false; 189 | const MockDestination::Message& m = mockDest1->messageAt(i); 190 | QCOMPARE(Logger::levelFromLogMessage(m.text, &conversionOk), m.level); 191 | QCOMPARE(Logger::levelFromLogMessage(m.text), m.level); 192 | QCOMPARE(conversionOk, true); 193 | } 194 | } 195 | 196 | void TestLog::cleanupTestCase() 197 | { 198 | QsLogging::Logger::destroyInstance(); 199 | } 200 | 201 | QTTESTUTIL_REGISTER_TEST(TestLog); 202 | #include "TestLog.moc" 203 | -------------------------------------------------------------------------------- /qslog/unittest/unittest.pro: -------------------------------------------------------------------------------- 1 | QT += core 2 | 3 | TARGET = QsLogUnitTest 4 | CONFIG += console qtestlib 5 | CONFIG -= app_bundle 6 | TEMPLATE = app 7 | 8 | # test-case sources 9 | SOURCES += TestLog.cpp 10 | 11 | # component sources 12 | include(../QsLog.pri) 13 | 14 | SOURCES += \ 15 | ./QtTestUtil/TestRegistry.cpp \ 16 | ./QtTestUtil/SimpleChecker.cpp 17 | 18 | HEADERS += \ 19 | ./QtTestUtil/TestRegistry.h \ 20 | ./QtTestUtil/TestRegistration.h \ 21 | ./QtTestUtil/QtTestUtil.h 22 | -------------------------------------------------------------------------------- /src/autoclosedialog.cpp: -------------------------------------------------------------------------------- 1 | #include "autoclosedialog.h" 2 | #include "ui_autoclosedialog.h" 3 | 4 | AutoCloseDialog::AutoCloseDialog(QWidget *parent) : 5 | QDialog(parent, Qt::FramelessWindowHint), 6 | ui(new Ui::AutoCloseDialog) 7 | { 8 | ui->setupUi(this); 9 | ui->retranslateUi(this); 10 | QTimer::singleShot(5000, this, SLOT(reject())); 11 | } 12 | 13 | AutoCloseDialog::~AutoCloseDialog() 14 | { 15 | delete ui; 16 | } 17 | 18 | void AutoCloseDialog::on_autoClosePushButton_clicked() 19 | { 20 | accept(); 21 | } 22 | -------------------------------------------------------------------------------- /src/filedownloader.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #include "filedownloader.h" 19 | #include "ui_dateidownloader.h" 20 | #include "math.h" 21 | 22 | #include "qslog/QsLog.h" 23 | 24 | FileDownloader::FileDownloader(int itemNumber, 25 | QWidget *parent) : 26 | QDialog(parent, Qt::FramelessWindowHint), 27 | ui(new Ui::DateiDownloader), 28 | manager(new QNetworkAccessManager(this)), 29 | itemNumber(itemNumber) 30 | { 31 | ui->setupUi(this); 32 | ui->retranslateUi(this); 33 | this->show(); 34 | 35 | Utils::centerWidgetOnDesktop(this); 36 | 37 | showedError = false; 38 | } 39 | 40 | FileDownloader::~FileDownloader() 41 | { 42 | delete manager; 43 | delete ui; 44 | } 45 | 46 | int FileDownloader::startNextDownload(QString fileName, QString courseName, QString filePath, QUrl fileUrl, int itemNummer, int itemSize, int time) 47 | { 48 | QLOG_DEBUG() << tr("Starte Download von ") << fileUrl.url(); 49 | 50 | // Anpassen der Labels 51 | ui->progressLabel->setText(QString("Datei %1/%2").arg(itemNummer+1).arg(itemNumber)); 52 | ui->veranstaltungLabel->setText(courseName); 53 | ui->dateinameLabel->setText(fileName); 54 | ui->progressBar->setFormat( "0 Byte / " % QString::number(correctSize(itemSize),'f',2) % " " % correctUnit(itemSize)); 55 | ui->progressBar->setValue(0); 56 | ui->progressBar->setMaximum(itemSize); 57 | ui->downloadSpeedLabel->setText(""); 58 | 59 | times.actime = 0; 60 | times.modtime = time; 61 | 62 | // Erstellen des Outputstreams 63 | output.setFileName(filePath); 64 | 65 | // Öffnen des Ausgabestreams 66 | if(!output.open(QIODevice::WriteOnly)) 67 | { 68 | Utils::errorMessageBox(tr("Fehler beim Öffnen mit Schreibberechtigung."), fileName); 69 | return 0; 70 | } 71 | 72 | downloadTime.start(); 73 | 74 | // Start des Requests 75 | reply = manager->get(QNetworkRequest(fileUrl)); 76 | QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgressSlot(qint64,qint64))); 77 | QObject::connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); 78 | QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot())); 79 | 80 | // Während des Downloads blockieren 81 | return(loop.exec()); 82 | } 83 | 84 | /// Anzeige des Downloadfortschritts der aktuellen Datei 85 | void FileDownloader::downloadProgressSlot(qint64 bytesReceived, qint64 bytesTotal) 86 | { 87 | (void) bytesTotal; 88 | 89 | // Aktualisieren der Progressbar anhand der Größe der empfangenen Bytes 90 | if (bytesTotal == -1) 91 | bytesTotal = ui->progressBar->maximum(); 92 | 93 | ui->progressBar->setFormat( QString::number(correctSize(bytesReceived),'f',2) % 94 | " " % correctUnit( bytesReceived ) % " / " % 95 | QString::number(correctSize(bytesTotal),'f',2) % 96 | " " % correctUnit(bytesTotal)); 97 | ui->progressBar->setValue(bytesReceived); 98 | ui->progressBar->update(); 99 | 100 | // Downloadgeschwindigkeit in kB/s 101 | double downloadSpeed = bytesReceived * 1000.0 / downloadTime.elapsed() / 1024; 102 | ui->downloadSpeedLabel->setText(QString::number(downloadSpeed, 'f', 1) % " kB/s"); 103 | } 104 | 105 | /// Abspeichern von empfangenen Dateiteilen 106 | void FileDownloader::readyReadSlot() 107 | { 108 | // Schreiben der runtergeladenen Bytes in die Datei 109 | if (output.write(reply->readAll()) == -1) 110 | { 111 | Utils::errorMessageBox(tr("Fehler beim Schreiben der Datei"), ui->dateinameLabel->text()); 112 | reply->abort(); 113 | } 114 | } 115 | 116 | void FileDownloader::finishedSlot() 117 | { 118 | // Entleeren und Schließen des Ausgabestreams 119 | output.flush(); 120 | output.close(); 121 | 122 | utime(output.fileName().toLocal8Bit(), ×); 123 | 124 | QObject::disconnect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgressSlot(qint64,qint64))); 125 | QObject::disconnect(reply, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); 126 | QObject::disconnect(reply, SIGNAL(finished()), this, SLOT(finishedSlot())); 127 | 128 | // Freigabe des Speichers 129 | reply->deleteLater(); 130 | 131 | if(reply->error()) 132 | { 133 | QString errorString = reply->errorString(); 134 | 135 | if(!showedError && !errorString.contains("server replied: Not Found") && !errorString.contains("Operation canceled")) 136 | { 137 | Utils::errorMessageBox(tr("Beim Download der Datei %1 ist ein Fehler aufgetreten. Weitere Fehler werden nur im Log angezeigt").arg(output.fileName()), 138 | errorString % "; " % reply->readAll()); 139 | showedError = true; 140 | } 141 | else 142 | { 143 | QLOG_ERROR() << tr("Beim Download der Datei %1 ist ein Fehler aufgetreten.").arg(output.fileName()) << 144 | ": " << errorString % "; " % reply->readAll(); 145 | } 146 | 147 | output.remove(); 148 | 149 | // Abort synchronisation completly if user desires 150 | if(errorString.contains("Operation canceled")) 151 | { 152 | loop.exit(0); 153 | return; 154 | } 155 | } 156 | 157 | loop.exit(1); 158 | } 159 | 160 | void FileDownloader::on_abortPushButton_clicked() 161 | { 162 | keyPressEvent(new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier)); 163 | } 164 | 165 | /// Abbruch der Synchronisation durch die Escapetaste 166 | void FileDownloader::keyPressEvent(QKeyEvent *event) 167 | { 168 | // Abfangen der Escapetaste 169 | if(event->key() == Qt::Key_Escape) 170 | { 171 | // Abbrechen des Synchronisation 172 | event->accept(); 173 | reply->abort(); 174 | } 175 | else 176 | { 177 | event->ignore(); 178 | } 179 | } 180 | 181 | /// Erzeugung der passenden Größeneinheit von der Dateigröße 182 | QString FileDownloader::correctUnit(qint64 bytes) 183 | { 184 | if(bytes > 1024 * 1024) 185 | { 186 | return "MB"; 187 | } 188 | else if (bytes > 1024) 189 | { 190 | return "kB"; 191 | } 192 | else 193 | { 194 | return "Byte"; 195 | } 196 | } 197 | 198 | /// Dateigröße in lesbare Größe umwandeln 199 | double FileDownloader::correctSize(qint64 bytes) 200 | { 201 | if(bytes > 1024 * 1024) 202 | { 203 | return bytes / (1024.0 * 1024); 204 | } 205 | else if (bytes > 1024) 206 | { 207 | return bytes / 1024.0; 208 | } 209 | else 210 | { 211 | return bytes; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/info.cpp: -------------------------------------------------------------------------------- 1 | #include "info.h" 2 | #include "ui_info.h" 3 | 4 | Info::Info(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::Info) 7 | { 8 | ui->setupUi(this); 9 | ui->tabWidget->setCurrentIndex(0); 10 | ui->retranslateUi(this); 11 | setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint); 12 | QImage image(":/icons/Sync-my-L2P.png"); 13 | ui->picture->setPixmap(QPixmap::fromImage(image)); 14 | ui->picture->adjustSize(); 15 | } 16 | Info::~Info() 17 | { 18 | delete ui; 19 | } 20 | -------------------------------------------------------------------------------- /src/logger.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "logger.h" 5 | #include "ui_logger.h" 6 | 7 | #include "qslog/QsLog.h" 8 | #include "qslog/QsLogDest.h" 9 | 10 | #include "utils.h" 11 | 12 | Logger::Logger(QWidget *parent) : 13 | QWidget(parent), 14 | ui(new Ui::Logger) 15 | { 16 | ui->setupUi(this); 17 | 18 | ui->logLevelCB->addItem(tr("Standard")); 19 | ui->logLevelCB->addItem(tr("Erweitert")); 20 | 21 | QsLogging::Logger::instance().addDestination(QsLogging::DestinationFactory::MakeFunctorDestination(this, SLOT(logSlot(QString,int)))); 22 | } 23 | 24 | Logger::~Logger() 25 | { 26 | delete ui; 27 | } 28 | 29 | /// Laden der Einstellungen 30 | void Logger::loadSettings() 31 | { 32 | QSettings settings; 33 | settings.beginGroup("logger"); 34 | ui->logLevelCB->setCurrentText(settings.value("logLevel", "standard").toString()); 35 | settings.endGroup(); 36 | } 37 | 38 | /// Speichern der Einstellungen 39 | void Logger::saveSettings() 40 | { 41 | QSettings settings; 42 | settings.beginGroup("logger"); 43 | settings.setValue("logLevel", ui->logLevelCB->currentText()); 44 | settings.endGroup(); 45 | 46 | } 47 | 48 | /// Empfänger für alle Nachrichten, die im Log auftauchen sollen 49 | void Logger::logSlot(QString message, int level) 50 | { 51 | (void) level; 52 | 53 | // Füge eine Leerzeile und färbe Nachrichten entsprechend des Typs ein 54 | if (message.contains("DEBUG")){ 55 | ui->logList->addItem(message + "\n"); 56 | ui->logList->item(ui->logList->count()-1)->setForeground(Qt::gray); 57 | 58 | } 59 | else if (message.contains("ERROR")){ 60 | ui->logList->addItem(message + "\n"); 61 | ui->logList->item(ui->logList->count()-1)->setForeground(Qt::red); 62 | 63 | } 64 | else 65 | { 66 | ui->logList->addItem(message + "\n"); 67 | // Use system default color 68 | } 69 | 70 | } 71 | 72 | /// Ausgewählte Logstufe an den Logger weitergeben 73 | void Logger::on_logLevelCB_currentIndexChanged(const QString &logLevel) 74 | { 75 | if(logLevel == QString(tr("Standard"))) 76 | { 77 | QsLogging::Logger::instance().setLoggingLevel(QsLogging::InfoLevel); 78 | QLOG_INFO() << tr("Setze Logging auf \"Standard\"."); 79 | } 80 | else if(logLevel == QString(tr("Erweitert"))) 81 | { 82 | QsLogging::Logger::instance().setLoggingLevel(QsLogging::TraceLevel); 83 | QLOG_INFO() << tr("Setze Logging auf \"Erweitert\"."); 84 | } 85 | } 86 | 87 | /// Speichern des gesamten Log in einer Datei 88 | void Logger::on_savePB_clicked() 89 | { 90 | QString textToWrite = getLogText(); 91 | 92 | QString filepath = QFileDialog::getSaveFileName(this, 93 | tr("Speicherort für das Logfile"), 94 | "", 95 | tr("Textdateien (*.txt)")); 96 | 97 | QLOG_DEBUG() << tr("Ausgewählter Speicherort für das Logfile: ") << filepath; 98 | 99 | QFile file(filepath); 100 | if(!file.open(QIODevice::WriteOnly)) 101 | { 102 | QLOG_ERROR() << tr("Fehler beim Initialisieren des Logfiles: ") << file.errorString(); 103 | return; 104 | } 105 | 106 | if(file.write(textToWrite.toLatin1()) == -1) 107 | { 108 | QLOG_ERROR() << tr("Fehler beim Schreiben des Logfiles: ") << file.errorString(); 109 | return; 110 | } 111 | 112 | file.close(); 113 | } 114 | 115 | /// Kopieren des gesamten Logs in die Zwischenablage 116 | void Logger::on_copyPB_clicked() 117 | { 118 | Utils::copyTextToClipboard(getLogText()); 119 | } 120 | 121 | /// Wandelt alle Logs in einen einzigen String um 122 | QString Logger::getLogText() 123 | { 124 | QList items = ui->logList->findItems("*", Qt::MatchWildcard); 125 | 126 | QString logText(""); 127 | 128 | foreach(QListWidgetItem* item, items) 129 | { 130 | logText.append( item->text() + "\r\n"); 131 | } 132 | 133 | return logText; 134 | } 135 | void Logger::retranslate() 136 | { 137 | ui->retranslateUi(this); 138 | } 139 | -------------------------------------------------------------------------------- /src/login.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include "clientId.h" 7 | #include "qslog/QsLog.h" 8 | #include "login.h" 9 | #include "utils.h" 10 | 11 | #define BASEURL QString("https://oauth.campus.rwth-aachen.de/oauth2waitress/oauth2.svc/") 12 | 13 | Login::Login(QWidget *parent) 14 | : QObject((QObject*)parent), stopLogin(false), settingsLoaded(false) 15 | { 16 | // Automatisch Abbruch des Logins nach 120 Sekunden 17 | stopLoginTimer.setSingleShot(true); 18 | stopLoginTimer.setInterval(120 * 1000); 19 | QObject::connect(&stopLoginTimer, SIGNAL(timeout()), this, SLOT(stopLoginSlot())); 20 | 21 | QObject::connect( &manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)) ); 22 | } 23 | 24 | void Login::init() 25 | { 26 | if(settingsLoaded) 27 | { 28 | return; 29 | } 30 | 31 | settingsLoaded = true; 32 | 33 | QSettings settings; 34 | settings.beginGroup("loginData"); 35 | refreshToken = settings.value("refreshToken", "").toString(); 36 | settings.endGroup(); 37 | 38 | QLOG_DEBUG() << tr("Geladenes RefreshToken: ") << refreshToken; 39 | } 40 | 41 | void Login::getAccess() 42 | { 43 | // Nach 120 Sekunden abbrechen 44 | stopLogin = false; 45 | 46 | stopLoginTimer.stop(); 47 | stopLoginTimer.start(); 48 | 49 | if(refreshToken.isEmpty()) 50 | { 51 | getUserCode(); 52 | } 53 | else 54 | { 55 | refreshAccess(); 56 | } 57 | } 58 | 59 | void Login::postRequest(QUrlQuery &query, QUrl url) 60 | { 61 | QByteArray queryString; 62 | queryString.append(query.toString().toUtf8()); 63 | 64 | url.setQuery(query); 65 | 66 | QNetworkRequest request; 67 | request.setUrl(url); 68 | request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); 69 | 70 | if(!stopLogin) 71 | { 72 | manager.post(request, queryString); 73 | } 74 | } 75 | 76 | void Login::saveAccessToken() 77 | { 78 | QSettings settings; 79 | 80 | settings.beginGroup("loginData"); 81 | settings.setValue("refreshToken", refreshToken); 82 | settings.endGroup(); 83 | } 84 | 85 | void Login::getUserCode() 86 | { 87 | QUrlQuery query; 88 | query.addQueryItem("client_id", CLIENTID); 89 | query.addQueryItem("scope", "userinfo.rwth moodle.rwth"); 90 | 91 | QUrl url(BASEURL + "code"); 92 | 93 | postRequest(query, url); 94 | } 95 | 96 | void Login::stopLoginSlot() 97 | { 98 | QLOG_DEBUG() << tr("Stoppe Login"); 99 | 100 | stopLoginTimer.stop(); 101 | 102 | if(accessToken.isEmpty()) 103 | { 104 | stopLogin = true; 105 | emit loginFailed(); 106 | } 107 | } 108 | 109 | void Login::deleteAccess() 110 | { 111 | QLOG_DEBUG() << tr("Lösche Zugriffsdaten."); 112 | 113 | accessToken.clear(); 114 | refreshToken.clear(); 115 | } 116 | 117 | void Login::checkForVerification() 118 | { 119 | // Starte das Polling 120 | QUrlQuery query; 121 | query.addQueryItem("client_id", CLIENTID); 122 | query.addQueryItem("code", verification["device_code"].toString()); 123 | query.addQueryItem("grant_type", "device"); 124 | 125 | QUrl url(BASEURL + "token"); 126 | 127 | postRequest(query, url); 128 | } 129 | 130 | void Login::refreshAccess() 131 | { 132 | accessToken.clear(); 133 | 134 | QUrlQuery query; 135 | query.addQueryItem("client_id", CLIENTID); 136 | query.addQueryItem("refresh_token", refreshToken); 137 | query.addQueryItem("grant_type", "refresh_token"); 138 | 139 | QUrl url(BASEURL + "token"); 140 | 141 | postRequest(query, url); 142 | } 143 | 144 | void Login::getTokenInfo() 145 | { 146 | QUrlQuery query; 147 | query.addQueryItem("client_id", CLIENTID); 148 | query.addQueryItem("access_token", accessToken); 149 | 150 | QUrl url(BASEURL + "tokeninfo"); 151 | 152 | postRequest(query, url); 153 | } 154 | 155 | void Login::finishedSlot(QNetworkReply *reply) 156 | { 157 | QJsonDocument document = QJsonDocument::fromJson(reply->readAll()); 158 | QJsonObject object = document.object(); 159 | 160 | if(object.isEmpty()) 161 | { 162 | QLOG_ERROR() << tr("Keine lesbare Antwort erhalten."); 163 | stopLoginSlot(); 164 | return; 165 | } 166 | 167 | QString status = object["status"].toString(); 168 | if(status == QString("ok")) 169 | { 170 | if(!object["user_code"].toString().isEmpty()) 171 | { 172 | // Benutzer muss App Zugriff erlauben 173 | 174 | verification = object; 175 | 176 | QString verificationUrl = verification["verification_url"].toString(); 177 | verificationUrl.append("?q=verify&d="); 178 | verificationUrl.append(verification["user_code"].toString()); 179 | 180 | QUrl url; 181 | url.setUrl(verificationUrl); 182 | 183 | QLOG_DEBUG() << tr("Öffne Browser für Verfikation. Url: ") << url; 184 | QDesktopServices::openUrl(url); 185 | 186 | QTimer::singleShot(verification["interval"].toInt() * 1000, this, SLOT(checkForVerification())); 187 | } 188 | else if(!object["refresh_token"].toString().isEmpty()) 189 | { 190 | // Zugriff gewährt 191 | 192 | QLOG_DEBUG() << tr("Neuer Zugriff gewährt."); 193 | refreshToken = object["refresh_token"].toString(); 194 | accessToken = object["access_token"].toString(); 195 | 196 | QTimer::singleShot(object["expires_in"].toInt() * 1000, this, SLOT(refreshAccess())); 197 | 198 | stopLoginTimer.stop(); 199 | emit newAccessToken(accessToken); 200 | QLOG_DEBUG() << "Accesstoken: " << accessToken; 201 | } 202 | else if(!object["access_token"].toString().isEmpty()) 203 | { 204 | // Zugriff erneuert 205 | QLOG_DEBUG() << tr("Zugriff durch Refreshtoken erneuert."); 206 | accessToken = object["access_token"].toString(); 207 | 208 | QTimer::singleShot(object["expires_in"].toInt() * 1000, this, SLOT(refreshAccess())); 209 | QLOG_DEBUG() << tr("Neuer accesstoken: ") << accessToken; 210 | 211 | // Check if necessary scopes are given 212 | getTokenInfo(); 213 | } 214 | else if(!object["scope"].toString().isEmpty()) 215 | { 216 | auto scopes = object["scope"].toString(); 217 | QLOG_DEBUG() << tr("Zugriff auf folgende Scopes: ") << scopes; 218 | if(scopes.contains("moodle.rwth")) 219 | { 220 | stopLoginTimer.stop(); 221 | emit newAccessToken(accessToken); 222 | } 223 | else 224 | { 225 | Utils::errorMessageBox(tr("Authorisierung für Moodle fehlt!"), 226 | tr("Du hast Sync-my-L2P noch nicht die Berechtigung erteilt, " 227 | "auf Moodle zuzugreifen. Bitte logge dich neu ein.")); 228 | deleteAccess(); 229 | getAccess(); 230 | } 231 | } 232 | else 233 | { 234 | QLOG_ERROR() << tr("Status der Antwort ok, aber Antworttyp nicht bekannt.\n") << object; 235 | 236 | stopLoginSlot(); 237 | } 238 | } 239 | else if(status == QString("error: authorization pending.")) 240 | { 241 | QLOG_DEBUG() << status; 242 | QTimer::singleShot(verification["interval"].toInt() * 1000, this, SLOT(checkForVerification())); 243 | } 244 | else if(status == QString("error: slow down")) 245 | { 246 | QLOG_DEBUG() << status; 247 | QTimer::singleShot(verification["interval"].toInt() * 1200, this, SLOT(checkForVerification())); 248 | } 249 | else if(status == QString("authorization invalid.")) 250 | { 251 | // RefreshToken abgelaufen, neuen Authorisierung starten 252 | QLOG_DEBUG() << status; 253 | QTimer::singleShot(50, this, SLOT(getUserCode())); 254 | } 255 | else if(status == QString("error: refresh token invalid.")) 256 | { 257 | // Ungültiger RefreshToken 258 | QLOG_DEBUG() << status; 259 | 260 | QTimer::singleShot(50, this, SLOT(getUserCode())); 261 | } 262 | else 263 | { 264 | QLOG_ERROR() << tr("Unerwarteter Antwortstatus: ") << status; 265 | 266 | stopLoginSlot(); 267 | } 268 | } 269 | 270 | 271 | -------------------------------------------------------------------------------- /src/logindialog.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "logindialog.h" 5 | #include "urls.h" 6 | #include "ui_logindialog.h" 7 | #include "qslog/QsLog.h" 8 | 9 | LoginDialog::LoginDialog(QWidget *parent) : 10 | QDialog(parent), 11 | ui(new Ui::LoginDialog) 12 | { 13 | ui->setupUi(this); 14 | ui->retranslateUi(this); 15 | 16 | setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint); 17 | this->moodleAvailable = NOTTESTED; 18 | } 19 | 20 | LoginDialog::~LoginDialog() 21 | { 22 | QObject::disconnect(login, SIGNAL(newAccessToken(QString)), this, SLOT(succededSlot())); 23 | QObject::disconnect(login, SIGNAL(loginFailed()), this, SLOT(failedSlot())); 24 | 25 | delete ui; 26 | } 27 | 28 | void LoginDialog::checkMoodleAvailability() 29 | { 30 | QUrl url(moodleApiDocs); 31 | QNetworkRequest request; 32 | request.setUrl(url); 33 | 34 | QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), 35 | this, SLOT(availabilityMoodleSlot(QNetworkReply*))); 36 | 37 | QLOG_INFO() << tr("Moodle Erreichbarkeitsrequest"); 38 | manager.get(request); 39 | } 40 | 41 | void LoginDialog::run(Login *login) 42 | { 43 | this->login = login; 44 | 45 | QObject::connect(this, SIGNAL(rejected()), this->login, SLOT(stopLoginSlot())); 46 | this->checkMoodleAvailability(); 47 | } 48 | 49 | void LoginDialog::availabilityMoodleSlot(QNetworkReply * reply) 50 | { 51 | QObject::disconnect(&manager, SIGNAL(finished(QNetworkReply*)), 52 | this, SLOT(availabilityMoodleSlot(QNetworkReply*))); 53 | 54 | QString response = reply->readAll(); 55 | 56 | if( reply->error() ) 57 | { 58 | response.truncate( 1000 ); 59 | QLOG_ERROR() << tr("Moodle nicht erreichbar. Genauer Fehler: ") << reply->errorString(); 60 | QLOG_ERROR() << tr("Inhalt der Antwort: ") << response; 61 | ui->statusLabel->setText(tr("Fehler: Moodle nicht erreichbar.")); 62 | this->moodleAvailable = NOTAVAILABLE; 63 | } 64 | else 65 | { 66 | QLOG_INFO() << tr("Moodle erreichbar"); 67 | this->moodleAvailable = AVAILABLE; 68 | checkForAuthentification(); 69 | } 70 | } 71 | 72 | void LoginDialog::failedSlot() 73 | { 74 | ui->statusLabel->setText(tr("Login fehlgeschlagen.")); 75 | } 76 | 77 | void LoginDialog::succededSlot() 78 | { 79 | ui->progressBar->setValue(3); 80 | ui->statusLabel->setText(tr("Login erfolgreich abgeschlossen!")); 81 | 82 | QTimer::singleShot(1500, this, SLOT(accept())); 83 | } 84 | 85 | void LoginDialog::checkForAuthentification() 86 | { 87 | if (this->moodleAvailable == NOTTESTED) 88 | { 89 | return; 90 | } 91 | QObject::connect(login, SIGNAL(newAccessToken(QString)), this, SLOT(succededSlot())); 92 | QObject::connect(login, SIGNAL(loginFailed()), this, SLOT(failedSlot())); 93 | 94 | if(!login->isRefreshTokenAvailable()) 95 | { 96 | ui->progressBar->setValue(1); 97 | ui->statusLabel->setText(tr("Authentifizierung notwendig. Browser öffnet automatisch.")); 98 | QTimer::singleShot(3000, login, SLOT(getAccess())); 99 | } 100 | else 101 | { 102 | ui->progressBar->setValue(2); 103 | ui->statusLabel->setText(tr("Einloggen...")); 104 | QTimer::singleShot(300, login, SLOT(getAccess())); 105 | } 106 | } 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mymainwindow.h" 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | QApplication a(argc, argv); 9 | 10 | MyMainWindow w; 11 | w.show(); 12 | 13 | QObject::connect(&a, SIGNAL(aboutToQuit()), &w, SLOT(closeTask())); 14 | return a.exec(); 15 | } 16 | -------------------------------------------------------------------------------- /src/mysortfilterproxymodel.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** This file is part of Sync-my-L2P. 3 | ** 4 | ** Sync-my-L2P is free software: you can redistribute it and/or modify 5 | ** it under the terms of the GNU Lesser General Public License as published by 6 | ** the Free Software Foundation, either version 3 of the License, or 7 | ** (at your option) any later version. 8 | ** 9 | ** Sync-my-L2P is distributed in the hope that it will be useful, 10 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | ** GNU Lesser General Public License for more details. 13 | ** 14 | ** You should have received a copy of the GNU Lesser General Public License 15 | ** along with Sync-my-L2P. If not, see . 16 | ****************************************************************************/ 17 | 18 | #include "mysortfilterproxymodel.h" 19 | #include 20 | 21 | MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent) 22 | :QSortFilterProxyModel(parent) 23 | { 24 | // Standardwerte hier müssen mit Standardwerten in GUI übereinstimmen, 25 | // da es sonst Probleme mit den valueChanged Signals gibt 26 | 27 | maxSizeFilter = false; 28 | maxSize = 1024*1024; 29 | 30 | dateFilter = false; 31 | minDate = QDate(1, 1, 1); 32 | maxDate = QDate(1, 1, 1); 33 | } 34 | 35 | void MySortFilterProxyModel::setFilterMinimumDate(const QDate &date) 36 | { 37 | minDate = date; 38 | invalidateFilter(); 39 | } 40 | 41 | void MySortFilterProxyModel::setFilterMaximumDate(const QDate &date) 42 | { 43 | maxDate = date; 44 | invalidateFilter(); 45 | } 46 | 47 | void MySortFilterProxyModel::setInRangeDateFilter(const bool filter) 48 | { 49 | dateFilter = filter; 50 | invalidateFilter(); 51 | } 52 | 53 | void MySortFilterProxyModel::setMaximumSize(const qint32 size) 54 | { 55 | maxSize = size*1024*1024; 56 | invalidateFilter(); 57 | } 58 | 59 | void MySortFilterProxyModel::setMaximumSizeFilter(const bool filter) 60 | { 61 | maxSizeFilter = filter; 62 | invalidateFilter(); 63 | } 64 | 65 | bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 66 | { 67 | // Holen des Items 68 | QStandardItemModel* source = (QStandardItemModel*) sourceModel(); 69 | QModelIndex index = source->index(sourceRow, 0, sourceParent); 70 | 71 | // Prüfen der Filterbedingungen 72 | bool show = true; 73 | if (maxSizeFilter) 74 | show = show && sizeInRange(source->data(index, sizeRole).toInt()); 75 | if (dateFilter && source->itemFromIndex(index)->type() == fileItem) 76 | show = show && dateInRange(source->data(index, dateRole).toDate()); 77 | return show; 78 | } 79 | 80 | bool MySortFilterProxyModel::dateInRange(const QDate &date) const 81 | { 82 | return (((date <= maxDate) || !maxDate.isValid()) && ((date >= minDate) || !minDate.isValid())); 83 | } 84 | 85 | bool MySortFilterProxyModel::sizeInRange(const qint32 size) const 86 | { 87 | return (size <= maxSize); 88 | } 89 | -------------------------------------------------------------------------------- /src/parser.cpp: -------------------------------------------------------------------------------- 1 | #include "parser.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | #include "qslog/QsLog.h" 9 | 10 | 11 | QString Parser::escapeString(QString untrimmedStr) 12 | { 13 | // Remove problematic characters for file systems that are allowed in RWTHmoodle 14 | QString escapePattern = "(:|<|>|/|\\\\|\\||\\*|\\^|\\?|\\\")"; 15 | QRegExp escapeRegExp(escapePattern, Qt::CaseSensitive); 16 | QString trimmedStr = untrimmedStr.replace(escapeRegExp, "").trimmed(); 17 | // Limit length as sometimes super long titles are used 18 | trimmedStr.truncate(100); 19 | return trimmedStr; 20 | } 21 | 22 | void Parser::parseMoodleCourses(QNetworkReply *reply, QStandardItemModel *itemModel) 23 | { 24 | // Empfangene Nachricht auslesen und als JSON interpretieren 25 | QByteArray response(reply->readAll()); 26 | QJsonDocument document = QJsonDocument::fromJson(response); 27 | QJsonObject object = document.object(); 28 | 29 | if(object.isEmpty()) 30 | { 31 | QLOG_WARN() << tr("Moodle-Kursinformationen leer bzw. nicht lesbar."); 32 | return; 33 | } 34 | 35 | if(object["StatusCode"].toInt() != 0) 36 | { 37 | QLOG_ERROR() << tr("Status der Moodle-Kursinformationen nicht ok: ") << 38 | QString(document.toJson()); 39 | return; 40 | } 41 | 42 | // Array mit allen einzelnen Vorlesungen/Veranstaltungen 43 | QJsonArray courses = object["Data"].toArray(); 44 | 45 | // Für jede Veranstaltung ein neues Strukturelement anlegen 46 | foreach(QJsonValue element, courses) 47 | { 48 | QJsonObject course = element.toObject(); 49 | 50 | QString title = course["courseTitle"].toString(); 51 | QString cid = QString::number(course["id"].toInt()); 52 | QJsonObject category = course["category"].toObject(); 53 | QString semester = category["idnumber"].toString(); 54 | QString url = course["url"].toString(); 55 | 56 | // Erstellen eines RegExps für unzulässige Buchstaben im Veranstaltungsnamen 57 | title = escapeString(title); 58 | 59 | Structureelement *newCourse = new Structureelement(title, QUrl(url), 0, 0, cid, courseItem, moodle); 60 | 61 | Utils::getSemesterItem(itemModel, semester)->appendRow(newCourse); 62 | 63 | QLOG_DEBUG() << tr("Moodle-Veranstaltung") << title << "(" << cid << tr(") hinzugefügt."); 64 | } 65 | } 66 | 67 | void Parser::parseMoodleFiles(QNetworkReply *reply, Structureelement* course) 68 | { 69 | Structureelement *currentCourse = course; 70 | 71 | QByteArray response = reply->readAll(); 72 | 73 | QJsonDocument document = QJsonDocument::fromJson(response); 74 | QJsonObject object = document.object(); 75 | 76 | if(object.isEmpty()) 77 | { 78 | QLOG_DEBUG() << tr("Moodle-Kursinformationen leer bzw. nicht lesbar."); 79 | return; 80 | } 81 | 82 | if(object["StatusCode"].toInt() != 0) 83 | { 84 | QLOG_ERROR() << tr("Status der Moodle-Kursinformationen nicht ok: \n") << 85 | "\n" << 86 | QString(document.toJson()); 87 | return; 88 | } 89 | 90 | if(object["IsError"].toBool()) 91 | { 92 | QLOG_ERROR() << tr("Moodle-Kursinformationen enthalten einen Fehler: \n") << 93 | "\n" << 94 | QString(document.toJson()); 95 | return; 96 | } 97 | 98 | QJsonArray files = object["Data"].toArray(); 99 | foreach(QJsonValue element, files) 100 | { 101 | QJsonObject file = element.toObject(); 102 | QString topicname; 103 | QString modulename; 104 | QString filename; 105 | QString sourceDirectory; 106 | int filesize; 107 | int timestamp; 108 | QString url; 109 | QStringList dirParts; 110 | 111 | QJsonObject fileInformation = file["fileinformation"].toObject(); 112 | 113 | topicname = escapeString(file["topicname"].toString()); 114 | modulename = escapeString(file["modulename"].toString()); 115 | filename = file["filename"].toString(); 116 | sourceDirectory = file["sourceDirectory"].toString(); 117 | filesize = fileInformation["filesize"].toInt(); 118 | timestamp = file["lastModified"].toInt(); 119 | url = file["downloadUrl"].toString(); 120 | 121 | // the list with the directories 122 | QStringList dirs{}; 123 | dirs.append(topicname); 124 | dirs.append(modulename); 125 | // modules can contain folders. this gets the folder names, as qstringlist 126 | dirParts = sourceDirectory.split('/'); 127 | if (dirParts.size() > 1) { 128 | dirParts.removeFirst(); 129 | dirParts.removeLast(); 130 | dirs += dirParts; 131 | } 132 | 133 | Structureelement *dir = Utils::getDirectoryItem(currentCourse, dirs); 134 | 135 | Structureelement* newFile = new Structureelement(filename, QUrl(url), timestamp, filesize, 136 | currentCourse->data(cidRole).toString(), 137 | fileItem, moodle); 138 | 139 | // Element hinzufügen 140 | dir->appendRow(newFile); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "utils.h" 12 | #include "urls.h" 13 | 14 | 15 | #include "qslog/QsLog.h" 16 | 17 | Utils::Utils(QObject *parent) : 18 | QObject(parent) 19 | { 20 | } 21 | 22 | /// Bestimmung des lokalen Pfads für ein Element 23 | Structureelement *Utils::getParentCourse(Structureelement *item) 24 | { 25 | Structureelement* currentItem = item; 26 | while(currentItem) 27 | { 28 | if(currentItem->type() == courseItem) 29 | { 30 | return currentItem; 31 | } 32 | 33 | currentItem = dynamic_cast(currentItem->parent()); 34 | } 35 | 36 | return nullptr; 37 | } 38 | 39 | QString Utils::getElementLocalPath(Structureelement *item, QString downloadDirectoryPath, bool includeFilname, bool includePrefix) 40 | { 41 | QString path; 42 | 43 | // Zwischenverzeichnisse 44 | Structureelement* parent = item; 45 | while ((parent = (Structureelement*) parent->parent()) != 0) 46 | { 47 | auto element_text = parent->text(); 48 | if(element_text.length() > 75 && !Utils::longPathsSupported()) 49 | element_text = element_text.left(75).trimmed(); 50 | while (element_text.endsWith(".")) { 51 | element_text.chop(1); 52 | } 53 | path.push_front(element_text % "/"); 54 | } 55 | 56 | // Downloadverzeichnis 57 | path.push_front(downloadDirectoryPath % "/"); 58 | 59 | // Fileprefix hinzufügen 60 | if(includePrefix) 61 | { 62 | path = QUrl::fromLocalFile(path).toString(); 63 | } 64 | 65 | // Dateiname 66 | if(includeFilname) 67 | { 68 | path.append(item->text()); 69 | } 70 | 71 | return path; 72 | } 73 | 74 | QString Utils::getElementRemotePath(Structureelement *item) 75 | { 76 | 77 | QString remoteUrl; 78 | auto typeEX = item->data(typeEXRole); 79 | if(typeEX == courseItem) 80 | { 81 | remoteUrl = item->data(urlRole).toString(); 82 | } 83 | else if (typeEX == directoryItem) 84 | { 85 | return ""; 86 | } 87 | else if (typeEX == fileItem) 88 | { 89 | QString filename = item->text(); 90 | QString downloadurl = item->data(urlRole).toString(); 91 | //QString downloadurl = item->data(urlRole).toUrl().toDisplayString(QUrl::FullyDecoded); 92 | remoteUrl = moodleDownloadFileUrl % "/" % filename % "?downloadurl=" % downloadurl; 93 | 94 | } 95 | return remoteUrl; 96 | } 97 | 98 | void Utils::copyTextToClipboard(QString text) 99 | { 100 | // Holen der globalen Zwischenablage 101 | QClipboard *clipboard = QApplication::clipboard(); 102 | 103 | // Kopieren der URL des mit der rechten Maustaste geklickten Items in die Zwischenablage 104 | clipboard->setText(text); 105 | } 106 | 107 | void Utils::errorMessageBox(QString message, QString detailMessage) 108 | { 109 | // Falls ein Fehler aufgetreten sein sollte, Ausgabe dessen 110 | QMessageBox messageBox; 111 | messageBox.setWindowIcon(QIcon(":/icons/magnifier.png")); 112 | messageBox.setText(message); 113 | messageBox.setInformativeText(detailMessage); 114 | messageBox.setStandardButtons(QMessageBox::Ok); 115 | messageBox.exec(); 116 | 117 | QLOG_ERROR() << message << ": " << detailMessage; 118 | } 119 | 120 | /// Erstellung einer Liste mit allen Veransaltungen 121 | QList Utils::getAllCourseItems(QStandardItemModel *itemModel) 122 | { 123 | QList courses; 124 | 125 | for(int row=0; row < itemModel->rowCount(); ++row) 126 | { 127 | Structureelement *element = static_cast(itemModel->item(row)); 128 | if(element->type() == courseItem) 129 | { 130 | courses.append(element); 131 | } 132 | else if(element->type() == semesterItem) 133 | { 134 | for(int innerRow=0; innerRow < element->rowCount(); ++innerRow) 135 | { 136 | courses.append(static_cast(element->child(innerRow))); 137 | } 138 | } 139 | else 140 | { 141 | QLOG_ERROR() << tr("Unbekanntes Element auf der Ebene der Veranstaltungen: ") << element->text(); 142 | } 143 | } 144 | 145 | return courses; 146 | } 147 | 148 | /// Factory für SemesterItems 149 | Structureelement *Utils::getSemesterItem(QStandardItemModel *itemModel, QString semester) 150 | { 151 | QList foundItems = itemModel->findItems(semester); 152 | Structureelement *semesterElement; 153 | 154 | if(foundItems.size()) 155 | { 156 | semesterElement = static_cast(foundItems.first()); 157 | } 158 | else 159 | { 160 | semesterElement = new Structureelement(semester, QUrl(), 0, 0, QString(), semesterItem); 161 | itemModel->appendRow(semesterElement); 162 | } 163 | 164 | return semesterElement; 165 | } 166 | 167 | /// Factory für DirectoryItems 168 | Structureelement *Utils::getDirectoryItem(Structureelement *courseItem, QStringList path) 169 | { 170 | Structureelement *currentItem = courseItem; 171 | 172 | // Iteriere entlang der Elemente des Pfads und erstelle diese ggf. 173 | foreach(QString item, path) 174 | { 175 | // Remove unnessescary whit 176 | item = item.simplified(); 177 | 178 | bool correctChildFound = false; 179 | for(int row=0; row < currentItem->rowCount(); ++row) 180 | { 181 | Structureelement *child = static_cast(currentItem->child(row)); 182 | if(child->text() == item) 183 | { 184 | currentItem = child; 185 | correctChildFound = true; 186 | break; 187 | } 188 | } 189 | 190 | if(!correctChildFound) 191 | { 192 | Structureelement* child = new Structureelement(item, QUrl(), 0, 0, QString(), directoryItem); 193 | 194 | currentItem->appendRow(child); 195 | currentItem = child; 196 | } 197 | } 198 | 199 | return currentItem; 200 | } 201 | 202 | /// Zentrieren eines Fenster auf dem Desktops 203 | void Utils::centerWidgetOnDesktop(QWidget *widget) 204 | { 205 | QRect desktopRect = widget->screen()->virtualGeometry(); 206 | QRect windowRect = widget->frameGeometry(); 207 | widget->move((desktopRect.width()-windowRect.width())/2+desktopRect.x(), (desktopRect.height()-windowRect.height())/2+desktopRect.y()); 208 | } 209 | 210 | /// Überprüfung aller Dateien, ob diese auf der Festplatte bereits existieren 211 | void Utils::checkAllFilesIfSynchronised(QList items, QString downloadDirectory) 212 | { 213 | foreach(Structureelement* item, items) 214 | { 215 | if(item->type() != fileItem) 216 | { 217 | continue; 218 | } 219 | 220 | QString filePath = getElementLocalPath(item, downloadDirectory, true, false); 221 | QFileInfo fileInfo(filePath); 222 | 223 | if(fileInfo.exists() && fileInfo.isFile() && 224 | fileInfo.size() == item->data(sizeRole).toInt() && 225 | fileInfo.lastModified() >= item->data(dateRole).toDateTime()) 226 | { 227 | item->setData(SYNCHRONISED, synchronisedRole); 228 | } 229 | else 230 | { 231 | item->setData(NOT_SYNCHRONISED, synchronisedRole); 232 | } 233 | 234 | } 235 | } 236 | 237 | /// check whether the OS supports long paths 238 | bool Utils::longPathsSupported() 239 | { 240 | const auto osVersion = QOperatingSystemVersion::current(); 241 | return osVersion.type() != QOperatingSystemVersion::Windows 242 | || osVersion >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 1607); 243 | } 244 | -------------------------------------------------------------------------------- /windows/lib/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | LICENSE ISSUES 3 | ============== 4 | 5 | The OpenSSL toolkit stays under a double license, i.e. both the conditions of 6 | the OpenSSL License and the original SSLeay license apply to the toolkit. 7 | See below for the actual license texts. 8 | 9 | OpenSSL License 10 | --------------- 11 | 12 | /* ==================================================================== 13 | * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions 17 | * are met: 18 | * 19 | * 1. Redistributions of source code must retain the above copyright 20 | * notice, this list of conditions and the following disclaimer. 21 | * 22 | * 2. Redistributions in binary form must reproduce the above copyright 23 | * notice, this list of conditions and the following disclaimer in 24 | * the documentation and/or other materials provided with the 25 | * distribution. 26 | * 27 | * 3. All advertising materials mentioning features or use of this 28 | * software must display the following acknowledgment: 29 | * "This product includes software developed by the OpenSSL Project 30 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 31 | * 32 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 33 | * endorse or promote products derived from this software without 34 | * prior written permission. For written permission, please contact 35 | * openssl-core@openssl.org. 36 | * 37 | * 5. Products derived from this software may not be called "OpenSSL" 38 | * nor may "OpenSSL" appear in their names without prior written 39 | * permission of the OpenSSL Project. 40 | * 41 | * 6. Redistributions of any form whatsoever must retain the following 42 | * acknowledgment: 43 | * "This product includes software developed by the OpenSSL Project 44 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 45 | * 46 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 47 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 49 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 50 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 51 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 53 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 55 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 57 | * OF THE POSSIBILITY OF SUCH DAMAGE. 58 | * ==================================================================== 59 | * 60 | * This product includes cryptographic software written by Eric Young 61 | * (eay@cryptsoft.com). This product includes software written by Tim 62 | * Hudson (tjh@cryptsoft.com). 63 | * 64 | */ 65 | 66 | Original SSLeay License 67 | ----------------------- 68 | 69 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 70 | * All rights reserved. 71 | * 72 | * This package is an SSL implementation written 73 | * by Eric Young (eay@cryptsoft.com). 74 | * The implementation was written so as to conform with Netscapes SSL. 75 | * 76 | * This library is free for commercial and non-commercial use as long as 77 | * the following conditions are aheared to. The following conditions 78 | * apply to all code found in this distribution, be it the RC4, RSA, 79 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation 80 | * included with this distribution is covered by the same copyright terms 81 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). 82 | * 83 | * Copyright remains Eric Young's, and as such any Copyright notices in 84 | * the code are not to be removed. 85 | * If this package is used in a product, Eric Young should be given attribution 86 | * as the author of the parts of the library used. 87 | * This can be in the form of a textual message at program startup or 88 | * in documentation (online or textual) provided with the package. 89 | * 90 | * Redistribution and use in source and binary forms, with or without 91 | * modification, are permitted provided that the following conditions 92 | * are met: 93 | * 1. Redistributions of source code must retain the copyright 94 | * notice, this list of conditions and the following disclaimer. 95 | * 2. Redistributions in binary form must reproduce the above copyright 96 | * notice, this list of conditions and the following disclaimer in the 97 | * documentation and/or other materials provided with the distribution. 98 | * 3. All advertising materials mentioning features or use of this software 99 | * must display the following acknowledgement: 100 | * "This product includes cryptographic software written by 101 | * Eric Young (eay@cryptsoft.com)" 102 | * The word 'cryptographic' can be left out if the rouines from the library 103 | * being used are not cryptographic related :-). 104 | * 4. If you include any Windows specific code (or a derivative thereof) from 105 | * the apps directory (application code) you must include an acknowledgement: 106 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 107 | * 108 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 109 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 110 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 111 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 112 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 113 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 114 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 115 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 116 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 117 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 118 | * SUCH DAMAGE. 119 | * 120 | * The licence and distribution terms for any publically available version or 121 | * derivative of this code cannot be changed. i.e. this code cannot simply be 122 | * copied and put under another distribution licence 123 | * [including the GNU Public Licence.] 124 | */ 125 | 126 | -------------------------------------------------------------------------------- /windows/lib/Readme.md: -------------------------------------------------------------------------------- 1 | 2 | Sync-my-L2P links against OpenSSL at runtime. This page describes where we get the OpenSSL DLLs from. 3 | 4 | ### Why not use QT's precompiled OpenSSL DLLs? 5 | 6 | On https://download.qt.io/ there are already prebuilt OpenSSL DLLs: 7 | 8 | * https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/tools_openssl_x86/qt.tools.openssl.win_x86/ 9 | * https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/tools_openssl_x64/qt.tools.openssl.win_x64/ 10 | 11 | They are built with an older version of Visual Studio. Therefore they link to msvcr100.dll which has to be installed on some systems (e.g. Windows 7) through the Microsoft Visual C++ 2010 SP1 Redistributable. But since Sync-my-L2P is built with a newer Visual Studio version, it ships with a newer Visual C++ Redistributable that doesn't contain msvcr100.dll. Therefore we compile OpenSSL ourselves with the same Visual Studio version as Sync-my-L2P. This way we only need one Visual C++ Redistributable. To keep Sync-my-L2P's build time short, we've checked in the precompiled DLLs. 12 | 13 | ### Prerequisites 14 | 15 | * Perl 16 | * nmake (comes with Visual Studio) 17 | * nasm (https://www.nasm.us/) 18 | 19 | ### Source 20 | 21 | The OpenSSL source code is downloaded from: https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/tools_openssl_src/qt.tools.openssl.src/ 22 | 23 | ### x86 build steps 24 | 25 | ```batch 26 | mkdir C:\dev\openssl-win32 27 | cd C:\dev\openssl-win32 28 | "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat" 29 | perl C:\dev\openssl-src\Tools\OpenSSL\src\Configure VC-WIN32 30 | nmake 31 | nmake test 32 | ``` 33 | 34 | ### x64 build steps 35 | 36 | ```batch 37 | mkdir C:\openssl-win64 38 | cd C:\openssl-win64 39 | "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" 40 | perl C:\dev\openssl-src\Tools\OpenSSL\src\Configure VC-WIN64A 41 | nmake 42 | nmake test 43 | ``` 44 | -------------------------------------------------------------------------------- /windows/lib/libcrypto-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/windows/lib/libcrypto-1_1-x64.dll -------------------------------------------------------------------------------- /windows/lib/libcrypto-1_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/windows/lib/libcrypto-1_1.dll -------------------------------------------------------------------------------- /windows/lib/libssl-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/windows/lib/libssl-1_1-x64.dll -------------------------------------------------------------------------------- /windows/lib/libssl-1_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwthmoodle/Sync-my-L2P/3b435df4a6192f22c096be0cb114a7550568046a/windows/lib/libssl-1_1.dll -------------------------------------------------------------------------------- /windows/license.xml.template: -------------------------------------------------------------------------------- 1 | 2 | 2020-05-28 3 | 1.2 4 | standard 5 | 0 6 | 0 7 | RWTH Aachen University - Open Source License 8 | 0 9 | VMware InstallBuilder Multiplatform Enterprise 10 | Sync-my-L2P 11 | PLACEHOLDER 12 | --------------------------------------------------------------------------------